/** * rechercher les bornes de recharge, * afficher des cercles colorés selon la puissance max de la station * lister les bornes trouvées dans la page * @type {boolean} */ let showHighPower = true const overrideQuery = true const initialZoom = 12 const osmMention = '© OpenStreetMap contributors' let unknown_color = '#c0b1b1' // color for unknown power output of the station // serveurs de tuiles: https://wiki.openstreetmap.org/wiki/Tile_servers // https://stamen-tiles.a.ssl.fastly.net/toner/{z}/{x}/{y}.png // https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png // https://tile.openstreetmap.org/{z}/{x}/{y}.png // 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png' const tileServer = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png' const tileServer_stamen = 'https://a.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png' // Créer la carte centrée sur Rouen // Liste des 20 villes les plus peuplées de France avec leurs coordonnées géographiques let cities = [ { name: 'Paris', coords: [48.8566, 2.3522] }, { name: 'Marseille', coords: [43.2965, 5.3698] }, { name: 'Lyon', coords: [45.7640, 4.8357] }, { name: 'Toulouse', coords: [43.6042, 1.4437] }, { name: 'Nice', coords: [43.7101, 7.2620] }, { name: 'Nantes', coords: [47.2184, -1.5536] }, { name: 'Strasbourg', coords: [48.5831, 7.7521] }, { name: 'Montpellier', coords: [43.6167, 3.8742] }, { name: 'Bordeaux', coords: [44.8378, -0.5792] }, { name: 'Lille', coords: [50.6293, 3.1466] }, { name: 'Rennes', coords: [48.1120, -1.6823] }, { name: 'Toulon', coords: [43.1230, 5.9291] }, { name: 'Le Havre', coords: [49.4943, 0.1079] }, { name: 'Saint-Etienne', coords: [45.4380, 4.3841] }, { name: 'Grenoble', coords: [45.1667, 5.7295] }, { name: 'Rouen', coords: [49.4431, 1.0820] }, { name: 'Dijon', coords: [47.3221, 5.0446] }, { name: 'Angers', coords: [47.4786, -0.5551] }, { name: 'Nîmes', coords: [43.8366, 4.3623] }, { name: 'Reims', coords: [49.2500, 4.0333] } ] // Choix au hasard d'une ville parmi la liste let randomCity = cities[Math.floor(Math.random() * cities.length)] console.log('randomCity', randomCity) // Initialisation de la carte avec la vue centrée sur la ville choisie let map = L.map('map').setView(randomCity.coords, initialZoom) var osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: osmMention+'© OpenStreetMap contributors' }) var cycle = L.tileLayer('https://{s}.tile.opencyclemap.org/{z}/{x}/{y}.png', { attribution: osmMention+'© OpenCycleMap contributors' }) var transport = L.tileLayer('https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png', { attribution: osmMention }) let tileGrey = L.tileLayer(tileServer, { attribution: osmMention }) let stamen = L.tileLayer(tileServer_stamen, { attribution: osmMention }) var baseLayers = { 'Grey': tileGrey, 'Stamen': stamen, 'OpenStreetMap': osm, // 'OpenCycleMap': cycle, 'Transport': transport } let overlays = {} // Si vous avez des calques superposables, ajoutez-les ici const layerControl = L.control.layers(baseLayers, overlays, { collapsed: true }).addTo(map) tileGrey.addTo(map) let filteredMarkers = L.layerGroup().addTo(map) function buildOverpassApiUrl (map, overpassQuery) { let baseUrl = 'https://overpass-api.de/api/interpreter' let bounds = map.getBounds().getSouth() + ',' + map.getBounds().getWest() + ',' + map.getBounds().getNorth() + ',' + map.getBounds().getEast() let resultUrl, query = '' if (overrideQuery) { query = `?data=[out:json][timeout:15];( node[amenity=charging_station](${bounds}); );out body geom;` } else { let nodeQuery = 'node[' + overpassQuery + '](' + bounds + ');' let wayQuery = 'way[' + overpassQuery + '](' + bounds + ');' let relationQuery = 'relation[' + overpassQuery + '](' + bounds + ');' query = '?data=[out:json][timeout:15];(' + nodeQuery + wayQuery + relationQuery + ');out body geom;' } resultUrl = baseUrl + query return resultUrl } const tags_to_display_in_popup = [ 'name', 'capacity', '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 function createJOSMEditLink (feature) { var coordinates = feature.geometry.coordinates var nodeId = feature.properties.id var left = coordinates[0] - margin_josm_bbox var right = coordinates[0] + margin_josm_bbox var bottom = coordinates[1] - margin_josm_bbox var top = coordinates[1] + margin_josm_bbox var josmUrl = `http://127.0.0.1:8111/load_and_zoom?changeset_hashtags=IRVE&layer_name=irve-depuis-OSM&left=${left}&top=${top}&right=${right}&bottom=${bottom}&select=${nodeId}` return josmUrl } function supprimerMarqueurs (map) { map.eachLayer((layer) => { if (layer instanceof L.Marker) { layer.remove() } }) } const colors = [ '#36423d', '#4e8a8d', '#2999b3', '#1782dd', '#2900ff', '#8000ff', ] function guessOutputPowerFromFeature (feature) { let outputPower = 0 let power = 0 if (feature.properties && feature.properties.tags) { /** * fouiller dans les tags les valeurs explicites de puissance déclarée. * Deviner aussi les puissances non déclarées: * - type 2 présent, max 43kW * - type Chademo présent, max 63kW * https://forum.openstreetmap.fr/t/bornes-de-recharges-et-puissance-chargeurs-quel-est-votre-avis/27828 * */ let found_type_2 = false let found_type_chademo = false for (var tag in feature.properties.tags) { if (tag.indexOf('type2') !== -1) { // console.log('tag type2', tag) found_type_2 = true power = 43 } if (tag.indexOf('chademo') !== -1) { found_type_chademo = true // console.log('tag chademo', tag) power = 63 } let value = feature.properties.tags[tag] if (value && tag.toLowerCase().indexOf('output') !== -1) { // console.log('tag contient output', tag, value) value = '' + value if (value.replace) { value = value.replace(' ') value = value.replace('kW', '') } let power = parseInt(value) // deviner les types de prises présents // if (power) { // console.log('power', power) // console.log('outputPower', outputPower) // } if (power > outputPower) { outputPower = power // console.log('power', power) } } } } feature.properties.outputPower = outputPower return outputPower } // 2024-12-16: au delà d'une valeur de 400kW on peut dire qu'il existe une erreur de saisie, nous n'avons pas de chargeur de 1800kW en production. const max_out_legit_power = 400 const error_color = 'red' function getColor (feature) { let outputPower = guessOutputPowerFromFeature(feature) feature.properties.tags.has_output_of_irve_specified = outputPower if (outputPower) { if(outputPower> max_out_legit_power){ return error_color; } let index = Math.min(Math.floor(outputPower / 10), colors.length - 1) return colors[index] } // autrement, sans puissance max trouvée, on met la couleur des indéfinis return unknown_color } let coef_reduction_bars = 0.8 function calculerPourcentage (partie, total, reduc) { if (total === 0) { return 'Division par zéro impossible' } let coef_reduction = 1 if (reduc) { coef_reduction = coef_reduction_bars } return ((partie / total) * 100 * coef_reduction).toFixed(1) } function displayStatsFromGeoJson (resultAsGeojson) { let count = resultAsGeojson.features.length let count_station_output = 0 let count_ref_eu = 0 let output_more_than_300 = 0 let output_more_than_200 = 0 let output_more_than_100 = 0 let output_more_than_50 = 0 let count_station_outputoutput_between_1_and_50 = 0 let count_output_unknown = 0 let count_estimated_type2combo = 0 let count_found_type2combo = 0 let count_found_type2 = 0 resultAsGeojson.features.map(feature => { let found_type2_combo = false // trouver si les tags présentent un type combo let found_type2 = false // trouver si les tags présentent un type 2 let keys_of_object = Object.keys(feature.properties.tags) keys_of_object.map(tagKey => { // console.log('tagKey', tagKey) if (tagKey.indexOf('type2_combo') !== -1) { found_type2_combo = true // console.log('tagkey trouvé combo', tagKey) } if (tagKey.indexOf('type2') !== -1) { found_type2 = true } }) let outputPower = guessOutputPowerFromFeature(feature) if (found_type2_combo) { count_found_type2combo++ } if (found_type2) { count_found_type2++ } if (outputPower == 0) { count_output_unknown++ } if (outputPower >= 200 && !found_type2_combo) { /** * si on trouve une puissance supérieure à 200kW on peut partir du principe que la station dispose d'une prise type_2_combo à minima */ count_estimated_type2combo++ } if (outputPower > 0 && outputPower < 50) { count_station_outputoutput_between_1_and_50++ } if (outputPower >= 50 && outputPower < 100) { output_more_than_50++ } else if (outputPower >= 100 && outputPower < 200) { output_more_than_100++ } else if (outputPower >= 200 && outputPower < 300) { output_more_than_200++ } else if (outputPower >= 300) { feature.properties.puissance_haute = true output_more_than_300++ } if (feature.properties.tags['charging_station:output']) { count_station_output++ } if (feature.properties.tags['ref:EU:EVSE']) { count_ref_eu++ } }) let bar_powers = `
` let stats_content = `