import {
Zondy,
SketchEditorNew,
defaultValue,
SketchStyle,
SketchDataType,
Polygon,
Log
} from '@mapgis/webclient-common'
/**
* 二维场景草图编辑类<br/>
* <br>[ES5引入方式]:<br/>
* const { SketchEditor2D } = Zondy <br/>
* [ES6引入方式]:<br/>
* import { SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* @classdesc 二维草图编辑类
* @class SketchEditor2D
* @extends SketchEditorNew
* @moduleEX SketchEditorModule
* @fires SketchEditorNew#草图绘制完成事件
* @fires SketchEditorNew#草图被选中事件
* @param {Object} options 构造参数
* @param {MapView} [options.mapView] 地图视图对象
* @param {GraphicsLayer} [options.layer] 草图图层管对象
* @param {SketchStyle} [options.sketchStyle] 草图符号
* @param {Object} [options.snappingOption] 草图捕获配置项
*
* @summary <h5>支持如下方法:</h5>
* <a href='#start'>[1、开始绘制草图]</a><br/>
* <a href='#stop'>[2、停止绘制]</a><br/>
* <a href='#remove'>[3、移除当前草图]</a><br/>
* <a href='#addVertex'>[4、向草线或面草图中插入新的顶点]</a><br/>
* <a href='#updateVertex'>[5、更新草图图形的某个顶点]</a><br/>
* <a href='#removeVertex'>[6、移除草图图形的某个顶点]</a><br/>
* <a href='#getSketchDataType'>[7、获取草图图形类型]</a><br/>
* <a href='#setSketchStyle'>[8、设置草图样式]</a><br/>
* <a href='#getSketchStyle'>[9、获取草图样式]</a><br/>
* <a href='#getGeometry'>[10、获取草图几何对象]</a><br/>
* <a href='#union'>[11、合并多个区几何]</a><br/>
* <a href='#split'>[12、分割草图对象或区几何对象]</a><br/>
* <a href='#undo'>[13、撤销当前编辑操作]</a><br/>
* <a href='#redo'>[14、恢复被撤销的草图]</a><br/>
*
* @example <caption><h7 id='MapView'>初始化一个二维场景草图编辑类</h7></caption>
* // [ES5引入方式]:
* const { SketchEditor2D } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { SketchStyle, SimpleMarkerSymbol, Color, SketchDataType} from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var simpleMarkerSymbol = new SimpleMarkerSymbol({
* color: new Color(24, 144, 255, 1),
* size: 10,
* });
* var sketchStyle = new SketchStyle({
* vertexStyle: simpleMarkerSymbol,
* lineStyle: undefined,
* fillStyle: undefined
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer(),
* vertexStyle: vertexStyle
* })
* SketchEditor2D.start(SketchDataType.POINT) // 绘制点
* SketchEditor2D.start(SketchDataType.POLYLINE) // 绘制线
* SketchEditor2D.start(SketchDataType.POLYGON) // 绘制区
* * */
class SketchEditor2D extends SketchEditorNew {
constructor(options) {
super(options)
options = defaultValue(options, {})
/**
* 地图视图
* @member {MapView|SecenView} SketchEditor.prototype._mapView
*/
this._mapView = options.mapView
/**
* 草图图层
* @member {GraphicsLayer} SketchEditor.prototype._layer
*/
this._layer = defaultValue(options.layer, undefined)
/**
* 草图符号
* @member {SketchStyle} SketchEditor.prototype._sketchStyle
*/
this._sketchStyle = defaultValue(options.sketchStyle, new SketchStyle())
/**
* 草图捕获配置项
* @member {Object} SketchEditor.prototype.snappingOption
*/
const snappingOption = {
showSelectBox: false,
showSelectVertex: false,
canEditFeature: false,
canEditVertex: false
}
this.snappingOption = defaultValue(options.snappingOption, snappingOption)
/**
* 草图量算配置项
* @member {Number} SketchEditor.prototype.measureOption
*/
this.measureOption = defaultValue(options.measureOption, undefined)
/**
* 草图绘制工具
* @member {Number} SketchEditor.prototype._drawTool
*/
this._drawTool = null
/**
* 草图回撤管理器
* @member {Number} SketchEditor.prototype._redoUndoManager
*/
this._redoUndoManager = undefined
/**
* 草图绘制类型
* @member {Number} SketchEditor.prototype._sketchDataType
*/
this._sketchDataType = null
}
/**
* 开始绘制草图<a id='start'></a>
* @param {SketchDataType} dataType 草图编辑类型
* @example <caption><h7 id='MapView'>初始化一个二维场景草图编辑类</h7></caption>
* // [ES5引入方式]:
* const { SketchEditor2D } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { SketchStyle, SimpleMarkerSymbol, Color, SketchDataType} from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var simpleMarkerSymbol = new SimpleMarkerSymbol({
* color: new Color(24, 144, 255, 1),
* size: 10,
* });
* var sketchStyle = new SketchStyle({
* vertexStyle: simpleMarkerSymbol,
* lineStyle: undefined,
* fillStyle: undefined
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer(),
* vertexStyle: vertexStyle
* })
* SketchEditor2D.start(SketchDataType.POINT) // 绘制点
* SketchEditor2D.start(SketchDataType.POLYLINE) // 绘制线
* SketchEditor2D.start(SketchDataType.POLYGON) // 绘制区
*/
start(dataType) {
super.start(dataType)
}
/**
* 停止绘制<a id='stop'></a>
*/
stop() {
super.stop()
}
/**
* 移除当前草图<a id='remove'></a>
*/
remove() {
super.remove()
}
/**
* 更新当前选中的草图
* @private
*/
update(data, featureId) {
super.updateFeature(data, featureId)
}
/**
* 向当前线或区草图中插入新的顶点<a id='addVertex'></a>
* @param {Point} point 新增/插入顶点
* @param {Number} index 新增/新增点的序号
*/
addVertex(point, index) {
super.addVertex(point, index)
}
/**
* 更新当前草图图形的某个顶点<a id='updateVertex'></a>
* @param {Point} point 新的顶点
* @param {Number} index 需更新的顶点的序号
*/
updateVertex(point, index) {
super.updateVertex(point, index)
}
/**
* 移除草图图形的某个顶点<a id='removeVertex'></a>
* @param {Number} index 需更新的顶点的序号
*/
removeVertex(index) {
super.removeVertex(index)
}
/**
* 获取草图图形类型<a id='getSketchDataType'></a>
* @private
*/
getSketchDataType() {
super.getSketchDataType()
}
/**
* 设置草图样式<a id='setSketchStyle'></a>
* @param {SketchStyle} sketchStyle
* @example
* // ES5引入方式
* const { SimpleFillSymbol, SimpleLineSymbol } = Zondy.Symbol
* const { Color, SketchStyle } = Zondy
* // ES6引入方式
* import { SimpleFillSymbol, SimpleLineSymbol, Color, SketchStyle } from "@mapgis/webclient-common"
* // 新建一个填充样式
* const fillStyle = new SimpleFillSymbol({
* color: new Color(0, 255, 255, 1),
* outline: new SimpleLineSymbol({
* color: new Color(255, 0, 0, 1),
* width: 2
* })
* })
* // 新建一个草图样式
* const sketchStyle = new SketchStyle({
* // 传入填充样式给区注记使用
* fillStyle: fillStyle,
* // 绘制线注记时显示分段长度
* isShowSegmentLength: true,
* // 绘制区注记时显示面积
* isShowArea: true
* })
* sketchEditor2D.setSketchStyle(sketchStyle)
*/
setSketchStyle() {
super.setSketchStyle()
}
/**
* 获取草图样式<a id='getSketchStyle'></a>
* @returns {SketchStyle}
*/
getSketchStyle() {
return super.getSketchStyle()
}
/**
* 获取草图几何对象<a id='getGeometry'></a>
* @returns {Geometry}
*/
getGeometry() {
return super.getGeometry()
}
/**
* 合并多个区几何<a id='union'></a>
* @param {Polygon} polygons 被合并的区几何对象
* @returns {Polygon} 合并后的几何对象
* @example <caption><h7 id='MapView'>二维草图几何合并</h7></caption>
* // [ES5引入方式]:
* const { MapView, SketchEditor2D, polygon } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { polygon } from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer()
* })
* const polygon = new Polygon({
* coordinates: [
* [
* [0, -60],
* [0, 60],
* [160, 60],
* [160, -60],
* [0, -60]
* ]
* ]
* })
* const polygon1 = new Polygon({
* coordinates: [
* [
* [10, -60],
* [10, 60],
* [170, 60],
* [170, -60],
* [10, -60]
* ]
* ]
* })
* const polygons = [polygon,polygon1]
* sketchEditor2D.union(polygons)
*/
union(polygons) {
return super.union(polygons)
}
/**
* 分割草图对象或区几何对象<a id='split'></a>
* @param {Polygon|SketchEditorNew} target 被分割的几何/草图对象
* @param {Polyline} splitPolyline 线几何对象
* @returns {Array<SketchEditorNew>} 合并后的几何对象
* @example <caption><h7 id='MapView'>二维草图几何分割</h7></caption>
* // [ES5引入方式]:
* const { MapView, SketchEditor2D, Polygon, LineString } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { Polygon, LineString } from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer()
* })
* const polygon = new Polygon({
* coordinates: [
* [
* [108, 29],
* [116, 29],
* [116, 33],
* [108, 33],
* [108, 29]
* ]
* ]
* })
* const polyline = new LineString({
* coordinates: [
* [100, 30],
* [120, 30]
* ]
* })
* const newSketchEditors = sketchEditor2D.split(polygon,polyline)
*/
split(target, splitPolyline) {
let polygon = null
const self = this
if (target instanceof Polygon) {
polygon = target
} else if (
target instanceof SketchEditorNew &&
target.drawTool._sketchDataType === SketchDataType.POLYGON
) {
polygon = target._sketchStage.entityGraphic
} else {
Log.error('传入对象不符合要求,请检查')
return
}
const splitPolygon = function (polygon, splitPolyline) {
const sketchEditors = []
const splitPolygons = self._sketchTopologyTool.splitPolygonByPolyline(
polygon,
splitPolyline
)
if (splitPolygons.length > 0) {
// 创建分割后的草图
splitPolygons.forEach((polygon) => {
// if (i != 0) return
const sketchEditor = new SketchEditor2D({
mapView: self._mapView,
layer: self._layer
})
sketchEditor.start(polygon)
})
}
return sketchEditors
}
return splitPolygon(polygon, splitPolyline)
}
/**
* 撤销当前编辑操作<a id='undo'></a>
* @returns {Geometry}
* @example <caption><h7 id='MapView'>二维草图几何分割</h7></caption>
* // [ES5引入方式]:
* const { MapView, SketchEditor2D, Polygon, LineString, SketchDataType } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { Polygon, LineString, SketchDataType } from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer()
* })
* sketchEditor2D.start(SketchDataType.POLYGON)
* console.log("是否可以进行撤销操作:" + this.sketchEditor2D.canUndo())
* const geometry = this.sketchEditor2D.undo()
* console.log("恢复后的几何对象" + geometry)
*/
undo() {
return super.undo()
}
/**
* 恢复被撤销的草图<a id='redo'></a>
* @returns {Geometry}
* @example <caption><h7 id='MapView'>二维草图几何分割</h7></caption>
* // [ES5引入方式]:
* const { SketchEditor2D } = Zondy
* [ES6引入方式]:
* import { MapView, SketchEditor2D } from "@mapgis/webclient-leaflet-plugin" <br/>
* import { Polygon, LineString } from "@mapgis/webclient-common" <br/>
* var map = new Map()
* var mapView = new MapView({
* viewId: "mapgis-2d-viewer",
* map: this.map,
* })
* var sketchEditor2D = new SketchEditor2D({
* mapView: this.mapView,
* layer: new GraphicsLayer()
* })
* sketchEditor2D.start(SketchDataType.POLYGON)
* console.log("是否可以进行恢复操作:" + this.sketchEditor2D.canRedo())
* const geometry = this.sketchEditor2D.redo()
* console.log("恢复后的几何对象" + geometry)
*/
redo() {
return super.redo()
}
/**
* 草图是否可执行撤销操作<a id='canUndo'></a>
* @returns {Boolean}
*/
canUndo() {
return super.canUndo()
}
/**
* 草图是否可执行恢复操作<a id='canRedo'></a>
* @returns {Boolean}
*/
canRedo() {
return super.canRedo()
}
/**
* 二维leaflet初始化监听图层加载完成事件
* @private
*/
_initLayerEvent() {
const self = this
this._layer.on('layerview-created', function (event) {
event.layerView.innerLayer.on('layeradd', (event) => {
if (self._drawTool && self._drawTool._hitTestDrawToolStack) {
let existIndex = -1
self._drawTool._hitTestDrawToolStack.forEach((drawTool, index) => {
if (
event.layer.__feature__id ===
drawTool._sketchStage.entityGraphic.id
) {
existIndex = index
}
})
if (existIndex > -1) {
self._drawTool._hitTestDrawToolStack[existIndex]._hitTestEvent()
self._drawTool._hitTestDrawToolStack.splice(existIndex, 1)
}
}
})
})
}
/**
* 二维leaflet草图拾取事件
* @private
*/
_hitTestEvent() {
const self = this
let handler = null
this._disableMapDrag = () => {
self._mapView._innerView.dragging.disable()
}
this._enableMapDrag = () => {
self._mapView._innerView.dragging.enable()
}
if (this._hitTestHandler) {
handler = this._hitTestHandler.bind(this)
}
this._hitTestEventHandlers = [handler]
if (this.snappingOption) {
const mode = this.snappingOption._hitTestMode
if (this._layer) {
for (const i in this._mapView._innerView._layers) {
const iLayer = this._mapView._innerView._layers[i]
if (iLayer.__feature__id) {
if (this._sketchStage.entityGraphic.id === iLayer.__feature__id) {
const curFeature = this._sketchStage.entityGraphic
const callbackFun = function (event) {
self._hitTestILayer = iLayer
event.lon = event.latlng.lng
event.lat = event.latlng.lat
self._hitTestFeature(curFeature, event)
// 发送草图被选中事件
self.fire('selected', { isSelected: true }, self)
}
if (mode === 0) {
iLayer.on('click', (event) => {
callbackFun(event)
})
} else {
iLayer.on('mousedown', (event) => {
// mouseDown拖动点图形时,地图拖拽事件会触发
self._disableMapDrag()
callbackFun(event)
})
}
}
}
}
}
}
}
}
Zondy.SketchEditor2D = SketchEditor2D
export default SketchEditor2D