openlayers 绘图功能,绘制多边形,draw组件的使用,一个简单的需求引发的思考(二)

上一篇是使用openlayers原生实现的,这一节使用vue3-openlayers实现(有轮子真好)

1 需求

使用openlayers绘图功能绘制多边形

2 分析

主要是openlayers中draw功能的使用

3 实现

为了方便,就不加载底图了,直接使用绘制功能

2.1 简单实现

<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />
		<ol-vector-layer>
      <ol-source-vector :projection="projection">
        <ol-interaction-draw
          :type="'Polygon'"
	       :features="features"
	       :source="source"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style>
            <ol-style-stroke color="rgba(228, 147, 87, 1)" :width="2"></ol-style-stroke>
            <ol-style-fill color="rgba(228, 147, 87, 0.5)"></ol-style-fill>
            <!-- <ol-style-circle :radius="5">
              <ol-style-fill color="#00dd11" />
              <ol-style-stroke color="blue" :width="2" />
            </ol-style-circle> -->
          </ol-style>
        </ol-interaction-draw>
      </ol-source-vector>

      <ol-style>
        <ol-style-stroke color="red" :width="2"></ol-style-stroke>
        <ol-style-fill color="rgba(255,0,0,0.3)"></ol-style-fill>
        <ol-style-circle :radius="7">
          <ol-style-fill color="red"></ol-style-fill>
        </ol-style-circle>
      </ol-style>
    </ol-vector-layer>
  </ol-map>
</template>

<script setup lang="ts">
import { DrawEvent } from 'ol/interaction/Draw';
const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const rotation = ref(0);
const features=ref([])
const source=ref([])


const drawstart = (event:Event) => {
  console.log(event);
};

const drawend = (event:DrawEvent) => {
  console.log(event.feature.getGeometry());
};
</script>
<style scoped lang="scss">

</style>


2.2 进阶实现(overrideStyleFunction属性的使用)

<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />
    <ol-vector-layer>
      <ol-source-vector :projection="projection">
        <ol-interaction-draw
          :type="'Polygon'"
          :features="features"
          :source="source"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style :overrideStyleFunction="handleStyleFunction">
            <!-- <ol-style-stroke color="rgba(228, 147, 87, 1)" :width="2"></ol-style-stroke>
            <ol-style-fill color="rgba(228, 147, 87, 0.5)"></ol-style-fill> -->
            <!-- <ol-style-circle :radius="5">
              <ol-style-fill color="#00dd11" />
              <ol-style-stroke color="blue" :width="2" />
            </ol-style-circle> -->
          </ol-style>
        </ol-interaction-draw>
      </ol-source-vector>

      <ol-style :overrideStyleFunction="styleFunction">
        <!-- <ol-style-stroke color="red" :width="2"></ol-style-stroke>
        <ol-style-fill color="rgba(255,0,0,0.3)"></ol-style-fill>
        <ol-style-circle :radius="7">
          <ol-style-fill color="red"></ol-style-fill>
        </ol-style-circle> -->
      </ol-style>
    </ol-vector-layer>
  </ol-map>
</template>

<script setup lang="ts">
import { FeatureLike } from 'ol/Feature';
import { LineString, Point } from 'ol/geom';
import { DrawEvent } from 'ol/interaction/Draw';
import { Circle, Fill, Stroke, Style } from 'ol/style';
const center = ref([121, 31]);
const projection = ref('EPSG:4326');
const zoom = ref(5);
const rotation = ref(0);
const features = ref([]);
const source = ref([]);

const drawstart = (event: Event) => {
  console.log(event);
};

const drawend = (event: DrawEvent) => {
  console.log(event.feature.getGeometry());
};

const handleStyleFunction = (feature: FeatureLike, currentStyle: Style) => {
  const geometry = feature.getGeometry();
  const coord = geometry.getCoordinates();
  const type = geometry.getType();
  const styles: Array<Style> = [];
  for (let i = 0; i < coord.length - 1; i++) {
    styles.push(
      new Style({
        geometry: new Point(coord[i]),
        image: new Circle({
          fill: new Fill({ color: [255, 255, 255, 1] }),
          stroke: new Stroke({
            color: 'rgba(228, 147, 87, 1)',
            width: 2
          }),
          radius: 4
        })
      })
    );
  }
  if (type === 'LineString') {
    for (let i = 0; i < coord.length - 1; i++) {
      styles.push(
        new Style({
          geometry: new LineString([coord[i], coord[i + 1]]),
          stroke: new Stroke({
            color: 'orange',
            lineDash: coord.length > 2 && i < coord.length - 2 ? [] : [10],
            width: 2
          })
        })
      );
    }
  }
  return styles;
};

const styleFunction = (feature: FeatureLike, currentStyle: Style) => {
  const styles = [];
  const coord = feature.getGeometry().getCoordinates();

  for (let i = 0; i < coord[0].length - 1; i++) {
    styles.push(
      new Style({
        geometry: new Point(coord[0][i]),
        image: new Circle({
          radius: 4,
          fill: new Fill({
            color: '#ffff'
          }),
          stroke: new Stroke({
            color: 'orange',
            width: 2
          })
        })
      })
    );
  }
  styles.push(
    new Style({
      fill: new Fill({
        color: [128, 128, 255, 0.5]
      }),
      stroke: new Stroke({
        color: 'blue',
        width: 2
      })
    })
  );
  return styles;
};
</script>
<style scoped lang="scss"></style>


存在问题:与上一篇一样,在点击鼠标后并且鼠标有移动时,前一段虚线才会变成实线,并且顶点加上Point,因为只有鼠标移动才会有新的坐标点加入到绘制,因为openlayers没有提供绘制过程中的钩子函数,所以只能是当前效果

最近更新

  1. TCP协议是安全的吗?

    2024-06-12 08:46:01       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-12 08:46:01       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-12 08:46:01       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-12 08:46:01       18 阅读

热门阅读

  1. ubuntu22.04禁止自动休眠的几种方式

    2024-06-12 08:46:01       9 阅读
  2. 算法训练营day53

    2024-06-12 08:46:01       7 阅读
  3. 代码随想录算法训练营day44

    2024-06-12 08:46:01       8 阅读
  4. 【环境搭建】3.阿里云ECS服务器 安装Redis

    2024-06-12 08:46:01       7 阅读
  5. CDN、CNAME、DNS

    2024-06-12 08:46:01       6 阅读