3

I have geopandas with CRS in meters (ITM {'init' :'epsg:2039'}).

I converted the geometry from espg:4326 so I have very high precision which I don't require: POINT (177559.4776412862 594546.4983892406)

How can I truncate the redundant digits after the floating-point? I tried to use:

df.geometry = df.geometry.simplify(0.5) but I get an error:

can't set attribute

  • what if you try df['coord2'] = df['coordinates'].apply(lambda x: np.round(np.array(x),2)? – Taras Sep 19 at 13:14
  • I followed your advice, though I would prefer to avoid using apply... df.geometry.apply(lambda p: sg.Point(np.trunc(p.x),np.trunc(p.y))) – Shakedk Sep 19 at 14:19
  • 1
    look at Rounding all coordinates in shapely? – gene Sep 19 at 15:10
2

The simplify method is meant for simplifying lines or polygons: reducing the number of vertices (thus reducing the number of coordinates, not the precision of each coordinate).
So for points, this has no effect (and even for lines and polygons, it does not do what you are after). The actual error you get is from the fact that you cannot overwrite the geometries using df.geometry =, you need to use the actual column name like df['geometry'] = ... to do that.

Then to come to your actual question: limiting the precision (rounding) the coordinates.

First, in most cases this is not actually a problem to have this precision, but rather it might be a display issue: you prefer to not see those many numbers when looking at the data, as those many decimals are irrelevant?
In that case, there is actually work being done in GeoPandas to do exactly that by default: https://github.com/geopandas/geopandas/pull/1057. You can already do this on individual points when converting to WKT:

>>> import shapely.geometry
>>> p = shapely.geometry.Point(177559.4776412862, 594546.4983892406)
>>> print(p)  
POINT (177559.4776412862 594546.4983892406)

>>> import shapely.wkt
>>> shapely.wkt.dumps(p, rounding_precision=2)
'POINT (177559.48 594546.50)'

If you actually want to round the coordinates: there is no direct way to do this with GeoPandas or Shapely. Some workarounds include getting the coordinates, rounding, and recreating the geometries. Or, outputting to WKT with a given precision, and loading it back, as mentioned in this answer: https://gis.stackexchange.com/a/276512/9828
For points this is still relatively easy:

# with p from above
>>> p_rounded = shapely.geometry.Point(*np.round(np.array(p.coords), 2))
>>> print(p_rounded)
POINT (177559.48 594546.5)

But for (multi)linestrings or (multi)polygons this gets much more complicated, so then the WKT way might be best (although less efficient):

>>> p_rounded = shapely.wkt.loads(shapely.wkt.dumps(p, rounding_precision=2)) 
>>> print(p_rounded)
POINT (177559.48 594546.5)

Both of these approaches could be applied on a full GeoSeries with apply.

But again, in most cases you don't care about those floating points for the actual coordinates (also rounded numbers have them, it is still a floating point), and it is mainly a display issue.

  • Thanks! But apart from display issue, I can also reduce the size of my df if I'm rounding points and using smaller data types, no? – Shakedk Sep 22 at 7:13
  • No, rounding will not change the fact that it are floating point numbers, and those will use the same amount of memory, even when rounded. – joris Sep 23 at 6:51
  • But then I can work with float32 instead of float64 and it reduces the space – Shakedk Sep 23 at 10:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.