Leaflet在vue中使用天地图(三) — 地图行政区域反选

3,407 阅读2分钟

效果图

惯例先上效果图

前言

因为甲方爸爸的要求,突出行政区,不能是以前的那种划分样式,因为觉得不够突出……官方没有直接的api供选择,因此查了下资料,再根据逻辑推算,最终断断续续咸鱼的花了一天时间完成了 默认的行政区划选中图,不够突出当前区域 这样才比较突出中心!

逻辑

leaflet官方没有给出行政区域反选的api,但是!

  • 1、只要有坐标点,就可以进行自定义绘制图形。
  • 2、行政区域的geo配置可供选择进行更改边框、填充区域的颜色和透明度。
  • 3、leaflet提供了当前显示的地图四个角的坐标点,并且也可以监听地图放大和拖动事件

有了这几个点,就可以自己绘制反选的地图啦。官网传送门:leafletjs.com/reference-1…

参考了其他大佬的文档:blog.csdn.net/u012420268/…

代码详解

  • 绘制自定义图形需要的坐标点格式举例为:[[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]],所以只要设置好坐标点就可以自行绘制了。(起点和终点的坐标点要一致,保证中间部分能空出来)

注意!!每次绘画完,再次进行绘画的时候,要清空上次的图形,不然会不断叠加

//清除
this.maskArea.remove(map)
// 绘画
var maskArea = L.polygon(maskArr, {
    color: "transparent", // 边界颜色
    fillColor: "#B7D2EA", // 填充色
    fillOpacity: 0.8, // 填充透明度
});
  • geo区域颜色的配置,此项是设置填充区域的透明度,具体可更改的配置可在leaflet官网查看,我将配置写在了geojson文件中,这样比较方便更改
L.geoJSON(geoJson, {
    style: function(feature) {
      return { fillOpacity: feature.properties.fillOpacity };
    }
  }).addTo(map);
  • 获取地图的四个点以及放大、拖动监听事件
map.getBounds().getNorthWest();// 获取西北角-其他三点同理

// 监听缩放地图
map.on("zoomend", function(e) {
});
// 监听拖动地图
map.on("moveend", function (e) {
});

完整代码

代码已进行了详细注释,关于所有leaflet地图的代码都以上传git:github.com/SaltedFishH…

<template>
    <div>
        <div id="myMap" class="map-box"></div>
    </div>
</template>

<script>
import L from "leaflet";
import Provider from "./chinatmsproviders";
require("leaflet/dist/leaflet.css");
import geoJson from "./geojson";

export default {
    data() {
        return {
            mapKey: "", //你的key
            map: null,
            maskArea: null // 保存图形
        };
    },
    mounted() {
        Provider(L); // 挂载插件
        this.getMap();
    },
    methods: {
        getMap() {
            let _this = this
            // 绘制地图地图
            let myCenter = new L.LatLng(30.42, 120.3); // 地图中心点
            let map = L.map("myMap", {
              center: myCenter,
              zoom: 9
            });
            L.tileLayer .chinaProvider("TianDiTu.Normal.Map", {
                maxZoom: 18,
                minZoom: 5,
                key: this.mapKey
            }).addTo(map);
            L.tileLayer.chinaProvider("TianDiTu.Normal.Annotion", {
                maxZoom: 18,
                minZoom: 5,
                key: this.mapKey
            }).addTo(map);

            // 设置行政区域样式
            L.geoJSON(geoJson, {
                style: function(feature) {
                    return { fillOpacity: feature.properties.fillOpacity };
                }
            }).addTo(map);
            this.map = map
            // 监听缩放地图事件
            map.on("zoomend", function(e) {
                _this.drawBoundary();
            });
            // 监听拖动地图事件
            map.on("moveend", function (e) {
                _this.drawBoundary();
            });
            // 反选
            this.drawBoundary();
        },

        // 反选 添加外部边界
        drawBoundary() {
            let map = this.map
            // 加载geo中的经纬点
            let coordArr = geoJson.features[0].geometry.coordinates
            // 获取此时地图的四个角经纬度
            var mapNW = map.getBounds().getNorthWest();
            var mapNE = map.getBounds().getNorthEast();
            var mapSE = map.getBounds().getSouthEast();
            var mapSW = map.getBounds().getSouthWest();

            // 添加到闭合图形中
            var maskArr = [];
            maskArr.push(mapNW);
            maskArr.push(mapSW);
            maskArr.push(mapSE);
            maskArr.push(mapNE);
            maskArr.push(mapNW); // 设置为闭合区域的起点

            // 添加各闭合点      
            coordArr.map(res=>{
                var points = [];        
                res.map(subRes => {
                    subRes.map(item => {
                        points.push({ lat: item[1], lng: item[0] });
                    });
                });
                
                //将闭合区域加到遮罩层上,每次添加完后要再加一次西北角作为下次添加的起点和最后一次的终点
                maskArr = maskArr.concat(points);
                maskArr.push(maskArr[0]);
            })

            // 移除图层-不移除图层会不断叠加遮罩
            if(this.maskArea){
                this.maskArea.remove(map)
                this.maskArea = null
            }
            // 添加遮罩
            var maskArea = L.polygon(maskArr, {
                color: "transparent", // 边界颜色
                fillColor: "#B7D2EA", // 填充色
                fillOpacity: 0.8, // 填充透明度
            });
            maskArea.addTo(map);
            this.maskArea = maskArea
        }
    }
};
</script>