-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
addGeotiff API development #29
Comments
The following example currently works, but only with the evil There is some scope creep happening somewhere, but I am not sure where and how to avoid it. Maybe @yeedle has an idea? library(stars)
library(leaflet)
library(leafem)
tif = system.file("tif/L7_ETMs.tif", package = "stars")
(x1 = read_stars(tif))
strs = st_warp(x1, crs = 4326)
fl = tempfile(fileext = ".tif")
write_stars(strs, fl)
pal = grDevices::colorRampPalette(hcl.colors(9, "viridis"))
ndvi = function(x) (x[4] - x[3]) / (x[4] + x[3])
leaflet() %>%
addTiles() %>%
addGeotiff(
file = fl
, group = "stars"
, resolution = 96
, arith = ndvi
, colorOptions = colorOptions(
palette = pal
)
) To get this to work: remotes::install_github("r-spatial/leafem") |
I've figured out the issue and have a suggested fix (see below), but I want to clear up a couple of things. The difference between The solution is to let the function evalMath(a, values) {
return Function('values', 'with(Math) return ' + a)(values);
} When you call pixelValuesToColorFn = values => {
let vals;
if (arith === null) {
if (bands.length > 1) {
bands = bands[0];
}
vals = values[bands];
}
if (arith !== null) {
vals = evalMath(arith, values);
}
let clr = scale.domain(domain);
if (isNaN(vals)) return nacol;
return clr(vals).hex();
}; and: function evalDomain(arr, arith) {
var out = [];
for (let i = 0; i < arr.length; i++) {
values = arr[i];
out.push(evalMath(arith, values));
}
return [Math.min(...out), Math.max(...out)];
} I hope you find the above helpful! |
@yeedle many many thanks! This works like a charm! I've included you as a contributor to the package (if that's ok with you).
Does this mean that if someone is hosting a map that includes |
I think any case in which you execute user-supplied strings opens you up to some vulnerabilities. Personally I believe that in this particular case it's highly unlikely. Even in the case of a hosted map, the user is still running the javascript in their own sandboxed browser. The only exception I can think of is a case where the javascript will get executed in a headless environment on a server, but I think the way you deparse and translate the R function into a JS expression makes even such a scenario very hard to exploit. If you want to completely stay away from any such concern, I'd suggest you use math.js's math expression parser or expr-eval instead. |
Thanks again @yeedle for a great explanation! And especially for the pointer to expr-eval. Do you have any experience with it? It looks like it could be very useful here. |
Don't have much experience but usage is pretty straightforward. You have your expression as a string, and then you have your variable. You instantiate a parser If you want I can open a PR replacing |
Thanks @yeedle ! A PR would be fantastic |
Yeah, the safer the better. Especially as I still quite comprehend the potential risks. So better be safe than sorry I guess. |
The examples using a |
In #25 I've been keeping track of the development for the new js functionality to add geotiff data to a leaflet map. The API has changed enough so that most examples over there won't work anymore. Hence, dev-tracking will continue here.
The "new" API has a few advantages over the old one:
addGeotiff
as opposed toaddGeoraster
arith
argument as opposed to some string representationarith
Math.
functions (https://twitter.com/TimSalabim3/status/1301078413315317761) though we are still using the evileval
in one place... to be addressedaddRGB
(for both stars and raster objects). We setrgb
toTRUE
inaddGeotiff
and the specifiedbands
will be used to create a RGB image (again, this happens in the browser - no pre-calculation in R)Examples to follow...
The text was updated successfully, but these errors were encountered: