-
Notifications
You must be signed in to change notification settings - Fork 293
/
gdal_geom.cpp
112 lines (103 loc) · 3.22 KB
/
gdal_geom.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <ogr_api.h>
#include <ogr_geometry.h>
#include <Rcpp.h>
#include "gdal_sf_pkg.h"
// [[Rcpp::export]]
Rcpp::NumericVector CPL_area(Rcpp::List sfc) {
std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
Rcpp::NumericVector out(sfc.length());
for (size_t i = 0; i < g.size(); i++) {
if (g[i]->getDimension() == 2) {
OGRwkbGeometryType gt = OGR_GT_Flatten(g[i]->getGeometryType());
if (gt == wkbMultiSurface || gt == wkbMultiPolygon) {
OGRGeometryCollection *gc = (OGRGeometryCollection *) g[i];
out[i] = gc->get_Area();
} else {
OGRSurface *surf = (OGRSurface *) g[i];
out[i] = surf->get_Area();
}
} else
out[i] = 0.0;
OGRGeometryFactory::destroyGeometry(g[i]);
}
return out;
}
// [[Rcpp::export]]
Rcpp::IntegerVector CPL_gdal_dimension(Rcpp::List sfc, bool NA_if_empty = true) {
std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
Rcpp::IntegerVector out(sfc.length());
for (size_t i = 0; i < g.size(); i++) {
if (NA_if_empty && g[i]->IsEmpty())
out[i] = NA_INTEGER;
else
out[i] = g[i]->getDimension();
OGRGeometryFactory f;
f.destroyGeometry(g[i]);
}
return out;
}
// [[Rcpp::export]]
Rcpp::NumericVector CPL_length(Rcpp::List sfc) {
std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
Rcpp::NumericVector out(sfc.length());
for (size_t i = 0; i < g.size(); i++) {
OGRwkbGeometryType gt = OGR_GT_Flatten(g[i]->getGeometryType());
switch (gt) {
case wkbPoint:
case wkbMultiPoint:
case wkbPolygon:
case wkbMultiPolygon:
out[i] = 0.0;
break;
case wkbLineString:
case wkbCircularString:
case wkbCompoundCurve:
case wkbCurve: {
OGRCurve *a = (OGRCurve *) g[i];
out[i] = a->get_Length();
}
break;
default: {
OGRGeometryCollection *a = (OGRGeometryCollection *) g[i];
out[i] = a->get_Length();
}
}
OGRGeometryFactory f;
f.destroyGeometry(g[i]);
}
return out;
}
// [[Rcpp::export]]
Rcpp::List CPL_gdal_segmentize(Rcpp::List sfc, double dfMaxLength = 0.0) {
if (dfMaxLength <= 0.0)
Rcpp::stop("argument dfMaxLength should be positive\n");
std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
for (size_t i = 0; i < g.size(); i++)
g[i]->segmentize(dfMaxLength);
Rcpp::List ret = sfc_from_ogr(g, true);
ret.attr("crs") = sfc.attr("crs");
return ret;
}
// [[Rcpp::export]]
Rcpp::List CPL_gdal_linestring_sample(Rcpp::List sfc, Rcpp::List distLst) {
if (sfc.size() != distLst.size())
Rcpp::stop("sfc and dist should have equal length"); // #nocov
std::vector<OGRGeometry *> g = ogr_from_sfc(sfc, NULL);
std::vector<OGRGeometry *> out(g.size());
for (size_t i = 0; i < g.size(); i++) {
if (wkbFlatten(g[i]->getGeometryType()) != wkbLineString)
Rcpp::stop("CPL_gdal_linestring_sample only available for LINESTRING"); // #nocov
OGRGeometryCollection *gc = new OGRGeometryCollection;
Rcpp::NumericVector dists = distLst[i];
for (int j = 0; j < dists.size(); j++) {
OGRPoint *poPoint = new OGRPoint;
((OGRLineString *) g[i])->Value(dists[j], poPoint);
gc->addGeometryDirectly(poPoint);
}
out[i] = OGRGeometryFactory::forceToMultiPoint(gc);
}
Rcpp::List ret = sfc_from_ogr(g, true); // releases g
ret = sfc_from_ogr(out, true); // releases out
ret.attr("crs") = sfc.attr("crs");
return ret;
}