Something went wrong on our end
-
Timothee P authoredTimothee P authored
edition-service.js 9.00 KiB
import { Draw, Snap } from 'ol/interaction';
import Modify from 'ol/interaction/Modify';
import { Collection } from 'ol';
import MultiPoint from 'ol/geom/MultiPoint';
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';
const editionService = {
drawnFeature: null,
featureToEdit: null,
editing_feature: {},
geom_type: 'linestring',
// Création d'une collection filtrée
filteredFeatures: new Collection(),
// Méthode pour créer un style basé sur la couleur actuelle
createDrawStyle(isEditing) {
return [
new Style({
// Style principal pour le polygone
fill: new Fill({
color: isEditing ? 'rgba(255, 145, 0, .2)' : 'rgba(255, 255, 255, .2)',
}),
// Style principal pour la ligne et le tour du polygone
stroke: new Stroke({
color: isEditing ? 'rgba(255, 145, 0, .9)' : 'rgba(255, 45, 0, 0.5)',
lineDash: [],
width: 2,
}),
// Style principal pour le point
image: new Circle({
radius: 7,
stroke: new Stroke({
color: 'rgba(255, 0, 0, 0.5)',
lineDash: [],
width: 2
}),
fill: new Fill({
color: isEditing ? 'rgba(255, 145, 0, 0.9)' : 'rgba(255, 255, 255, 0.5)'
})
}),
// Style pour le texte, pas utilisé mais peut être conservé au cas où
text: new Text({
font: '12px Calibri,sans-serif',
fill: new Fill({ color: '#000' }),
stroke: new Stroke({
color: '#fff',
width: 1
}),
text: ''
}),
zIndex: 50
}),
// Style pour afficher des points sur les sommets de ligne ou polygone (seulement en mode édition)
...(isEditing
? [
// Définition du style de point
new Style({
image: new Circle({
radius: 5,
stroke: new Stroke({
color: 'rgba(255, 145, 0, .9)',
width: 2,
}),
fill: new Fill({
color: 'rgba(255, 145, 0, .5)',
}),
}),
// Récupération des sommets où afficher les points uniquement pour ligne et polygone
geometry: function (feature) {
const geometry = feature.getGeometry();
if (geometry.getType() === 'LineString') {
return new MultiPoint(geometry.getCoordinates()); // Sommets de la ligne
} else if (geometry.getType() === 'Polygon') {
return new MultiPoint(geometry.getCoordinates()[0]); // Sommets du premier anneau
}
return null;
},
}),
]
: []),
];
},
// Méthode pour changer la couleur de la géométrie existante en passant en mode édition
toggleEditionColor(isEditing) {
const drawStyle = this.createDrawStyle(isEditing); // Re-crée le style
this.drawnItems.setStyle(drawStyle); // Applique le style à la couche
},
setEditingFeature(feature) {
this.editing_feature = feature;
},
initFeatureToEdit(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) {
this.geom_type = geomType;
this.drawSource = new VectorSource();
this.drawnItems = new VectorLayer({
source: this.drawSource,
style: this.createDrawStyle(),
zIndex: 4000
});
mapService.getMap().addLayer(this.drawnItems);
if (this.draw) {
mapService.getMap().removeInteraction(this.draw);
}
let gType = 'Point';
if (geomType.toUpperCase().indexOf('POLYGON') >= 0) {
gType = 'Polygon';
}
else if (geomType.toUpperCase().indexOf('LINE') >= 0) {
gType = 'LineString';
}
this.draw = new Draw({
source: this.drawSource,
type: gType,
style: this.createDrawStyle()
});
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.modify = new Modify({
style: this.createDrawStyle(),
features: this.filteredFeatures, // Limite la modification aux entités filtrées
});
// 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);
}
};
mapService.getMap().addInteraction(this.modify);
// Supprime dynamiquement la feature des entités modifiables
this.drawSource.on('removefeature', (event) => {
const feature = event.feature;
this.filteredFeatures.remove(feature);
});
},
resetAllTools() {
if (this.draw) {
this.draw.setActive(false);
}
if (this.modify) {
this.modify.setActive(false);
}
},
removeSelectInteraction(interaction) {
interaction.getFeatures().clear();
interaction.setActive(false);
},
activeUpdateFeature(isEditing) {
this.resetAllTools();
if (isEditing) {
// Mise à jour des entités modifiables
this.drawSource.forEachFeature((feature) => {
if (
(this.featureToEdit && feature.id_ === this.featureToEdit.id) ||
(this.drawnFeature && feature.ol_uid === this.drawnFeature.ol_uid) ||
(!this.drawnFeature && !this.featureToEdit)
) {
this.filteredFeatures.push(feature);
}
});
this.modify.setActive(true);
}
this.toggleEditionColor(isEditing);
},
/**
* Deletes the currently displayed feature from the map.
* This method removes the feature directly from the source without additional selection steps.
* It assumes that there is only one feature present in the source.
* Resets the color for future drawings to the default to ensure that the editing color
* is not displayed if the edit mode was active prior to deletion.
*/
removeFeatureFromMap() {
// Access the source where the features are stored
const source = this.drawSource; // Replace with the correct reference to your OpenLayers source
// Get all features from the source
const features = source.getFeatures();
// Check if there is a feature to delete
if (features.length > 0 && confirm('Etes-vous sur de vouloir supprimer cet objet ?')) {
try {
// Reset all other tools to ensure only the delete feature functionality is active
this.resetAllTools();
// Remove the feature from the source
const featureToRemove = features[0];
source.removeFeature(featureToRemove);
// Reinitialize the feature edited on the map
this.editing_feature = undefined;
// Toggle draw mode to create a new feature
this.draw.setActive(true);
// Reset color to default
this.toggleEditionColor(false);
// Return operation result after user confirmed to remove the feature
return true;
} catch (error) {
// Log an error if the feature cannot be removed
console.error('Error while deleting the feature: ', error);
}
}
return false;
},
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;