openlayers / openlayers

OpenLayers
https://openlayers.org
BSD 2-Clause "Simplified" License
11.29k stars 3.03k forks source link

Addition of Option for Weight Average Calculation in Heatmap #16047

Open fabric-io-rodrigues opened 1 month ago

fabric-io-rodrigues commented 1 month ago

Hello OpenLayers team,

I hope this message finds you well!

I am using the Heatmap component of OpenLayers in my project and I have observed that the current functionality, which includes options for blur, radius, and weight, works very well for summable data such as population or accident counts. However, I am dealing with a specific case where summing weights is not appropriate, such as when visualizing prices by region (e.g., fuel prices by neighborhood).

For data like prices, calculating the average of the values is crucial for accurate visualization. Currently, the heatmap sums the weights when coordinates are close to each other, but in my case, having an option to calculate the average of these weights would be far more useful.

I would like to suggest considering the addition of an option to compute the average of weights in the heatmap. This would provide a more accurate and meaningful representation of price data and similar metrics.

I also wanted to point out that this topic has been previously raised in issue #11819 (Heatmap layer intersection between points), but it was closed due to inactivity. I believe this enhancement would greatly benefit the community, and I hope it can be revisited.

Thank you very much for the excellent work on OpenLayers, which has been instrumental not only for my project but for many others around the world. 😃

I look forward to your response and am available for any additional information if needed.

ahocevar commented 1 month ago

To be honest, I don't know how a heat map of averages would work. The idea behind the heatmap is to draw a point with a color according to its weight (giving it the red-yellow heat effect), and when all points are drawn, blur the resulting image.

For data like prices, given my cartographic knowledge, I would create a choropleth or raster map that aggregates points with price attributes into the respective regional units or raster cells, by average.

fabric-io-rodrigues commented 1 month ago

Hi @ahocevar, thank you so much for your response and for your time! I know that the OpenLayers project, especially now with version 10, requires a lot of effort, so I really appreciate your attention.

I just wanted to gently insist on the use of averages in the heatmap. Although I mentioned prices as an example, the average also makes a big difference for other data types like temperature, air quality, and pollution levels.

To illustrate, I’m sending a figure showing two circles representing temperature measurements: 28°C (#B8FFF7) and 42°C (#94FFB7). With the blur turned off to make it clearer, the overlap of the circles results in 70°C (#9AFF6B), which doesn’t make much sense for temperature. Similarly, for air quality data or pollution indices, the average provides a more accurate view of the environmental impact.

image image image

It would be great to have the option to calculate the average of weights in the heatmap. This would help provide a more precise and useful visualization for these types of data.

I’m testing the latest version of OpenLayers and am really pleased with the results. Thanks again for your consideration and for the excellent work on the tool!

ahocevar commented 1 month ago

Sorry to insist, but what I tried to explain above is that the heatmap is not something that's calculated, but the result of drawing pixels with a fixed color scale for values between 0 and 1, using a "source-over" composite operation, and then applying a blur to the final result.

What you're asking for is drawing pixels with a user defined color scale for arbitrary values, using an "overlay" composite operation, and then apply a blur to the final result. This can be done with a vector layer, prerender and postrender functions, and a blur css filter with a className on the layer.

See https://codesandbox.io/p/sandbox/vector-layer-forked-mvw2ls for an example.

Note that the "overlay" composite operation comes close to what you want, but may not give the exact results. You might have to try with different comosite operations. Also, the linear interpolation of rgb colors as done in the style above may not give you a perfect color wheel - again, you might want to experiment with different color interpolation, maybe using Style objects instead of flat styles, and based on hls colors.

mike-000 commented 1 month ago

The result of overlay would be affected by the rendering order of the features. Whatever operation is used it is unlikely to give meaningful results if 3 or more features overlap (e.g. https://openlayers.org/en/v5.3.0/examples/blend-modes.html).

data types like temperature, air quality, and pollution levels

These are typically represented as a raster using an Inverse Distance Weight (IDW) interpolation algorithm which can handle multiple randomly distributed sample points. None of the major mapping clients support that directly but all have third-party extensions available, e.g. https://stackblitz.com/edit/js-z4ota1?file=package.json,index.html,index.js Sometimes called an "interpolated heatmap" but it is not a true heatmap as each pixel on the output must be calculated.

You could avoid using third-party software by creating a DataTile source based on an IDW algorithm https://stackblitz.com/edit/js-ofc5fn?file=package.json,index.html,index.js (algorithm derived from ol-ext source code). Ideally the tile edge artefacts should be removed by applying a gutter.