自学内容网 自学内容网

【GeoJSON在线编辑平台】(1)创建地图+要素绘制+折点编辑+拖拽移动

前言

简单实现一下地图加载、要素绘制、折点编辑和拖拽移动。打算统一都写到一个类里面。
为了快速实现,直接去参考了官方案例。

创建地图

pnpm install ol

ol

加载地图

在这里,我们创建一个 mapView.js 的文件专门用来放地图和视图相关的方法,需要时引用即可。

/*
 * @Date: 2024-10-31 16:17:31
 * @LastEditors: ReBeX  cswwwx@gmail.com
 * @LastEditTime: 2024-11-04 11:24:42
 * @FilePath: \geojson-editor-ol\src\utils\mapView.js
 * @Description: 地图及视图相关方法
 * @Reference: https://openlayers.org/en/latest/apidoc/module-ol_Map-Map.html
 */

import TileLayer from 'ol/layer/Tile.js'
import Map from 'ol/Map.js'
import { get } from 'ol/proj.js'
import OSM from 'ol/source/OSM.js'
import View from 'ol/View.js'
import 'ol/ol.css'

/**
 * @description: 地图:简易初始化
 * @return {*}
 */
export function initMap() {
  const map = new Map({
    target: 'map',
    controls: [],
    view: new View({
      center: [0, 0],
      zoom: 1,
      extent: get('EPSG:3857').getExtent(),
    }),
    layers: [
      new TileLayer({
        source: new OSM(),
      }),
    ],
  })

  return map
}

实现绘制

在这里插入图片描述

代码参考自官方案例:https://openlayers.org/en/latest/examples/?q=draw

import { Draw } from 'ol/interaction.js'
import { createBox, createRegularPolygon } from 'ol/interaction/Draw.js'
import { Vector as VectorLayer } from 'ol/layer.js'
import { Vector as VectorSource } from 'ol/source.js'

/**
 * @description: 矢量编辑类
 * @function: init 初始化
 * @function: draw 绘制
 * @function: stopDraw 停止绘制
 * @return {*}
 */
export class VectorEditor {
  map = null // 地图实例
  _source = null // 数据源
  _vector = null // 图层
  _draw = null // 绘制交互

  constructor(map) {
    this.map = map // 引入地图实例
    this.init()
  }

  // 操作:初始化
  init() {
    this._source = new VectorSource()
    this._vector = new VectorLayer({
      source: this._source,
    })
    this.map.addLayer(this._vector)

    this.stopDraw() // 停止绘制
  }

  // 操作:绘制
  // Options: 'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'Circle', 'Square', 'Box'
  draw(type) {
    this.stopDraw() // 停止绘制

    let value = type // 绘制类型
    let geometryFunction = null

    switch (type) {
      case 'Square':
        value = 'Circle'
        geometryFunction = createRegularPolygon(4)
        break
      case 'Box':
        value = 'Circle'
        geometryFunction = createBox()
        break
    }

    this._draw = new Draw({
      source: this._source,
      type: value,
      geometryFunction, // 绘制回调
    })

    this.map.addInteraction(this._draw)
  }

  // 复位:停止绘制
  stopDraw() {
    this.map.removeInteraction(this._draw)
  }
}

使用方法:

let drawVector = new VectorEditor(map) // 初始化绘制实例

drawVector.draw('Polygon') // 开始绘制

折点编辑

在这里插入图片描述

参考官方案例:https://openlayers.org/en/latest/examples/snap.html

简单来讲就是引入 SelectModify ,直接对上面代码的基础上进行完善:

import { Draw, Modify, Select } from 'ol/interaction.js'
import { createBox, createRegularPolygon } from 'ol/interaction/Draw.js'
import { Vector as VectorLayer } from 'ol/layer.js'
import { Vector as VectorSource } from 'ol/source.js'

/**
 * @description: 矢量编辑类
 * @function: init 初始化
 * @function: draw 绘制
 * @function: watch 监听
 * @function: modify 修改
 * @function: stopDraw 停止绘制
 * @return {*}
 */
export class VectorEditor {
  map = null // 地图实例
  _source = null // 数据源
  _vector = null // 图层
  _draw = null // 绘制交互
  _select = null // 选择交互
  _modify = null // 修改交互

  constructor(map) {
    this.map = map // 引入地图实例
    this.init()
  }

  // 操作:初始化
  init() {
    this._source = new VectorSource()
    this._vector = new VectorLayer({
      source: this._source,
    })
    this.map.addLayer(this._vector)

    this._select = new Select() // 实例化选择交互
    this._modify = new Modify({ // 实例化修改交互
      features: this._select.getFeatures(),
    })

    this.map.addInteraction(this._modify)
    this.map.addInteraction(this._select)
    this.stopDraw()
    this.watch()
  }

  // 监听:各类事件
  watch() {
    // 事件:选择状态改变时清空已选择的要素
    this._select.on('change:active', () => {
      this._select.getFeatures().forEach((item) => {
        this._select.getFeatures().remove(item)
      })
    })
  }

  // 操作:绘制
  // Options: 'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'Circle', 'Square', 'Box'
  draw(type) {
    this.stopDraw() // 停止绘制

    let value = type // 绘制类型
    let geometryFunction = null

    switch (type) {
      case 'Square':
        value = 'Circle'
        geometryFunction = createRegularPolygon(4)
        break
      case 'Box':
        value = 'Circle'
        geometryFunction = createBox()
        break
    }

    this._draw = new Draw({
      source: this._source,
      type: value,
      geometryFunction, // 绘制回调
    })

    this.map.addInteraction(this._draw)
  }

  // 复位:停止绘制
  stopDraw() {
    this.map.removeInteraction(this._draw)
    this._modify.setActive(false)
    this._select.setActive(false)
  }

  // 操作:修改
  modify(flag = true) {
    this.stopDraw()

    this._select.setActive(flag)
    this._modify.setActive(flag)
  }
}

使用方法:

let drawVector = new VectorEditor(map) // 初始化绘制实例

drawVector.modify() // 编辑

拖拽移动

在这里插入图片描述

参考官方案例:https://openlayers.org/en/latest/examples/translate-features.html

这次是引入 Translate

/*
 * @Date: 2024-11-04 13:46:37
 * @LastEditors: ReBeX  cswwwx@gmail.com
 * @LastEditTime: 2024-11-04 15:56:23
 * @FilePath: \geojson-editor-ol\src\utils\vectorEditor.js
 * @Description: 矢量编辑相关功能
 */
 
import { Draw, Modify, Select, Translate } from 'ol/interaction.js'
import { createBox, createRegularPolygon } from 'ol/interaction/Draw.js'
import { Vector as VectorLayer } from 'ol/layer.js'
import { Vector as VectorSource } from 'ol/source.js'

/**
 * @description: 矢量编辑类
 * @function: init 初始化
 * @function: draw 绘制
 * @function: watch 监听
 * @function: modify 修改
 * @function: translate 移动
 * @function: stopDraw 停止绘制
 * @return {*}
 */
export class VectorEditor {
  map = null // 地图实例
  _source = null // 数据源
  _vector = null // 图层
  _draw = null // 绘制交互
  _select = null // 选择交互
  _modify = null // 修改交互
  _translate = null // 拖拽交互

  constructor(map) {
    this.map = map // 引入地图实例
    this.init()
  }

  // 操作:初始化
  init() {
    this._source = new VectorSource()
    this._vector = new VectorLayer({
      source: this._source,
    })
    this.map.addLayer(this._vector)

    this._select = new Select() // 实例化选择交互
    this._modify = new Modify({ // 实例化修改交互
      features: this._select.getFeatures(),
    })
    this._translate = new Translate({
      features: this._select.getFeatures(),
    })

    this.map.addInteraction(this._modify)
    this.map.addInteraction(this._select)
    this.map.addInteraction(this._translate)

    this.stopDraw()
    this.watch()
  }

  // 监听:各类事件
  watch() {
    // 事件:选择状态改变时清空已选择的要素
    this._select.on('change:active', () => {
      this._select.getFeatures().forEach((item) => {
        this._select.getFeatures().remove(item)
      })
    })
  }

  // 操作:绘制
  // Options: 'Point', 'LineString', 'Polygon', 'MultiPoint', 'MultiLineString', 'MultiPolygon', 'Circle', 'Square', 'Box'
  draw(type) {
    this.stopDraw() // 停止绘制

    let value = type // 绘制类型
    let geometryFunction = null

    switch (type) {
      case 'Square':
        value = 'Circle'
        geometryFunction = createRegularPolygon(4)
        break
      case 'Box':
        value = 'Circle'
        geometryFunction = createBox()
        break
    }

    this._draw = new Draw({
      source: this._source,
      type: value,
      geometryFunction, // 绘制回调
    })

    this.map.addInteraction(this._draw)
  }

  // 复位:停止绘制
  stopDraw() {
    this.map.removeInteraction(this._draw)
    this._modify.setActive(false)
    this._select.setActive(false)
    this._translate.setActive(false)
  }

  // 操作:修改
  modify(flag = true) {
    this.stopDraw()

    this._select.setActive(flag)
    this._modify.setActive(flag)
  }

  // 操作:拖拽
  translate(flag = true) {
    this.stopDraw()

    this._select.setActive(flag)
    this._translate.setActive(flag)
  }
}

指路

项目地址:cswwww/geojson-editor-ol

系列专栏:
【GeoJSON在线编辑平台】(0)项目启动与前言-CSDN博客


原文地址:https://blog.csdn.net/ReBeX/article/details/143480571

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!