diff --git a/src/distVector.cpp b/src/distVector.cpp index 1e016a210..05ed4fcce 100644 --- a/src/distVector.cpp +++ b/src/distVector.cpp @@ -19,11 +19,10 @@ #include "spatVector.h" #include "distance.h" #include "geosphere.h" +#include "vecmath.h" - - -std::vector SpatVector::nearestDistLonLat(std::vector&x, std::vector&y, std::string unit, std::string method) { +std::vector SpatVector::nearestDistLonLat(std::vector x, std::vector y, std::string unit, std::string method) { // for use with rasterize std::vector d; @@ -89,7 +88,7 @@ std::vector SpatVector::nearestDistLonLat(std::vector&x, std::ve } size_t nseg = vx.size() - 1; for (size_t i=0; i SpatVector::distance(SpatVector x, bool pairwise, std::strin std::string gtype = type(); std::string xtype = x.type(); - if ((gtype != "points") || (xtype != "points")) { + if ((gtype == "points") && (xtype == "points")) { + std::vector> p = coordinates(); + std::vector> px = x.coordinates(); + return pointdistance(p[0], p[1], px[0], px[1], pairwise, m, lonlat, method); + } else if ((gtype == "points") || (xtype == "points")) { if (lonlat) { // not ok for multi-points if (gtype == "points") { @@ -185,19 +188,31 @@ std::vector SpatVector::distance(SpatVector x, bool pairwise, std::strin return nearestDistLonLat(xy[0], xy[1], unit, method); } } else { - std::string distfun=""; - d = geos_distance(x, pairwise, distfun); - if (m != 1) { - for (double &i : d) i *= m; + return geos_distance(x, pairwise, "", m); + } + } else { + if (lonlat) { + size_t n = size() * x.size(); + d.reserve(n); + + for (size_t i=0; i> xy1 = tmp1.coordinates(); + for (size_t j=0; j d1 = tmp2.nearestDistLonLat(xy1[0], xy1[1], unit, method); + + std::vector> xy2 = tmp2.coordinates(); + std::vector d2 = tmp1.nearestDistLonLat(xy2[0], xy2[1], unit, method); + + d.push_back(std::min(vmin(d1, false), vmin(d2, false))); + } } - return d; + } else { + d = geos_distance(x, pairwise, "", m); } } - - std::vector> p = coordinates(); - std::vector> px = x.coordinates(); - - return pointdistance(p[0], p[1], px[0], px[1], pairwise, m, lonlat, method); + return d; } @@ -218,12 +233,7 @@ std::vector SpatVector::distance(bool sequential, std::string unit, cons } std::string gtype = type(); if (gtype != "points") { - std::string distfun=""; - d = geos_distance(sequential, distfun); - if (m != 1) { - for (double &i : d) i *= m; - } - return d; + return geos_distance(sequential, "", m); } else { if (sequential) { std::vector> p = coordinates(); diff --git a/src/geos_methods.cpp b/src/geos_methods.cpp index 0d1bb983a..0728609a2 100644 --- a/src/geos_methods.cpp +++ b/src/geos_methods.cpp @@ -2349,7 +2349,7 @@ bool get_dist_fun(dist_fn &f, std::string s) { } -std::vector SpatVector::geos_distance(SpatVector v, bool parallel, std::string fun) { +std::vector SpatVector::geos_distance(SpatVector v, bool parallel, std::string fun, double m) { std::vector out; @@ -2415,10 +2415,13 @@ std::vector SpatVector::geos_distance(SpatVector v, bool parallel, std:: } } geos_finish(hGEOSCtxt); + if (m != 1) { + for (double &d : out) d *= m; + } return out; } -std::vector SpatVector::geos_distance(bool sequential, std::string fun) { +std::vector SpatVector::geos_distance(bool sequential, std::string fun, double m) { std::vector out; dist_fn distfun; @@ -2457,6 +2460,9 @@ std::vector SpatVector::geos_distance(bool sequential, std::string fun) out.push_back(0); } geos_finish(hGEOSCtxt); + if (m != 1) { + for (double &d : out) d *= m; + } return out; } @@ -2927,6 +2933,8 @@ SpatVector SpatVector::gaps() { +// also use GEOSPreparedNearestPoints_r() + SpatVector SpatVector::nearest_point(SpatVector v, bool parallel, const std::string method) { SpatVector out; diff --git a/src/spatVector.h b/src/spatVector.h index c8038a3f3..7afcfa36f 100644 --- a/src/spatVector.h +++ b/src/spatVector.h @@ -203,8 +203,7 @@ class SpatVector { // std::vector pointdistance_seq(const std::vector& px, const std::vector& py, double m, bool lonlat); - std::vector nearestDistLonLat(std::vector &x, std::vector &y, std::string unit, std::string method); - + std::vector nearestDistLonLat(std::vector x, std::vector y, std::string unit, std::string method); std::vector> knearest(size_t k); size_t size(); @@ -384,8 +383,8 @@ class SpatVector { std::vector equals_exact(SpatVector v, double tol); std::vector equals_exact(bool symmetrical, double tol); - std::vector geos_distance(SpatVector v, bool parallel, std::string fun); - std::vector geos_distance(bool sequential, std::string fun); + std::vector geos_distance(SpatVector v, bool parallel, std::string fun, double m); + std::vector geos_distance(bool sequential, std::string fun, double m); SpatVector nearest_point(SpatVector v, bool parallel, const std::string method); SpatVector nearest_point(const std::string method);