def test_tight_with_island(): # build a peanut first: r = 100 thetas = np.linspace(0,2*np.pi,250) peanut = np.zeros( (len(thetas),2), np.float64) x = r*np.cos(thetas) y = r*np.sin(thetas) * (0.9/10000 * x*x + 0.05) peanut[:,0] = x peanut[:,1] = y # put two holes into it thetas = np.linspace(0,2*np.pi,30) hole1 = np.zeros( (len(thetas),2), np.float64) hole1[:,0] = 10*np.cos(thetas) - 75 hole1[:,1] = 10*np.sin(thetas) hole2 = np.zeros( (len(thetas),2), np.float64) hole2[:,0] = 20*np.cos(thetas) + 75 hole2[:,1] = 20*np.sin(thetas) rings = [peanut,hole1,hole2] density = field.ConstantField( 6.0 ) p=paver.Paving(rings,density,label='tight_with_island') p.pave_all()
def test_embedded_channel(): # 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()
def test_dumbarton(): shp=os.path.join( os.path.dirname(__file__), 'data','dumbarton.shp') features=wkb2shp.shp2geom(shp) geom = features['geom'][0] dumbarton = np.array(geom.exterior) density = field.ConstantField(250.0) p=paver.Paving(dumbarton, density,label='dumbarton') p.pave_all()
def test_long_channel(): l = 2000 w = 50 long_channel = np.array([[0, 0], [l, 0], [l, w], [0, w]], np.float64) density = field.ConstantField(19.245) p = paver.Paving(long_channel, density) p.pave_all()
def test_narrow_channel(): l = 1000 w = 50 long_channel = np.array([[0, 0], [l, 0.375 * w], [l, 0.625 * w], [0, w]], np.float64) density = field.ConstantField(w / np.sin(60 * np.pi / 180.) / 4) p = paver.Paving(long_channel, density) p.pave_all()
def test_long_channel_rigid(): l = 2000 w = 50 long_channel = np.array([[0, 0], [l, 0], [l, w], [0, w]], np.float64) density = field.ConstantField(19.245) p = paver.Paving(long_channel, density, initial_node_status=paver.Paving.RIGID) p.pave_all()
def test_cul_de_sac(): r = 5 theta = np.linspace(-np.pi / 2, np.pi / 2, 20) cap = r * np.swapaxes(np.array([np.cos(theta), np.sin(theta)]), 0, 1) box = np.array([[-3 * r, r], [-4 * r, -r]]) ring = np.concatenate((box, cap)) density = field.ConstantField(2 * r / (np.sqrt(3) / 2)) p = paver.Paving(ring, density, label='cul_de_sac') p.pave_all()
def test_tight_peanut(): r = 100 thetas = np.linspace(0,2*np.pi,300) peanut = np.zeros( (len(thetas),2), np.float64) x = r*np.cos(thetas) y = r*np.sin(thetas) * (0.9/10000 * x*x + 0.05) peanut[:,0] = x peanut[:,1] = y density = field.ConstantField( 6.0 ) p=paver.Paving(peanut,density,label='tight_peanut') p.pave_all()
def test_bow(): x = np.linspace(-100,100,50) # with /1000 it seems to do okay # with /500 it still looks okay y = x**2 / 250.0 bow = np.swapaxes( np.concatenate( (x[None,:],y[None,:]) ), 0,1) height = np.array([0,20]) ring = np.concatenate( (bow+height,bow[::-1]-height) ) density = field.ConstantField(2) p=paver.Paving(ring,density,label='bow') p.pave_all()
def gen_sine_sine(): t = np.linspace(1.0,12*np.pi,400) x1 = 100*t y1 = 200*np.sin(t) # each 2*pi, the radius gets bigger by exp(2pi*b) x2 = x1 y2 = y1+50 # now perturb both sides, but keep amplitude < 20 y1 = y1 + 20*np.sin(10*t) y2 = y2 + 10*np.cos(5*t) x = np.concatenate( (x1,x2[::-1]) ) y = np.concatenate( (y1,y2[::-1]) ) shore = np.swapaxes( np.concatenate( (x[None,:],y[None,:]) ), 0,1) rings = [shore] # and make some islands: north_island_shore = 0.4*y1 + 0.6*y2 south_island_shore = 0.6*y1 + 0.4*y2 Nislands = 20 # islands same length as space between islands, so divide # island shorelines into 2*Nislands blocks for i in range(Nislands): i_start = int( (2*i+0.5)*len(t)/(2*Nislands) ) i_stop = int( (2*i+1.5)*len(t)/(2*Nislands) ) north_y = north_island_shore[i_start:i_stop] south_y = south_island_shore[i_start:i_stop] north_x = x1[i_start:i_stop] south_x = x2[i_start:i_stop] x = np.concatenate( (north_x,south_x[::-1]) ) y = np.concatenate( (north_y,south_y[::-1]) ) island = np.swapaxes( np.concatenate( (x[None,:],y[None,:]) ), 0,1) rings.append(island) density = field.ConstantField(25.0) min_density = field.ConstantField(2.0) p = paver.Paving(rings,density=density,min_density=min_density) print("Smoothing to nominal 1.0m") # mostly just to make sure that long segments are # sampled well relative to the local feature scale. p.smooth() print("Adjusting other densities to local feature size") p.telescope_rate=1.1 p.adjust_density_by_apollonius() return p
def test_expansion(): # 40: too close to a 120deg angle - always bisect on centerline # 30: rows alternate with wall and bisect seams # 35: starts to diverge, but recovers. # 37: too close to 120. d = 36 pnts = np.array([[0., 0.], [100, -d], [200, 0], [200, 100], [100, 100 + d], [0, 100]]) density = field.ConstantField(6) p = paver.Paving([pnts], density, label='expansion') p.pave_all()
def test_basic(): # Define a polygon boundary=np.array([[0,0],[1000,0],[1000,1000],[0,1000]]) island =np.array([[200,200],[600,200],[200,600]]) rings=[boundary,island] # And the scale: scale=field.ConstantField(50) p=paver.Paving(rings=rings,density=scale) p.pave_all()
def test_peninsula(): r = 100 thetas = np.linspace(0,2*np.pi,1000) pen = np.zeros( (len(thetas),2), np.float64) pen[:,0] = r*(0.2+ np.abs(np.sin(2*thetas))**0.2)*np.cos(thetas) pen[:,1] = r*(0.2+ np.abs(np.sin(2*thetas))**0.2)*np.sin(thetas) density = field.ConstantField( 10.0 ) pen2 = upsample_linearring(pen,density) p=paver.Paving(pen2,density,label='peninsula') p.pave_all()
def test_circle(): r = 100 thetas = np.linspace(0,2*np.pi,200)[:-1] circle = np.zeros((len(thetas),2),np.float64) circle[:,0] = r*np.cos(thetas) circle[:,1] = r*np.sin(thetas) class CircleDensityField(field.Field): # horizontally varying, from 5 to 20 def value(self,X): X = np.array(X) return 5 + 15 * (X[...,0] + 100) / 200.0 density = CircleDensityField() p=paver.Paving(circle,density,label='circle') p.pave_all()
def test_basic_apollo(): # Define a polygon boundary=np.array([[0,0],[1000,0],[1000,1000],[0,1000]]) island =np.array([[200,200],[600,200],[200,600]]) rings=[boundary,island] # And the scale: scale=field.PyApolloniusField() scale.insert([50,50],20) p=paver.Paving(rings=rings,density=scale) p.pave_all() return p
def test_small_island(): l = 100 square = np.array([[0, 0], [l, 0], [l, l], [0, l]], np.float64) r = 10 theta = np.linspace(0, 2 * np.pi, 30) circle = r / np.sqrt(2) * np.swapaxes( np.array([np.cos(theta), np.sin(theta)]), 0, 1) island1 = circle + np.array([45, 45]) island2 = circle + np.array([65, 65]) island3 = circle + np.array([20, 80]) rings = [square, island1, island2, island3] density = field.ConstantField(10) p = paver.Paving(rings, density) p.pave_all()
def test_ngon(nsides=7): # hexagon works ok, though a bit of perturbation # septagon starts to show expansion issues, but never pronounced # octagon - works fine. theta = np.linspace(0,2*np.pi,nsides+1)[:-1] r=100 x = r*np.cos(theta) y = r*np.sin(theta) poly = np.swapaxes( np.concatenate( (x[None,:],y[None,:]) ), 0,1) density = field.ConstantField(6) p=paver.Paving(poly,density,label='ngon%02d'%nsides) p.pave_all()
def test_peanut(): # like a figure 8, or a peanut r = 100 thetas = np.linspace(0,2*np.pi,1000) peanut = np.zeros( (len(thetas),2), np.float64) peanut[:,0] = r*(0.5+0.3*np.cos(2*thetas))*np.cos(thetas) peanut[:,1] = r*(0.5+0.3*np.cos(2*thetas))*np.sin(thetas) min_pnt = peanut.min(axis=0) max_pnt = peanut.max(axis=0) d_data = np.array([ [min_pnt[0],min_pnt[1], 1.5], [min_pnt[0],max_pnt[1], 1.5], [max_pnt[0],min_pnt[1], 8], [max_pnt[0],max_pnt[1], 8]]) density = field.XYZField(X=d_data[:,:2],F=d_data[:,2]) p=paver.Paving(peanut,density) p.pave_all()
## plt.figure(3).clf() fig, ax = plt.subplots(1, 1, num=3) scat = ax.scatter(cutoff_xyz[:, 0], cutoff_xyz[:, 1], 20, cutoff_xyz[:, 2]) plot_wkb.plot_wkb(total_poly, zorder=-2) ax.axis('equal') ## from stompy.spatial import field from stompy.grid import paver six.moves.reload_module(paver) p = paver.Paving(geom=total_poly, density=field.ConstantField(Lres)) p.verbose = 1 p.pave_all() ## # But better to just use a subset of the existing grid. select = g.select_nodes_intersecting(total_poly) g_sub = g.copy() for n in np.nonzero(~select)[0]: g_sub.delete_node_cascade(n) g_sub.renumber() g_sub.orient_edges()
def run(self, argv): try: opts, rest = getopt.getopt(argv[1:], 'hb:s:a:t:i:c:r:dv:np:om:i:f:g:C:', ['slide-interior', 'rigid-interior']) except getopt.GetoptError as e: print(e) print("-" * 80) self.usage() exit(1) for opt, val in opts: if opt == '-h': self.usage() exit(1) elif opt == '-s': self.scale_shps.append(val) elif opt == '-a': self.tele_scale_shps.append(val) elif opt == '-t': self.effective_tele_rate = float(val) elif opt == '-f': self.scale_factor = float(val) elif opt == '-b': self.boundary_shp = val elif opt == '-p': self.plot_interval = int(val) elif opt == '-c': self.checkpoint_interval = int(val) elif opt == '-C': self.scale_ratio_for_cutoff = float(val) elif opt == '-r': self.resume_checkpoint_fn = val elif opt == '-d': self.smooth = 0 elif opt == '-v': self.verbosity = int(val) elif opt == '-n': self.dry_run = 1 elif opt == '-o': self.optimize = 1 elif opt == '-m': self.density_map = val elif opt == '-i': if not self.interior_shps: self.interior_shps = [] self.interior_shps.append(val) elif opt == '-g': self.output_shp = val elif opt == '--slide-interior': self.slide_interior = 1 elif opt == '--rigid-interior': self.slide_interior = 0 self.check_parameters() log_fp = open('tom.log', 'wt') log_fp.write("TOM log:\n") log_fp.write(" ".join(argv)) log_fp.close() if not self.resume_checkpoint_fn: bound_args = self.prepare_boundary() density_args = self.prepare_density() args = {} args.update(bound_args) args.update(density_args) args['slide_internal_guides'] = self.slide_interior # Wait until after smoothing to add degenerate interior lines # args.update(self.prepare_interiors()) self.p = paver.Paving(**args) self.p.verbose = self.verbosity self.p.scale_ratio_for_cutoff = self.scale_ratio_for_cutoff if self.smooth: self.p.smooth() # and write out the smoothed shoreline wkb2shp.wkb2shp(self.smoothed_poly_shp, [self.p.poly], overwrite=True) int_args = self.prepare_interiors() if int_args.has_key('degenerates'): for degen in int_args['degenerates']: self.p.clip_and_add_degenerate_ring(degen) else: self.p = paver.Paving.load_complete(self.resume_checkpoint_fn) self.p.verbose = self.verbosity if self.dry_run: print("dry run...") elif self.density_map: f = self.p.density x1, y1, x2, y2, dx, dy = map(float, self.density_map.split(',')) bounds = np.array([[x1, y1], [x2, y2]]) rasterized = f.to_grid(dx=dx, dy=dy, bounds=bounds) rasterized.write_gdal("scale-raster.tif") else: starting_step = self.p.step self.create_grid() if (not os.path.exists('final.pav') ) or self.p.step > starting_step: self.p.write_complete('final.pav') if (not os.path.exists('final.pdf') ) or self.p.step > starting_step: self.plot_intermediate(fn='final.pdf', color_by_step=False) # write grid as shapefile if self.output_shp: print("Writing shapefile with %d features (edgse)" % (self.p.Nedges())) self.p.write_shp(self.output_shp, only_boundaries=0, overwrite=1) # by reading the suntans grid output back in, we should get boundary edges # marked as 1 - self.p probably doesn't have these markers g = trigrid.TriGrid(suntans_path='.') g.write_shp('trigrid_write.shp', only_boundaries=0, overwrite=1) if self.optimize: self.run_optimization() self.p.write_complete('post-optimize.pav') self.plot_intermediate(fn='post-optimize.pdf')
try: j = g.add_edge(nodes=[na, nb]) except g.GridException: pass cycles = g.find_cycles(max_cycle_len=g.Nnodes()) polys = [geometry.Polygon(g.nodes['x'][cycle]) for cycle in cycles] from shapely import ops full_poly = ops.cascaded_union(polys) ## # scale=field.ConstantField(100) scale = apollo # out of order, from below p = paver.Paving(geom=full_poly, density=scale) p.verbose = 1 p.pave_all() output_dir = 'grid_v01' os.path.exists(output_dir) or os.makedirs(output_dir) p.write_suntans(output_dir) ## g = unstructured_grid.SuntansGrid(output_dir) g.write_ugrid(os.path.join(output_dir, 'grid-v01.nc'))