Skip to content

Commit 10219fe

Browse files
committed
Merge branch 'main' into fielddomain
2 parents cde88c3 + ce61d7f commit 10219fe

File tree

7 files changed

+61
-9
lines changed

7 files changed

+61
-9
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# version 1.0-13
22

3+
* use GEOS' overlayNG routines for (GEOS) Intersection, Difference, Union and SymDifference; #2143
4+
35
* added `duplicated.sf()`; #2138, #2140, thanks to @bart1
46

57
* `select.sf()` allows selecting the same column twice under different names; #1886

R/sample.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ st_sample = function(x, size, ...) UseMethod("st_sample")
3535
#'
3636
#' Fibonacci sampling see: Alvaro Gonzalez, 2010. Measurement of Areas on a Sphere Using Fibonacci and Latitude-Longitude Lattices.
3737
#' Mathematical Geosciences 42(1), p. 49-64
38+
#'
39+
#' For regular sampling on the sphere, see also \code{geosphere::regularCoordinates}.
3840
#'
3941
#' Sampling methods from package \code{spatstat} are interfaced (see examples), and need their own parameters to be set.
4042
#' For instance, to use \code{spatstat.random::rThomas()}, set \code{type = "Thomas"}.

configure

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3660,8 +3660,8 @@ printf "%s\n" "$as_me: Install failure: compilation and/or linkage problems." >&
36603660
as_fn_error $? "cannot link projection code" "$LINENO" 5
36613661
fi
36623662
3663-
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking GDAL: checking whether PROJ is available fur running:" >&5
3664-
printf %s "checking GDAL: checking whether PROJ is available fur running:... " >&6; }
3663+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking GDAL: checking whether PROJ is available for running:" >&5
3664+
printf %s "checking GDAL: checking whether PROJ is available for running:... " >&6; }
36653665
./gdal_proj
36663666
if test `echo $?` -ne 0 ; then
36673667
gdal_has_proj=no

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ if test "${gdal_has_proj}" = no; then
288288
AC_MSG_ERROR([cannot link projection code])
289289
fi
290290

291-
AC_MSG_CHECKING(GDAL: checking whether PROJ is available fur running:)
291+
AC_MSG_CHECKING(GDAL: checking whether PROJ is available for running:)
292292
./gdal_proj
293293
if test `echo $?` -ne 0 ; then
294294
gdal_has_proj=no

man/st_sample.Rd

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/geos.cpp

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ typedef char (* log_fn)(GEOSContextHandle_t, const GEOSGeometry *, const GEOSGeo
6262
typedef char (* log_prfn)(GEOSContextHandle_t, const GEOSPreparedGeometry *,
6363
const GEOSGeometry *);
6464
typedef GEOSGeom (* geom_fn)(GEOSContextHandle_t, const GEOSGeom, const GEOSGeom);
65+
typedef GEOSGeom (* geom_fnp)(GEOSContextHandle_t, const GEOSGeom, const GEOSGeom, double grid_size);
6566

6667
static int notice = 0; // global var to silently catch notice of illegal geoms, e.g. non-closed rings
6768

@@ -170,6 +171,17 @@ static std::vector<GEOSGeometry*> to_raw(std::vector<GeomPtr> & g) {
170171
return raw;
171172
}
172173

174+
double geos_grid_size(Rcpp::List x) {
175+
double precision = x.attr("precision");
176+
if (precision != 0.0)
177+
precision = 1. / precision;
178+
return precision;
179+
}
180+
181+
double geos_grid_size_xy(Rcpp::List x, Rcpp::List y) {
182+
return std::max(geos_grid_size(x), geos_grid_size(y));
183+
}
184+
173185
std::vector<GeomPtr> geometries_from_sfc(GEOSContextHandle_t hGEOSCtxt, Rcpp::List sfc, int *dim = NULL, bool stop_on_NULL = true) {
174186

175187
Rcpp::List sfc_cls = get_dim_sfc(sfc);
@@ -185,10 +197,8 @@ std::vector<GeomPtr> geometries_from_sfc(GEOSContextHandle_t hGEOSCtxt, Rcpp::Li
185197
Rcpp::stop("GEOS does not support XYM or XYZM geometries; use st_zm() to drop M\n"); // #nocov
186198

187199
#ifdef HAVE_390
188-
double precision = sfc.attr("precision");
189-
bool set_precision = precision != 0.0;
190-
if (set_precision)
191-
precision = 1/precision;
200+
double grid_size = geos_grid_size(sfc);
201+
bool set_precision = grid_size != 0.0;
192202
sfc.attr("precision") = 0.0; // so that CPL_write_wkb doesn't do the rounding;
193203
#endif
194204
Rcpp::List wkblst = CPL_write_wkb(sfc, true);
@@ -205,7 +215,7 @@ std::vector<GeomPtr> geometries_from_sfc(GEOSContextHandle_t hGEOSCtxt, Rcpp::Li
205215
}
206216
#ifdef HAVE_390
207217
else if (set_precision)
208-
g[i] = geos_ptr(GEOSGeom_setPrecision_r(hGEOSCtxt, g[i].get(), precision, GEOS_PREC_VALID_OUTPUT), hGEOSCtxt);
218+
g[i] = geos_ptr(GEOSGeom_setPrecision_r(hGEOSCtxt, g[i].get(), grid_size, GEOS_PREC_VALID_OUTPUT), hGEOSCtxt);
209219
#endif
210220
}
211221
GEOSWKBReader_destroy_r(hGEOSCtxt, wkb_reader);
@@ -933,6 +943,7 @@ Rcpp::List CPL_geos_op2(std::string op, Rcpp::List sfcx, Rcpp::List sfcy) {
933943
std::vector<GeomPtr> out;
934944
std::vector<double> index_x, index_y;
935945
std::vector<size_t> items(x.size());
946+
double grid_size = geos_grid_size_xy(sfcx, sfcy);
936947

937948
if (op == "intersection") {
938949

@@ -955,7 +966,11 @@ Rcpp::List CPL_geos_op2(std::string op, Rcpp::List sfcx, Rcpp::List sfcy) {
955966
std::sort(sel.begin(), sel.end());
956967
for (size_t item = 0; item < sel.size(); item++) {
957968
size_t j = sel[item];
969+
#ifndef HAVE_390
958970
GeomPtr geom = geos_ptr(GEOSIntersection_r(hGEOSCtxt, x[j].get(), y[i].get()), hGEOSCtxt);
971+
#else
972+
GeomPtr geom = geos_ptr(GEOSIntersectionPrec_r(hGEOSCtxt, x[j].get(), y[i].get(), grid_size), hGEOSCtxt);
973+
#endif
959974
if (geom == nullptr)
960975
Rcpp::stop("GEOS exception"); // #nocov
961976
if (! chk_(GEOSisEmpty_r(hGEOSCtxt, geom.get()))) {
@@ -968,19 +983,33 @@ Rcpp::List CPL_geos_op2(std::string op, Rcpp::List sfcx, Rcpp::List sfcy) {
968983
}
969984

970985
} else {
986+
#ifndef HAVE_390
971987
geom_fn geom_function;
972988
if (op == "union")
973989
geom_function = (geom_fn) GEOSUnion_r;
974990
else if (op == "difference")
975991
geom_function = (geom_fn) GEOSDifference_r;
976992
else if (op == "sym_difference")
977993
geom_function = (geom_fn) GEOSSymDifference_r;
994+
#else
995+
geom_fnp geom_function;
996+
if (op == "union")
997+
geom_function = (geom_fn) GEOSUnionPrec_r;
998+
else if (op == "difference")
999+
geom_function = (geom_fn) GEOSDifferencePrec_r;
1000+
else if (op == "sym_difference")
1001+
geom_function = (geom_fn) GEOSSymDifferencePrec_r;
1002+
#endif
9781003
else
9791004
Rcpp::stop("invalid operation"); // #nocov
9801005

9811006
for (size_t i = 0; i < y.size(); i++) {
9821007
for (size_t j = 0; j < x.size(); j++) {
1008+
#ifndef HAVE_390
9831009
GeomPtr geom = geos_ptr(geom_function(hGEOSCtxt, x[j].get(), y[i].get()), hGEOSCtxt);
1010+
#else
1011+
GeomPtr geom = geos_ptr(geom_function(hGEOSCtxt, x[j].get(), y[i].get(), grid_size), hGEOSCtxt);
1012+
#endif
9841013
if (geom == nullptr)
9851014
Rcpp::stop("GEOS exception"); // #nocov
9861015
if (! chk_(GEOSisEmpty_r(hGEOSCtxt, geom.get()))) {
@@ -1156,6 +1185,7 @@ Rcpp::List CPL_nary_difference(Rcpp::List sfc) {
11561185
GEOSContextHandle_t hGEOSCtxt = CPL_geos_init();
11571186
std::vector<GeomPtr> x = geometries_from_sfc(hGEOSCtxt, sfc, &dim);
11581187
std::vector<GeomPtr> out;
1188+
double grid_size = geos_grid_size(sfc);
11591189
// initialize trees to find overlapping areas quickly
11601190
for (size_t i = 0; i < x.size(); i++) {
11611191
// if i'th geometry in x is empty then skip it
@@ -1185,7 +1215,11 @@ Rcpp::List CPL_nary_difference(Rcpp::List sfc) {
11851215
// test if the items intersect with geom
11861216
if (chk_(GEOSIntersects_r(hGEOSCtxt, geom.get(), out[tree_sel[j]].get()))) {
11871217
// if they do then erase overlapping parts from geom
1218+
#ifndef HAVE_390
11881219
geom = geos_ptr(GEOSDifference_r(hGEOSCtxt, geom.get(), out[tree_sel[j]].get()), hGEOSCtxt);
1220+
#else
1221+
geom = geos_ptr(GEOSDifferencePrec_r(hGEOSCtxt, geom.get(), out[tree_sel[j]].get(), grid_size), hGEOSCtxt);
1222+
#endif
11891223
if (geom == nullptr)
11901224
Rcpp::stop("GEOS exception"); // #nocov
11911225
// ensure that geom is valid
@@ -1221,6 +1255,7 @@ Rcpp::List CPL_nary_intersection(Rcpp::List sfc) {
12211255
std::vector<GeomPtr> x = geometries_from_sfc(hGEOSCtxt, sfc, &dim);
12221256
std::vector<GeomPtr> out;
12231257
int errors = 0;
1258+
double grid_size = geos_grid_size(sfc);
12241259
#ifdef HAVE350
12251260
notice = 0;
12261261
GEOSContext_setNoticeMessageHandler_r(hGEOSCtxt,
@@ -1249,7 +1284,11 @@ Rcpp::List CPL_nary_intersection(Rcpp::List sfc) {
12491284
// iterate over items in query and erase overlapping areas in geom
12501285
for (size_t j = 0; j < tree_sel.size(); j++) {
12511286
size_t k = tree_sel[j];
1287+
#ifndef HAVE_390
12521288
GeomPtr inters = geos_ptr(GEOSIntersection_r(hGEOSCtxt, out[k].get(), geom.get()), hGEOSCtxt);
1289+
#else
1290+
GeomPtr inters = geos_ptr(GEOSIntersectionPrec_r(hGEOSCtxt, out[k].get(), geom.get(), grid_size), hGEOSCtxt);
1291+
#endif
12531292
if (geom.get() != nullptr) {
12541293
if (inters == nullptr)
12551294
errors++;
@@ -1259,7 +1298,11 @@ Rcpp::List CPL_nary_intersection(Rcpp::List sfc) {
12591298
if (geom == nullptr)
12601299
Rcpp::stop("GEOS exception"); // #nocov
12611300
// cut out inters from out[k]:
1301+
#ifndef HAVE_390
12621302
GeomPtr g = geos_ptr(GEOSDifference_r(hGEOSCtxt, out[k].get(), inters.get()), hGEOSCtxt);
1303+
#else
1304+
GeomPtr g = geos_ptr(GEOSDifferencePrec_r(hGEOSCtxt, out[k].get(), inters.get(), grid_size), hGEOSCtxt);
1305+
#endif
12631306
if (g == nullptr)
12641307
Rcpp::warning("GEOS difference returns NULL"); // #nocov
12651308
else {

src/stars.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ List CPL_read_gdal(CharacterVector fname, CharacterVector options, CharacterVect
366366
CharacterVector descriptions(bands.size());
367367
NumericMatrix ranges(bands.size(), 4);
368368
IntegerMatrix blocksizes(bands.size(), 2);
369+
IntegerVector colorInterp(bands.size());
369370
for (int i = 0; i < bands.size(); i++) {
370371
if ((poBand = poDataset->GetRasterBand(bands(i))) == NULL)
371372
stop("trying to read a band that is not present");
@@ -391,6 +392,7 @@ List CPL_read_gdal(CharacterVector fname, CharacterVector options, CharacterVect
391392
poBand->GetBlockSize(&nBlockXSize, &nBlockYSize);
392393
blocksizes(i, 0) = nBlockXSize;
393394
blocksizes(i, 1) = nBlockYSize;
395+
colorInterp(i) = (int) poBand->GetColorInterpretation();
394396
}
395397

396398
// get metadata items:
@@ -462,7 +464,8 @@ List CPL_read_gdal(CharacterVector fname, CharacterVector options, CharacterVect
462464
_["blocksizes"] = blocksizes,
463465
_["descriptions"] = descriptions,
464466
_["default_geotransform"] = default_geotransform,
465-
_["proxy"] = LogicalVector::create(!read_data)
467+
_["proxy"] = LogicalVector::create(!read_data),
468+
_["colorInterp"] = colorInterp
466469
);
467470
if (read_data) {
468471
ReturnList.attr("data") = read_gdal_data(poDataset, nodatavalue, nXOff, nYOff,

0 commit comments

Comments
 (0)