equinor / leaflet.tilelayer.gloperations

Custom Leaflet TileLayer using WebGL to do operations on and colorize floating-point pixels
https://github.com/equinor/leaflet.tilelayer.gloperations
Other
30 stars 6 forks source link

Get maximum and minimum values within current view #51

Open col16 opened 3 years ago

col16 commented 3 years ago

Hi there,

I've got your library going on the https://hirdsexplorer.nz/ website, and it's worked quite well so far.

I'd like to be able to update the colormap after every scroll event, so that it spans from the lowest to the highest values that are currently visible, to allow the user to see the spatial variation in that particular area. This is a common feature in GIS software packages. At the moment I use a global minimum and maximum on each colormap, and the maximum is dictated by the mountains.

Is this a feature that you would be willing to have in your library?

I would be willing to help in some way, but I'm not sure how. I've had a look in src/shaders/index.ts to see how pixel values are calculated, but it seems to me the challenge will be in working out which parts of each tile is visible at any one time. Do you have any ideas on how it could be done?

Thanks, Cameron

thor85 commented 3 years ago

Hi. Sorry, I did not see this before. That should be possible I think, but I do not have time to work on this plugin at the moment. If you make a PR I will have a look if I can merge it.

You could maybe calculate min/max for the visible tiles? They will cover a slightly larger are than your viewport, but you will not get redraws from small movements that do not load new tiles.

To get only the visible tiles you could prune all tiles and request them again, but that seems wasteful. Instead you could use getPixelBounds() to get the tile coordinates, e.g.: https://stackoverflow.com/a/24896130/7291737

When you have the coordinates for the visible tiles and they are loaded, you can get the pixel values from the _tiles cache. E.g.: let pixelData = this._tiles["5:6:2"].el.pixelData. This is a Uint8Array with the RGBA bytes and needs to be converted to a Float32Array to get the values you need: let values = new Float32Array(pixelData.buffer)

Do this for all visible tiles and you have all the values to find min/max. Update the colormap with new min/max, which will trigger a redraw.