I have a shapefile, which I converted into GeoPandas DataFrame. I would like to round the coordinates to 5 decimals.
Is there a method/function in GeoPandas that can do this?
My shapefile contains MultiPolygons.
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It only takes a minute to sign up.
Sign up to join this communityI have a shapefile, which I converted into GeoPandas DataFrame. I would like to round the coordinates to 5 decimals.
Is there a method/function in GeoPandas that can do this?
My shapefile contains MultiPolygons.
You can use the regex module to find the coordinates in a wkt representation of the geometries, round and load back:
import geopandas as gpd
from shapely.wkt import loads
import re
simpledec = re.compile(r"\d*\.\d+")
def mround(match):
return "{:.5f}".format(float(match.group()))
shapefile = '/home/bera/GIS/data/test/polys.shp'
df = gpd.read_file(shapefile)
df.geometry = df.geometry.apply(lambda x: loads(re.sub(simpledec, mround, x.wkt)))
df.to_file('/home/bera/GIS/data/test/polys_round.shp')
See: Rounding using regular expressions
Or try this: Is it possible to round all coordinates in shapely?
I recommend researching topojson and mapshaper as these tools were created to intelligently simplify shapes, preserving topology. Both tools are written in javascript. Mapshaper has a precision option for the output. You can run Mapshaper through a website, mapshaper.org or download the command line tools.
Here's a solution which rounds the numbers directly without relying on regex. Built off of this one: https://gis.stackexchange.com/a/432720. The shapely.ops.transform
function ensures it always works on all geometry types.
from shapely.ops import transform
def round_coordinates(geom, ndigits=2):
def _round_coords(x, y, z=None):
x = round(x, ndigits)
y = round(y, ndigits)
if z is not None:
z = round(x, ndigits)
return (x,y,z)
else:
return (x,y)
return transform(_round_coords, geom)
import geopandas as gpd
from shapely.geometry import Point
point_geoms = [Point(10.1234567, 20.1234567), Point(30.5123456, 40.59876543)]
gdf = gpd.GeoDataFrame({'id':[1,2]}, geometry=gpd.GeoSeries(point_geoms))
gdf['geometry'] = gdf.geometry.apply(round_coordinates, ndigits=1)
gdf.to_wkt()
I encountered a similar issue and searching for a solution! How can I round the coordinates of the "SHAPE" column in an SDF created with pandas.DataFrame.spatial
? The "round function would not work against "SHAPE" because it is not a number.
import pandas as pd
df = pd.DataFrame.spatial.from_featureclass("c:\\test.gdb\testFeatureClass")
df.round({"SHAPE": 5}) # TypeError: unsupported operand type(s) for *: 'Polyline' and 'float'
I am trying to use "merge" operation on 2 sdf to identify changes made in geometry. However, I found that "identical" feature from gdb and agol has tinny difference in coordinates (9th or 10th decimal in feet). I am thinking to use round the decimal of coordinates to 7 or 8 place.
I am not an expert. But the code below does the job for me. Consider 'gdf' is a geopandas dataframe.
gdf_rounded = gdf.__round__(5)
gdf_rounded = gdf.round(5)
Rounds the coordinates to 5 decimal places
__round__
worked in my case, as per a different answer here. My geodataframe in this case has only a geometry column, but it dud reduce the coordinate precision properly