Skip to content

图片标注

TIP

点击地图添加图片标注。

代码如下:

点我查看代码
vue
<template>
  <div id="map"></div>
</template>

<script lang="ts" setup>
import { onMounted, reactive, onBeforeUnmount } from "vue";
import { Map, View, Feature } from "ol";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { defaults, FullScreen } from "ol/control";
import { XYZ, Vector as VectorSource } from "ol/source";
import { Point } from "ol/geom";
import { ATTRIBUTIONS, SHENZHEN, MAPURL } from "../../../constants";
import { createLabelStyle, addVectorLabel } from "./tools";

interface State {
  map: Map | null;
  vectorSource: VectorSource<Point> | null;
}

const state: State = reactive({
  map: null,
  vectorSource: null,
});

const raster = new TileLayer({
  source: new XYZ({
    attributions: ATTRIBUTIONS,
    url: MAPURL,
    maxZoom: 20,
  }),
});

const initMap = () => {
  state.map = new Map({
    //初始化map
    target: "map",
    //地图容器中加载的图层
    layers: [
      //加载瓦片图层数据
      raster,
    ],
    view: new View({
      projection: "EPSG:4326", // 坐标系,有EPSG:4326和EPSG:3 857
      center: SHENZHEN, // 深圳坐标
      //地图初始显示级别
      zoom: 5,
    }),
    //加载控件到地图容器中
    controls: defaults().extend([
      new FullScreen(), //加载全屏显示控件(目前支持非IE内核浏览器)
    ]),
  });
  //实例化Vector要素,通过矢量图层添加到地图容器中
  const iconFeature = new Feature({
    geometry: new Point(SHENZHEN),
  });
  iconFeature.setStyle(createLabelStyle());
  //矢量标注的数据源
  state.vectorSource = new VectorSource({
    features: [iconFeature],
  });
  //矢量标注图层
  const vectorLayer = new VectorLayer({
    source: state.vectorSource,
  });
  state.map.addLayer(vectorLayer);
};

onMounted(() => {
  initMap();
  if (state.map) {
    state.map.on("click", (evt) => {
      //鼠标单击点坐标
      const coordinate = evt.coordinate;
      //添加一个新的标注(矢量要素)
      addVectorLabel({
        coordinate,
        vectorSource: state.vectorSource,
      });
    });
  }
});

onBeforeUnmount(() => {
  if (state.map) {
    state.map.dispose();
    state.map = null;
  }
});
</script>

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

tools 代码如下:

点我查看代码
ts
import { Style, Icon } from 'ol/style'
import { Feature } from 'ol'
import { Point } from 'ol/geom'
import { VectorLabelOptions } from '../../../@types'

/**
 * 创建矢量标注样式函数,设置image为图标ol.style.Icon
 * @param {ol.Feature} feature 要素
 */
export const createLabelStyle = (): Style =>
  new Style({
    image: new Icon({
      //设置图标点
      anchor: [0.5, 60],
      //图标起点
      anchorOrigin: 'top-right',
      //指定x值为图标点的x值
      anchorXUnits: 'fraction',
      //指定Y值为像素的值
      anchorYUnits: 'pixels',
      //偏移
      offsetOrigin: 'top-right',
      // offset:[0,10],
      //图标缩放比例
      scale: 0.4,
      //透明度
      opacity: 0.75,
      //图标的url
      src: '/image/blue.png',
    }),
  })

/**
 * 添加一个新的标注(矢量要素)
 * @param {ol.Coordinate} coordinate 坐标点
 * @param {ol.source.Vector} vectorSource 矢量标注的数据源
 * @param {string} name 标注名
 */
export const addVectorLabel = ({
  coordinate,
  vectorSource,
  name = '标注点',
}: VectorLabelOptions) => {
  if (vectorSource === null) return
  //新建一个要素 ol.Feature
  const newFeature = new Feature({
    //几何信息
    geometry: new Point(coordinate),
    //名称属性
    name,
  })
  //设置要素的样式
  newFeature.setStyle(createLabelStyle())
  //将新要素添加到数据源中
  vectorSource.addFeature(newFeature)
}

如有转载或 CV 的请标注本站原文地址