Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Faster way of polygon intersection with shapely

I have a large number of polygons (~100000) and try to find a smart way of calculating their intersecting area with a regular grid cells.

Currently, I am creating the polygons and the grid cells using shapely (based on their corner coordinates). Then, using a simple for-loop I go through each polygon and compare it to nearby grid cells.

Just a small example to illustrate the polygons/grid cells.

from shapely.geometry import box, Polygon # Example polygon  xy = [[130.21001, 27.200001], [129.52, 27.34], [129.45, 27.1], [130.13, 26.950001]] polygon_shape = Polygon(xy) # Example grid cell gridcell_shape = box(129.5, -27.0, 129.75, 27.25) # The intersection polygon_shape.intersection(gridcell_shape).area 

(BTW: the grid cells have the dimensions 0.25x0.25 and the polygons 1x1 at max)

Actually this is quite fast for an individual polygon/grid cell combo with around 0.003 seconds. However, running this code on a huge amount of polygons (each one could intersect dozens of grid cells) takes around 15+ minutes (up to 30+ min depending on the number of intersecting grid cells) on my machine which is not acceptable. Unfortunately, I have no idea how it is possible to write a code for polygon intersection to get the area of overlap. Do you have any tips? Is there an alternative to shapely?

like image 913
HyperCube Avatar asked Feb 04 '13 23:02

HyperCube


People also ask

How do you find where two polygons intersect?

Compute the center of mass for each polygon. Compute the min or max or average distance from each point of the polygon to the center of mass. If C1C2 (where C1/2 is the center of the first/second polygon) >= D1 + D2 (where D1/2 is the distance you computed for first/second polygon) then the two polygons "intersect".

How do you check if a line intersects a polygon?

Line crosses the polygon if and only if it crosses one of its edges (ignoring for a second the cases when it passes through a vertex). So, in your case you just need to test all edges of your polygon against your line and see if there's an intersection. and then calculate the value Ax + By + C for points a and b .

How do you check if two polygons overlap in Python?

You can use the GDAL/OGR Python bindings for that. It returns None if they don't intersect. If they intersect it returns the geometry were both intersect. Also you can find further infos in the GDAL/OGR Cookbook .

Is Point in polygon shapely?

There are basically two ways of conducting Point in Polygon queries in Shapely: using a function called . within() that checks if a point is within a polygon. using a function called .


1 Answers

Consider using Rtree to help identify which grid cells that a polygon may intersect. This way, you can remove the for loop used with the array of lat/lons, which is probably the slow part.

Structure your code something like this:

from shapely.ops import cascaded_union from rtree import index idx = index.Index()  # Populate R-tree index with bounds of grid cells for pos, cell in enumerate(grid_cells):     # assuming cell is a shapely object     idx.insert(pos, cell.bounds)  # Loop through each Shapely polygon for poly in polygons:     # Merge cells that have overlapping bounding boxes     merged_cells = cascaded_union([grid_cells[pos] for pos in idx.intersection(poly.bounds)])     # Now do actual intersection     print(poly.intersection(merged_cells).area) 
like image 185
Mike T Avatar answered Sep 16 '22 12:09

Mike T