Closed rCarto closed 5 years ago
Is this with the latest development code?
If yes, would you be able to dig deeper and find specific examples of the exact problems that these geometries have? E.g., “too few points”, how many points are there? Also, what do the self-intersections look like? The isoband algorithm shouldn’t produce any self-intersections, but it can produce degenerate polygons with zero height or width, and the validation algorithm may interpret those as not valid.
Yes v0.2.0 from github master. Here is an example of self intersection:
library(raster)
#> Le chargement a nécessité le package : sp
library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.1.2, PROJ 4.9.3
library(isoband)
library(lwgeom)
#> Linking to liblwgeom 2.5.0dev r16016, GEOS 3.5.1, PROJ 4.9.3
x <- c(365, 363, 362,
361, 359, 357, 358, 359, 360, 360, 359, 357, 357, 357, 359,
360, 359, 357, 362, 359, 359, 360, 359, 357, 370, 364, 361,
360, 359, 356, 379, 370, 364, 361, 359, 357, 388, 379, 370,
364, 361, 359)
m <- matrix(data = x, nrow = 7, byrow = TRUE)
raw <- isobands(x = 1:6, y = 7:1, z = m,
levels_low = c(350, 360, 380),
levels_high = c(360,380,390))
bands <- st_sfc(iso_to_sfg(raw))
plot(bands, col = 2:4)
plot(bands[1], col = 2)
plot(bands[2], col = 3)
st_is_valid(bands, reason=TRUE)
#> [1] "Self-intersection[4 4]" "Self-intersection[4 4]"
#> [3] "Valid Geometry"
What I was expecting:
band_valid <- st_make_valid(bands)
band_valid_poly <- st_collection_extract(band_valid, "POLYGON")
plot(band_valid_poly, col = 2:4)
Created on 2019-03-13 by the reprex package (v0.2.1)
Great example, thanks! It looks to me like the problem occurs at the original isobanding stage, not the conversion to sf. I'll look into this to see whether there's a good reason the code fails to merge the two polygons or whether it's an oversight that can be fixed.
Do you also have a similar example for the Too few points in geometry component
error?
The problem is that mathematically the isobanding algorithm is doing the right thing here. There's a vertical line of zero width that belongs to the green band, not the red one. I'll have to ponder whether this can be addressed within isoband. Maybe st_make_valid()
is always going to be required.
library(isoband)
x <- c(365, 363, 362,
361, 359, 357, 358, 359, 360, 360, 359, 357, 357, 357, 359,
360, 359, 357, 362, 359, 359, 360, 359, 357, 370, 364, 361,
360, 359, 356, 379, 370, 364, 361, 359, 357, 388, 379, 370,
364, 361, 359)
m <- matrix(data = x, nrow = 7, byrow = TRUE)
plot_iso(m, vlo = 360, vhi = 370, fill_band = 3)
Created on 2019-03-13 by the reprex package (v0.2.1)
All right. I'm ok with the use of st_make_valid()
anyway :-) .
Here is an example with Too few points in geometry component...
:
library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.1.2, PROJ 4.9.3
library(isoband)
library(lwgeom)
#> Linking to liblwgeom 2.5.0dev r16016, GEOS 3.5.1, PROJ 4.9.3
xx <- c(3237, 4000, 4000, 3752, 2989, 3313, 4043,
4026, 4009, 3993,4270, 5000, 5000, 4996, 4426, 4220,
4935, 4923, 4651, 3394, 3190, 3531, 2577,
1629, 674)
m <- matrix(data = xx, nrow = 5, byrow = TRUE)
raw <- isobands(x = 1:5, y = 5:1, z = m,
levels_low = c( 674, 2000, 4000),
levels_high = c(2000,4000,5000))
bands <- st_sfc(iso_to_sfg(raw))
plot(bands, col = 2:4)
st_is_valid(bands, reason=TRUE)
#> [1] "Valid Geometry"
#> [2] "Valid Geometry"
#> [3] "Too few points in geometry component[3 3]"
band_valid <- st_make_valid(bands)
band_valid_poly <- st_collection_extract(band_valid, "POLYGON")
plot(band_valid_poly, col = 2:4)
Created on 2019-03-14 by the reprex package (v0.2.1)
Thanks. Again the isobanding algorithm is technically correct, so that's comforting. There's a ridge of height zero that doesn't belong to the blue band. However, I thought I had filtered out those degenerate polygons in the conversion to sf, so I'll have to look more closely what is happening here.
library(isoband)
xx <- c(3237, 4000, 4000, 3752, 2989, 3313, 4043,
4026, 4009, 3993,4270, 5000, 5000, 4996, 4426, 4220,
4935, 4923, 4651, 3394, 3190, 3531, 2577,
1629, 674)
m <- matrix(data = xx, nrow = 5, byrow = TRUE)
plot_iso(m, vlo = 4000, vhi = 5000, fill_band = 4)
Created on 2019-03-14 by the reprex package (v0.2.1)
I've decided to close this by improving the documentation of iso_to_sfg()
. There's no simple way to avoid these invalid geometries, and lwgeom::st_make_valid()
is probably the best way to deal with them. So now the documentation states this.
May be related to #5 .
Here is a piece of code producing isobands as sf polygons from a raster.
iso is composed of valid and invalid geometries. It is not possible to use geometric operators (e.g.
st_intersection()
) on these geometries.I use
lwgeom::st_make_valid()
to clean the geometries. It produces a GEOMETRY column (polylines and polygons), hence the use ofst_collection_extract()
.Created on 2019-03-13 by the reprex package (v0.2.1)