GIS開發(fā)中會遇到需要使用熱力圖Heatmap的時候虹茶,openlayers5官方示例給出的是kml文件描述的熱力圖數(shù)據(jù),開發(fā)中接觸更多的還是GeoJSON格式峰搪,本文就使用GeoJSON格式來實現(xiàn)一個熱力圖。
一、實現(xiàn)思路
https://openlayers.org/en/latest/examples/heatmap-earthquakes.html
官方例子是從一個kml文件解析出生成的熱力圖赖捌,那么我們先分析一下生成一個熱力圖需要哪些數(shù)據(jù):
- 地點
- 坐標(biāo)
- 震級
基本上我們有了這三個數(shù)據(jù)就可以描述一個地點的地震情況了。
接下來我們看一下官方例子里使用了哪些技術(shù)矮烹,核心代碼:
//前面省略了import語句等越庇,詳見官方的Demo
var vector = new HeatmapLayer({
source: new VectorSource({
url: 'data/kml/2012_Earthquakes_Mag5.kml',
format: new KML({
extractStyles: false
})
}),
blur: parseInt(blur.value, 10),
radius: parseInt(radius.value, 10)
});
vector.getSource().on('addfeature', function(event) {
var name = event.feature.get('name');
var magnitude = parseFloat(name.substr(2));
event.feature.set('weight', magnitude - 5);
});
openlayers5有一個 ol/layer/heatmap 類,用來渲染熱力圖奉狈,那么稍微研究一下初始化該類型對象的代碼:
var vector = new HeatmapLayer({
source: new VectorSource({
url: 'data/kml/2012_Earthquakes_Mag5.kml',
//實際上我們只需要把這里的source對象換成GeoJSON對象就可以使用GeoJSON描述的數(shù)據(jù)源了
format: new KML({
extractStyles: false
})
}),
blur: parseInt(blur.value, 10),
radius: parseInt(radius.value, 10)
});
可以看到初始化source的時候卤唉,format初始化為一個KML對象,那么我們一會試試把它換成GeoJSON對象仁期。
下面一段代碼是在這個熱力圖圖層添加要素的時候觸發(fā)的addfeatrue事件上面綁定一個回調(diào)函數(shù)桑驱,是做什么的呢?我們先看一下kml文件跛蛋,重點關(guān)注Placemark字段:
<Placemark id="2012 Jan 15 13:40:16.40 UTC">
<name>M 5.9 - 2012 Jan 15, SOUTH SHETLAND ISLANDS</name>
<magnitude>5.9</magnitude>
<Point>
<coordinates>-56.072,-60.975,0</coordinates>
</Point>
</Placemark>
然后對照回調(diào)函數(shù)的代碼看一下:
vector.getSource().on('addfeature', function(event) {
//從name字段取得字符串: M 5.9 - 2012 Jan 15, SOUTH SHETLAND ISLANDS
var name = event.feature.get('name');
//從子串中取得浮點數(shù):5.9
var magnitude = parseFloat(name.substr(2));
//設(shè)定feature的權(quán)重weight為:5.9-5=0.9
event.feature.set('weight', magnitude - 5);
});
分析完這一段代碼之后熬的,我們就可以自己動手了。
二赊级、實現(xiàn)步驟
首先我們得搞一些GeoJSON描述的地震數(shù)據(jù):
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
為了調(diào)試方便我下載到了本地保存為earthquake.json押框。
首先改造heatmap初始化過程:
let heatMapLayer = new HeatmapLayer({
source: new VectorSource({
//我們使用json數(shù)據(jù)
url: './earthquake.json',
format: new GeoJSON()
}),
//這里可以根據(jù)自己項目的實際,綁定頁面的控件動態(tài)調(diào)整
blur: 5,
radius: 5
});
然后我們看一下GeoJSON格式理逊,每一個地震點的信息就是這樣來表示的:
{
"type": "Feature",
"properties": {
"mag": 1.36,
"place": "6km W of Cobb, CA",
"time": 1554968762010,
"updated": 1554969663578,
"tz": -480,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/nc73163930",
"detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/nc73163930.geojson",
"felt": null,
"cdi": null,
"mmi": null,
"alert": null,
"status": "automatic",
"tsunami": 0,
"sig": 28,
"net": "nc",
"code": "73163930",
"ids": ",nc73163930,",
"sources": ",nc,",
"types": ",geoserve,nearby-cities,origin,phase-data,scitech-link,",
"nst": 25,
"dmin": 0.01216,
"rms": 0.04,
"gap": 32,
"magType": "md",
"type": "earthquake",
"title": "M 1.4 - 6km W of Cobb, CA"
},
"geometry": {
"type": "Point",
"coordinates": [-122.7946701, 38.8251648, 2.4]
},
"id": "nc73163930"
},
……
顯而易見橡伞,mag字段就是地震的震級盒揉,是我們需要的,place是發(fā)生的地點兑徘,geometry的信息就是這個feature的形態(tài)预烙。
- 地點√
- 坐標(biāo)√
- 震級√
似乎萬事俱備了。
最后我們需要實現(xiàn)的就是回調(diào)函數(shù):
heatMapLayer.getSource().on('addfeature', function(event) {
var place = event.feature.get('place');
var magnitude = event.feature.get('mag');
//設(shè)定權(quán)重減去的數(shù)字是為了過濾地震等級道媚,比如只想顯示3級以上地震扁掸,那就減去3
event.feature.set('weight', magnitude-3);
});
效果圖: