Exercices Outils dessin
Exercice - Dessin, Modification, Export#
Notre objectif est de créer une interface de dessin de polygone, avec un mode édition, et la possiblité d’exporter/importer nos formes. Nous allons utiliser OpenLayers. Pour Leaflet, ce n’est pas natif, mais c’est le plugin Leaflet Draw
- Dans une carte OpenLayers
- Créez une nouvelle couche + source vectorielle, vide
- Ajoutez une interaction de dessin à la carte
ol.interaction.Draw
, type Polygon, basée sur notre sourcemap.addInteraction()
- Ajoutez ensuite deux nouvelles interactions (
Modify
etSnap
), après celle de dessin - Remarquez qu’OpenLayers gère déjà une grande partie de comportements (création de point, modification, dessin à main levée, etc.)
Ensuite, pour la partie export :
- Ajoutez en HTML un bouton pour télécharger (et le CSS associé)
<div id="tools">
<a id="download" download="features.json">Download</a>
</div>
#tools {
position: absolute;
top: 1rem;
right: 1rem;
}
#tools a {
display: inline-block;
padding: 0.5rem;
background: white;
cursor: pointer;
}
Nous devons maintenant modifier le href
de cet objet lorsque la source change. Pour cela :
- Ajoutez un événement
change
sur la source - Récupérez les features de la source et convertissez-les en geoJSON
source.getFeatures()
format.writeFeatures(features)
- Modifiez le
href
en créant une URL de données (data URL)download.href = "data:application/json;charset=utf-8," + encodeURIComponent(json);
Pour l’import :
- Ajoutez une nouvelle interaction (
ol.interaction.DragAndDrop
), toujours sur la même source - Précisez le format attendu (
formatConstructors: [ol.format.GeoJSON]
)
Si l’on souhaite ajouter un contrôle pour activer le dessin, il faut :
- le créer sous forme de classe
- l’ajouter à la carte (avec le CSS correspondant)
- ajouter/supprimer les interactions lors du click
class DrawControl extends ol.control.Control {
constructor() {
const button = document.createElement('button');
button.innerHTML = '⭓';
const element = document.createElement('div');
element.className = 'draw-control ol-unselectable ol-control';
element.appendChild(button);
super({
element: element,
});
this.active = false;
button.addEventListener('click', () => this.click());
}
click() {
this.active = !this.active;
if (this.active) {
map.addInteraction(modifyInteraction);
map.addInteraction(drawInteraction);
map.addInteraction(snapInteraction);
this.element.classList.add('is-active');
} else {
map.removeInteraction(modifyInteraction);
map.removeInteraction(drawInteraction);
map.removeInteraction(snapInteraction);
this.element.classList.remove('is-active');
}
}
}
let map = new ol.Map({
...
controls: ol.control.defaults.defaults().extend([
new DrawControl()
])
});
.draw-control {
top: 65px;
left: 0.5em;
}
.is-active button,
.is-active button:hover,
.is-active button:focus {
background: mediumblue;
color: #fff;
}