mirror of
https://forge.chapril.org/tykayn/libre-charge-map
synced 2025-10-04 17:04:53 +02:00
ajout temps de charge moyen
This commit is contained in:
parent
0ce172f706
commit
24e1800085
6 changed files with 167 additions and 29 deletions
|
@ -125,6 +125,13 @@
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="average_charge_kwh">
|
||||||
|
Consommation moyenne sur une charge rapide (kWh) :
|
||||||
|
</label>
|
||||||
|
<input type="number" id="average_charge_kwh" min="1" max="200" value="26" step="1"
|
||||||
|
style="width: 4em;">
|
||||||
</p>
|
</p>
|
||||||
<div class="filter-sockets" id="filterSockets">
|
<div class="filter-sockets" id="filterSockets">
|
||||||
|
|
||||||
|
|
4
js/langs/en.json
Normal file
4
js/langs/en.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"filter_title": "Filters",
|
||||||
|
"filter_description": "Display stations with a power greater than:"
|
||||||
|
}
|
4
js/langs/fr.json
Normal file
4
js/langs/fr.json
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"filter_title": "Filtres",
|
||||||
|
"filter_description": "Afficher les stations avec une puissance supérieure à:"
|
||||||
|
}
|
70
js/lcm_i18n.js
Normal file
70
js/lcm_i18n.js
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gestion des traductions dans libre charge map
|
||||||
|
*/
|
||||||
|
class LcmI18n {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.i18n = {};
|
||||||
|
this.language = this.detectLanguage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Détecte la langue préférée du navigateur
|
||||||
|
* @returns {string} Code de langue sur 2 caractères (ex: 'fr', 'en')
|
||||||
|
*/
|
||||||
|
detectLanguage() {
|
||||||
|
// Récupérer la langue du navigateur
|
||||||
|
const browserLang = navigator.language || navigator.userLanguage;
|
||||||
|
|
||||||
|
// Extraire les 2 premiers caractères (code langue)
|
||||||
|
const lang = browserLang.substring(0, 2).toLowerCase();
|
||||||
|
|
||||||
|
// Par défaut retourner 'en' si la langue n'est pas reconnue
|
||||||
|
return lang || 'en';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Récupère la langue courante
|
||||||
|
* @returns {string} Code de langue sur 2 caractères (ex: 'fr', 'en')
|
||||||
|
*/
|
||||||
|
getCurrentLanguage() {
|
||||||
|
return this.language;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Traduit une chaîne de caractères dans la langue courante
|
||||||
|
* @param {string} key - Clé de traduction
|
||||||
|
* @param {Object} params - Paramètres optionnels pour la substitution
|
||||||
|
* @returns {string} Chaîne traduite
|
||||||
|
*/
|
||||||
|
translate(key, params = {}) {
|
||||||
|
// Vérifier si la clé existe dans les traductions
|
||||||
|
if (!this.i18n[this.language] || !this.i18n[this.language][key]) {
|
||||||
|
console.error(`[LcmI18n] Clé de traduction introuvable: "${key}" pour la langue "${this.language}"`);
|
||||||
|
|
||||||
|
return 'I18N_RROR[' + key + ']';
|
||||||
|
}
|
||||||
|
// Obtenir les traductions pour la langue courante
|
||||||
|
const translations = this.i18n[this.language] || {};
|
||||||
|
|
||||||
|
// Récupérer la traduction ou utiliser la clé par défaut
|
||||||
|
let translation = translations[key] || key;
|
||||||
|
|
||||||
|
// Remplacer les paramètres dans la traduction
|
||||||
|
Object.keys(params).forEach(param => {
|
||||||
|
translation = translation.replace(`{${param}}`, params[param]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alias raccourci pour la méthode translate()
|
||||||
|
*/
|
||||||
|
t(key, params = {}) {
|
||||||
|
return this.translate(key, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const lcm_i18n = new LcmI18n();
|
102
js/lcm_main.js
102
js/lcm_main.js
|
@ -13,6 +13,7 @@ let geojsondata;
|
||||||
let lastLatLng;
|
let lastLatLng;
|
||||||
let searchLocationMarker = null;
|
let searchLocationMarker = null;
|
||||||
let count_hidden_by_filters = 0;
|
let count_hidden_by_filters = 0;
|
||||||
|
let averageChargeKwh = 26;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -691,9 +692,22 @@ function eachFeature(feature, layer, stats) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calcul du temps de recharge
|
||||||
|
let rechargeTimeText = '';
|
||||||
|
if (outPowerGuessed && outPowerGuessed > 0) {
|
||||||
|
const hours = averageChargeKwh / outPowerGuessed;
|
||||||
|
const minutes = Math.round(hours * 60);
|
||||||
|
const h = Math.floor(minutes / 60);
|
||||||
|
const m = minutes % 60;
|
||||||
|
rechargeTimeText = `<div class="recharge-time">
|
||||||
|
⏱️ Temps moyen de recharge :
|
||||||
|
<strong>${h > 0 ? h + 'h ' : ''}${m} min</strong>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
// contenu de la popup
|
// contenu de la popup
|
||||||
let html = `<span class="color-indication" style="background-color: ${lcm_color_utils.getColor(feature)};">${displayOutPowerGuessed}</span>
|
let html = `<span class="color-indication" style="background-color: ${lcm_color_utils.getColor(feature)};">${displayOutPowerGuessed}</span>
|
||||||
|
${rechargeTimeText}
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div class="socket-list">
|
<div class="socket-list">
|
||||||
${displaySocketsList(feature)}
|
${displaySocketsList(feature)}
|
||||||
|
@ -850,18 +864,34 @@ function eachFeature(feature, layer, stats) {
|
||||||
* @param {*} feature
|
* @param {*} feature
|
||||||
*/
|
*/
|
||||||
function fillDetailsWithFeature(feature) {
|
function fillDetailsWithFeature(feature) {
|
||||||
|
// Stocker le feature courant pour pouvoir rafraîchir le détail si besoin
|
||||||
|
$('#current_station_infos').data('currentFeature', feature);
|
||||||
|
|
||||||
// Ajout du lien vers Panoramax
|
// Ajout du lien vers Panoramax
|
||||||
const panoramaxLink = `https://api.panoramax.xyz/#focus=map&map=16.7/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}&speed=250`;
|
const panoramaxLink = `https://api.panoramax.xyz/#focus=map&map=16.7/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}&speed=250`;
|
||||||
|
|
||||||
|
|
||||||
let link_josm = createJOSMEditLink(feature);
|
let link_josm = createJOSMEditLink(feature);
|
||||||
let outPowerGuessed = lcm_utils.guessOutputPowerFromFeature(feature);
|
let outPowerGuessed = lcm_utils.guessOutputPowerFromFeature(feature);
|
||||||
let displayOutPowerGuessed = '? kW';
|
let displayOutPowerGuessed = '? kW';
|
||||||
if (outPowerGuessed) {
|
if (outPowerGuessed) {
|
||||||
displayOutPowerGuessed = outPowerGuessed + ' kW max';
|
displayOutPowerGuessed = outPowerGuessed + ' kW max';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AJOUT : Calcul du temps de recharge pour le panneau latéral
|
||||||
|
let rechargeTimeText = '';
|
||||||
|
if (outPowerGuessed && outPowerGuessed > 0) {
|
||||||
|
const hours = averageChargeKwh / outPowerGuessed;
|
||||||
|
const minutes = Math.round(hours * 60);
|
||||||
|
const h = Math.floor(minutes / 60);
|
||||||
|
const m = minutes % 60;
|
||||||
|
rechargeTimeText = `<div class="recharge-time">
|
||||||
|
⏱️ Temps estimé pour charger ${averageChargeKwh} kWh à ${outPowerGuessed} kW :
|
||||||
|
<strong>${h > 0 ? h + 'h ' : ''}${m} min</strong>
|
||||||
|
</div>`;
|
||||||
|
} else {
|
||||||
|
rechargeTimeText = `<div class="recharge-time">⏱️ Temps estimé : puissance inconnue</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
let content = '';
|
let content = '';
|
||||||
let table_details = '';
|
let table_details = '';
|
||||||
let count_features_in_table = 0;
|
let count_features_in_table = 0;
|
||||||
|
@ -884,34 +914,35 @@ function fillDetailsWithFeature(feature) {
|
||||||
if (!count_features_in_table) {
|
if (!count_features_in_table) {
|
||||||
table_details += '<div class="no-feature-in-table">Aucune information renseignée</div>'
|
table_details += '<div class="no-feature-in-table">Aucune information renseignée</div>'
|
||||||
}
|
}
|
||||||
content += ` <span class="color-indication" style="background-color: ${lcm_color_utils.getColor(feature)};">${displayOutPowerGuessed}</span>
|
content += `
|
||||||
|
<span class="color-indication" style="background-color: ${lcm_color_utils.getColor(feature)};">${displayOutPowerGuessed}</span>
|
||||||
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_car#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire en voiture vers cette station"> 🚗</a>
|
${rechargeTimeText}
|
||||||
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_bike#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire en vélo vers cette station">🚴♀️</a>
|
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_car#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire en voiture vers cette station"> 🚗</a>
|
||||||
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_foot#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire à pied vers cette station">👠</a>
|
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_bike#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire en vélo vers cette station">🚴♀️</a>
|
||||||
|
<a href="https://www.openstreetmap.org/directions?from=&to=${feature.geometry.coordinates[1]},${feature.geometry.coordinates[0]}&engine=fossgis_osrm_foot#map=14/${feature.geometry.coordinates[1]}/${feature.geometry.coordinates[0]}" class="navigation-link by-car" title="itinéraire à pied vers cette station">👠</a>
|
||||||
|
|
||||||
|
|
||||||
<a class="edit-button" href="https://www.openstreetmap.org/edit?editor=id&node=${feature.properties.id}">✏️</a>
|
<a class="edit-button" href="https://www.openstreetmap.org/edit?editor=id&node=${feature.properties.id}">✏️</a>
|
||||||
<a class="edit-button josm" data-href="${link_josm}" href="#">JOSM</a>
|
<a class="edit-button josm" data-href="${link_josm}" href="#">JOSM</a>
|
||||||
<a href="${makeMapCompleteUrl(feature)}" target="_blank" class="edit-button mapcomplete-link" title="Voir sur MapComplete">
|
<a href="${makeMapCompleteUrl(feature)}" target="_blank" class="edit-button mapcomplete-link" title="Voir sur MapComplete">
|
||||||
<img src="https://mapcomplete.org/assets/themes/charging_stations/plug.svg" alt="icone">
|
<img src="https://mapcomplete.org/assets/themes/charging_stations/plug.svg" alt="icone">
|
||||||
</a>
|
</a>
|
||||||
<a href="${panoramaxLink}" target="_blank" class="panoramax-link" title="Voir sur Panoramax">
|
<a href="${panoramaxLink}" target="_blank" class="panoramax-link" title="Voir sur Panoramax">
|
||||||
<img src="styles/images/panoramax.ico" alt="icone">
|
<img src="styles/images/panoramax.ico" alt="icone">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
<div class="socket-list">
|
<div class="socket-list">
|
||||||
${displaySocketsList(feature)}
|
${displaySocketsList(feature)}
|
||||||
</div>
|
</div>
|
||||||
<div class="table-details" >
|
<div class="table-details" >
|
||||||
${table_details}
|
${table_details}
|
||||||
</div>
|
</div>
|
||||||
<div class="bad-tags">
|
<div class="bad-tags">
|
||||||
<h3>Problèmes de qualité</h3>
|
<h3>Problèmes de qualité</h3>
|
||||||
${lcm_utils.displayBadTagsFromFeature(feature)}
|
${lcm_utils.displayBadTagsFromFeature(feature)}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
$('#current_station_infos').html(`<div class='island irve-details'><h2>Détails</h2>${content}</div>`);
|
$('#current_station_infos').html(`<div class='island irve-details'><h2>Détails</h2>${content}</div>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,7 +1051,13 @@ function onMapMoveEnd() {
|
||||||
setCoordinatesOfLeafletMapFromQueryParameters()
|
setCoordinatesOfLeafletMapFromQueryParameters()
|
||||||
|
|
||||||
|
|
||||||
|
import { lcm_i18n } from './lcm_i18n.js';
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
// Charger le service de traduction
|
||||||
|
|
||||||
|
// Détecter la langue du navigateur
|
||||||
|
const currentLanguage = lcm_i18n.detectLanguage();
|
||||||
|
console.log('Langue détectée:', currentLanguage);
|
||||||
init()
|
init()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1481,6 +1518,15 @@ function init() {
|
||||||
|
|
||||||
osmose_markers.addTo(map);
|
osmose_markers.addTo(map);
|
||||||
|
|
||||||
|
$('#average_charge_kwh').val(averageChargeKwh);
|
||||||
|
|
||||||
|
$('#average_charge_kwh').on('input', function () {
|
||||||
|
averageChargeKwh = parseFloat($(this).val()) || 26;
|
||||||
|
// Si un détail de station est affiché, le mettre à jour
|
||||||
|
if ($('#current_station_infos').data('currentFeature')) {
|
||||||
|
fillDetailsWithFeature($('#current_station_infos').data('currentFeature'));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -706,4 +706,11 @@ header {
|
||||||
@include meta.load-css('_mobile.scss');
|
@include meta.load-css('_mobile.scss');
|
||||||
@include meta.load-css('_overrides.scss');
|
@include meta.load-css('_overrides.scss');
|
||||||
@include meta.load-css('_responsive.scss');
|
@include meta.load-css('_responsive.scss');
|
||||||
@include meta.load-css('_animations.scss');
|
@include meta.load-css('_animations.scss');
|
||||||
|
|
||||||
|
.recharge-time {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: #2a2;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue