Skip to content

Conversation

@arriopolis
Copy link
Contributor

@arriopolis arriopolis commented Jan 16, 2026

This PR ports this JTS PR to GEOS. It adds a spatial index to the polygonbuilder in overlayNG.

The proposed implementation differs from the JTS implementation, since the latter uses an HPR-tree (Hilbert-packed R-tree) as the spatial filter. The implementation of the HPR-tree has not yet been ported to GEOS, so I'm using an STR-tree here instead. Following the discussion at the JTS PR, the adverse consequences should be insignificant.

The performance improvements are substantial. Similar to this GEOS PR, I benchmarked the code using a difference operation between two MultiPolygons. To simulate real-world data, I used datasets taken from OSM. Specifically, I took the landmass of a region, and subtracted all its rivers and lakes. The resulting runtimes are listed in the table below.

Region No. points object No. points water Old runtime (ms) New runtime (ms)
Zuid Holland 10338 244996 121 119
Netherlands 130042 930803 635 511
Spain 637196 787533 943 707
Germany 264483 2325827 2565 1305
France 653589 3353064 3928 2330
USA 8473315 28684522 508820 24706

All timings have been obtained by taking the average runtime of 5 independent runs. The improvement becomes pretty significant for large objects (~20x improvement for USA), signifying that this PR removes a considerable bottleneck in the old implementation. I also verified that the two implementations produce the same results by comparing the areas of the resulting objects.

@arriopolis arriopolis changed the title added a spatial index to the overlayng polygonbuilder Added a spatial index to the overlayng polygonbuilder Jan 16, 2026
@pramsey pramsey self-requested a review January 16, 2026 20:59
Copy link
Member

@pramsey pramsey left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice contained change. I guess we need a port of HPRtree at some point.

@dr-jts
Copy link
Contributor

dr-jts commented Jan 16, 2026

@arriopolis Nice work!

I guess we need a port of HPRtree at some point.

@pramsey yes indeedy. It might be even more effective in GEOS than JTS, due to advantages of less memory allocation, better locality, and better small-size index handling.

Copy link
Member

@dbaston dbaston left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great!

if (hole->getShell() == nullptr) {
OverlayEdgeRing* shell = hole->findEdgeRingContaining(shells);
// get list of overlapping shells
std::vector<OverlayEdgeRing*> shellListOverlaps;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can move this outside of the for loop and call .clear() inside the for loop to reuse it.

@dbaston dbaston merged commit 3dde4d5 into libgeos:main Jan 17, 2026
30 checks passed
@arriopolis arriopolis deleted the add-spatial-index-polygonbuilder branch January 18, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants