1. 程式人生 > >mapboxgl根據GeoJSON點線面建立及定位操作

mapboxgl根據GeoJSON點線面建立及定位操作

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
            );

        };