def shp2pol(shpfile, outdir): """ Converts a polygon shape file to a *.pol file Uses the first polygon in the file and the filename as the polygon name """ XY, name = readShpPoly(shpfile) xy = XY[0] numverts = xy.shape[0] polynameext = os.path.basename(shpfile) polyname, ext = os.path.splitext(polynameext) outfile = '%s/%s.pol' % (outdir, polyname) print('Writing polygon to: %s...' % outfile) f = open(outfile, 'w') f.write('POLYGON_NAME\n') f.write('%s\n' % polyname) f.write('NUMBER_OF_VERTICES\n') f.write('%d\n' % numverts) for ii in range(numverts): f.write('%6.10f %6.10f\n' % (xy[ii, 0], xy[ii, 1])) f.close() print('Done.')
def setAgeSource(self, shpfile): """ Sets the age source term using a polygon shapefile """ # Read the shapefile XY, tmp = readShpPoly(shpfile, FIELDNAME=None) if len(XY) < 1: raise Exception(' could not find any polygons in shapefile: %s' % shpfile) for xpoly in XY: xycells = np.asarray([self.xv, self.yv]) #ind1 = nxutils.points_inside_poly(xycells.T,xpoly) ind1 = inpolygon(xycells.T, xpoly) # Sets all vertical layers for now... self.agesource[:, ind1] = 1.
def calc_agebin(binfile, ncfile, polyfile, ntout): """ Calculate the from a binary file and save to netcdf """ # Load the polygon from a shapefile xypoly, field = readShpPoly(polyfile) # Load the binary file object PTM = PtmBin(binfile) # Count the number of particles from the first time step time, pdata = PTM.read_timestep() N = pdata.shape[0] tsec = othertime.SecondsSince(PTM.time) dt = tsec[1] - tsec[0] # Initialize the age particle object Age = ParticleAge(xypoly[0], N) # Loop through outctr = ntout ncctr = 0 for tt in range(PTM.nt - 1): # Read the current time step time, pdata = PTM.read_timestep(ts=tt) # Update the age variable Age.update_age(pdata['x'][:, 0], pdata['x'][:, 1], pdata['x'][:, 2], dt) # Write to netcdf if outctr == ntout: Age.write_nc(time, ncctr, ncfile=ncfile) ncctr += 1 outctr = 0 outctr += 1 print('Done.')
def modifyBCmarker(suntanspath, bcfile, saveplot=False): """ Modifies SUNTANS boundary markers with a shapefile The shapefile must contain polygons with the integer-type field "marker" """ print('#######################################################') print(' Modifying the boundary markers for grid in folder:') print(' %s' % suntanspath) # Load the grid into an object grd = sunpy.Grid(suntanspath) # Find the edge points xe = np.mean(grd.xp[grd.edges], axis=1) ye = np.mean(grd.yp[grd.edges], axis=1) # Read the shapefile if not bcfile == None: XY, newmarker = readShpPoly(bcfile, FIELDNAME='marker') if len(XY) < 1: print( 'Error - could not find any polygons with the field name "marker" in shapefile: %s' % bcfile) return XY, edge_id = readShpPoly(bcfile, FIELDNAME='edge_id') if len(XY) < 1: print( 'Error - could not find any polygons with the field name "edge_id" in shapefile: %s' % bcfile) return else: XY = [] newmarker = [] edge_id = [] # Plot before updates #plt.figure() #grd.plotBC() #plt.plot(XY[0][:,0],XY[0][:,1],'m',linewidth=2) #plt.show() # Reset all markers to one (closed) ind0 = grd.mark > 0 grd.mark[ind0] = 1 # Find the points inside each of the polygon and assign new bc grd.edge_id = grd.mark * 0 # Flag to identify linked edges/segments (marker=4 only) for xpoly, bctype, segmentID in zip(XY, newmarker, edge_id): ind0 = grd.mark > 0 edges = np.asarray([xe[ind0], ye[ind0]]) mark = grd.mark[ind0] #ind1 = nxutils.points_inside_poly(edges.T,xpoly) ind1 = inpolygon(edges.T, xpoly) if bctype == 4: eflag = grd.edge_id[ind0] eflag[ind1] = segmentID grd.edge_id[ind0] = eflag bctype = 2 mark[ind1] = bctype grd.mark[ind0] = mark # Save the new markers to edges.dat edgefile = suntanspath + '/edges.dat' grd.saveEdges(edgefile) print('Updated markers written to: %s' % (edgefile)) # Plot the markers if saveplot: plt.figure() grd.plotBC() if len(XY) > 0: plt.plot(XY[0][:, 0], XY[0][:, 1], 'm', linewidth=2) figfile = suntanspath + '/BoundaryMarkerTypes.pdf' plt.savefig(figfile) print('Marker plot saved to: %s' % (figfile)) print('Done.') print('#######################################################')
""" Test the GDAL map packages on some data """ from sfoda.utils.maptools import readShpPoly datafile = '/home/suntans/Projects/testdata/suntans_bc_markers_type2.shp' print('Reading file: ', datafile) data = readShpPoly(datafile) print(data) print('Done')
def create_gmsh_geo(shpfile, scalefile, geofile, startpoly=0, ndmin=8, scalefac=1.0,\ r=1.08, lcmax=2000.0, sigmoid=0,\ linetype='BSpline'): """ Generate a gmsh *.geo file using a boundary from a shpfile Inputs: --- - shpfile : a polygon shapefile with the domain boundaries. Make sure that the first polygon is the outer ring. If not change 'startpoly' parameter. - scalefile : a line shapefile with field 'scale' specifying the target grid resolution for that region. - geofile: output geo ascii file. *Optional* - startpoly [default=0] - the index of the outer polygon in the shapefile. - ndmin [default=8] - the minimum range of the scale = ndmin*scale - r : expansion factor - lcmax [default=2000] - the maximum grid cell size. - sigmoid [default=0] - linetype - 'BSpline' or 'Line' """ # Load the polygon shape file xy, field = readShpPoly(shpfile, FIELDNAME='FID') # Load the scale shape file xyscale, scale = readShpPointLine(scalefile, FIELDNAME='scale') # Load the 'embed' flag to see if the scale layer should be embedded #try: # exyscale,embed = readShpPointLine(scalefile,FIELDNAME='embed') #except: # print 'Warning - could not find "embed" field in shapefile. Setting embed = 0.' # embed = [ss*0 for ss in scale] exyscale, embed = readShpPointLine(scalefile, FIELDNAME='embed') if embed == []: embed = [ss * 0 for ss in scale] ## output geo and svg file fgeo = open(geofile, 'w') fgeo.write("""IP = newp; IL = newl; IS = news; IF = newf; """) ip = 0 # Point counter il = 0 # Line counter rp = 0 lines = [] for loop in xy: firstp = ip for p in range(loop.shape[0]): rp = rp + 1 fgeo.write("Point(IP + %i) = {%.16e, %.16e, %.16e}; // %i\n" % (ip, loop[p, 0], loop[p, 1], 0., rp - 1)) ip = ip + 1 if linetype == 'Line' and ip > 1: fgeo.write("Line(IL + %i) = {IP + %i , IP + %i};\n" % \ (il, ip-2, ip-1)) il = il + 1 lines.append(il - 1) if linetype == 'BSpline': fgeo.write("BSpline(IL + %i) = {IP + %i : IP + %i, IP + %i};\n" % \ (il, firstp, ip - 1, firstp)) il = il + 1 lines.append(il - 1) # Create the surface polygon fgeo.write('\n//%s\n//Surface Polygon Definition\n//%s\n\n' % (72 * '#', 72 * '#')) surfstart = il fgeo.write("Line Loop(IL + %i) = {IL + %s};\n" % (il, startpoly)) il += 1 for ll in lines: if ll != startpoly: fgeo.write("Line Loop(IL + %i) = {IL + %s};\n" % (il, ll)) il += 1 surfend = il - 1 fgeo.write("Plane Surface(IL + %i) = {IL + %i : IL + %i};\n" % (il, surfstart, surfend)) fgeo.write('Physical Surface("Ocean") = {IL + %i};\n' % il) surface_id = il # Keep this to embed lines into il += 1 # Create the grid scale lines and fields fgeo.write('\n//%s\n//Grid Scale Definition\n//%s\n\n' % (72 * '#', 72 * '#')) slines = [] # Reference to scale lines for loop, ss, ee in zip(xyscale, scale, embed): firstp = ip ss *= scalefac # Applies scale factor for p in range(loop.shape[0]): rp = rp + 1 #fgeo.write("Point(IP + %i) = {%.16e, %.16e, %.16e}; // %i\n" % (ip, loop[p,0], loop[p,1], 0., rp -1)) fgeo.write( "Point(IP + %i) = {%.16e, %.16e, %.16e,%.16e}; // %i\n" % (ip, loop[p, 0], loop[p, 1], 0., rp - 1, float(ss))) ip = ip + 1 if ee: #fgeo.write("BSpline(IL + %i) = {IP + %i : IP + %i};\n" % (il, firstp, ip - 1)) fgeo.write("%s(IL + %i) = {IP + %i : IP + %i};\n" % (linetpye, il, firstp, ip - 1)) # Embed this line in the main surface so that cells are aligned fgeo.write("Line{IL + %i} In Surface{IL + %i};\n" % (il, surface_id)) else: # Don't embed (can set as BSpline) fgeo.write("%s(IL + %i) = {IP + %i : IP + %i};\n" % (linetype, il, firstp, ip - 1)) slines.append(il) il = il + 1 ifield = 0 # Field counter fids = [] ii = 0 for ss, line in zip(scale, slines): fgeo.write("Field[IF + %i] = Attractor;\n" % ifield) fgeo.write("Field[IF + %i].EdgesList = {IL + %i};\n" % (ifield, line)) nodesperedge = get_nnodes_from_line(xyscale[ii], 2.0 * float(ss)) fgeo.write("Field[IF + %i].NNodesByEdge = %i;\n" % (ifield, nodesperedge)) ifield += 1 fgeo.write("Field[IF + %i] = Threshold;\n" % ifield) # Find the maximum distance Nk = np.log(lcmax / ss) / np.log(r) print(ss, Nk) lmin = float(ndmin) * float(ss) lmax = lmin + Nk * ss fgeo.write("Field[IF + %i].DistMax = %6.2f;\n" % (ifield, lmax)) fgeo.write("Field[IF + %i].DistMin = %6.2f;\n" % (ifield, lmin)) fgeo.write("Field[IF + %i].IField = IF + %i;\n" % (ifield, ifield - 1)) fgeo.write("Field[IF + %i].LcMax = %6.2f;\n" % (ifield, lcmax)) fgeo.write("Field[IF + %i].LcMin = %6.2f;\n" % (ifield, float(ss))) fgeo.write("Field[IF + %i].Sigmoid = %d;\n" % (ifield, sigmoid)) fids.append(ifield) ifield += 1 ii += 1 fieldlist = '{' for ff in fids: fieldlist += 'IF + %d, ' % ff fieldlist = fieldlist[:-2] + '}' fgeo.write("Field[IF + %i] = Min;\n" % ifield) fgeo.write("Field[IF + %i].FieldsList = %s;\n" % (ifield, fieldlist)) fgeo.write("Background Field = IF + %i;\n" % ifield) # Set Quad options by default fgeo.write("Mesh.CharacteristicLengthMax=%.16e;//Max cell size\n" % lcmax) fgeo.write("Mesh.RecombineAll=0;//recombine all defined surfaces\n") fgeo.write("Mesh.Algorithm=6;//front\n") fgeo.write("Mesh.Smoothing=10;//10 smoothing steps\n") fgeo.write("Mesh.Remove4Triangles = 1;\n") fgeo.close() print('Complete. GMSH geo file written to:\n\t %s' % geofile)