示例#1
0
def process_quad_patch(name, M=None):

    center_idx = np.nonzero(centerlines['name'] == name)[0][0]
    centerline = centerlines['geom'][center_idx]
    if M is None:
        M = centerlines['rows'][center_idx]
    bound = bounds['geom'][bounds['name'] == name][0]

    center = linestring_utils.resample_linearring(np.array(centerline),
                                                  scale,
                                                  closed_ring=0)

    g = unstructured_grid.UnstructuredGrid(max_sides=6)

    # Smooth the exterior

    ext_points = np.array(bound.exterior)
    ext_points = linestring_utils.resample_linearring(ext_points,
                                                      scale,
                                                      closed_ring=True)
    from stompy import filters
    ext_points[:, 0] = filters.lowpass_fir(ext_points[:, 0], 3)
    ext_points[:, 1] = filters.lowpass_fir(ext_points[:, 1], 3)
    smooth_bound = geometry.Polygon(ext_points)

    L = smooth_bound.exterior.length

    def profile(x, s, perp):
        probe_left = geometry.LineString([x, x + L * perp])
        probe_right = geometry.LineString([x, x - L * perp])

        left_cross = smooth_bound.exterior.intersection(probe_left)
        right_cross = smooth_bound.exterior.intersection(probe_right)

        assert left_cross.type == 'Point', "Fix this for multiple intersections"
        assert right_cross.type == 'Point', "Fix this for multiple intersections"

        pnt_left = np.array(left_cross)
        pnt_right = np.array(right_cross)
        d_left = utils.dist(x, pnt_left)
        d_right = utils.dist(x, pnt_right)

        return np.interp(np.linspace(-1, 1, M), [-1, 0, 1],
                         [-d_right, 0, d_left])

    g.add_rectilinear_on_line(center, profile)
    g.renumber()
    return g
示例#2
0
def test_embedded_channel():
    assert False  # no API yet.
    # trying out degenerate internal lines - the trick may be mostly in
    # how to specify them.
    # make a large rectangle, with a sinuous channel in the middle
    L = 500.0
    W = 300.0

    rect = np.array([[0, 0], [L, 0], [L, W], [0, W]])

    x = np.linspace(0.1 * L, 0.9 * L, 50)
    y = W / 2 + 0.1 * W * np.cos(4 * np.pi * x / L)
    shore = np.swapaxes(np.concatenate((x[None, :], y[None, :])), 0, 1)

    density = field.ConstantField(10)

    # this will probably get moved into Paver itself.
    # Note closed_ring=0 !
    shore = resample_linearring(shore, density, closed_ring=0)

    south_shore = shore - np.array([0, 0.1 * W])
    north_shore = shore + np.array([0, 0.1 * W])

    p = paver.Paving([rect], density, degenerates=[north_shore, south_shore])
    p.pave_all()
示例#3
0
 def add_monitor_transects(self,features,dx=None):
     """
     Add a sampled transect. dx=None will eventually just pull each
     cell along the line.  otherwise sample at even distance dx.
     """
     # Sample each cell intersecting the given feature
     assert dx is not None,"Not ready for adaptive transect resolution"
     for feat in features:
         pnts=np.array(feat['geom'])
         pnts=linestring_utils.resample_linearring(pnts,dx,closed_ring=False)
         self.log.info("Resampling leads to %d points for %s"%(len(pnts),feat['name']))
         # punt with length of the name -- not sure if DFM is okay with >20 characters
         pnts_and_names=[ dict(geom=geometry.Point(pnt),name="%s_%04d"%(feat['name'][:13],i))
                          for i,pnt in enumerate(pnts) ]
         self.add_monitor_points(pnts_and_names)
示例#4
0
 def dem_analysis(self, bathy_fn):
     # 1.0 is from half the current DEM resolution
     pad = 10.0
     bounds = [
         self.section_ls[:, 0].min() - pad,
         self.section_ls[:, 0].max() + pad,
         self.section_ls[:, 1].min() - pad,
         self.section_ls[:, 1].max() + pad
     ]
     self.dem = field.GdalGrid(bathy_fn, geo_bounds=bounds)
     res = 0.5 * self.dem.dx
     self.section_segs = linestring_utils.resample_linearring(
         self.section_ls, res, closed_ring=0)
     self.section_z = self.dem(self.section_segs)
     self.section_s = utils.dist_along(self.section_segs)
示例#5
0
def eval_pnt_pair(pnt_pair, node_depths):
    metrics = {}
    nodes = metrics['nodes'] = [g.select_nodes_nearest(xy) for xy in pnt_pair]
    node_path = metrics['node_path'] = g.shortest_path(nodes[0], nodes[1])
    path_xy = metrics['path_xy'] = g.nodes['x'][node_path]
    path_dist = metrics['path_dist'] = utils.dist_along(path_xy)
    path_z = metrics['path_z'] = node_depths[node_path]

    resamp_xy = linestring_utils.resample_linearring(path_xy,
                                                     2.0,
                                                     closed_ring=False)
    metrics['resamp_xy'] = resamp_xy

    metrics['resamp_z'] = resamp_z = dem(resamp_xy)
    metrics['resamp_dist'] = resamp_dist = utils.dist_along(resamp_xy)

    # edge depths with bedlevtyp3, sampled to higher resolution
    seg_z_typ3 = 0.5 * (path_z[:-1] + path_z[1:])
    resamp_z_typ3 = seg_z_typ3[
        np.searchsorted(path_dist, resamp_dist).clip(1,
                                                     len(path_dist) - 1) - 1]
    metrics['resamp_z_typ3'] = resamp_z_typ3

    metrics['ref_eta'] = ref_eta = 1.0

    A_dem = np.trapz((ref_eta - resamp_z).clip(0, np.inf), resamp_dist)
    L_dem = np.trapz(1. * (ref_eta > resamp_z), resamp_dist)
    A_typ3 = np.trapz((ref_eta - resamp_z_typ3).clip(0, np.inf), resamp_dist)
    L_typ3 = np.trapz(1. * (ref_eta > resamp_z_typ3), resamp_dist)

    metrics['A_dem'] = A_dem
    metrics['L_dem'] = L_dem
    metrics['A_typ3'] = A_typ3
    metrics['L_typ3'] = L_typ3

    metrics['A_err'] = A_typ3 - A_dem
    metrics['L_err'] = L_typ3 - L_dem
    metrics['z_err'] = metrics['A_err'] / (L_dem + 0.1)

    return metrics
示例#6
0
def resample_to_common(trans,dz=None,dx=None,resample_x=True,resample_z=True,
                       seg=None,save_original='orig_'):
    """
    trans: list of xr_transect Datasets.
    dx: length scale for horizontal resampling, defaults to median.  Pass 0
     to use seg as is.
    dz: length scale for vertical resampling.  defaults to 10th percentile.
    resample_x: can be set to false to skip horizontal resampling if all transects
     already have the same horizontal coordinates
    resample_z: can be set to false to skip vertical resampling if all transects
     already have the same vertical coordinates.
    seg: the linestring of the new transect.  defaults to fitting a line.

    save_original: if not None, a prefix for saving coordinates before resampling.
    """
    if resample_z:
        trans=resample_to_common_z(trans,dz=dz,save_original=save_original)

    if resample_x:
        if seg is None:
            seg=transects_to_segment(trans)

        if dx is None:
            # Define the target vertical and horizontal bins
            all_dx=[get_dx_sample(tran).values
                    for tran in trans]
            median_dx=np.median(np.concatenate(all_dx))
            dx=median_dx

        if dx>=0:
            # Keep this general, so that segment is allowed to have more than
            # just two vertices
            new_xy = linestring_utils.resample_linearring(seg,dx,closed_ring=False)
        else:
            new_xy = seg

        trans=[resample_d(tran,new_xy,save_original=save_original)
               for tran in trans]
    return trans
示例#7
0
hydro = extract_global(model)

##

# Sample datasets
if 1:
    import bathy
    dem = bathy.dem()

    # fake, sparser tracks.
    adcp_shp = wkb2shp.shp2geom('sparse_fake_bathy_trackline.shp')
    xys = []
    for feat in adcp_shp['geom']:
        feat_xy = np.array(feat)
        feat_xy = linestring_utils.resample_linearring(feat_xy,
                                                       1.0,
                                                       closed_ring=0)
        feat_xy = filters.lowpass_fir(feat_xy, winsize=6, axis=0)
        xys.append(feat_xy)
    adcp_xy = np.concatenate(xys)
    source_ds = xr.Dataset()
    source_ds['x'] = ('sample', 'xy'), adcp_xy
    source_ds['z'] = ('sample', ), dem(adcp_xy)

##


def steady_streamline_oneway(g, Uc, x0, max_t=3600, max_dist=np.inf):
    # trace some streamlines
    x0 = np.asarray(x0)
    t0 = 0.0
示例#8
0
# domain boundary including the random noise
ring_noise = ring + noise_lp[:, None] * ring_norm

# Create the curvilinear section
thalweg = centerline[50:110]

plt.figure(1).clf()
plt.plot(centerline[:, 0], centerline[:, 1], 'k-', zorder=2)
plt.axis('equal')

plot_wkb.plot_wkb(channel, zorder=-2)
plt.plot(ring_noise[:, 0], ring_noise[:, 1], 'm-')

plt.plot(thalweg[:, 0], thalweg[:, 1], 'r--', lw=3)

##

# First, just the curvilinear section:
g = unstructured_grid.UnstructuredGrid(max_sides=4)

thalweg_resamp = linestring_utils.resample_linearring(thalweg,
                                                      50,
                                                      closed_ring=0)

g.add_rectilinear_on_line(
    thalweg_resamp,
    profile=lambda x, s, perp: np.linspace(-200, 200, 20),
    add_streamwise=False)
g.plot_edges(zorder=5, color='y')
示例#9
0
ds_resamp=[xr_transect.resample_z(tran,new_z)
           for tran in trans]

##

plt.figure(2).clf()
fig,axs=plt.subplots(2,1,num=2,sharex=True,sharey=True)

xr_transect.plot_scalar(all_ds[0],all_ds[0].Ve,ax=axs[0])
xr_transect.plot_scalar(ds_resamp[0],ds_resamp[0].Ve,ax=axs[1])

##

# Keep this general, so that segment is allowed to have more than
# just two vertices
new_xy = linestring_utils.resample_linearring(seg,dx)

##

# resampling a single transect onto the new horizontal coordinates.
# can only operate on transects which have a uniform z coordinate
ds_in=ds_resamp[0]
assert ds_in.z_ctr.ndim==1,"Resampling horizontal requires uniform vertical coordinate"

## 
new_ds=xr.Dataset()
new_ds['z'


# x-z of a single transect:
示例#10
0
# A centerline:
sec0=np.array([[0,W/2],[L,W/2]])
s=np.linspace(0,np.pi/2,40)[1:] # skip first point
x_arc=np.cos(s)
y_arc=np.sin(s)

bend_r=W # radius of bend
bend_ctr=sec0[-1] + np.array([0,bend_r])
sec1=bend_ctr + bend_r*np.c_[ y_arc, -x_arc]

sec2=np.array( [sec1[-1],
                sec1[-1] +np.array([0,L] ) ] )

centerline=np.concatenate([sec0,sec1,sec2])
from stompy.spatial import linestring_utils
centerline=linestring_utils.resample_linearring(centerline,dx_lon,closed_ring=0)


def profile(x,s):
    return np.linspace(-W/2.,W/2.,int(W/dy_lat))

ret=g.add_rectilinear_on_line(centerline,profile)

y=g.cells['d_lat']/(W/2.0)
bathy=depth_center+(y**2)*(depth_edge-depth_center)
g.add_cell_field('depth',bathy,on_exists='overwrite')

if rotate!=0.0:
    g.nodes['x']=utils.rot(rotate*np.pi/180., g.nodes['x'] )

示例#11
0
dem_in_poly = dem.polygon_mask(region_poly)
pixA = dem.dx * dem.dy
pix_z = dem.F[dem_in_poly]


def eta_to_V(eta):
    return (pixA * (eta - pix_z).clip(0, np.inf)).sum()


etas = np.linspace(-10, 5, 200)
dem_volumes = np.array([eta_to_V(eta) for eta in etas])

##
from stompy.spatial import linestring_utils
section_segs = linestring_utils.resample_linearring(section_ls,
                                                    0.5 * dem.dx,
                                                    closed_ring=0)
section_z = dem(section_segs)
section_s = utils.dist_along(section_segs)


def eta_to_xA(eta):
    return np.trapz((eta - section_z).clip(0, np.inf), section_s)


dem_xas = np.array([eta_to_xA(eta) for eta in etas])

##

plt.figure(2).clf()
fig, axs = plt.subplots(3, 2, sharex='col', sharey='row', num=2)
示例#12
0
fig = plt.figure(1)
fig.clf()
ax = fig.add_subplot(1, 1, 1)

csc_grid.plot_edges(ax=ax)
ax.plot(cs_xy[:, 0], cs_xy[:, 1], 'g-', label='Cross section')
ax.axis('equal')
ax.axis(zoom)

##

from stompy.spatial import linestring_utils

# Pull profile from DEM along those lines:
cs_line = linestring_utils.resample_linearring(cs_xy, 2.0, closed_ring=False)
cs_dist = utils.dist_along(cs_line)
# this cross-section includes levees -- skip outside the levees
# channel_sel=(cs_dist>=106)&(cs_dist<=345)
# or with the aligned cross-section:
channel_sel = (cs_dist >= 61) & (cs_dist <= 299)

cs_line_z = dem(cs_line)

plt.figure(3).clf()
fig, ax = plt.subplots(num=3)

ax.plot(cs_dist, cs_line_z, 'k-')

sel_z = cs_line_z[channel_sel]
sel_d = cs_dist[channel_sel]