OpenLayers 5 使用GeoJSON數(shù)據(jù)渲染熱力圖
GIS開發(fā)中會(huì)遇到需要使用熱力圖Heatmap的時(shí)候,openlayers5官方示例給出的是kml文件描述的熱力圖數(shù)據(jù),開發(fā)中接觸更多的還是GeoJSON格式,本文就使用GeoJSON格式來(lái)實(shí)現(xiàn)一個(gè)熱力圖。
地震熱力圖
一、實(shí)現(xiàn)思路
https://openlayers.org/en/latest/examples/heatmap-earthquakes.html
官方例子是從一個(gè)kml文件解析出生成的熱力圖,那么我們先分析一下生成一個(gè)熱力圖需要哪些數(shù)據(jù):
地點(diǎn)
坐標(biāo)
震級(jí)
基本上我們有了這三個(gè)數(shù)據(jù)就可以描述一個(gè)地點(diǎn)的地震情況了。
接下來(lái)我們看一下官方例子里使用了哪些技術(shù),核心代碼:
//前面省略了import語(yǔ)句等,詳見官方的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有一個(gè) ol/layer/heatmap 類,用來(lái)渲染熱力圖,那么稍微研究一下初始化該類型對(duì)象的代碼:
var vector = new HeatmapLayer({
source: new VectorSource({
url: ‘data/kml/2012_Earthquakes_Mag5.kml’,
//實(shí)際上我們只需要把這里的source對(duì)象換成GeoJSON對(duì)象就可以使用GeoJSON描述的數(shù)據(jù)源了
format: new KML({
extractStyles: false
})
}),
blur: parseInt(blur.value, 10),
radius: parseInt(radius.value, 10)
});
可以看到初始化source的時(shí)候,format初始化為一個(gè)KML對(duì)象,那么我們一會(huì)試試把它換成GeoJSON對(duì)象。
下面一段代碼是在這個(gè)熱力圖圖層添加要素的時(shí)候觸發(fā)的addfeatrue事件上面綁定一個(gè)回調(diào)函數(shù),是做什么的呢?我們先看一下kml文件,重點(diǎn)關(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>
然后對(duì)照回調(diào)函數(shù)的代碼看一下:
vector.getSource().on(‘a(chǎn)ddfeature’, function(event) {
//從name字段取得字符串: M 5.9 - 2012 Jan 15, SOUTH SHETLAND ISLANDS
var name = event.feature.get(‘name’);
//從子串中取得浮點(diǎn)數(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);
});
分析完這一段代碼之后,我們就可以自己動(dòng)手了。
二、實(shí)現(xiàn)步驟
首先我們得搞一些GeoJSON描述的地震數(shù)據(jù):
https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson
為了調(diào)試方便我下載到了本地保存為earthquake.json。
首先改造heatmap初始化過(guò)程:
let heatMapLayer = new HeatmapLayer({
source: new VectorSource({
//我們使用json數(shù)據(jù)
url: ‘./earthquake.json’,
format: new GeoJSON()
}),
//這里可以根據(jù)自己項(xiàng)目的實(shí)際,綁定頁(yè)面的控件動(dòng)態(tài)調(diào)整
blur: 5,
radius: 5
});
然后我們看一下GeoJSON格式,每一個(gè)地震點(diǎn)的信息就是這樣來(lái)表示的:
{
“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字段就是地震的震級(jí),是我們需要的,place是發(fā)生的地點(diǎn),geometry的信息就是這個(gè)feature的形態(tài)。
地點(diǎn)√
坐標(biāo)√
震級(jí)√
似乎萬(wàn)事俱備了。
最后我們需要實(shí)現(xiàn)的就是回調(diào)函數(shù):
heatMapLayer.getSource().on(‘a(chǎn)ddfeature’, function(event) {
var place = event.feature.get(‘place’);
var magnitude = event.feature.get(‘mag’);
//設(shè)定權(quán)重減去的數(shù)字是為了過(guò)濾地震等級(jí),比如只想顯示3級(jí)以上地震,那就減去3
event.feature.set(‘weight’, magnitude-3);
});
效果圖: