使用vue+openLayers开发离线地图以及离线点位的展示

发布时间 2023-08-10 09:46:07作者: _August0401

1 .下载 引入到需要的组件中

npm install ol

2. 需要用到的api... (根据开发需求以及实际情况进行引入)

import ol from "ol";
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { OSM, Vector as VectorSource, XYZ } from "ol/source";
import Overlay from "ol/Overlay";
import {
  Circle as sCircle,
  Fill,
  Stroke,
  Style,
  Circle as CircleStyle,
  Icon,
} from "ol/style";
import { defaults } from "ol/control";

3. 准备一个dom容器以及弹出层的容器

<div id="map"></div>
<div ref="popup" class="popup"></div>

4. 准备变量

map:null, // 地图容器
markers:[], // 地图点位
zoom:13, // 地图初始高度
position:[116.397128,39.916527], // 地图默认经纬度
popup:null, // 后期需要使用到的悬浮弹框

5. 代码如下:

mounted:{
    // 初始化一个地图
    this.initMap();
    // 获取后台的点位数据
    this.getData();
},
methods:{
      initMap(){
       // 首先创建一个离线瓦片图层
      const offlineLayer = new TileLayer({
       source: new XYZ({
          url: "后台地址+服务器文件名称" + "/{z}/{x}/{y}.png", // 设置本地离线瓦片所在路径
        }),
      }); 
       // 创建标点符号图层 设置他的样式
      const vectorLayer = new VectorLayer({
        source: new VectorSource({
          features: [],
        }),
        style: new Style({
          image: new sCircle({
            radius: 10,
            stroke: new Stroke({
              // 边界样式
              color: "rgba(64, 169, 255,.25)", // 边界颜色
              width: 16, // 边界宽度
            }),
            fill: new Fill({
              color: "#40a9ff",
            }),
          }),
        }),
      });
         // 创建地图
      this.map = new Map({
        // 设置地图控件,默认的三个控件都不显示
        controls: defaults({
          attribution: false,
          rotate: false,
          zoom: false,
        }),
        target: "map",
        layers: [offlineLayer, vectorLayer],
        view: new View({
          center: this.position, // 地图中心点
          zoom: this.zoom, // 缩放
          projection: "EPSG:4326", // 坐标系
          maxZoom: 18, // 限制地图缩放最大级别为18
        }),
      });
           // 创建弹出框
      this.popup = new Overlay({
        element: this.$refs.popup,

        positioning: "bottom-center",
        stopEvent: true,
        autoPanAnimation: {
          duration: 250,
        },
      });

      // 绑定
      this.map.addOverlay(this.popup);

      this.popup.setPositioning("center-center");

      // 监听鼠标移动 
      //openlayers / singleclick提供的方法
      this.map.on("pointermove", this.onMouseMove);
      // 监听鼠标单击
      this.map.on("singleclick", this.onMapClick);
    }, 
  },      
},
      // 获取数据 $get是对axios请求进行封装
    getData() {
     this.$get("点位接口").then((response) => {
       this.markers = response.data;
       setTimeout(() => { // 数据多可以使用定时器延时一下加载 避免全部加载造成卡顿
         this.addMarkers();
       }, 200);
     });
 },
      // 添加标记
    addMarkers() {
      const features = [];
      for (const marker of this.markers) {
        const feature = new Feature({
          geometry: new Point([marker.lon, marker.lat]),
          name: marker.name,
          num: marker.num,
          address: marker.address,
        });
        features.push(feature);
      }
      const vectorLayer = this.map.getLayers().getArray()[1];
      const source = vectorLayer.getSource();
      source.addFeatures(features);
    },
    // 鼠标移动
    onMouseMove(event) {
      const pixel = this.map.getEventPixel(event.originalEvent);
      const feature = this.map.forEachFeatureAtPixel(
        pixel,
        (feature) => feature
      );
      const coordinates = feature.getGeometry().getCoordinates();
      if (feature) {
        const name = feature.get("name");
        const number = feature.get("cumber");
        const address = feature.get("address");
        this.popup.getElement().innerHTML = `
        <div>名称: <span>${name}</span></div>
        <div>号码: <span>${number}</span></div>
        <div>地址: <span>${address}</span></div>
        `;
        this.popup.setPosition(coordinates);
        this.popup.getElement().style.display = "block";
        this.map.getTargetElement().style.cursor = "pointer";
      } else {
        this.popup.getElement().style.display = "none";
        this.map.getTargetElement().style.cursor = "-webkit-grab";
      }
    },
        
    // 地图单击 可根据不同的需求对两个方法进行改写
     onMapClick(event) {
      const pixel = this.map.getEventPixel(event.originalEvent);
      const feature = this.map.forEachFeatureAtPixel(
        pixel,
        (feature) => feature
      );
      if (feature) {
        const coordinates = feature.getGeometry().getCoordinates();
        console.log(coordinates);
      }
    },
}

6. 最后贴出popup的样式

#map {
  height: 100%;
}

.popup {
  position: absolute;
  background-color: white;
  padding: 5px;
  border-radius: 5px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2), 0 2px 10px rgba(0, 0, 0, 0.1);
}

#popup {
  min-width: 19.375rem;
  min-height: 3.125rem;
  white-space: normal;
  font-size: 0.75rem;
  background-color: white;
  /* -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
  filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); */
}

7. 参考中文官网OpenLayers 3 介绍