up
This commit is contained in:
parent
ce029e2c76
commit
bbf1bf3cdd
14
README.md
14
README.md
@ -1,15 +1,17 @@
|
|||||||
# Carte des IRVE filtrable
|
# Carte des IRVE filtrable
|
||||||
|
|
||||||
![libre-charge-map_overview.jpg](libre-charge-map_overview.jpg)
|
![libre-charge-map_overview.jpg](libre-charge-map_overview.jpg)
|
||||||
|
|
||||||
|
|
||||||
fait avec le données OpenStreetMap (OSM) ainsi que des icones
|
fait avec le données OpenStreetMap (OSM) ainsi que des icones
|
||||||
|
|
||||||
![libre-charge-map_popup.jpg](libre-charge-map_popup.jpg)
|
![libre-charge-map_popup.jpg](libre-charge-map_popup.jpg)
|
||||||
|
Venez discuter sur le forum OpenStreetMap: https://forum.openstreetmap.org/viewtopic.php?id=69882
|
||||||
|
|
||||||
développé par tykayn - https://www.cipherbliss.com - à partir d'un squelette d'example pour Leaflet.
|
développé par tykayn - https://www.cipherbliss.com - à partir d'un squelette d'example pour Leaflet.
|
||||||
Mastodon: https://mastodon.cipherbliss.com/@tykayn
|
Mastodon: https://mastodon.cipherbliss.com/@tykayn
|
||||||
|
|
||||||
|
# Fonctionnalités
|
||||||
|
Affichage des stations de recharge colorées selon leur puissance maximale délivrée sur un totem.
|
||||||
|
Changement de fond de carte.
|
||||||
|
|
||||||
# comment ça marche ?
|
# comment ça marche ?
|
||||||
Avec une lib qui affiche un fond de carte sur lequel on peut naviguer et des marqueurs, on demande poliment à un site web, Overpass Turbo, quels sont les points et polygones d'OpenStreetMap correspondant à plusieurs types de restaurants et lieux où l'on peut trouver à manger et à boire à consommer sur place ou à emporter.
|
Avec une lib qui affiche un fond de carte sur lequel on peut naviguer et des marqueurs, on demande poliment à un site web, Overpass Turbo, quels sont les points et polygones d'OpenStreetMap correspondant à plusieurs types de restaurants et lieux où l'on peut trouver à manger et à boire à consommer sur place ou à emporter.
|
||||||
@ -39,6 +41,14 @@ let req = 'https://overpass-api.de/api/interpreter?data=[out:json][timeout:25];
|
|||||||
'nwr[amenity=charging_station](area.searchArea);' +
|
'nwr[amenity=charging_station](area.searchArea);' +
|
||||||
'out body geom;'
|
'out body geom;'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Travaux en cours
|
||||||
|
- ouvrir les charging_station zone dans JOSM
|
||||||
|
- filtres avancés sur le type de prise
|
||||||
|
- affichage optionnel des restaurants et autres lieux où l'on peut trouver à manger et à boire comme dans MeltingPot. https://www.cipherbliss.com/ou-manger
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# sources
|
# sources
|
||||||
Sources disponibles sur https://forge.chapril.org/tykayn/libre-charge-map.git
|
Sources disponibles sur https://forge.chapril.org/tykayn/libre-charge-map.git
|
||||||
Carte similaire, celle des cuisines de restaurant: https://forge.chapril.org/tykayn/melting-pot
|
Carte similaire, celle des cuisines de restaurant: https://forge.chapril.org/tykayn/melting-pot
|
||||||
|
51
index.html
51
index.html
@ -27,15 +27,20 @@
|
|||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>
|
||||||
|
<img class="icon-img" src="img/prise-de-courant.png" alt="prise"> Libre Charge Map
|
||||||
|
</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
|
||||||
|
<button id="toggleSidePanel">
|
||||||
|
☰
|
||||||
|
</button>
|
||||||
<div id="zoomMessage">
|
<div id="zoomMessage">
|
||||||
Zoomez pour voir les stations de recharge
|
Zoomez pour voir les stations de recharge
|
||||||
</div>
|
</div>
|
||||||
<div id='map'>
|
<div class="research_display">
|
||||||
|
|
||||||
<div class='leaflet-control-container'>
|
|
||||||
<div class='leaflet-top leaflet-right'>
|
|
||||||
|
|
||||||
<div class="research_display">
|
|
||||||
<div id='spinning_icon'>
|
<div id='spinning_icon'>
|
||||||
<svg
|
<svg
|
||||||
id='star'
|
id='star'
|
||||||
@ -45,25 +50,29 @@
|
|||||||
xmlns='http://www.w3.org/2000/svg'
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
version='1.1'>
|
version='1.1'>
|
||||||
<polygon
|
<polygon
|
||||||
fill='red'
|
fill='red'
|
||||||
stroke='red'
|
stroke='red'
|
||||||
stroke-width='10'
|
stroke-width='10'
|
||||||
points='350,75 379,161 469,161 397,215
|
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>
|
||||||
</div>
|
</div>
|
||||||
|
<div id='map'>
|
||||||
|
|
||||||
|
<div class='leaflet-control-container'>
|
||||||
|
<div class='leaflet-top leaflet-right'>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
<div class="side-panel">
|
<div class="side-panel">
|
||||||
<h1>
|
|
||||||
<img class="icon-img" src="img/prise-de-courant.png" alt="prise"> Libre Charge Map
|
|
||||||
</h1>
|
|
||||||
<div id="bars_power">
|
<div id="bars_power">
|
||||||
</div>
|
</div>
|
||||||
<div id="round_power_legend">
|
<div id="round_power_legend">
|
||||||
@ -110,6 +119,9 @@
|
|||||||
<button id="setRandomView" class="rounded-button">
|
<button id="setRandomView" class="rounded-button">
|
||||||
🎲 Une ville au hasard
|
🎲 Une ville au hasard
|
||||||
</button>
|
</button>
|
||||||
|
<button id="sendToJOSM" class="rounded-button">
|
||||||
|
🗺️ Éditer dans JOSM
|
||||||
|
</button>
|
||||||
|
|
||||||
<!-- <button id="toggle">-->
|
<!-- <button id="toggle">-->
|
||||||
<!-- toggle : montrer les stations avec à minima 150kW de puissance dispo-->
|
<!-- toggle : montrer les stations avec à minima 150kW de puissance dispo-->
|
||||||
@ -117,8 +129,11 @@
|
|||||||
|
|
||||||
|
|
||||||
<div id="infos_carte"></div>
|
<div id="infos_carte"></div>
|
||||||
|
|
||||||
<div id="filters">
|
<div id="filters">
|
||||||
filtres: <br>
|
<h2>
|
||||||
|
🔍 Filtres:
|
||||||
|
</h2>
|
||||||
<div class="filter-group">
|
<div class="filter-group">
|
||||||
qualité
|
qualité
|
||||||
<button id="filterUnkown">kW max inconnu</button>
|
<button id="filterUnkown">kW max inconnu</button>
|
||||||
|
33
js/config.js
33
js/config.js
@ -9,6 +9,35 @@ const config = {
|
|||||||
cartodb : 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{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',
|
stamen : 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png',
|
||||||
transport : '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: [
|
||||||
|
'name',
|
||||||
|
'capacity',
|
||||||
|
'description',
|
||||||
|
'date_start',
|
||||||
|
'charging_station:output',
|
||||||
|
'socket:type_2',
|
||||||
|
'socket:type2:output',
|
||||||
|
'socket:typee',
|
||||||
|
'socket:typee:output',
|
||||||
|
'socket:type2_combo',
|
||||||
|
'socket:type2_combo:output',
|
||||||
|
'socket:chademo',
|
||||||
|
'operator', 'ref:EU:EVSE',
|
||||||
|
'network',
|
||||||
|
'opening_hours',
|
||||||
|
'contact',
|
||||||
|
'phone',
|
||||||
|
'contact:phone',
|
||||||
|
'website',
|
||||||
|
'contact:website',
|
||||||
|
'ref',
|
||||||
|
'fee',
|
||||||
|
'payment',
|
||||||
|
'payment:contactless',
|
||||||
|
'authentication:app',
|
||||||
|
'authentication:debit_card',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export default config
|
export default config
|
||||||
|
29
js/editor.js
Normal file
29
js/editor.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Fonctions liées à l'édition des données OSM et à l'interaction avec JOSM
|
||||||
|
*/
|
||||||
|
|
||||||
|
export function sendToJOSM(map) {
|
||||||
|
const bounds = map.getBounds();
|
||||||
|
const bbox = `${bounds.getWest()},${bounds.getSouth()},${bounds.getEast()},${bounds.getNorth()}`;
|
||||||
|
|
||||||
|
const josmUrl = `http://127.0.0.1:8111/load_and_zoom?left=${bounds.getWest()}&right=${bounds.getEast()}&top=${bounds.getNorth()}&bottom=${bounds.getSouth()}&select=node[amenity=charging_station]&changeset_hashtags=IRVE&layer_name=irve-depuis-OSM`;
|
||||||
|
|
||||||
|
return fetch(josmUrl)
|
||||||
|
.then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
console.log('Données envoyées à JOSM avec succès');
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
console.error('Erreur : JOSM doit être ouvert avec l\'option "Contrôle à distance" activée');
|
||||||
|
throw new Error('JOSM non accessible');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Erreur JOSM:', error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
sendToJOSM
|
||||||
|
};
|
213
js/main.js
213
js/main.js
@ -7,6 +7,7 @@
|
|||||||
import config from './config.js'
|
import config from './config.js'
|
||||||
import utils from './utils.js'
|
import utils from './utils.js'
|
||||||
import colorUtils from './color-utils.js'
|
import colorUtils from './color-utils.js'
|
||||||
|
import editor from './editor.js'
|
||||||
|
|
||||||
console.log('config', config)
|
console.log('config', config)
|
||||||
let geojsondata;
|
let geojsondata;
|
||||||
@ -86,6 +87,10 @@ function updateURLWithMapCoordinatesAndZoom() {
|
|||||||
history.replaceState(null, null, url)
|
history.replaceState(null, null, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let all_stations_markers = L.layerGroup().addTo(map) // layer group pour tous les marqueurs
|
||||||
|
// let stations_much_speed_wow = L.layerGroup().addTo(map) // layer group des stations rapides
|
||||||
|
|
||||||
var osm = L.tileLayer(config.tileServers.osm, {
|
var osm = L.tileLayer(config.tileServers.osm, {
|
||||||
attribution: config.osmMention + '© <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
|
attribution: config.osmMention + '© <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors'
|
||||||
})
|
})
|
||||||
@ -113,22 +118,26 @@ var baseLayers = {
|
|||||||
// 'OpenCycleMap': cycle,
|
// 'OpenCycleMap': cycle,
|
||||||
'Transport': transport
|
'Transport': transport
|
||||||
}
|
}
|
||||||
|
|
||||||
let all_stations_markers = L.layerGroup().addTo(map) // layer group pour tous les marqueurs
|
|
||||||
// let stations_much_speed_wow = L.layerGroup().addTo(map) // layer group des stations rapides
|
|
||||||
|
|
||||||
let overlays = {
|
let overlays = {
|
||||||
stations_bof: all_stations_markers
|
stations_bof: all_stations_markers
|
||||||
// , stations_much_speed_wow
|
}
|
||||||
} // Si vous avez des calques superposables, ajoutez-les ici
|
|
||||||
|
|
||||||
const layerControl = L.control.layers(baseLayers, overlays, {collapsed: true}).addTo(map)
|
const layerControl = L.control.layers(baseLayers, overlays, {collapsed: true}).addTo(map)
|
||||||
tileGrey.addTo(map)
|
tileGrey.addTo(map)
|
||||||
|
|
||||||
|
|
||||||
function buildOverpassApiUrl(map, overpassQuery) {
|
function buildOverpassApiUrl(map, overpassQuery) {
|
||||||
|
|
||||||
let baseUrl = 'https://overpass-api.de/api/interpreter'
|
let baseUrl = 'https://overpass-api.de/api/interpreter'
|
||||||
let bounds = map.getBounds().getSouth() + ',' + map.getBounds().getWest() + ',' + map.getBounds().getNorth() + ',' + map.getBounds().getEast()
|
// Ajouter une marge de 2 kilomètres autour des bounds
|
||||||
|
// Conversion approximative: 1 degré = 111km à l'équateur
|
||||||
|
const kilometersMarginForLoading = 2
|
||||||
|
const marginInDegrees = kilometersMarginForLoading / 111 // 2 kilomètres convertis en degrés
|
||||||
|
const south = map.getBounds().getSouth() - marginInDegrees
|
||||||
|
const west = map.getBounds().getWest() - marginInDegrees
|
||||||
|
const north = map.getBounds().getNorth() + marginInDegrees
|
||||||
|
const east = map.getBounds().getEast() + marginInDegrees
|
||||||
|
let bounds = south + ',' + west + ',' + north + ',' + east
|
||||||
let resultUrl, query = ''
|
let resultUrl, query = ''
|
||||||
|
|
||||||
if (config.overrideQuery) {
|
if (config.overrideQuery) {
|
||||||
@ -144,36 +153,8 @@ function buildOverpassApiUrl(map, overpassQuery) {
|
|||||||
}
|
}
|
||||||
resultUrl = baseUrl + query
|
resultUrl = baseUrl + query
|
||||||
return resultUrl
|
return resultUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags_to_display_in_popup = [
|
|
||||||
'name',
|
|
||||||
'capacity',
|
|
||||||
'description',
|
|
||||||
'date_start',
|
|
||||||
'charging_station:output',
|
|
||||||
'socket:type_2',
|
|
||||||
'socket:type2:output',
|
|
||||||
'socket:typee',
|
|
||||||
'socket:typee:output',
|
|
||||||
'socket:type2_combo',
|
|
||||||
'socket:type2_combo:output',
|
|
||||||
'socket:chademo',
|
|
||||||
'operator', 'ref:EU:EVSE',
|
|
||||||
'network',
|
|
||||||
'opening_hours',
|
|
||||||
'contact',
|
|
||||||
'phone',
|
|
||||||
'contact:phone',
|
|
||||||
'website',
|
|
||||||
'contact:website',
|
|
||||||
'ref',
|
|
||||||
'fee',
|
|
||||||
'payment',
|
|
||||||
'payment:contactless',
|
|
||||||
'authentication:app',
|
|
||||||
'authentication:debit_card',
|
|
||||||
]
|
|
||||||
const margin_josm_bbox = 0.00001
|
const margin_josm_bbox = 0.00001
|
||||||
|
|
||||||
function createJOSMEditLink(feature) {
|
function createJOSMEditLink(feature) {
|
||||||
@ -288,6 +269,48 @@ function displayStatsFromGeoJson(resultAsGeojson) {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
|
let stats_content = `<div class="stats-table">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Nombre</th>
|
||||||
|
<th>Pourcentage</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Puissance inconnue</td>
|
||||||
|
<td>${count_output_unknown}</td>
|
||||||
|
<td>${calculerPourcentage(count_output_unknown, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>1-50 kW</td>
|
||||||
|
<td>${count_station_outputoutput_between_1_and_50}</td>
|
||||||
|
<td>${calculerPourcentage(count_station_outputoutput_between_1_and_50, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>50-100 kW</td>
|
||||||
|
<td>${output_more_than_50}</td>
|
||||||
|
<td>${calculerPourcentage(output_more_than_50, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>100-200 kW</td>
|
||||||
|
<td>${output_more_than_100}</td>
|
||||||
|
<td>${calculerPourcentage(output_more_than_100, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>200-300 kW</td>
|
||||||
|
<td>${output_more_than_200}</td>
|
||||||
|
<td>${calculerPourcentage(output_more_than_200, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>300+ kW</td>
|
||||||
|
<td>${output_more_than_300}</td>
|
||||||
|
<td>${calculerPourcentage(output_more_than_300, count)}%</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
let stats_content = `<div class="stats">
|
let stats_content = `<div class="stats">
|
||||||
Statistiques des <strong>${count}</strong> stations trouvées: <br/>
|
Statistiques des <strong>${count}</strong> stations trouvées: <br/>
|
||||||
${count_station_output} (${calculerPourcentage(count_station_output, count)}%) ont une info de puissance max délivrée <i>charging_station:output</i>. <br/>
|
${count_station_output} (${calculerPourcentage(count_station_output, count)}%) ont une info de puissance max délivrée <i>charging_station:output</i>. <br/>
|
||||||
@ -300,13 +323,14 @@ ${output_more_than_50} (${calculerPourcentage(output_more_than_50, count)}%) ont
|
|||||||
${count_found_type2combo} (${calculerPourcentage(count_found_type2combo, count)}%) ont un prise combo définie <i>*type2_combo*</i>. <br/>
|
${count_found_type2combo} (${calculerPourcentage(count_found_type2combo, count)}%) ont un prise combo définie <i>*type2_combo*</i>. <br/>
|
||||||
${count_estimated_type2combo} (${calculerPourcentage(count_estimated_type2combo, count)}%) ont une prise combo présumée à partir de la puissance max trouvée mais non spécifiée <i>*type2_combo*</i>. <br/>${count_found_type2} (${calculerPourcentage(count_found_type2, count)}%) ont un prise type2 définie <i>*type2*</i>. <br/>
|
${count_estimated_type2combo} (${calculerPourcentage(count_estimated_type2combo, count)}%) ont une prise combo présumée à partir de la puissance max trouvée mais non spécifiée <i>*type2_combo*</i>. <br/>${count_found_type2} (${calculerPourcentage(count_found_type2, count)}%) ont un prise type2 définie <i>*type2*</i>. <br/>
|
||||||
</div>`
|
</div>`
|
||||||
|
*
|
||||||
|
*/
|
||||||
$('#found_charging_stations').html(stats_content)
|
$('#found_charging_stations').html(stats_content)
|
||||||
$('#bars_power').html(bar_powers)
|
$('#bars_power').html(bar_powers)
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindEventsOnJosmRemote() {
|
function bindEventsOnJosmRemote() {
|
||||||
let josm_remote_buttons = $(`.josm`)
|
let josm_remote_buttons = $(`#sendToJOSM`)
|
||||||
// console.log('josm_remote_buttons', josm_remote_buttons[0])
|
// console.log('josm_remote_buttons', josm_remote_buttons[0])
|
||||||
$(josm_remote_buttons[0]).on('click', () => {
|
$(josm_remote_buttons[0]).on('click', () => {
|
||||||
// console.log('link', josm_remote_buttons[0])
|
// console.log('link', josm_remote_buttons[0])
|
||||||
@ -383,8 +407,8 @@ function makePopupOfFeature(feature) {
|
|||||||
popupContent += '</div>'
|
popupContent += '</div>'
|
||||||
popupContent += '<div class="key-values" >'
|
popupContent += '<div class="key-values" >'
|
||||||
// ne montrer que certains champs dans la popup
|
// ne montrer que certains champs dans la popup
|
||||||
tags_to_display_in_popup.forEach(function (key) {
|
config.tags_to_display_in_popup.forEach(function (key) {
|
||||||
if (tags_to_display_in_popup.indexOf(key)) {
|
if (config.tags_to_display_in_popup.indexOf(key)) {
|
||||||
let value = feature.properties.tags[key]
|
let value = feature.properties.tags[key]
|
||||||
if (value) {
|
if (value) {
|
||||||
if (value.indexOf('http') !== -1) {
|
if (value.indexOf('http') !== -1) {
|
||||||
@ -599,7 +623,20 @@ function onMapMoveEnd() {
|
|||||||
loadOverpassQuery()
|
loadOverpassQuery()
|
||||||
}
|
}
|
||||||
$('#infos_carte').html(infos)
|
$('#infos_carte').html(infos)
|
||||||
updateURLWithMapCoordinatesAndZoom()
|
// Stocker les dernières coordonnées connues
|
||||||
|
if (!window.lastKnownPosition) {
|
||||||
|
window.lastKnownPosition = center;
|
||||||
|
updateURLWithMapCoordinatesAndZoom();
|
||||||
|
} else {
|
||||||
|
// Calculer la distance en km entre l'ancienne et la nouvelle position
|
||||||
|
const distanceKm = map.distance(center, window.lastKnownPosition) / 1000;
|
||||||
|
|
||||||
|
// Ne mettre à jour que si on s'est déplacé de plus de 2km
|
||||||
|
if (distanceKm > 2) {
|
||||||
|
window.lastKnownPosition = center;
|
||||||
|
updateURLWithMapCoordinatesAndZoom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -618,6 +655,9 @@ $(document).ready(function () {
|
|||||||
$('#load').on('click', function () {
|
$('#load').on('click', function () {
|
||||||
loadOverpassQuery()
|
loadOverpassQuery()
|
||||||
})
|
})
|
||||||
|
$('#toggleSidePanel').on('click', function () {
|
||||||
|
$('body').toggleClass('side-panel-open')
|
||||||
|
})
|
||||||
// filtres
|
// filtres
|
||||||
// boutons de toggle et de cycle de visibilité
|
// boutons de toggle et de cycle de visibilité
|
||||||
//
|
//
|
||||||
@ -643,6 +683,7 @@ function showActiveFilter(filterVariableName, selectorId) {
|
|||||||
$(selectorId).attr('class', 'filter-state-' + filterVariableName)
|
$(selectorId).attr('class', 'filter-state-' + filterVariableName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function cycleVariableState(filterVariableName, selectorId) {
|
function cycleVariableState(filterVariableName, selectorId) {
|
||||||
console.log('filterVariableName', filterVariableName, filterStatesAvailable)
|
console.log('filterVariableName', filterVariableName, filterStatesAvailable)
|
||||||
if (filterVariableName) {
|
if (filterVariableName) {
|
||||||
@ -674,3 +715,93 @@ $('#toggle-stats').on('click', function() {
|
|||||||
$(this).text(text.replace('🔼', '🔽'));
|
$(this).text(text.replace('🔼', '🔽'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ajouter ces variables avec les autres déclarations globales
|
||||||
|
let food_places_markers = L.layerGroup();
|
||||||
|
const foodIcon = L.divIcon({
|
||||||
|
className: 'food-marker',
|
||||||
|
html: '🍽️',
|
||||||
|
iconSize: [20, 20],
|
||||||
|
iconAnchor: [10, 10]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ajouter cette fonction avec les autres fonctions de recherche
|
||||||
|
function searchFoodPlaces(map) {
|
||||||
|
const bounds = map.getBounds();
|
||||||
|
const bbox = bounds.getSouth() + ',' + bounds.getWest() + ',' + bounds.getNorth() + ',' + bounds.getEast();
|
||||||
|
|
||||||
|
const query = `
|
||||||
|
[out:json][timeout:25];
|
||||||
|
(
|
||||||
|
node["amenity"="restaurant"](${bbox});
|
||||||
|
node["amenity"="cafe"](${bbox});
|
||||||
|
);
|
||||||
|
out body;
|
||||||
|
>;
|
||||||
|
out skel qt;`;
|
||||||
|
|
||||||
|
const url = `https://overpass-api.de/api/interpreter?data=${encodeURIComponent(query)}`;
|
||||||
|
|
||||||
|
food_places_markers.clearLayers();
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const geojson = osmtogeojson(data);
|
||||||
|
geojson.features.forEach(feature => {
|
||||||
|
const coords = feature.geometry.coordinates;
|
||||||
|
const properties = feature.properties;
|
||||||
|
const name = properties.tags.name || 'Sans nom';
|
||||||
|
const type = properties.tags.amenity;
|
||||||
|
|
||||||
|
const marker = L.marker([coords[1], coords[0]], {
|
||||||
|
icon: foodIcon
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.bindPopup(`
|
||||||
|
<strong>${name}</strong><br>
|
||||||
|
Type: ${type}<br>
|
||||||
|
${properties.tags.cuisine ? 'Cuisine: ' + properties.tags.cuisine : ''}
|
||||||
|
`);
|
||||||
|
|
||||||
|
food_places_markers.addLayer(marker);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Erreur lors de la recherche des restaurants:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modifier la fonction init pour ajouter le contrôle des couches
|
||||||
|
function init() {
|
||||||
|
// ... existing map initialization code ...
|
||||||
|
|
||||||
|
// Ajouter le groupe de marqueurs à la carte
|
||||||
|
food_places_markers.addTo(map);
|
||||||
|
$('#found_charging_stations').hide();
|
||||||
|
|
||||||
|
// Ajouter le contrôle des couches
|
||||||
|
const overlayMaps = {
|
||||||
|
"Stations de recharge": all_stations_markers,
|
||||||
|
"Restaurants et cafés": food_places_markers
|
||||||
|
};
|
||||||
|
|
||||||
|
L.control.layers(null, overlayMaps).addTo(map);
|
||||||
|
|
||||||
|
// Ajouter l'événement de recherche sur le déplacement de la carte
|
||||||
|
map.on('moveend', function() {
|
||||||
|
if (map.getZoom() > 13) { // Ajuster le niveau de zoom selon vos besoins
|
||||||
|
searchFoodPlaces(map);
|
||||||
|
} else {
|
||||||
|
food_places_markers.clearLayers();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('sendToJOSM').addEventListener('click', () => {
|
||||||
|
editor.sendToJOSM(map)
|
||||||
|
.then(() => {
|
||||||
|
alert('Données envoyées à JOSM avec succès !');
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
alert('Erreur : JOSM doit être ouvert avec l\'option "Contrôle à distance" activée');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #ccc;
|
background: #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -94,7 +94,7 @@ img.leaflet-marker-icon.tag-socket\:type2_yes {
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chercherButton {
|
.side-panel button {
|
||||||
min-width: 10em;
|
min-width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ img.leaflet-marker-icon.tag-socket\:type2_yes {
|
|||||||
background: #96b1ea;
|
background: #96b1ea;
|
||||||
}
|
}
|
||||||
|
|
||||||
#chercherButton:hover,
|
button:hover,
|
||||||
.edit-button:hover {
|
.edit-button:hover {
|
||||||
background: #0d377b;
|
background: #0d377b;
|
||||||
border: solid 1px #08285c;
|
border: solid 1px #08285c;
|
||||||
@ -149,8 +149,8 @@ a {
|
|||||||
|
|
||||||
#spinning_icon {
|
#spinning_icon {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 11rem;
|
top: 0;
|
||||||
left: 20.5rem;
|
left: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
background: white;
|
background: white;
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
@ -292,6 +292,7 @@ marqueurs
|
|||||||
button {
|
button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
|
background: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bars_power {
|
#bars_power {
|
||||||
@ -302,7 +303,7 @@ button {
|
|||||||
.bar {
|
.bar {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding: 0.55rem;
|
padding: 0.35rem;
|
||||||
padding-right: 0.25rem;
|
padding-right: 0.25rem;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
@ -339,6 +340,11 @@ button {
|
|||||||
#infos_carte{
|
#infos_carte{
|
||||||
padding: 1rem 0;
|
padding: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button + button{
|
||||||
|
margin-left: 1rem;
|
||||||
|
|
||||||
|
}
|
||||||
.filter-group button{
|
.filter-group button{
|
||||||
padding: 1rem 2rem;
|
padding: 1rem 2rem;
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
@ -376,6 +382,9 @@ button {
|
|||||||
background-size:contain;
|
background-size:contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#round_power_legend{
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
.side-panel {
|
.side-panel {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -386,8 +395,36 @@ button {
|
|||||||
background: white;
|
background: white;
|
||||||
box-shadow: -2px 0 5px rgba(0,0,0,0.2);
|
box-shadow: -2px 0 5px rgba(0,0,0,0.2);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 20px;
|
padding: 1rem 2rem;
|
||||||
|
padding-bottom: 15rem;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
|
visibility: hidden;
|
||||||
|
top: 5.7rem;
|
||||||
|
width: 26vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toggleSidePanel{
|
||||||
|
position: fixed;
|
||||||
|
top: 1rem;
|
||||||
|
right: 2rem;
|
||||||
|
z-index: 10;
|
||||||
|
background: white;
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
header{
|
||||||
|
padding-left: 2rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.side-panel-open .side-panel{
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.side-panel-open #map{
|
||||||
|
margin-left: 23.5rem;
|
||||||
|
}
|
||||||
|
#infos_carte{
|
||||||
|
clear:both;
|
||||||
}
|
}
|
||||||
#zoomMessage{
|
#zoomMessage{
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@ -404,6 +441,17 @@ button {
|
|||||||
animation: rainbow-border 4s linear infinite;
|
animation: rainbow-border 4s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header{
|
||||||
|
background: #222;
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
|
header h1{
|
||||||
|
line-height: 3rem;
|
||||||
|
}
|
||||||
|
header img{
|
||||||
|
float: left;
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
@keyframes rainbow-border {
|
@keyframes rainbow-border {
|
||||||
0% { border-left-color: #ff0000; }
|
0% { border-left-color: #ff0000; }
|
||||||
17% { border-left-color: #ff8000; }
|
17% { border-left-color: #ff8000; }
|
||||||
@ -416,7 +464,10 @@ button {
|
|||||||
|
|
||||||
#map {
|
#map {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
margin-right: 300px; /* Pour laisser de la place au panneau */
|
top: 5.55rem;
|
||||||
|
}
|
||||||
|
.side-panel #map{
|
||||||
|
margin-left: 20vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Style pour mobile */
|
/* Style pour mobile */
|
||||||
|
Loading…
Reference in New Issue
Block a user