import { Controller } from '@hotwired/stimulus';
|
|
import 'leaflet';
|
|
|
|
export default class extends Controller {
|
|
static values = {
|
|
geojson: String,
|
|
overpassResult: String,
|
|
icon: String,
|
|
popupUrl: String,
|
|
}
|
|
|
|
connect() {
|
|
const simpleIcon = L.icon({
|
|
iconUrl: this.iconValue,
|
|
iconSize: [16, 16],
|
|
iconAnchor: [8, 16],
|
|
popupAnchor: [0, 0],
|
|
});
|
|
|
|
const iconHtml = `
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="bi bi-geo-alt-fill" viewBox="0 0 16 16">
|
|
<path fill="currentColor" d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10m0-7a3 3 0 1 1 0-6 3 3 0 0 1 0 6"/>
|
|
</svg>
|
|
`;
|
|
const icons = {
|
|
'danger': L.divIcon({ html: iconHtml, className: 'svg-icon text-danger', iconSize: [16, 16], iconAnchor: [8, 16], }),
|
|
'warning': L.divIcon({ html: iconHtml, className: 'svg-icon text-warning', iconSize: [16, 16], iconAnchor: [8, 16], }),
|
|
'success': L.divIcon({ html: iconHtml, className: 'svg-icon text-success', iconSize: [16, 16], iconAnchor: [8, 16], }),
|
|
'info': L.divIcon({ html: iconHtml, className: 'svg-icon text-info', iconSize: [16, 16], iconAnchor: [8, 16], }),
|
|
};
|
|
|
|
var geojsons, _this = this, map = L.map(this.element);
|
|
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).addTo(map);
|
|
|
|
var layer = L.featureGroup();
|
|
|
|
var layer2 = L.featureGroup();
|
|
if (this.overpassResultValue !== '') {
|
|
geojsons = JSON.parse(this.overpassResultValue);
|
|
if (geojsons.elements.length > 0) {
|
|
geojsons.elements.forEach(function (element) {
|
|
element.members.forEach(function (member) {
|
|
const polygon = L.polyline(member.geometry.map(function (coord) { return L.latLng(coord.lat, coord.lon)}), {
|
|
color: '#0dcaf0',
|
|
weight: 6,
|
|
opacity: 0.8,
|
|
}).addTo(layer2).bindPopup(L.popup({
|
|
overpassElement: element,
|
|
}).setContent('…'));
|
|
});
|
|
});
|
|
layer2.on('popupopen', function (event) {
|
|
var element = event.popup.options.overpassElement;
|
|
delete element.members;
|
|
element['map'] = {
|
|
'center': map.getCenter(),
|
|
'zoom': map.getZoom(),
|
|
};
|
|
fetch(_this.popupUrlValue + '?' + (new URLSearchParams({
|
|
'element': JSON.stringify(element),
|
|
})))
|
|
.then(function (response) {
|
|
return response.text();
|
|
})
|
|
.then(function (text) {
|
|
event.popup.setContent(text);
|
|
});
|
|
});
|
|
layer2.addTo(layer);
|
|
}
|
|
}
|
|
|
|
var layer1 = L.featureGroup();
|
|
geojsons = JSON.parse(this.geojsonValue);
|
|
if (geojsons.length > 0) {
|
|
geojsons.forEach(function (geojson) {
|
|
|
|
const feature0 = geojson.features[0].properties;
|
|
|
|
const polygon = L.geoJSON(geojson, {
|
|
style: function (feature) {
|
|
var color = 'blue';
|
|
switch (feature.properties.color) {
|
|
case 'danger' : color = '#dc3545'; break
|
|
case 'warning' : color = '#ffc107'; break
|
|
case 'success' : color = '#198754'; break
|
|
}
|
|
return {color: color};
|
|
}
|
|
}).bindTooltip(feature0.name).addTo(layer1).on('click', function (event) {
|
|
window.location.href = event.layer.feature.properties.url;
|
|
});
|
|
|
|
L.marker(polygon.getBounds().getCenter(), {
|
|
icon: icons[feature0.color],
|
|
title: feature0.name,
|
|
clickUrl: feature0.url,
|
|
}).addTo(layer1).on('click', function (event) {
|
|
window.location.href = event.target.options.clickUrl;
|
|
});
|
|
|
|
});
|
|
layer1.addTo(layer);
|
|
}
|
|
|
|
layer.addTo(map);
|
|
|
|
if (this.overpassResultValue !== '') {
|
|
L.control.layers({}, {
|
|
'Overpass': layer2,
|
|
'Tâches': layer1,
|
|
}).addTo(map);
|
|
}
|
|
|
|
map.fitBounds(layer1.getBounds());
|
|
}
|
|
}
|