2525// #include "sort.h"
2626#include " math_utils.h"
2727
28+ std::vector<double > SpatVector::distLonLat (std::vector<double > x, std::vector<double > y, std::string unit, std::string method, bool min, bool transp) {
2829
30+ size_t np = x.size ();
31+ size_t ng = size ();
32+ double inf = std::numeric_limits<double >::infinity ();
33+ std::vector<std::vector<double >> d (np, std::vector<double >(ng, inf));
34+ if (type () == " polygons" ) {
35+ std::vector<int > inside = pointInPolygon (x, y);
36+ for (size_t i=0 ; i<ng; i++) {
37+ for (size_t j=0 ; j<np; j++) {
38+ if (inside[i*np+j]) {
39+ d[j][i] = 0 ;
40+ }
41+ }
42+ }
43+ }
44+
45+
46+ double r = 6378137 ;
47+ double m = 1 ;
48+ if (unit == " km" ) {
49+ r = 6378.137 ;
50+ m = 0.001 ;
51+ }
52+ std::function<double (double ,double ,double ,double ,double ,double ,double )> d2seg;
53+ if (method != " geo" ) {
54+ deg2rad (x);
55+ deg2rad (y);
56+ d2seg = dist2segment_cos;
57+ } else {
58+ d2seg = dist2segment_geo;
59+ }
60+
61+ std::vector<double > dout;
62+ std::vector<double > vx, vy;
63+
64+ if (type () == " polygons" ) {
65+ for (size_t g=0 ; g<ng; g++) {
66+ size_t nparts = geoms[g].size ();
67+ for (size_t h=0 ; h<nparts; h++) {
68+ vx = geoms[g].parts [h].x ;
69+ vy = geoms[g].parts [h].y ;
70+ if (method != " geo" ) {
71+ deg2rad (vx);
72+ deg2rad (vy);
73+ }
74+ size_t nseg = vx.size () - 1 ;
75+ for (size_t i=0 ; i<np; i++) {
76+ if (d[i][g] != 0 ) {
77+ for (size_t j=0 ; j<nseg; j++) {
78+ d[i][g] = std::min (d[i][g],
79+ d2seg (x[i], y[i], vx[j], vy[j], vx[j+1 ], vy[j+1 ], r));
80+ }
81+ }
82+ }
83+ size_t nh = geoms[g].parts [h].nHoles ();
84+ for (size_t k=0 ; k < nh; k++) {
85+ vx = geoms[g].parts [h].holes [k].x ;
86+ vy = geoms[g].parts [h].holes [k].y ;
87+ if (method != " geo" ) {
88+ deg2rad (vx);
89+ deg2rad (vy);
90+ }
91+ size_t nseg = vx.size () - 1 ;
92+ for (size_t i=0 ; i<np; i++) {
93+ if (d[i][g] != 0 ) {
94+ for (size_t j=0 ; j<nseg; j++) {
95+ d[i][g] = std::min (d[i][g],
96+ d2seg (x[i], y[i], vx[j], vy[j], vx[j+1 ], vy[j+1 ], r));
97+ }
98+ }
99+ }
100+ }
101+ }
102+ }
103+ } else if (type () == " lines" ) {
104+ for (size_t g=0 ; g<ng; g++) {
105+ size_t nparts = geoms[g].size ();
106+ for (size_t h=0 ; h<nparts; h++) {
107+ vx = geoms[g].parts [h].x ;
108+ vy = geoms[g].parts [h].y ;
109+ if (method != " geo" ) {
110+ deg2rad (vx);
111+ deg2rad (vy);
112+ }
113+ size_t nseg = vx.size () - 1 ;
114+ for (size_t i=0 ; i<np; i++) {
115+ for (size_t j=0 ; j<nseg; j++) {
116+ d[i][g] = std::min (d[i][g],
117+ d2seg (x[i], y[i], vx[j], vy[j], vx[j+1 ], vy[j+1 ], r));
118+ }
119+ }
120+ }
121+ }
122+
123+
124+ } else { // if (type() == "points") {
125+ std::vector<std::vector<double >> pts = coordinates ();
126+ if (method != " geo" ) {
127+ deg2rad (pts[0 ]);
128+ deg2rad (pts[1 ]);
129+ }
130+ return pointdistance (x, y, pts[0 ], pts[1 ], false , m, true , method);
131+ }
132+
133+
134+ if (min) {
135+ dout.reserve (d.size ());
136+ if (transp) {
137+ std::vector<double > temp (d.size ());
138+ for (size_t i=0 ; i<d[0 ].size (); i++) {
139+ for (size_t j=0 ; j<d.size (); j++) {
140+ temp[i] = d[j][i];
141+ }
142+ dout.push_back (vmin (temp, false ));
143+ }
144+ } else {
145+ for (size_t i=0 ; i<d.size (); i++) {
146+ dout.push_back (vmin (d[i], false ));
147+ }
148+ }
149+ } else {
150+ dout.reserve (np*ng);
151+ if (transp) {
152+ for (size_t i=0 ; i<d[0 ].size (); i++) {
153+ for (size_t j=0 ; j<d.size (); j++) {
154+ dout.push_back (d[j][i]);
155+ }
156+ }
157+ } else {
158+ size_t j = 0 ;
159+ for (size_t i=0 ; i<d.size (); i++) {
160+ dout.insert (dout.begin ()+j, d[i].begin (), d[i].end ());
161+ j += d[i].size ();
162+ }
163+ }
164+ }
165+ if ((method == " geo" ) && (m != 1 )) {
166+ for (double & v : dout) v *= m;
167+ }
168+
169+ return dout;
170+ }
171+
172+
173+ /*
29174std::vector<double> SpatVector::nearestDistLonLat(std::vector<double> x, std::vector<double> y, std::string unit, std::string method) {
30175
31176// for use with rasterize
@@ -139,8 +284,8 @@ std::vector<double> SpatVector::nearestDistLonLat(std::vector<double> x, std::ve
139284
140285 return d;
141286}
142-
143-
287+ }
288+ */
144289
145290std::vector<double > SpatVector::distance (SpatVector x, bool pairwise, std::string unit, const std::string method) {
146291
@@ -191,10 +336,10 @@ std::vector<double> SpatVector::distance(SpatVector x, bool pairwise, std::strin
191336 // not ok for multi-points
192337 if (gtype == " points" ) {
193338 std::vector<std::vector<double >> xy = coordinates ();
194- return x.nearestDistLonLat (xy[0 ], xy[1 ], unit, method);
339+ return x.distLonLat (xy[0 ], xy[1 ], unit, method, false , false );
195340 } else {
196341 std::vector<std::vector<double >> xy = x.coordinates ();
197- return nearestDistLonLat (xy[0 ], xy[1 ], unit, method);
342+ return distLonLat (xy[0 ], xy[1 ], unit, method, false , true );
198343 }
199344 } else {
200345 return geos_distance (x, pairwise, " " , m);
@@ -209,10 +354,10 @@ std::vector<double> SpatVector::distance(SpatVector x, bool pairwise, std::strin
209354 std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
210355 for (size_t j=0 ; j<x.size (); j++) {
211356 SpatVector tmp2 = x.subset_rows (long (j));
212- std::vector<double > d1 = tmp2.nearestDistLonLat (xy1[0 ], xy1[1 ], unit, method);
357+ std::vector<double > d1 = tmp2.distLonLat (xy1[0 ], xy1[1 ], unit, method, true , false );
213358
214359 std::vector<std::vector<double >> xy2 = tmp2.coordinates ();
215- std::vector<double > d2 = tmp1.nearestDistLonLat (xy2[0 ], xy2[1 ], unit, method);
360+ std::vector<double > d2 = tmp1.distLonLat (xy2[0 ], xy2[1 ], unit, method, true , false );
216361
217362 d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
218363 }
@@ -316,9 +461,9 @@ std::vector<double> SpatVector::distance(bool sequential, std::string unit, cons
316461 std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
317462 for (size_t i=0 ; i<n; i++) {
318463 SpatVector tmp2 = subset_rows ( (long )i+1 );
319- std::vector<double > d1 = tmp2.nearestDistLonLat (xy1[0 ], xy1[1 ], unit, method);
464+ std::vector<double > d1 = tmp2.distLonLat (xy1[0 ], xy1[1 ], unit, method, true , false );
320465 std::vector<std::vector<double >> xy2 = tmp2.coordinates ();
321- std::vector<double > d2 = tmp1.nearestDistLonLat (xy2[0 ], xy2[1 ], unit, method);
466+ std::vector<double > d2 = tmp1.distLonLat (xy2[0 ], xy2[1 ], unit, method, true , false );
322467 d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
323468 tmp1 = tmp2;
324469 xy1 = xy2;
@@ -332,9 +477,9 @@ std::vector<double> SpatVector::distance(bool sequential, std::string unit, cons
332477 std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
333478 for (size_t j=(i+1 ); j<s; j++) {
334479 SpatVector tmp2 = subset_rows ( long (j) );
335- std::vector<double > d1 = tmp2.nearestDistLonLat (xy1[0 ], xy1[1 ], unit, method);
480+ std::vector<double > d1 = tmp2.distLonLat (xy1[0 ], xy1[1 ], unit, method, true , false );
336481 std::vector<std::vector<double >> xy2 = tmp2.coordinates ();
337- std::vector<double > d2 = tmp1.nearestDistLonLat (xy2[0 ], xy2[1 ], unit, method);
482+ std::vector<double > d2 = tmp1.distLonLat (xy2[0 ], xy2[1 ], unit, method, true , false );
338483 d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
339484 }
340485 }
0 commit comments