mirror of
https://forge.chapril.org/tykayn/libre-charge-map
synced 2025-06-20 01:34:43 +02:00
187 lines
7.5 KiB
JavaScript
187 lines
7.5 KiB
JavaScript
/**
|
|
/**
|
|
* compter les stations IRVE par ville et les tags associés
|
|
*/
|
|
import fs from 'fs';
|
|
import fetch from 'node-fetch';
|
|
|
|
const distanceThreshold = 10; // Distance maximale en km du centre ville
|
|
// Liste des 15 plus grandes villes de France avec leurs coordonnées et seuils spécifiques
|
|
|
|
const cities = [
|
|
{ name: "Paris", coords: [48.8566, 2.3522], threshold: 15 }, // Plus grande ville, plus grand rayon
|
|
{ name: "Marseille", coords: [43.2965, 5.3700], threshold: 12 },
|
|
{ name: "Lyon", coords: [45.7640, 4.8357], threshold: 12 },
|
|
{ name: "Toulouse", coords: [43.6047, 1.4442], threshold: 10 },
|
|
{ name: "Nice", coords: [43.7055, 7.262], threshold: 10 },
|
|
{ name: "Nantes", coords: [47.2184, -1.5536], threshold: 10 },
|
|
{ name: "Montpellier", coords: [43.6108, 3.8767], threshold: 8 },
|
|
{ name: "Strasbourg", coords: [48.5734, 7.7521], threshold: 8 },
|
|
{ name: "Bordeaux", coords: [44.8378, -0.5792], threshold: 8 },
|
|
{ name: "Lille", coords: [50.6292, 3.0585], threshold: 8 },
|
|
{ name: "Rennes", coords: [48.1141, -1.6778], threshold: 8 },
|
|
{ name: "Reims", coords: [49.2583, 4.0316], threshold: 6 },
|
|
{ name: "Le Havre", coords: [49.4944, 0.1064], threshold: 6 },
|
|
{ name: "Saint-Étienne", coords: [45.4484, 4.3928], threshold: 6 },
|
|
{ name: "Toulon", coords: [43.1242, 5.928], threshold: 6 },
|
|
{ name: "Rouen", coords: [49.4431, 1.0993], threshold: 6 },
|
|
{ name: "Ajaccio", coords: [41.9192, 8.7386], threshold: 6 },
|
|
{ name: "Saint-Denis", coords: [-20.8789, 55.4481], threshold: 6 },
|
|
{ name: "Brest", coords: [48.3904, -4.4861], threshold: 6 },
|
|
{ name: "Cergy", coords: [49.0379, 2.0760], threshold: 6 },
|
|
{ name: "Évry", coords: [48.6240, 2.4350], threshold: 6 },
|
|
{ name: "Saint-Quentin-en-Yvelines", coords: [48.7704, 2.0150], threshold: 4 },
|
|
{ name: "Marne-la-Vallée", coords: [48.8439, 2.7875], threshold: 4 },
|
|
{ name: "Melun-Sénart", coords: [48.5711, 2.6298], threshold: 4 },
|
|
{ name: "Dieppe", coords: [49.9237, 1.0789], threshold: 4 },
|
|
{ name: "Le Mans", coords: [48.0061, 0.1996], threshold: 4 },
|
|
{ name: "Orléans", coords: [47.9029, 1.9039], threshold: 4 },
|
|
{ name: "Nîmes", coords: [43.8367, 4.3600], threshold: 4 },
|
|
{ name: "Aix-en-Provence", coords: [43.5297, 5.4474], threshold: 4 },
|
|
{ name: "Tours", coords: [47.3942, 0.6900], threshold: 4 },
|
|
{ name: "Limoges", coords: [45.8333, 1.2500], threshold: 4 },
|
|
{ name: "Angers", coords: [47.4785, -0.5632], threshold: 4 },
|
|
{ name: "Lorient", coords: [47.7479, -2.7795], threshold: 4 },
|
|
{ name: "Saint-Nazaire", coords: [47.2862, -2.2133], threshold: 4 },
|
|
{ name: "Saint-Malo", coords: [48.6455, -2.0155], threshold: 4 },
|
|
{ name: "Saint-Étienne-du-Rouvray", coords: [49.3833, 1.0833], threshold: 4 },
|
|
{ name: "Saint-Quentin", coords: [49.8333, 2.8833], threshold: 4 },
|
|
|
|
|
|
];
|
|
|
|
// Fonction pour charger les données GeoJSON
|
|
function loadGeojson(filePath) {
|
|
try {
|
|
const data = fs.readFileSync(filePath, 'utf8');
|
|
return JSON.parse(data);
|
|
} catch (error) {
|
|
console.error('Erreur lors du chargement du fichier GeoJSON:', error.message);
|
|
throw new Error(`Impossible de charger le fichier ${filePath}: ${error.message}`);
|
|
}
|
|
|
|
}
|
|
|
|
// Fonction pour télécharger le fichier si manquant
|
|
async function ensureDataFile(filePath) {
|
|
if (!fs.existsSync(filePath)) {
|
|
console.log('Téléchargement du fichier opendata.json...');
|
|
const response = await fetch('https://www.data.gouv.fr/fr/datasets/r/7eee8f09-5d1b-4f48-a304-5e99e8da1e26');
|
|
const buffer = await response.arrayBuffer();
|
|
fs.writeFileSync(filePath, Buffer.from(buffer));
|
|
console.log('Téléchargement terminé');
|
|
}
|
|
}
|
|
|
|
// Fonction pour calculer la distance entre deux points en km
|
|
function calculateDistance(lat1, lon1, lat2, lon2) {
|
|
const R = 6371; // Rayon de la Terre en km
|
|
const dLat = (lat2 - lat1) * Math.PI / 180;
|
|
const dLon = (lon2 - lon1) * Math.PI / 180;
|
|
const a =
|
|
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
|
|
Math.sin(dLon / 2) * Math.sin(dLon / 2);
|
|
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
return R * c;
|
|
}
|
|
|
|
// Fonction pour compter le nombre d'éléments IRVE par ville et les tags associés
|
|
function countIrveByCityWithTags(irveData, cities, distanceThreshold) {
|
|
const irveCountByCity = [];
|
|
const allTags = new Map();
|
|
const irvePoints = irveData.elements;
|
|
// const irvePoints = irveData.features;
|
|
// console.log(irveData.elements.length, 'irvePoints dans le fichier', irvePoints.length, 'rayon : ', distanceThreshold, 'km');
|
|
|
|
// Pour chaque ville
|
|
for (const city of cities) {
|
|
const cityTagsCount = new Map();
|
|
let totalCount = 0;
|
|
let totalCapacity = 0;
|
|
|
|
// Pour chaque point IRVE
|
|
for (let i = 0; i < irvePoints.length; i++) {
|
|
if (irvePoints[i].lon !== undefined && irvePoints[i].lat !== undefined) {
|
|
const distance = calculateDistance(
|
|
city.coords[0], // latitude de la ville (premier élément)
|
|
city.coords[1], // longitude de la ville (deuxième élément)
|
|
irvePoints[i].lat,
|
|
irvePoints[i].lon
|
|
);
|
|
// console.log(irvePoints[i].lon, irvePoints[i].lat, 'distance : ', distance, 'km');
|
|
|
|
if (distance <= city.threshold) {
|
|
totalCount++;
|
|
totalCapacity += (irvePoints[i].tags?.capacity * 1) || 0;
|
|
const tags = irvePoints[i].tags || {};
|
|
for (const [tag, value] of Object.entries(tags)) {
|
|
cityTagsCount.set(tag, (cityTagsCount.get(tag) || 0) + 1);
|
|
allTags.set(tag, (allTags.get(tag) || 0) + 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Créer la feature pour la ville
|
|
const cityFeature = {
|
|
type: "Feature",
|
|
geometry: {
|
|
type: "Point",
|
|
coordinates: [city.coords[1], city.coords[0]]
|
|
},
|
|
properties: {
|
|
name: city.name,
|
|
totalCount: totalCount,
|
|
totalCapacity: totalCapacity,
|
|
threshold: city.threshold,
|
|
tags: Object.fromEntries(cityTagsCount)
|
|
}
|
|
};
|
|
irveCountByCity.push(cityFeature);
|
|
console.log(totalCount, totalCapacity, city.name);
|
|
}
|
|
return irveCountByCity;
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fonction pour sauvegarder les résultats dans un fichier GeoJSON
|
|
function saveGeojson(data, filePath) {
|
|
const featureCollection = {
|
|
type: "FeatureCollection",
|
|
features: data
|
|
};
|
|
fs.writeFileSync(filePath, JSON.stringify(featureCollection, null, 2));
|
|
}
|
|
|
|
// Chemins des fichiers GeoJSON d'entrée et de sortie
|
|
const inputFilePath = 'js/openstreetmap.json';
|
|
const outputFilePath = 'js/irve_count_by_city_with_tags.geojson';
|
|
|
|
// Exécution du script
|
|
try {
|
|
// await ensureDataFile(inputFilePath);
|
|
const irveData = loadGeojson(inputFilePath);
|
|
|
|
// Compter le nombre d'éléments IRVE par ville et les tags associés
|
|
const irveCountByCityWithTags = countIrveByCityWithTags(irveData, cities, distanceThreshold);
|
|
|
|
// Sauvegarder les résultats dans un fichier GeoJSON
|
|
saveGeojson(irveCountByCityWithTags, outputFilePath);
|
|
|
|
// Créer un fichier CSV avec les totaux par ville
|
|
const csvContent = irveCountByCityWithTags
|
|
.map(city => `${city.properties.name},${city.properties.totalCount},${city.properties.totalCapacity}`)
|
|
.join('\n');
|
|
|
|
const csvHeader = 'Ville,Nombre total de bornes,Capacité totale\n';
|
|
fs.writeFileSync('js/irve_totaux_par_ville.csv', csvHeader + csvContent);
|
|
console.log('Les totaux par ville ont été sauvés dans js/irve_totaux_par_ville.csv');
|
|
|
|
console.log(`Les résultats ont été sauvés dans ${outputFilePath}`);
|
|
} catch (error) {
|
|
console.error('Erreur lors de l\'exécution du script:', error);
|
|
}
|
|
|