Ol4網格生成以及優化
概述
先描述一下大致場景:以0.05為單元格大小生成網格,並在地圖上繪製,繪製的時候需要區分海陸。本文以此需求為契機,簡單描述一下該需求的實現以及如何來優化。
效果
實現
優化前
var source = new ol.source.Vector({
features: []
});
var vector = new ol.layer.Vector({
source: source,
zIndex: 1,
opacity: 0.65,
style: styleFunction
});
map.addLayer(vector);
var landData = format.readFeatures(chinaZone, options);
landGeom = landData[0].getGeometry();
function styleFunction(feat) {
var i = feat.get("i"),
j = feat.get("j"),
isLand = feat.get("land");
if(isLand) {
var val = data[i][j];
var color;
if (val > 0.33 && val <= 0.66) {
color = "orange";
} else if (val > 0.66 && val <= 1) {
color = "red";
} else {
color = 'yellow';
}
return new ol.style.Style({
fill: new ol.style.Fill({
color: color,
})
})
}
}
function generateGrid() {
var bound = $("#bound").val(),
size = Number($("#size").val());
var bounds = bound.split(",").map(Number);
console.time('Time Test');
createGrid(bounds, size);
console.timeEnd('Time Test')
}
function isOnLand(coord) {
var is = false;
for(var i = 0;i<landData.length;i++){
var geom = landData[i].getGeometry();
if (geom.intersectsCoordinate(coord)) {
is = true;
break;
}
}
return is;
}
function createGrid(bound, size) {
var gridData = {
type: "FeatureCollection",
features: []
};
var deltaLon = bound[2] - bound[0],
deltaLat = bound[3] - bound[1];
var numLon, numLat;
numLon = Math.ceil(deltaLon / size);
numLat = Math.ceil(deltaLat/ size);
var minLon = bound[0],
maxLat = bound[3];
for(var i = 0; i < numLat; i++) {
var lat1 = maxLat - i * size,
lat2 = maxLat - (i + 1) * size;
var latC = (lat1 + lat2) / 2;
data[i] = [];
for(var j = 0; j < numLon; j++) {
data[i][j] = Math.random();
var lon1 = minLon + j * size,
lon2 = minLon + (j + 1) * size;
var lonC = (lon1 + lon2) / 2;
var coord = ol.proj.fromLonLat([lonC, latC]);
var prop = {
i: i,
j: j,
land: isOnLand(coord)
};
// 網格面
var featG = {
"type":"Feature",
"properties": prop,
"geometry":{
"type":"Polygon",
"coordinates":[[
[lon1, lat1],
[lon2, lat1],
[lon2, lat2],
[lon1, lat2],
[lon1, lat1]
]]
}
};
gridData.features.push(featG);
}
}
var gridFeatures = format.readFeatures(gridData, options);
source.addFeatures(gridFeatures);
}
優化後
var source = new ol.source.Vector({
features: []
});
var vector = new ol.layer.Vector({
source: source,
zIndex: 1,
opacity: 0.65,
style: styleFunction,
renderMode: 'image'
});
map.addLayer(vector);
var landData = format.readFeatures(chinaZone, options);
landGeom = landData[0].getGeometry();
function styleFunction(feat) {
// i為lat,j為lon
var i = feat.get("i"),
j = feat.get("j"),
land = feat.get("land");
if(land) {
var val = data[i][j];
var color;
if (val > 0.33 && val <= 0.66) {
color = "orange";
} else if (val > 0.66 && val <= 1) {
color = "red";
} else {
color = 'yellow';
}
return new ol.style.Style({
// stroke: new ol.style.Stroke({
// color: 'grey',
// width: 1
// }),
fill: new ol.style.Fill({
color: color,
})
})
}
}
function generateGrid() {
var bound = $("#bound").val(),
size = Number($("#size").val());
var bounds = bound.split(",").map(Number);
console.time('Time Test');
createGrid(bounds, size);
console.timeEnd('Time Test')
}
function isOnLand(coord) {
return landGeom.intersectsCoordinate(coord);
}
/**
* 建立網格
* @param bound
* @param size
* @returns {{grid: {features: Array, type: string}, center: {features: Array, type: string}}}
*/
function createGrid(bound, size) {
var deltaLon = bound[2] - bound[0],
deltaLat = bound[3] - bound[1];
var numLat;
numLat = Math.ceil(deltaLat / size);
for (var i = 0; i < numLat; i++) {
data[i] = [];
getFeatures(bound, i, deltaLon, size)
.then(res => {
var json = {
"type": "FeatureCollection",
features: res
};
var features = format.readFeatures(json, options);
source.addFeatures(features);
})
}
}
function getFeatures(bound, i, deltaLon, size) {
var promise = new Promise(function(resolve, reject) {
window.setTimeout(function() {
var features = [];
var minLon = bound[0],
maxLat = bound[3],
numLon = Math.ceil(deltaLon / size);
var lat1 = maxLat - i * size,
lat2 = maxLat - (i + 1) * size;
var latC = (lat1 + lat2) / 2;
for(var j = 0; j < numLon; j++) {
var lon1 = minLon + j * size,
lon2 = minLon + (j + 1) * size;
var lonC = (lon1 + lon2) / 2;
var coord = ol.proj.fromLonLat([lonC, latC]);
var prop = {
i: i,
j: j,
land: isOnLand(coord)
};
data[i][j] = Math.random();
// 網格面
var featG = {
"type":"Feature",
"properties": prop,
"geometry":{
"type":"Polygon",
"coordinates":[[
[lon1, lat1],
[lon2, lat1],
[lon2, lat2],
[lon1, lat2],
[lon1, lat1]
]]
}
};
features.push(featG);
}
resolve(features);
});
});
return promise;
}
思路分析
通過前面的兩張圖可以明顯看出,優化前後效率上有了質的變化,這說明我們的優化思路是正確的。下面說一下我在做這部分優化的時候的思路:
1.找到原因
從本案例來看,能影響效率的有可能有兩點:1、js的for迴圈比較慢;2、渲染到地圖上的時候比較慢。於是就做了一下測試,發現原因其實是1,而不是2.
2.思考解決
既然找到了是1影響了效率,那就考慮如何優化1。在本案例中,第一層迴圈有200,第二層迴圈有140,由於js的執行是單執行緒順序執行的,所以我思考把這個迴圈拆開,拆成若干個迴圈,非同步執行,這樣就能避免同步執行慢的問題。因此,在優化的時候用了setTimeout
和promise
來實現迴圈的非同步執行。
3. 其他
此外,在建立vectorLayer的時候,加入了renderMode: 'image'
引數,提高渲染層面的效率。
思考優化
本案例其實還可以做進一步的優化,優化主要在渲染上,優化思路類似於地圖切片,將展示資料建立索引,並將展示結果進行分塊,以達到優化展示。
技術部落格
CSDN:http://blog.csdn.NET/gisshixisheng
線上教程
https://edu.csdn.net/course/detail/799
https://edu.csdn.net/course/detail/7471
聯絡方式
型別 | 內容 |
---|---|
1004740957 | |
公眾號 | lzugis15 |
niujp08@qq.com | |
webgis群 | 452117357 |
Android群 | 337469080 |
GIS資料視覺化群 | 458292378 |
相關文章
- MySQL查詢優化之優化器工作流程以及優化的執行計劃生成MySql優化
- 詳解SEO布詞以及網站排名優化技巧網站優化
- 尾遞迴以及優化遞迴優化
- MySQL 索引原理以及優化MySql索引優化
- 插入排序以及優化排序優化
- Android效能優化(4):UI渲染機制以及優化Android優化UI
- HBase建模、使用以及優化優化
- Webpack入門以及打包優化Web優化
- 個人部落格 SEO 優化(2):站內優化優化
- 使用React中後臺效能優化以及移動端優化React優化
- 使用vue中後臺效能優化以及移動端優化Vue優化
- Synchronized的實現原理以及優化synchronized優化
- provider的使用以及優化心得IDE優化
- 序列化篇 生成xml 以及讀取xmlXML
- 前端不止:Web效能優化–關鍵渲染路徑以及優化策略前端Web優化
- navmesh 生成網格資訊 總 (更新中 )
- Apache網頁優化與安全優化Apache網頁優化
- VuePress 部落格之 SEO 優化(三)標題、連結優化Vue優化
- 網路安全網格概念以及特點簡單普及
- 大規模服務網格效能優化 | Aeraki xDS 按需載入優化
- 一次完整的 Web 請求和渲染過程以及如何優化網頁Web優化網頁
- 13、nginx服務叢集搭建以及優化Nginx優化
- Node效能如何進行監控以及優化?優化
- KubeCon 2021|使用 eBPF 代替 iptables 優化服務網格資料面效能eBPF優化
- 網頁效能優化網頁優化
- 網站效能優化網站優化
- apache網頁優化Apache網頁優化
- 網站如何優化網站優化
- VuePress 部落格優化之開啟 HTTPSVue優化HTTP
- 運籌優化(八)--圖與網路優化優化
- iOS效能優化 - 網路圖片載入優化iOS優化
- mysql鎖機制總結,以及優化建議MySql優化
- 網站優化(一)——從何處著手開啟網站優化?網站優化
- 大規格檔案的上傳優化優化
- DNS與網站優化DNS網站優化
- 多執行緒下的網格生成及效能分析執行緒
- mysql 大表中count() 使用方法以及效能優化.MySql優化
- async與defer的作用與區別以及阻塞優化優化