Example #1
0
def process_layer(orig_layer,output_name,tolerance=0.0,
                  create_polygons=False,close_arc=False,
                  single_feature=True,
                  remove_duplicates=True):
    """
    remove_duplicates: if true, exactly duplicated nodes along a single path will be removed, i.e.
      the linestring A-B-B-C will become A-B-C.
    single_feature: only save the biggest feature
    """
    ### The actual geometry processing: ###
    ### <processing>
    new_features = merge_lines(orig_layer)

    if remove_duplicates:
        print "Checking the merged features for duplicate points"
        # possibly important here to have the duplicate test more stringent than
        # the tolerant_merge_lines.
        # also have to be careful about a string of points closely spaced - don't
        # want to remove all of them, just enough to keep the minimal spacing above
        # tolerance.
        short_tol = 0.5*tolerance
        
        for fi in range(len(new_features)):
            pnts = new_features[fi]
            valid = ones( len(pnts), 'bool8')
            # go with a slower but safer loop here -
            last_valid=0
            for i in range(1,len(pnts)):
                if vector_mag( pnts[last_valid]-pnts[i] ) < short_tol:
                    if i==len(pnts)-1:
                        # special case to avoid moving the last vertex
                        valid[last_valid] = False
                        last_valid = i
                    else:
                        valid[i] = False
                else:
                    last_valid = i
            
            # print "Ring %d: # invalid=%d / %d"%(i,sum(~valid),len(new_features[i]))
            new_features[fi] = new_features[fi][valid,:]

    if tolerance > 0.0:
        new_features = tolerant_merge_lines(new_features,tolerance)

    ### </processing>
    
    ### <output>
    if create_polygons:
        geoms = lines_to_polygons(new_features,close_arc=close_arc,single_feature=single_feature)
    else:
        # Line output
        geoms = [shapely.geometry.LineString(pnts) for pnts in new_features]

    # Write it all out to a shapefile:
    progress_message("Writing output")

    wkb2shp.wkb2shp(output_name,geoms,
                    overwrite=True)

    return output_name
Example #2
0
def clean_degenerate_rings(point_lists,degen_shpname='degenerate_rings.shp'):
    """ Given a list of lists of points - filter out point lists
    which represent degenerate rings, writing the invalid rings
    to a shapefile degen_shpname, and returning a list of only
    the valid rings.  Unclosed linestrings are passed through.

    set degen_shpname to None to disable that output.
    """
    degen_lines = []
    valid_lists = []
    for i in range(len(point_lists)):
        point_list = point_lists[i]
        if all(point_list[0]!=point_list[-1]):
            valid_lists.append(point_list)
        else: # closed - check it's area
            poly = shapely.geometry.Polygon(point_list)
	    try:
		a = poly.area
                valid_lists.append(point_list)
            except ValueError:
		print "degenerate feature",i# ,point_list
                degen_line = shapely.geometry.LineString(point_list)
		degen_lines.append(degen_line)

    if degen_shpname is not None and len(degen_lines)>0:
        wkb2shp.wkb2shp(degen_shpname,degen_lines,srs_text='EPSG:26910',overwrite=True)

    return valid_lists
Example #3
0
def clean_degenerate_rings(point_lists, degen_shpname='degenerate_rings.shp'):
    """ Given a list of lists of points - filter out point lists
    which represent degenerate rings, writing the invalid rings
    to a shapefile degen_shpname, and returning a list of only
    the valid rings.  Unclosed linestrings are passed through.

    set degen_shpname to None to disable that output.
    """
    degen_lines = []
    valid_lists = []
    for i in range(len(point_lists)):
        point_list = point_lists[i]
        if all(point_list[0] != point_list[-1]):
            valid_lists.append(point_list)
        else:  # closed - check it's area
            poly = shapely.geometry.Polygon(point_list)
            try:
                a = poly.area
                valid_lists.append(point_list)
            except ValueError:
                print "degenerate feature", i  # ,point_list
                degen_line = shapely.geometry.LineString(point_list)
                degen_lines.append(degen_line)

    if degen_shpname is not None and len(degen_lines) > 0:
        wkb2shp.wkb2shp(degen_shpname,
                        degen_lines,
                        srs_text='EPSG:26910',
                        overwrite=True)

    return valid_lists
Example #4
0
# make an island by masking a few triangles
island = ((mt.x[mt.triangles].mean(axis=1) - 0.75)**2 +
          (mt.y[mt.triangles].mean(axis=1) - 0.75)**2) < 0.03
mt.set_mask(island)

import pylab
pylab.figure()
contour = tri.tricontourf(pylab.gca(), mt, point_vals)
pylab.axis('equal')

from shapely import geometry
import wkb2shp

geoms = []
vals = []  # tuples of vmin,vmax

for colli, coll in enumerate(contour.collections):
    vmin, vmax = contour.levels[colli:colli + 2]

    for p in coll.get_paths():
        p.simplify_threshold = 0.0
        polys = p.to_polygons()

        geoms.append(geometry.Polygon(polys[0], polys[1:]))
        vals.append((vmin, vmax))

wkb2shp.wkb2shp("contour-output.shp",
                geoms,
                overwrite=True,
                fields=array(vals, dtype=[('min', float64), ('max', float64)]))
Example #5
0
    # could also do a transect, but we'd have to pick a specific line up of the stations
    import wkb2shp
    from shapely import geometry

    pc = PolarisCruise()
    stations = pc.station_locs_utm()

    geoms = [
        geometry.Point(stations[i, 0], stations[i, 1])
        for i in range(len(stations))
    ]

    i_iter = iter(range(len(stations)))

    def field_gen(g):
        i = i_iter.next()

        s = pc.station_data[i]
        return {
            'name': s['name'],
            'station_no': s['station_no'],
            'depth': s['depth'],
            'source': 'polaris_cruise'
        }

    wkb2shp.wkb2shp(
        '/home/rusty/classes/research/suntans/runs/polaris_points.shp',
        geoms,
        field_gen=field_gen,
        overwrite=True)
Example #6
0

import pylab
pylab.figure()
contour=tri.tricontourf(pylab.gca(),mt , point_vals)
pylab.axis('equal')

from shapely import geometry
import wkb2shp

geoms = []
vals = [] # tuples of vmin,vmax

for colli,coll in enumerate(contour.collections):
    vmin,vmax = contour.levels[colli:colli+2]
    
    for p in coll.get_paths():
        p.simplify_threshold = 0.0
        polys = p.to_polygons()
        
        geoms.append( geometry.Polygon(polys[0],polys[1:] ) )
        vals.append( (vmin,vmax) )

            
            
wkb2shp.wkb2shp("contour-output.shp",
                geoms,
                overwrite=True,
                fields =array( vals, dtype=[('min',float64),
                                            ('max',float64)] ))
Example #7
0
class Tom(object):
    scale_shps = None
    tele_scale_shps = None
    # NB: this is adjusted by scale_factor before being handed to ApolloniusGraph
    effective_tele_rate = 1.1
    boundary_shp = None
    plot_interval = None
    checkpoint_interval = None
    smooth = 1
    resume_checkpoint_fn = None
    verbosity = 1
    dry_run = 0
    optimize = None
    interior_shps = None
    output_shp = None
    slide_interior = 1
    scale_factor = 1.0
    scale_ratio_for_cutoff = 1.0

    # These are not currently mutable from the command line
    # but could be.
    checkpoint_fn = "checkpoint.pav"
    plot_fn = "partial-grid.pdf"
    boundary_poly_shp = "processed-boundary.shp"
    smoothed_poly_shp = "smoothed-shoreline.shp"
    linestring_join_tolerance = 1.0
    scale_shp_field_name = 'scale'
    density_map = None

    # non-customizable instance variables
    original_boundary_geo = None

    def __init__(self):
        self.scale_shps = []
        self.tele_scale_shps = []

    def usage(self):
        print "tom.py   -h                   # show this help message      "
        print "         -b boundary.shp      # boundary shapefile          "
        print "         -i interior.shp      # interior paving guides      "
        print "         --slide-interior     # Allow nodes on interior lines to slide [default]"
        print "         --rigid-interior     # Force nodes on interior lines to stay put"
        print "         -s scale.shp         # scale shapefile             "
        if field.has_apollonius:
            print "         -a telescoping_scale.shp # auto telescoping scale shapefile"
            print "         -t N.NN              # telescoping rate - defaults to 1.1"
        else:
            print "         [DISABLED] -a telescoping_scale.shp"
        print "         -f N.NN              # factor for adjusting scale globally"
        print "         -C N.NN              # smoothing: min number of cells across a channel"
        print "         -p N                 # output interval for plots   "
        print "         -c N                 # checkpoint interval         "
        print "         -d                   # disable smoothing "
        print "         -o                   # enable optimization "
        print "         -r checkpoint.pav    # resume from a checkpoint    "
        print "         -v N                 # set verbosity level N"
        print "         -n                   # ready the shoreline, but don't mesh it"
        print "         -m x1,y1,x2,y2,dx,dy # output raster of scale field"

        print "         -g output.shp        # output shapefile of grid"

        print " boundary.shp: "
        print "   A shapefile containing either lines or a single polygon.  If "
        print "   lines, they must join together within a tolerance of 1.0 units"
        print " scale.shp:"
        print "   A shapefile containing points with a field 'scale', which gives"
        print "   the desired length of the edges in a region."
        print "   If the CGAL-python library is available, multiple shapefiles can "
        print "   be specified, including LineString layers."
        print " interior.shp:"
        print "   A shapefile containg line segments which will be used to guide the orientation of cells"
        print " output interval N: "
        print "   Every N steps of the algorithm create a PDF of the grid so far"
        print " checkpoint interval N:"
        print "   Every N steps of the algorithm make a backup of the grid and all"
        print "   intermediate information"
        print " resume from checkpoint"
        print "   Loads a previously saved checkpoint file and will continue where it"
        print "   left off."
        print " verbosity level N:"
        print "   Defaults to 1, which prints step numbers."
        print "   0: almost silent"
        print "   1: ~1 line per step"
        print "   2: ~30 lines per step"
        print "   3: ~100 lines per step and will try to plot intermediate stages"
        print " raster of scale field: the given region will be rasterized and output to scale-raster.tif"

    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, 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')
Example #8
0
def process_layer(orig_layer,
                  output_name,
                  tolerance=0.0,
                  create_polygons=False,
                  close_arc=False,
                  single_feature=True,
                  remove_duplicates=True):
    """
    remove_duplicates: if true, exactly duplicated nodes along a single path will be removed, i.e.
      the linestring A-B-B-C will become A-B-C.
    single_feature: only save the biggest feature
    """
    ### The actual geometry processing: ###
    ### <processing>
    new_features = merge_lines(orig_layer)

    if remove_duplicates:
        print "Checking the merged features for duplicate points"
        # possibly important here to have the duplicate test more stringent than
        # the tolerant_merge_lines.
        # also have to be careful about a string of points closely spaced - don't
        # want to remove all of them, just enough to keep the minimal spacing above
        # tolerance.
        short_tol = 0.5 * tolerance

        for fi in range(len(new_features)):
            pnts = new_features[fi]
            valid = ones(len(pnts), 'bool8')
            # go with a slower but safer loop here -
            last_valid = 0
            for i in range(1, len(pnts)):
                if vector_mag(pnts[last_valid] - pnts[i]) < short_tol:
                    if i == len(pnts) - 1:
                        # special case to avoid moving the last vertex
                        valid[last_valid] = False
                        last_valid = i
                    else:
                        valid[i] = False
                else:
                    last_valid = i

            # print "Ring %d: # invalid=%d / %d"%(i,sum(~valid),len(new_features[i]))
            new_features[fi] = new_features[fi][valid, :]

    if tolerance > 0.0:
        new_features = tolerant_merge_lines(new_features, tolerance)

    ### </processing>

    ### <output>
    if create_polygons:
        geoms = lines_to_polygons(new_features,
                                  close_arc=close_arc,
                                  single_feature=single_feature)
    else:
        # Line output
        geoms = [shapely.geometry.LineString(pnts) for pnts in new_features]

    # Write it all out to a shapefile:
    progress_message("Writing output")

    wkb2shp.wkb2shp(output_name, geoms, overwrite=True)

    return output_name