Skip to content

Commit c7ca3dd

Browse files
committed
Port JTS-1177
Simplify FacetSequence implementation
1 parent 0154023 commit c7ca3dd

File tree

6 files changed

+125
-116
lines changed

6 files changed

+125
-116
lines changed

include/geos/operation/distance/FacetSequence.h

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,27 @@
1818

1919
#pragma once
2020

21-
#include <geos/geom/CoordinateSequence.h>
2221
#include <geos/geom/Envelope.h>
2322
#include <geos/geom/Coordinate.h>
24-
#include <geos/geom/LineSegment.h>
25-
#include <geos/operation/distance/GeometryLocation.h>
23+
24+
namespace geos {
25+
namespace geom {
26+
class CoordinateSequence;
27+
}
28+
}
2629

2730
namespace geos {
2831
namespace operation {
2932
namespace distance {
33+
3034
class FacetSequence {
35+
3136
private:
37+
3238
const geom::CoordinateSequence* pts;
3339
const std::size_t start;
3440
const std::size_t end;
35-
const geom::Geometry* geom;
41+
3642
/*
3743
* Unlike JTS, we store the envelope in the FacetSequence so
3844
* that it has a clear owner. This is helpful when making a
@@ -41,25 +47,24 @@ class FacetSequence {
4147
geom::Envelope env;
4248

4349
double computeDistanceLineLine(const FacetSequence& facetSeq,
44-
std::vector<GeometryLocation> *locs) const;
50+
std::vector<geom::Coordinate> *locs) const;
4551

4652
double computeDistancePointLine(const geom::Coordinate& pt,
4753
const FacetSequence& facetSeq,
48-
std::vector<GeometryLocation> *locs) const;
54+
std::vector<geom::Coordinate> *locs) const;
4955

5056
void updateNearestLocationsPointLine(const geom::Coordinate& pt,
51-
const FacetSequence& facetSeq, std::size_t i,
5257
const geom::Coordinate& q0, const geom::Coordinate &q1,
53-
std::vector<GeometryLocation> *locs) const;
58+
std::vector<geom::Coordinate> *locs) const;
5459

55-
void updateNearestLocationsLineLine(std::size_t i, const geom::Coordinate& p0, const geom::Coordinate& p1,
56-
const FacetSequence& facetSeq,
57-
std::size_t j, const geom::Coordinate& q0, const geom::Coordinate &q1,
58-
std::vector<GeometryLocation> *locs) const;
60+
void updateNearestLocationsLineLine(const geom::Coordinate& p0, const geom::Coordinate& p1,
61+
const geom::Coordinate& q0, const geom::Coordinate &q1,
62+
std::vector<geom::Coordinate> *locs) const;
5963

6064
void computeEnvelope();
6165

6266
public:
67+
6368
const geom::Envelope* getEnvelope() const;
6469

6570
const geom::Coordinate* getCoordinate(std::size_t index) const;
@@ -72,9 +77,14 @@ class FacetSequence {
7277

7378
FacetSequence(const geom::CoordinateSequence* pts, std::size_t start, std::size_t end);
7479

75-
FacetSequence(const geom::Geometry* geom, const geom::CoordinateSequence* pts, std::size_t start, std::size_t end);
76-
77-
std::vector<GeometryLocation> nearestLocations(const FacetSequence& facetSeq) const;
80+
/**
81+
* Computes the locations of the nearest points between this sequence
82+
* and another sequence.
83+
* The locations are presented in the same order as the input sequences.
84+
*
85+
* @return a pair of {@link Coordinate}s for the nearest points
86+
*/
87+
std::vector<geom::Coordinate> nearestLocations(const FacetSequence& facetSeq) const;
7888

7989
};
8090

include/geos/operation/distance/FacetSequenceTreeBuilder.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,32 @@
1818

1919
#pragma once
2020

21-
#include <geos/index/ItemVisitor.h>
2221
#include <geos/index/strtree/TemplateSTRtree.h>
23-
#include <geos/geom/Geometry.h>
24-
#include <geos/geom/CoordinateSequence.h>
2522
#include <geos/operation/distance/FacetSequence.h>
2623

24+
25+
namespace geos {
26+
namespace geom {
27+
class CoordinateSequence;
28+
class Geometry;
29+
}
30+
}
31+
2732
namespace geos {
2833
namespace operation {
2934
namespace distance {
35+
3036
class GEOS_DLL FacetSequenceTreeBuilder {
37+
3138
private:
39+
3240
// 6 seems to be a good facet sequence size
3341
static const std::size_t FACET_SEQUENCE_SIZE = 6;
3442

3543
// Seems to be better to use a minimum node capacity
3644
static const std::size_t STR_TREE_NODE_CAPACITY = 4;
3745

38-
static void addFacetSequences(const geom::Geometry* geom,
39-
const geom::CoordinateSequence* pts,
46+
static void addFacetSequences(const geom::CoordinateSequence* pts,
4047
std::vector<FacetSequence> & sections);
4148
static std::vector<FacetSequence> computeFacetSequences(const geom::Geometry* g);
4249

@@ -55,6 +62,7 @@ class GEOS_DLL FacetSequenceTreeBuilder {
5562
};
5663

5764
public:
65+
5866
/** \brief
5967
* Return a tree of FacetSequences constructed from the supplied Geometry.
6068
*
@@ -63,6 +71,7 @@ class GEOS_DLL FacetSequenceTreeBuilder {
6371
*/
6472
static std::unique_ptr<geos::index::strtree::TemplateSTRtree<const FacetSequence*>> build(const geom::Geometry* g);
6573
};
74+
6675
}
6776
}
6877
}

include/geos/operation/distance/IndexedFacetDistance.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,15 @@ class GEOS_DLL IndexedFacetDistance {
9494
/// \return true of the geometry lies within the specified distance
9595
bool isWithinDistance(const geom::Geometry* g, double maxDistance) const;
9696

97-
/// \brief Computes the nearest locations on the base geometry and the given geometry.
98-
///
99-
/// \param g the geometry to compute the nearest location to
100-
/// \return the nearest locations
101-
std::vector<GeometryLocation> nearestLocations(const geom::Geometry* g) const;
97+
static bool isWithinDistance(const geom::Geometry* g1, const geom::Geometry* g2, double distance);
10298

103-
/// \brief Compute the nearest locations on the target geometry and the given geometry.
99+
/// \brief Computes the nearest points on the base geometry and the given geometry.
104100
///
105101
/// \param g the geometry to compute the nearest point to
106102
/// \return the nearest points
107103
std::unique_ptr<geom::CoordinateSequence> nearestPoints(const geom::Geometry* g) const;
108104

105+
109106
private:
110107
struct FacetDistance {
111108
double operator()(const FacetSequence* a, const FacetSequence* b) const

src/operation/distance/FacetSequence.cpp

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
*
1717
**********************************************************************/
1818

19+
#include <geos/geom/Geometry.h>
20+
#include <geos/geom/LineSegment.h>
1921
#include <geos/algorithm/Distance.h>
2022
#include <geos/operation/distance/FacetSequence.h>
2123

@@ -25,20 +27,11 @@ using namespace geos::geom;
2527
using namespace geos::operation::distance;
2628
using namespace geos::algorithm;
2729

28-
FacetSequence::FacetSequence(const Geometry *p_geom, const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end) :
29-
pts(p_pts),
30-
start(p_start),
31-
end(p_end),
32-
geom(p_geom)
33-
{
34-
computeEnvelope();
35-
}
3630

37-
FacetSequence::FacetSequence(const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end) :
38-
pts(p_pts),
39-
start(p_start),
40-
end(p_end),
41-
geom(nullptr)
31+
FacetSequence::FacetSequence(const CoordinateSequence* p_pts, std::size_t p_start, std::size_t p_end)
32+
: pts(p_pts)
33+
, start(p_start)
34+
, end(p_end)
4235
{
4336
computeEnvelope();
4437
}
@@ -61,16 +54,16 @@ FacetSequence::distance(const FacetSequence& facetSeq) const
6154
bool isPointThis = isPoint();
6255
bool isPointOther = facetSeq.isPoint();
6356

64-
if(isPointThis && isPointOther) {
57+
if (isPointThis && isPointOther) {
6558
const Coordinate& pt = pts->getAt(start);
6659
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
6760
return pt.distance(seqPt);
6861
}
69-
else if(isPointThis) {
62+
else if (isPointThis) {
7063
const Coordinate& pt = pts->getAt(start);
7164
return computeDistancePointLine(pt, facetSeq, nullptr);
7265
}
73-
else if(isPointOther) {
66+
else if (isPointOther) {
7467
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
7568
return computeDistancePointLine(seqPt, *this, nullptr);
7669
}
@@ -84,20 +77,18 @@ FacetSequence::distance(const FacetSequence& facetSeq) const
8477
* just return the whole mess, since it only ends up holding two
8578
* locations.
8679
*/
87-
std::vector<GeometryLocation>
80+
std::vector<Coordinate>
8881
FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
8982
{
9083
bool isPointThis = isPoint();
9184
bool isPointOther = facetSeq.isPoint();
92-
std::vector<GeometryLocation> locs;
85+
std::vector<Coordinate> locs;
9386
if (isPointThis && isPointOther) {
9487
const Coordinate& pt = pts->getAt(start);
9588
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
96-
GeometryLocation gl1(geom, start, pt);
97-
GeometryLocation gl2(facetSeq.geom, facetSeq.start, seqPt);
9889
locs.clear();
99-
locs.push_back(gl1);
100-
locs.push_back(gl2);
90+
locs.push_back(pt);
91+
locs.push_back(seqPt);
10192
}
10293
else if (isPointThis) {
10394
const Coordinate& pt = pts->getAt(start);
@@ -107,7 +98,7 @@ FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
10798
const Coordinate& seqPt = facetSeq.pts->getAt(facetSeq.start);
10899
computeDistancePointLine(seqPt, *this, &locs);
109100
// unflip the locations
110-
GeometryLocation tmp = locs[0];
101+
Coordinate tmp = locs[0];
111102
locs[0] = locs[1];
112103
locs[1] = tmp;
113104
}
@@ -120,20 +111,20 @@ FacetSequence::nearestLocations(const FacetSequence& facetSeq) const
120111
double
121112
FacetSequence::computeDistancePointLine(const Coordinate& pt,
122113
const FacetSequence& facetSeq,
123-
std::vector<GeometryLocation> *locs) const
114+
std::vector<Coordinate> *locs) const
124115
{
125116
double minDistance = DoubleInfinity;
126117

127-
for(std::size_t i = facetSeq.start; i < facetSeq.end - 1; i++) {
118+
for (std::size_t i = facetSeq.start; i < facetSeq.end - 1; i++) {
128119
const Coordinate& q0 = facetSeq.pts->getAt(i);
129120
const Coordinate& q1 = facetSeq.pts->getAt(i + 1);
130121
double dist = Distance::pointToSegment(pt, q0, q1);
131-
if(dist < minDistance || (locs != nullptr && locs->empty())) {
122+
if (dist < minDistance || (locs != nullptr && locs->empty())) {
132123
minDistance = dist;
133124
if (locs != nullptr) {
134-
updateNearestLocationsPointLine(pt, facetSeq, i, q0, q1, locs);
125+
updateNearestLocationsPointLine(pt, q0, q1, locs);
135126
}
136-
if(minDistance <= 0.0) {
127+
if (minDistance <= 0.0) {
137128
return minDistance;
138129
}
139130
}
@@ -143,22 +134,21 @@ FacetSequence::computeDistancePointLine(const Coordinate& pt,
143134
}
144135

145136
void
146-
FacetSequence::updateNearestLocationsPointLine(const Coordinate& pt,
147-
const FacetSequence& facetSeq, std::size_t i,
148-
const Coordinate& q0, const Coordinate &q1,
149-
std::vector<GeometryLocation> *locs) const
137+
FacetSequence::updateNearestLocationsPointLine(
138+
const Coordinate& pt, const Coordinate& q0, const Coordinate &q1,
139+
std::vector<Coordinate> *locs) const
150140
{
151-
geom::LineSegment seg(q0, q1);
141+
LineSegment seg(q0, q1);
152142
Coordinate segClosestPoint;
153143
seg.closestPoint(pt, segClosestPoint);
154144
locs->clear();
155-
locs->emplace_back(geom, start, pt);
156-
locs->emplace_back(facetSeq.geom, i, segClosestPoint);
145+
locs->push_back(pt);
146+
locs->push_back(segClosestPoint);
157147
return;
158148
}
159149

160150
double
161-
FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vector<GeometryLocation> *locs) const
151+
FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vector<Coordinate> *locs) const
162152
{
163153
double minDistance = DoubleInfinity;
164154

@@ -192,7 +182,7 @@ FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vecto
192182
if(dist <= minDistance) {
193183
minDistance = dist;
194184
if(locs != nullptr) {
195-
updateNearestLocationsLineLine(i, p0, p1, facetSeq, j, q0, q1, locs);
185+
updateNearestLocationsLineLine(p0, p1, q0, q1, locs);
196186
}
197187
if(minDistance <= 0.0) return minDistance;
198188
}
@@ -203,19 +193,19 @@ FacetSequence::computeDistanceLineLine(const FacetSequence& facetSeq, std::vecto
203193
}
204194

205195
void
206-
FacetSequence::updateNearestLocationsLineLine(std::size_t i, const Coordinate& p0, const Coordinate& p1,
207-
const FacetSequence& facetSeq,
208-
std::size_t j, const Coordinate& q0, const Coordinate &q1,
209-
std::vector<GeometryLocation> *locs) const
196+
FacetSequence::updateNearestLocationsLineLine(
197+
const Coordinate& p0, const Coordinate& p1,
198+
const Coordinate& q0, const Coordinate &q1,
199+
std::vector<Coordinate> *locs) const
210200
{
211201
LineSegment seg0(p0, p1);
212202
LineSegment seg1(q0, q1);
213203

214204
auto closestPts = seg0.closestPoints(seg1);
215205

216206
locs->clear();
217-
locs->emplace_back(geom, i, closestPts[0]);
218-
locs->emplace_back(facetSeq.geom, j, closestPts[1]);
207+
locs->push_back(closestPts[0]);
208+
locs->push_back(closestPts[1]);
219209
}
220210

221211
void

src/operation/distance/FacetSequenceTreeBuilder.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,21 +44,21 @@ FacetSequenceTreeBuilder::computeFacetSequences(const Geometry* g)
4444
class FacetSequenceAdder : public geom::GeometryComponentFilter {
4545
std::vector<FacetSequence>& m_sections;
4646

47-
public :
48-
FacetSequenceAdder(std::vector<FacetSequence> & p_sections) :
49-
m_sections(p_sections) {}
50-
void
51-
filter_ro(const Geometry* geom) override
52-
{
53-
if(const LineString* ls = dynamic_cast<const LineString*>(geom)) {
54-
const CoordinateSequence* seq = ls->getCoordinatesRO();
55-
addFacetSequences(geom, seq, m_sections);
47+
public :
48+
FacetSequenceAdder(std::vector<FacetSequence> & p_sections) :
49+
m_sections(p_sections) {}
50+
void
51+
filter_ro(const Geometry* geom) override
52+
{
53+
if(const LineString* ls = dynamic_cast<const LineString*>(geom)) {
54+
const CoordinateSequence* seq = ls->getCoordinatesRO();
55+
addFacetSequences(seq, m_sections);
56+
}
57+
else if(const Point* pt = dynamic_cast<const Point*>(geom)) {
58+
const CoordinateSequence* seq = pt->getCoordinatesRO();
59+
addFacetSequences(seq, m_sections);
60+
}
5661
}
57-
else if(const Point* pt = dynamic_cast<const Point*>(geom)) {
58-
const CoordinateSequence* seq = pt->getCoordinatesRO();
59-
addFacetSequences(geom, seq, m_sections);
60-
}
61-
}
6262
};
6363

6464
FacetSequenceAdder facetSequenceAdder(sections);
@@ -68,8 +68,9 @@ FacetSequenceTreeBuilder::computeFacetSequences(const Geometry* g)
6868
}
6969

7070
void
71-
FacetSequenceTreeBuilder::addFacetSequences(const Geometry* geom, const CoordinateSequence* pts,
72-
std::vector<FacetSequence> & sections)
71+
FacetSequenceTreeBuilder::addFacetSequences(
72+
const CoordinateSequence* pts,
73+
std::vector<FacetSequence>& sections)
7374
{
7475
std::size_t i = 0;
7576
std::size_t size = pts->size();
@@ -82,7 +83,7 @@ FacetSequenceTreeBuilder::addFacetSequences(const Geometry* geom, const Coordina
8283
if(end >= size - 1) {
8384
end = size;
8485
}
85-
sections.emplace_back(geom, pts, i, end);
86+
sections.emplace_back(pts, i, end);
8687
i += FACET_SEQUENCE_SIZE;
8788
}
8889
}

0 commit comments

Comments
 (0)