ShapelyDeprecationWarnings and the use of "geoms"
Question:
Some lines to look up geographical information by given pair of coordinates, referenced from https://gis.stackexchange.com/questions/254869/projecting-google-maps-coordinate-to-lookup-country-in-shapefile.
import geopandas as gpd
from shapely.geometry import Point
pt = Point(8.7333333, 53.1333333)
# countries shapefile from
# http://thematicmapping.org/downloads/world_borders.php
folder = 'C:\My Documents\'
data = gpd.read_file(folder + 'TM_WORLD_BORDERS-0.3.shp')
for index, row in data.iterrows():
poly = row['geometry']
if poly.contains(pt):
print (row)
# ---------- Print out as -----------------------------------
FIPS GM
ISO2 DE
ISO3 DEU
UN 276
NAME Germany
AREA 34895
POP2005 82652369
REGION 150
SUBREGION 155
LON 9.851
LAT 51.11
geometry (POLYGON ((8.710255000000018 47.69680799999997...
Name: 71, dtype: object
It works but prints out paragraphs of ShapelyDeprecationWarnings:
C:Python38libsite-packagespandascoredtypesinference.py:384: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the `geoms` property to access the constituent parts of a multi-part geometry.
iter(obj) # Can iterate over it.
C:Python38libsite-packagespandascoredtypesinference.py:385: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
len(obj) # Has a length associated with it.
C:Python38libsite-packagespandasioformatsprinting.py:120: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the `geoms` property to access the constituent parts of a multi-part geometry.
s = iter(seq)
C:Python38libsite-packagespandasioformatsprinting.py:124: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
for i in range(min(nitems, len(seq)))
C:Python38libsite-packagespandasioformatsprinting.py:128: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
if nitems < len(seq):
To update the above code to avoid ShapelyDeprecationWarnings, I’ve tried to replace "for index, row in data.iterrows()" to "for index, row in data.geoms", and "poly = row[‘geometry’]" to "poly = row.geoms". Neither worked.
What’s the right way to update the code to avoid ShapelyDeprecationWarnings?
Answers:
Let’s start by examining the geometry column with data.geometry
. This reveals that the geometry contains normal polygons and multipolygons.
0 MULTIPOLYGON (((-61.68667 17.02444, -61.88722 ...
1 POLYGON ((2.96361 36.80222, 4.78583 36.89472, ...
...
New answer
The error is only caused by Geopandas doing some operations on the row when we are trying to print it. A row is a pandas.Series
object.
Simple solution is to temporarily drop the geometry column from the dataframe, before we retrieve a single row for printing.
for index, row in data.iterrows():
poly = row['geometry']
if poly.contains(pt):
print(data.drop(columns='geometry')
.iloc[[row.name]]
.iloc[0])
Old answer
The geoms
property only exists on MULTIPOLYGONS.
Thus you have to adjust your code to deal with this accordingly:
for index, row in data.iterrows():
results = []
if hasattr(row.geometry, "geoms"):
for part in row.geometry.geoms:
if part.contains(pt):
results.append(row)
elif row.geometry.contains(pt):
results.append(row)
else:
pass
for row in results:
print(data.drop(columns='geometry').iloc[[row.name]].iloc[0])
Some lines to look up geographical information by given pair of coordinates, referenced from https://gis.stackexchange.com/questions/254869/projecting-google-maps-coordinate-to-lookup-country-in-shapefile.
import geopandas as gpd
from shapely.geometry import Point
pt = Point(8.7333333, 53.1333333)
# countries shapefile from
# http://thematicmapping.org/downloads/world_borders.php
folder = 'C:\My Documents\'
data = gpd.read_file(folder + 'TM_WORLD_BORDERS-0.3.shp')
for index, row in data.iterrows():
poly = row['geometry']
if poly.contains(pt):
print (row)
# ---------- Print out as -----------------------------------
FIPS GM
ISO2 DE
ISO3 DEU
UN 276
NAME Germany
AREA 34895
POP2005 82652369
REGION 150
SUBREGION 155
LON 9.851
LAT 51.11
geometry (POLYGON ((8.710255000000018 47.69680799999997...
Name: 71, dtype: object
It works but prints out paragraphs of ShapelyDeprecationWarnings:
C:Python38libsite-packagespandascoredtypesinference.py:384: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the `geoms` property to access the constituent parts of a multi-part geometry.
iter(obj) # Can iterate over it.
C:Python38libsite-packagespandascoredtypesinference.py:385: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
len(obj) # Has a length associated with it.
C:Python38libsite-packagespandasioformatsprinting.py:120: ShapelyDeprecationWarning: Iteration over multi-part geometries is deprecated and will be removed in Shapely 2.0. Use the `geoms` property to access the constituent parts of a multi-part geometry.
s = iter(seq)
C:Python38libsite-packagespandasioformatsprinting.py:124: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
for i in range(min(nitems, len(seq)))
C:Python38libsite-packagespandasioformatsprinting.py:128: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the number of parts of a multi-part geometry.
if nitems < len(seq):
To update the above code to avoid ShapelyDeprecationWarnings, I’ve tried to replace "for index, row in data.iterrows()" to "for index, row in data.geoms", and "poly = row[‘geometry’]" to "poly = row.geoms". Neither worked.
What’s the right way to update the code to avoid ShapelyDeprecationWarnings?
Let’s start by examining the geometry column with data.geometry
. This reveals that the geometry contains normal polygons and multipolygons.
0 MULTIPOLYGON (((-61.68667 17.02444, -61.88722 ...
1 POLYGON ((2.96361 36.80222, 4.78583 36.89472, ...
...
New answer
The error is only caused by Geopandas doing some operations on the row when we are trying to print it. A row is a pandas.Series
object.
Simple solution is to temporarily drop the geometry column from the dataframe, before we retrieve a single row for printing.
for index, row in data.iterrows():
poly = row['geometry']
if poly.contains(pt):
print(data.drop(columns='geometry')
.iloc[[row.name]]
.iloc[0])
Old answer
The geoms
property only exists on MULTIPOLYGONS.
Thus you have to adjust your code to deal with this accordingly:
for index, row in data.iterrows():
results = []
if hasattr(row.geometry, "geoms"):
for part in row.geometry.geoms:
if part.contains(pt):
results.append(row)
elif row.geometry.contains(pt):
results.append(row)
else:
pass
for row in results:
print(data.drop(columns='geometry').iloc[[row.name]].iloc[0])