diff --git a/assets/controllers/map_controller.js b/assets/controllers/map_controller.js index 868e818..83722eb 100644 --- a/assets/controllers/map_controller.js +++ b/assets/controllers/map_controller.js @@ -51,19 +51,29 @@ export default class extends Controller { if (geojsons.elements.length > 0) { // Ajoute chaque forme geojsons.elements.forEach(function (element) { - element.members.forEach(function (member) { - // TODO On est parti du principe que les features du - // geojson sont toutes des polylines ce qui est un peu - // réducteur, à terme il faudrait distinguer les nœuds, - // des chemins, des polygones, etc. - const polygon = L.polyline(member.geometry.map(function (coord) { return L.latLng(coord.lat, coord.lon)}), { - color: '#0dcaf0', // bleu info bootstrap - weight: 6, // l’idée c’est que ce soit plus gros (par défaut c’est 3) que le tracé des données des tâches parce que ce sera en dessous - opacity: 0.8, + // Cas d’un nœud + if (element.type === 'node') { + L.marker([ element.lat, element.lon ], { + icon: icons['info'], }).addTo(overpassLayer).bindPopup(L.popup({ overpassElement: element, // on transmet les données du geojson à la popup par là }).setContent('…')); // le contenu définitif de la popup sera chargé plus tard en ajax - }); + } + // Cas d’autre chose qu’un nœud, sans distinction + if (element.members) { + element.members.forEach(function (member) { + // TODO On est parti du principe que les features du + // geojson sont toutes des polylines ce qui est un peu + // réducteur, à terme il faudrait distinguer les géométries + const polygon = L.polyline(member.geometry.map(function (coord) { return L.latLng(coord.lat, coord.lon)}), { + color: '#0dcaf0', // bleu info bootstrap + weight: 6, // l’idée c’est que ce soit plus gros (par défaut c’est 3) que le tracé des données des tâches parce que ce sera en dessous + opacity: 0.8, + }).addTo(overpassLayer).bindPopup(L.popup({ + overpassElement: element, // on transmet les données du geojson à la popup par là + }).setContent('…')); // le contenu définitif de la popup sera chargé plus tard en ajax + }); + } }); // Intervient lors de l’ouverture de la popup associée à la forme overpassLayer.on('popupopen', function (event) { @@ -96,42 +106,39 @@ export default class extends Controller { geojsons = JSON.parse(this.geojsonValue); if (geojsons.length > 0) { geojsons.forEach(function (geojson) { - // TODO Ici aussi on ne distingue pas les géométries des - // features mais ça vaudrait peut-être le coup de s’adapter un - // peu à la situation en cas de nœud, chemin ou zone… - - // Par facilité on conserve les propriétés de la première feature pour plus tard - const feature0 = geojson.features[0].properties; - - // Dessine la forme de la tâche avec la proprieté `name` qui - // s’ffiche au survol et cliquable vers l’adresse web dans la - // propriété `url` - const polygon = L.geoJSON(geojson, { - style: function (feature) { - // Par défaut c’est un bleu par défaut de leaflet mais - // sinon on utilise les couleurs de Bootstrap - 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}; + geojson.features.forEach(function (feature) { + // Dessine la forme de la tâche avec la proprieté `name` qui + // s’ffiche au survol et cliquable vers l’adresse web dans la + // propriété `url` + if (feature.geometry.type === 'Point') { + L.marker([ + feature.geometry.coordinates[1], + feature.geometry.coordinates[0], + ], { + icon: icons[feature.properties.color], + title: feature.properties.name, + clickUrl: feature.properties.url, + }).addTo(taskLayer).on('click', function (event) { + window.location.href = event.target.options.clickUrl; + }); + } else { + const polygon = L.geoJSON(feature, { + style: function (feature) { + // Par défaut c’est un bleu par défaut de leaflet mais + // sinon on utilise les couleurs de Bootstrap + 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(feature.properties.name).addTo(taskLayer).on('click', function (event) { + window.location.href = event.layer.feature.properties.url; + }); } - }).bindTooltip(feature0.name).addTo(taskLayer).on('click', function (event) { - window.location.href = event.layer.feature.properties.url; }); - - // Ajoute un marqueur au centroïde de la forme (car les - // marqueurs gardent la même taille quelque-soit le zoom - L.marker(polygon.getBounds().getCenter(), { - icon: icons[feature0.color], - title: feature0.name, - clickUrl: feature0.url, - }).addTo(taskLayer).on('click', function (event) { - window.location.href = event.target.options.clickUrl; - }); - }); taskLayer.addTo(layer); } diff --git a/src/Controller/MapController.php b/src/Controller/MapController.php index 346fb45..986e2e6 100644 --- a/src/Controller/MapController.php +++ b/src/Controller/MapController.php @@ -22,14 +22,19 @@ class MapController extends AbstractController 'imagery' => [ 'id' => 'osmfr', ], - 'load_and_zoom' => [ + ]; + + // TODO dans le cas d’un nœud il n’y a pas de bounds mais on doit + // pouvoir trouver les coins d’une bbox autour sans trop de difficultés + if (isset($element['bounds'])) { + $josmCommands['load_and_zoom'] = [ 'bottom' => $element['bounds']['minlat'], 'top' => $element['bounds']['maxlat'], 'left' => $element['bounds']['minlon'], 'right' => $element['bounds']['maxlon'], 'select' => sprintf('%s%d', $element['type'], $element['id']), - ], - ]; + ]; + } return $this->render('partials/_overpass-element-popup.html.twig', [ 'element' => $element, diff --git a/src/Controller/ProjectController.php b/src/Controller/ProjectController.php index af38bf3..91bf17d 100644 --- a/src/Controller/ProjectController.php +++ b/src/Controller/ProjectController.php @@ -119,7 +119,7 @@ class ProjectController extends AbstractController $task->setName($row[$col['name']]); $task->setDescription($row[$col['description']]); $task->setOsm($row[$col['osm']]); - $task->setGeojson(json_decode($row[$col['geojson']], true)); + $task->setGeojson($row[$col['geojson']]); if (isset($row[$col['status']]) and in_array($row[$col['status']], [ Task::STATUS_TODO, Task::STATUS_DOING, diff --git a/src/Service/GeoJsonManager.php b/src/Service/GeoJsonManager.php index a611ba1..806fb03 100644 --- a/src/Service/GeoJsonManager.php +++ b/src/Service/GeoJsonManager.php @@ -34,10 +34,7 @@ class GeoJsonManager } foreach ($data['features'] as $index => $feature) { - if (!isset($feature['properties'])) { - continue; - } - $feature['properties'] = array_merge($feature['properties'], [ + $feature['properties'] = array_merge(!isset($feature['properties']) ? [] : $feature['properties'], [ 'name' => $task->getName(), 'url' => $this->router->generate('app_task_show', ['slug' => $task->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL), 'color' => $this->taskLifecycleStateMachine->getMetadataStore()->getPlaceMetadata($task->getStatus())['color'],