[feature request] use onRender or onRenderStaticComplete to read and display raster values
Is it possible to use onRender or onRenderStaticComplete to read and display (on mouse hover) a data matrix which we write to disk when adding a raster/stars image?
@timelyportfolio @edzer we could trial this for an alpha version of a addStars function?
With commit https://github.com/r-spatial/mapview/commit/f692478da443ea17cfb6c526dd086b2652584254 commit I am able to register the original values of the array as a data dependency to the map. The leaflet instance knows where to find the data (see screenshot) but the data is in the wrong format (console throws an error: "SyntaxError: unexpected token: identifier"). So it's basically a matter of a) getting the format of the data correct so that the leaflet instance accepts it as a valid var and b) enable some JS function to query this var when hovering over the image.

Commit https://github.com/r-spatial/mapview/commit/4956dc14c69e4a8fba1e949b9de9e5698933e6f2 now enables passing of valid JSON array to browser. With this code
library(mapview)
library(stars)
r <- raster::raster(matrix(1:9, 3, byrow = TRUE), crs = "+init=epsg:4326")
bounds <- raster::extent(raster::projectExtent(raster::projectExtent(r, crs = sp::CRS(leaflet:::epsg3857)), crs = sp::CRS(leaflet:::epsg4326)))
x = st_as_stars(r)
attr(x, "dimensions")$band = NULL
x[[1]] = x[[1]][, , 1]
map = leaflet() %>% addProviderTiles("OpenStreetMap") %>%
mapview:::addStarsImage(x, bounds = bounds)
map <- htmlwidgets::onRender(
map,
paste0(
"
function(el, x, data) {
// get the leaflet map
var map = this; //HTMLWidgets.find('#' + el.id);
// we need a new div element because we have to handle
// the mouseover output separately
// debugger;
function addElement () {
// generate new div Element
var newDiv = $(document.createElement('div'));
// append at end of leaflet htmlwidget container
$(el).append(newDiv);
//provide ID and style
newDiv.addClass('lnlt');
newDiv.css({
'position': 'relative',
'bottomleft': '0px',
'background-color': 'rgba(255, 255, 255, 0.7)',
'box-shadow': '0 0 2px #bbb',
'background-clip': 'padding-box',
'margin': '0',
'padding-left': '5px',
'color': '#333',
'font': '9px/1.5 \"Helvetica Neue\", Arial, Helvetica, sans-serif',
'text-align': 'right',
});
return newDiv;
}
// check for already existing lnlt class to not duplicate
var lnlt = $(el).find('.lnlt');
if(!lnlt.length) {
lnlt = addElement();
map.on('mousemove', function (e) {
lnlt.text(stars);
});
};
}
"
)
)
map
we can now show the data array in the small strip at the top of the map. array 'stars' is recognised as a valid var (see console output on right).

Which leaves us with a proper way of querying and displaying the data array when hovering over the image. This is where we really need help from JS experts such as @timelyportfolio or @bhaskarvk or anyone else who would be able to realise this.
Why not add a control and change its contents on mouseover?
Check example 5 http://rpubs.com/bhaskarvk/esri-leaflet-image-map-layers
Will start taking a look into this.
@timelyportfolio, no need. I have a working version of this. Will push as soon as I'm back from skiing. May need help to adapt to leaflet > 1 though at some stage.
@tim-salabim ok great. I think we might need to make the data dependency a little more robust and I have some ideas but will wait to see what you have before proceeding.
This commit provides a first implementation of addImageQuery to display image values on mouseover or click.
library(mapview)
library(stars)
library(raster)
kili_data <- system.file("extdata", "kiliNDVI.tif", package = "mapview")
kiliNDVI <- stack(kili_data)
# kiliNDVI = projectRaster(kiliNDVI, crs = "+init=epsg:4326")
kili_stars_1 = st_as_stars(kiliNDVI[[1]])
kili_stars_2 = st_as_stars(kiliNDVI[[12]])
map = leaflet() %>% addProviderTiles("OpenStreetMap") %>%
mapview:::addStarsImage(kili_stars_1, colors = "Greens",
group = "k_1", layerId = "k_1") %>%
mapview:::addStarsImage(kili_stars_2, colors = "Greens",
group = "kili_2", layerId = "kili_2") %>%
mapview:::addImageQuery(kili_stars_1, group = "k_1", layerId = "k_1",
digits = 3, position = "bottomleft") %>%
mapview:::addImageQuery(kili_stars_2, group = "kili_2", layerId = "kili_2",
position = "bottomleft") %>%
addLayersControl(overlayGroups = c("k_1", "kili_2"),
position = "topleft") %>%
addControl("test")
map
There is still an issue if we provide the data in geographic coordinates (commented out). The mousemove event doesn't stop properly when leaving the image.
@timelyportfolio I'd be greatful if you could have a look especially at the javascript part. This was developed by my cousin, nicknamed "joda", so I called it joda.js (which has a very nice ring to it).
Great, having a look now and will respond over the week. Recruiting family to open source - love it.
This is now by-default used when rendering raster layers with mapview. addImageQuery actually allows the user to choose whether the query should be done/displayed on click or mousemove, mapview implements the latter as default (which is currently not changeable). Especially for stacks this can be a bit much, as it will automatically query all available layers of the stack at once, even though only one is seen. I think that it would be ideal to have only the values of the visible layer displayed on mouseover and only show values of all layers of the stack on click.
I don't consider this top priority, but it would be nice to have nonetheless. I will try to adapt the JS code accordingly which will be a challenge for me but also be a good way to learn more JS!
Any help, thoughts more than welcome.