25
25
// #include "sort.h"
26
26
#include " math_utils.h"
27
27
28
+ std::vector<double > SpatVector::distLonLat (std::vector<double > x, std::vector<double > y, std::string unit, std::string method, bool min, bool transp) {
28
29
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
+ /*
29
174
std::vector<double> SpatVector::nearestDistLonLat(std::vector<double> x, std::vector<double> y, std::string unit, std::string method) {
30
175
31
176
// for use with rasterize
@@ -139,8 +284,8 @@ std::vector<double> SpatVector::nearestDistLonLat(std::vector<double> x, std::ve
139
284
140
285
return d;
141
286
}
142
-
143
-
287
+ }
288
+ */
144
289
145
290
std::vector<double > SpatVector::distance (SpatVector x, bool pairwise, std::string unit, const std::string method) {
146
291
@@ -191,10 +336,10 @@ std::vector<double> SpatVector::distance(SpatVector x, bool pairwise, std::strin
191
336
// not ok for multi-points
192
337
if (gtype == " points" ) {
193
338
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 );
195
340
} else {
196
341
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 );
198
343
}
199
344
} else {
200
345
return geos_distance (x, pairwise, " " , m);
@@ -209,10 +354,10 @@ std::vector<double> SpatVector::distance(SpatVector x, bool pairwise, std::strin
209
354
std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
210
355
for (size_t j=0 ; j<x.size (); j++) {
211
356
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 );
213
358
214
359
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 );
216
361
217
362
d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
218
363
}
@@ -316,9 +461,9 @@ std::vector<double> SpatVector::distance(bool sequential, std::string unit, cons
316
461
std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
317
462
for (size_t i=0 ; i<n; i++) {
318
463
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 );
320
465
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 );
322
467
d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
323
468
tmp1 = tmp2;
324
469
xy1 = xy2;
@@ -332,9 +477,9 @@ std::vector<double> SpatVector::distance(bool sequential, std::string unit, cons
332
477
std::vector<std::vector<double >> xy1 = tmp1.coordinates ();
333
478
for (size_t j=(i+1 ); j<s; j++) {
334
479
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 );
336
481
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 );
338
483
d.push_back (std::min (vmin (d1, false ), vmin (d2, false )));
339
484
}
340
485
}
0 commit comments