diff --git a/include/geos/geom/prep/PreparedPolygon.h b/include/geos/geom/prep/PreparedPolygon.h index 112fa90a95..a2feee6c91 100644 --- a/include/geos/geom/prep/PreparedPolygon.h +++ b/include/geos/geom/prep/PreparedPolygon.h @@ -53,6 +53,7 @@ class PreparedPolygon : public BasicPreparedGeometry { bool isRectangle; mutable std::unique_ptr segIntFinder; mutable std::unique_ptr ptOnGeomLoc; + mutable std::unique_ptr indexedPtOnGeomLoc; mutable noding::SegmentString::ConstVect segStrings; mutable std::unique_ptr indexedDistance; diff --git a/src/geom/prep/PreparedPolygon.cpp b/src/geom/prep/PreparedPolygon.cpp index 669237ebed..332c4798e3 100644 --- a/src/geom/prep/PreparedPolygon.cpp +++ b/src/geom/prep/PreparedPolygon.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // std #include @@ -68,11 +69,18 @@ algorithm::locate::PointOnGeometryLocator* PreparedPolygon:: getPointLocator() const { + // If we are only going to locate a single point, it's faster to do a brute-force SimplePointInAreaLocator + // instead of an IndexedPointInAreaLocator. There's a reasonable chance we will only use this locator + // once (for example, if we get here through Geometry::intersects). So we create a simple locator for the + // first usage and switch to an indexed locator when it is clear we're in a multiple-use scenario. if(! ptOnGeomLoc) { - ptOnGeomLoc.reset(new algorithm::locate::IndexedPointInAreaLocator(getGeometry())); + ptOnGeomLoc = detail::make_unique(&getGeometry()); + return ptOnGeomLoc.get(); + } else if (!indexedPtOnGeomLoc) { + indexedPtOnGeomLoc = detail::make_unique(getGeometry()); } - return ptOnGeomLoc.get(); + return indexedPtOnGeomLoc.get(); } bool