Exemple #1
0
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.')
Exemple #2
0
    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.
Exemple #3
0
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.')
Exemple #4
0
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('#######################################################')
Exemple #5
0
"""
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')
Exemple #6
0
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)