欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

程序员文章站 2022-04-19 20:58:55
...
1. 效果图vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果
2. 准备边界的 data 数据
2.1 给大家推荐一个geoJson提供边界数据的网址:geo数据源,大家可以在上面选择需要的区域的边界,下载json数据。

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

2.2 准备待会会用到的 china.json 文件(红色框中是 geo数据源 中国的边界数据)

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

3. 实现省市区域描边代码(核心请看上面 步骤2的边界数据获取 和 addArea 描边界方法)

addArea 方法
① 创建一个features 数组
② 遍历geo数据源,MultiPolygonPolygon 是 json数据源 geometry 属性的一个类型,一般的地图边界可能会存在两种格式,如果是MultiPolygon则使用 new MultiPolygo 去解析,如果是 Polygon则使用new Polygon 去解析json数据,把解析的数据返回到一个参数 routeFeature
③ 把循环遍历的 routeFeature 放在 创建的 features
④ 创建feature对象,最后添加到图层。

/**
 * 画中国地图区域
 * geo 参数是数据源 json 数据
 */
addArea(geo = []) {
    if (geo.length == 0) {
        return false;
    }
    let features = [];
    geo.forEach(g => {
        let lineData = g.features[0];
        let routeFeature = "";
        let data = lineData.geometry.coordinates;
        if (lineData.geometry.type == "MultiPolygon") {
            routeFeature = new Feature({
                geometry: new MultiPolygon(
                    lineData.geometry.coordinates
                ).transform("EPSG:4326", "EPSG:3857")
            });
        } else if (lineData.geometry.type == "Polygon") {
            routeFeature = new Feature({
                geometry: new Polygon(
                    lineData.geometry.coordinates
                ).transform("EPSG:4326", "EPSG:3857")
            });
        }
        // 设置样式
        routeFeature.setStyle(
            new Style({
                fill: new Fill({ color: "#4e98f444" }),
                stroke: new Stroke({
                    width: 3,
                    color: [71, 137, 227, 1]
                })
            })
        );
        features.push(routeFeature);
    });
    // 设置图层
    let routeLayer = new VectorLayer({
        source: new VectorSource({
            features: features
        })
    });
    // 添加图层
    this.map.addLayer(routeLayer);
},
3. 完整代码
<template>
    <div id="app">
        <div id="Map" ref="map"></div>
    </div>
</template>
<script>
import "ol/ol.css";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import XYZ from "ol/source/XYZ";
import { Map, View, Feature, ol } from "ol";
import { Style, Stroke, Fill } from "ol/style";
import { Polygon, MultiPolygon } from "ol/geom";
import { defaults as defaultControls, OverviewMap } from "ol/control";
import { fromLonLat } from "ol/proj";

import areaGeo from "@/geoJson/china.json";
export default {
    data() {
        return {
            map: null
        };
    },
    methods: {
        /**
         * 初始化地图
         */
        initMap() {
            this.map = new Map({
                target: "Map",
                controls: defaultControls({
                    zoom: true
                }).extend([]),
                layers: [
                    new TileLayer(
                        {
                            source: new XYZ({
                                url:
                                    "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
                            })
                        },
                        { zoomOffset: 1 }
                    )
                ],
                view: new View({
                    center: fromLonLat([108.522097, 37.272848]),
                    zoom: 4.7,
                    maxZoom: 19,
                    minZoom: 4
                })
            });
        },
        /**
         * 设置区域
         */
        addArea(geo = []) {
            if (geo.length == 0) {
                return false;
            }
            let features = [];
            geo.forEach(g => {
                let lineData = g.features[0];
                let routeFeature = "";
                let data = lineData.geometry.coordinates;
                if (lineData.geometry.type == "MultiPolygon") {
                    routeFeature = new Feature({
                        geometry: new MultiPolygon(
                            lineData.geometry.coordinates
                        ).transform("EPSG:4326", "EPSG:3857")
                    });
                } else if (lineData.geometry.type == "Polygon") {
                    routeFeature = new Feature({
                        geometry: new Polygon(
                            lineData.geometry.coordinates
                        ).transform("EPSG:4326", "EPSG:3857")
                    });
                }
                routeFeature.setStyle(
                    new Style({
                        fill: new Fill({ color: "#4e98f444" }),
                        stroke: new Stroke({
                            width: 3,
                            color: [71, 137, 227, 1]
                        })
                    })
                );
                features.push(routeFeature);
            });
            // 设置图层
            let routeLayer = new VectorLayer({
                source: new VectorSource({
                    features: features
                })
            });
            // 添加图层
            this.map.addLayer(routeLayer);
        },
        /**
         * 鼠标悬浮改变图标样式
         */
        pointerMove() {
            let _that = this;
            this.map.on("pointermove", function(evt) {
                _that.map.getTargetElement().style.cursor = _that.map.hasFeatureAtPixel(
                    evt.pixel
                )
                    ? "pointer"
                    : "";
            });
        }
    },
    mounted() {
        this.initMap();
        this.addArea(areaGeo);
        this.pointerMove();
    }
};
</script>
<style lang="scss" scoped>
// 此处非核心内容,已删除
</style>
4. 画省,市,区边界,道理一样,只需要换成对应的 geo边界数据文件即可
4.1 如:四川省(下载对应的geo json数据)

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

import areaGeo from "@/geoJson/sichuan.json";

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

4.2 如:成都市,金牛区(下载对应的geo json数据)

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

import areaGeo from "@/geoJson/chengdu.json";
import areaGeo from "@/geoJson/jinniu.json";

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

5. 画多个省份,或者市区的边界数据 (如:粤港澳大湾区项目需要如下展示效果)

把下载的多个geo数据源的文件放在一个json里面,用逗号隔开。

9area.json 数据文件截图。vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果

import areaGeo from "@/geoJson/9area.json";

vue openlayers【五】Feature类实现地图省市区边界,区域填充,多省市区(粤港澳大湾区)效果