openlayers实现地图中的标注点

1,034 阅读3分钟

openlayers中地图中的标注点是可以通过多个图层叠加的方式来展现,比如说在WEB开发中,在一个容器中有很多个div盒子,这些盒子的背景颜色是全透明的,但是每个盒子的一部分区域可以写上自己想要的效果,再叠加到一起看起来就像是在一个div中实现的一样。openlayers中的图层大致可以理解成这个意思。

在Map对象上的layers这个option属性接收的是一个数组Array,这里面可以放置的图层就很多了,所以对于我们在操作就灵活很多。此处有疑问移步上篇# VueJS中的Openlayers渲染地图

Feature、Style设置标注点的两个构造方法

  • Feature是为我们创建一个feature对象的构造方法,包含经纬度及其他自定义的属性。但是这个类仅仅是创建一个地图要素(feature),只是创建这个我们是看不到任何效果的,就像是我们在做web开发中,没有样式的html,效果是看不见的。所以需要为feature设置样式Style
  • Style类就是为我们解决feature的样式问题,在openlayers中,可以设置基础的图形、文字,也可以使用自定义的图片,或者是两者的组合

image.png 比如图中北京市的标注是由文字和一个小圆点组合而成

实现一个点的标注

//导入ol标注相关的方法和属性
import Feature from "ol/Feature";
import { Point } from "ol/geom";
import {
    Circle as CircleStyle,
    RegularShape,
    Fill,
    Stroke,
    Style,
    Icon,
    Text,
} from "ol/style";
export default{
    data() {
        return {
            //在响应式数据中定义需要展现的图层
            cityLayer: new VectorLayer({
                name: "cityLayer",
                source: new VectorSource({}),
                style: null,
            }),
        };
    },
}

  • 初始化Map的时候在layers配置中,把cityLayer这个图层加入进去,否则没有加载的图层不会显示
        //创建点的标注实例和样式
        renderPoint() {
            let feature = new Feature({
                geometry: new Point([116.405289, 39.904987]),//设置标注点的经纬度
                name: "北京",
                //可以写一些自定义的属性
            });
            //为feature设置样式
            feature.setStyle(
                new Style({
                    image: new CircleStyle({
                        radius: 5,
                        stroke: new Stroke({
                            color: "#fff",
                        }),
                        fill: new Fill({
                            color: "#3399CC",
                        }),
                    }),
                    text: new Text({
                        text: '北京-110',
                        textAlign: "center",
                        font: "14px PingFangSC-Regular",
                        offsetX: 0,
                        offsetY: -20,
                        padding: [6, 6, 3, 6],
                        backgroundStroke: new Stroke({
                            color: "rgba(0, 0, 0, 0)",
                            width: 1,
                        }),
                        backgroundFill: new Fill({
                            color: "rgba(0,194,233, 0.4)",
                        }),
                        fill: new Fill({
                            color: "rgba(255, 255, 255, 1)",
                        }),
                    }),
                })
            );
            this.cityLayer.getSource().addFeatures([feature]);
        }

实现地图标注全国各直辖市、省会等城市

在此之前需要用到一个基础的data数据,就是全国各主要城市的经纬度,大致结构是这样

const chinaData = [{    name: "北京",    value: [116.405289, 39.904987]
},{ 
    name: "天津", 
    value: [117.190186, 39.125595] 
}]

创建features和设置style

        renderFeatures() {
            //清除该图层所有的feature要素
            this.cityLayer.getSource().clear();
            //创建features
            let features = this.createFeature(chinaData);
            //将features加入到图层中
            this.cityLayer.getSource().addFeatures(features);
        },
        createFeature(chinaData) {
            let features = [];
            for (const city of chinaData) {
                let feature = new Feature({
                    geometry: new Point(city.value),
                    name: city.name,
                });
                feature.setStyle(
                    new Style({
                        image: new CircleStyle({
                            radius: 5,
                            stroke: new Stroke({
                                color: "#fff",
                            }),
                            fill: new Fill({
                                color: "#3399CC",
                            }),
                        }),
                        text: new Text({
                            text: city.name,
                            textAlign: "center",
                            font: "14px PingFangSC-Regular",
                            offsetX: 0,
                            offsetY: -20,
                            padding: [6, 6, 3, 6],
                            backgroundStroke: new Stroke({
                                color: "rgba(0, 0, 0, 0)",
                                width: 1,
                            }),
                            backgroundFill: new Fill({
                                color: "rgba(0,194,233, 0.4)",
                            }),
                            fill: new Fill({
                                color: "rgba(255, 255, 255, 1)",
                            }),
                        }),
                    })
                );
                // feature.setStyle(createCommandNumberStyle(command))
                features.push(feature);
            }
            return features;
        },

image.png

几个实用API

  • 1、setVisible 设置图层的显示隐藏,接收一个bool类型的参数
  • 2、fit 自定义显示地图的缩放等级,地图的缩放等级和中心点在不确定的情况下,使用默认值显得不太合适,需要根据获取到的数据来确定这些值,这时,fit方法就派上用场了。具体使用
this.map.getView().fit([最小经度, 最小纬度, 最大经度, 最大纬度],{
    size: this.map.getSize(),
    maxZoom: 18,
    duration: 1000,
    padding: [150, 450, 350, 450]
});