import fs from 'fs'; import readline from 'readline'; import { downloadJSON, downloadAndSaveFile, filtrerEtEnregistrerLignes, loadEnvFile, customSplit } from './functions.js' import { transformToGPS } from './gps.js' const columns = [ 'nofinesset', 'nofinessej', 'rs', 'rslongue', 'complrs', 'compldistrib', 'numvoie', 'typvoie', 'voie', 'compvoie', 'lieuditbp', 'commune', 'departement', 'libdepartement', 'ligneacheminement', 'telephone', 'telecopie', 'categetab', 'libcategetab', 'categagretab', 'libcategagretab', 'siret', 'codeape', 'codemft', 'libmft', 'codesph', 'libsph', 'dateouv', 'dateautor', 'datemaj', 'numuai', 'coordxet', 'coordyet' ]; export const downloadFiness = async () => { const MAIN_URL = 'https://www.data.gouv.fr/api/1/datasets/finess-extraction-du-fichier-des-etablissements/' const FILENAME = './tmp/finess.csv' const data = await downloadJSON(MAIN_URL); const finessUrl = data.resources.find(r => r.type === "main" && r.title.includes('géolocalisés'))?.url downloadAndSaveFile(finessUrl, FILENAME) } export const transformFiness = async () => { const fichierEntree = './tmp/finess.csv'; const fichierStructures = './tmp/finess_structureet.csv'; const fichierGeolocalisation = './tmp/finess_geolocalisation.csv'; const fichierSortie = './initdb/finess.csv' const conditionFiltre = (ligne) => ligne.includes('structureet'); await filtrerEtEnregistrerLignes(fichierEntree, fichierStructures, fichierGeolocalisation, conditionFiltre); await fusionnerCoordonneesGPSStructures(fichierStructures, fichierGeolocalisation, fichierSortie); } // Fonction pour fusionner les coordonnées GPS dans le fichier CSV de structures export async function fusionnerCoordonneesGPSStructures(fichierStructures, fichierCoordonnees, fichierSortie) { try { // Créer un flux de lecture pour le fichier de coordonnées const lecteurCoordonnees = readline.createInterface({ input: fs.createReadStream(fichierCoordonnees), crlfDelay: Infinity }); // Créer un dictionnaire pour stocker les coordonnées par structureid const coordonnees = {}; // Fonction pour traiter chaque ligne du fichier de coordonnées const traiterLigneCoordonnees = (ligne) => { // exemple de ligne // geolocalisation;970300802;317351.6;571220.2;2,ATLASANTE,100,IGN,BD_ADRESSE,V2.2,UTM_N22;2024-01-08 const valeurs = ligne.split(';'); const structureid = valeurs[1]; const coordX = parseFloat(valeurs[2]); const coordY = parseFloat(valeurs[3]); const system = valeurs[4] coordonnees[structureid] = { system, coordX, coordY }; }; // Lire chaque ligne du fichier de coordonnées for await (const ligne of lecteurCoordonnees) { traiterLigneCoordonnees(ligne); } // Créer un flux de lecture pour le fichier de structures const lecteurStructures = readline.createInterface({ input: fs.createReadStream(fichierStructures), crlfDelay: Infinity }); // Créer un flux d'écriture vers le fichier de sortie const fichierSortieStream = fs.createWriteStream(fichierSortie); // Création de l'entête d'insertion // fichierSortieStream.write('INSERT INTO finess (' + columns.join(', ') + ') VALUES\n'); fichierSortieStream.write(columns.join(";") + '\n'); const ecrireLigneStructure = (ligne, isFirst) => { let dataArray = ligne.split(';'); // Fix le nom d'une association contenant un ; ... "ASSO; LA RELÈVE" if (dataArray.length > 34) { dataArray = customSplit(ligne, ';') dataArray = dataArray.map(value => value.replaceAll(";", "%3B")) } dataArray.shift(); // Suppression du premier champs inutil // const defaultValue = (value) => (value === null || value === '' ? 'NULL' : `'${value.replaceAll("'", "''")}'`) // const typedData = { // nofinesset: defaultValue(dataArray[0]), // nofinessej: defaultValue(dataArray[1]), // rs: defaultValue(dataArray[2]), // rslongue: defaultValue(dataArray[3]), // complrs: defaultValue(dataArray[4]), // compldistrib: defaultValue(dataArray[5]), // numvoie: defaultValue(dataArray[6]), // typvoie: defaultValue(dataArray[7]), // voie: defaultValue(dataArray[8]), // compvoie: defaultValue(dataArray[9]), // lieuditbp: defaultValue(dataArray[10]), // commune: defaultValue(dataArray[11]), // departement: defaultValue(dataArray[12]), // libdepartement: defaultValue(dataArray[13]), // ligneacheminement: defaultValue(dataArray[14]), // telephone: defaultValue(dataArray[15]), // telecopie: defaultValue(dataArray[16]), // categetab: defaultValue(dataArray[17]), // libcategetab: defaultValue(dataArray[18]), // categagretab: defaultValue(dataArray[19]), // libcategagretab: defaultValue(dataArray[20]), // siret: defaultValue(dataArray[21]), // codeape: defaultValue(dataArray[22]), // codemft: defaultValue(dataArray[23]), // libmft: defaultValue(dataArray[24]), // codesph: defaultValue(dataArray[25]), // libsph: defaultValue(dataArray[26]), // dateouv: defaultValue((new Date(dataArray[27] || '1900-01-01')).toISOString().split('T')[0]), // Utilise la date par défaut si la date est vide // dateautor: defaultValue((new Date(dataArray[28] || '1900-01-01')).toISOString().split('T')[0]), // datemaj: defaultValue((new Date(dataArray[29] || '1900-01-01')).toISOString().split('T')[0]), // numuai: defaultValue(dataArray[30]), // coordxet: dataArray[31] ? parseFloat(dataArray[31]) : 'NULL', // coordyet: dataArray[32] ? parseFloat(dataArray[32]) : 'NULL', // }; // if (typedData.nofinesset === '690051545') { // console.log(dataArray[20]) // } // const formattedData = Object.values(typedData).map((value) => (isNaN(value) ? `'${value.replaceAll("'", "''")}'` : (value === null || value === '' ? 'NULL' : value))); // Assurez-vous que les chaînes sont entourées de guillemets simples // fichierSortieStream.write(`${isFirst ? '' : ',\n'} (${Object.values(typedData).join(', ')})`); // fichierSortieStream.write('INSERT INTO finess (' + columns.join(', ') + ') VALUES ' + `(${Object.values(typedData).join(', ')});\n`); fichierSortieStream.write(`${dataArray.join(';')}\n`); } let isFirst = true // Lire chaque ligne du fichier de structures for await (const ligne of lecteurStructures) { const valeurs = ligne.split(';'); const structureid = valeurs[1]; // Vérifier si des coordonnées existent pour cette structureid if (coordonnees.hasOwnProperty(structureid)) { const { system, coordX, coordY } = coordonnees[structureid]; const coordonneesGPS = transformToGPS(system, coordX, coordY); if (coordonneesGPS) { // Écrire les valeurs dans le fichier de sortie ecrireLigneStructure(`${ligne};${coordonneesGPS.latitude};${coordonneesGPS.longitude}`, isFirst); } else { // Si aucune coordonnée n'est disponible, écrire la ligne telle quelle dans le fichier de sortie ecrireLigneStructure(`${ligne};;`, isFirst); } } else { // Si aucune coordonnée n'est disponible, écrire la ligne telle quelle dans le fichier de sortie ecrireLigneStructure(`${ligne};;`, isFirst); } isFirst = false } // Fermer la parenthèse finale et le point-virgule // fichierSortieStream.write(';'); fichierSortieStream.end(); console.log(`Le fichier SQL a été généré : ${fichierSortie}`); console.log('Fusion des coordonnées GPS dans le fichier de structures terminée.'); } catch (erreur) { console.error(`Erreur lors de la fusion des coordonnées GPS : ${erreur.message}`); } }