You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
4.6 KiB

2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
  1. import { Controller } from '@hotwired/stimulus';
  2. import 'leaflet';
  3. export default class extends Controller {
  4. static values = {
  5. geojson: String,
  6. overpassResult: String,
  7. icon: String,
  8. popupUrl: String,
  9. }
  10. connect() {
  11. const simpleIcon = L.icon({
  12. iconUrl: this.iconValue,
  13. iconSize: [16, 16],
  14. iconAnchor: [8, 16],
  15. popupAnchor: [0, 0],
  16. });
  17. const iconHtml = `
  18. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="bi bi-geo-alt-fill" viewBox="0 0 16 16">
  19. <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"/>
  20. </svg>
  21. `;
  22. const icons = {
  23. 'danger': L.divIcon({ html: iconHtml, className: 'svg-icon text-danger', iconSize: [16, 16], iconAnchor: [8, 16], }),
  24. 'warning': L.divIcon({ html: iconHtml, className: 'svg-icon text-warning', iconSize: [16, 16], iconAnchor: [8, 16], }),
  25. 'success': L.divIcon({ html: iconHtml, className: 'svg-icon text-success', iconSize: [16, 16], iconAnchor: [8, 16], }),
  26. 'info': L.divIcon({ html: iconHtml, className: 'svg-icon text-info', iconSize: [16, 16], iconAnchor: [8, 16], }),
  27. };
  28. var geojsons, _this = this, map = L.map(this.element);
  29. L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
  30. maxZoom: 19,
  31. attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
  32. }).addTo(map);
  33. var layer = L.featureGroup();
  34. var layer2 = L.featureGroup();
  35. if (this.overpassResultValue !== '') {
  36. geojsons = JSON.parse(this.overpassResultValue);
  37. if (geojsons.elements.length > 0) {
  38. geojsons.elements.forEach(function (element) {
  39. element.members.forEach(function (member) {
  40. const polygon = L.polyline(member.geometry.map(function (coord) { return L.latLng(coord.lat, coord.lon)}), {
  41. color: '#0dcaf0',
  42. weight: 6,
  43. opacity: 0.8,
  44. }).addTo(layer2).bindPopup(L.popup({
  45. overpassElement: element,
  46. }).setContent('…'));
  47. });
  48. });
  49. layer2.on('popupopen', function (event) {
  50. var element = event.popup.options.overpassElement;
  51. delete element.members;
  52. fetch(_this.popupUrlValue + '?' + (new URLSearchParams({
  53. 'element': JSON.stringify(element),
  54. })))
  55. .then(function (response) {
  56. return response.text();
  57. })
  58. .then(function (text) {
  59. event.popup.setContent(text);
  60. });
  61. });
  62. layer2.addTo(layer);
  63. }
  64. }
  65. var layer1 = L.featureGroup();
  66. geojsons = JSON.parse(this.geojsonValue);
  67. if (geojsons.length > 0) {
  68. geojsons.forEach(function (geojson) {
  69. const feature0 = geojson.features[0].properties;
  70. const polygon = L.geoJSON(geojson, {
  71. style: function (feature) {
  72. var color = 'blue';
  73. switch (feature.properties.color) {
  74. case 'danger' : color = '#dc3545'; break
  75. case 'warning' : color = '#ffc107'; break
  76. case 'success' : color = '#198754'; break
  77. }
  78. return {color: color};
  79. }
  80. }).bindTooltip(feature0.name).addTo(layer1).on('click', function (event) {
  81. window.location.href = event.layer.feature.properties.url;
  82. });
  83. L.marker(polygon.getBounds().getCenter(), {
  84. icon: icons[feature0.color],
  85. title: feature0.name,
  86. clickUrl: feature0.url,
  87. }).addTo(layer1).on('click', function (event) {
  88. window.location.href = event.target.options.clickUrl;
  89. });
  90. });
  91. layer1.addTo(layer);
  92. }
  93. layer.addTo(map);
  94. if (this.overpassResultValue !== '') {
  95. L.control.layers({}, {
  96. 'Overpass': layer2,
  97. 'Tâches': layer1,
  98. }).addTo(map);
  99. }
  100. map.fitBounds(layer.getBounds());
  101. }
  102. }