@daishu10000/leaflet-heat 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/PUBLISH_TO_NPM.md +127 -0
- package/README.md +95 -0
- package/demo/draw.html +57 -0
- package/demo/index.html +46 -0
- package/dist/leaflet-heat.js +11 -0
- package/package.json +54 -0
- package/src/HeatLayer.js +218 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014, Vladimir Agafonkin
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are
|
|
5
|
+
permitted provided that the following conditions are met:
|
|
6
|
+
|
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this list of
|
|
8
|
+
conditions and the following disclaimer.
|
|
9
|
+
|
|
10
|
+
2. Redistributions in binary form must reproduce the above copyright notice, this list
|
|
11
|
+
of conditions and the following disclaimer in the documentation and/or other materials
|
|
12
|
+
provided with the distribution.
|
|
13
|
+
|
|
14
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
15
|
+
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
17
|
+
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
18
|
+
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
19
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
20
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
|
21
|
+
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
22
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# 将修复版 Leaflet.heat 发布到 npm
|
|
2
|
+
|
|
3
|
+
原仓库长期未维护,你可以把自己的修复版本以**新包名**发布到 npm,这样别人可以通过 `npm install 你的包名` 使用。
|
|
4
|
+
|
|
5
|
+
## 一、两种发布方式
|
|
6
|
+
|
|
7
|
+
### 方式 A:Scoped 包(推荐)
|
|
8
|
+
|
|
9
|
+
用你的 npm 用户名做命名空间,例如:`@你的用户名/leaflet-heat`。
|
|
10
|
+
|
|
11
|
+
- **优点**:不会和原包 `leaflet.heat` 冲突,名字清晰,安装:`npm i @你的用户名/leaflet-heat`
|
|
12
|
+
- **缺点**:安装时要用 scoped 名
|
|
13
|
+
|
|
14
|
+
### 方式 B:全新包名
|
|
15
|
+
|
|
16
|
+
例如:`leaflet-heat-fixed`、`leaflet-heat-bugfix` 等。
|
|
17
|
+
|
|
18
|
+
- **优点**:名字好记,安装:`npm i leaflet-heat-fixed`
|
|
19
|
+
- **缺点**:需要先到 https://www.npmjs.com 搜一下名字是否已被占用
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 二、发布前修改 package.json
|
|
24
|
+
|
|
25
|
+
在项目根目录打开 `package.json`,至少改这两处:
|
|
26
|
+
|
|
27
|
+
1. **改包名**(二选一)
|
|
28
|
+
- Scoped:`"name": "@你的npm用户名/leaflet-heat"`
|
|
29
|
+
- 新名字:`"name": "leaflet-heat-fixed"`(或你喜欢的未被占用的名字)
|
|
30
|
+
|
|
31
|
+
2. **升版本**(便于和原版区分):
|
|
32
|
+
- 例如:`"version": "0.2.1"`
|
|
33
|
+
|
|
34
|
+
如果你把代码放到了自己的 GitHub,可以顺便改:
|
|
35
|
+
|
|
36
|
+
- `"repository": { "type": "git", "url": "https://github.com/你的用户名/Leaflet.heat.git" }`
|
|
37
|
+
- `"homepage": "https://github.com/你的用户名/Leaflet.heat#readme"`
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 三、发布步骤
|
|
42
|
+
|
|
43
|
+
1. **注册 npm 账号**(若还没有)
|
|
44
|
+
- 打开 https://www.npmjs.com/signup 注册。
|
|
45
|
+
|
|
46
|
+
2. **在项目根目录登录**
|
|
47
|
+
```bash
|
|
48
|
+
cd 你的/Leaflet.heat/ 路径
|
|
49
|
+
npm login
|
|
50
|
+
```
|
|
51
|
+
按提示输入用户名、密码、邮箱(和一次性验证码)。
|
|
52
|
+
|
|
53
|
+
3. **确认要发布的内容**
|
|
54
|
+
- 发布前会打包当前目录(受 `.gitignore` / `.npmignore` 影响)。
|
|
55
|
+
- 默认会包含 `dist/`、`package.json`、`README.md`、`LICENSE` 等;若有 `files` 字段则只发布 `files` 里列出的。
|
|
56
|
+
- 建议:保持 `main: "dist/leaflet-heat.js"`,确保 `dist/leaflet-heat.js` 已构建好(你本地修复后重新 build 一次)。
|
|
57
|
+
|
|
58
|
+
4. **发布**
|
|
59
|
+
- 若包名是 **scoped**(如 `@xxx/leaflet-heat`),首次发布需加 `--access public`(否则会变成私有包):
|
|
60
|
+
```bash
|
|
61
|
+
npm publish --access public
|
|
62
|
+
```
|
|
63
|
+
- 若包名是**普通名**(如 `leaflet-heat-fixed`):
|
|
64
|
+
```bash
|
|
65
|
+
npm publish
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
5. **验证**
|
|
69
|
+
- 到 https://www.npmjs.com 搜索你的包名,能看到说明发布成功。
|
|
70
|
+
- 在空目录里执行:
|
|
71
|
+
```bash
|
|
72
|
+
npm init -y
|
|
73
|
+
npm i @你的用户名/leaflet-heat
|
|
74
|
+
# 或
|
|
75
|
+
npm i leaflet-heat-fixed
|
|
76
|
+
```
|
|
77
|
+
确认 `node_modules` 里存在且引用的是 `dist/leaflet-heat.js`。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 四、以后更新版本
|
|
82
|
+
|
|
83
|
+
修改代码后:
|
|
84
|
+
|
|
85
|
+
1. 在 `package.json` 里把 `version` 改成更大(如 `0.2.2`)。
|
|
86
|
+
2. 若你有 `prepublish` 脚本,先本地构建:
|
|
87
|
+
```bash
|
|
88
|
+
npm run prepublish
|
|
89
|
+
```
|
|
90
|
+
或直接生成 `dist/leaflet-heat.js`。
|
|
91
|
+
3. 再执行:
|
|
92
|
+
```bash
|
|
93
|
+
npm publish
|
|
94
|
+
```
|
|
95
|
+
即可更新 npm 上的版本。
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## 五、别人怎么用你的包
|
|
100
|
+
|
|
101
|
+
安装:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
npm install @你的用户名/leaflet-heat
|
|
105
|
+
# 或
|
|
106
|
+
npm install leaflet-heat-fixed
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
在项目里和原版一样用(入口仍是 Leaflet 热力图 API):
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
import 'leaflet'
|
|
113
|
+
import 'leaflet.heat' // 若包 main 指向 dist/leaflet-heat.js,且会挂到 L.heatLayer
|
|
114
|
+
// 或
|
|
115
|
+
require('leaflet');
|
|
116
|
+
require('@你的用户名/leaflet-heat');
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
若你的包没有自动把 `L.heatLayer` 挂到全局 `L`,就需要按你打包方式(例如 dist 是 UMD)在页面上先引入 Leaflet 再引入你的 heat 脚本。
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## 六、可选:在 README 里说明
|
|
124
|
+
|
|
125
|
+
建议在 `README.md` 开头加一小段,说明这是原 Leaflet.heat 的社区修复版、修复了哪些问题、安装方式(你的包名),并保留原作者的 license 和致谢。这样别人搜索时更容易发现你的版本。
|
|
126
|
+
|
|
127
|
+
完成以上步骤后,你的修改版本就稳定地发布在 npm 上了,不依赖原仓库是否维护。
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Leaflet.heat
|
|
2
|
+
==========
|
|
3
|
+
|
|
4
|
+
A tiny, simple and fast [Leaflet](http://leafletjs.com) heatmap plugin.
|
|
5
|
+
Uses [simpleheat](https://github.com/mourner/simpleheat) under the hood,
|
|
6
|
+
additionally clustering points into a grid for performance.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
## Demos
|
|
10
|
+
|
|
11
|
+
- [10,000 points →](http://leaflet.github.io/Leaflet.heat/demo)
|
|
12
|
+
- [Adding points dynamically →](http://leaflet.github.io/Leaflet.heat/demo/draw.html)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
## Basic Usage
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
var heat = L.heatLayer([
|
|
19
|
+
[50.5, 30.5, 0.2], // lat, lng, intensity
|
|
20
|
+
[50.6, 30.4, 0.5],
|
|
21
|
+
...
|
|
22
|
+
], {radius: 25}).addTo(map);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To include the plugin, just use `leaflet-heat.js` from the `dist` folder:
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script src="leaflet-heat.js"></script>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Building
|
|
32
|
+
To build the dist files run:
|
|
33
|
+
```npm install && npm run prepublish```
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Reference
|
|
37
|
+
|
|
38
|
+
#### L.heatLayer(latlngs, options)
|
|
39
|
+
|
|
40
|
+
Constructs a heatmap layer given an array of points and an object with the following options:
|
|
41
|
+
- **minOpacity** - the minimum opacity the heat will start at
|
|
42
|
+
- **maxZoom** - zoom level where the points reach maximum intensity (as intensity scales with zoom),
|
|
43
|
+
equals `maxZoom` of the map by default
|
|
44
|
+
- **max** - maximum point intensity, `1.0` by default
|
|
45
|
+
- **radius** - radius of each "point" of the heatmap, `25` by default
|
|
46
|
+
- **blur** - amount of blur, `15` by default
|
|
47
|
+
- **gradient** - color gradient config, e.g. `{0.4: 'blue', 0.65: 'lime', 1: 'red'}`
|
|
48
|
+
- **pane** - Map pane where the heat will be drawn. Defaults to 'overlayPane'.
|
|
49
|
+
|
|
50
|
+
Each point in the input array can be either an array like `[50.5, 30.5, 0.5]`,
|
|
51
|
+
or a [Leaflet LatLng object](http://leafletjs.com/reference.html#latlng).
|
|
52
|
+
|
|
53
|
+
Optional third argument in each `LatLng` point (`altitude`) represents point intensity.
|
|
54
|
+
Unless `max` option is specified, intensity should range between `0.0` and `1.0`.
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
#### Methods
|
|
58
|
+
|
|
59
|
+
- **setOptions(options)**: Sets new heatmap options and redraws it.
|
|
60
|
+
- **addLatLng(latlng)**: Adds a new point to the heatmap and redraws it.
|
|
61
|
+
- **setLatLngs(latlngs)**: Resets heatmap data and redraws it.
|
|
62
|
+
- **redraw()**: Redraws the heatmap.
|
|
63
|
+
|
|
64
|
+
## Changelog
|
|
65
|
+
|
|
66
|
+
### 0.2.0 — Oct 26, 2015
|
|
67
|
+
|
|
68
|
+
- Fixed intensity to work properly with `max` option.
|
|
69
|
+
- Fixed zoom animation on Leaflet 1.0 beta 2.
|
|
70
|
+
- Fixed tiles and point intensity in demos.
|
|
71
|
+
|
|
72
|
+
#### 0.1.3 — Nov 25, 2015
|
|
73
|
+
|
|
74
|
+
- Fixed some edge cases when handling point intensity.
|
|
75
|
+
- Added `minOpacity` option.
|
|
76
|
+
|
|
77
|
+
#### 0.1.2 — Nov 5, 2014
|
|
78
|
+
|
|
79
|
+
- Added compatibility with Leaflet 0.8-dev.
|
|
80
|
+
|
|
81
|
+
#### 0.1.1 — Apr 22, 2014
|
|
82
|
+
|
|
83
|
+
- Fixed overlaying two heatmaps on top of each other.
|
|
84
|
+
- Fixed rare animation issues.
|
|
85
|
+
|
|
86
|
+
#### 0.1.0 — Feb 3, 2014
|
|
87
|
+
|
|
88
|
+
- Added `addLatLng`, `setLatlngs`, `setOptions` and `redraw` methods.
|
|
89
|
+
- Added `max` option and support for different point intensity values (through `LatLng` third argument).
|
|
90
|
+
- Added `gradient` option to customize colors.
|
|
91
|
+
|
|
92
|
+
#### 0.0.1 — Jan 31, 2014
|
|
93
|
+
|
|
94
|
+
- Initial release.
|
|
95
|
+
|
package/demo/draw.html
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Leaflet.heat demo</title>
|
|
5
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
|
|
6
|
+
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
|
|
7
|
+
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
|
|
8
|
+
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
|
|
9
|
+
<style>
|
|
10
|
+
#map { width: 800px; height: 600px; }
|
|
11
|
+
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
|
|
12
|
+
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
|
|
13
|
+
a { color: #0077ff; }
|
|
14
|
+
</style>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
|
|
18
|
+
<p>
|
|
19
|
+
A dynamic demo of <a href="https://github.com/Leaflet/Leaflet.heat">Leaflet.heat</a>, a tiny and fast Leaflet heatmap plugin.
|
|
20
|
+
<iframe class="ghbtns" src="https://ghbtns.com/github-btn.html?user=Leaflet&repo=Leaflet.heat&type=watch&count=true"
|
|
21
|
+
allowtransparency="true" frameborder="0" scrolling="0" width="90" height="20"></iframe>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<div id="map"></div>
|
|
25
|
+
|
|
26
|
+
<!-- <script src="../node_modules/simpleheat/simpleheat.js"></script>
|
|
27
|
+
<script src="../src/HeatLayer.js"></script>
|
|
28
|
+
-->
|
|
29
|
+
<script src="../dist/leaflet-heat.js"></script>
|
|
30
|
+
|
|
31
|
+
<script src="https://leaflet.github.io/Leaflet.markercluster/example/realworld.388.js"></script>
|
|
32
|
+
<script>
|
|
33
|
+
|
|
34
|
+
var map = L.map('map').setView([-37.82109, 175.2193], 16);
|
|
35
|
+
|
|
36
|
+
var tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
37
|
+
attribution: '© <a href="https://osm.org/copyright">OpenStreetMap</a> contributors',
|
|
38
|
+
}).addTo(map);
|
|
39
|
+
|
|
40
|
+
addressPoints = addressPoints.map(function (p) { return [p[0], p[1]]; });
|
|
41
|
+
|
|
42
|
+
var heat = L.heatLayer(addressPoints).addTo(map),
|
|
43
|
+
draw = true;
|
|
44
|
+
|
|
45
|
+
map.on({
|
|
46
|
+
movestart: function () { draw = false; },
|
|
47
|
+
moveend: function () { draw = true; },
|
|
48
|
+
mousemove: function (e) {
|
|
49
|
+
if (draw) {
|
|
50
|
+
heat.addLatLng(e.latlng);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
</script>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>Leaflet.heat demo</title>
|
|
5
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css"
|
|
6
|
+
integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
|
|
7
|
+
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"
|
|
8
|
+
integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
|
|
9
|
+
<style>
|
|
10
|
+
#map { width: 800px; height: 600px; }
|
|
11
|
+
body { font: 16px/1.4 "Helvetica Neue", Arial, sans-serif; }
|
|
12
|
+
.ghbtns { position: relative; top: 4px; margin-left: 5px; }
|
|
13
|
+
a { color: #0077ff; }
|
|
14
|
+
</style>
|
|
15
|
+
</head>
|
|
16
|
+
<body>
|
|
17
|
+
|
|
18
|
+
<p>
|
|
19
|
+
A 10,000-point demo of <a href="https://github.com/Leaflet/Leaflet.heat">Leaflet.heat</a>, a tiny and fast Leaflet heatmap plugin.
|
|
20
|
+
<iframe class="ghbtns" src="http://ghbtns.com/github-btn.html?user=Leaflet&repo=Leaflet.heat&type=watch&count=true"
|
|
21
|
+
allowtransparency="true" frameborder="0" scrolling="0" width="90" height="20"></iframe>
|
|
22
|
+
</p>
|
|
23
|
+
|
|
24
|
+
<div id="map"></div>
|
|
25
|
+
|
|
26
|
+
<!-- <script src="../node_modules/simpleheat/simpleheat.js"></script>
|
|
27
|
+
<script src="../src/HeatLayer.js"></script> -->
|
|
28
|
+
|
|
29
|
+
<script src="../dist/leaflet-heat.js"></script>
|
|
30
|
+
|
|
31
|
+
<script src="http://leaflet.github.io/Leaflet.markercluster/example/realworld.10000.js"></script>
|
|
32
|
+
<script>
|
|
33
|
+
|
|
34
|
+
var map = L.map('map').setView([-37.87, 175.475], 12);
|
|
35
|
+
|
|
36
|
+
var tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
37
|
+
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
|
38
|
+
}).addTo(map);
|
|
39
|
+
|
|
40
|
+
addressPoints = addressPoints.map(function (p) { return [p[0], p[1]]; });
|
|
41
|
+
|
|
42
|
+
var heat = L.heatLayer(addressPoints).addTo(map);
|
|
43
|
+
|
|
44
|
+
</script>
|
|
45
|
+
</body>
|
|
46
|
+
</html>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
(c) 2014, Vladimir Agafonkin
|
|
3
|
+
simpleheat, a tiny JavaScript library for drawing heatmaps with Canvas
|
|
4
|
+
https://github.com/mourner/simpleheat
|
|
5
|
+
*/
|
|
6
|
+
!function(){"use strict";function t(i){return this instanceof t?(this._canvas=i="string"==typeof i?document.getElementById(i):i,this._ctx=i.getContext("2d"),this._width=i.width,this._height=i.height,this._max=1,void this.clear()):new t(i)}t.prototype={defaultRadius:25,defaultGradient:{.4:"blue",.6:"cyan",.7:"lime",.8:"yellow",1:"red"},data:function(t,i){return this._data=t,this},max:function(t){return this._max=t,this},add:function(t){return this._data.push(t),this},clear:function(){return this._data=[],this},radius:function(t,i){i=i||15;var a=this._circle=document.createElement("canvas"),s=a.getContext("2d"),e=this._r=t+i;return a.width=a.height=2*e,s.shadowOffsetX=s.shadowOffsetY=200,s.shadowBlur=i,s.shadowColor="black",s.beginPath(),s.arc(e-200,e-200,t,0,2*Math.PI,!0),s.closePath(),s.fill(),this},gradient:function(t){var i=document.createElement("canvas"),a=i.getContext("2d"),s=a.createLinearGradient(0,0,0,256);i.width=1,i.height=256;for(var e in t)s.addColorStop(e,t[e]);return a.fillStyle=s,a.fillRect(0,0,1,256),this._grad=a.getImageData(0,0,1,256).data,this},draw:function(t){this._circle||this.radius(this.defaultRadius),this._grad||this.gradient(this.defaultGradient);var i=this._ctx;i.clearRect(0,0,this._width,this._height);for(var a,s=0,e=this._data.length;e>s;s++)a=this._data[s],i.globalAlpha=Math.max(a[2]/this._max,t||.05),i.drawImage(this._circle,a[0]-this._r,a[1]-this._r);var n=i.getImageData(0,0,this._width,this._height);return this._colorize(n.data,this._grad),i.putImageData(n,0,0),this},_colorize:function(t,i){for(var a,s=3,e=t.length;e>s;s+=4)a=4*t[s],a&&(t[s-3]=i[a],t[s-2]=i[a+1],t[s-1]=i[a+2])}},window.simpleheat=t}(),/*
|
|
7
|
+
(c) 2014, Vladimir Agafonkin
|
|
8
|
+
Leaflet.heat, a tiny and fast heatmap plugin for Leaflet.
|
|
9
|
+
https://github.com/Leaflet/Leaflet.heat
|
|
10
|
+
*/
|
|
11
|
+
L.HeatLayer=(L.Layer?L.Layer:L.Class).extend({initialize:function(t,i){this._latlngs=t,L.setOptions(this,i)},setLatLngs:function(t){return this._latlngs=t,this.redraw()},addLatLng:function(t){return this._latlngs.push(t),this.redraw()},setOptions:function(t){return L.setOptions(this,t),this._heat&&this._updateOptions(),this.redraw()},redraw:function(){return!this._heat||this._frame||this._map._animating||(this._frame=L.Util.requestAnimFrame(this._redraw,this)),this},onAdd:function(t){this._map=t,this._canvas||this._initCanvas(),t._panes.overlayPane.appendChild(this._canvas),t.on("moveend",this._reset,this),t.options.zoomAnimation&&L.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._canvas),t.off("moveend",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},_initCanvas:function(){var t=this._canvas=L.DomUtil.create("canvas","leaflet-heatmap-layer leaflet-layer"),i=L.DomUtil.testProp(["transformOrigin","WebkitTransformOrigin","msTransformOrigin"]);t.style[i]="50% 50%";var a=this._map.getSize();t.width=a.x,t.height=a.y;var s=this._map.options.zoomAnimation&&L.Browser.any3d;L.DomUtil.addClass(t,"leaflet-zoom-"+(s?"animated":"hide")),this._heat=simpleheat(t),this._updateOptions()},_updateOptions:function(){this._heat.radius(this.options.radius||this._heat.defaultRadius,this.options.blur),this.options.gradient&&this._heat.gradient(this.options.gradient),this.options.max&&this._heat.max(this.options.max)},_reset:function(){var t=this._map.containerPointToLayerPoint([0,0]);L.DomUtil.setPosition(this._canvas,t);var i=this._map.getSize();this._heat._width!==i.x&&(this._canvas.width=this._heat._width=i.x),this._heat._height!==i.y&&(this._canvas.height=this._heat._height=i.y),this._redraw()},_redraw:function(){var t,i,a,s,e,n,h,o,r,d=[],_=this._heat._r,l=this._map.getSize(),m=new L.Bounds(L.point([-_,-_]),l.add([_,_])),c=void 0===this.options.max?1:this.options.max,u=void 0===this.options.maxZoom?this._map.getMaxZoom():this.options.maxZoom,f=1/Math.pow(2,Math.max(0,Math.min(u-this._map.getZoom(),12))),g=_/2,p=[],v=this._map._getMapPanePos(),w=v.x%g,y=v.y%g;for(t=0,i=this._latlngs.length;i>t;t++)if(a=this._map.latLngToContainerPoint(this._latlngs[t]),m.contains(L.point(a.x,a.y))){e=Math.floor((a.x-w)/g)+2,n=Math.floor((a.y-y)/g)+2;var x=void 0!==this._latlngs[t].alt?this._latlngs[t].alt:void 0!==this._latlngs[t][2]?+this._latlngs[t][2]:1;r=x*f,p[n]=p[n]||[],s=p[n][e],s?(s[0]=(s[0]*s[2]+a.x*r)/(s[2]+r),s[1]=(s[1]*s[2]+a.y*r)/(s[2]+r),s[2]+=r):p[n][e]=[a.x,a.y,r]}for(t=0,i=p.length;i>t;t++)if(p[t])for(h=0,o=p[t].length;o>h;h++)s=p[t][h],s&&d.push([Math.round(s[0]),Math.round(s[1]),Math.min(s[2],c)]);this._heat.data(d).draw(this.options.minOpacity),this._frame=null},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),a=this._map._getCenterOffset(t.center)._multiplyBy(-i).subtract(this._map._getMapPanePos());L.DomUtil.setTransform?L.DomUtil.setTransform(this._canvas,a,i):this._canvas.style[L.DomUtil.TRANSFORM]=L.DomUtil.getTranslateString(a)+" scale("+i+")"}}),L.heatLayer=function(t,i){return new L.HeatLayer(t,i)};
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daishu10000/leaflet-heat",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "A tiny and fast Leaflet heatmap plugin (community bugfix fork).",
|
|
5
|
+
"homepage": "https://github.com/Leaflet/Leaflet.heat",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"heatmap",
|
|
8
|
+
"canvas",
|
|
9
|
+
"visualization",
|
|
10
|
+
"gis",
|
|
11
|
+
"leaflet",
|
|
12
|
+
"plugin"
|
|
13
|
+
],
|
|
14
|
+
"author": "Vladimir Agafonkin",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git://github.com/Leaflet/Leaflet.heat.git"
|
|
18
|
+
},
|
|
19
|
+
"main": "dist/leaflet-heat.js",
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"eslint": "^1.7.3",
|
|
22
|
+
"eslint-config-mourner": "^1.0.1",
|
|
23
|
+
"simpleheat": "~0.4.0",
|
|
24
|
+
"uglify-js": "^2.5.0"
|
|
25
|
+
},
|
|
26
|
+
"eslintConfig": {
|
|
27
|
+
"extends": "mourner",
|
|
28
|
+
"globals": {
|
|
29
|
+
"L": false,
|
|
30
|
+
"simpleheat": false
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"test": "eslint src",
|
|
35
|
+
"prepublish": "uglifyjs node_modules/simpleheat/simpleheat.js src/HeatLayer.js -c -m -o dist/leaflet-heat.js"
|
|
36
|
+
},
|
|
37
|
+
"license": "BSD-2-Clause",
|
|
38
|
+
"jshintConfig": {
|
|
39
|
+
"quotmark": "single",
|
|
40
|
+
"globals": {
|
|
41
|
+
"L": true,
|
|
42
|
+
"simpleheat": true
|
|
43
|
+
},
|
|
44
|
+
"trailing": true,
|
|
45
|
+
"camelcase": true,
|
|
46
|
+
"curly": true,
|
|
47
|
+
"eqeqeq": true,
|
|
48
|
+
"noempty": true,
|
|
49
|
+
"nonbsp": true,
|
|
50
|
+
"undef": true,
|
|
51
|
+
"unused": true,
|
|
52
|
+
"browser": true
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/HeatLayer.js
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
L.HeatLayer = (L.Layer ? L.Layer : L.Class).extend({
|
|
4
|
+
|
|
5
|
+
// options: {
|
|
6
|
+
// minOpacity: 0.05,
|
|
7
|
+
// maxZoom: 18,
|
|
8
|
+
// radius: 25,
|
|
9
|
+
// blur: 15,
|
|
10
|
+
// max: 1.0
|
|
11
|
+
// },
|
|
12
|
+
|
|
13
|
+
initialize: function (latlngs, options) {
|
|
14
|
+
this._latlngs = latlngs;
|
|
15
|
+
L.setOptions(this, options);
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
setLatLngs: function (latlngs) {
|
|
19
|
+
this._latlngs = latlngs;
|
|
20
|
+
return this.redraw();
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
addLatLng: function (latlng) {
|
|
24
|
+
this._latlngs.push(latlng);
|
|
25
|
+
return this.redraw();
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
setOptions: function (options) {
|
|
29
|
+
L.setOptions(this, options);
|
|
30
|
+
if (this._heat) {
|
|
31
|
+
this._updateOptions();
|
|
32
|
+
}
|
|
33
|
+
return this.redraw();
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
getBounds: function () {
|
|
37
|
+
return L.latLngBounds(this._latlngs);
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
redraw: function () {
|
|
41
|
+
if (this._heat && !this._frame && this._map && !this._map._animating) {
|
|
42
|
+
this._frame = L.Util.requestAnimFrame(this._redraw, this);
|
|
43
|
+
}
|
|
44
|
+
return this;
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
onAdd: function (map) {
|
|
48
|
+
this._map = map;
|
|
49
|
+
|
|
50
|
+
if (!this._canvas) {
|
|
51
|
+
this._initCanvas();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (this.options.pane) {
|
|
55
|
+
this.getPane().appendChild(this._canvas);
|
|
56
|
+
}else{
|
|
57
|
+
map._panes.overlayPane.appendChild(this._canvas);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
map.on('moveend', this._reset, this);
|
|
61
|
+
|
|
62
|
+
if (map.options.zoomAnimation && L.Browser.any3d) {
|
|
63
|
+
map.on('zoomanim', this._animateZoom, this);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
this._reset();
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
onRemove: function (map) {
|
|
70
|
+
if (this.options.pane) {
|
|
71
|
+
this.getPane().removeChild(this._canvas);
|
|
72
|
+
}else{
|
|
73
|
+
map.getPanes().overlayPane.removeChild(this._canvas);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
map.off('moveend', this._reset, this);
|
|
77
|
+
|
|
78
|
+
if (map.options.zoomAnimation) {
|
|
79
|
+
map.off('zoomanim', this._animateZoom, this);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
addTo: function (map) {
|
|
84
|
+
map.addLayer(this);
|
|
85
|
+
return this;
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
_initCanvas: function () {
|
|
89
|
+
var canvas = this._canvas = L.DomUtil.create('canvas', 'leaflet-heatmap-layer leaflet-layer');
|
|
90
|
+
|
|
91
|
+
var originProp = L.DomUtil.testProp(['transformOrigin', 'WebkitTransformOrigin', 'msTransformOrigin']);
|
|
92
|
+
canvas.style[originProp] = '50% 50%';
|
|
93
|
+
|
|
94
|
+
var size = this._map.getSize();
|
|
95
|
+
canvas.width = size.x;
|
|
96
|
+
canvas.height = size.y;
|
|
97
|
+
|
|
98
|
+
var animated = this._map.options.zoomAnimation && L.Browser.any3d;
|
|
99
|
+
L.DomUtil.addClass(canvas, 'leaflet-zoom-' + (animated ? 'animated' : 'hide'));
|
|
100
|
+
|
|
101
|
+
this._heat = simpleheat(canvas);
|
|
102
|
+
this._updateOptions();
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
_updateOptions: function () {
|
|
106
|
+
this._heat.radius(this.options.radius || this._heat.defaultRadius, this.options.blur);
|
|
107
|
+
|
|
108
|
+
if (this.options.gradient) {
|
|
109
|
+
this._heat.gradient(this.options.gradient);
|
|
110
|
+
}
|
|
111
|
+
if (this.options.max) {
|
|
112
|
+
this._heat.max(this.options.max);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
_reset: function () {
|
|
117
|
+
var topLeft = this._map.containerPointToLayerPoint([0, 0]);
|
|
118
|
+
L.DomUtil.setPosition(this._canvas, topLeft);
|
|
119
|
+
|
|
120
|
+
var size = this._map.getSize();
|
|
121
|
+
|
|
122
|
+
if (this._heat._width !== size.x) {
|
|
123
|
+
this._canvas.width = this._heat._width = size.x;
|
|
124
|
+
}
|
|
125
|
+
if (this._heat._height !== size.y) {
|
|
126
|
+
this._canvas.height = this._heat._height = size.y;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this._redraw();
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
_redraw: function () {
|
|
133
|
+
if (!this._map) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
var data = [],
|
|
137
|
+
r = this._heat._r,
|
|
138
|
+
size = this._map.getSize(),
|
|
139
|
+
bounds = new L.Bounds(
|
|
140
|
+
L.point([-r, -r]),
|
|
141
|
+
size.add([r, r])),
|
|
142
|
+
|
|
143
|
+
max = this.options.max === undefined ? 1 : this.options.max,
|
|
144
|
+
maxZoom = this.options.maxZoom === undefined ? this._map.getMaxZoom() : this.options.maxZoom,
|
|
145
|
+
v = 1 / Math.pow(2, Math.max(0, Math.min(maxZoom - this._map.getZoom(), 12))),
|
|
146
|
+
cellSize = r / 2,
|
|
147
|
+
grid = [],
|
|
148
|
+
panePos = this._map._getMapPanePos(),
|
|
149
|
+
offsetX = panePos.x % cellSize,
|
|
150
|
+
offsetY = panePos.y % cellSize,
|
|
151
|
+
i, len, p, cell, x, y, j, len2, k;
|
|
152
|
+
|
|
153
|
+
// console.time('process');
|
|
154
|
+
for (i = 0, len = this._latlngs.length; i < len; i++) {
|
|
155
|
+
p = this._map.latLngToContainerPoint(this._latlngs[i]);
|
|
156
|
+
p = L.point(p.x, p.y);
|
|
157
|
+
if (bounds.contains(p)) {
|
|
158
|
+
x = Math.floor((p.x - offsetX) / cellSize) + 2;
|
|
159
|
+
y = Math.floor((p.y - offsetY) / cellSize) + 2;
|
|
160
|
+
|
|
161
|
+
var alt =
|
|
162
|
+
this._latlngs[i].alt !== undefined ? this._latlngs[i].alt :
|
|
163
|
+
this._latlngs[i][2] !== undefined ? +this._latlngs[i][2] : 1;
|
|
164
|
+
k = alt * v;
|
|
165
|
+
|
|
166
|
+
grid[y] = grid[y] || [];
|
|
167
|
+
cell = grid[y][x];
|
|
168
|
+
|
|
169
|
+
if (!cell) {
|
|
170
|
+
grid[y][x] = [p.x, p.y, k];
|
|
171
|
+
|
|
172
|
+
} else {
|
|
173
|
+
cell[0] = (cell[0] * cell[2] + p.x * k) / (cell[2] + k); // x
|
|
174
|
+
cell[1] = (cell[1] * cell[2] + p.y * k) / (cell[2] + k); // y
|
|
175
|
+
cell[2] += k; // cumulated intensity value
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
for (i = 0, len = grid.length; i < len; i++) {
|
|
181
|
+
if (grid[i]) {
|
|
182
|
+
for (j = 0, len2 = grid[i].length; j < len2; j++) {
|
|
183
|
+
cell = grid[i][j];
|
|
184
|
+
if (cell) {
|
|
185
|
+
data.push([
|
|
186
|
+
Math.round(cell[0]),
|
|
187
|
+
Math.round(cell[1]),
|
|
188
|
+
Math.min(cell[2], max)
|
|
189
|
+
]);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// console.timeEnd('process');
|
|
195
|
+
|
|
196
|
+
// console.time('draw ' + data.length);
|
|
197
|
+
this._heat.data(data).draw(this.options.minOpacity);
|
|
198
|
+
// console.timeEnd('draw ' + data.length);
|
|
199
|
+
|
|
200
|
+
this._frame = null;
|
|
201
|
+
},
|
|
202
|
+
|
|
203
|
+
_animateZoom: function (e) {
|
|
204
|
+
var scale = this._map.getZoomScale(e.zoom),
|
|
205
|
+
offset = this._map._getCenterOffset(e.center)._multiplyBy(-scale).subtract(this._map._getMapPanePos());
|
|
206
|
+
|
|
207
|
+
if (L.DomUtil.setTransform) {
|
|
208
|
+
L.DomUtil.setTransform(this._canvas, offset, scale);
|
|
209
|
+
|
|
210
|
+
} else {
|
|
211
|
+
this._canvas.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ')';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
L.heatLayer = function (latlngs, options) {
|
|
217
|
+
return new L.HeatLayer(latlngs, options);
|
|
218
|
+
};
|