OpenLayers 5 使用GeoJSON數(shù)據(jù)渲染熱力圖
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ù):
地點
坐標
震級
基本上我們有了這三個數(shù)據(jù)就可以描述一個地點的地震情況了。
接下來我們看一下官方例子里使用了哪些技術,核心代碼:
//前面省略了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事件上面綁定一個回調函數(shù),是做什么的呢?我們先看一下kml文件,重點關注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>
然后對照回調函數(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’);
//從子串中取得浮點數(shù):5.9
var magnitude = parseFloat(name.substr(2));
//設定feature的權重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
為了調試方便我下載到了本地保存為earthquake.json。
首先改造heatmap初始化過程:
let heatMapLayer = new HeatmapLayer({
source: new VectorSource({
//我們使用json數(shù)據(jù)
url: ‘./earthquake.json’,
format: new GeoJSON()
}),
//這里可以根據(jù)自己項目的實際,綁定頁面的控件動態(tài)調整
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)。
地點√
坐標√
震級√
似乎萬事俱備了。
最后我們需要實現(xiàn)的就是回調函數(shù):
heatMapLayer.getSource().on(‘a(chǎn)ddfeature’, function(event) {
var place = event.feature.get(‘place’);
var magnitude = event.feature.get(‘mag’);
//設定權重減去的數(shù)字是為了過濾地震等級,比如只想顯示3級以上地震,那就減去3
event.feature.set(‘weight’, magnitude-3);
});
效果圖:
