Skip to content

处理事件

上次更新 2025年8月20日星期三 3:16:20 字数 0 字 时长 0 分钟

示例

新标签页预览

代码实现

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, transform } 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";
import { toStringHDMS } from "ol/coordinate";

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 vectorSource = new VectorSource();
  const vectorLayer = new VectorLayer({
    source: vectorSource,
  });
  map.addLayer(vectorLayer);

  // 添加标记点
  const marker = new Feature({
    geometry: new Point(fromLonLat([-0.09, 51.505])),
  });
  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),
  });
  circle.setStyle(
    new Style({
      fill: new Fill({
        color: "rgba(255,0,0,0.5)",
      }),
      stroke: new Stroke({
        color: "#ff0000",
        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]),
      ],
    ]),
  });
  polygon.setStyle(
    new Style({
      fill: new Fill({
        color: "rgba(0,0,255,0.5)",
      }),
      stroke: new Stroke({
        color: "#0000ff",
        width: 2,
      }),
    })
  );
  vectorSource.addFeature(polygon);

  // 创建弹出层
  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,
    positioning: "bottom-center",
  });
  map.addOverlay(overlay);

  // 关闭按钮点击事件
  closer.onclick = function () {
    overlay.setPosition(undefined);
    closer.blur();
    return false;
  };

  // 点击事件处理
  map.on("click", function (evt) {
    const coordinate = evt.coordinate;
    const hdms = toStringHDMS(transform(coordinate, "EPSG:3857", "EPSG:4326"));

    content.innerHTML = "<p>你点击了地图:</p><code>" + hdms + "</code>";
    overlay.setPosition(coordinate);
  });
});
</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>
关注公众号