diff --git a/public/views/d.map.html b/public/views/d.map.html index ac03542..443fcda 100755 --- a/public/views/d.map.html +++ b/public/views/d.map.html @@ -32,23 +32,17 @@ var root = ""; // POI icons - window.poi_icons = { - - "": "img/.svg", - - "default": "img/default.svg" - }; - - window.poi_style_map = { - $t) { - $color = isset($t[2]) ? $t[2] : '#ef2929'; - // Read size/shape from structure if provided, else fallback to sensible defaults - $size = isset($t[6]) ? (int)$t[6] : 16; - $shape = isset($t[7]) ? $t[7] : 'square'; - ?> - "": { color: "", size: , shape: "" }, - - }; + window.poi_style_map = { + $t) { + $color = isset($t[2]) ? $t[2] : '#ef2929'; + $size = isset($t[6]) ? (int)$t[6] : 16; + $shape = isset($t[7]) ? $t[7] : 'square'; + $icon = isset($t[3]) ? $config['views_url']."img/".$t[3].".svg" : $config['views_url']."img/default.svg"; + ?> + "": { color: "", size: , shape: "", icon: "" }, + + "default": { color: "#ef2929", size: 16, shape: "square", icon: "img/default.svg" } + }; diff --git a/public/views/d.poi.edit.html b/public/views/d.poi.edit.html index 1ef5f7f..e590dd9 100755 --- a/public/views/d.poi.edit.html +++ b/public/views/d.poi.edit.html @@ -44,16 +44,16 @@
- poi_type == $type[3] ? 'checked' : ''?>> - + poi_type == $type[3] ? 'checked' : ''?>> +
@@ -240,6 +240,19 @@ $( "#name" ).change(function() { var poi_type = "poi_type?>"; var is_new = ; var root = ""; + + // POI icons + window.poi_style_map = { + $t) { + $color = isset($t[2]) ? $t[2] : '#ef2929'; + $size = isset($t[6]) ? (int)$t[6] : 16; + $shape = isset($t[7]) ? $t[7] : 'square'; + $icon = isset($t[3]) ? $config['views_url']."img/".$t[3].".svg" : $config['views_url']."img/default.svg"; + ?> + "": { color: "", size: , shape: "", icon: "" }, + + "default": { color: "#ef2929", size: 16, shape: "square", icon: "img/default.svg" } + }; diff --git a/public/views/d.poi.view.html b/public/views/d.poi.view.html index 0900f12..54b223f 100644 --- a/public/views/d.poi.view.html +++ b/public/views/d.poi.view.html @@ -31,8 +31,8 @@

+ src="views/img/poi_type?>.svg" + alt=""> name?>

@@ -100,25 +100,25 @@ -
-
+
+
- poi_type][5]; - $poiValues = $poi->parameters ?? []; + poi_type][5]; + $poiValues = $poi->parameters ?? []; - // Séparer les booléens des autres champs - $boolFields = []; - $otherFields = []; + // Séparer les booléens des autres champs + $boolFields = []; + $otherFields = []; - foreach ($poiFields as $key => $label) { - if ($key[0] === 'b') { - $boolFields[$key] = $label; - } else { - $otherFields[$key] = $label; - } - } - ?> + foreach ($poiFields as $key => $label) { + if ($key[0] === 'b') { + $boolFields[$key] = $label; + } else { + $otherFields[$key] = $label; + } + } + ?>
@@ -166,13 +166,13 @@ ?>
- $label): ?> - -
-
-
-
- + $label): ?> + +
+
+
+
+
@@ -183,9 +183,9 @@ @@ -212,7 +212,7 @@ @@ -221,9 +221,9 @@ @@ -272,11 +272,11 @@
comment_html?> - photo)) { ?> -
- Photo du commentaire -
- + photo)) { ?> +
+ Photo du commentaire +
+
@@ -300,7 +300,20 @@ var poi_lon = lon?>; var poi_type = "poi_type?>"; var poi_mode = "view"; - var root = ""; + var root = ""; + + // POI icons + window.poi_style_map = { + $t) { + $color = isset($t[2]) ? $t[2] : '#ef2929'; + $size = isset($t[6]) ? (int)$t[6] : 16; + $shape = isset($t[7]) ? $t[7] : 'square'; + $icon = isset($t[3]) ? $config['views_url']."img/".$t[3].".svg" : $config['views_url']."img/default.svg"; + ?> + "": { color: "", size: , shape: "", icon: "" }, + + "default": { color: "#ef2929", size: 16, shape: "square", icon: "img/default.svg" } + }; diff --git a/public/views/js/d.map.js b/public/views/js/d.map.js index 93ba2be..54ca1b8 100755 --- a/public/views/js/d.map.js +++ b/public/views/js/d.map.js @@ -104,7 +104,7 @@ $(document).ready(function() { return L.icon({ iconUrl: iconUrl, iconSize: [size, size], - iconAnchor: [Math.floor(size / 2), size], + iconAnchor: [Math.floor(size / 2), Math.floor(size / 2)], popupAnchor: [0, -size] }); } @@ -251,14 +251,21 @@ $(document).ready(function() { // helper local : construit un L.Icon en fonction du type et du zoom function getMarkerIconFor(type, zoom) { - var size = (zoom > 11) ? 32 : 24; + var baseSize = 16; + if (window.poi_style_map && window.poi_style_map[type] && window.poi_style_map[type].size) { + baseSize = window.poi_style_map[type].size; + } - return L.icon({ - iconUrl: window.poi_icons[type], - iconSize: [size, size], - iconAnchor: [Math.floor(size / 2), size], - popupAnchor: [0, -size] - }); + var size = zoom > 11 + ? Math.round(baseSize * 2) + : Math.round(baseSize * 1.5); + + return L.icon({ + iconUrl: window.poi_style_map[type].icon || window.poi_style_map["default"].icon, + iconSize: [size, size], + iconAnchor: [Math.floor(size / 2), Math.floor(size / 2)], + popupAnchor: [0, -size] + }); } $.getJSON( diff --git a/public/views/js/d.poi_map.js b/public/views/js/d.poi_map.js index 21bd78d..423975a 100755 --- a/public/views/js/d.poi_map.js +++ b/public/views/js/d.poi_map.js @@ -1,40 +1,131 @@ // Carte des POIs et marqueur principal. var mymap; var poi_layer; +var poiApiLayer; $(document).ready(function() { // Mode : edit (formulaire) ou view (affichage) var isEdit = (typeof poi_mode === "undefined" || poi_mode === "edit"); - // Différentes couches pour la carte. + // --------------------------------------------------------- + // Fonds de carte + // --------------------------------------------------------- var topo_maptiler = L.tileLayer( 'https://api.maptiler.com/maps/topographique/{z}/{x}/{y}.png?key=Sm8M7mJ53GtYdl773rpi', { tms: false, - attribution: 'Carte © MapTiler, Données © Contributeurs OpenStreetMap', + attribution: 'Carte © MapTiler, Données © OpenStreetMap', tileSize: 512, zoomOffset: -1, minZoom: 1 } ); + var ign = L.tileLayer( - 'https://data.geopf.fr/private/wmts?&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/jpeg&LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&apikey=ign_scan_ws', + 'https://data.geopf.fr/private/wmts?&REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE=normal&TILEMATRIXSET=PM&FORMAT=image/jpeg&LAYER=GEOGRAPHICALGRIDSYSTEMS.MAPS&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', { attribution: 'Carte & Connées © IGN-F/Géoportail' } ); - // Couches de base. + var baseLayers = { "OpenStreetMap": topo_maptiler, "IGN France": ign }; + // --------------------------------------------------------- + // Carte + // --------------------------------------------------------- mymap = L.map('mapid', { zoomControl: false, - layers: [topo_maptiler] + layers: [topo_maptiler], + minZoom: 10 }).setView([47, 3], 6); + $("#map-credits").html(topo_maptiler.getAttribution()); + // --------------------------------------------------------- + // Icônes / markers issus de poi/api_bbox + // --------------------------------------------------------- + function getMarkerIconFor(type, zoom) { + var baseSize = 16; + if (window.poi_style_map && window.poi_style_map[type] && window.poi_style_map[type].size) { + baseSize = window.poi_style_map[type].size; + } + + var size = zoom > 11 + ? Math.round(baseSize * 2) + : Math.round(baseSize * 1.5); + + return L.icon({ + iconUrl: window.poi_style_map[type].icon || window.poi_style_map["default"].icon, + iconSize: [size, size], + iconAnchor: [Math.floor(size / 2), Math.floor(size / 2)], + popupAnchor: [0, -size] + }); + } + + function refreshPoiApiLayer() { + var b = mymap.getBounds(); + + $.getJSON( + root + "poi/api_bbox", + { + north: b.getNorth(), + south: b.getSouth(), + east: b.getEast(), + west: b.getWest() + }, + function(pois) { + if (poiApiLayer) { + mymap.removeLayer(poiApiLayer); + } + + poiApiLayer = L.layerGroup(); + + const pathParts = window.location.pathname.split('/'); + const poiIndex = pathParts.indexOf('poi'); + const currentPermalink = (poiIndex !== -1 && pathParts[poiIndex + 1]) + ? decodeURIComponent(pathParts[poiIndex + 1]) + : null; + + pois.forEach(function(poi) { + if (currentPermalink && poi.permalink === currentPermalink) { + return; // ne pas afficher le POI courant + } + + var markerIcon = getMarkerIconFor(poi.type, mymap.getZoom()); + + var marker = L.marker( + [poi.lat, poi.lon], + { icon: markerIcon } + ); + + marker.bindTooltip( + poi.name, + { + direction: "top", + offset: [0, -10], + opacity: 0.9, + className: "poi-tooltip" + } + ); + + marker.on("click", function() { + window.location = root + "poi/" + poi.permalink; + }); + + poiApiLayer.addLayer(marker); + }); + + poiApiLayer.addTo(mymap); + } + ); + } + + // --------------------------------------------------------- + // Contrôles + // --------------------------------------------------------- L.control.scale({ position: "bottomleft", imperial: false @@ -70,22 +161,28 @@ $(document).ready(function() { poiicon = L.icon({ iconSize: [24, 24], iconAnchor: [12, 12], - iconUrl: root + "views/img/" + poi_type + ".svg" - }); + iconUrl: root + "views/img/" + poi_type + ".svg" + }); } if (poiicon) { - poi_layer = L.marker([startLat, startLon], {draggable: isEdit, icon: poiicon}).addTo(mymap); + poi_layer = L.marker([startLat, startLon], { draggable: isEdit, icon: poiicon }).addTo(mymap); } else { - poi_layer = L.marker([startLat, startLon], {draggable: isEdit}).addTo(mymap); + poi_layer = L.marker([startLat, startLon], { draggable: isEdit }).addTo(mymap); } if (isEdit) { - // Mise à jour des coordonnées à chaque déplacement. - poi_layer.bindTooltip("Glissez moi au bon endroit.", {permanent: true, direction: 'auto'}).openTooltip(); + poi_layer.bindTooltip("Glissez moi au bon endroit.", { permanent: true, direction: 'auto' }).openTooltip(); } + // Centrage sur la cabane actuelle + if (typeof poi_lat !== "undefined" && typeof poi_lon !== "undefined") { + mymap.setView([poi_lat, poi_lon], 14); + } + + // --------------------------------------------------------- // Interactions uniquement en mode édition + // --------------------------------------------------------- if (isEdit) { mymap.on('click', function(e){ poi_layer.setLatLng(e.latlng); @@ -98,8 +195,7 @@ $(document).ready(function() { $("#elevation_icon").show(); }); - // Si l'utilisateur modifie les champs lat/lon manuellement. - $("#lat,#lon").change(function() { // If the user changes the lat/lon input values manualy + $("#lat,#lon").change(function() { if(isNaN($("#lat").val()) || isNaN($("#lon").val()) || $("#lat").val().length==0 || $("#lon").val()==null) $("#elevation_icon").hide(); else { @@ -119,7 +215,6 @@ $(document).ready(function() { poi_layer.setIcon(editPoiIcon); }); - // Chargement de l'altitude via le proxy. $("#elevation_icon").click(function(e) { $(this).find($(".fas")).removeClass('fa-search-location').addClass('fa-spinner').addClass('fa-spin'); $.get(root+"poi/elevation_proxy", {location:$("#lat").val()+","+$("#lon").val()}, function(result){ @@ -127,10 +222,22 @@ $(document).ready(function() { $("#elevation_icon").find($(".fas")).removeClass('fa-spinner').removeClass('fa-spin').addClass('fa-search-location'); }); }); - } else { - // Mode affichage : centrer sur le POI si coordonnées présentes - if (typeof poi_lat !== "undefined" && typeof poi_lon !== "undefined") { - mymap.setView([poi_lat, poi_lon], 14); - } } -}); + + // --------------------------------------------------------- + // Rechargement du calque depuis poi/api_bbox + // --------------------------------------------------------- + mymap.on("zoomend", function() { + if (mymap.getZoom() >= 10) { + refreshPoiApiLayer(); + } + }); + + mymap.on("moveend", function() { + if (mymap.getZoom() >= 10) { + refreshPoiApiLayer(); + } + }); + + refreshPoiApiLayer(); +}); \ No newline at end of file