Something went wrong on our end
-
Timothee P authoredTimothee P authored
edition-service.js 10.64 KiB
import { Draw, Snap } from 'ol/interaction';
import GeometryType from 'ol/geom/GeometryType';
import Modify from 'ol/interaction/Modify';
import Select from 'ol/interaction/Select';
import MultiPoint from 'ol/geom/MultiPoint';
import Point from 'ol/geom/Point';
import {
Fill, Stroke, Style, Circle, Text //RegularShape, Circle as CircleStyle, Text,Icon
} from 'ol/style';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import mapService from '@/services/map-service';
import { buffer } from 'ol/extent';
// device detection
const isMobile = /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent)
//eslint-disable-next-line
|| /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0,4));
const editionService = {
drawnFeature: null,
featureToEdit: null,
editing_feature: {},
geom_type: 'linestring',
drawStyle: new Style({
fill: new Fill({
color: 'rgba(255, 255, 255, 0.2)'
}),
stroke: new Stroke({
color: 'rgba(255, 45, 0, 0.5)',
lineDash: [],
width: 2
}),
image: new Circle({
radius: 7,
stroke: new Stroke({
color: 'rgba(255, 0, 0, 0.5)',
lineDash: [],
width: 2
}),
fill: new Fill({
color: 'rgba(255, 255, 255, 0.5)'
})
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff',
width: 1
}),
text: ''
}),
zIndex: 50
}),
setEditingFeature(feature) {
this.editing_feature = feature;
},
startEditFeature(feature){
this.editing_feature = feature;
this.draw.setActive(false);
this.drawSource.addFeature(feature);
this.drawnItems.setZIndex(50);
mapService.fitExtent(buffer(this.drawSource.getExtent(),200));
},
addEditionControls(geomType, isEditable) {
this.geom_type = geomType;
this.drawSource = new VectorSource();
this.drawnItems = new VectorLayer({
source: this.drawSource,
style: this.drawStyle,
zIndex: 4000
});
window.olMap = mapService.getMap();
mapService.getMap().addLayer(this.drawnItems);
if (this.draw) {
mapService.getMap().removeInteraction(this.draw);
}
let gType = GeometryType.POINT;
if (geomType.toUpperCase().indexOf('POLYGON') >= 0) {
gType = GeometryType.POLYGON;
}
else if (geomType.toUpperCase().indexOf('LINE') >= 0) {
gType = GeometryType.LINE_STRING;
}
this.draw = new Draw({
source: this.drawSource,
type: gType,
style: this.drawStyle,
//geometryName: layer.getGeomAttributeName()
});
mapService.getMap().addInteraction(this.draw);
this.setEditingFeature(undefined);
this.draw.on('drawend', (evt) => {
var feature = evt.feature;
this.drawnFeature = feature;
this.setEditingFeature(feature);
this.draw.setActive(false);
});
this.selectForUpdate = new Select({
style: [
this.drawStyle,
new Style({
image: new Circle({
radius: 5,
fill: new Fill({
color: 'orange',
}),
}),
geometry: function (feature) {
// return the coordinates of the first ring of the polygon
const coordinates = feature.getGeometry().getCoordinates()[0];
if (feature.getGeometry() instanceof Point){
return feature.getGeometry();
}
return new MultiPoint(coordinates);
},
})
],
filter: (feature) => {
if (this.featureToEdit && feature.id_ === this.featureToEdit.id) {
return true;
} else if (this.drawnFeature && feature.ol_uid === this.drawnFeature.ol_uid) {
return true;
} else if (!this.drawnFeature && !this.featureToEdit) {
return true;
}
return false;
}
});
// On mobile stop drawing when selecting a drawn point
if (isMobile) {
this.selectForUpdate.on('select', () => {
// Permet de stopper le dessin de ligne ou polygone sur mobile
if (this.draw.getActive() && (this.draw.sketchCoords_.length > 2 || this.draw.sketchCoords_[0].length > 3)) {
this.draw.finishDrawing();
}
});
}
this.modify = new Modify({
style: this.drawStyle,
features: this.selectForUpdate.getFeatures()
});
// This workaround allows to avoid the ol freeze
// referenced bug : https://github.com/openlayers/openlayers/issues/6310
// May be corrected in a future version
this.modify.handleUpEvent_old = this.modify.handleUpEvent;
this.modify.handleUpEvent = function (evt) {
try {
this.handleUpEvent_old(evt);
} catch (ex) {
console.log(ex);
}
};
if (isEditable) mapService.getMap().addInteraction(this.selectForUpdate); // disable edit on double-click if edition is disabled
mapService.getMap().addInteraction(this.modify);
},
resetAllTools() {
if (this.draw) {
this.draw.setActive(false);
}
if (this.selectForDeletion) {
this.removeSelectInteraction(this.selectForDeletion);
}
if (this.selectForUpdate) {
this.removeSelectInteraction(this.selectForUpdate);
}
if (this.modify) {
this.modify.setActive(false);
}
},
removeSelectInteraction(interaction) {
interaction.getFeatures().clear();
interaction.setActive(false);
},
activeUpdateFeature() {
this.resetAllTools();
this.modify.setActive(true);
this.selectForUpdate.setActive(true);
this.selectForUpdate.getFeatures().push(this.editing_feature);
},
activeDeleteFeature() {
this.resetAllTools();
if (!this.selectForDeletion) {
const style = new Style({
fill: new Fill({
color: 'rgba(255, 0, 0, 0.2)'
}),
stroke: new Stroke({
color: 'rgba(255, 0, 0, 0.5)',
width: 2
}),
image: new Circle({
radius: 7,
fill: new Fill({
color: 'rgba(255, 0, 0, 0.5)'
})
}),
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: 'rgba(255, 0, 0, 0.5)' }),
}),
zIndex: 50
});
this.selectForDeletion = new Select({
style: style,
filter: (feature) => {
if (this.featureToEdit && feature.id_ === this.featureToEdit.id) {
return true;
} else if (this.drawnFeature && feature.ol_uid === this.drawnFeature.ol_uid) {
return true;
} else if (!this.drawnFeature && !this.featureToEdit) {
return true;
}
return false;
}
});
mapService.getMap().addInteraction(this.selectForDeletion);
// Lorsque de nouvelles features sont sélectionnées
const selected_features = this.selectForDeletion.getFeatures();
this.listenerKey = selected_features.on('add', (evt) => {
var feature = evt.element;
if (feature) {
setTimeout(() => {
if (confirm('Etes-vous sur de vouloir supprimer cet objet ?')) {
// supprimer l'edition de la sélection
this.selectForDeletion.getFeatures().clear();
// supprimer l'edition de la carte
this.drawSource.removeFeature(feature);
this.editing_feature = undefined;
this.draw.setActive(true);
this.selectForDeletion.setActive(false);
}
}, 300);
}
});
} else {
this.selectForDeletion.setActive(true);
}
},
setFeatureToEdit(feature) {
this.featureToEdit = feature;
},
removeActiveFeatures() {
this.drawnFeature = null;
this.featureToEdit = null;
},
addSnapInteraction(map) {
// The snap interaction must be added after the Modify and Draw interactions
// in order for its map browser event handlers to be fired first. Its handlers
// are responsible of doing the snapping.
// Since we can't give a list of source to snap,
// we use this workaround, an interaction collection: https://github.com/openlayers/openlayers/issues/7100
let interactions = [];
map.getLayers().forEach((layer) => {
if (layer instanceof VectorLayer) {
let interaction = new Snap({
source: layer.getSource()
});
interactions.push(interaction);
}
});
for(let snap of interactions ) {
map.addInteraction(snap);
}
},
removeSnapInteraction(map) {
// Find the double click interaction that is on the map.
let interactions = [];
map.getInteractions().forEach(function (interaction) {
if (interaction instanceof Snap) {
interactions.push(interaction);
}
});
// Remove the interaction from the map.
for(let snap of interactions ) {
map.removeInteraction(snap);
}
}
};
export default editionService;