r-spatial / sf

Simple Features for R
https://r-spatial.github.io/sf/
Other
1.33k stars 294 forks source link

st_as_sf names geometry column 'x' #2429

Closed DOSull closed 1 month ago

DOSull commented 1 month ago

Running this code [specific corrdinates near Wellington in NZTM projection]

set.seed(0)
points <- data.frame(x = runif(100, -5000, 5000) + 1.75e6,
                     y = runif(100, -5000, 5000) + 5.43e6) |>
  st_as_sf(coords = c("x", "y"), crs = 2193)

polys <- points |>
  st_union() |>
  st_voronoi() |>
  st_cast() |>
  st_as_sf()

polys

yields

Simple feature collection with 100 features and 0 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 1735338 ymin: 5415335 xmax: 1764715 ymax: 5444723
Projected CRS: NZGD2000 / New Zealand Transverse Mercator 2000
First 10 features:
                                x
1  POLYGON ((1735338 5438858, ...

when I would expect st_as_sf to yield a simple feature collection with the geometry column called geom or geometry. If I use st_sf() in place of st_as_sf() I get the even stranger seeming

Simple feature collection with 100 features and 0 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 1735187 ymin: 5415129 xmax: 1764850 ymax: 5444745
Projected CRS: NZGD2000 / New Zealand Transverse Mercator 2000
First 10 features:
   st_cast.st_voronoi.st_union.points...
1         POLYGON ((1735187 5438683, ...

Clearly, I can easily rename(geom = x) or st_set_geometry(value = "geom"), it just seems odd that I should have to!

What am I missing?

edzer commented 1 month ago

I agree, also because


> st_as_sf(data.frame(polys))
Simple feature collection with 100 features and 0 fields
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 1735338 ymin: 5415335 xmax: 1764715 ymax: 5444723
Projected CRS: NZGD2000 / New Zealand Transverse Mercator 2000
First 10 features:
                         geometry
1  POLYGON ((1735338 5438858, ...
...
DOSull commented 1 month ago

That's fine, but the st_as_sf help says that the parameter can be an sfc object

## S3 method for class 'sfc'
st_as_sf(x, ...)

There's no hint that if I supply an sfc then I'll get an sf object with an unusually named geometry column. Or that I need the intervening step of converting to a dataframe to get an sf object with a geometry columned called geometry! Knowing the behaviour, there are simple workarounds, and your comment shows another, but I don't think this behaviour is what is implied by the help documentation.

edzer commented 1 month ago

https://github.com/r-spatial/sf/commit/e5bce2e9726c1dd716f4d674ed04810f3252ec2e fixed this.

edzer commented 3 weeks ago

I reverted this, as it breaks several reverse dependencies. Feel free to chase them to change their code and I'll apply this once more. It's not a bug.

From CRAN:

*** Changes to worse in reverse dependencies ***
Debian: [<https://win-builder.r-project.org/incoming_pretest/sf_1.0-17_20240905_121833/reverseDependencies/summary.txt>](https://win-builder.r-project.org/incoming_pretest/sf_1.0-17_20240905_121833/reverseDependencies/summary.txt)
GDAtools, amt, eSDM, googletraffic, ofpetrial, rangeMapper, roads, sfnetworks, spbal, spdep, ulex, waywiser

some of these, like eSDM are cased by other changes see https://github.com/SWFSC/eSDM/issues/17

rsbivand commented 3 weeks ago

Failure in spdep:

sq <- st_polygon(list(rbind(c(0,0), c(1,0), c(1,1), c(0,1), c(0,0))))
sq2 <- sq + c(0,1)
sq3 <- sq + c(1,0)
sq4 <- sq + c(1,1)
gm <- st_sfc(list(sq, sq2, sq3, sq4))
df <- st_as_sf(gm, id=1:4)

Here, the id variable is left outside the data.frame object. df <- st_as_sf(gm) passes. Arguably, the usage in spdep was wrong, updated to st_as_sf(data.frame(gm, id=1:4)).