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)
相关推荐
大鱼前端2 小时前
2025年,AI时代下的前端职业思考
前端
勉灬之2 小时前
封装上传组件,提供各种校验、显示预览、排序等功能
开发语言·前端·javascript
outstanding木槿4 小时前
react中实现拖拽排序
前端·javascript·react.js
ordinary904 小时前
vue.js scoped样式冲突
前端·vue.js
我要学编程(ಥ_ಥ)5 小时前
速通前端篇——JavaScript
开发语言·前端·javascript
大强的博客5 小时前
《Vue3实战教程》19:Vue3组件 v-model
前端·javascript·vue.js
塔塔开!.6 小时前
element ui 组件 时间选择器出现转换问题的解决办法
前端·javascript·vue.js
胡桃夹夹子7 小时前
前端,npm install安装依赖卡在sill idealTree buildDeps(设置淘宝依赖)
前端·npm·node.js
大叔_爱编程7 小时前
wx015基于springboot+vue+uniapp的经济新闻资讯的设计与实现
vue.js·spring boot·小程序·uni-app·毕业设计·源码·课程设计
xing.yu.CTF7 小时前
HTML基础到精通笔记
前端·笔记·html