1

I am currently working with multiple shapefiles in R and working towards rasterizing them using a combination of functions from sf,terra and stars. However, I noticed while reading in a shapefile that terra::vect() and sf::st_read() are providing me with different extents for the same shapefile. Please see below.

 terra::vect(shapefile1)
 class       : SpatVector 
 geometry    : polygons 
 dimensions  : 538, 3  (geometries, attributes)
 extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 
 names       :    id       class gridcode
 type        : <int>       <chr>    <int>
 values      :     1 settlements        2
                   2 settlements        2
                   3 settlements        2

sf::st_read(shapefile1)
Reading layer `1870-settlements' from data source 
  `data\spatial\1870-settlements.shp' 
  using driver `ESRI Shapefile'
replacing null geometries with empty geometries
Simple feature collection with 538 features and 3 fields (with 1 geometry empty)
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 76.492 ymin: 11.22461 xmax: 77.00837 ymax: 11.53395
Geodetic CRS:  WGS 84

Why am I getting this discrepancy? Such an error surely impacts future analyses.

Edit: Adding a link to the file - https://drive.google.com/drive/u/2/folders/1uDVQt1F64rUTfCXclwr-sM-oFjyJ2NwV

3
  • Hard to tell without your data files. Maybe one is working in spherical coordinates and considering the bounds of great circle curves between points and not simple straight lines in lat-long cartesian space. Can you share your data file or show the same problem with public data?
    – Spacedman
    Commented Apr 14, 2022 at 19:39
  • I am guessing it has to do with this message replacing null geometries with empty geometries and it would be very helpful if you could share your file (even if privately) Commented Apr 14, 2022 at 22:32
  • @Spacedman and RobertHijmans - added a link to the file. Commented Apr 15, 2022 at 13:37

2 Answers 2

3

The incorrect extent shown by terra does not appear to affect anything of importance, but this bug has now been fixed in terra version 1.5-28 (currently the development version, which you may be able to install with install.packages('terra', repos='https://rspatial.r-universe.dev'))

Records that do not have an associated geometry now get an extent that is NA (as in sf).

library(terra)
# terra 1.5.28
v <- vect("1870-nilgiris-settlements.shp")
v
# class       : SpatVector 
# geometry    : polygons 
# dimensions  : 538, 3  (geometries, attributes)
# extent      : 76.492, 77.00837, 11.22461, 11.53395  (xmin, xmax, ymin, ymax)
# source      : 1870-nilgiris-settlements.shp
# coord. ref. : lon/lat WGS 84 (EPSG:4326) 
# names       :    id       class gridcode
# type        : <int>       <chr>    <int>
# values      :     1 settlements        2
#                   2 settlements        2
#                   3 settlements        2

i <- emptyGeoms(v)
i
#[1] 371
v[i]
# class       : SpatVector 
# geometry    : null 
# dimensions  : 1, 3  (geometries, attributes)
# extent      : NaN, NaN, NaN, NaN  (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84 (EPSG:4326) 
# names       :    id       class gridcode
# type        : <int>       <chr>    <int>
# values      :   371 settlements        2
2

The 371st feature has a null geometry, which terra assigns the extent of "anywhere on the globe":

> v[371]
 class       : SpatVector 
 geometry    : unknown 
 dimensions  : 1, 3  (geometries, attributes)
 extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
 coord. ref. : lon/lat WGS 84 (EPSG:4326) 
 names       :    id       class gridcode
 type        : <int>       <chr>    <int>
 values      :   371 settlements        2

Whereas sf says "Its... no idea":

> s[371,]
Simple feature collection with 1 feature and 3 fields (with 1 geometry empty)
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: NA ymin: NA xmax: NA ymax: NA
Geodetic CRS:  WGS 84
     id       class gridcode      geometry
371 371 settlements        2 POLYGON EMPTY

There's an argument for either approach, I guess. You could also argue that sf should return NA for the bounds of anything with at least one feature with NA bounds, but it doesn't:

> s[371:372,]
Simple feature collection with 2 features and 3 fields (with 1 geometry empty)
Geometry type: POLYGON
Dimension:     XY
Bounding box:  xmin: 76.87192 ymin: 11.49424 xmax: 76.87287 ymax: 11.49516
Geodetic CRS:  WGS 84
     id       class gridcode                       geometry
371 371 settlements        2                  POLYGON EMPTY
372 372 settlements        2 POLYGON ((76.87235 11.49516...

Interesting different behaviour between packages though, might be worth reporting to the maintainers.

I don't know what the Simple Features standard says about bounds for missing geometries. In the end I guess you'll want to fix this point anyway, either dropping it from analyses or giving it a location.

4
  • 1
    Are you planning on pointing this out to the terra or sf developers? This seems like behavior that should follow an excepted standard, on how null geometry is handled when defining that extent and throw a warning about null geometry being present. If you do not want to deal with it, I would be happy to like this post and point out the discrepancy in behavior. Personally, I would prefer to not have a null geometry influence the extent. Commented Apr 15, 2022 at 14:39
  • @JeffreyEvans Please go ahead and raise an issue, if you wouldn't mind! Commented Apr 15, 2022 at 15:25
  • 1
    @JeffreyEvans maybe discuss on r-sig-geo mailing list first? Might get a consensus between sf, terra, and other package authors first. I'll kick it off...
    – Spacedman
    Commented Apr 15, 2022 at 15:41
  • What terra did was clearly wrong, IMO. A geometry that is not, does not have an extent. Commented Apr 17, 2022 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.