【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博客

相关推荐
摇头的金丝猴16 分钟前
uniapp vue3 使用echarts-gl 绘画3d图表
前端·uni-app·echarts
清清ww28 分钟前
【TS】九天学会TS语法---计划篇
前端·typescript
南棱笑笑生1 小时前
20241105编译Rockchip原厂的Android13并给荣品PRO-RK3566开发板刷机
java·开发语言·前端
dy17171 小时前
el-date-picker日期选择器动态设置日期
前端·vue.js·elementui
浏览器爱好者1 小时前
Chrome与火狐哪个浏览器的性能表现更好
前端·chrome
Topstip1 小时前
在 Google Chrome 上查找并安装 SearchGPT 扩展
前端·人工智能·chrome·gpt·ai·chatgpt
gqkmiss1 小时前
Chrome 130 版本开发者工具(DevTools)更新内容
前端·chrome·chrome devtools·开发者工具·chrome 130
codeGoogle2 小时前
计算机书籍打包
前端·后端·编程语言
小远yyds2 小时前
跨平台使用高德地图服务
前端·javascript·vue.js·小程序·uni-app
weixin_516875652 小时前
使用 axios 拦截器实现请求和响应的统一处理(附常见面试题)
前端·javascript·vue.js