🎨 displace search to top

This commit is contained in:
Tykayn 2025-04-18 17:53:07 +02:00 committed by tykayn
parent e0a042c28b
commit b30985b581
7 changed files with 581 additions and 291 deletions

View file

@ -1,5 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang='fr'> <html lang='fr'>
<head> <head>
<title>LibreChargeMap - OSM Bliss</title> <title>LibreChargeMap - OSM Bliss</title>
<meta charset='utf-8'> <meta charset='utf-8'>
@ -11,29 +12,29 @@
<meta property="og:image:width" content="3436"> <meta property="og:image:width" content="3436">
<meta property="og:image:height" content="1086"> <meta property="og:image:height" content="1086">
<meta <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'>
name='viewport' <link rel='stylesheet' href='styles/leaflet.css' />
content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'> <link rel="stylesheet" href="https://unpkg.com/leaflet-geosearch@3.1.0/dist/geosearch.css" />
<link <link rel='stylesheet' href='styles/style.css' />
rel='stylesheet'
href='styles/leaflet.css'/>
<link rel="stylesheet" href="https://unpkg.com/leaflet-geosearch@3.1.0/dist/geosearch.css"/>
<link
rel='stylesheet'
href='styles/style.css'/>
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=yes, minimum-scale=0.25, maximum-scale=5.0"> content="width=device-width, initial-scale=1.0, user-scalable=yes, minimum-scale=0.25, maximum-scale=5.0">
<link rel="shortcut icon" href="img/french.png"> <link rel="shortcut icon" href="img/french.png">
</head> </head>
<body class="side-panel-open"> <body class="side-panel-open">
<div id="bars_power">
<header> </div>
<header>
<h1> <h1>
<img class="icon-img" src="img/prise-de-courant.png" alt="prise"> Libre Charge Map <img class="icon-img" src="img/prise-de-courant.png" alt="prise"> Libre Charge Map
</h1> </h1>
</header> </header>
<main>
<main>
<button id="toggleSidePanel"> <button id="toggleSidePanel">
@ -43,20 +44,11 @@
</div> </div>
<div class="research_display"> <div class="research_display">
<div id='spinning_icon'> <div id='spinning_icon'>
<svg <svg id='star' width='4cm' height='4cm' viewBox='0 0 700 400' xmlns='http://www.w3.org/2000/svg'
id='star'
width='4cm'
height='4cm'
viewBox='0 0 700 400'
xmlns='http://www.w3.org/2000/svg'
version='1.1'> version='1.1'>
<polygon <polygon fill='red' stroke='red' stroke-width='10' points='350,75 379,161 469,161 397,215
fill='red'
stroke='red'
stroke-width='10'
points='350,75 379,161 469,161 397,215
423,301 350,250 277,301 303,215 423,301 350,250 277,301 303,215
231,161 321,161'/> 231,161 321,161' />
</svg> </svg>
</div> </div>
@ -73,11 +65,18 @@
</div> </div>
</div> </div>
</main> </main>
<div class="side-panel">
<div class="side-panel">
<form onclick="searchLocation()">
<!-- <fieldset>-->
<input type="text" id="searchLocation" placeholder="Rechercher un lieu" class="search-input">
<button id="searchButton" class="rounded-button">🔍 Rechercher</button>
<select id="searchResults" class="search-results" size="5" style="display: none;"></select>
<!-- </fieldset>-->
</form>
<div id="bars_power">
</div>
<div id="round_power_legend"> <div id="round_power_legend">
<br> <br>
<span class="marker-demo"> <span class="marker-demo">
@ -105,36 +104,9 @@
<p>Cartes des stations de recharge pour véhicules électriques basée sur les données collaborative <a <p>Cartes des stations de recharge pour véhicules électriques basée sur les données collaborative <a
href="https://openstreetmap.org">OpenStreetMap</a></p> href="https://openstreetmap.org">OpenStreetMap</a></p>
<form onclick="searchLocation()">
<!-- <fieldset>-->
<input type="text" id="searchLocation" placeholder="Rechercher un lieu" class="search-input">
<button id="searchButton" class="rounded-button">🔍 Rechercher</button>
<select id="searchResults" class="search-results" size="5" style="display: none;"></select>
<!-- </fieldset>-->
</form>
<div class="filters-box">
<button id="removeMarkers" class="rounded-button">
🗑️ Effacer les marqueurs
</button>
<button id="chercherButton" class="rounded-button">
🔄 Recharger
</button>
<button id="setRandomView" class="rounded-button">
🎲 Une ville au hasard
</button>
<button id="sendToJOSM" class="rounded-button">
🗺️ Éditer dans JOSM
</button>
<button id="shareUrl" class="rounded-button">
📤 Partager l'URL
</button>
<!-- <button id="toggle">-->
<!-- toggle : montrer les stations avec à minima 150kW de puissance dispo-->
<!-- </button>-->
</div>
<div id="current_station_infos"></div> <div id="current_station_infos"></div>
<div id="infos_carte"></div> <div id="infos_carte"></div>
@ -156,19 +128,20 @@
<button id="cableMissing">sans information de câble</button> <button id="cableMissing">sans information de câble</button>
<i class="info"> <i class="info">
<span class="i">i</span> <span class="i">i</span>
<span class="tooltip">mettre un marqueur aux stations qui n'ont pas d'information de câble</span> <span class="tooltip">mettre un marqueur aux stations qui n'ont pas d'information de
câble</span>
</i> </i>
</fieldset> </fieldset>
<!-- <button id="filterChelou">les valeurs chelou</button>--> <!-- <button id="filterChelou">les valeurs chelou</button>-->
</div> </div>
<!-- TODO add more filters--> <!-- TODO add more filters-->
<!-- <div class="filter-group">--> <!-- <div class="filter-group">-->
<!-- prise:--> <!-- prise:-->
<!-- <button id="filterType2">type 2</button>--> <!-- <button id="filterType2">type 2</button>-->
<!-- <button id="filterType2_cable">type 2 avec câble</button>--> <!-- <button id="filterType2_cable">type 2 avec câble</button>-->
<!-- <button id="filterType2_combo">type CCS</button>--> <!-- <button id="filterType2_combo">type CCS</button>-->
<!-- <button id="filterType2_combo_cable">type CCS avec câble</button>--> <!-- <button id="filterType2_combo_cable">type CCS avec câble</button>-->
<!-- </div>--> <!-- </div>-->
<!-- <div class="filter-group">--> <!-- <div class="filter-group">-->
<!-- puissance:--> <!-- puissance:-->
<!-- <button id="filterLower50kw">- de 50kW</button>--> <!-- <button id="filterLower50kw">- de 50kW</button>-->
@ -200,13 +173,15 @@
À propos de ce plan</h2> À propos de ce plan</h2>
<p> <p>
La carte thématique proposant des points de charge pour véhicule électrique, basée sur les données La carte thématique proposant des points de charge pour véhicule électrique, basée sur les données
d'OpenStreetMap. Voir la documentation OSM concernant <a href="https://wiki.openstreetmap.org/wiki/Key:socket:*">les sockets</a> et les d'OpenStreetMap. Voir la documentation OSM concernant <a
href="https://wiki.openstreetmap.org/wiki/Key:socket:*">les sockets</a> et les
<a href="https://wiki.openstreetmap.org/wiki/FR:Tag:amenity%3Dcharging_station"> <a href="https://wiki.openstreetmap.org/wiki/FR:Tag:amenity%3Dcharging_station">
stations de recharge pour véhicules électriques stations de recharge pour véhicules électriques
</a>. </a>.
</p> </p>
<br> <br>
Fait par <a href="https://mastodon.cipherbliss.com/@tykayn">Tykayn</a> - <a href="https://www.cipherbliss.com">www.cipherbliss.com</a>. Fait par <a href="https://mastodon.cipherbliss.com/@tykayn">Tykayn</a> - <a
href="https://www.cipherbliss.com">www.cipherbliss.com</a>.
<a href="https://forge.chapril.org/tykayn/">Sources disponibles sur la forge du Chapril.</a> <a href="https://forge.chapril.org/tykayn/">Sources disponibles sur la forge du Chapril.</a>
<div class="icones"> <div class="icones">
<img class="icon-img" src="img/Type2_Connector_Outline.svg" alt="type2"> <img class="icon-img" src="img/Type2_Connector_Outline.svg" alt="type2">
@ -221,19 +196,48 @@
câble électrique <a href="https://www.flaticon.com/fr/icones-gratuites/energie" title="energie icônes">Energie câble électrique <a href="https://www.flaticon.com/fr/icones-gratuites/energie" title="energie icônes">Energie
icônes créées par rukanicon - Flaticon</a> icônes créées par rukanicon - Flaticon</a>
</div> </div>
<script src='js/leaflet.js'></script>
<script src='js/jquery-3.2.1.min.js'></script>
<script src="https://unpkg.com/leaflet-geosearch@3.1.0/dist/bundle.min.js"></script>
<script src='js/osmtogeojson.js'></script>
<script
type='module'
src='js/lcm_main.js'></script>
<script>
</script> <div class="filters-box">
<button id="removeMarkers" class="rounded-button" title="Effacer les marqueurs">
🗑️
<!-- Effacer les marqueurs -->
</button>
<button id="chercherButton" class="rounded-button" title="Recharger">
🔄
<!-- Recharger -->
</button>
<button id="setRandomView" class="rounded-button" title="Une ville au hasard">
🎲
<!-- Une ville au hasard -->
</button>
<button id="sendToJOSM" class="rounded-button" title="Éditer dans JOSM">
🗺️
<!-- Éditer dans JOSM -->
</button>
<button id="shareUrl" class="rounded-button" title="Partager l'URL">
📤
<!-- Partager l'URL -->
</button>
<!-- <button id="toggle">-->
<!-- toggle : montrer les stations avec à minima 150kW de puissance dispo-->
<!-- </button>-->
</div>
<script src='js/leaflet.js'></script>
<script src='js/jquery-3.2.1.min.js'></script>
<script src="https://unpkg.com/leaflet-geosearch@3.1.0/dist/bundle.min.js"></script>
<script src='js/osmtogeojson.js'></script>
<script type='module' src='js/lcm_main.js'></script>
<script>
</script>
</body> </body>
</html> </html>

View file

@ -1,15 +1,18 @@
const lcm_config = { const lcm_config = {
osmMention:'&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors', osmMention: '&copy; <a href="https://openstreetmap.org/copyright">OpenStreetMap</a> contributors',
showHighPower : true, showHighPower: true,
overrideQuery : true, overrideQuery: true,
initialZoom : 12, initialZoom: 12,
max_possible_station_output : 400, hide_osmose_markers_if_close_to_existing_charging_stations: true,
tileServers:{ hide_osmose_markers_if_close_to_existing_charging_stations_distance: 5, // meters
osm : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
cycle : 'https://{s}.tile.thunderforest.org/cycle/{z}/{x}/{y}.png', max_possible_station_output: 400,
cartodb : 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png', tileServers: {
stamen : 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', osm: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
transport : 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png' cycle: 'https://{s}.tile.thunderforest.org/cycle/{z}/{x}/{y}.png',
cartodb: 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png',
stamen: 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
transport: 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png'
}, },
tags_to_display_in_popup: [ tags_to_display_in_popup: [
'description', 'description',

View file

@ -11,6 +11,9 @@ import { sendToJOSM, createJOSMEditLink } from './lcm_editor.js'
let geojsondata; let geojsondata;
let lastLatLng; let lastLatLng;
let searchLocationMarker = null;
// serveurs de tuiles: https://wiki.openstreetmap.org/wiki/Tile_servers // serveurs de tuiles: https://wiki.openstreetmap.org/wiki/Tile_servers
// https://stamen-tiles.a.ssl.fastly.net/toner/{z}/{x}/{y}.png // https://stamen-tiles.a.ssl.fastly.net/toner/{z}/{x}/{y}.png
@ -49,6 +52,164 @@ let display_higer_than_200kw = 'show';
let display_chelou = 'show'; // les stations avec une valeur suspecte, plus de 400kW let display_chelou = 'show'; // les stations avec une valeur suspecte, plus de 400kW
// Ajouter cette fonction avant searchLocation
function moveToLocation(place) {
const lat = parseFloat(place.lat);
const lon = parseFloat(place.lon);
if (isNaN(lat) || isNaN(lon)) {
console.error('Coordonnées invalides:', place);
return;
}
// Supprimer l'ancien marqueur s'il existe
if (searchLocationMarker) {
map.removeLayer(searchLocationMarker);
}
// Créer un nouveau marqueur avec une icône personnalisée
searchLocationMarker = L.marker([lat, lon], {
icon: L.divIcon({
className: 'search-location-marker',
html: '📍',
iconSize: [30, 30],
iconAnchor: [15, 30]
})
});
// Ajouter un popup avec le nom du lieu
const popupContent = `
<strong>${place.display_name}</strong>
${place.type ? `<br>Type: ${place.type}` : ''}
${place.context ? `<br>${place.context}` : ''}
`;
searchLocationMarker.bindPopup(popupContent);
// Ajouter le marqueur à la carte
searchLocationMarker.addTo(map);
// Centrer la carte sur le lieu
map.setView([lat, lon], map.getZoom());
// Ouvrir le popup automatiquement
searchLocationMarker.openPopup();
// Faire disparaître le marqueur après 10 secondes
// setTimeout(() => {
// if (searchLocationMarker) {
// map.removeLayer(searchLocationMarker);
// searchLocationMarker = null;
// }
// }, 10000);
}
// Déplacer searchLocationWithAddok avant searchLocation
function searchLocationWithAddok(searchText, mapCenter) {
const baseUrl = 'https://demo.addok.xyz/search';
const params = new URLSearchParams({
q: searchText,
limit: 10,
lat: mapCenter.lat,
lon: mapCenter.lng
});
const url = `${baseUrl}?${params.toString()}`;
return fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Erreur réseau lors de la recherche');
}
return response.json();
})
.then(data => {
if (!data.features || data.features.length === 0) {
throw new Error('Aucun résultat trouvé');
}
return data.features.map(feature => ({
lat: feature.geometry.coordinates[1],
lon: feature.geometry.coordinates[0],
display_name: feature.properties.label,
importance: feature.properties.score,
context: feature.properties.context,
type: feature.properties.type,
city: feature.properties.city,
distance: feature.properties.distance
}));
});
}
// Modifier la fonction searchLocation
function searchLocation() {
const location = $('#searchLocation').val();
if (!location) {
alert('Veuillez entrer un lieu à rechercher.');
return;
}
const useAddok = $('#useAddok').is(':checked');
const searchPromise = useAddok
? searchLocationWithAddok(location, map.getCenter())
: fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(location)}`)
.then(response => response.json());
searchPromise
.then(data => {
const resultsDropdown = $('#searchResults');
resultsDropdown.empty();
if (!data || data.length === 0) {
alert('Lieu non trouvé. Veuillez essayer un autre terme de recherche.');
resultsDropdown.hide();
return;
}
// Toujours sélectionner le premier résultat
moveToLocation(data[0]);
// Si il y a plus d'un résultat, les afficher quand même dans la liste
if (data.length > 1) {
// Ajouter le bouton de fermeture avant la liste des résultats
const closeButton = $('<button>')
.addClass('close-results-button')
.html('❌')
.attr('title', 'Fermer les résultats de recherche')
.on('click', function () {
$('#searchResults').hide();
$(this).hide();
$('#searchLocation').val('').focus();
});
resultsDropdown.before(closeButton);
data.forEach((place, index) => {
let displayText = place.display_name;
if (useAddok && place.distance) {
displayText += ` (${Math.round(place.distance)}m)`;
}
const option = $('<option></option>')
.val(index)
.text(displayText)
.data('place', place);
resultsDropdown.append(option);
});
resultsDropdown.show();
closeButton.show();
// Sélectionner visuellement le premier résultat dans la liste
resultsDropdown.val(0);
} else {
resultsDropdown.hide();
}
})
.catch(error => {
console.error('Erreur lors de la recherche du lieu :', error);
alert('Erreur lors de la recherche du lieu : ' + error.message);
});
}
function setRandomView() { function setRandomView() {
let randomCity = lcm_utils.cities[Math.floor(Math.random() * lcm_utils.cities.length)]; let randomCity = lcm_utils.cities[Math.floor(Math.random() * lcm_utils.cities.length)];
map = map.setView(randomCity.coords, lcm_config.initialZoom); map = map.setView(randomCity.coords, lcm_config.initialZoom);
@ -104,10 +265,22 @@ let stamen =
L.tileLayer(lcm_config.tileServers.stamen, { L.tileLayer(lcm_config.tileServers.stamen, {
attribution: lcm_config.osmMention attribution: lcm_config.osmMention
}) })
// Ajouter après les autres déclarations de tileLayer
let bdortho = L.tileLayer('https://wxs.ign.fr/ortho/geoportail/wmts?' +
'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTHOIMAGERY.ORTHOPHOTOS' +
'&STYLE=normal&FORMAT=image/jpeg&TILEMATRIXSET=PM&' +
'TILEMATRIX={z}&TILEROW={y}&TILECOL={x}', {
attribution: '&copy; <a href="https://geoservices.ign.fr/bdortho">IGN-F/Géoportail</a>',
maxZoom: 19
});
// Modifier la définition de baseLayers pour inclure la BD ORTHO
var baseLayers = { var baseLayers = {
'Grey': tileGrey, 'Grey': tileGrey,
'Stamen': stamen, 'Stamen': stamen,
'OpenStreetMap': osm, 'OpenStreetMap': osm,
'BD ORTHO IGN': bdortho,
// 'OpenCycleMap': cycle, // 'OpenCycleMap': cycle,
'Transport': transport 'Transport': transport
} }
@ -669,6 +842,7 @@ function onMapMoveEnd() {
// Calculer la distance en km entre l'ancienne et la nouvelle position // Calculer la distance en km entre l'ancienne et la nouvelle position
const distanceKm = map.distance(center, window.lastKnownPosition) / 1000; const distanceKm = map.distance(center, window.lastKnownPosition) / 1000;
console.log('déplacement de ', distanceKm, 'km')
// Ne mettre à jour que si on s'est déplacé de plus de 2km // Ne mettre à jour que si on s'est déplacé de plus de 2km
if (distanceKm > 2) { if (distanceKm > 2) {
window.lastKnownPosition = center; window.lastKnownPosition = center;
@ -679,7 +853,7 @@ function onMapMoveEnd() {
// Ajout d'un log pour déboguer // Ajout d'un log pour déboguer
console.log("Zoom actuel:", map.getZoom()); console.log("Zoom actuel:", map.getZoom());
if (map.getZoom() > 12) { if (map.getZoom() >= 12) {
console.log("Recherche des issues Osmose..."); console.log("Recherche des issues Osmose...");
searchOsmoseIssues(map); searchOsmoseIssues(map);
} else { } else {
@ -854,19 +1028,42 @@ const osmoseIcon = L.divIcon({
iconAnchor: [15, 40] iconAnchor: [15, 40]
}); });
// Ajouter cette nouvelle fonction // Ajouter cette fonction utilitaire pour calculer la distance entre deux points
function calculateDistance(lat1, lon1, lat2, lon2) {
return L.latLng(lat1, lon1).distanceTo([lat2, lon2]);
}
// Ajouter cette fonction pour vérifier si le calque des stations est actif
function isChargingStationLayerActive() {
return map.hasLayer(all_stations_markers);
}
// Modifier la fonction searchOsmoseIssues
function searchOsmoseIssues(map) { function searchOsmoseIssues(map) {
const bounds = map.getBounds(); const bounds = map.getBounds();
const zoom = map.getZoom(); const zoom = map.getZoom();
// Construction de la bbox avec l'ordre correct : ouest,sud,est,nord
const bbox = `${bounds.getWest()}%2C${bounds.getSouth()}%2C${bounds.getEast()}%2C${bounds.getNorth()}`; const bbox = `${bounds.getWest()}%2C${bounds.getSouth()}%2C${bounds.getEast()}%2C${bounds.getNorth()}`;
// URL formatée selon l'exemple fourni
const url = `https://osmose.openstreetmap.fr/api/0.3/issues?zoom=${zoom}&item=8410%2C8411&level=1%2C2%2C3&limit=500&bbox=${bbox}`; const url = `https://osmose.openstreetmap.fr/api/0.3/issues?zoom=${zoom}&item=8410%2C8411&level=1%2C2%2C3&limit=500&bbox=${bbox}`;
console.log("Recherche des issues Osmose (liste) avec l'URL :", url); console.log("Recherche des issues Osmose (liste) avec l'URL :", url);
osmose_markers.clearLayers(); osmose_markers.clearLayers();
// Modifier la vérification des stations existantes
const existingStations = [];
if (lcm_config.hide_osmose_markers_if_close_to_existing_charging_stations &&
isChargingStationLayerActive() && // Nouvelle condition
geojsondata &&
geojsondata.features) {
geojsondata.features.forEach(feature => {
if (feature.geometry && feature.geometry.coordinates) {
existingStations.push({
lat: feature.geometry.coordinates[1],
lon: feature.geometry.coordinates[0]
});
}
});
}
fetch(url) fetch(url)
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
@ -883,22 +1080,27 @@ function searchOsmoseIssues(map) {
console.log(`Nombre d'issues Osmose (liste) trouvées: ${issuesList.length}`); console.log(`Nombre d'issues Osmose (liste) trouvées: ${issuesList.length}`);
issuesList.forEach(issueInfo => { issuesList.forEach(issueInfo => {
// Vérifier si les coordonnées sont valides if (issueInfo.lat == null || issueInfo.lon == null || !issueInfo.id) {
if (issueInfo.lat == null || issueInfo.lon == null) { return;
console.warn("Issue Osmose sans coordonnées ignorée:", issueInfo);
return; // Ignorer cette issue
} }
const lat = parseFloat(issueInfo.lat); const lat = parseFloat(issueInfo.lat);
const lon = parseFloat(issueInfo.lon); const lon = parseFloat(issueInfo.lon);
const issueId = issueInfo.id; // C'est l'UUID
// Vérifier si l'UUID est valide // Vérifier la distance avec les stations existantes
if (!issueId) { if (lcm_config.hide_osmose_markers_if_close_to_existing_charging_stations) {
console.warn("Issue Osmose sans ID (UUID) ignorée:", issueInfo); const tooClose = existingStations.some(station => {
const distance = calculateDistance(lat, lon, station.lat, station.lon);
return distance <= lcm_config.hide_osmose_markers_if_close_to_existing_charging_stations_distance;
});
if (tooClose) {
console.log(`Marqueur Osmose ignoré car trop proche d'une station existante: ${lat},${lon}`);
return; return;
} }
}
// Créer le marqueur Osmose si il n'est pas trop proche d'une station existante
const osmoseMarker = L.circle([lat, lon], { const osmoseMarker = L.circle([lat, lon], {
color: "purple", color: "purple",
fillColor: "purple", fillColor: "purple",
@ -906,7 +1108,7 @@ function searchOsmoseIssues(map) {
radius: 10, radius: 10,
className: 'leaflet-osmose-layer', className: 'leaflet-osmose-layer',
pane: 'markerPane', pane: 'markerPane',
issueId: issueId issueId: issueInfo.id
}); });
// Préparer une popup de chargement simple // Préparer une popup de chargement simple
@ -916,8 +1118,7 @@ function searchOsmoseIssues(map) {
const clickedMarker = e.target; const clickedMarker = e.target;
const storedIssueId = clickedMarker.options.issueId; const storedIssueId = clickedMarker.options.issueId;
// Afficher immédiatement la popup de chargement handleMarkerClick(clickedMarker, map); // Nouvelle gestion du clic
clickedMarker.openPopup();
const detailUrl = `https://osmose.openstreetmap.fr/api/0.3/issue/${storedIssueId}?langs=auto`; const detailUrl = `https://osmose.openstreetmap.fr/api/0.3/issue/${storedIssueId}?langs=auto`;
console.log("Récupération des détails pour l'issue:", detailUrl); console.log("Récupération des détails pour l'issue:", detailUrl);
@ -978,9 +1179,39 @@ function searchOsmoseIssues(map) {
}); });
} }
// Modifier la fonction init pour ajouter le nouveau calque // Modifier la gestion du clic sur les marqueurs Osmose
function init() { function handleMarkerClick(marker, map) {
const popup = marker.getPopup();
const markerLatLng = marker.getLatLng();
// Calculer la position relative du marqueur dans la vue
const markerPoint = map.latLngToContainerPoint(markerLatLng);
const mapHeight = map.getContainer().clientHeight;
// Si le marqueur est dans la moitié supérieure de l'écran
if (markerPoint.y < mapHeight / 2) {
// Calculer le décalage nécessaire pour centrer la popup
const targetLatLng = map.containerPointToLatLng([
markerPoint.x,
mapHeight / 2
]);
// Déplacer la carte avec une animation
map.once('moveend', () => {
marker.openPopup();
});
map.panTo(targetLatLng, {
animate: true,
duration: 0.5
});
} else {
marker.openPopup();
}
}
// Ajouter un écouteur d'événements pour le changement de visibilité des calques
function init() {
food_places_markers.addTo(map); food_places_markers.addTo(map);
$('#found_charging_stations').hide(); $('#found_charging_stations').hide();
@ -991,8 +1222,18 @@ function init() {
"Bornes potentielles (Osmose)": osmose_markers "Bornes potentielles (Osmose)": osmose_markers
}; };
L.control.layers(null, overlayMaps).addTo(map); // Créer deux contrôles de couches séparés
const baseLayerControl = L.control.layers(baseLayers, null, {
collapsed: true,
className: 'leaflet-control-layers base-layers',
id: 'base-layers-control'
}).addTo(map);
const overlayControl = L.control.layers(null, overlayMaps, {
collapsed: true,
className: 'leaflet-control-layers overlay-layers',
id: 'overlay-layers-control'
}).addTo(map);
$('#sendToJOSM').on('click', () => { $('#sendToJOSM').on('click', () => {
sendToJOSM(map, geojsondata) sendToJOSM(map, geojsondata)
@ -1025,9 +1266,25 @@ function init() {
} }
}); });
document.getElementById('searchButton').addEventListener('click', searchLocation);
osmose_markers.addTo(map); osmose_markers.addTo(map);
// Ajouter le contrôle de source de recherche
const searchControl = `
<div class="search-source-control">
<label>
<input type="checkbox" id="useAddok" checked>
Utiliser Addok (France)
</label>
</div>
`;
$('#searchLocation').after(searchControl);
// Mettre à jour les marqueurs Osmose quand la visibilité des stations change
map.on('overlayremove overlayadd', function (e) {
if (e.name === "Stations de recharge" && map.getZoom() > 12) {
searchOsmoseIssues(map);
}
});
} }
@ -1045,51 +1302,6 @@ function copyCurrentUrl() {
function searchLocation() {
const location = $('#searchLocation').val();
if (!location) {
alert('Veuillez entrer un lieu à rechercher.');
return;
}
const url = `https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(location)}`;
fetch(url)
.then(response => response.json())
.then(data => {
const resultsDropdown = $('#searchResults');
resultsDropdown.empty(); // Clear previous results
if (data.length === 0) {
alert('Lieu non trouvé. Veuillez essayer un autre terme de recherche.');
resultsDropdown.hide();
} else if (data.length === 1) {
const place = data[0];
moveToLocation(place);
resultsDropdown.hide();
} else {
data.forEach((place, index) => {
const option = $('<option></option>')
.val(index)
.text(`${place.display_name} (${place.lat}, ${place.lon})`);
resultsDropdown.append(option);
});
resultsDropdown.show();
}
})
.catch(error => {
console.error('Erreur lors de la recherche du lieu :', error);
alert('Erreur lors de la recherche du lieu.');
});
}
function moveToLocation(place) {
const lat = parseFloat(place.lat);
const lon = parseFloat(place.lon);
map.setView([lat, lon], 13); // Ajustez le niveau de zoom selon vos besoins
}
init() init()
// Créer un nouveau pane pour les marqueurs Osmose avec un zIndex plus élevé // Créer un nouveau pane pour les marqueurs Osmose avec un zIndex plus élevé

BIN
styles/images/layers-2x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View file

@ -154,7 +154,7 @@ img.leaflet-marker-icon.tag-socket\:type2_yes {
} }
.side-panel button { .side-panel button {
min-width: 15em; min-width: 2em;
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
@ -356,11 +356,6 @@ button {
background: white; background: white;
} }
#bars_power {
margin: 1rem 0;
height: 3rem;
}
.bar { .bar {
height: 2em; height: 2em;
text-align: right; text-align: right;
@ -582,13 +577,14 @@ header {
} }
.filters-box { .filters-box {
margin-top: 4rem; position: absolute;
height: 10rem; bottom: 0.7rem;
width: auto; right: 25vw;
z-index: 100;
.rounded-button { .rounded-button {
margin-right: 1rem; margin-right: 0.5rem;
margin-bottom: 1rem; margin-bottom: 0.5rem;
} }
} }
@ -652,6 +648,10 @@ header {
box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
border: 2px solid white; border: 2px solid white;
}
.leaflet-osmose-layer {
&::before { &::before {
content: ''; content: '';
transform: rotate(45deg); transform: rotate(45deg);
@ -662,6 +662,16 @@ header {
} }
} }
#bars_power {
position: absolute;
bottom: -16.7px;
width: 122.4%;
z-index: 10000;
margin: 1rem 0;
height: 0.4rem;
overflow: hidden;
}
/* Animation au survol plus visible */ /* Animation au survol plus visible */
.osmose-marker-drop:hover .osmose-marker-inner { .osmose-marker-drop:hover .osmose-marker-inner {
@ -720,6 +730,24 @@ header {
opacity: 0.9; opacity: 0.9;
} }
#searchResults {
width: 100%;
}
.search-source-control {
margin: 5px 0;
font-size: 0.9em;
}
.search-source-control label {
display: flex;
align-items: center;
gap: 5px;
}
.search-source-control input[type="checkbox"] {
margin: 0;
}
@keyframes bounce { @keyframes bounce {
@ -814,3 +842,46 @@ overrides leaflet
border-left-color: #ff0000; border-left-color: #ff0000;
} }
} }
/* Styles pour les contrôles de couches */
.leaflet-control-layers {
&.base-layers {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M2 9l10-5 10 5-10 5-10-5zm0 6l10 5 10-5M2 12l10 5 10-5"/></svg>');
background-size: 16px;
background-position: 6px center;
background-repeat: no-repeat;
padding-left: 28px !important;
.leaflet-control-layers-toggle {
background-image: none;
width: auto;
padding-right: 10px;
}
&::after {
content: "Fonds";
margin-left: 5px;
font-size: 12px;
}
}
&.overlay-layers {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>');
background-size: 16px;
background-position: 6px center;
background-repeat: no-repeat;
padding-left: 28px !important;
.leaflet-control-layers-toggle {
background-image: none;
width: auto;
padding-right: 10px;
}
&::after {
content: "Calques";
margin-left: 5px;
font-size: 12px;
}
}
}

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["main.scss"],"names":[],"mappings":"CAAA,MACE,yBACA,mBACA,yBACA,8BACA,6BACA,mCACA,2BACA,mBACA,0BACA,oDACA,+BACA,uCACA,6BACA,iCACA,0BAGF,EACE,sBAGF,KACE,YACA,WACA,mCACA,UACA,SAGF,KACE,YACA,WACA,mCACA,UACA,SACA,UACA,SAGF,KACE,+CACA,eAGF,EACE,+CACA,eACA,eAGF,KACE,YACA,WACA,SACA,iBAME,YACE,6BAKJ,0BACE,mBAKJ,QACE,aAGF,SACE,gBACA,wBACA,cACA,YACA,WACA,iBAGF,MACE,wBACA,yBACA,qBACA,kBACA,kCACA,mBACA,eACA,mBACA,WACA,gCAGF,OACE,iBACA,mBAGF,GACE,mBAGF,uBACE,eACA,YACA,SACA,aACA,+BACA,SACA,WAEA,yBACE,eAIJ,8BACE,6BAGF,8CACE,4BACA,qBACA,iBAGF,8DAIE,oCACA,iBACA,kBACA,sBACA,sCACA,YAGF,gBACE,SACA,kBACA,WAEA,oBACE,WACA,YAIJ,mBACE,eACA,mBAGF,iBACE,gBACA,oBACA,WACA,kBACA,QACA,cAEA,uBACE,YACA,mBAIJ,aACE,0CACA,yBACA,eAGF,aAOE,gBANA,mBACE,0CACA,yBACA,eAMJ,WACE,WAGF,gBACE,GACE,uBAGF,KACE,0BAIJ,EACE,wBAGF,wBACE,aACA,mCAGF,eACE,eACA,MACA,OACA,WACA,gBACA,eAEA,mBACE,eACA,UACA,WACA,gBACA,mBACA,WACA,YACA,kCAIJ,QACE,eACA,cAGF,uBACE,gBACA,qBACA,qBAGF,eACE,WACA,cACA,cACA,gBACA,gBACA,gBACA,iBAGF,WACE,UACA,qBAGF,aACE,UACA,iBACA,qBACA,mBAGF,gBACE,oBAGF,MACE,WAGF,kBACE,aACA,mBACA,cACA,kBACA,UACA,WACA,2BACA,YACA,eACA,eACA,YAIF,SACE,4CACA,iBACA,gBAEA,WACE,gCAQJ,aACE,kBAGF,wBACE,mBACA,qBACA,WACA,YACA,gBAGF,eACE,8CAGF,gCACE,mBAGF,4DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,yBACE,gBAGF,OACE,eACA,cACA,gBAGF,YACE,cACA,YAGF,KACE,WACA,iBACA,oCACA,WAGF,YACE,gBACA,cACA,WACA,cAGF,UACE,WACA,YACA,UAGF,cACE,kBAGF,gBACE,mBACA,gBACA,qBACA,mBACA,eAGF,qBACE,sBAGF,aACE,eAGF,cACE,iBAGF,qBACE,kBACA,qBAEA,2BACE,kBACA,YACA,UACA,SACA,eAGF,6CACE,iBACA,WAGF,6CACE,kBACA,YAGF,iDACE,6BACA,aAGF,uCACE,gBAGF,uCACE,YAGF,2CACE,aAIJ,+BACE,wBAGF,oBACE,gBAGF,YACE,eACA,eACA,OACA,MACA,WACA,YACA,gBACA,qCACA,gBACA,kBACA,qBACA,aACA,kBACA,WACA,WAGF,iBACE,eACA,SACA,WACA,WACA,gBACA,kBACA,kBACA,oCAGF,OACE,kBACA,WAIA,6BACE,mBACA,WACA,4BACA,YAGF,sBACE,mBACA,YACA,aAIJ,aACE,WAGF,aACE,eACA,YACA,SACA,2BACA,0CACA,kBACA,kBACA,oCACA,kBACA,WACA,iDACA,4CAGF,OACE,gBACA,eACA,WAEA,UACE,YACA,iBAGF,WACE,WACA,kBAIJ,KACE,UACA,YAGF,iBACE,iBAGF,gBACE,oBACA,mBACA,uBACA,eACA,eACA,gCAEA,sBACE,yBAIJ,cACE,WACA,aACA,mBACA,sCACA,kBAGF,qBACE,eACA,YACA,WACA,WACA,gBACA,aACA,kBAGF,eACE,kBAGF,aACE,gBACA,aACA,WAEA,6BACE,kBACA,mBAIJ,cACE,kBAKA,SACE,mBACA,mBACA,YACA,UACA,gBACA,qBACA,kBAGF,eACE,UAIA,qBACE,UACA,mCAKN,uBACE,iBACA,cAGF,eACE,eACA,kBACA,iBACA,oCACA,kBACA,yBAGF,oBACE,kBACA,aAGF,qBACE,kBACA,WACA,YACA,yBACA,4BACA,yBACA,aACA,mBACA,uBACA,kCACA,sBAEA,6BACE,YACA,wBACA,WACA,eACA,uCACA,iBAMJ,+CACE,mCACA,yBAGF,yBACE,iBACA,gBACA,cACA,YACA,yBACA,kBAGF,eACE,WACA,yBAGF,kCACE,sBAGF,kBACE,gBACA,eAGF,8BACE,iBACA,WAGF,gBACE,gBACA,aACA,sBACA,QAGF,kBACE,iBACA,qBACA,kBACA,kBAGF,kCACE,yBACA,WAGF,wBACE,WAIF,kBAEE,QAEE,uCAGF,IACE,2CAQJ,+BACE,iBAIF,0BACE,UACE,YACA,iBAGF,iBACE,WACA,WAOF,6BACE,gBACA,eACA,qCACA,gBACA,YAGF,mBACE,eAGF,2BAEE,SACA,OACA,MACA,YACA,YACA,YAIF,OACE,iBAIJ,0BACE,GACE,sBAGF,IACE,0BAGF,IACE,uBAGF,IACE,uBAGF,IACE,uBAGF,IACE,0BAGF,KACE","file":"style.css"} {"version":3,"sourceRoot":"","sources":["main.scss"],"names":[],"mappings":"CAAA,MACE,yBACA,mBACA,yBACA,8BACA,6BACA,mCACA,2BACA,mBACA,0BACA,oDACA,+BACA,uCACA,6BACA,iCACA,0BAGF,EACE,sBAGF,KACE,YACA,WACA,mCACA,UACA,SAGF,KACE,YACA,WACA,mCACA,UACA,SACA,UACA,SAGF,KACE,+CACA,eAGF,EACE,+CACA,eACA,eAGF,KACE,YACA,WACA,SACA,iBAME,YACE,6BAKJ,0BACE,mBAKJ,QACE,aAGF,SACE,gBACA,wBACA,cACA,YACA,WACA,iBAGF,MACE,wBACA,yBACA,qBACA,kBACA,kCACA,mBACA,eACA,mBACA,WACA,gCAGF,OACE,iBACA,mBAGF,GACE,mBAGF,uBACE,eACA,YACA,SACA,aACA,+BACA,SACA,WAEA,yBACE,eAIJ,8BACE,6BAGF,8CACE,4BACA,qBACA,iBAGF,8DAIE,oCACA,iBACA,kBACA,sBACA,sCACA,YAGF,gBACE,SACA,kBACA,WAEA,oBACE,WACA,YAIJ,mBACE,cACA,mBAGF,iBACE,gBACA,oBACA,WACA,kBACA,QACA,cAEA,uBACE,YACA,mBAIJ,aACE,0CACA,yBACA,eAGF,aAOE,gBANA,mBACE,0CACA,yBACA,eAMJ,WACE,WAGF,gBACE,GACE,uBAGF,KACE,0BAIJ,EACE,wBAGF,wBACE,aACA,mCAGF,eACE,eACA,MACA,OACA,WACA,gBACA,eAEA,mBACE,eACA,UACA,WACA,gBACA,mBACA,WACA,YACA,kCAIJ,QACE,eACA,cAGF,uBACE,gBACA,qBACA,qBAGF,eACE,WACA,cACA,cACA,gBACA,gBACA,gBACA,iBAGF,WACE,UACA,qBAGF,aACE,UACA,iBACA,qBACA,mBAGF,gBACE,oBAGF,MACE,WAGF,kBACE,aACA,mBACA,cACA,kBACA,UACA,WACA,2BACA,YACA,eACA,eACA,YAIF,SACE,4CACA,iBACA,gBAEA,WACE,gCAQJ,aACE,kBAGF,wBACE,mBACA,qBACA,WACA,YACA,gBAGF,eACE,8CAGF,gCACE,mBAGF,4DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,6DAEE,mBAGF,yBACE,gBAGF,OACE,eACA,cACA,gBAGF,KACE,WACA,iBACA,oCACA,WAGF,YACE,gBACA,cACA,WACA,cAGF,UACE,WACA,YACA,UAGF,cACE,kBAGF,gBACE,mBACA,gBACA,qBACA,mBACA,eAGF,qBACE,sBAGF,aACE,eAGF,cACE,iBAGF,qBACE,kBACA,qBAEA,2BACE,kBACA,YACA,UACA,SACA,eAGF,6CACE,iBACA,WAGF,6CACE,kBACA,YAGF,iDACE,6BACA,aAGF,uCACE,gBAGF,uCACE,YAGF,2CACE,aAIJ,+BACE,wBAGF,oBACE,gBAGF,YACE,eACA,eACA,OACA,MACA,WACA,YACA,gBACA,qCACA,gBACA,kBACA,qBACA,aACA,kBACA,WACA,WAGF,iBACE,eACA,SACA,WACA,WACA,gBACA,kBACA,kBACA,oCAGF,OACE,kBACA,WAIA,6BACE,mBACA,WACA,4BACA,YAGF,sBACE,mBACA,YACA,aAIJ,aACE,WAGF,aACE,eACA,YACA,SACA,2BACA,0CACA,kBACA,kBACA,oCACA,kBACA,WACA,iDACA,4CAGF,OACE,gBACA,eACA,WAEA,UACE,YACA,iBAGF,WACE,WACA,kBAIJ,KACE,UACA,YAGF,iBACE,iBAGF,gBACE,oBACA,mBACA,uBACA,eACA,eACA,gCAEA,sBACE,yBAIJ,cACE,WACA,aACA,mBACA,sCACA,kBAGF,qBACE,eACA,YACA,WACA,WACA,gBACA,aACA,kBAGF,eACE,kBAGF,aACE,kBACA,aACA,WACA,YAEA,6BACE,mBACA,oBAIJ,cACE,kBAKA,SACE,mBACA,mBACA,YACA,UACA,gBACA,qBACA,kBAGF,eACE,UAIA,qBACE,UACA,mCAKN,uBACE,iBACA,cAGF,eACE,eACA,kBACA,iBACA,oCACA,kBACA,yBAGF,oBACE,kBACA,aAGF,qBACE,kBACA,WACA,YACA,yBACA,4BACA,yBACA,aACA,mBACA,uBACA,kCACA,sBAMA,8BACE,YACA,wBACA,WACA,eACA,uCACA,iBAIJ,YACE,kBACA,eACA,aACA,cACA,cACA,aACA,gBAKF,+CACE,mCACA,yBAGF,yBACE,iBACA,gBACA,cACA,YACA,yBACA,kBAGF,eACE,WACA,yBAGF,kCACE,sBAGF,kBACE,gBACA,eAGF,8BACE,iBACA,WAGF,gBACE,gBACA,aACA,sBACA,QAGF,kBACE,iBACA,qBACA,kBACA,kBAGF,kCACE,yBACA,WAGF,wBACE,WAGF,eACE,WAGF,uBACE,aACA,eAGF,6BACE,aACA,mBACA,QAGF,4CACE,SAGF,kBAEE,QAEE,uCAGF,IACE,2CAQJ,+BACE,iBAIF,0BACE,UACE,YACA,iBAGF,iBACE,WACA,WAOF,6BACE,gBACA,eACA,qCACA,gBACA,YAGF,mBACE,eAGF,2BAEE,SACA,OACA,MACA,YACA,YACA,YAIF,OACE,iBAIJ,0BACE,GACE,sBAGF,IACE,0BAGF,IACE,uBAGF,IACE,uBAGF,IACE,uBAGF,IACE,0BAGF,KACE,uBAMF,oCACE,wOACA,qBACA,+BACA,4BACA,6BAEA,mEACE,sBACA,WACA,mBAGF,2CACE,gBACA,gBACA,eAIJ,uCACE,yOACA,qBACA,+BACA,4BACA,6BAEA,sEACE,sBACA,WACA,mBAGF,8CACE,kBACA,gBACA","file":"style.css"}