GithubHelp home page GithubHelp logo

leaflet / leaflet.heat Goto Github PK

View Code? Open in Web Editor NEW
1.5K 64.0 522.0 55 KB

A tiny, simple and fast heatmap plugin for Leaflet.

Home Page: http://leaflet.github.io/Leaflet.heat/demo

License: BSD 2-Clause "Simplified" License

JavaScript 100.00%

leaflet.heat's Introduction

Leaflet.heat

A tiny, simple and fast Leaflet heatmap plugin. Uses simpleheat under the hood, additionally clustering points into a grid for performance.

Demos

Basic Usage

var heat = L.heatLayer([
	[50.5, 30.5, 0.2], // lat, lng, intensity
	[50.6, 30.4, 0.5],
	...
], {radius: 25}).addTo(map);

To include the plugin, just use leaflet-heat.js from the dist folder:

<script src="leaflet-heat.js"></script>

Building

To build the dist files run: npm install && npm run prepublish

Reference

L.heatLayer(latlngs, options)

Constructs a heatmap layer given an array of points and an object with the following options:

  • minOpacity - the minimum opacity the heat will start at
  • maxZoom - zoom level where the points reach maximum intensity (as intensity scales with zoom), equals maxZoom of the map by default
  • max - maximum point intensity, 1.0 by default
  • radius - radius of each "point" of the heatmap, 25 by default
  • blur - amount of blur, 15 by default
  • gradient - color gradient config, e.g. {0.4: 'blue', 0.65: 'lime', 1: 'red'}
  • pane - Map pane where the heat will be drawn. Defaults to 'overlayPane'.

Each point in the input array can be either an array like [50.5, 30.5, 0.5], or a Leaflet LatLng object.

Optional third argument in each LatLng point (altitude) represents point intensity. Unless max option is specified, intensity should range between 0.0 and 1.0.

Methods

  • setOptions(options): Sets new heatmap options and redraws it.
  • addLatLng(latlng): Adds a new point to the heatmap and redraws it.
  • setLatLngs(latlngs): Resets heatmap data and redraws it.
  • redraw(): Redraws the heatmap.

Changelog

0.2.0 — Oct 26, 2015

  • Fixed intensity to work properly with max option.
  • Fixed zoom animation on Leaflet 1.0 beta 2.
  • Fixed tiles and point intensity in demos.

0.1.3 — Nov 25, 2015

  • Fixed some edge cases when handling point intensity.
  • Added minOpacity option.

0.1.2 — Nov 5, 2014

  • Added compatibility with Leaflet 0.8-dev.

0.1.1 — Apr 22, 2014

  • Fixed overlaying two heatmaps on top of each other.
  • Fixed rare animation issues.

0.1.0 — Feb 3, 2014

  • Added addLatLng, setLatlngs, setOptions and redraw methods.
  • Added max option and support for different point intensity values (through LatLng third argument).
  • Added gradient option to customize colors.

0.0.1 — Jan 31, 2014

  • Initial release.

leaflet.heat's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

leaflet.heat's Issues

Negative values

Hello,

I would like to specify a heat map with negative and positive values. Is it possible ?

Example : [ P1 {lat:0, lng:0, value: -0.5}, P2 {lat:10, lng:0, value: -0.2}, P3 {lat:10, lng:10, value: 0.3} ]

I think about a solution but it doesn't work :
In this example, if I add 0.5 to the values I will have positive values. However, assuming 0 is blue and 1 is red, the fusion of P1 and P2 will produce a more red color although a fusion of negative values will produce a more blue color.

Thank you

Radius with respect to zoom level

@mourner Is it possible to change the radius based on zoom level. For eg. if I zoom out, the radius of a lat/lng should decrease and if we zoom in the radius should increase, but keeping the allocated intensity value to the given lat/lng value and not adding up the intensities on zoom out.

I tried to modify the draw() function but it doesnt work. The radius() function just gets called once upon initialization, I tried to call it on each zoom in/ out activity from redraw() but it doesn't work, following is the sample code of what I am trying to achieve:

  draw: function(t) {
        this._ctx.canvas.height = this._ctx.canvas.height + (this._r * 10);
        this._ctx.canvas.width = this._ctx.canvas.width + (this._r * 10);
        this._circle || this.radius(this.defaultRadius), this._grad || this.gradient(this.defaultGradient);

The canvas draw fails to plot the points on the map.

Heatmap tile not updating on drag

In example the heatmap is only loaded after a drag has ended, resulting in a half drawn heatmap.
See this picture for a visual explanation.

What can be done to draw heatmaps while dragging or alternatively always have the heatmap drawn even if not inside the current viewport?

Bug: Heat map created is not what one expects

There seems to be bug in heat map generation. For example there are five points with different weights and a defined color gradient. Expected output must be these points with different colors, yet the out shows same color for each point.

Below is the example code which generates incorrect output
`var map = L.map('map').setView([43.46811941, -90.04569087], 5);

var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(map);

addressPoints = [[42.35810000, -71.06360000, 10.3],
[42.82995815, -74.78991444, 0.4],
[43.17929819, -78.56603306, 0.5],
[43.40320216, -82.37774519, 0.6],
[43.49975489, -86.20965845, 0.7],
[43.46811941, -90.04569087, 0.8],];

var heat = L.heatLayer(addressPoints, {minOpacity:1, blur:0, max: 1.0}).addTo(map);`

Please see the following fiddles
Fiddle with incorrect output using heat_map.js: https://jsfiddle.net/y20js9nm/13/
Fiddle with correct output using heatmap.js: https://jsfiddle.net/pz4usuLe/40/ (had problems with loading external js)
Fiddle with correct output using heatmap.js: https://jsfiddle.net/pz4usuLe/43/ (Fixed)

Setting opacity and Z index for Heat layer

How would you go about toggling a heat layer's opacity on/off and adjusting the Z index- in reference to having multiple heat layers on the same map? Mainly just worried about the opacity, but the z index would be nice.

Thanks!

Misalignment when pinch-zooming

From Leaflet/Leaflet#4511 by @mgleahy:


Hello all,

I'm trying out leaflet-heat, and would like to work with the 1.0.0-rc1 version of leaaflet. So far, pretty much everything is working fairly well, except that the pinch zoom of a leaflet-heat layer on a mobile device does not animate with the rest of the map. It works fine with leaflet-0.7.7.

I'm just wondering if someone knows what I would need to change in the leaflet-heat source to make it play nice with leaflet 1.0.0...any suggestions?

Here's a sample - open it on an iPad, or other touch device...then try a pinch zoom:

http://playground-leaflet.rhcloud.com/tohi/1

fixed radius

Hi,

I'd like my heat point around lat/lng to have a fixed (zoom independent) radius of 500m : how can I specify this ?

Thank you

Support for leaflet 0.8-dev

Any change for support for leaflet 0.8-dev?

Chrome throws following errror

Uncaught TypeError: Cannot read property 'call' of undefined leaflet.js:5
o.Map.o.Evented.extend.whenReady leaflet.js:5
o.Map.include.addLayer

Add geojson to the readme?

I see from #12 and other places that others besides me are very interested in using geojson files as sources for heat maps. After a little fiddling, I seem to have it working for myself. Any objections to adding fairly explicit instructions to the readme?

PS My own preference would be for built-in support, seeing how it's not very difficult and geojson is a fairly robust standard.

Cannot render heat point when the user rotate the global map over 360 deg

I found a bug that the heat map doesn't render the points when the global map is rotated over 360 deg.

The bug is caused by LatLngBounds.contains method which cannot handle the latLng point properly when the lng doesn't fit into [-180,180]

I have a fix for HeatLayer.js

    var southWest = this._map.containerPointToLatLng(L.point([-r, -r]));                
    var northEast = this._map.containerPointToLatLng(size.add([r, r]));               
    var bounds = new L.LatLngBounds(southWest,northEast);

    // console.time('process');
    for (i = 0, len = this._latlngs.length; i < len; i++) {
        var point = $.extend([],this._latlngs[i]);
        while( point[1] < southWest.lng ) {
            point[1] += 360;
        }
        while( point[1] > northEast.lng ) {
            point[1] -= 360;
        }

Radius per point

Is it possible to set a custom radius per point rather than a radius for the set of points. I am trying to construct a heatmap from polygon centroids and would be great to be able to set a larger radius for larger polygons. The resultant effect would then hopefully be that I could weight the intensities for smaller polygons over those of larger.

Are there any draw events for a Leaflet.heat layer?

I am pretty sure the answer is no, so I guess this is a feature request/call for help?

It would be very useful if there were events that we could listen for to know when the heatmap drawing has started and completed, similar to other leaflet layer types. I am building an time series animation with a heatmap layer but the drawing inevitably lags behind the time tick marker. In this case it would be nice to know when the heatmap render has completed and wait to advance the time tick marker until it has drawn.

Anyone have any suggestions?

max option not working

When I set the max value to 5, I am getting following error in my browser:

Uncaught IndexSizeError: Failed to execute 'addColorStop' on 'CanvasGradient': The provided value (5) is outside the range (0.0, 1.0)

Support for geojson? (feature request)

Since geojson is turning into a de-facto standard, it seems like it would be useful to have geojson support for adding points, similar to the standard leaflet library. It seems like it would be a fairly simple fix, and I would consider contributing if there is sufficient interest.

Intensity doesn't work correctly

When intesity is provided as altitude it isn't computed properly (the values are too small and everything is trated as value 1). To get it to work correctly I changed two bits of code in the _redraw function:

  • line 144
k = this._latlngs[i].alt || (1 * v);

Multiplying the alt with v makes it really small, so I went for not doing it.

  • line 168
Math.max(cell[2], 1)

If the values are too small in line 144 this will always be < 1 and after changing line 144 it will always be 1 if Math.min() is still used.
As far as I can see it produces a result which looks better, but still isn't really correct IMO. I used this data for testing:

{max: 70, data: [{lat: 0, lon: 0, value: 0},{lat: 10, lon: 10, value: 10},{lat: 20, lon: 20, value: 20},{lat: 30, lon: 30, value: 30},{lat: 40, lon: 40, value: 40},{lat: 50, lon: 50, value: 50},{lat: 60, lon: 60, value: 60},{lat: 70, lon: 70, value: 70}]}

and when zoomed out max it doesn't look correctly to me.

add support bower

Hi,
I would like to use your library for our development (replace the old git://github.com/johnthillaye/Leaflet.heat.git). We are using bower to pull the libraries, and is it possible to add bower support to your library?

Thanks

Jonathan

Does the intensity/altitude value work with individual points?

It seems that the only way to have sections show up as higher color intensities is to have several points clustered close together.

In other words, when given individual points (that are far apart from another) with different altitude values, the heatmap will show the same color of intensity for all points. Is this expected behavior?

Heatmap changes after zooming

I've found that the heatmap imagery can change slightly after zooming with no change to the data points:

orig after-zoom

I think this happens when you zoom out quickly (ie. multiple zoom levels at once) and then in quickly again. That's how I reproduce it anyway, it may just be random.

error loading my own points

trying the 10.000 points example,

i got this error
"Uncaught TypeError: Cannot read property '0' of undefined "

sample of my data:


var addressPoints = [
[-35.4185239604101, -60.1819977605355,"540"],
[-35.4256691043552, -60.1671376727503,"711"]
.....
];

No tags

This package has npm versions but not corresponding git tags. Using npm version will create the tag automatically: for future releases we should have git tags.

Incompatible plugin with Leaflet 1.0.dev

Could you please update project to be compatible with latest Leaflet 1.0.dev?
It has essential bug fixes, but with that one Leaflet.heat doesn't work at all.

All what do I have is this error "Uncaught TypeError: Cannot read property 'lat' of null"

IE9 -heatmap position is off after panning

Not sure if Leaflet.heat supports IE9... There seems to be an issue with heatmap layer positioning after user pans around the map.

ie9_heat_1

ie9_heat_2

If anybody else needs to support IE9, adding 'position:absolute;' to '.leaflet-heatmap-layer' seems to do the trick.

problem overlaying two heatmaps

Hi Vladimir,

I just noticed a small glitch with the heatmaps library for Leaflet: there’s no way to overlay two heatmaps one on top of the other.
Is it any simple to fix?

How to use on mobile?

Edited (in case it helps someone else): I've tried to do the following to make it work on iPad. I was expecting it to make the mouseover (or touch) work, but instead the map stays static and the touch events do not work. What's wrong?

Code follows below:

             map.on ({
                        touchstart: function () { draw = false; },
                        touchend:   function () { draw = true; },
                        touchmove: function (e) {
                            if (draw) {
                                heat.addLatLng(e.latlng);
                            }
                        }
             })

Extract canval layer functionality

Leaflet.heat code contains one of the best canvas layer solution for Leaflet. Is there someone to make this separate project and maintain it?

/*
Generic Canvas Overlay for leaflet,
Stanislav Sumbera, April , 2014

  • added userDrawFunc that is called when Canvas need to be redrawn
  • added few useful params fro userDrawFunc callback

*/

L.CanvasOverlay = L.Class.extend({

initialize: function (userDrawFunc, options) {
    this._userDrawFunc = userDrawFunc;
    L.setOptions(this, options);
},

drawing: function (userDrawFunc) {
    this._userDrawFunc = userDrawFunc;
    return this;
},

params:function(options){
    L.setOptions(this, options);
    return this;
},

canvas: function () {
    return this._canvas;
},

redraw: function () {
    if (!this._frame) {
        this._frame = L.Util.requestAnimFrame(this._redraw, this);
    }
    return this;
},



onAdd: function (map) {
    this._map = map;
    this._canvas = L.DomUtil.create('canvas', 'leaflet-heatmap-layer');

    var size = this._map.getSize();
    this._canvas.width = size.x;
    this._canvas.height = size.y;

    var animated = this._map.options.zoomAnimation && L.Browser.any3d;
    L.DomUtil.addClass(this._canvas, 'leaflet-zoom-' + (animated ? 'animated' : 'hide'));


    map._panes.overlayPane.appendChild(this._canvas);

    map.on('moveend', this._reset, this);
    map.on('resize',  this._resize, this);

    if (map.options.zoomAnimation && L.Browser.any3d) {
        map.on('zoomanim', this._animateZoom, this);
    }

    this._reset();
},

onRemove: function (map) {
    map.getPanes().overlayPane.removeChild(this._canvas);

    map.off('moveend', this._reset, this);
    map.off('resize', this._resize, this);

    if (map.options.zoomAnimation) {
        map.off('zoomanim', this._animateZoom, this);
    }
    this_canvas = null;

},

addTo: function (map) {
    map.addLayer(this);
    return this;
},

_resize: function (resizeEvent) {
    this._canvas.width  = resizeEvent.newSize.x;
    this._canvas.height = resizeEvent.newSize.y;
},

_reset: function () {
    var topLeft = this._map.containerPointToLayerPoint([0, 0]);
    L.DomUtil.setPosition(this._canvas, topLeft);
    this._redraw();
},

_redraw: function () {
    var size     = this._map.getSize();
    var bounds   = this._map.getBounds();
    var zoomScale = (size.x * 180) / (20037508.34  * (bounds.getEast() - bounds.getWest())); // resolution = 1/zoomScale
    var zoom = this._map.getZoom();

    // console.time('process');

    if (this._userDrawFunc) {
        this._userDrawFunc(this,
                            {
                                canvas   :this._canvas,
                                bounds   : bounds,
                                size     : size,
                                zoomScale: zoomScale,
                                zoom : zoom,
                                options: this.options
                           });
    }


    // console.timeEnd('process');

    this._frame = null;
},

_animateZoom: function (e) {
    var scale = this._map.getZoomScale(e.zoom),
        offset = this._map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this._map._getMapPanePos());

    this._canvas.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')';

}

});

L.canvasOverlay = function (userDrawFunc, options) {
return new L.CanvasOverlay(userDrawFunc, options);
};

Building Leaflet.heat

I have a need to specify minOpacity and pass it to draw like so:

this._heat.data(data).draw(this.options.minOpacity || 0.05);

I was hoping to submit a PR with this change, but I don't see a grunt or jake file or anything. How do I run a build for this?

Opacity

I am trying to implement a heatmap with high opacity but when I set minOpacity it seems to not have any effect. Is there something I am missing?

Heatmap canvas obscures the SVG shapes

Hi,

My use case is as follows, I draw a shape (using the leaflet-draw plugin for shape drawing and editing) on the map to query some locations from a database in an area covered by that shape and show them on a map. I am also attaching a hover over label to the shape to show what data the locations represent. See screenshot below:

image

The problem is when I do a similar thing but with heatmap instead of markers, I lose the connection with the shape because the heatmap canvas gets placed on top of the svg shapes and I can't see the label anymore. Not only that I can't even remove the shape anymore because of this.

image

Is there a way to get around this problem in the current implementation of the leaflet-heat?

Thanks a bunch
Aman

BringToFront/BringToBack?

Is there any way to accomplish similar behavior to the ILayer BringToFront/Back? My use case is that I need to be able to reorder the layers on the map to, for example, send the heatmap layer below the other layers.

question regarding performance

Hi,

great demo.

is the heatmap able to handle 200k data points (lat/long)? i plan to add the points on the fly, e.g. addLatLng, so will it slow down the rendering?

you set the default radius to 25, what does it mean? does the radius scale based on map zoom?

Thanks

Examples using Leaflet.heat in R with %>% approach but more specifically using addressPoints or similar

Any examples of Leaflet.heat code following this structure would be very helpful eg.
L2 = leaflet() %>% addTiles()

L2 = L2 %>% registerPlugin(leafletHeatPlugin)
L2 = L2 %>% setView(29.7632836, -95.3632715, 10)
L2 = L2 %>% addLayersControl(
baseGroups = names(esri),
options = layersControlOptions(collapsed = TRUE)
)

L2 = L2 %>% addAssets
L2 = L2 %>% addHeatmap(addressPoints)
L2 = L2 %>% add

the Leaflet.heat approaches that seem to sort of work use L2$ and yet many examples of Leaflet in R are given using %>%:

L2 <- Leaflet$new()
L2$setView(c(47.5982623,-122.3415519), zoom=10)
L2$tileLayer(provider="Acetate.terrain")

add heatmap plugin

L2$addAssets(jshead = c("http://leaflet.github.io/Leaflet.heat/dist/leaflet-heat.js"))

heatmap layer

L2$setTemplate(afterScript = sprintf("
<script>
var addressPoints = %s
var heat = L.heatLayer(addressPoints).addTo(map)
</script>
", j
))

option to change size of heatmap layer

is it possible to add an option to leaflet.heat to expand the heatmap layer beyond the size of the map-view, say triple the length & height? so that when a user pans, the heatmap is not cutt off and instead feels "continous"?

I just can test your examples on Safari

I'm testing your examples but i can only get them to work on Safari, have you hear of any incompatibilities with other browsers?
It works here ( http://leaflet.github.io/Leaflet.heat/demo/draw.html ) without any flaws, but when i try to copy your code, and run in my app it only works with Safari, doesn't show any error, i can't see any heatmap points, just the map.

Any help would be appreciated.

Best regards,
João Rodrigues

Intensities adding up on zoom out

@mourner @meceo @tmcw @jfirebaugh @ddproxy

Hello Guys,

I am trying to create a heatmap based on the the values, I don't want to see the density as of now.

Is there a way I can avoid mixing the intensities as I zoom out? I tried playing with your library but no luck. It will be great if we can average out the intensities as we zoom out instead of adding them up.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.