mapboxgl根據GeoJSON點線面建立及定位操作
阿新 • • 發佈:2018-12-05
mapboxgl的開發很方便,圖層建立、圖層的要素更新、圖層要素點選、要素資訊框、定位到要素、地圖滑鼠樣式等操作很多,總結了一些程式碼,共享給大家。
關鍵是:map.addSource、 map.addLayer、設定layer的paint、mapboxgl.Popup、map.fitBounds、map.flyTo、map.getCanvas().style.cursor、 map.getSource('geodataPolygon').setData
先建立一個mapboxgl的地圖吧,程式碼如下:
var map, graphicLayer; map = new mapboxgl.Map({ container: 'map', style: { "version": 8, "sources": { "raster-tiles": { "type": "raster", "tiles": ["https:///mt0.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}", "https:///mt1.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}", "https:///mt2.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}", "https:///mt3.google.cn/vt/lyrs=m&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}"], "tileSize": 256, }, }, "layers": [{ "id": "simple-tiles", "type": "raster", "source": "raster-tiles", "minzoom": 0, "maxzoom": 22 }] }, center: [104.064013, 30.54742], zoom: 12.64 }); map.addControl(new mapboxgl.NavigationControl(), 'top-left');
mapboxgl根據多型別的GeoJSON資料(含Point Polygon LineString)建立
//多型別的資料含Point Polygon LineString var geojson = { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "name": "天府三街" }, "geometry": { "type": "Point", "coordinates": [104.06303023033792, 30.54675753000589] } }, { "type": "Feature", "properties": { "name": "天府五街" }, "geometry": { "type": "Point", "coordinates": [104.06056505865428, 30.537889923501893] } } , { "type": "Feature", "properties": { "name": "銀泰城" }, "geometry": { "coordinates": [[[104.05734538204854, 30.542126961366336], [104.05733923297134, 30.540628203046936], [104.06044451507631, 30.540659979072146], [104.06041991880102, 30.542142849135033], [104.05734538204854, 30.542126961366336]]], "type": "Polygon" } }, { "type": "Feature", "geometry": { "type": "LineString", "properties": { "name": "天府大道" }, "coordinates": [ [104.06913702979529, 30.546739585129146], [104.06907454389955, 30.54592791405807], [104.06912588372228, 30.544417223111353], [104.06914299695103, 30.542508560460377] ] } } ] }; //多種型別的資料一起初始化 function initGeometryMutil() { map.addSource('geodata', { type: 'geojson', data: geojson }); map.addLayer({ "id": "polygonlayer", "type": "fill", "source": "geodata", "paint": { "fill-color": "red", "fill-opacity": 0.4 }, "filter": ["==", "$type", "Polygon"] }); map.addLayer({ 'id': 'pointlayer', 'type': 'circle', 'source': "geodata", "filter": ["==", "$type", "Point"], 'paint': { // make circles larger as the user zooms from z12 to z22 'circle-radius': { 'base': 1.75, 'stops': [[12, 2], [22, 180]] }, "circle-color": "#B42222" } }); map.addLayer({ 'id': 'linelayer', 'type': 'line', 'source': "geodata", "filter": ["==", "$type", "LineString"], "layout": { "line-join": "round", "line-cap": "round" }, "paint": { "line-color": "#BF93E4", "line-width": 5 } }); }
單獨的點、線、面型別GeoJSON建立
var geojsonPoints = { "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "name": "天府三街" }, "geometry": { "type": "Point", "coordinates": [104.06303023033792, 30.54675753000589] } }, { "type": "Feature", "properties": { "name": "天府五街" }, "geometry": { "type": "Point", "coordinates": [104.06056505865428, 30.537889923501893] } } ] }; var geojsonPolygon = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id":1, "name": "銀泰城" }, "geometry": { "coordinates": [[[104.05734538204854, 30.542126961366336], [104.05733923297134, 30.540628203046936], [104.06044451507631, 30.540659979072146], [104.06041991880102, 30.542142849135033], [104.05734538204854, 30.542126961366336]]], "type": "Polygon" } } ] }; var geojsonLine = { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": 1, "name": "天府大道" }, "geometry": { "type": "LineString", "coordinates": [ [104.06913702979529, 30.546739585129146], [104.06907454389955, 30.54592791405807], [104.06912588372228, 30.544417223111353], [104.06914299695103, 30.542508560460377] ] } } ] }; //僅初始化點型別 function initPoints() { map.addSource('geodataPoint', { type: 'geojson', data: geojsonPoints }); map.addLayer({ 'id': 'pointlayer', 'type': 'circle', 'source': "geodataPoint", 'paint': { // make circles larger as the user zooms from z12 to z22 'circle-radius': { 'base': 1.75, 'stops': [[12, 2], [22, 180]] }, //'circle-radius':13, "circle-color": "#B42222" } }); } //僅初始化線型別 function initLines() { map.addSource('geodataLine', { type: 'geojson', data: geojsonLine }); map.addLayer({ 'id': 'linelayer', 'type': 'line', 'source': "geodataLine", "layout": { "line-join": "round", "line-cap": "round" }, "paint": { "line-color": "#BF93E4", "line-width": 5 } }); } //僅初始化面型別 function initPolygon() { map.addSource('geodataPolygon', { type: 'geojson', data: geojsonPolygon }); map.addLayer({ "id": "polygonlayer", "type": "fill", "source": "geodataPolygon", "paint": { "fill-color": "red", "fill-opacity": 0.4 } }); }
點選線、面圖層,顯示資訊框
// 點選 面 圖層的符號,顯示資訊
map.on('click', 'polygonlayer', function (e) {
//map.flyTo({ center: e.features[0].geometry.coordinates });
//var boundingBox = getPolygonBoundingBox(e.features[0]);
//map.fitBounds(boundingBox, { padding: 200 });
var coordinates = e.lngLat;
var description = e.features[0].properties.id + "<br/>" + e.features[0].properties.name;
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}//防止資料越界
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
//點選 線 圖層的符號,顯示資訊
map.on('click', 'linelayer', function (e) {
var coordinates = e.lngLat;
var description = e.features[0].properties.id + "<br/>" + e.features[0].properties.name;
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}//防止資料越界
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
});
定位到點、線、面
//定位到某一個面
document.getElementById("btnZoom2FirstPolygon").onclick = function () {
if (geojsonPolygon.features.length == 0) {
alert("已經沒有多邊形面Feature了,至少有一條才能定位");
return;
};
var boundingBox = getPolygonBoundingBox(geojsonPolygon.features[0]);
map.fitBounds(boundingBox, { padding: 200 });
};
//定位到某一條線
document.getElementById("btnZoom2FirstLine").onclick = function () {
if (geojsonLine.features.length == 0) {
alert("已經沒有線Feature了,至少有一條才能定位");
return;
};
// Geographic coordinates of the LineString
var coordinates = geojsonLine.features[0].geometry.coordinates;
// Pass the first coordinates in the LineString to `lngLatBounds` &
// wrap each coordinate pair in `extend` to include them in the bounds
// result. A variation of this technique could be applied to zooming
// to the bounds of multiple Points or Polygon geomteries - it just
// requires wrapping all the coordinates with the extend method.
var bounds = coordinates.reduce(function (bounds, coord) {
return bounds.extend(coord);
}, new mapboxgl.LngLatBounds(coordinates[0], coordinates[0]));
map.fitBounds(bounds, {
padding: 20
});
};
//定位到某一個點
document.getElementById("btnZoom2FirstPoint").onclick = function () {
if (geojsonPoints.features.length == 0) {
alert("已經沒有線Feature了,至少有一點才能定位");
return;
};
// Geographic coordinates of the LineString
var coordinates = geojsonPoints.features[0].geometry.coordinates;
var xy = new mapboxgl.LngLat(coordinates[0], coordinates[1]);
map.flyTo({center:xy, zoom:16});
};
function getPolygonBoundingBox(feature) {
// bounds [xMin, yMin][xMax, yMax]
var bounds = [[], []];
var polygon;
var latitude;
var longitude;
for (var i = 0; i < feature.geometry.coordinates.length; i++) {
if (feature.geometry.coordinates.length === 1) {
// Polygon coordinates[0][nodes]
polygon = feature.geometry.coordinates[0];
} else {
// Polygon coordinates[poly][0][nodes]
polygon = feature.geometry.coordinates[i][0];
}
for (var j = 0; j < polygon.length; j++) {
longitude = polygon[j][0];
latitude = polygon[j][1];
bounds[0][0] = bounds[0][0] < longitude ? bounds[0][0] : longitude;
bounds[1][0] = bounds[1][0] > longitude ? bounds[1][0] : longitude;
bounds[0][1] = bounds[0][1] < latitude ? bounds[0][1] : latitude;
bounds[1][1] = bounds[1][1] > latitude ? bounds[1][1] : latitude;
}
}
return bounds;
}
設定mapboxgl圖層滑鼠的樣式
// Change the cursor to a pointer when the it enters a feature in the 'symbols' layer.
map.on('mouseenter', 'polygonlayer', function () {
map.getCanvas().style.cursor = 'pointer';
});
// Change it back to a pointer when it leaves.
map.on('mouseleave', 'polygonlayer', function () {
map.getCanvas().style.cursor = '';
});
通過操作mapboxgl中GeoJSON的資料,更新Source來實現圖層資料的新增、修改、刪除
document.getElementById("btnAddData").onclick = function () {
geojsonPolygon.features.push(
{
"type": "Feature",
"properties": {
"id":2,
"name": "香年廣場"
},
"geometry": {
"coordinates": [[[104.06580881154582, 30.545463011873835], [104.06579777330768, 30.54478171727888], [104.06711500077967, 30.544753197865305], [104.06711132135428, 30.54549153107891], [104.06580881154582, 30.545463011873835]]],
"type": "Polygon"
}
}
);
map.getSource('geodataPolygon').setData(
geojsonPolygon
);
};
document.getElementById("btnGetDataAndUpdate").onclick = function () {
for(var i=0; i<geojsonPolygon.features.length; i++ )
{
if (geojsonPolygon.features[i].properties["id"] == 2)
{
geojsonPolygon.features.pop(geojsonPolygon.features[i]);
}
}
map.getSource('geodataPolygon').setData(
geojsonPolygon
);
};
document.getElementById("btnDeleteAll").onclick = function () {
geojsonPolygon.features = [];
map.getSource('geodataPolygon').setData(
geojsonPolygon
);
};