terra icon indicating copy to clipboard operation
terra copied to clipboard

Create extent polygon from SpatRaster or SpatVector

Open brownag opened this issue 2 years ago • 2 comments

Hello!

as.polygons(<SpatExtent>) returns a bounding box polygon, which is awesome, but it has no CRS. This makes sense because the SpatExtent does not have a way to keep track of CRS; in this case it needs to be set explicitly for the result SpatVector with crs argument.

I often have to do something using vector objects such as shown the below, and almost always I forget to specify crs to as.polygons() the first time around

library(terra)
x <- vect(system.file("ex/lux.shp", package="terra"))
y <- as.polygons(ext(x), crs = crs(x))
plot(y)
plot(x, add=TRUE)

I often stumble over this, so I wanted to ask a question / make a suggestion:

  • Is there a reason why a SpatExtent object does not store the CRS that the boundaries are in?

  • Would something like as.ext.polygon() make sense to have in lieu of source CRS being explicitly linked to SpatExtent?

as.ext.polygon <- function(x, crs = crs(x)) as.polygons(ext(x), crs = crs)

I wouldn't say the CRS is a requirement of an "extent"... I can imagine times where you might want the CRS to not transfer, or otherwise deal in generic cartesian bounding boxes. I think CRS is convenient to have if you know the bounds have a specific CRS or the CRS was set in the object the extent is calculated from--which for me at least is most of the time.

I think that having ext(<SpatRaster/SpatVector>) take a default crs=crs(x) argument would be helpful, with crs="" or NULL to prevent CRS from being assigned in result SpatExtent (current behavior). If crs different from CRS of x I suppose it could be either an error or it could project the boundaries from source CRS of x to the target crs. Having crs(<SpatExtent>) might sometimes come in handy if it was an option.

brownag avatar Jun 29 '22 22:06 brownag

You can now do

library(terra)
#terra 1.5.49
x <- vect(system.file("ex/lux.shp", package="terra"))
(z <- as.polygons(x, extent=T))
# class       : SpatVector 
# geometry    : polygons 
# dimensions  : 1, 0  (geometries, attributes)
# extent      : 5.74414, 6.528252, 49.44781, 50.18162  (xmin, xmax, ymin, ymax)
# coord. ref. : lon/lat WGS 84 (EPSG:4326) 

This was already available for SpatRaster so it made sense to me to also have that for SpatVector.

Early I did consider combining the extent and crs into a single object. But I found it too cumbersome. I cannot remember all the details, unfortunately, but one example would be when you want to fix an extent. For example, this would remove the crs from x

ext(x) = ext(c(0,1,0,1))

(but this would not)

ext(x) = c(0,1,0,1)

I need to think about it again.

rhijmans avatar Jun 29 '22 23:06 rhijmans

Great, thanks, https://github.com/rspatial/terra/commit/817072c74d5978da8a62d83f248e1ea46b01895d and your explanation are helpful

brownag avatar Jun 30 '22 00:06 brownag

I am going to leave the SpatExtent as-is for the moment. I think the simplicity outweighs the downside of not having a crs attached.

rhijmans avatar Sep 02 '22 01:09 rhijmans