123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- /*
- * Leaflet Heatmap Overlay
- *
- * Copyright (c) 2008-2016, Patrick Wied (https://www.patrick-wied.at)
- * Dual-licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
- * and the Beerware (http://en.wikipedia.org/wiki/Beerware) license.
- */
- ;(function (name, context, factory) {
- // Supports UMD. AMD, CommonJS/Node.js and browser context
- if (typeof module !== "undefined" && module.exports) {
- module.exports = factory(
- require('heatmap.js'),
- require('leaflet')
- );
- } else if (typeof define === "function" && define.amd) {
- define(['heatmap.js', 'leaflet'], factory);
- } else {
- // browser globals
- if (typeof window.h337 === 'undefined') {
- throw new Error('heatmap.js must be loaded before the leaflet heatmap plugin');
- }
- if (typeof window.L === 'undefined') {
- throw new Error('Leaflet must be loaded before the leaflet heatmap plugin');
- }
- context[name] = factory(window.h337, window.L);
- }
- })("HeatmapOverlay", this, function (h337, L) {
- 'use strict';
- // Leaflet < 0.8 compatibility
- if (typeof L.Layer === 'undefined') {
- L.Layer = L.Class;
- }
- var HeatmapOverlay = L.Layer.extend({
- initialize: function (config) {
- this.cfg = config;
- this._el = L.DomUtil.create('div', 'leaflet-zoom-hide');
- this._data = [];
- this._max = 1;
- this._min = 0;
- this.cfg.container = this._el;
- },
- onAdd: function (map) {
- var size = map.getSize();
- this._map = map;
- this._width = size.x;
- this._height = size.y;
- this._el.style.width = size.x + 'px';
- this._el.style.height = size.y + 'px';
- this._el.style.position = 'absolute';
- this._origin = this._map.layerPointToLatLng(new L.Point(0, 0));
- map.getPanes().overlayPane.appendChild(this._el);
- if (!this._heatmap) {
- this._heatmap = h337.create(this.cfg);
- }
- // this resets the origin and redraws whenever
- // the zoom changed or the map has been moved
- map.on('moveend', this._reset, this);
- this._draw();
- },
- addTo: function (map) {
- map.addLayer(this);
- return this;
- },
- onRemove: function (map) {
- // remove layer's DOM elements and listeners
- map.getPanes().overlayPane.removeChild(this._el);
- map.off('moveend', this._reset, this);
- },
- _draw: function() {
- if (!this._map) { return; }
-
- var mapPane = this._map.getPanes().mapPane;
- var point = mapPane._leaflet_pos;
- // reposition the layer
- this._el.style[HeatmapOverlay.CSS_TRANSFORM] = 'translate(' +
- -Math.round(point.x) + 'px,' +
- -Math.round(point.y) + 'px)';
- this._update();
- },
- _update: function() {
- var bounds, zoom, scale;
- var generatedData = { max: this._max, min: this._min, data: [] };
- bounds = this._map.getBounds();
- zoom = this._map.getZoom();
- scale = Math.pow(2, zoom);
- if (this._data.length == 0) {
- if (this._heatmap) {
- this._heatmap.setData(generatedData);
- }
- return;
- }
- var latLngPoints = [];
- var radiusMultiplier = this.cfg.scaleRadius ? scale : 1;
- var localMax = 0;
- var localMin = 0;
- var valueField = this.cfg.valueField;
- var len = this._data.length;
-
- while (len--) {
- var entry = this._data[len];
- var value = entry[valueField];
- var latlng = entry.latlng;
- // we don't wanna render points that are not even on the map ;-)
- if (!bounds.contains(latlng)) {
- continue;
- }
- // local max is the maximum within current bounds
- localMax = Math.max(value, localMax);
- localMin = Math.min(value, localMin);
- var point = this._map.latLngToContainerPoint(latlng);
- var latlngPoint = { x: Math.round(point.x), y: Math.round(point.y) };
- latlngPoint[valueField] = value;
- var radius;
- if (entry.radius) {
- radius = entry.radius * radiusMultiplier;
- } else {
- radius = (this.cfg.radius || 2) * radiusMultiplier;
- }
- latlngPoint.radius = radius;
- latLngPoints.push(latlngPoint);
- }
- if (this.cfg.useLocalExtrema) {
- generatedData.max = localMax;
- generatedData.min = localMin;
- }
- generatedData.data = latLngPoints;
- this._heatmap.setData(generatedData);
- },
- setData: function(data) {
- this._max = data.max || this._max;
- this._min = data.min || this._min;
- var latField = this.cfg.latField || 'lat';
- var lngField = this.cfg.lngField || 'lng';
- var valueField = this.cfg.valueField || 'value';
-
- // transform data to latlngs
- var data = data.data;
- var len = data.length;
- var d = [];
-
- while (len--) {
- var entry = data[len];
- var latlng = new L.LatLng(entry[latField], entry[lngField]);
- var dataObj = { latlng: latlng };
- dataObj[valueField] = entry[valueField];
- if (entry.radius) {
- dataObj.radius = entry.radius;
- }
- d.push(dataObj);
- }
- this._data = d;
-
- this._draw();
- },
- // experimential... not ready.
- addData: function(pointOrArray) {
- if (pointOrArray.length > 0) {
- var len = pointOrArray.length;
- while(len--) {
- this.addData(pointOrArray[len]);
- }
- } else {
- var latField = this.cfg.latField || 'lat';
- var lngField = this.cfg.lngField || 'lng';
- var valueField = this.cfg.valueField || 'value';
- var entry = pointOrArray;
- var latlng = new L.LatLng(entry[latField], entry[lngField]);
- var dataObj = { latlng: latlng };
-
- dataObj[valueField] = entry[valueField];
- this._max = Math.max(this._max, dataObj[valueField]);
- this._min = Math.min(this._min, dataObj[valueField]);
- if (entry.radius) {
- dataObj.radius = entry.radius;
- }
- this._data.push(dataObj);
- this._draw();
- }
- },
- _reset: function () {
- this._origin = this._map.layerPointToLatLng(new L.Point(0, 0));
-
- var size = this._map.getSize();
- if (this._width !== size.x || this._height !== size.y) {
- this._width = size.x;
- this._height = size.y;
- this._el.style.width = this._width + 'px';
- this._el.style.height = this._height + 'px';
- this._heatmap._renderer.setDimensions(this._width, this._height);
- }
- this._draw();
- }
- });
- HeatmapOverlay.CSS_TRANSFORM = (function() {
- var div = document.createElement('div');
- var props = [
- 'transform',
- 'WebkitTransform',
- 'MozTransform',
- 'OTransform',
- 'msTransform'
- ];
- for (var i = 0; i < props.length; i++) {
- var prop = props[i];
- if (div.style[prop] !== undefined) {
- return prop;
- }
- }
- return props[0];
- })();
- return HeatmapOverlay;
- });
|