Saturday, 19 October 2019

python - Buffer GeoPandas dataframe based on a column value


I have a GeoPandas dataframe with a series of polygons in the geometry column. I also have a bufferdist column for each row containing an integer. The dataframe looks like


    bufferdist  geometry
0 600 POLYGON ((-122.9486846923828 48.65513944114847...
1 300 POLYGON ((-122.8642272949219 48.68053413474483...

How can I buffer each polygon in the dataframe to the distance of the bufferdist column?


I tried this


df['geometry'] = df.buffer(df.bufferdist)


but it returns the stacktrace


ArgumentError                             Traceback (most recent call last)
in ()
----> 1 df['geometry'] = df.buffer(df.bufferdist)

C:\Users\nickp\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\geopandas\base.py in buffer(self, distance, resolution)
298 def buffer(self, distance, resolution=16):
299 return gpd.GeoSeries([geom.buffer(distance, resolution)
--> 300 for geom in self.geometry],

301 index=self.index, crs=self.crs)
302

C:\Users\nickp\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\geopandas\base.py in (.0)
298 def buffer(self, distance, resolution=16):
299 return gpd.GeoSeries([geom.buffer(distance, resolution)
--> 300 for geom in self.geometry],
301 index=self.index, crs=self.crs)
302


C:\Users\nickp\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\shapely\geometry\base.py in buffer(self, distance, resolution, quadsegs, cap_style, join_style, mitre_limit)
582 'Cannot compute offset from zero-length line segment')
583 if cap_style == CAP_STYLE.round and join_style == JOIN_STYLE.round:
--> 584 return geom_factory(self.impl['buffer'](self, distance, res))
585
586 if 'buffer_with_style' not in self.impl:

C:\Users\nickp\AppData\Local\Programs\ArcGIS\Pro\bin\Python\envs\arcgispro-py3\lib\site-packages\shapely\topology.py in __call__(self, this, *args)
76 def __call__(self, this, *args):
77 self._validate(this)

---> 78 return self.fn(this._geom, *args)

ArgumentError: argument 3: : wrong type

I'm sure I'm doing something wrong. Is there a better way?



Answer



Simply apply a function to each row:


# for each row...
def buffer(row):
return row.geometry.buffer(row.bufferid)


import geopandas as gpd
test = gpd.read_file("test_buffer.shp")
test.head(3)
bufferid geometry
0 300 POLYGON ((-0.6927016645326504 0.50320102432778...
1 100 POLYGON ((-0.5211267605633801 0.40332906530089...
2 600 POLYGON ((-0.7208706786171574 0.17285531370038...

# copy of the dataframe

buffered = test.copy()
# apply the function
buffered['geometry'] = buffered.apply(buffer, axis=1)
buffered.head(3)
bufferid geometry
0 300 POLYGON ((-226.0421711994954 198.5375833429314...
1 100 POLYGON ((-87.13968536542335 50.37557441425873...
2 600 POLYGON ((-317.4813433539906 509.7440504871266...

Or with lambda functions



buffered = test.copy()
buffered['geometry'] = buffered.apply(lambda x: x.geometry.buffer(x.bufferid), axis=1)
buffered.head(3)
bufferid geometry
0 300 POLYGON ((-226.0421711994954 198.5375833429314...
1 100 POLYGON ((-87.13968536542335 50.37557441425873...
2 600 POLYGON ((-317.4813433539906 509.7440504871266...

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...