需求

一般再绘制点,或者面的时候。会有点击弹窗的需求。

按需引入

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import Map from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import { Tile as TileLayer } from 'ol/layer';
import { fromLonLat, transform } from "ol/proj";
import { Point } from "ol/geom";
import { Feature, Overlay } from "ol";
import { Style, Icon } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import { Vector as VectorSource } from "ol/source";

初始化标记点

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
 const iconFeature = new Feature({
                geometry: new Point(fromLonLat([113.90314496806384, 32.55119145031371])),
            });

            const iconStyle = new Style({
                image: new Icon({
                    anchor: [0.5, 46],
                    anchorXUnits: "fraction",
                    anchorYUnits: "pixels",
                    src: require("@/assets/marker-icon.png"),
                }),
            });

            iconFeature.setStyle(iconStyle);

            this.pointLayer = new VectorLayer({
                source: new VectorSource({
                    features: [iconFeature],
                }),
            });

            this.map.addLayer(this.pointLayer);

初始化弹窗

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 // 点击地图展示弹窗
            this.popup = new Overlay({
                element: document.getElementById('popup'),
                positioning: 'bottom-center',       //相对于其位置属性的实际位置
                stopEvent: false,                   //事件冒泡
            });
            this.map.addOverlay(this.popup);
            let close = document.getElementById('popupclose')
            close.onclick = () => {
                this.popup.setPosition(undefined);
            }

监听地图点击事件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 this.map.on('click', evt => {
                let feature = this.map.forEachFeatureAtPixel(evt.pixel, (feature, layerVetor) => {
                    if (layerVetor == this.pointLayer) {
                        return feature;
                    }

                });
                if (feature) {
                    var coordinate = evt.coordinate;
                    this.popup.setPosition(coordinate);
                }

            })

forEachFeatureAtPixel 判断是否点击到绘制的点

效果如下

整体代码如下

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<template>
    <div>
        <div id="map">
        </div>
        <!-- 弹窗 -->
        <div id="popup">
            <div id="popupclose">X</div>
            <div id="content">我是弹窗</div>
        </div>
    </div>
</template>

<script>
import Map from 'ol/Map';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ';
import { Tile as TileLayer } from 'ol/layer';
import { fromLonLat, transform } from "ol/proj";
import { Point } from "ol/geom";
import { Feature, Overlay } from "ol";
import { Style, Icon } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import { Vector as VectorSource } from "ol/source";
export default {
    name: 'HelloWorld',
    data() {
        return {
            map: null,
            popup: null,
            pointLayer: null

        }
    },
    mounted() {

        this.init();
    },
    methods: {
        init() {
            let baseLayer = new TileLayer({
                visible: true,
                name: "电子图",
                source: new XYZ({
                    url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
                    crossOrigin: "anonymous",
                }),
            });
            this.map = new Map({
                target: 'map',
                layers: [baseLayer],
                view: new View({
                    center: fromLonLat([113.90314496806384, 32.55119145031371]),
                    zoom: 16
                })
            });
            this.setPoint()
            this.addpopup()

            this.map.on('click', evt => {
                let feature = this.map.forEachFeatureAtPixel(evt.pixel, (feature, layerVetor) => {
                    if (layerVetor == this.pointLayer) {
                        return feature;
                    }

                });
                if (feature) {
                    var coordinate = evt.coordinate;
                    this.popup.setPosition(coordinate);
                }

            })
        },
        setPoint() {
            const iconFeature = new Feature({
                geometry: new Point(fromLonLat([113.90314496806384, 32.55119145031371])),
            });

            const iconStyle = new Style({
                image: new Icon({
                    anchor: [0.5, 46],
                    anchorXUnits: "fraction",
                    anchorYUnits: "pixels",
                    src: require("@/assets/marker-icon.png"),
                }),
            });

            iconFeature.setStyle(iconStyle);

            this.pointLayer = new VectorLayer({
                source: new VectorSource({
                    features: [iconFeature],
                }),
            });

            this.map.addLayer(this.pointLayer);


        },
        addpopup() {
            // 点击地图展示弹窗
            this.popup = new Overlay({
                element: document.getElementById('popup'),
                positioning: 'bottom-center',       //相对于其位置属性的实际位置
                stopEvent: false,                   //事件冒泡
            });
            this.map.addOverlay(this.popup);
            let close = document.getElementById('popupclose')
            close.onclick = () => {
                this.popup.setPosition(undefined);
            }
        },


    }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#map {
    width: 1920px;
    height: 1080px;
}

#popup {
    width: 260px;
    height: auto;
    background: rgba(0, 0, 0, 0.6);

    border-radius: 2px;
    z-index: 100000;
    color: #fff;

}

#popupclose {
    text-align: right;
    color: #fff;
    cursor: pointer;
    margin-right: 20px;
    margin-top: 20px;
}

#content {
    text-align: center;
    padding: 10px;
}</style>