/**
* Create Edit Control
* @type function
* @returns {function} See parameters of return function in {@link CONTROL_FACTORIES_edit}
*/
BKGWebMap.Control.createEdit = function () {
return function (map, controlName, options, panel) {
var _this = this;
var mapId = map.getTarget();
var interactionSelect;
var globalLayer;
var globalFeature;
var editButtonSaveAttributes;
var enterColumnInput;
var enterColumnButton;
var columnSelect;
var formatSelect;
var exportNameInput;
// Check if control should be created
if (options.active === false) {
return undefined;
}
// If no panel exists and no other div ID is defined, do not create this control
if (!panel && (!options.div || options.div === '')) {
window.console.log(BKGWebMap.ERROR.noPanelNoDivForControl + controlName);
return undefined;
}
var target;
var inPanel = true;
if (options.div && options.div !== '') {
target = options.div;
inPanel = false;
} else {
target = panel.element.getElementsByClassName('bkgwebmap-panelbar')[0];
}
// Control title for panel
var title = 'Editieren';
// Tooltip position
var tooltipClass = 'bkgwebmap-paneltooltip bkgwebmap-paneltooltipleft';
var tooltipTextClass = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptextleft';
if (inPanel && panel.getPanelPosition() === 'right') {
tooltipClass = 'bkgwebmap-paneltooltip bkgwebmap-paneltooltipright';
tooltipTextClass = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptextright';
}
// Create DOM
var editPanel = document.createElement('div');
editPanel.className = 'bkgwebmap-editpanel ' + tooltipClass;
editPanel.onclick = function () {
clearDropdown(layerSelect);
map.getLayers().forEach(function (layer) {
_this.getEditableLayer(map, layer);
});
};
var parser = new DOMParser();
var editPanelIcon = parser.parseFromString(BKGWebMap.PANEL_ICONS.EDIT, 'text/xml');
editPanelIcon.documentElement.setAttribute('class', 'bkgwebmap-panelicons bkgwebmap-paneliconsopen');
editPanel.appendChild(editPanelIcon.documentElement);
var editPanelTooltip = document.createElement('span');
editPanelTooltip.className = tooltipTextClass;
editPanelTooltip.innerHTML = title;
editPanel.appendChild(editPanelTooltip);
var editPanelContent = document.createElement('div');
var editPanelContentClass = 'bkgwebmap-editpanelcontent';
editPanelContent.className = editPanelContentClass + ' bkgwebmap-panelsinglecontent';
var layerSelect = document.createElement('select');
layerSelect.className = 'bkgwebmap-layerselect';
layerSelect.setAttribute('data-bkgwebmap-lasteditlayer', '');
var selectItem = document.createElement('option');
selectItem.innerHTML = 'Layer auswählen';
layerSelect.appendChild(selectItem);
editPanelContent.appendChild(layerSelect);
var editAccordionTitle = document.createElement('div');
editAccordionTitle.innerHTML = 'Editierung';
editAccordionTitle.className = 'bkgwebmap-editaccordionheader';
var editAccordionHeader = document.createElement('div');
editAccordionHeader.className = 'bkgwebmap-customlayerwmsheader';
var editAccordionMinusDiv = document.createElement('div');
editAccordionMinusDiv.className = 'bkgwebmap-editaccordionplusminus';
editAccordionMinusDiv.innerHTML = '+';
editAccordionHeader.appendChild(editAccordionTitle);
editAccordionHeader.appendChild(editAccordionMinusDiv);
editAccordionHeader.addEventListener('click', function () {
var parent = this.parentNode;
var minusPlus = parent.getElementsByClassName('bkgwebmap-editaccordionplusminus')[0];
editInterfaceWrapper.style.display = editInterfaceWrapper.style.display === 'none' ? 'block' : 'none';
minusPlus.innerHTML = minusPlus.innerHTML === '+' ? '-' : '+';
});
editPanelContent.appendChild(editAccordionHeader);
// edit interface wrapper
var editInterfaceWrapper = document.createElement('div');
var editInterfaceSelectLayerSpan = document.createElement('span');
editInterfaceSelectLayerSpan.innerHTML = 'Layer auswählen!';
editInterfaceWrapper.appendChild(editInterfaceSelectLayerSpan);
editInterfaceWrapper.style.display = 'none';
editPanelContent.appendChild(editInterfaceWrapper);
var exportAccordionTitle = document.createElement('div');
exportAccordionTitle.innerHTML = 'Exportieren';
exportAccordionTitle.className = 'bkgwebmap-exportaccordionheader';
var exportAccordionHeader = document.createElement('div');
exportAccordionHeader.className = 'bkgwebmap-customlayerwmsheader';
var exportAccordionMinusDiv = document.createElement('div');
exportAccordionMinusDiv.className = 'bkgwebmap-exportaccordionplusminus';
exportAccordionMinusDiv.innerHTML = '+';
exportAccordionHeader.appendChild(exportAccordionTitle);
exportAccordionHeader.appendChild(exportAccordionMinusDiv);
exportAccordionHeader.addEventListener('click', function () {
var parent = this.parentNode;
var minusPlus = parent.getElementsByClassName('bkgwebmap-exportaccordionplusminus')[0];
exportInterfaceWrapper.style.display = exportInterfaceWrapper.style.display === 'none' ? 'block' : 'none';
minusPlus.innerHTML = minusPlus.innerHTML === '+' ? '-' : '+';
});
editPanelContent.appendChild(exportAccordionHeader);
var exportInterfaceWrapper = document.createElement('div');
var exportInterfaceSelectLayerSpan = document.createElement('span');
exportInterfaceSelectLayerSpan.innerHTML = 'Layer auswählen!';
exportInterfaceWrapper.insertBefore(exportInterfaceSelectLayerSpan, exportInterfaceWrapper.childNodes[0]);
exportInterfaceWrapper.style.display = 'none';
editPanelContent.appendChild(exportInterfaceWrapper);
var exportInterfaceInnerWrapper = document.createElement('div');
exportInterfaceInnerWrapper.style.display = 'none';
exportInterfaceWrapper.appendChild(exportInterfaceInnerWrapper);
var editButtonPoint = document.createElement('div');
editButtonPoint.className = 'bkgwebmap-editbutton bkgwebmap-paneltooltip bkgwebmap-paneltooltiptopright';
editButtonPoint.setAttribute('data-bkgwebmap-editgeom', 'Point');
var parserIconPoint = new DOMParser();
var iconPoint = parserIconPoint.parseFromString(BKGWebMap.PANEL_ICONS.EDIT_POINT, 'text/xml');
editButtonPoint.appendChild(iconPoint.documentElement);
var editButtonPointTooltip = document.createElement('span');
editButtonPointTooltip.className = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptexttopright';
editButtonPointTooltip.innerHTML = 'Punkte hinzufügen oder verschieben';
editButtonPoint.appendChild(editButtonPointTooltip);
tooltipHoverEvent(editButtonPoint);
editInterfaceWrapper.appendChild(editButtonPoint);
var editButtonLine = document.createElement('div');
editButtonLine.className = 'bkgwebmap-editbutton bkgwebmap-paneltooltip bkgwebmap-paneltooltiptopright';
editButtonLine.setAttribute('data-bkgwebmap-editgeom', 'LineString');
var parserIconLine = new DOMParser();
var iconLine = parserIconLine.parseFromString(BKGWebMap.PANEL_ICONS.EDIT_LINE, 'text/xml');
editButtonLine.appendChild(iconLine.documentElement);
var editButtonLineTooltip = document.createElement('span');
editButtonLineTooltip.className = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptexttopright';
editButtonLineTooltip.innerHTML = 'Linien hinzufügen oder verschieben';
editButtonLine.appendChild(editButtonLineTooltip);
tooltipHoverEvent(editButtonLine);
editInterfaceWrapper.appendChild(editButtonLine);
var editButtonPolygon = document.createElement('div');
editButtonPolygon.className = 'bkgwebmap-editbutton bkgwebmap-paneltooltip bkgwebmap-paneltooltiptopright';
editButtonPolygon.setAttribute('data-bkgwebmap-editgeom', 'Polygon');
var parserIconPolygon = new DOMParser();
var iconPolygon = parserIconPolygon.parseFromString(BKGWebMap.PANEL_ICONS.EDIT_POLYGON, 'text/xml');
editButtonPolygon.appendChild(iconPolygon.documentElement);
var editButtonPolygonTooltip = document.createElement('span');
editButtonPolygonTooltip.className = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptexttopright';
editButtonPolygonTooltip.innerHTML = 'Polygone hinzufügen oder verschieben';
editButtonPolygon.appendChild(editButtonPolygonTooltip);
tooltipHoverEvent(editButtonPolygon);
editInterfaceWrapper.appendChild(editButtonPolygon);
var editButtonAttributes = document.createElement('div');
editButtonAttributes.className = 'bkgwebmap-editbutton bkgwebmap-paneltooltip bkgwebmap-paneltooltiptopright';
var parserIconAttributes = new DOMParser();
var iconAttributes = parserIconAttributes.parseFromString(BKGWebMap.PANEL_ICONS.ATTRIBUTES, 'text/xml');
editButtonAttributes.appendChild(iconAttributes.documentElement);
var attributesTooltip = document.createElement('span');
attributesTooltip.className = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptexttopright';
attributesTooltip.innerHTML = 'Attribute';
editButtonAttributes.appendChild(attributesTooltip);
tooltipHoverEvent(editButtonAttributes);
editInterfaceWrapper.appendChild(editButtonAttributes);
var editButtonDelete = document.createElement('div');
editButtonDelete.className = 'bkgwebmap-editbutton bkgwebmap-paneltooltip bkgwebmap-paneltooltiptopright';
var parserIconDelete = new DOMParser();
var iconDelete = parserIconDelete.parseFromString(BKGWebMap.PANEL_ICONS.DELETE, 'text/xml');
editButtonDelete.appendChild(iconDelete.documentElement);
var editButtonDeleteTooltip = document.createElement('span');
editButtonDeleteTooltip.className = 'bkgwebmap-paneltooltiptext bkgwebmap-paneltooltiptexttopright';
editButtonDeleteTooltip.innerHTML = 'Features löschen';
editButtonDelete.appendChild(editButtonDeleteTooltip);
tooltipHoverEvent(editButtonDelete);
editInterfaceWrapper.appendChild(editButtonDelete);
var attributesContainer = document.createElement('div');
editInterfaceWrapper.appendChild(attributesContainer);
var deleteAttributesContainer = document.createElement('div');
editInterfaceWrapper.appendChild(deleteAttributesContainer);
var addAttributesContainer = document.createElement('div');
editInterfaceWrapper.appendChild(addAttributesContainer);
// check if export key exists; if not use default
if (options.export === undefined) {
options.export = BKGWebMap.CONTROLS.tools.edit.export;
}
var formats = BKGWebMap.CONTROLS.tools.edit.export.formats;
// check if exporting is activated
if (options.export.active) {
if (options.export.formats instanceof Array && options.export.formats.length) {
formats = options.export.formats;
}
var exportVectorButton = document.createElement('div');
exportVectorButton.className = 'bkgwebmap-editbutton-visible';
exportVectorButton.innerHTML = 'Layer exportieren';
exportInterfaceInnerWrapper.appendChild(exportVectorButton);
formatSelect = document.createElement('select');
formatSelect.className = 'bkgwebmap-formatselect';
selectItem = document.createElement('option');
selectItem.className = 'bkgwebmap-formatselectitem';
selectItem.innerHTML = 'Format auswählen';
selectItem.setAttribute('data-bkgwebmap-export-format', 'none');
formatSelect.appendChild(selectItem);
var defaultFormats = BKGWebMap.CONTROLS.tools.edit.export.formats;
var formatLowerCase;
for (var i = 0; i < defaultFormats.length; i++) {
if (formats.indexOf(defaultFormats[i]) !== -1) {
selectItem = document.createElement('option');
selectItem.className = 'bkgwebmap-formatselectitem';
selectItem.innerHTML = defaultFormats[i];
formatLowerCase = defaultFormats[i].toLowerCase();
selectItem.setAttribute('data-bkgwebmap-export-format', formatLowerCase);
formatSelect.appendChild(selectItem);
}
}
exportInterfaceInnerWrapper.appendChild(formatSelect);
exportNameInput = document.createElement('input');
exportNameInput.type = 'text';
exportNameInput.className = 'bkgwebmap-attributemaskinput';
exportNameInput.placeholder = 'Dateinamen eingeben';
exportInterfaceInnerWrapper.appendChild(exportNameInput);
var exportNameExtension = document.createElement('span');
exportInterfaceInnerWrapper.appendChild(exportNameExtension);
exportVectorButton.onclick = exportVectorLayer;
formatSelect.onchange = function () {
var exportFormat = formatSelect.options[formatSelect.selectedIndex].getAttribute('data-bkgwebmap-export-format');
exportNameExtension.innerHTML = '.' + exportFormat;
};
}
// add all contents to panel
if (inPanel) {
panel.addPanelContent(editPanelContent);
} else {
editPanel.appendChild(editPanelContent);
editPanelContent.style.display = 'none';
}
function clickControl() {
if (inPanel) {
var activeContent = panel.getActiveContent();
if (activeContent === '') {
panel.openPanel();
panel.changePanelContent(title, editPanelContentClass);
hideEditButtons();
_this.activeIcon();
} else if (activeContent === editPanelContentClass) {
panel.closePanel();
} else {
panel.changePanelContent(title, editPanelContentClass);
hideEditButtons();
_this.activeIcon();
}
} else if (editPanelContent.style.display === 'none') {
editPanelContent.style.display = 'block';
} else {
editPanelContent.style.display = 'none';
}
}
this.activeIcon = function () {
editPanel.classList.add('bkgwebmap-panelactive');
};
// clears all elements but the first one in a given select dropdown
function clearDropdown(select) {
var elements = select.length;
for (var i = 0; i < elements - 1; i++) {
select.remove(1);
}
}
// Event listeners
var elementForEvent = editPanel;
if (!inPanel) {
elementForEvent = editPanel.querySelector('svg');
}
elementForEvent.addEventListener('click', clickControl, { passive: true });
elementForEvent.addEventListener('mouseenter', function () {
var allTooltips = document.getElementById(mapId).getElementsByClassName('bkgwebmap-paneltooltiptext');
for (var i = 0; i < allTooltips.length; i++) {
allTooltips[i].style.visibility = '';
}
editPanelTooltip.style.visibility = 'visible';
setTimeout(function () {
editPanelTooltip.style.visibility = '';
}, 1200);
}, false);
var editableLayersObject = {};
_this.getEditableLayer = function (map, layer) {
var layerProperties;
// check if layer is a vector or a group
// if group, iterate through group to find vectors
// only add layers to dropdown if they are editable
if (layer instanceof ol.layer.Vector) {
layerProperties = layer.getProperties();
if (layerProperties.edit && layer.getVisible() === true) {
selectItem = document.createElement('option');
selectItem.innerHTML = layerProperties.name;
selectItem.setAttribute('data-bkgwebmap-edit-layer', layerProperties.uniqueId);
layerSelect.appendChild(selectItem);
editableLayersObject[layerProperties.uniqueId] = layer;
}
} else if (layer instanceof ol.layer.Group) {
// only if group is visible loop through it
if (layer.getVisible() === true) {
layer.getLayers().forEach(function (subLayer) {
if (subLayer instanceof ol.layer.Vector && subLayer.getVisible() === true) {
layerProperties = subLayer.getProperties();
if (layerProperties.edit) {
selectItem = document.createElement('option');
selectItem.innerHTML = layerProperties.name;
selectItem.setAttribute('data-bkgwebmap-edit-layer', layerProperties.uniqueId);
layerSelect.appendChild(selectItem);
editableLayersObject[layerProperties.uniqueId] = subLayer;
}
}
});
}
}
};
// checks whether there are editable layers
// this has nothing to do with visibility, but with what is in the config
_this.editableLayerAvailable = function () {
var layerProperties;
var isAvailable = false;
map.getLayers().forEach(function (layer) {
if (layer instanceof ol.layer.Vector) {
layerProperties = layer.getProperties();
if (layerProperties.edit) {
isAvailable = true;
}
} else if (layer instanceof ol.layer.Group) {
layer.getLayers().forEach(function (subLayer) {
if (subLayer instanceof ol.layer.Vector) {
layerProperties = subLayer.getProperties();
if (layerProperties.edit) {
isAvailable = true;
}
}
});
}
});
return isAvailable;
};
// empty layer to be used when no editable layer is found
var emptyLayerSource = new ol.source.Vector();
var symbol = BKGWebMap.MAP_ICONS_ENCODED.circle.a + '%23ffcc33' + BKGWebMap.MAP_ICONS_ENCODED.circle.b + '%23ffcc33' + BKGWebMap.MAP_ICONS_ENCODED.circle.c;
var emptyLayerVector = new ol.layer.Vector({
source: emptyLayerSource,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new ol.style.Stroke({
color: '#ffcc33',
width: 2
}),
image: new ol.style.Icon(({
anchor: [0.5, 0.5],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
imgSize: BKGWebMap.MAP_ICONS_ENCODED.circle.size,
src: 'data:image/svg+xml;charset=utf8,' + symbol
}))
})
});
emptyLayerVector.setProperties({
edit: true,
name: 'Neue Zeichnung',
uniqueId: 'emptyLayerDigitizingVector',
visibility: true
});
// adds the empty layer to the map
// checks first whether the emptyLayer option is activated
this.addEmptyLayer = function addEmptyLayer() {
if (options.emptyLayer === true) {
map.addLayer(emptyLayerVector);
map.getControls().forEach(function (control) {
if (BKGWebMap.Control.LayerSwitcher && control instanceof BKGWebMap.Control.LayerSwitcher) {
control.addInLayerSwitcher(emptyLayerVector, false, false, true, null);
}
});
map.getLayers().forEach(function (layer) {
_this.getEditableLayer(map, layer);
});
}
};
layerSelect.onchange = function () {
editInterfaceSelectLayerSpan.innerHTML = '';
exportInterfaceSelectLayerSpan.innerHTML = '';
removeAllButtonsHighlightings();
var activeLayerId = getActiveLayerId();
layerSelect.setAttribute('data-bkgwebmap-lasteditlayer', activeLayerId);
hideEditButtons();
if (activeLayerId != null) {
_this.removeEditInteractions();
var layerFeatures = editableLayersObject[activeLayerId].getSource().getFeatures();
var editGeoms = BKGWebMap.Util.findGeometryType(layerFeatures);
// if the digitizing vector is detected, allow all geoms
if (activeLayerId === emptyLayerVector.getProperties().uniqueId) {
editGeoms = ['Point', 'LineString', 'Polygon'];
}
showEditButtons(editGeoms);
globalLayer = editableLayersObject[activeLayerId];
exportInterfaceInnerWrapper.style.display = 'block';
} else {
editInterfaceSelectLayerSpan.innerHTML = 'Layer auswählen!';
exportInterfaceSelectLayerSpan.innerHTML = 'Layer auswählen!';
exportInterfaceInnerWrapper.style.display = 'none';
}
createDeleteColumnMask();
attributesContainer.innerHTML = '';
addAttributesContainer.innerHTML = '';
if (activeLayerId !== null) {
createAddColumnMask();
}
};
function getActiveLayerId() {
var id = layerSelect.options[layerSelect.selectedIndex].getAttribute('data-bkgwebmap-edit-layer');
return id;
}
function hideEditButtons() {
editButtonPoint.style.display = 'none';
editButtonLine.style.display = 'none';
editButtonPolygon.style.display = 'none';
editButtonAttributes.style.display = 'none';
editButtonDelete.style.display = 'none';
}
function showEditButtons(editGeoms) {
if (editGeoms.indexOf('Point') > -1) {
editButtonPoint.style.display = 'inline-block';
}
if (editGeoms.indexOf('LineString') > -1) {
editButtonLine.style.display = 'inline-block';
}
if (editGeoms.indexOf('Polygon') > -1) {
editButtonPolygon.style.display = 'inline-block';
}
editButtonAttributes.style.display = 'inline-block';
editButtonDelete.style.display = 'inline-block';
}
editButtonPoint.onclick = onClickEditButton;
editButtonLine.onclick = onClickEditButton;
editButtonPolygon.onclick = onClickEditButton;
// when edit button is clicked
function onClickEditButton() {
var geomType = this.getAttribute('data-bkgwebmap-editgeom');
higlightEditButton(geomType);
var activeLayerId = getActiveLayerId();
_this.removeEditInteractions();
var layerSource = editableLayersObject[activeLayerId].getSource();
addEditInteractions(layerSource, geomType);
}
function higlightEditButton(geomType) {
removeAllButtonsHighlightings();
if (geomType === 'Point') {
editButtonPoint.classList.add('bkgwebmap-editbutton-active');
} else if (geomType === 'LineString') {
editButtonLine.classList.add('bkgwebmap-editbutton-active');
} else if (geomType === 'Polygon') {
editButtonPolygon.classList.add('bkgwebmap-editbutton-active');
}
}
function removeAllButtonsHighlightings() {
editButtonPoint.classList.remove('bkgwebmap-editbutton-active');
editButtonLine.classList.remove('bkgwebmap-editbutton-active');
editButtonPolygon.classList.remove('bkgwebmap-editbutton-active');
editButtonAttributes.classList.remove('bkgwebmap-editbutton-active');
editButtonDelete.classList.remove('bkgwebmap-editbutton-active');
}
var interactionDraw;
var interactionModify;
var interactionSnap;
// adds draw, modify, snap interactions
function addEditInteractions(layerSource, geomType) {
_this.removeEditInteractions();
removeAttributeListener();
// define interactions
interactionModify = new ol.interaction.Modify({ source: layerSource });
interactionSnap = new ol.interaction.Snap({ source: layerSource });
interactionDraw = new ol.interaction.Draw({
source: layerSource,
type: geomType
});
interactionDraw.on('drawend', onDrawEnd);
// add interactions
map.addInteraction(interactionModify);
map.addInteraction(interactionSnap);
map.addInteraction(interactionDraw);
}
// show the attribute mask and define a global layer and feature
function onDrawEnd(e) {
// get the columns that should be added to the new feature
var availableProperties = getLayerProperties();
var attributes = {};
var columnName;
// create columns with empty attributes
for (var key in availableProperties) {
if (Object.prototype.hasOwnProperty.call(availableProperties, key)) {
var propType = typeof (availableProperties[key]);
if ((propType === 'string' || propType === 'number') && key.length > 0) {
columnName = key;
attributes[columnName] = '';
}
}
}
// add attributes to the feature
e.feature.setProperties(attributes);
var activeLayerId = getActiveLayerId();
globalLayer = editableLayersObject[activeLayerId];
globalFeature = e.feature;
generateAttributesMask(attributes);
}
this.removeEditInteractions = function () {
map.getInteractions().forEach(function (interaction) {
if (interaction instanceof ol.interaction.Modify) {
map.removeInteraction(interaction);
}
if (interaction instanceof ol.interaction.Snap) {
map.removeInteraction(interaction);
}
if (interaction instanceof ol.interaction.Draw) {
map.removeInteraction(interaction);
}
if (interaction instanceof ol.interaction.Select) {
map.removeInteraction(interaction);
}
attributesContainer.innerHTML = '';
});
};
editButtonDelete.onclick = addDeleteInteraction;
function addDeleteInteraction() {
removeAllButtonsHighlightings();
editButtonDelete.classList.add('bkgwebmap-editbutton-active');
var activeLayerId = getActiveLayerId();
removeAttributeListener();
_this.removeEditInteractions();
var layerToBeSelected = editableLayersObject[activeLayerId];
// multi means when features are overlapping; in that case all below the click will be selected, not just the top one
interactionSelect = new ol.interaction.Select({
layers: [layerToBeSelected],
multi: false,
hitTolerance: 5
});
interactionSelect.on('select', function () {
var selectedFeature = interactionSelect.getFeatures().item(0);
interactionSelect.getFeatures().forEach(function (feature) {
if (selectedFeature === feature) {
var deleteFeature = confirm('Objekt löschen?');
if (deleteFeature === true) {
layerToBeSelected.getSource().removeFeature(feature);
removeAllButtonsHighlightings();
_this.removeEditInteractions();
}
}
});
});
map.addInteraction(interactionSelect);
}
editButtonAttributes.onclick = addAttributesInteraction;
function addAttributesInteraction() {
removeAllButtonsHighlightings();
editButtonAttributes.classList.add('bkgwebmap-editbutton-active');
var activeLayerId = getActiveLayerId();
removeAttributeListener();
_this.removeEditInteractions();
var layerToBeSelected = editableLayersObject[activeLayerId];
globalLayer = layerToBeSelected;
// multi means when features are overlapping; in that case all below the click will be selected, not just the top one
interactionSelect = new ol.interaction.Select({
layers: [layerToBeSelected],
multi: false
});
interactionSelect.on('select', function () {
var selectedFeature = interactionSelect.getFeatures().item(0); // get the selected item
if (selectedFeature === undefined) {
attributesContainer.innerHTML = '';
} else {
interactionSelect.getFeatures().forEach(function (feature) {
if (selectedFeature === feature) {
var layerProperties = selectedFeature.getProperties();
globalFeature = selectedFeature;
generateAttributesMask(layerProperties);
}
});
}
});
map.addInteraction(interactionSelect);
}
function generateAttributesMask(layerProperties) {
var inputElement;
var inputLabel;
var lineBreak;
var selectItem;
attributesContainer.innerHTML = '';
columnSelect = document.createElement('select');
columnSelect.className = 'bkgwebmap-columnselect';
for (var key in layerProperties) {
if (Object.prototype.hasOwnProperty.call(layerProperties, key)) {
var propType = typeof (layerProperties[key]);
if ((propType === 'string' || propType === 'number') && key.length > 0) {
inputLabel = document.createElement('span');
inputLabel.innerHTML = '<b>' + key + '</b>';
attributesContainer.appendChild(inputLabel);
lineBreak = document.createElement('br');
attributesContainer.appendChild(lineBreak);
inputElement = document.createElement('input');
inputElement.type = 'text';
inputElement.value = layerProperties[key];
inputElement.className = 'bkgwebmap-attributemaskinput';
inputElement.setAttribute('data-bkgwebmap-attributekey', key);
attributesContainer.appendChild(inputElement);
lineBreak = document.createElement('br');
attributesContainer.appendChild(lineBreak);
selectItem = document.createElement('option');
selectItem.innerHTML = key;
selectItem.setAttribute('data-bkgwebmap-column', key);
columnSelect.appendChild(selectItem);
}
}
}
editButtonSaveAttributes = document.createElement('div');
editButtonSaveAttributes.className = 'bkgwebmap-editbutton-visible';
editButtonSaveAttributes.innerHTML = 'Speichern';
attributesContainer.appendChild(editButtonSaveAttributes);
editButtonSaveAttributes.onclick = saveAttributes;
}
function addAttributeColumn() {
var newColumnName = enterColumnInput.value;
if (newColumnName.length === 0) {
alert('Bitte Spaltennamen eingeben!');
} else {
var addColumn = confirm('Soll die Spalte ' + newColumnName + ' in allen Elementen der Ebene hinzugefügt werden?');
if (addColumn === true) {
var newColumn = {};
var columnName = enterColumnInput.value;
newColumn[columnName] = '';
var features = globalLayer.getSource().getFeatures();
features.forEach(function (feature) {
feature.setProperties(newColumn);
});
enterColumnInput.value = '';
createDeleteColumnMask();
if (attributesContainer.innerHTML.length > 0) { // if attributes container is open, refresh it
var layerProperties = globalFeature.getProperties();
generateAttributesMask(layerProperties);
}
}
}
}
function deleteAttributeColumn() {
var selectedColumn = columnSelect.options[columnSelect.selectedIndex].getAttribute('data-bkgwebmap-column');
var deleteColumn = confirm('Soll die Spalte ' + selectedColumn + ' in allen Elementen der Ebene gelöscht werden?');
if (deleteColumn === true) {
var features = globalLayer.getSource().getFeatures();
features.forEach(function (feature) {
var properties = feature.getProperties();
for (var key in properties) {
if (Object.prototype.hasOwnProperty.call(properties, key)) {
if (key === selectedColumn) {
feature.unset(key);
var layerProperties = feature.getProperties();
if (attributesContainer.innerHTML.length > 0) { // if attributes container is open, refresh it
generateAttributesMask(layerProperties);
}
}
}
}
});
createDeleteColumnMask();
}
}
function saveAttributes() {
var inputElements = attributesContainer.getElementsByTagName('input');
var key;
var propertiesObject = {};
for (var i = 0; i < inputElements.length; i++) {
key = inputElements[i].getAttribute('data-bkgwebmap-attributekey');
if (key !== 'newcolumnnameinputfield') {
propertiesObject[key] = inputElements[i].value;
}
}
var features = globalLayer.getSource().getFeatures();
features.forEach(function (feature) {
if (feature === globalFeature) {
feature.setProperties(propertiesObject);
alert('Die Attribute wurden erfolgreich gespeichert.');
}
});
}
// gets the properties of the first feature in a vector
function getLayerProperties() {
var activeLayerId = getActiveLayerId();
if (activeLayerId !== null) {
var feature = editableLayersObject[activeLayerId].getSource().getFeatures()[0];
if (feature !== undefined) {
var props = feature.getProperties();
return props;
}
}
}
function createDeleteColumnMask() {
var deleteColumnButton;
var selectItem;
columnSelect = document.createElement('select');
columnSelect.className = 'bkgwebmap-columnselect';
deleteAttributesContainer.innerHTML = '';
var layerProperties = getLayerProperties();
var propertyCount = 0;
for (var key in layerProperties) {
if (Object.prototype.hasOwnProperty.call(layerProperties, key)) {
var propType = typeof (layerProperties[key]);
if ((propType === 'string' || propType === 'number') && key.length > 0) {
selectItem = document.createElement('option');
selectItem.innerHTML = key;
selectItem.setAttribute('data-bkgwebmap-column', key);
columnSelect.appendChild(selectItem);
propertyCount += 1;
}
}
}
if (propertyCount > 0) {
var dividingLine = document.createElement('hr');
deleteAttributesContainer.appendChild(dividingLine);
deleteColumnButton = document.createElement('div');
deleteColumnButton.className = 'bkgwebmap-editbutton-visible';
deleteColumnButton.innerHTML = 'Spalte löschen';
deleteAttributesContainer.appendChild(deleteColumnButton);
deleteAttributesContainer.appendChild(columnSelect);
deleteColumnButton.onclick = deleteAttributeColumn;
deleteAttributesContainer.appendChild(columnSelect);
}
}
function createAddColumnMask() {
addAttributesContainer.innerHTML = '';
var dividingLine = document.createElement('hr');
addAttributesContainer.appendChild(dividingLine);
enterColumnButton = document.createElement('div');
enterColumnButton.className = 'bkgwebmap-editbutton-visible';
enterColumnButton.innerHTML = 'Neue Spalte';
addAttributesContainer.appendChild(enterColumnButton);
enterColumnInput = document.createElement('input');
enterColumnInput.type = 'text';
enterColumnInput.className = 'bkgwebmap-attributemaskinput';
enterColumnInput.placeholder = 'Spaltennamen eingeben';
enterColumnInput.setAttribute('data-bkgwebmap-attributekey', 'newcolumnnameinputfield');
addAttributesContainer.appendChild(enterColumnInput);
enterColumnButton.onclick = addAttributeColumn;
}
function exportVectorLayer() {
var exportFormat;
var features;
var filename;
var activeLayerId = getActiveLayerId();
if (activeLayerId === null) {
alert('Layer auswählen!');
} else {
exportFormat = formatSelect.options[formatSelect.selectedIndex].getAttribute('data-bkgwebmap-export-format');
if (exportFormat === 'none') {
alert('Export Format auswählen!');
} else {
var mapCrs = map.getView().getProjection().getCode();
features = editableLayersObject[activeLayerId].getSource().getFeatures();
filename = exportNameInput.value;
if (filename.length === 0) {
filename = 'bkg_export';
}
switch (exportFormat) {
case 'geojson':
exportFileGeoJson(mapCrs, features, filename);
break;
case 'gml':
exportFileGml(mapCrs, features, filename);
break;
case 'gpx':
exportFileGpx(mapCrs, features, filename);
break;
case 'kml':
exportFileKml(mapCrs, features, filename);
break;
case 'wkt':
exportFileWkt(mapCrs, features, filename);
break;
// no default
}
}
}
}
function exportFileGeoJson(mapCrs, features, filename) {
var format = new ol.format.GeoJSON();
var exportLayer = format.writeFeatures(features, {
dataProjection: 'EPSG:4326',
featureProjection: mapCrs
});
var blob = new Blob([exportLayer], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename + '.geojson');
}
function exportFileGml(mapCrs, features, filename) {
var format = new ol.format.GML3({
featureType: ['topp'],
featureNS: {
topp: 'topp'
},
srsName: mapCrs
});
var exportLayer = format.writeFeatures(features, {
featureProjection: mapCrs,
dataProjection: mapCrs
});
var blob = new Blob([exportLayer], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename + '.gml');
}
function exportFileGpx(mapCrs, features, filename) {
var format = new ol.format.GPX();
var exportLayer = format.writeFeatures(features, {
dataProjection: 'EPSG:4326',
featureProjection: mapCrs
});
var blob = new Blob([exportLayer], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename + '.gpx');
}
function exportFileKml(mapCrs, features, filename) {
var format = new ol.format.KML();
var exportLayer = format.writeFeatures(features, {
dataProjection: 'EPSG:4326',
featureProjection: mapCrs
});
var blob = new Blob([exportLayer], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename + '.kml');
}
function exportFileWkt(mapCrs, features, filename) {
var format = new ol.format.WKT();
var exportLayer = format.writeFeatures(features, {
dataProjection: 'EPSG:4326',
featureProjection: mapCrs
});
var blob = new Blob([exportLayer], { type: 'text/plain;charset=utf-8' });
saveAs(blob, filename + '.wkt');
}
// deactivates click handler for WMS feature request and GeoSearch
function removeAttributeListener() {
map.getControls().forEach(function (control) {
if (BKGWebMap.Control.ShowAttributes && control instanceof BKGWebMap.Control.ShowAttributes) {
map.un('click', control.clickAttributesActivate);
}
if (BKGWebMap.Control.GeoSearch && control instanceof BKGWebMap.Control.GeoSearch) {
map.un('click', control.geoSearchClickActivate);
}
if (BKGWebMap.Control.CopyCoordinates && control instanceof BKGWebMap.Control.CopyCoordinates) {
map.un('click', control.clickCopyCoordinatesActivate);
}
});
}
// reactivates click handler for WMS feature request and GeoSearch
this.addAttributeListener = function () {
map.getControls().forEach(function (control) {
if (BKGWebMap.Control.ShowAttributes && control instanceof BKGWebMap.Control.ShowAttributes) {
map.on('click', control.clickAttributesActivate);
}
if (BKGWebMap.Control.GeoSearch && control instanceof BKGWebMap.Control.GeoSearch) {
map.on('click', control.geoSearchClickActivate);
}
if (BKGWebMap.Control.CopyCoordinates && control instanceof BKGWebMap.Control.CopyCoordinates) {
map.on('click', control.clickCopyCoordinatesActivate);
}
});
};
// Show/hide tooltips
function tooltipHoverEvent(tooltipButton) {
tooltipButton.addEventListener('mouseenter', function () {
var allTooltips = editPanelContent.getElementsByClassName('bkgwebmap-paneltooltiptext');
for (var i = 0; i < allTooltips.length; i++) {
allTooltips[i].style.visibility = '';
}
var currentButton = tooltipButton.getElementsByClassName('bkgwebmap-paneltooltiptext')[0];
currentButton.style.visibility = 'visible';
setTimeout(function () {
currentButton.style.visibility = '';
}, 1200);
});
}
/**
* Change menu with edit layers
*/
this.adaptLayerMenu = function () {
if (layerSelect.childElementCount === 2) {
layerSelect.selectedIndex = 1;
setTimeout(function () {
layerSelect.dispatchEvent(new CustomEvent('change'));
}, 100);
} else {
var lastLayerId = layerSelect.getAttribute('data-bkgwebmap-lasteditlayer');
var layersWithIds = layerSelect.querySelectorAll('[data-bkgwebmap-edit-layer]');
if (layersWithIds.length) {
for (var i = 0; i < layersWithIds.length; i++) {
if (layersWithIds[i].getAttribute('data-bkgwebmap-edit-layer') === lastLayerId) {
layerSelect.selectedIndex = i + 1;
setTimeout(function () {
layerSelect.dispatchEvent(new CustomEvent('change'));
}, 100);
}
}
}
}
};
// Finalize control
ol.control.Control.call(this, {
element: editPanel,
target: target
});
};
};