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)
相关推荐
慧一居士19 分钟前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead21 分钟前
小哆啦解题记——两数失踪事件
前端·算法·面试
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang
中微子6 小时前
React Router 面试指南:从基础到实战
前端·react.js·前端框架
3Katrina6 小时前
深入理解 useLayoutEffect:解决 UI "闪烁"问题的利器
前端·javascript·面试
前端_学习之路7 小时前
React--Fiber 架构
前端·react.js·架构
伍哥的传说8 小时前
React 实现五子棋人机对战小游戏
前端·javascript·react.js·前端框架·node.js·ecmascript·js
qq_424409198 小时前
uniapp的app项目,某个页面长时间无操作,返回首页
前端·vue.js·uni-app