mapview icon indicating copy to clipboard operation
mapview copied to clipboard

SpatVector and SpatRaster inputs

Open AMBarbosa opened this issue 3 years ago • 13 comments

Thanks for this amazing package! I realize that mapView() already implements a lot of data inputs, but is there any chance it could also implement the (also widely and increasingly used) SpatVector and SpatRaster formats? Cheers!

AMBarbosa avatar Jun 22 '22 17:06 AMBarbosa

Yes, this is on my to-do list. I should mention though that I envision this to just be as simple as:

setMethod('mapView', signature(x = 'SpatVector'),
          function(x,
                   zcol = NULL,
                   layer.name = NULL,
                   ...) {
            if (is.null(layer.name))
              layer.name = makeLayerName(x, zcol, up = 2)
            mapView(st_as_sf(x), layer.name = layer.name, zcol = zcol, ...)
          }
)

so effectively not adding more internal code, but relying on sf and stars coercion for SpatVector and SpatRaster, respectively.

If you are up for the challenge, I'd also happily receive a PR for this :-)

tim-salabim avatar Jun 22 '22 17:06 tim-salabim

The above is adapted from the current method for SpatialPointsDataFrame

tim-salabim avatar Jun 22 '22 17:06 tim-salabim

This is a duplicate of #340. Though it's getting more urgent (I'm getting crazy CRS handling in the old raster package on the latest rolling release distro, it's probably only going to get worse from here on out).

GreatEmerald avatar Jun 28 '22 16:06 GreatEmerald

Oops, sorry if it's a duplicate. But the 'terra' package has come a very long way since #340, it should now completely replace both 'raster' and 'sp' (I'm certainly doing it in my packages and it makes everything better -- totally worth the trouble!), and please note it's not just for rasters but also for vector maps. Simply coercing SpatRaster to 'stars' and SpatVector to 'sf' (as per Tim's response above) should do the trick, though I'm very wary of touching other people's code, especially in complex packages where I could break something elsewhere ;)

AMBarbosa avatar Jun 28 '22 17:06 AMBarbosa

though I'm very wary of touching other people's code, especially in complex packages where I could break something elsewhere ;)

I hear ya, will implement this soon (hopefully)

tim-salabim avatar Jun 29 '22 08:06 tim-salabim

Unfortunately the coercion or reading using stars sometimes fails to read files properly. Here's a simple example that fails on my machine:

library(stars)
#> Loading required package: abind
#> Loading required package: sf
#> Linking to GEOS 3.10.2, GDAL 3.4.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(mapview)

mapview(read_stars(system.file("ex/meuse.tif", package="terra")))
#> Error in validateScalarName(name): Invalid argument 'name' (must be a non-empty character string and contain no '/' or '\')

Created on 2022-06-29 by the reprex package (v2.0.1)

library(terra)
#> terra 1.5.34
library(stars)
#> Loading required package: abind
#> Loading required package: sf
#> Linking to GEOS 3.10.2, GDAL 3.4.2, PROJ 8.2.1; sf_use_s2() is TRUE
library(mapview)

mapview(st_as_stars(rast(system.file("ex/meuse.tif", package="terra"))))
#> Error in validateScalarName(name): Invalid argument 'name' (must be a non-empty character string and contain no '/' or '\')

Created on 2022-06-29 by the reprex package (v2.0.1)

Probably some issue in stars, but good to keep in mind.

GreatEmerald avatar Jun 29 '22 11:06 GreatEmerald

Probably some issue in stars, but good to keep in mind.

Not sure ;-)

It looks like mapview tries but fails to create a title from everything between mapview( and the matching ), as this works:

library(stars)
library(mapview)
r = read_stars(system.file("ex/meuse.tif", package="terra"))
mapview(r)

and shows r - 1 as legend title.

@tim-salabim isn't it a better idea to use names(x)[1] as the title for the image?

edzer avatar Jun 29 '22 11:06 edzer

I've just tried it on my end and indeed that fails, but not if you separate the commands:

strs <- st_as_stars(rast(system.file("ex/meuse.tif", package="terra")))
mapview(strs)   # this works

It looks like it has to do with validateScalarName() being applied to the entire file path, which contains "/".

AMBarbosa avatar Jun 29 '22 11:06 AMBarbosa

This is JavaScript biting us here:

htmltools:::validateScalarName
function (x, name = deparse(substitute(x))) 
{
    if (length(x) != 1 || x == "" || grepl("[/\\]", x)) 
        stop("Invalid argument '", name, "' (must be a non-empty character string and contain no '/' or '\\')")
}
<bytecode: 0x564dea5d9140>
<environment: namespace:htmltools>

and yes, mapview is trying to infer the layer name using deparse(subsitute(x)) so those slashes are carried forward to leaflet -> htmltools... I'll have a look how to avoid those

tim-salabim avatar Jun 29 '22 11:06 tim-salabim

Good to know that was a JavaScript issue; indeed when separated the command works, but then if I try to plot(r), my R session explodes with Error: C stack usage 46814669739132 is too close to the limit, hence why I thought it could be an issue in stars. But perhaps it's something with my software stack...

GreatEmerald avatar Jun 29 '22 12:06 GreatEmerald

@edzer I agree, using names() is a better approach for raster data. This is what we do in the raster method. Not sure why this is not done in the stars method. I'll investigate.

tim-salabim avatar Jun 29 '22 12:06 tim-salabim

But perhaps it's something with my software stack...

maybe switch to using stars from github? I'm pretty close to a new CRAN release.

edzer avatar Jun 29 '22 13:06 edzer

In case it helps, the latest version of leaflet now accepts SpatRaster (https://github.com/rstudio/leaflet/blob/main/man/addRasterImage.Rd) and SpatVector inputs (e.g. https://github.com/rstudio/leaflet/blob/main/man/leaflet.Rd).

AMBarbosa avatar Jul 11 '22 10:07 AMBarbosa

@tim-salabim Close?

Nowosad avatar Dec 05 '22 14:12 Nowosad

yip, closing

tim-salabim avatar Jan 06 '23 11:01 tim-salabim