474 lines
17 KiB
JavaScript
474 lines
17 KiB
JavaScript
import {shiftKeyOnly as ol_events_condition_shiftKeyOnly} from 'ol/events/condition.js'
|
|
import {click as ol_events_condition_click} from 'ol/events/condition.js'
|
|
import ol_interaction_Draw from 'ol/interaction/Draw.js'
|
|
import ol_geom_LineString from 'ol/geom/LineString.js'
|
|
import ol_geom_Polygon from 'ol/geom/Polygon.js'
|
|
import ol_interaction_Select from 'ol/interaction/Select.js'
|
|
|
|
import ol_control_Bar from './Bar.js'
|
|
import ol_control_Button from './Button.js'
|
|
import ol_control_Toggle from './Toggle.js'
|
|
import ol_control_TextButton from './TextButton.js'
|
|
import ol_interaction_Delete from '../interaction/Delete.js'
|
|
import ol_ext_element from '../util/element.js'
|
|
import ol_interaction_Offset from '../interaction/Offset.js'
|
|
import ol_interaction_Split from '../interaction/Split.js'
|
|
import ol_interaction_Transform from '../interaction/Transform.js'
|
|
import ol_interaction_ModifyFeature from '../interaction/ModifyFeature.js'
|
|
import ol_interaction_DrawRegular from '../interaction/DrawRegular.js'
|
|
import ol_interaction_DrawHole from '../interaction/DrawHole.js'
|
|
|
|
/** Control bar for editing in a layer
|
|
* @constructor
|
|
* @extends {ol_control_Bar}
|
|
* @fires info
|
|
* @param {Object=} options Control options.
|
|
* @param {String} options.className class of the control
|
|
* @param {String} options.target Specify a target if you want the control to be rendered outside of the map's viewport.
|
|
* @param {boolean} options.edition false to remove the edition tools, default true
|
|
* @param {Object} options.interactions List of interactions to add to the bar
|
|
* ie. Select, Delete, Info, DrawPoint, DrawLine, DrawPolygon
|
|
* Each interaction can be an interaction or true (to get the default one) or false to remove it from bar
|
|
* @param {ol.source.Vector} options.source Source for the drawn features.
|
|
*/
|
|
var ol_control_EditBar = class olcontrolEditBar extends ol_control_Bar {
|
|
constructor(options) {
|
|
options = options || {}
|
|
options.interactions = options.interactions || {}
|
|
|
|
// New bar
|
|
super({
|
|
className: (options.className ? options.className + ' ' : '') + 'ol-editbar',
|
|
toggleOne: true,
|
|
target: options.target
|
|
})
|
|
|
|
this._source = options.source
|
|
// Add buttons / interaction
|
|
this._interactions = {}
|
|
this._setSelectInteraction(options)
|
|
if (options.edition !== false)
|
|
this._setEditInteraction(options)
|
|
this._setModifyInteraction(options)
|
|
}
|
|
/**
|
|
* Set the map instance the control is associated with
|
|
* and add its controls associated to this map.
|
|
* @param {_ol_Map_} map The map instance.
|
|
*/
|
|
setMap(map) {
|
|
if (this.getMap()) {
|
|
if (this._interactions.Delete)
|
|
this.getMap().removeInteraction(this._interactions.Delete)
|
|
if (this._interactions.ModifySelect)
|
|
this.getMap().removeInteraction(this._interactions.ModifySelect)
|
|
}
|
|
super.setMap(map)
|
|
|
|
if (this.getMap()) {
|
|
if (this._interactions.Delete)
|
|
this.getMap().addInteraction(this._interactions.Delete)
|
|
if (this._interactions.ModifySelect)
|
|
this.getMap().addInteraction(this._interactions.ModifySelect)
|
|
}
|
|
}
|
|
/** Get an interaction associated with the bar
|
|
* @param {string} name
|
|
*/
|
|
getInteraction(name) {
|
|
return this._interactions[name]
|
|
}
|
|
/** Get the option title */
|
|
_getTitle(option) {
|
|
if (option) {
|
|
if (option.get)
|
|
return option.get('title')
|
|
else if (typeof (option) === 'string')
|
|
return option
|
|
else
|
|
return option.title
|
|
}
|
|
}
|
|
/** Add selection tool:
|
|
* 1. a toggle control with a select interaction
|
|
* 2. an option bar to delete / get information on the selected feature
|
|
* @private
|
|
*/
|
|
_setSelectInteraction(options) {
|
|
var self = this
|
|
|
|
// Sub bar
|
|
var sbar = new ol_control_Bar()
|
|
var selectCtrl
|
|
|
|
// Delete button
|
|
if (options.interactions.Delete !== false) {
|
|
if (options.interactions.Delete instanceof ol_interaction_Delete) {
|
|
this._interactions.Delete = options.interactions.Delete
|
|
} else {
|
|
this._interactions.Delete = new ol_interaction_Delete()
|
|
}
|
|
var del = this._interactions.Delete
|
|
del.setActive(false)
|
|
if (this.getMap())
|
|
this.getMap().addInteraction(del)
|
|
sbar.addControl(new ol_control_Button({
|
|
className: 'ol-delete',
|
|
title: this._getTitle(options.interactions.Delete) || "Delete",
|
|
name: 'Delete',
|
|
handleClick: function (e) {
|
|
// Delete selection
|
|
del.delete(selectCtrl.getInteraction().getFeatures())
|
|
var evt = {
|
|
type: 'select',
|
|
selected: [],
|
|
deselected: selectCtrl.getInteraction().getFeatures().getArray().slice(),
|
|
mapBrowserEvent: e.mapBrowserEvent
|
|
}
|
|
selectCtrl.getInteraction().getFeatures().clear()
|
|
selectCtrl.getInteraction().dispatchEvent(evt)
|
|
}
|
|
}))
|
|
}
|
|
|
|
// Info button
|
|
if (options.interactions.Info !== false) {
|
|
sbar.addControl(new ol_control_Button({
|
|
className: 'ol-info',
|
|
name: 'Info',
|
|
title: this._getTitle(options.interactions.Info) || "Show informations",
|
|
handleClick: function () {
|
|
self.dispatchEvent({
|
|
type: 'info',
|
|
features: selectCtrl.getInteraction().getFeatures()
|
|
})
|
|
}
|
|
}))
|
|
}
|
|
|
|
// Select button
|
|
if (options.interactions.Select !== false) {
|
|
if (options.interactions.Select instanceof ol_interaction_Select) {
|
|
this._interactions.Select = options.interactions.Select
|
|
} else {
|
|
this._interactions.Select = new ol_interaction_Select({
|
|
condition: ol_events_condition_click
|
|
})
|
|
}
|
|
var sel = this._interactions.Select
|
|
selectCtrl = new ol_control_Toggle({
|
|
className: 'ol-selection',
|
|
name: 'Select',
|
|
title: this._getTitle(options.interactions.Select) || "Select",
|
|
interaction: sel,
|
|
bar: sbar.getControls().length ? sbar : undefined,
|
|
autoActivate: true,
|
|
active: true
|
|
})
|
|
|
|
this.addControl(selectCtrl)
|
|
sel.on('change:active', function () {
|
|
if (!sel.getActive()) {
|
|
sel.getFeatures().clear()
|
|
}
|
|
}.bind(this))
|
|
}
|
|
}
|
|
/** Add editing tools
|
|
* @private
|
|
*/
|
|
_setEditInteraction(options) {
|
|
if (options.interactions.DrawPoint !== false) {
|
|
if (options.interactions.DrawPoint instanceof ol_interaction_Draw) {
|
|
this._interactions.DrawPoint = options.interactions.DrawPoint
|
|
} else {
|
|
this._interactions.DrawPoint = new ol_interaction_Draw({
|
|
type: 'Point',
|
|
source: this._source
|
|
})
|
|
}
|
|
var pedit = new ol_control_Toggle({
|
|
className: 'ol-drawpoint',
|
|
name: 'DrawPoint',
|
|
title: this._getTitle(options.interactions.DrawPoint) || 'Point',
|
|
interaction: this._interactions.DrawPoint
|
|
})
|
|
this.addControl(pedit)
|
|
}
|
|
|
|
if (options.interactions.DrawLine !== false) {
|
|
if (options.interactions.DrawLine instanceof ol_interaction_Draw) {
|
|
this._interactions.DrawLine = options.interactions.DrawLine
|
|
} else {
|
|
this._interactions.DrawLine = new ol_interaction_Draw({
|
|
type: 'LineString',
|
|
source: this._source,
|
|
// Count inserted points
|
|
geometryFunction: function (coordinates, geometry) {
|
|
if (geometry)
|
|
geometry.setCoordinates(coordinates)
|
|
else
|
|
geometry = new ol_geom_LineString(coordinates)
|
|
this.nbpts = geometry.getCoordinates().length
|
|
return geometry
|
|
}
|
|
})
|
|
}
|
|
var ledit = new ol_control_Toggle({
|
|
className: 'ol-drawline',
|
|
title: this._getTitle(options.interactions.DrawLine) || 'LineString',
|
|
name: 'DrawLine',
|
|
interaction: this._interactions.DrawLine,
|
|
// Options bar associated with the control
|
|
bar: new ol_control_Bar({
|
|
controls: [
|
|
new ol_control_TextButton({
|
|
html: this._getTitle(options.interactions.UndoDraw) || 'undo',
|
|
title: this._getTitle(options.interactions.UndoDraw) || "delete last point",
|
|
handleClick: function () {
|
|
if (ledit.getInteraction().nbpts > 1)
|
|
ledit.getInteraction().removeLastPoint()
|
|
}
|
|
}),
|
|
new ol_control_TextButton({
|
|
html: this._getTitle(options.interactions.FinishDraw) || 'finish',
|
|
title: this._getTitle(options.interactions.FinishDraw) || "finish",
|
|
handleClick: function () {
|
|
// Prevent null objects on finishDrawing
|
|
if (ledit.getInteraction().nbpts > 2)
|
|
ledit.getInteraction().finishDrawing()
|
|
}
|
|
})
|
|
]
|
|
})
|
|
})
|
|
|
|
this.addControl(ledit)
|
|
}
|
|
|
|
if (options.interactions.DrawPolygon !== false) {
|
|
if (options.interactions.DrawPolygon instanceof ol_interaction_Draw) {
|
|
this._interactions.DrawPolygon = options.interactions.DrawPolygon
|
|
} else {
|
|
this._interactions.DrawPolygon = new ol_interaction_Draw({
|
|
type: 'Polygon',
|
|
source: this._source,
|
|
// Count inserted points
|
|
geometryFunction: function (coordinates, geometry) {
|
|
this.nbpts = coordinates[0].length
|
|
if (geometry)
|
|
geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])])
|
|
else
|
|
geometry = new ol_geom_Polygon(coordinates)
|
|
return geometry
|
|
}
|
|
})
|
|
}
|
|
this._setDrawPolygon(
|
|
'ol-drawpolygon',
|
|
this._interactions.DrawPolygon,
|
|
this._getTitle(options.interactions.DrawPolygon) || 'Polygon',
|
|
'DrawPolygon',
|
|
options
|
|
)
|
|
}
|
|
|
|
// Draw hole
|
|
if (options.interactions.DrawHole !== false) {
|
|
if (options.interactions.DrawHole instanceof ol_interaction_DrawHole) {
|
|
this._interactions.DrawHole = options.interactions.DrawHole
|
|
} else {
|
|
this._interactions.DrawHole = new ol_interaction_DrawHole()
|
|
}
|
|
this._setDrawPolygon(
|
|
'ol-drawhole',
|
|
this._interactions.DrawHole,
|
|
this._getTitle(options.interactions.DrawHole) || 'Hole',
|
|
'DrawHole',
|
|
options
|
|
)
|
|
}
|
|
|
|
// Draw regular
|
|
if (options.interactions.DrawRegular !== false) {
|
|
var label = { pts: 'pts', circle: 'circle' }
|
|
if (options.interactions.DrawRegular instanceof ol_interaction_DrawRegular) {
|
|
this._interactions.DrawRegular = options.interactions.DrawRegular
|
|
label.pts = this._interactions.DrawRegular.get('ptsLabel') || label.pts
|
|
label.circle = this._interactions.DrawRegular.get('circleLabel') || label.circle
|
|
} else {
|
|
this._interactions.DrawRegular = new ol_interaction_DrawRegular({
|
|
source: this._source,
|
|
sides: 4
|
|
})
|
|
if (options.interactions.DrawRegular) {
|
|
label.pts = options.interactions.DrawRegular.ptsLabel || label.pts
|
|
label.circle = options.interactions.DrawRegular.circleLabel || label.circle
|
|
}
|
|
}
|
|
var regular = this._interactions.DrawRegular
|
|
|
|
var div = document.createElement('div')
|
|
|
|
var down = ol_ext_element.create('DIV', { parent: div })
|
|
ol_ext_element.addListener(down, ['click', 'touchstart'], function () {
|
|
var sides = regular.getSides() - 1
|
|
if (sides < 2)
|
|
sides = 2
|
|
regular.setSides(sides)
|
|
text.textContent = sides > 2 ? sides + ' ' + label.pts : label.circle
|
|
}.bind(this))
|
|
|
|
var text = ol_ext_element.create('TEXT', { html: '4 ' + label.pts, parent: div })
|
|
|
|
var up = ol_ext_element.create('DIV', { parent: div })
|
|
ol_ext_element.addListener(up, ['click', 'touchstart'], function () {
|
|
var sides = regular.getSides() + 1
|
|
if (sides < 3)
|
|
sides = 3
|
|
regular.setSides(sides)
|
|
text.textContent = sides + ' ' + label.pts
|
|
}.bind(this))
|
|
|
|
var ctrl = new ol_control_Toggle({
|
|
className: 'ol-drawregular',
|
|
title: this._getTitle(options.interactions.DrawRegular) || 'Regular',
|
|
name: 'DrawRegular',
|
|
interaction: this._interactions.DrawRegular,
|
|
// Options bar associated with the control
|
|
bar: new ol_control_Bar({
|
|
controls: [
|
|
new ol_control_TextButton({
|
|
html: div
|
|
})
|
|
]
|
|
})
|
|
})
|
|
this.addControl(ctrl)
|
|
}
|
|
|
|
}
|
|
/**
|
|
* @private
|
|
*/
|
|
_setDrawPolygon(className, interaction, title, name, options) {
|
|
var fedit = new ol_control_Toggle({
|
|
className: className,
|
|
name: name,
|
|
title: title,
|
|
interaction: interaction,
|
|
// Options bar associated with the control
|
|
bar: new ol_control_Bar({
|
|
controls: [
|
|
new ol_control_TextButton({
|
|
html: this._getTitle(options.interactions.UndoDraw) || 'undo',
|
|
title: this._getTitle(options.interactions.UndoDraw) || 'undo last point',
|
|
handleClick: function () {
|
|
if (fedit.getInteraction().nbpts > 1)
|
|
fedit.getInteraction().removeLastPoint()
|
|
}
|
|
}),
|
|
new ol_control_TextButton({
|
|
html: this._getTitle(options.interactions.FinishDraw) || 'finish',
|
|
title: this._getTitle(options.interactions.FinishDraw) || 'finish',
|
|
handleClick: function () {
|
|
// Prevent null objects on finishDrawing
|
|
if (fedit.getInteraction().nbpts > 3)
|
|
fedit.getInteraction().finishDrawing()
|
|
}
|
|
})
|
|
]
|
|
})
|
|
})
|
|
this.addControl(fedit)
|
|
return fedit
|
|
}
|
|
/** Add modify tools
|
|
* @private
|
|
*/
|
|
_setModifyInteraction(options) {
|
|
// Modify on selected features
|
|
if (options.interactions.ModifySelect !== false && options.interactions.Select !== false) {
|
|
if (options.interactions.ModifySelect instanceof ol_interaction_ModifyFeature) {
|
|
this._interactions.ModifySelect = options.interactions.ModifySelect
|
|
} else {
|
|
this._interactions.ModifySelect = new ol_interaction_ModifyFeature({
|
|
features: this.getInteraction('Select').getFeatures()
|
|
})
|
|
}
|
|
if (this.getMap())
|
|
this.getMap().addInteraction(this._interactions.ModifySelect)
|
|
// Activate with select
|
|
this._interactions.ModifySelect.setActive(this._interactions.Select.getActive())
|
|
this._interactions.Select.on('change:active', function () {
|
|
this._interactions.ModifySelect.setActive(this._interactions.Select.getActive())
|
|
}.bind(this))
|
|
}
|
|
|
|
if (options.interactions.Transform !== false) {
|
|
if (options.interactions.Transform instanceof ol_interaction_Transform) {
|
|
this._interactions.Transform = options.interactions.Transform
|
|
} else {
|
|
this._interactions.Transform = new ol_interaction_Transform({
|
|
select: this._interactions.Select,
|
|
addCondition: ol_events_condition_shiftKeyOnly
|
|
})
|
|
// Remove selection if not active
|
|
if (this._interactions.Select) {
|
|
this._interactions.Transform.on('change:active', function() {
|
|
if (!this._interactions.Select.getActive()) {
|
|
this._interactions.Select.getFeatures().clear();
|
|
}
|
|
}.bind(this))
|
|
}
|
|
}
|
|
var transform = new ol_control_Toggle({
|
|
html: '<i></i>',
|
|
className: 'ol-transform',
|
|
title: this._getTitle(options.interactions.Transform) || 'Transform',
|
|
name: 'Transform',
|
|
interaction: this._interactions.Transform
|
|
})
|
|
this.addControl(transform)
|
|
}
|
|
|
|
if (options.interactions.Split !== false) {
|
|
if (options.interactions.Split instanceof ol_interaction_Split) {
|
|
this._interactions.Split = options.interactions.Split
|
|
} else {
|
|
this._interactions.Split = new ol_interaction_Split({
|
|
sources: this._source
|
|
})
|
|
}
|
|
var split = new ol_control_Toggle({
|
|
className: 'ol-split',
|
|
title: this._getTitle(options.interactions.Split) || 'Split',
|
|
name: 'Split',
|
|
interaction: this._interactions.Split
|
|
})
|
|
this.addControl(split)
|
|
}
|
|
|
|
if (options.interactions.Offset !== false) {
|
|
if (options.interactions.Offset instanceof ol_interaction_Offset) {
|
|
this._interactions.Offset = options.interactions.Offset
|
|
} else {
|
|
this._interactions.Offset = new ol_interaction_Offset({
|
|
source: this._source
|
|
})
|
|
}
|
|
var offset = new ol_control_Toggle({
|
|
html: '<i></i>',
|
|
className: 'ol-offset',
|
|
title: this._getTitle(options.interactions.Offset) || 'Offset',
|
|
name: 'Offset',
|
|
interaction: this._interactions.Offset
|
|
})
|
|
this.addControl(offset)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
export default ol_control_EditBar
|