0

I have a list of named polygons:

import pandas as pd
import geopandas as gp
from shapely.geometry import Polygon
from shapely.geometry import Point
import matplotlib.path as mpltPath
df = gp.GeoDataFrame([['a', Polygon([(1, 0), (1, 1), (2,2), (1,2)])],
                     ['b', Polygon([(1, 1), (2,2), (3,1)])]],
                     columns = ['name','geometry'])
df = gp.GeoDataFrame(df, geometry = 'geometry')

and a list of points:

points = gp.GeoDataFrame( [['box', Point(1.5, 1.75)],
                          ['cone', Point(3.0,2.0)],
                        ['triangle', Point(2.5,1.25)]],
                     columns=['id', 'geometry'], 
                     geometry='geometry')

I am trying to find out what points are in what polygons and add a column to the point dataframe with 'True' or 'False'

I've previously been shown the methods here which show some ways of quickly doing this and have got the script:

point = points['geometry']
path = mpltPath.Path(df['geometry'])
points['inside'] = path.contains_points(point)

but I get the error: float() argument must be a string or a number, not 'Polygon'

How do I fix this?

Alternatively I have been trying this method:

points['inside'] = []
for geo1 in df['geometry']:
    for geo2 in points['geometry']:
        if geo1.contains(geo2):
            points['inside'].append('True')

however here I also get an error: Length of values des not match length of index

Any help with either of these would be greatly appreciated!

tom91
  • 685
  • 7
  • 24

1 Answers1

1

I didn't get the "true/false column", but this should do the job:

points.apply(lambda row: (row['id'], list(map(lambda e: e[0], list(filter(lambda p: p[1].contains(row['geometry']), df.values))))), axis=1)

For each point you get the polygons that contains it, output:

0         (box, [a])
1         (cone, [])
2    (triangle, [b])
dtype: object
  • Thank you for this. The 'True, False column' would basically be a column that is added to the points dataframe that would have true next to a point if it fell within either polygon a or b. This is because in the actual data set I have 1000s of points to check within 100s of polygons and don't want to be adding a column manually – tom91 Nov 21 '18 at 15:37
  • 1
    Oh, got it. Then this: `points['inside'] = points.geometry.map(lambda x: True if reduce(lambda a,b: a+b, list(map(lambda p: p.contains(x), df.geometry.values))) else False)` – Federico Pucci Nov 21 '18 at 15:49