[geos-commits] [SCM] GEOS branch main updated. c7ca3dd29bf379c43ae6f97fbc1bdfa10dcf630e
git at osgeo.org
git at osgeo.org
Thu Jan 29 12:36:18 PST 2026
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".
The branch, main has been updated
via c7ca3dd29bf379c43ae6f97fbc1bdfa10dcf630e (commit)
from 0154023f7e0d15a27d2bf38fe6b78408be560bc8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit c7ca3dd29bf379c43ae6f97fbc1bdfa10dcf630e
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date: Thu Jan 29 12:35:09 2026 -0800
Port JTS-1177
Simplify FacetSequence implementation
diff --git a/include/geos/operation/distance/FacetSequence.h b/include/geos/operation/distance/FacetSequence.h
index fbef50e90..61f9fd65b 100644
--- a/include/geos/operation/distance/FacetSequence.h
+++ b/include/geos/operation/distance/FacetSequence.h
@@ -18,21 +18,27 @@
#pragma once
-#include <geos/geom/CoordinateSequence.h>
#include <geos/geom/Envelope.h>
#include <geos/geom/Coordinate.h>
-#include <geos/geom/LineSegment.h>
-#include <geos/operation/distance/GeometryLocation.h>
+
+namespace geos {
+namespace geom {
+class CoordinateSequence;
+}
+}
namespace geos {
namespace operation {
namespace distance {
+
class FacetSequence {
+
private:
+
const geom::CoordinateSequence* pts;
const std::size_t start;
const std::size_t end;
- const geom::Geometry* geom;
+
/*
* Unlike JTS, we store the envelope in the FacetSequence so
* that it has a clear owner. This is helpful when making a
@@ -41,25 +47,24 @@ private:
geom::Envelope env;
double computeDistanceLineLine(const FacetSequence& facetSeq,
- std::vector<GeometryLocation> *locs) const;
+ std::vector<geom::Coordinate> *locs) const;
double computeDistancePointLine(const geom::Coordinate& pt,
const FacetSequence& facetSeq,
- std::vector<GeometryLocation> *locs) const;
+ std::vector<geom::Coordinate> *locs) const;
void updateNearestLocationsPointLine(const geom::Coordinate& pt,
- const FacetSequence& facetSeq, std::size_t i,
const geom::Coordinate& q0, const geom::Coordinate &q1,
- std::vector<GeometryLocation> *locs) const;
+ std::vector<geom::Coordinate> *locs) const;
- void updateNearestLocationsLineLine(std::size_t i, const geom::Coordinate& p0, const geom::Coordinate& p1,
- const FacetSequence& facetSeq,
- std::size_t j, const geom::Coordinate& q0, const geom::Coordinate &q1,
- std::vector<GeometryLocation> *locs) const;
+ void updateNearestLocationsLineLine(const geom::Coordinate& p0, const geom::Coordinate& p1,
+ const geom::Coordinate& q0, const geom::Coordinate &q1,
+ std::vector<geom::Coordinate> *locs) const;
void computeEnvelope();
public:
+
const geom::Envelope* getEnvelope() const;
const geom::Coordinate* getCoordinate(std::size_t index) const;
@@ -72,9 +77,14 @@ public:
FacetSequence(const geom::CoordinateSequence* pts, std::size_t start, std::size_t end);
- FacetSequence(const geom::Geometry* geom, const geom::CoordinateSequence* pts, std::size_t start, std::size_t end);
-
- std::vector<GeometryLocation> nearestLocations(const FacetSequence& facetSeq) const;
+ /**
+ * Computes the locations of the nearest points between this sequence
+ * and another sequence.
+ * The locations are presented in the same order as the input sequences.
+ *
+ * @return a pair of {@link Coordinate}s for the nearest points
+ */
+ std::vector<geom::Coordinate> nearestLocations(const FacetSequence& facetSeq) const;
};
diff --git a/include/geos/operation/distance/FacetSequenceTreeBuilder.h b/include/geos/operation/distance/FacetSequenceTreeBuilder.h
index 2a8731fb3..29f7e0589 100644
--- a/include/geos/operation/distance/FacetSequenceTreeBuilder.h
+++ b/include/geos/operation/distance/FacetSequenceTreeBuilder.h
@@ -18,25 +18,32 @@
#pragma once
-#include <geos/index/ItemVisitor.h>
#include <geos/index/strtree/TemplateSTRtree.h>
-#include <geos/geom/Geometry.h>
-#include <geos/geom/CoordinateSequence.h>
#include <geos/operation/distance/FacetSequence.h>
+
+namespace geos {
+namespace geom {
+class CoordinateSequence;
+class Geometry;
+}
+}
+
namespace geos {
namespace operation {
namespace distance {
+
class GEOS_DLL FacetSequenceTreeBuilder {
+
private:
+
// 6 seems to be a good facet sequence size
static const std::size_t FACET_SEQUENCE_SIZE = 6;
// Seems to be better to use a minimum node capacity
static const std::size_t STR_TREE_NODE_CAPACITY = 4;
- static void addFacetSequences(const geom::Geometry* geom,
- const geom::CoordinateSequence* pts,
+ static void addFacetSequences(const geom::CoordinateSequence* pts,
std::vector<FacetSequence> & sections);
static std::vector<FacetSequence> computeFacetSequences(const geom::Geometry* g);
@@ -55,6 +62,7 @@ private:
};
public:
+
/** \brief
* Return a tree of FacetSequences constructed from the supplied Geometry.
*
@@ -63,6 +71,7 @@ public:
*/
static std::unique_ptr<geos::index::strtree::TemplateSTRtree<const FacetSequence*>> build(const geom::Geometry* g);
};
+
}
}
}
diff --git a/include/geos/operation/distance/IndexedFacetDistance.h b/include/geos/operation/distance/IndexedFacetDistance.h
index 87044c274..6739efbf0 100644
--- a/include/geos/operation/distance/IndexedFacetDistance.h
+++ b/include/geos/operation/distance/IndexedFacetDistance.h
@@ -94,18 +94,15 @@ public:
/// \return true of the geometry lies within the specified distance
bool isWithinDistance(const geom::Geometry* g, double maxDistance) const;
- /// \brief Computes the nearest locations on the base geometry and the given geometry.
- ///
- /// \param g the geometry to compute the nearest location to
- /// \return the nearest locations
- std::vector<GeometryLocation> nearestLocations(const geom::Geometry* g) const;
+ static bool isWithinDistance(const geom::Geometry* g1, const geom::Geometry* g2, double distance);
- /// \brief Compute the nearest locations on the target geometry and the given geometry.
+ /// \brief Computes the nearest points on the base geometry and the given geometry.
///
/// \param g the geometry to compute the nearest point to
/// \return the nearest points
std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const;
+
private:
struct FacetDistance {
double operator()(const FacetSequence* a, const FacetSequence* b) const
diff --git a/src/operation/distance/FacetSequence.cpp b/src/operation/distance/FacetSequence.cpp
index 4e1f4f496..ebc1501dd 100644
--- a/src/operation/distance/FacetSequence.cpp
+++ b/src/operation/distance/FacetSequence.cpp
@@ -16,6 +16,8 @@
*
**********************************************************************/
+#include <geos/geom/Geometry.h>
+#include <geos/geom/LineSegment.h>
#include <geos/algorithm/Distance.h>
#include <geos/operation/distance/FacetSequence.h>
@@ -25,20 +27,11 @@ using namespace geos::geom;
using namespace geos::operation::distance;
using namespace geos::algorithm;
-FacetSequence::FacetSequence(const Geometry *p_geom, const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end) :
- pts(p_pts),
- start(p_start),
- end(p_end),
- geom(p_geom)
-{
- computeEnvelope();
-}
-FacetSequence::FacetSequence(const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end) :
- pts(p_pts),
- start(p_start),
- end(p_end),
- geom(nullptr)
+FacetSequence::FacetSequence(const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end)
+ : pts(p_pts)
+ , start(p_start)
+ , end(p_end)
{
computeEnvelope();
}
@@ -61,16 +54,16 @@ FacetSequence::distance(const FacetSequence& facetSeq) const
bool isPointThis = isPoint();
bool isPointOther = facetSeq.isPoint();
- if(isPointThis && isPointOther) {
+ if (isPointThis && isPointOther) {
const Coordinate& pt = pts->getAt(start);
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
return pt.distance(seqPt);
}
- else if(isPointThis) {
+ else if (isPointThis) {
const Coordinate& pt = pts->getAt(start);
return computeDistancePointLine(pt, facetSeq, nullptr);
}
- else if(isPointOther) {
+ else if (isPointOther) {
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
return computeDistancePointLine(seqPt, *this, nullptr);
}
@@ -84,20 +77,18 @@ FacetSequence::distance(const FacetSequence& facetSeq) const
* just return the whole mess, since it only ends up holding two
* locations.
*/
-std::vector<GeometryLocation>
+std::vector<Coordinate>
FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
{
bool isPointThis = isPoint();
bool isPointOther = facetSeq.isPoint();
- std::vector<GeometryLocation> locs;
+ std::vector<Coordinate> locs;
if (isPointThis && isPointOther) {
const Coordinate& pt = pts->getAt(start);
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
- GeometryLocation gl1(geom, start, pt);
- GeometryLocation gl2(facetSeq.geom, facetSeq.start, seqPt);
locs.clear();
- locs.push_back(gl1);
- locs.push_back(gl2);
+ locs.push_back(pt);
+ locs.push_back(seqPt);
}
else if (isPointThis) {
const Coordinate& pt = pts->getAt(start);
@@ -107,7 +98,7 @@ FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
computeDistancePointLine(seqPt, *this, &locs);
// unflip the locations
- GeometryLocation tmp = locs[0];
+ Coordinate tmp = locs[0];
locs[0] = locs[1];
locs[1] = tmp;
}
@@ -120,20 +111,20 @@ FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
double
FacetSequence::computeDistancePointLine(const Coordinate& pt,
const FacetSequence& facetSeq,
- std::vector<GeometryLocation> *locs) const
+ std::vector<Coordinate> *locs) const
{
double minDistance = DoubleInfinity;
- for(std::size_t i = facetSeq.start; i < facetSeq.end - 1; i++) {
+ for (std::size_t i = facetSeq.start; i < facetSeq.end - 1; i++) {
const Coordinate& q0 = facetSeq.pts->getAt(i);
const Coordinate& q1 = facetSeq.pts->getAt(i + 1);
double dist = Distance::pointToSegment(pt, q0, q1);
- if(dist < minDistance || (locs != nullptr && locs->empty())) {
+ if (dist < minDistance || (locs != nullptr && locs->empty())) {
minDistance = dist;
if (locs != nullptr) {
- updateNearestLocationsPointLine(pt, facetSeq, i, q0, q1, locs);
+ updateNearestLocationsPointLine(pt, q0, q1, locs);
}
- if(minDistance <= 0.0) {
+ if (minDistance <= 0.0) {
return minDistance;
}
}
@@ -143,22 +134,21 @@ FacetSequence::computeDistancePointLine(const Coordinate& pt,
}
void
-FacetSequence::updateNearestLocationsPointLine(const Coordinate& pt,
- const FacetSequence& facetSeq, std::size_t i,
- const Coordinate& q0, const Coordinate &q1,
- std::vector<GeometryLocation> *locs) const
+FacetSequence::updateNearestLocationsPointLine(
+ const Coordinate& pt, const Coordinate& q0, const Coordinate &q1,
+ std::vector<Coordinate> *locs) const
{
- geom::LineSegment seg(q0, q1);
+ LineSegment seg(q0, q1);
Coordinate segClosestPoint;
seg.closestPoint(pt, segClosestPoint);
locs->clear();
- locs->emplace_back(geom, start, pt);
- locs->emplace_back(facetSeq.geom, i, segClosestPoint);
+ locs->push_back(pt);
+ locs->push_back(segClosestPoint);
return;
}
double
-FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vector<GeometryLocation> *locs) const
+FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vector<Coordinate> *locs) const
{
double minDistance = DoubleInfinity;
@@ -192,7 +182,7 @@ FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vecto
if(dist <= minDistance) {
minDistance = dist;
if(locs != nullptr) {
- updateNearestLocationsLineLine(i, p0, p1, facetSeq, j, q0, q1, locs);
+ updateNearestLocationsLineLine(p0, p1, q0, q1, locs);
}
if(minDistance <= 0.0) return minDistance;
}
@@ -203,10 +193,10 @@ FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vecto
}
void
-FacetSequence::updateNearestLocationsLineLine(std::size_t i, const Coordinate& p0, const Coordinate& p1,
- const FacetSequence& facetSeq,
- std::size_t j, const Coordinate& q0, const Coordinate &q1,
- std::vector<GeometryLocation> *locs) const
+FacetSequence::updateNearestLocationsLineLine(
+ const Coordinate& p0, const Coordinate& p1,
+ const Coordinate& q0, const Coordinate &q1,
+ std::vector<Coordinate> *locs) const
{
LineSegment seg0(p0, p1);
LineSegment seg1(q0, q1);
@@ -214,8 +204,8 @@ FacetSequence::updateNearestLocationsLineLine(std::size_t i, const Coordinate& p
auto closestPts = seg0.closestPoints(seg1);
locs->clear();
- locs->emplace_back(geom, i, closestPts[0]);
- locs->emplace_back(facetSeq.geom, j, closestPts[1]);
+ locs->push_back(closestPts[0]);
+ locs->push_back(closestPts[1]);
}
void
diff --git a/src/operation/distance/FacetSequenceTreeBuilder.cpp b/src/operation/distance/FacetSequenceTreeBuilder.cpp
index da91bb66b..ec10c8c57 100644
--- a/src/operation/distance/FacetSequenceTreeBuilder.cpp
+++ b/src/operation/distance/FacetSequenceTreeBuilder.cpp
@@ -44,21 +44,21 @@ FacetSequenceTreeBuilder::computeFacetSequences(const Geometry* g)
class FacetSequenceAdder : public geom::GeometryComponentFilter {
std::vector<FacetSequence>& m_sections;
- public :
- FacetSequenceAdder(std::vector<FacetSequence> & p_sections) :
- m_sections(p_sections) {}
- void
- filter_ro(const Geometry* geom) override
- {
- if(const LineString* ls = dynamic_cast<const LineString*>(geom)) {
- const CoordinateSequence* seq = ls->getCoordinatesRO();
- addFacetSequences(geom, seq, m_sections);
+ public :
+ FacetSequenceAdder(std::vector<FacetSequence> & p_sections) :
+ m_sections(p_sections) {}
+ void
+ filter_ro(const Geometry* geom) override
+ {
+ if(const LineString* ls = dynamic_cast<const LineString*>(geom)) {
+ const CoordinateSequence* seq = ls->getCoordinatesRO();
+ addFacetSequences(seq, m_sections);
+ }
+ else if(const Point* pt = dynamic_cast<const Point*>(geom)) {
+ const CoordinateSequence* seq = pt->getCoordinatesRO();
+ addFacetSequences(seq, m_sections);
+ }
}
- else if(const Point* pt = dynamic_cast<const Point*>(geom)) {
- const CoordinateSequence* seq = pt->getCoordinatesRO();
- addFacetSequences(geom, seq, m_sections);
- }
- }
};
FacetSequenceAdder facetSequenceAdder(sections);
@@ -68,8 +68,9 @@ FacetSequenceTreeBuilder::computeFacetSequences(const Geometry* g)
}
void
-FacetSequenceTreeBuilder::addFacetSequences(const Geometry* geom, const CoordinateSequence* pts,
- std::vector<FacetSequence> & sections)
+FacetSequenceTreeBuilder::addFacetSequences(
+ const CoordinateSequence* pts,
+ std::vector<FacetSequence>& sections)
{
std::size_t i = 0;
std::size_t size = pts->size();
@@ -82,7 +83,7 @@ FacetSequenceTreeBuilder::addFacetSequences(const Geometry* geom, const Coordina
if(end >= size - 1) {
end = size;
}
- sections.emplace_back(geom, pts, i, end);
+ sections.emplace_back(pts, i, end);
i += FACET_SEQUENCE_SIZE;
}
}
diff --git a/src/operation/distance/IndexedFacetDistance.cpp b/src/operation/distance/IndexedFacetDistance.cpp
index 74beff4e8..6555920cd 100644
--- a/src/operation/distance/IndexedFacetDistance.cpp
+++ b/src/operation/distance/IndexedFacetDistance.cpp
@@ -27,7 +27,7 @@ namespace geos {
namespace operation {
namespace distance {
-/*public static*/
+/* public static */
double
IndexedFacetDistance::distance(const Geometry* g1, const Geometry* g2)
{
@@ -35,9 +35,17 @@ IndexedFacetDistance::distance(const Geometry* g1, const Geometry* g2)
return ifd.distance(g2);
}
-/*public static*/
+/* public static */
+bool
+IndexedFacetDistance::isWithinDistance(const Geometry* g1, const Geometry* g2, double distance)
+{
+ IndexedFacetDistance ifd(g1);
+ return ifd.isWithinDistance(g2, distance);
+}
+
+/* public static */
std::unique_ptr<CoordinateSequence>
-IndexedFacetDistance::nearestPoints(const geom::Geometry* g1, const geom::Geometry* g2)
+IndexedFacetDistance::nearestPoints(const Geometry* g1, const Geometry* g2)
{
IndexedFacetDistance dist(g1);
return dist.nearestPoints(g2);
@@ -47,15 +55,32 @@ double
IndexedFacetDistance::distance(const Geometry* g) const
{
auto tree2 = FacetSequenceTreeBuilder::build(g);
- auto nearest = cachedTree->nearestNeighbour<FacetDistance>(*tree2);
-
- if (!nearest.first) {
+ auto objs = cachedTree->nearestNeighbour<FacetDistance>(*tree2);
+ if (!objs.first || !objs.second) {
throw util::GEOSException("Cannot calculate IndexedFacetDistance on empty geometries.");
}
-
- return nearest.first->distance(*nearest.second);
+ auto fs1 = static_cast<const FacetSequence*>(objs.first);
+ auto fs2 = static_cast<const FacetSequence*>(objs.second);
+ return fs1->distance(*fs2);
}
+std::unique_ptr<geom::CoordinateSequence>
+IndexedFacetDistance::nearestPoints(const geom::Geometry* g) const
+{
+ auto tree2 = FacetSequenceTreeBuilder::build(g);
+ auto objs = cachedTree->nearestNeighbour<FacetDistance>(*tree2);
+ if (!objs.first || !objs.second) {
+ throw util::GEOSException("Cannot calculate IndexedFacetDistance on empty geometries.");
+ }
+ auto fs1 = static_cast<const FacetSequence*>(objs.first);
+ auto fs2 = static_cast<const FacetSequence*>(objs.second);
+ auto nearestPts = fs1->nearestLocations(*fs2);
+ std::unique_ptr<CoordinateSequence> cs(new CoordinateSequence());
+ cs->setPoints(nearestPts);
+ return cs;
+}
+
+
bool
IndexedFacetDistance::isWithinDistance(const Geometry* g, double maxDistance) const
{
@@ -80,29 +105,6 @@ IndexedFacetDistance::isWithinDistance(const Geometry* g, double maxDistance) co
return cachedTree->isWithinDistance<FacetDistance>(*tree2, maxDistance);
}
-std::vector<GeometryLocation>
-IndexedFacetDistance::nearestLocations(const geom::Geometry* g) const
-{
-
- auto tree2 = FacetSequenceTreeBuilder::build(g);
- auto nearest = cachedTree->nearestNeighbour<FacetDistance>(*tree2);
-
- if (!nearest.first) {
- throw util::GEOSException("Cannot calculate IndexedFacetDistance on empty geometries.");
- }
-
- return nearest.first->nearestLocations(*nearest.second);
-}
-
-std::unique_ptr<CoordinateSequence>
-IndexedFacetDistance::nearestPoints(const geom::Geometry* g) const
-{
- std::vector<GeometryLocation> minDistanceLocation = nearestLocations(g);
- auto nearestPts = detail::make_unique<CoordinateSequence>(2u);
- nearestPts->setAt(minDistanceLocation[0].getCoordinate(), 0);
- nearestPts->setAt(minDistanceLocation[1].getCoordinate(), 1);
- return nearestPts;
-}
}
}
-----------------------------------------------------------------------
Summary of changes:
include/geos/operation/distance/FacetSequence.h | 40 +++++++-----
.../operation/distance/FacetSequenceTreeBuilder.h | 19 ++++--
.../geos/operation/distance/IndexedFacetDistance.h | 9 +--
src/operation/distance/FacetSequence.cpp | 76 ++++++++++------------
.../distance/FacetSequenceTreeBuilder.cpp | 35 +++++-----
src/operation/distance/IndexedFacetDistance.cpp | 62 +++++++++---------
6 files changed, 125 insertions(+), 116 deletions(-)
hooks/post-receive
--
GEOS
More information about the geos-commits
mailing list