18#include <geos/export.h>
19#include <geos/algorithm/distance/PointPairDistance.h>
20#include <geos/geom/CoordinateSequenceFilter.h>
21#include <geos/util/math.h>
25#include <unordered_map>
35class CoordinateSequence;
77 using DistanceToPairMap = std::unordered_map<double, std::array<std::size_t, 2>>;
99 std::size_t m_numRows;
100 std::size_t m_numCols;
101 double m_defaultValue;
109 MatrixStorage(std::size_t numRows, std::size_t numCols,
double defaultValue)
112 , m_defaultValue(defaultValue) {};
122 virtual double get(std::size_t i, std::size_t j)
const = 0;
130 virtual void set(std::size_t i, std::size_t j,
double value) = 0;
139 virtual bool isValueSet(std::size_t i, std::size_t j)
const = 0;
149 std::vector<double> m_matrix;
161 RectMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
164 m_matrix.resize(numRows * numCols, defaultValue);
167 double get(std::size_t i, std::size_t j)
const override {
168 return m_matrix[i * m_numCols + j];
171 void set(std::size_t i, std::size_t j,
double value)
override {
172 m_matrix[i * m_numCols + j] = value;
175 bool isValueSet(std::size_t i, std::size_t j)
const override {
176 return get(i, j) != m_defaultValue;
190 std::vector<double> m_v;
191 std::vector<std::size_t> m_ri;
192 std::vector<std::size_t> m_ci;
196 CsrMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue, std::size_t expectedValues)
199 m_v.resize(expectedValues);
200 m_ci.resize(expectedValues);
201 m_ri.resize(numRows + 1);
204 CsrMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
205 :
CsrMatrix(numRows, numCols, defaultValue, expectedValuesHeuristic(numRows, numCols))
215 std::size_t max = std::max(numRows, numCols);
216 return max * max / 10;
232 std::pair<bool, std::size_t>
233 cppBinarySearch(
const std::vector<std::size_t>& vec, std::size_t fromIndex, std::size_t toIndex, std::size_t key)
const {
235 if (fromIndex > toIndex || toIndex > vec.size())
239 auto first_it = vec.begin() +
static_cast<std::ptrdiff_t
>(fromIndex);
240 auto last_it = vec.begin() +
static_cast<std::ptrdiff_t
>(toIndex);
243 auto it = std::lower_bound(first_it, last_it, key);
246 auto result_index = std::distance(vec.begin(), it);
249 if (it != last_it && *it == key) {
251 return {
true, result_index};
254 return {
false, result_index};
258 std::pair<bool, std::size_t> indexOf(std::size_t i, std::size_t j)
const {
259 std::size_t cLow = m_ri[i];
260 std::size_t cHigh = m_ri[i+1];
261 if (cHigh <= cLow)
return {
false, cLow};
262 return cppBinarySearch(m_ci, cLow, cHigh, j);
265 double get(std::size_t i, std::size_t j)
const override {
267 std::pair<bool, std::size_t> vi = indexOf(i, j);
270 return m_defaultValue;
272 return m_v[vi.second];
275 void set(std::size_t i, std::size_t j,
double value)
override {
278 std::pair<bool, std::size_t> vi = indexOf(i, j);
284 ensureCapacity(m_ri[m_numRows] + 1);
287 for (std::size_t ii = i + 1; ii <= m_numRows; ii++)
291 std::size_t viv = vi.second;
292 for (std::size_t ii = m_ri[m_numRows]; ii > viv; ii--) {
293 m_ci[ii] = m_ci[ii - 1];
294 m_v[ii] = m_v[ii - 1];
302 m_v[vi.second] = value;
305 bool isValueSet(std::size_t i, std::size_t j)
const override {
306 auto r = indexOf(i, j);
315 if (required < m_v.size())
318 std::size_t increment = std::max(m_numRows, m_numCols);
319 m_v.resize(m_v.size() + increment);
320 m_ci.resize(m_v.size() + increment);
331 std::unordered_map<std::size_t, double> m_matrix;
341 HashMapMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
345 double get(std::size_t i, std::size_t j)
const override {
346 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
347 std::size_t key = i << halfsz | j;
348 auto it_found = m_matrix.find(key);
349 if (it_found != m_matrix.end()) {
350 return (*it_found).second;
353 return m_defaultValue;
357 void set(std::size_t i, std::size_t j,
double value)
override {
358 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
359 std::size_t key = i << halfsz | j;
360 m_matrix[key] = value;
363 bool isValueSet(std::size_t i, std::size_t j)
const override {
364 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
365 std::size_t key = i << halfsz | j;
366 auto it_found = m_matrix.find(key);
367 return it_found != m_matrix.end();
401 void setDensifyFraction(
double dFrac);
409 std::unique_ptr<PointPairDistance> ptDist;
410 double densifyFraction = -1.0;
424 DistanceToPairMap& distanceToPair,
425 double key, std::array<std::size_t, 2> val);
434 static std::unique_ptr<MatrixStorage> createMatrixStorage(
435 std::size_t rows, std::size_t cols);
447 static std::unique_ptr<PointPairDistance> computeFrechet(
450 std::vector<std::size_t>& diagonal,
452 DistanceToPairMap& distanceToPair);
463 static double getMinDistanceAtCorner(
476 void computeCoordinateDistances(
478 std::vector<std::size_t>& diagonal,
479 MatrixStorage& distances, DistanceToPairMap& distanceToPair);
490 static std::vector<std::size_t> bresenhamDiagonal(
491 std::size_t numCols, std::size_t numRows);
499 static std::unique_ptr<geom::CoordinateSequence> getDensifiedCoordinates(
508 : m_numSubSegs(static_cast<uint32_t>(util::round(1.0 / fraction)))
514 std::size_t index)
override;
516 bool isGeometryChanged()
const override {
520 bool isDone()
const override {
526 uint32_t m_numSubSegs;
Definition DiscreteFrechetDistance.h:187
static std::size_t expectedValuesHeuristic(std::size_t numRows, std::size_t numCols)
Definition DiscreteFrechetDistance.h:214
void ensureCapacity(std::size_t required)
Definition DiscreteFrechetDistance.h:314
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:275
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:305
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:265
std::pair< bool, std::size_t > cppBinarySearch(const std::vector< std::size_t > &vec, std::size_t fromIndex, std::size_t toIndex, std::size_t key) const
Definition DiscreteFrechetDistance.h:233
Definition DiscreteFrechetDistance.h:328
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:345
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:357
HashMapMatrix(std::size_t numRows, std::size_t numCols, double defaultValue)
Definition DiscreteFrechetDistance.h:341
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:363
Definition DiscreteFrechetDistance.h:95
virtual void set(std::size_t i, std::size_t j, double value)=0
virtual double get(std::size_t i, std::size_t j) const =0
MatrixStorage(std::size_t numRows, std::size_t numCols, double defaultValue)
Definition DiscreteFrechetDistance.h:109
virtual bool isValueSet(std::size_t i, std::size_t j) const =0
Definition DiscreteFrechetDistance.h:146
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:171
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:167
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:175
RectMatrix(std::size_t numRows, std::size_t numCols, double defaultValue)
Definition DiscreteFrechetDistance.h:161
The Fréchet distance is a measure of similarity between curves. Thus, it can be used like the Hausdor...
Definition DiscreteFrechetDistance.h:75
static double distance(const geom::Geometry &geom0, const geom::Geometry &geom1, double densityFrac)
static double distance(const geom::Geometry &geom0, const geom::Geometry &geom1)
DiscreteFrechetDistance(const geom::Geometry &geom0, const geom::Geometry &geom1)
Definition DiscreteFrechetDistance.h:87
std::array< geom::CoordinateXY, 2 > getCoordinates()
Interface for classes which provide operations that can be applied to the coordinates in a Coordinate...
Definition CoordinateSequenceFilter.h:56
The internal representation of a list of coordinates inside a Geometry.
Definition CoordinateSequence.h:57
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition Geometry.h:201
Basic namespace for all GEOS functionalities.
Definition geos.h:38