使用 Popups
示例
代码实现
vue
<template>
<div id="map" class="w-full h-96"></div>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
</template>
<script setup>
import { onMounted } from "vue";
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { fromLonLat } from "ol/proj";
import VectorSource from "ol/source/Vector";
import VectorLayer from "ol/layer/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import Circle from "ol/geom/Circle";
import Polygon from "ol/geom/Polygon";
import { Style, Fill, Stroke, Circle as CircleStyle } from "ol/style";
import Overlay from "ol/Overlay";
onMounted(() => {
// 创建地图
const map = new Map({
target: "map",
layers: [
new TileLayer({
source: new XYZ({
url: "http://{a-c}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
}),
}),
],
view: new View({
center: fromLonLat([-0.09, 51.505]),
zoom: 13,
}),
});
// 创建弹窗元素
const container = document.getElementById("popup");
const content = document.getElementById("popup-content");
const closer = document.getElementById("popup-closer");
// 创建弹窗覆盖物
const overlay = new Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250,
},
});
map.addOverlay(overlay);
// 关闭按钮点击事件
closer.onclick = function () {
overlay.setPosition(undefined);
closer.blur();
return false;
};
// 创建矢量图层
const vectorSource = new VectorSource();
const vectorLayer = new VectorLayer({
source: vectorSource,
});
map.addLayer(vectorLayer);
// 添加标记点
const marker = new Feature({
geometry: new Point(fromLonLat([-0.09, 51.505])),
name: "A pretty CSS3 popup.<br> Easily customizable.",
});
marker.setStyle(
new Style({
image: new CircleStyle({
radius: 6,
fill: new Fill({
color: "#3388ff",
}),
stroke: new Stroke({
color: "#ffffff",
width: 2,
}),
}),
})
);
vectorSource.addFeature(marker);
// 添加圆
const circle = new Feature({
geometry: new Circle(fromLonLat([-0.11, 51.508]), 500),
name: "我是圆",
});
circle.setStyle(
new Style({
fill: new Fill({
color: "rgba(255,0,51,0.5)",
}),
stroke: new Stroke({
color: "red",
width: 2,
}),
})
);
vectorSource.addFeature(circle);
// 添加多边形
const polygon = new Feature({
geometry: new Polygon([
[
fromLonLat([-0.08, 51.509]),
fromLonLat([-0.06, 51.503]),
fromLonLat([-0.047, 51.51]),
fromLonLat([-0.08, 51.509]),
],
]),
name: "我是多边形",
});
polygon.setStyle(
new Style({
fill: new Fill({
color: "rgba(51,136,255,0.5)",
}),
stroke: new Stroke({
color: "#3388ff",
width: 2,
}),
})
);
vectorSource.addFeature(polygon);
// 点击事件处理
map.on("click", function (evt) {
const feature = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
});
if (feature) {
const coordinates =
feature.getGeometry().getType() === "Point"
? feature.getGeometry().getCoordinates()
: evt.coordinate;
content.innerHTML = feature.get("name");
overlay.setPosition(coordinates);
} else {
overlay.setPosition(undefined);
}
});
});
</script>
<style scoped>
.w-full {
width: 100%;
}
.h-96 {
height: 24rem;
}
.ol-popup {
position: absolute;
background-color: white;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
padding: 15px 35px 15px 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
min-width: 180px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
position: absolute;
top: 8px;
right: 8px;
width: 20px;
height: 20px;
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #999;
border-radius: 50%;
transition: all 0.2s;
}
.ol-popup-closer:hover {
background: #f0f0f0;
color: #666;
}
.ol-popup-closer:after {
content: "×";
}
</style>