openlayers 绘图功能,编辑多边形,modify组件的使用(四)

本篇使用vue3-openlayers介绍一下编辑工具 modify

1 需求

使用 openlayers 绘图功能绘制多边形,绘制完成后可进行编辑

2 分析

主要是 openlayers 中 draw,modify 功能的使用

3 实现

javascript 复制代码
<template>
  <ol-map
    :loadTilesWhileAnimating="true"
    :loadTilesWhileInteracting="true"
    style="width: 100%; height: 100%"
		ref="mapRef"
  >
    <ol-view
      ref="view"
      :center="center"
      :rotation="rotation"
      :zoom="zoom"
      :projection="projection"
    />
    <ol-vector-layer>
      <ol-source-vector :projection="projection" :features="features">
        <ol-interaction-draw
          :type="'Polygon'"
          :source="source"
          @drawend="drawend"
          @drawstart="drawstart"
        >
          <ol-style :overrideStyleFunction="handleStyleFunction">
          </ol-style>
        </ol-interaction-draw>
				<ol-interaction-modify
				:pixelTolerance="10"
				:insertVertexCondition="handleInsertVertexCondition"
				@modifyend="handleModifyEnd"
        >
          <ol-style :overrideStyleFunction="handleModifyStyleFunction">
          </ol-style>
        </ol-interaction-modify>
      </ol-source-vector>
      <ol-style :overrideStyleFunction="styleFunction">
      </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 mapRef=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 handleInsertVertexCondition =(e)=>{
	return false;
}

const handleModifyStyleFunction = (feature: FeatureLike, currentStyle: Style) => {
	const coord = feature.getGeometry().getCoordinates();
  const layer = mapRef.value.map.getLayers().item(0);
  const features = layer.getSource().getFeatures();
  const coords = features.map(feature => feature.getGeometry().getCoordinates()).flat(2);
  let style = undefined;
	// 只有鼠标在顶点时才能触发编辑功能
  if (coords.find(c => c.toString() === coord.toString())) {
    style = new Style({
      geometry: new Point(coord),
      image: new Circle({
        radius: 6,
        fill: new Fill({
          color: '#ffff'
        }),
        stroke: new Stroke({
          color: 'red',
          width: 2
        })
      })
    });
  }

  return style;
};

const handleModifyEnd=(e)=>{
	features.value.push(e.feature);//这里可以把编辑后的feature添加到layer绑定的features中
	e.features.forEach(feature => {
      console.log(feature.getGeometry().getCoordinates());//获取所有坐标
    });
}

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>



```![](https://img-blog.csdnimg.cn/direct/423a30bfe6c9461fb9f174494883c499.gif#pic_center)
相关推荐
人工智能训练师8 小时前
Ubuntu22.04如何安装新版本的Node.js和npm
linux·运维·前端·人工智能·ubuntu·npm·node.js
Seveny078 小时前
pnpm相对于npm,yarn的优势
前端·npm·node.js
yddddddy9 小时前
css的基本知识
前端·css
昔人'9 小时前
css `lh`单位
前端·css
Nan_Shu_61411 小时前
Web前端面试题(2)
前端
知识分享小能手11 小时前
React学习教程,从入门到精通,React 组件核心语法知识点详解(类组件体系)(19)
前端·javascript·vue.js·学习·react.js·react·anti-design-vue
蚂蚁RichLab前端团队12 小时前
🚀🚀🚀 RichLab - 花呗前端团队招贤纳士 - 【转岗/内推/社招】
前端·javascript·人工智能
孩子 你要相信光12 小时前
css之一个元素可以同时应用多个动画效果
前端·css
萌萌哒草头将军12 小时前
Oxc 和 Rolldown Q4 更新计划速览!🚀🚀🚀
javascript·vue.js·vite
huangql52013 小时前
npm 发布流程——从创建组件到发布到 npm 仓库
前端·npm·node.js