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

前言

简单实现一下地图加载、要素绘制、折点编辑和拖拽移动。打算统一都写到一个类里面。

为了快速实现,直接去参考了官方案例。

创建地图

bash 复制代码
pnpm install ol

加载地图

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

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

js 复制代码
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)
  }
}

使用方法:

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

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

折点编辑

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

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

js 复制代码
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)
  }
}

使用方法:

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

drawVector.modify() // 编辑

拖拽移动

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

这次是引入 Translate

js 复制代码
/*
 * @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博客

相关推荐
peachSoda720 分钟前
随手记:鼠标触顶方法
前端·javascript·vue.js
疯狂的沙粒20 分钟前
Vue项目开发 formatData 函数有哪些常用的场景?
前端·javascript·vue.js
逆旅行天涯20 分钟前
【功能实现】bilibili顶部鼠标跟随效果怎么实现?
前端·javascript·vue
毛毛三由24 分钟前
【10分钟学习Vue自定义指令开发】鼠标放置提示指令
前端·javascript·vue.js
一秒美工助手25 分钟前
鼠标经过遮罩效果 详情页阿里巴巴国际站外贸跨境电商装修运营 详情页装修无线端装修手机装修设计代码证书滚动特效效果代码,自定义内容代码模板模块设计设置装修
前端·javascript·html·计算机外设
桑榆肖物1 小时前
将 .NET Aspire 添加到现有应用:前端 JavaScript 项目处理
前端·javascript·.net
Wh1teR0se3 小时前
[极客大挑战 2019]Secret File--详细解析
前端·web安全·网络安全
ZhaiMou4 小时前
HTML5拖拽API学习 托拽排序和可托拽课程表
前端·javascript·学习·html5
code_shenbing7 小时前
跨平台WPF框架Avalonia教程 三
前端·microsoft·ui·c#·wpf·跨平台·界面设计
NightCyberpunk8 小时前
JavaScript学习笔记
javascript·笔记·学习