前言
简单实现一下地图加载、要素绘制、折点编辑和拖拽移动。打算统一都写到一个类里面。
为了快速实现,直接去参考了官方案例。
创建地图
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
简单来讲就是引入 Select 和 Modify ,直接对上面代码的基础上进行完善:
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)
}
}