Skip to content

Commit d179cfd

Browse files
committed
m
1 parent af2a1e9 commit d179cfd

File tree

3 files changed

+158
-12
lines changed

3 files changed

+158
-12
lines changed

R/coerce.R

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,8 +313,9 @@ setMethod("as.lines", signature(x="matrix"),
313313
if (ncol(x) == 2) {
314314
nr <- nrow(x)
315315
p@pntr$setGeometry("lines", rep(1, nr), rep(1, nr), x[,1], x[,2], rep(FALSE, nr))
316+
crs(p) <- crs
316317
} else if (ncol(x) == 4) {
317-
p@pntr$setLinesStartEnd(x, crs)
318+
p@pntr$setLinesStartEnd(x, crs(crs))
318319
} else {
319320
error("expecting a two or four column matrix", "as.lines")
320321
}

man/sample.Rd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ In order to assure regularity when requesting a regular sample, the number of ce
2929

3030
\arguments{
3131
\item{x}{SpatRaster, SpatVector or SpatExtent}
32-
\item{size}{numeric. The sample size. If \code{x} is a SpatVector, you can also provide a vector of the same length as \code{x} in which case sampling is done separately for each geometry. If \code{x} is a SpatRaster, and you are using \code{method="regular"} you can specify the size as two numbers (number of rows and columns)}
32+
\item{size}{numeric. The sample size. If \code{x} is a SpatVector, you can also provide a vector of the same length as \code{x} in which case sampling is done separately for each geometry. If \code{x} is a SpatRaster, and you are using \code{method="regular"} you can specify the size as two numbers (number of rows and columns). Note that when using \code{method="stratified"}, the sample size is returned for each stratum}
3333
\item{method}{character. Should be "regular" or "random", If \code{x} is a \code{SpatRaster}, it can also be "stratified" (each value in \code{x} is a stratum) or "weights" (each value in \code{x} is a probability weight)}
3434
\item{replace}{logical. If \code{TRUE}, sampling is with replacement (if \code{method="random"})}
3535
\item{na.rm}{logical. If \code{TRUE}, \code{NAs} are removed. Only used with random sampling of cell values. That is with \code{method="random", as.raster=FALSE, cells=FALSE}}

src/distVector.cpp

Lines changed: 155 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,152 @@
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+
/*
29174
std::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

145290
std::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

Comments
 (0)