Esempio n. 1
0
    def asShape(self):
        """returns geometry as shapefile._Shape() object"""
        shp = shapefile._Shape(shp_helper.shp_dict[self.geometryType.split(
            'Geometry')[1].upper()])
        if self.geometryType != ESRI_POINT:
            shp.points = self.json[JSON_CODE[self.geometryType]]
        else:
            shp.points = [[self.json[X], self.json[Y]]]

        # check if multipart, will need to fix if it is
        if any(isinstance(i, list) for i in shp.points):
            coords = []
            part_indices = [0] + [len(i) for i in iter(shp.points)][:-1]
            ##            for i in shp.points:
            ##                coords.extend(i)
            ##            shp.points = coords
            shp.parts = shapefile._Array('i', part_indices)
        else:
            shp.parts = shapefile._Array('i', [0])

        if shp.shapeType not in (0, 1, 8, 18, 28, 31):
            XMin = min(coords[0] for coords in shp.points)
            YMin = min(coords[1] for coords in shp.points)
            XMax = max(coords[0] for coords in shp.points)
            YMax = max(coords[1] for coords in shp.points)
            shp.bbox = shapefile._Array('d', [XMin, YMin, XMax, YMax])

        return shp
Esempio n. 2
0
def shapely_to_pyshp(shapely_geometry):
    """This function converts a shapely geometry into a geojson and then into a pyshp object.
    Copied from Karim Bahgat's answer at:
     https://gis.stackexchange.com/questions/52705/how-to-write-shapely-geometries-to-shapefiles"""

    # first convert shapely to geojson
    try:
        shapelytogeojson = shapely.geometry.mapping
    except:
        import shapely.geometry
        shapelytogeojson = shapely.geometry.mapping
    geoj = shapelytogeojson(shapely_geometry)

    # create empty pyshp shape
    record = shapefile._Shape()

    # set shapetype
    if geoj["type"] == "Null":
        pyshp_type = 0
    elif geoj["type"] == "Point":
        pyshp_type = 1
    elif geoj["type"] == "LineString":
        pyshp_type = 3
    elif geoj["type"] == "Polygon":
        pyshp_type = 5
    elif geoj["type"] == "MultiPoint":
        pyshp_type = 8
    elif geoj["type"] == "MultiLineString":
        pyshp_type = 3
    elif geoj["type"] == "MultiPolygon":
        pyshp_type = 5

    record.shapeType = pyshp_type

    # set points and parts
    if geoj["type"] == "Point":
        record.points = geoj["coordinates"]
        record.parts = [0]

    elif geoj["type"] in ("MultiPoint", "Linestring"):
        record.points = geoj["coordinates"]
        record.parts = [0]

    elif geoj["type"] in "Polygon":
        record.points = geoj["coordinates"][0]
        record.parts = [0]

    elif geoj["type"] in ("MultiPolygon", "MultiLineString"):
        index = 0
        points = []
        parts = []
        for each_multi in geoj["coordinates"]:
            points.extend(each_multi[0])
            parts.append(index)
            index += len(each_multi[0])

        record.points = points
        record.parts = parts

    return record
Esempio n. 3
0
    def asShape(self):
        """returns geometry as shapefile._Shape() object"""
        shp = shapefile._Shape(shp_helper.shp_dict[self.geometryType.split('Geometry')[1].upper()])
        if self.geometryType != 'esriGeometryPoint':
            shp.points = self.JSON[JSON_CODE[self.geometryType]]
        else:
            shp.points = [[self.JSON['x'], self.JSON['y']]]

        # check if multipart, will need to fix if it is
        if any(isinstance(i, list) for i in shp.points):
            coords = []
            part_indices = [0] + [len(i) for i in iter(shp.points)][:-1]
            for i in shp.points:
                coords.extend(i)
            shp.points = coords
            shp.parts = shapefile._Array('i', part_indices)
        else:
            shp.parts = shapefile._Array('i', [0])

        if shp.shapeType not in (0,1,8,18,28,31):
            XMin = min(coords[0] for coords in shp.points)
            YMin = min(coords[1] for coords in shp.points)
            XMax = max(coords[0] for coords in shp.points)
            YMax = max(coords[1] for coords in shp.points)
            shp.bbox = shapefile._Array('d', [XMin, YMin, XMax, YMax])

        return shp
Esempio n. 4
0
 def geoj2shape(geoj):
     # create empty pyshp shape
     shape = pyshp._Shape()
     # set shapetype
     geojtype = geoj["type"]
     if geojtype == "Null":
         pyshptype = pyshp.NULL
     elif geojtype == "Point":
         pyshptype = pyshp.POINT
     elif geojtype == "LineString":
         pyshptype = pyshp.POLYLINE
     elif geojtype == "Polygon":
         pyshptype = pyshp.POLYGON
     elif geojtype == "MultiPoint":
         pyshptype = pyshp.MULTIPOINT
     elif geojtype == "MultiLineString":
         pyshptype = pyshp.POLYLINE
     elif geojtype == "MultiPolygon":
         pyshptype = pyshp.POLYGON
     shape.shapeType = pyshptype
     
     # set points and parts
     if geojtype == "Point":
         shape.points = [ geoj["coordinates"] ]
         shape.parts = [0]
     elif geojtype in ("MultiPoint","LineString"):
         shape.points = geoj["coordinates"]
         shape.parts = [0]
     elif geojtype in ("Polygon"):
         points = []
         parts = []
         index = 0
         for ext_or_hole in geoj["coordinates"]:
             points.extend(ext_or_hole)
             parts.append(index)
             index += len(ext_or_hole)
         shape.points = points
         shape.parts = parts
     elif geojtype in ("MultiLineString"):
         points = []
         parts = []
         index = 0
         for linestring in geoj["coordinates"]:
             points.extend(linestring)
             parts.append(index)
             index += len(linestring)
         shape.points = points
         shape.parts = parts
     elif geojtype in ("MultiPolygon"):
         points = []
         parts = []
         index = 0
         for polygon in geoj["coordinates"]:
             for ext_or_hole in polygon:
                 points.extend(ext_or_hole)
                 parts.append(index)
                 index += len(ext_or_hole)
         shape.points = points
         shape.parts = parts
     return shape
Esempio n. 5
0
        def geoj2shape(geoj):
            # create empty pyshp shape
            shape = pyshp._Shape()
            # set shapetype
            geojtype = geoj["type"] if geoj else "Null"
            if geojtype == "Null":
                pyshptype = pyshp.NULL
            elif geojtype == "Point":
                pyshptype = pyshp.POINT
            elif geojtype == "LineString":
                pyshptype = pyshp.POLYLINE
            elif geojtype == "Polygon":
                pyshptype = pyshp.POLYGON
            elif geojtype == "MultiPoint":
                pyshptype = pyshp.MULTIPOINT
            elif geojtype == "MultiLineString":
                pyshptype = pyshp.POLYLINE
            elif geojtype == "MultiPolygon":
                pyshptype = pyshp.POLYGON
            shape.shapeType = pyshptype

            # set points and parts
            if geojtype == "Point":
                shape.points = [geoj["coordinates"]]
                shape.parts = [0]
            elif geojtype in ("MultiPoint", "LineString"):
                shape.points = geoj["coordinates"]
                shape.parts = [0]
            elif geojtype in ("Polygon"):
                points = []
                parts = []
                index = 0
                for ext_or_hole in geoj["coordinates"]:
                    points.extend(ext_or_hole)
                    parts.append(index)
                    index += len(ext_or_hole)
                shape.points = points
                shape.parts = parts
            elif geojtype in ("MultiLineString"):
                points = []
                parts = []
                index = 0
                for linestring in geoj["coordinates"]:
                    points.extend(linestring)
                    parts.append(index)
                    index += len(linestring)
                shape.points = points
                shape.parts = parts
            elif geojtype in ("MultiPolygon"):
                points = []
                parts = []
                index = 0
                for polygon in geoj["coordinates"]:
                    for ext_or_hole in polygon:
                        points.extend(ext_or_hole)
                        parts.append(index)
                        index += len(ext_or_hole)
                shape.points = points
                shape.parts = parts
            return shape
def shply_to_shape(shply_obj_list, out_path):
    """
    outpath looks like this out_path = r"../geodata/split_up_poly_circle.shp"
    :param shply_obj_list:
    :param out_path:
    :return:
    """
    pyshp_writer = shapefile.Writer()
    pyshp_writer.field("name")
    if len(shply_obj_list) > 1:
        for feature in shply_obj_list:
            geojson = mapping(feature)

            # create empty pyshp shape
            record = shapefile._Shape()

            # shapeType 3 is Mulitlinestring
            # shapeType 8 is Multipolygon
            # shapeType 5 is Polygon
            record.shapeType = 5
            record.points = geojson["coordinates"][0]
            record.parts = [0]

            pyshp_writer._shapes.append(record)
            # add a list of attributes to go along with the shape
            pyshp_writer.record(["empty record"])
    else:
        geojson = mapping(shply_obj_list[0])
        # create empty pyshp shape
        record = shapefile._Shape()

        # shapeType 3 is Mulitlinestring
        # shapeType 8 is Multipolygon
        # shapeType 5 is Polygon
        record.shapeType = 5
        record.points = geojson["coordinates"][0]
        record.parts = [0]

        pyshp_writer._shapes.append(record)
        # add a list of attributes to go along with the shape
        pyshp_writer.record(["empty record"])

    pyshp_writer.save(out_path)
Esempio n. 7
0
        def geoj2shape(geoj):
            shape = pyshp._Shape()
            geojtype = geoj['type']
            shape.shapeType = geoj2shape_format[geojtype]

            # Set points and parts
            # Points is a list of points, parts is the index of the start of each unique part
            if geojtype == 'Point':
                # Points don't have parts - just a list of coords
                shape.points = [geoj['cordinates']]
                shape.parts = [0]
            elif geojtype in ('MultiPoint', 'LineString'):
                # Either a set of unrelated points or a single line feature - no feature parts
                shape.points = geoj['coordinates']
                shape.parts = [0]
            elif geojtype == 'Polygon':
                # Polygons can have exterior rings and interior holes - parts of a single feature
                points = []
                parts = []
                index = 0
                for ext_or_hole in geoj['coordinates']:
                    # Add the point list
                    points.extend(ext_or_hole)
                    # Track where each part starts in the point list
                    parts.append(index)
                    index += len(ext_or_hole)
                shape.points = points
                shape.parts = parts
            elif geojtype == 'MultiLineString':
                # Multiline string is a line with parts
                points = []
                parts = []
                index = 0
                for linestring in geoj['coordinates']:
                    points.extend(linestring)
                    parts.append(index)
                    index += len(linestring)
                shape.points = points
                shape.parts = parts
            elif geojtype == 'MultiPolygon':
                # Multipolygon is a multi-part polygon - multiple parts, each potentially with their own parts
                points = []
                parts = []
                index = 0
                for Polygon in geoj['coordinates']:
                    for ext_or_hole in polygon:
                        points.extend(ext_or_hole)
                        parts.append(index)
                        index += len(ext_or_hole)
                shape.points = points
                shape.parts = parts
            return shape
Esempio n. 8
0
def shapely_to_pyshp(shapely_geom):
    """ Shapely geometry to pyshp. Code adapted from
    https://gis.stackexchange.com/questions/52705/
    how-to-write-shapely-geometries-to-shapefiles.

    Parameters:
        shapely_geom(shapely.geometry): shapely geometry to convert

    Returns:
        shapefile._Shape

    """
    # first convert shapely to geojson
    geoj = shapely.geometry.mapping(shapely_geom)
    # create empty pyshp shape
    record = shapefile._Shape()
    # set shapetype
    pyshptype = GEOMETRY_TYPE[geoj["type"]]
    record.shapeType = pyshptype
    # set points and parts
    if geoj["type"] == "Point":
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] in ("MultiPoint", "LineString"):
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] == "Polygon":
        index = 0
        points = []
        parts = []
        for eachmulti in geoj["coordinates"]:
            points.extend(eachmulti)
            parts.append(index)
            index += len(eachmulti)
        record.points = points
        record.parts = parts
    elif geoj["type"] in ("MultiPolygon", "MultiLineString"):
        index = 0
        points = []
        parts = []
        for polygon in geoj["coordinates"]:
            for part in polygon:
                points.extend(part)
                parts.append(index)
                index += len(part)
        record.points = points
        record.parts = parts
    return record
Esempio n. 9
0
def shapely_to_pyshp(shapelygeom):
    # first convert shapely to geojson
    try:
        shapelytogeojson = shapely.geometry.mapping
    except:
        import shapely.geometry
        shapelytogeojson = shapely.geometry.mapping
    geoj = shapelytogeojson(shapelygeom)
    # create empty pyshp shape
    record = shapefile._Shape()
    # set shapetype
    if geoj["type"] == "Null":
        pyshptype = 0
    elif geoj["type"] == "Point":
        pyshptype = 1
    elif geoj["type"] == "LineString":
        pyshptype = 3
    elif geoj["type"] == "Polygon":
        pyshptype = 5
    elif geoj["type"] == "MultiPoint":
        pyshptype = 8
    elif geoj["type"] == "MultiLineString":
        pyshptype = 3
    elif geoj["type"] == "MultiPolygon":
        pyshptype = 5
    record.shapeType = pyshptype
    # set points and parts
    if geoj["type"] == "Point":
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] in ("MultiPoint", "Linestring"):
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] in ("Polygon"):
        record.points = geoj["coordinates"][0]
        record.parts = [0]
    elif geoj["type"] in ("MultiPolygon", "MultiLineString"):
        index = 0
        points = []
        parts = []
        for eachmulti in geoj["coordinates"]:
            points.extend(eachmulti[0])
            parts.append(index)
            index += len(eachmulti[0])
        record.points = points
        record.parts = parts
    return record
    roads_intersect = roads_london_shply.intersection(clip_shply)

    # only export linestrings, shapely also created points
    if roads_intersect.geom_type == "LineString":
        roads_clip_list.append(roads_intersect)

# open writer to write our new shapefile too
pyshp_writer = shapefile.Writer()

# create new field
pyshp_writer.field("name")

# convert our shapely geometry back to pyshp, record for record
for feature in roads_clip_list:
    geojson = mapping(feature)

    # create empty pyshp shape
    record = shapefile._Shape()

    # shapeType 3 is linestring
    record.shapeType = 3
    record.points = geojson["coordinates"]
    record.parts = [0]

    pyshp_writer._shapes.append(record)
    # add a list of attributes to go along with the shape
    pyshp_writer.record(["empty record"])

# save to disk
pyshp_writer.save(r"../geodata/roads_clipped2.shp")
    # only export linestrings, shapely also created points
    if roads_intersect.geom_type == "LineString":
        roads_clip_list.append(roads_intersect)

# open writer to write our new shapefile too
pyshp_writer = shapefile.Writer()

# create new field
pyshp_writer.field("name")

# convert our shapely geometry back to pyshp, record for record
for feature in roads_clip_list:
    geojson = mapping(feature)

    # create empty pyshp shape
    record = shapefile._Shape()

    # shapeType 3 is linestring
    record.shapeType = 3
    record.points = geojson["coordinates"]
    record.parts = [0]

    pyshp_writer._shapes.append(record)
    # add a list of attributes to go along with the shape
    pyshp_writer.record(["empty record"])

# save to disk
pyshp_writer.save(r"../geodata/roads_clipped.shp")

# setup matplotlib figure that will display the results
fig = pyplot.figure(1, figsize=SIZE, dpi=90, facecolor="white")
Esempio n. 12
0
def shape_from_pyshp_to_shapely(pyshp_shape, threshold):
    """
     convert pyshp object to shapely object
    :param pyshp_shape: pyshp (shapefile) object
    :return: shapely object if successful, False otherwise
    """

    parts_index = pyshp_shape.parts
    if len(parts_index) < 2:
        # Create a polygon with no holes
        record = Polygon(pyshp_shape.points)
    else:
        # Create a polygon with one or several holes
        seperate_parts = []
        parts_index.append(len(pyshp_shape.points))
        for i in range(0, len(parts_index) - 1):
            points = pyshp_shape.points[parts_index[i]:parts_index[i + 1]]
            seperate_parts.append(points)

        # if list(parts_index)==[0,121,130,135,140]:
        #     debug = 1

        # assuming the first part is exterior
        # exterior = seperate_parts[0]  # assuming the first part is exterior
        # interiors = [seperate_parts[i] for i in range(1,len(seperate_parts))]
        # assuming the last part is exterior
        # exterior = seperate_parts[len(parts_index)-2]
        # interiors = [seperate_parts[i] for i in range(0,len(seperate_parts)-2)]

        all_polygons = []
        length = len(seperate_parts)
        flag = 0
        for i in range(length - 1):
            if len(seperate_parts[flag]) > len(seperate_parts[i + 1]):
                flag = flag
            else:
                flag = i + 1
        threshold = len(seperate_parts[flag]) - 1
        while (len(seperate_parts) > 0):
            print("the first polygon has %d points" % len(seperate_parts[0]))
            #if shapefile.signed_area(seperate_parts[0]) < 0: # the area of  ring is clockwise, it's not a hole
            #if shapefile.signed_area(seperate_parts[0]) > 0:
            if len(seperate_parts[0]) > threshold:
                print("the exterior polygon has %d points" %
                      len(seperate_parts[0]))
                exterior = tuple(seperate_parts[0])
                seperate_parts.remove(seperate_parts[0])

                # find all the holes attach to the first exterior
                interiors = []
                holes_points = []
                for points in seperate_parts:
                    #if shapefile.signed_area(points) >= 0: # the value >= 0 means the ring is counter-clockwise,  then they form a hole
                    if len(points) < threshold:
                        interiors.append(tuple(points))
                        holes_points.append(points)
                # remove the parts which are holes
                for points in holes_points:
                    seperate_parts.remove(points)
                    # else:
                    #     break
                if len(interiors) < 1:
                    interiors = None
                else:
                    interiors = tuple(interiors)
                polygon = Polygon(shell=exterior, holes=interiors)
                all_polygons.append(polygon)
            else:
                seperate_parts.remove(seperate_parts[0])
        if len(all_polygons) > 1:
            record = MultiPolygon(polygons=all_polygons)
        else:
            record = all_polygons[0]
    shapelytogeojson = shapely.geometry.mapping
    geoj = shapelytogeojson(record)
    # create empty pyshp shape
    record = shapefile._Shape()
    record.points = geoj["coordinates"][0]
    record.shapeType = 5
    record.parts = [0]
    # # plot shape for checking
    # from matplotlib import pyplot as plt
    # from descartes import PolygonPatch
    # from math import sqrt
    # # from shapely.geometry import Polygon, LinearRing
    # # from shapely.ops import cascaded_union
    # BLUE = '#6699cc'
    # GRAY = '#999999'
    #
    # # plot these two polygons separately
    # fig = plt.figure(1,  dpi=90) #figsize=SIZE,
    # ax = fig.add_subplot(111)
    # poly1patch = PolygonPatch(record, fc=BLUE, ec=BLUE, alpha=0.5, zorder=2)
    # # poly2patch = PolygonPatch(polygon2, ec=BLUE, alpha=0.5, zorder=2)
    # ax.add_patch(poly1patch)
    # # ax.add_patch(poly2patch)
    # boundary = record.bounds
    # xrange = [boundary[0], boundary[2]]
    # yrange = [boundary[1], boundary[3]]
    # ax.set_xlim(*xrange)
    # # ax.set_xticks(range(*xrange) + [xrange[-1]])
    # ax.set_ylim(*yrange)
    # # ax.set_yticks(range(*yrange) + [yrange[-1]])
    # # ax.set_aspect(1)
    #
    # plt.show()

    return record
def shape_from_shapely_to_pyshp(shapely_shape, keep_holes=True):
    """
    convert shape object in the shapely object to pyshp object (shapefile)
    Note however: the function will NOT handle any interior polygon holes if there are any,
    it simply ignores them.
    :param shapely_shape: the shapely object
    :return: object if successful, False otherwise
    """
    # first convert shapely to geojson
    try:
        shapelytogeojson = shapely.geometry.mapping
    except:
        import shapely.geometry
        shapelytogeojson = shapely.geometry.mapping
    geoj = shapelytogeojson(shapely_shape)
    # create empty pyshp shape
    record = shapefile._Shape()
    # set shapetype
    if geoj["type"] == "Null":
        pyshptype = 0
    elif geoj["type"] == "Point":
        pyshptype = 1
    elif geoj["type"] == "LineString":
        pyshptype = 3
    elif geoj["type"] == "Polygon":
        pyshptype = 5
    elif geoj["type"] == "MultiPoint":
        pyshptype = 8
    elif geoj["type"] == "MultiLineString":
        pyshptype = 3
    elif geoj["type"] == "MultiPolygon":
        pyshptype = 5
    record.shapeType = pyshptype
    # set points and parts
    if geoj["type"] == "Point":
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] in ("MultiPoint", "Linestring"):
        record.points = geoj["coordinates"]
        record.parts = [0]
    elif geoj["type"] in ("Polygon"):
        if keep_holes is False:
            record.points = geoj["coordinates"][0]
            record.parts = [0]
        else:
            # need to consider the holes
            all_coordinates = geoj["coordinates"]
            parts_count = len(all_coordinates)
            # print(parts_count)
            record.parts = []
            for i in range(0, parts_count):
                # record.points = geoj["coordinates"][0]
                record.parts.append(len(record.points))
                record.points.extend(all_coordinates[i])

    elif geoj["type"] in ("MultiPolygon", "MultiLineString"):
        if keep_holes is False:
            index = 0
            points = []
            parts = []
            for eachmulti in geoj["coordinates"]:
                points.extend(eachmulti[0])
                parts.append(index)
                index += len(eachmulti[0])
            record.points = points
            record.parts = parts
        else:
            # need to consider the holes
            all_polygons_coor = geoj["coordinates"]
            polygon_count = len(all_polygons_coor)
            # print(parts_count)
            record.parts = []
            for i in range(0, polygon_count):
                for j in range(0, len(all_polygons_coor[i])):
                    # record.points = geoj["coordinates"][0]
                    record.parts.append(len(record.points))
                    record.points.extend(all_polygons_coor[i][j])

        # index = 0
        # points = []
        # parts = []
        # skip = 1
        # for eachmulti in geoj["coordinates"]:
        #     if skip ==1 :
        #         skip = skip + 1
        #         continue
        #
        #     points.extend(eachmulti[0])
        #     parts.append(index)
        #     index += len(eachmulti[0])
        # record.points = points
        # record.parts = parts
    return record