18#include <geos/export.h>
19#include <geos/algorithm/distance/PointPairDistance.h>
20#include <geos/geom/CoordinateSequenceFilter.h>
21#include <geos/util/math.h>
24#include <unordered_map>
34class CoordinateSequence;
76 using DistanceToPairMap = std::unordered_map<double, std::array<std::size_t, 2>>;
98 std::size_t m_numRows;
99 std::size_t m_numCols;
100 double m_defaultValue;
108 MatrixStorage(std::size_t numRows, std::size_t numCols,
double defaultValue)
111 , m_defaultValue(defaultValue) {};
121 virtual double get(std::size_t i, std::size_t j)
const = 0;
129 virtual void set(std::size_t i, std::size_t j,
double value) = 0;
138 virtual bool isValueSet(std::size_t i, std::size_t j)
const = 0;
148 std::vector<double> m_matrix;
160 RectMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
163 m_matrix.resize(numRows * numCols, defaultValue);
166 double get(std::size_t i, std::size_t j)
const override {
167 return m_matrix[i * m_numCols + j];
170 void set(std::size_t i, std::size_t j,
double value)
override {
171 m_matrix[i * m_numCols + j] = value;
174 bool isValueSet(std::size_t i, std::size_t j)
const override {
175 return get(i, j) != m_defaultValue;
189 std::vector<double> m_v;
190 std::vector<std::size_t> m_ri;
191 std::vector<std::size_t> m_ci;
195 CsrMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue, std::size_t expectedValues)
198 m_v.resize(expectedValues);
199 m_ci.resize(expectedValues);
200 m_ri.resize(numRows + 1);
203 CsrMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
204 :
CsrMatrix(numRows, numCols, defaultValue, expectedValuesHeuristic(numRows, numCols))
214 std::size_t max = std::max(numRows, numCols);
215 return max * max / 10;
231 std::pair<bool, std::size_t>
232 cppBinarySearch(
const std::vector<std::size_t>& vec, std::size_t fromIndex, std::size_t toIndex, std::size_t key)
const {
234 if (fromIndex > toIndex || toIndex > vec.size())
238 auto first_it = vec.begin() +
static_cast<std::ptrdiff_t
>(fromIndex);
239 auto last_it = vec.begin() +
static_cast<std::ptrdiff_t
>(toIndex);
242 auto it = std::lower_bound(first_it, last_it, key);
245 auto result_index = std::distance(vec.begin(), it);
248 if (it != last_it && *it == key) {
250 return {
true, result_index};
253 return {
false, result_index};
257 std::pair<bool, std::size_t> indexOf(std::size_t i, std::size_t j)
const {
258 std::size_t cLow = m_ri[i];
259 std::size_t cHigh = m_ri[i+1];
260 if (cHigh <= cLow)
return {
false, cLow};
261 return cppBinarySearch(m_ci, cLow, cHigh, j);
264 double get(std::size_t i, std::size_t j)
const override {
266 std::pair<bool, std::size_t> vi = indexOf(i, j);
269 return m_defaultValue;
271 return m_v[vi.second];
274 void set(std::size_t i, std::size_t j,
double value)
override {
277 std::pair<bool, std::size_t> vi = indexOf(i, j);
283 ensureCapacity(m_ri[m_numRows] + 1);
286 for (std::size_t ii = i + 1; ii <= m_numRows; ii++)
290 std::size_t viv = vi.second;
291 for (std::size_t ii = m_ri[m_numRows]; ii > viv; ii--) {
292 m_ci[ii] = m_ci[ii - 1];
293 m_v[ii] = m_v[ii - 1];
301 m_v[vi.second] = value;
304 bool isValueSet(std::size_t i, std::size_t j)
const override {
305 auto r = indexOf(i, j);
314 if (required < m_v.size())
317 std::size_t increment = std::max(m_numRows, m_numCols);
318 m_v.resize(m_v.size() + increment);
319 m_ci.resize(m_v.size() + increment);
330 std::unordered_map<std::size_t, double> m_matrix;
340 HashMapMatrix(std::size_t numRows, std::size_t numCols,
double defaultValue)
344 double get(std::size_t i, std::size_t j)
const override {
345 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
346 std::size_t key = i << halfsz | j;
347 auto it_found = m_matrix.find(key);
348 if (it_found != m_matrix.end()) {
349 return (*it_found).second;
352 return m_defaultValue;
356 void set(std::size_t i, std::size_t j,
double value)
override {
357 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
358 std::size_t key = i << halfsz | j;
359 m_matrix[key] = value;
362 bool isValueSet(std::size_t i, std::size_t j)
const override {
363 static constexpr std::size_t halfsz =
sizeof(std::size_t) * 4;
364 std::size_t key = i << halfsz | j;
365 auto it_found = m_matrix.find(key);
366 return it_found != m_matrix.end();
400 void setDensifyFraction(
double dFrac);
408 std::unique_ptr<PointPairDistance> ptDist;
409 double densifyFraction = -1.0;
423 DistanceToPairMap& distanceToPair,
424 double key, std::array<std::size_t, 2> val);
433 static std::unique_ptr<MatrixStorage> createMatrixStorage(
434 std::size_t rows, std::size_t cols);
446 static std::unique_ptr<PointPairDistance> computeFrechet(
449 std::vector<std::size_t>& diagonal,
451 DistanceToPairMap& distanceToPair);
462 static double getMinDistanceAtCorner(
475 void computeCoordinateDistances(
477 std::vector<std::size_t>& diagonal,
478 MatrixStorage& distances, DistanceToPairMap& distanceToPair);
489 static std::vector<std::size_t> bresenhamDiagonal(
490 std::size_t numCols, std::size_t numRows);
498 static std::unique_ptr<geom::CoordinateSequence> getDensifiedCoordinates(
507 : m_numSubSegs(static_cast<uint32_t>(util::round(1.0 / fraction)))
513 std::size_t index)
override;
515 bool isGeometryChanged()
const override {
519 bool isDone()
const override {
525 uint32_t m_numSubSegs;
Definition DiscreteFrechetDistance.h:186
static std::size_t expectedValuesHeuristic(std::size_t numRows, std::size_t numCols)
Definition DiscreteFrechetDistance.h:213
void ensureCapacity(std::size_t required)
Definition DiscreteFrechetDistance.h:313
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:274
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:304
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:264
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:232
Definition DiscreteFrechetDistance.h:327
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:344
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:356
HashMapMatrix(std::size_t numRows, std::size_t numCols, double defaultValue)
Definition DiscreteFrechetDistance.h:340
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:362
Definition DiscreteFrechetDistance.h:94
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:108
virtual bool isValueSet(std::size_t i, std::size_t j) const =0
Definition DiscreteFrechetDistance.h:145
void set(std::size_t i, std::size_t j, double value) override
Definition DiscreteFrechetDistance.h:170
double get(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:166
bool isValueSet(std::size_t i, std::size_t j) const override
Definition DiscreteFrechetDistance.h:174
RectMatrix(std::size_t numRows, std::size_t numCols, double defaultValue)
Definition DiscreteFrechetDistance.h:160
The Fréchet distance is a measure of similarity between curves. Thus, it can be used like the Hausdor...
Definition DiscreteFrechetDistance.h:74
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:86
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:56
Basic implementation of Geometry, constructed and destructed by GeometryFactory.
Definition Geometry.h:196
Basic namespace for all GEOS functionalities.
Definition geos.h:38