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?

Asked By: Mark K

||

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])
Answered By: ffrosch
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.