GeospatialPython / pyshp

This library reads and writes ESRI Shapefiles in pure Python.
MIT License
1.09k stars 259 forks source link

Enhance combination with shapely #249

Open forestbat opened 1 year ago

forestbat commented 1 year ago

When I try to calculate something such as distance between geometries, I will use shapely however shapely's geometry is not hashable,so I must use shapely's wkt such as: dict[key] = shapely_geometry.wkt WKT is string, however, shapely's wkt probably occurs integer such as: 'LINESTRING (121 43.422917……121.047917 43.460417)' And if I try to convert geometries of pyshp to wkt with my code:

def shape_type_to_wkt(shape: Shape):
    geo_shpfile = shape.__geo_interface__
    geo_class = geo_shpfile['type'].upper()
    wkt: str = geo_class + ' ('
    geo_coords = []
    if geo_class == 'POINT':
        geo_coords.append(geo_shpfile['coordinates'])
    else:
        geo_coords = list(geo_shpfile['coordinates'])
    for coord_tuple in geo_coords:
        wkt += str(coord_tuple[0])
        wkt += ' '
        wkt += str(coord_tuple[1])
        wkt += ', '
    wkt = wkt.rstrip(', ')
    wkt += ')'
    return wkt

WKT generated from this method will occurs float64'LINESTRING (121.0 43.422917……121.047917 43.460417)' This brings me some trouble,I must use shape_type_to_wkt(shapely.loads(nearest_line.wkt)) to convert probable integer to float in shapely's wkt. Above code is my business code and I only tested it in 2-dimensions qgis layer which only has Point and LineString, so I hope you can enchance combination for pyshp and shapely, don't let this irritating problem to occur.

Contributions

karimbahgat commented 1 year ago

I'm not sure I fully understand your problem. You're saying shapely's wkt method encodes integer coordinates without decimals, while your own pyshp wkt function will represent those integers with decimals. Why is this a problem? If you really need them to produce the same exact wkt, adding a Python check for .isinteger() in your function should fix this. And what are suggesting pyshp is doing wrong or could be doing to fix this problem?

I have considered the benefit of having a wkt property for pyshp if that's what you're suggesting, so would happily accept PRs for this.

As for interoperability with shapely, this can easily be done with geojson dicts or strings (which should be hashable):

# from shapely to geojson to pyshp
geoj = shapely_obj.__geo_interface__
writer.shape(geoj) # this is the pyshp writer which accepts writing shapes from geojson dicts

# from pyshp to geojson to shapely
geoj = pyshp_shape.__geo_interface__
pyshp_obj = shapely.geometry.shape(geoj)

But maybe I'm missing something.

forestbat commented 1 year ago
# from shapely to geojson to pyshp
geoj = shapely_obj.__geo_interface__
writer.shape(geoj) # this is the pyshp writer which accepts writing shapes from geojson dicts

# from pyshp to geojson to shapely
geoj = pyshp_shape.__geo_interface__
pyshp_obj = shapely.geometry.shape(geoj)

Thanks for your code. And yes,I hope pyshp can have a wkt property.