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()
})
}
}
/** 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({
addCondition: ol_events_condition_shiftKeyOnly
})
}
var transform = new ol_control_Toggle({
html: '',
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: '',
className: 'ol-offset',
title: this._getTitle(options.interactions.Offset) || 'Offset',
name: 'Offset',
interaction: this._interactions.Offset
})
this.addControl(offset)
}
}
}
export default ol_control_EditBar