diff --git a/R/normalize-sf.R b/R/normalize-sf.R index 40916214..eaf2b93f 100644 --- a/R/normalize-sf.R +++ b/R/normalize-sf.R @@ -9,6 +9,8 @@ metaData.sf <- function(obj) { sanitize_sf <- function(obj) { sanitized_sf <- sf::st_geometry(obj) attr(sanitized_sf, "names") <- NULL + # Remove Z and M dimensions if present + sanitized_sf <- sf::st_zm(sanitized_sf) sanitized_sf } @@ -26,6 +28,9 @@ pointData.sfc_POINT <- function(obj) { } check_crs(obj) + + # Remove Z and M dimensions if present + obj <- sf::st_zm(obj) structure( sf_coords(do.call("rbind", obj)), @@ -36,6 +41,9 @@ pointData.sfc_POINT <- function(obj) { #' @export pointData.POINT <- function(obj) { check_crs(obj) + + # Remove Z and M dimensions if present + obj <- sf::st_zm(obj) bbox <- sf_bbox(obj) @@ -79,6 +87,9 @@ polygonData.sf <- function(obj) { #' @export polygonData.sfc <- function(obj) { check_crs(obj) + + # Remove Z and M dimensions if present + obj <- sf::st_zm(obj) structure( to_multipolygon_list(obj), @@ -88,6 +99,9 @@ polygonData.sfc <- function(obj) { #' @export polygonData.sfg <- function(obj) { + # Remove Z and M dimensions if present + obj <- sf::st_zm(obj) + structure( to_multipolygon_list(obj), bbox = sf_bbox(obj) diff --git a/tests/testthat/test-normalize.R b/tests/testthat/test-normalize.R index ab9c4ac6..3b788fd8 100644 --- a/tests/testthat/test-normalize.R +++ b/tests/testthat/test-normalize.R @@ -146,3 +146,93 @@ test_that("fails if not lat/long columns present", { "Couldn't infer longitude/latitude columns" ) }) + +# ZM dimensions ----------------------------------------------------------- + +test_that("derivePolygons handles sf LINESTRING with Z dimension", { + # Create a LINESTRING with Z dimension + s1 <- sf::st_linestring(matrix(c(0, 1, 0, 1, 5, 6), ncol = 3)) + + # Should work without error + result <- derivePolygons(s1) + verifyPolygonData(result) + + # Check that we get 2D coordinates (lng, lat only) + coords <- result[[1]][[1]][[1]] + expect_named(coords, c("lng", "lat")) + expect_equal(coords$lng, c(0, 1)) + expect_equal(coords$lat, c(0, 1)) +}) + +test_that("derivePolygons handles sf LINESTRING with ZM dimensions", { + # Create a LINESTRING with ZM dimensions + s2 <- sf::st_linestring(matrix(c(0, 1, 0, 1, 5, 6, 2, 3), ncol = 4), dim = "XYZM") + + # Should work without error + result <- derivePolygons(s2) + verifyPolygonData(result) + + # Check that we get 2D coordinates (lng, lat only) + coords <- result[[1]][[1]][[1]] + expect_named(coords, c("lng", "lat")) + expect_equal(coords$lng, c(0, 1)) + expect_equal(coords$lat, c(0, 1)) +}) + +test_that("derivePolygons handles sf object with Z dimension", { + # Create a simple feature collection with Z dimension + s1 <- sf::st_linestring(matrix(c(0, 1, 0, 1, 5, 6), ncol = 3)) + sfc <- sf::st_sfc(s1) + sf_obj <- sf::st_sf(id = 1, geometry = sfc) + + # Should work without error + result <- derivePolygons(sf_obj) + verifyPolygonData(result) + + # Check that we get 2D coordinates (lng, lat only) + coords <- result[[1]][[1]][[1]] + expect_named(coords, c("lng", "lat")) + expect_equal(coords$lng, c(0, 1)) + expect_equal(coords$lat, c(0, 1)) +}) + +test_that("derivePoints handles sf POINT with Z dimension", { + # Create a POINT with Z dimension + p1 <- sf::st_point(c(1, 2, 3)) + + # Should work without error + result <- derivePoints(p1) + expect_named(result, c("lng", "lat")) + expect_equal(result$lng, 1) + expect_equal(result$lat, 2) +}) + +test_that("derivePoints handles sf object with Z dimension", { + # Create a simple feature collection with Z dimension + p1 <- sf::st_point(c(1, 2, 3)) + p2 <- sf::st_point(c(4, 5, 6)) + sfc <- sf::st_sfc(p1, p2) + sf_obj <- sf::st_sf(id = 1:2, geometry = sfc) + + # Should work without error + result <- derivePoints(sf_obj) + expect_named(result, c("lng", "lat")) + expect_equal(result$lng, c(1, 4)) + expect_equal(result$lat, c(2, 5)) +}) + +test_that("derivePolygons handles sfc with Z dimension", { + # Test with sfc_LINESTRING directly (like in the issue example) + s1 <- sf::st_linestring(matrix(c(0, 1, 0, 1, 5, 6), ncol = 3)) + sfc <- sf::st_sfc(s1) + + # Should work without error + result <- derivePolygons(sfc) + verifyPolygonData(result) + + # Check that we get 2D coordinates (lng, lat only) + coords <- result[[1]][[1]][[1]] + expect_named(coords, c("lng", "lat")) + expect_equal(coords$lng, c(0, 1)) + expect_equal(coords$lat, c(0, 1)) +})