Following on from How can I add points to a LineString in shapely?, I'm hitting a problem where floating point representations mean objects aren't precisely where I expect them be after they are moved using affinity.translate
.
This would be fixed if there was a way of rounding all the coordinates to the nearest cm (or other insignificantly-small value).
Does this exist?
For what it's worth, I'm doing all my intersection and union operations first before the translation and that seems to be working.
Answer
Shapely and GEOS cannot reduce precision (floating-point precision problem) but you can use other functions as numpy.round()
or round()
,with the GeoJSON format.
For polygons
from shapely.geometry import shape, mapping
import numpy as np
# one polygon
print poly.wkt
POLYGON ((101.2200527190607 -114.6493019170767, 146.6225142079163 -114.4488495484725, 185.0301801801801 -114.2792792792793, 184.6581081081081 -217.7153153153153, 14.99324324324321 -218.4594594594595, 16.4815315315315 -115.0234234234234, 101.2200527190607 -114.6493019170767))
# convert to GeoJSON format
geojson = mapping(poly)
print geojson
{'type': 'Polygon', 'coordinates': (((101.2200527190607, -114.6493019170767), (146.6225142079163, -114.4488495484725), (185.0301801801801, -114.2792792792793), (184.6581081081081, -217.7153153153153), (14.99324324324321, -218.4594594594595), (16.4815315315315, -115.0234234234234), (101.2200527190607, -114.6493019170767)),)}
geosjson['coordinates'] = np.round(np.array(geosjon['coordinates']),2)
print geosjson
{'type': 'Polygon', 'coordinates': array([[[ 101.22, -114.65],
[ 146.62, -114.45],
[ 185.03, -114.28],
[ 184.66, -217.72],
[ 14.99, -218.46],
[ 16.48, -115.02],
[ 101.22, -114.65]]])}
print shape(geosjson)
POLYGON ((101.22 -114.65, 146.62 -114.45, 185.03 -114.28, 184.66 -217.72, 14.99 -218.46, 16.48 -115.02, 101.22 -114.65))
If you don't want to use Numpy, you can adapt the function def _set_precision(coords, precision)
of the geosjson-precision module
def set_precision(coords, precision):
result = []
try:
return round(coords, int(precision))
except TypeError:
for coord in coords:
result.append(_set_precision(coord, precision))
return result
geojson = mapping(poly)
geosjson['coordinates']= set_precision(geosjson['coordinates'], 2)
print geosjson
{'type': 'Polygon', 'coordinates': [[[101.22, -114.65], [146.62, -114.45], [185.03, -114.28], [184.66, -217.72], [14.99, -218.46], [16.48, -115.02], [101.22, -114.65]]]}
print shape(geosjson)
POLYGON ((101.22 -114.65, 146.62 -114.45, 185.03 -114.28, 184.66 -217.72, 14.99 -218.46, 16.48 -115.02, 101.22 -114.65))
No comments:
Post a Comment