302 lines
8.7 KiB
JavaScript
302 lines
8.7 KiB
JavaScript
/* Copyright (c) 2019 Jean-Marc VIGLINO,
|
|
released under the CeCILL-B license (French BSD license)
|
|
(http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt).
|
|
*/
|
|
import ol_layer_Vector from 'ol/layer/Vector.js'
|
|
import ol_style_Style from 'ol/style/Style.js'
|
|
import ol_style_RegularShape from 'ol/style/RegularShape.js'
|
|
import ol_style_Stroke from 'ol/style/Stroke.js'
|
|
import ol_source_Vector from 'ol/source/Vector.js'
|
|
import ol_Feature from 'ol/Feature.js'
|
|
import ol_geom_Point from 'ol/geom/Point.js'
|
|
import ol_geom_LineString from 'ol/geom/LineString.js'
|
|
import ol_geom_Polygon from 'ol/geom/Polygon.js'
|
|
import ol_geom_Circle from 'ol/geom/Circle.js'
|
|
|
|
import ol_style_Style_defaultStyle from '../style/defaultStyle.js'
|
|
import {ol_coordinate_dist2d} from "../geom/GeomUtils.js";
|
|
|
|
/** A sketch layer used as overlay to handle drawing sketch (helper for drawing tools)
|
|
* @constructor
|
|
* @extends {ol/layer/Vector}
|
|
* @fires drawstart
|
|
* @fires drawend
|
|
* @fires drawabort
|
|
* @param {*} options
|
|
* @param {string} options.type Geometry type, default LineString
|
|
* @param {ol_style_Style|Array<ol_style_Style>} options.style Drawing style
|
|
* @param {ol_style_Style|Array<ol_style_Style>} options.sketchStyle Sketch style
|
|
*/
|
|
var ol_layer_SketchOverlay = class ollayerSketchOverlay extends ol_layer_Vector {
|
|
constructor(options) {
|
|
options = options || {}
|
|
|
|
var style = options.style || ol_style_Style_defaultStyle(true)
|
|
var sketchStyle = options.sketchStyle
|
|
if (!sketchStyle) {
|
|
sketchStyle = ol_style_Style_defaultStyle()
|
|
sketchStyle = [
|
|
new ol_style_Style({
|
|
image: new ol_style_RegularShape({
|
|
points: 4,
|
|
radius: 10,
|
|
radius2: 0,
|
|
stroke: new ol_style_Stroke({
|
|
color: [255, 255, 255, .5],
|
|
width: 3
|
|
})
|
|
})
|
|
}),
|
|
sketchStyle[0].clone()
|
|
]
|
|
sketchStyle[1].setImage(new ol_style_RegularShape({
|
|
points: 4,
|
|
radius: 10,
|
|
radius2: 0,
|
|
stroke: new ol_style_Stroke({
|
|
color: [0, 153, 255, 1],
|
|
width: 1.25
|
|
})
|
|
}))
|
|
}
|
|
|
|
super({
|
|
name: 'sketch',
|
|
source: new ol_source_Vector({ useSpatialIndex: false }),
|
|
style: function (f) {
|
|
return (f.get('sketch') ? sketchStyle : style)
|
|
},
|
|
updateWhileAnimating: true,
|
|
updateWhileInteracting: true
|
|
})
|
|
|
|
this._geom = []
|
|
|
|
// Sketch features
|
|
this.getSource().addFeatures([
|
|
new ol_Feature({
|
|
sketch: true,
|
|
geometry: new ol_geom_Point([])
|
|
}),
|
|
new ol_Feature({
|
|
sketch: true,
|
|
geometry: new ol_geom_LineString([])
|
|
}),
|
|
new ol_Feature(),
|
|
new ol_Feature(new ol_geom_Point([]))
|
|
])
|
|
|
|
this.setGeometryType(options.type)
|
|
}
|
|
/** Set geometry type
|
|
* @param {string} type Geometry type
|
|
* @return {string} the current type
|
|
*/
|
|
setGeometryType(type) {
|
|
var t = /^Point$|^LineString$|^Polygon$|^Circle$/.test(type) ? type : 'LineString'
|
|
if (t !== this._type) {
|
|
this.abortDrawing()
|
|
this._type = t
|
|
}
|
|
return this._type
|
|
}
|
|
/** Get geometry type
|
|
* @return {string} Geometry type
|
|
*/
|
|
getGeometryType() {
|
|
return this._type
|
|
}
|
|
/** Add a new Point to the sketch
|
|
* @param {ol.coordinate} coord
|
|
* @return {boolean} true if point has been added, false if same coord
|
|
*/
|
|
addPoint(coord) {
|
|
if (this._lastCoord !== this._position) {
|
|
if (!this._geom.length) {
|
|
this.startDrawing()
|
|
}
|
|
this._geom.push(coord)
|
|
this._lastCoord = coord
|
|
this._position = coord
|
|
this.drawSketch()
|
|
if (this.getGeometryType() === 'Point') {
|
|
this.finishDrawing()
|
|
}
|
|
if (this.getGeometryType() === 'Circle' && this._geom.length >= 2) {
|
|
this.finishDrawing()
|
|
}
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
/** Remove the last Point from the sketch
|
|
*/
|
|
removeLastPoint() {
|
|
this._geom.pop()
|
|
this._lastCoord = this._geom[this._geom.length - 1]
|
|
this.drawSketch()
|
|
}
|
|
/** Strat a new drawing
|
|
* @param {*} options
|
|
* @param {string} type Geometry type, default the current type
|
|
* @param {Array<ol.coordinate>} coordinates a list of coordinates to extend
|
|
* @param {ol.Feature} feature a feature to extend (LineString or Polygon only)
|
|
* @param {boolean} atstart extent coordinates or feature at start, default false (extend at end)
|
|
*/
|
|
startDrawing(options) {
|
|
options = options || {}
|
|
this._geom = []
|
|
if (options.type)
|
|
this.setGeometryType(options.type)
|
|
this.drawSketch()
|
|
if (!this._drawing) {
|
|
this.dispatchEvent({
|
|
type: 'drawstart',
|
|
feature: this.getFeature()
|
|
})
|
|
}
|
|
this._drawing = true
|
|
}
|
|
/** Finish drawing
|
|
* @return {ol.Feature} the drawed feature
|
|
*/
|
|
finishDrawing(valid) {
|
|
var f = this.getSource().getFeatures()[2].clone()
|
|
var isvalid = !!f
|
|
switch (this.getGeometryType()) {
|
|
case 'Circle':
|
|
case 'LineString': {
|
|
isvalid = this._geom.length > 1
|
|
break
|
|
}
|
|
case 'Polygon': {
|
|
isvalid = this._geom.length > 2
|
|
break
|
|
}
|
|
}
|
|
if (valid && !isvalid)
|
|
return false
|
|
this._geom = []
|
|
this._lastCoord = null
|
|
this.drawSketch()
|
|
if (this._drawing) {
|
|
this.dispatchEvent({
|
|
type: 'drawend',
|
|
valid: isvalid,
|
|
feature: f
|
|
})
|
|
}
|
|
this._drawing = false
|
|
return f
|
|
}
|
|
/** Abort drawing
|
|
*/
|
|
abortDrawing() {
|
|
if (this._drawing) {
|
|
this.dispatchEvent({
|
|
type: 'drawabort',
|
|
feature: this.getFeature()
|
|
})
|
|
}
|
|
this._drawing = false
|
|
this._geom = []
|
|
this._lastCoord = null
|
|
this.drawSketch()
|
|
}
|
|
/** Set current position
|
|
* @param {ol.coordinate} coord
|
|
*/
|
|
setPosition(coord) {
|
|
this._position = coord
|
|
this.drawLink()
|
|
}
|
|
/** Get current position
|
|
* @return {ol.coordinate}
|
|
*/
|
|
getPosition() {
|
|
return this._position
|
|
}
|
|
/** Draw/refresh link
|
|
*/
|
|
drawLink() {
|
|
var features = this.getSource().getFeatures()
|
|
if (this._position) {
|
|
if (this._lastCoord && this._lastCoord === this._position) {
|
|
features[0].getGeometry().setCoordinates([])
|
|
} else {
|
|
features[0].getGeometry().setCoordinates(this._position)
|
|
}
|
|
if (this._geom.length) {
|
|
if (this.getGeometryType() === 'Circle') {
|
|
features[1].setGeometry(new ol_geom_Circle(this._geom[0], ol_coordinate_dist2d(this._geom[0], this._position)))
|
|
} else if (this.getGeometryType() === 'Polygon') {
|
|
features[1].setGeometry(new ol_geom_LineString([this._lastCoord, this._position, this._geom[0]]))
|
|
} else {
|
|
features[1].setGeometry(new ol_geom_LineString([this._lastCoord, this._position]))
|
|
}
|
|
} else {
|
|
features[1].setGeometry(new ol_geom_LineString([]))
|
|
}
|
|
} else {
|
|
features[0].getGeometry().setCoordinates([])
|
|
features[1].setGeometry(new ol_geom_LineString([]))
|
|
}
|
|
}
|
|
/** Get current feature
|
|
*/
|
|
getFeature() {
|
|
return this.getSource().getFeatures()[2]
|
|
}
|
|
/** Draw/refresh sketch
|
|
*/
|
|
drawSketch() {
|
|
this.drawLink()
|
|
var features = this.getSource().getFeatures()
|
|
if (!this._geom.length) {
|
|
features[2].setGeometry(null)
|
|
features[3].setGeometry(new ol_geom_Point([]))
|
|
} else {
|
|
if (!this._lastCoord)
|
|
this._lastCoord = this._geom[this._geom.length - 1]
|
|
features[3].getGeometry().setCoordinates(this._lastCoord)
|
|
switch (this._type) {
|
|
case 'Point': {
|
|
features[2].setGeometry(new ol_geom_Point(this._lastCoord))
|
|
break
|
|
}
|
|
case 'Circle': {
|
|
if (!features[2].getGeometry()) {
|
|
features[2].setGeometry(new ol_geom_Circle(this._geom[0], ol_coordinate_dist2d(this._geom[0], this._geom[this._geom.length - 1])))
|
|
} else {
|
|
features[2].getGeometry().setRadius(ol_coordinate_dist2d(this._geom[0], this._geom[this._geom.length - 1]))
|
|
}
|
|
break
|
|
}
|
|
case 'LineString': {
|
|
if (!features[2].getGeometry()) {
|
|
features[2].setGeometry(new ol_geom_LineString(this._geom))
|
|
} else {
|
|
features[2].getGeometry().setCoordinates(this._geom)
|
|
}
|
|
break
|
|
}
|
|
case 'Polygon': {
|
|
this._geom.push(this._geom[0])
|
|
if (!features[2].getGeometry()) {
|
|
features[2].setGeometry(new ol_geom_Polygon([this._geom]))
|
|
} else {
|
|
features[2].getGeometry().setCoordinates([this._geom])
|
|
}
|
|
this._geom.pop()
|
|
break
|
|
}
|
|
default: {
|
|
console.error('[ol/layer/SketchOverlay~drawSketch] geometry type not supported (' + this._type + ')')
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export default ol_layer_SketchOverlay |