From f35ff6d19c8de0f4a2dbd0d44a03f01346b0216e Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 21 Sep 2022 21:03:28 -0400 Subject: [PATCH 1/2] Avoid copying test geometry in PreparedPolygonIntersects The const_cast is not pretty but it is the best that can be done with the current SegmentString API. --- include/geos/noding/SegmentStringUtil.h | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/include/geos/noding/SegmentStringUtil.h b/include/geos/noding/SegmentStringUtil.h index c630839187..b780a8f578 100644 --- a/include/geos/noding/SegmentStringUtil.h +++ b/include/geos/noding/SegmentStringUtil.h @@ -19,6 +19,7 @@ #pragma once +#include #include #include #include @@ -53,15 +54,9 @@ class SegmentStringUtil { geom::LineString::ConstVect lines; geom::util::LinearComponentExtracter::getLines(*g, lines); - for(std::size_t i = 0, n = lines.size(); i < n; i++) { - geom::LineString* line = (geom::LineString*)(lines[i]); - - // we take ownership of the coordinates here - // TODO: check if this can be optimized by getting - // the internal CS. - auto pts = line->getCoordinates(); - - segStr.push_back(new NodedSegmentString(pts.release(), g)); + for(const geom::LineString* line : lines) { + auto pts = line->getCoordinatesRO(); + segStr.push_back(new BasicSegmentString(const_cast(pts), g)); } } From 83d8e34bd7f2c98a73e0094880eabdb0f1556cde Mon Sep 17 00:00:00 2001 From: Daniel Baston Date: Wed, 21 Sep 2022 21:04:31 -0400 Subject: [PATCH 2/2] SimplePointInAreaLocator: avoid dynamic_cast and rearrange some envelope checks Makes a surprisingly large difference in performance test --- .../locate/SimplePointInAreaLocator.cpp | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/algorithm/locate/SimplePointInAreaLocator.cpp b/src/algorithm/locate/SimplePointInAreaLocator.cpp index ddd1f3fa22..644be36924 100644 --- a/src/algorithm/locate/SimplePointInAreaLocator.cpp +++ b/src/algorithm/locate/SimplePointInAreaLocator.cpp @@ -40,16 +40,6 @@ namespace locate { // geos.algorithm geom::Location SimplePointInAreaLocator::locate(const Coordinate& p, const Geometry* geom) { - if(geom->isEmpty()) { - return Location::EXTERIOR; - } - - /* - * Do a fast check against the geometry envelope first - */ - if (! geom->getEnvelopeInternal()->intersects(p)) - return Location::EXTERIOR; - return locateInGeometry(p, geom); } @@ -62,16 +52,21 @@ SimplePointInAreaLocator::isContained(const Coordinate& p, const Geometry* geom) geom::Location SimplePointInAreaLocator::locateInGeometry(const Coordinate& p, const Geometry* geom) { + /* + * Do a fast check against the geometry envelope first + */ + if (! geom->getEnvelopeInternal()->intersects(p)) + return Location::EXTERIOR; + if (geom->getDimension() < 2) { return Location::EXTERIOR; } if (geom->getNumGeometries() == 1) { - auto poly = dynamic_cast(geom->getGeometryN(0)); - if (poly) { + if (geom->getGeometryTypeId() == GEOS_POLYGON) { + auto poly = static_cast(geom); return locatePointInPolygon(p, poly); } - // Else it is a collection with a single element. Will be handled below. } for (std::size_t i = 0; i < geom->getNumGeometries(); i++) { const Geometry* gi = geom->getGeometryN(i);