import fs from 'fs'; import readline from 'readline'; import pg from 'pg'; import { downloadJSON, downloadAndSaveFile, filtrerEtEnregistrerLignes, loadEnvFile } from './functions.js' import { transformToGPS } from './gps.js' const { Pool } = pg 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 conditionFiltre = (ligne) => ligne.includes('structureet'); await filtrerEtEnregistrerLignes(fichierEntree, fichierStructures, fichierGeolocalisation, conditionFiltre); await fusionnerCoordonneesGPSStructures(fichierStructures, fichierGeolocalisation, fichierEntree); } export const importFiness = async () => { // Exemple d'utilisation avec le nom du fichier CSV const fichierEntree = './tmp/finess.csv'; insererDonneesPostgres(fichierEntree); } // 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 Lambert 93 const lecteurCoordonnees = readline.createInterface({ input: fs.createReadStream(fichierCoordonnees), crlfDelay: Infinity }); // Créer un dictionnaire pour stocker les coordonnées Lambert 93 par structureid const coordonnees = {}; // Fonction pour traiter chaque ligne du fichier de coordonnées Lambert 93 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 Lambert 93 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); // Écrire l'entête dans le fichier de sortie // fichierSortieStream.write('structureid,nofinesset,coordxet,coordyet,latitude,longitude\n'); // Fonction pour traiter chaque ligne du fichier de structures const traiterLigneStructures = (ligne) => { const valeurs = ligne.split(';'); const structureid = valeurs[1]; // Vérifier si des coordonnées Lambert 93 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 fichierSortieStream.write(`${ligne};${coordonneesGPS.latitude};${coordonneesGPS.longitude}\n`); } else { // Si aucune coordonnée n'est disponible, écrire la ligne telle quelle dans le fichier de sortie fichierSortieStream.write(`${ligne};;\n`); } } else { // Si aucune coordonnée n'est disponible, écrire la ligne telle quelle dans le fichier de sortie fichierSortieStream.write(`${ligne};;\n`); } }; // Lire chaque ligne du fichier de structures for await (const ligne of lecteurStructures) { traiterLigneStructures(ligne); } 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}`); } } // Fonction pour lire le fichier CSV et insérer les données dans PostgreSQL export async function insererDonneesPostgres(nomFichierCSV) { const envVariables = loadEnvFile() const pool = new Pool({ user: envVariables.POSTGRES_USER, host: 'localhost', database: envVariables.POSTGRES_DB, password: envVariables.POSTGRES_PASSWORD, port: 5432, max: 10, // Nombre maximum de connexions dans le pool idleTimeoutMillis: 30000, // Délai d'attente maximum pour une connexion avant d'être libérée }); const client = await pool.connect(); 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' ]; // Fonction pour insérer une ligne dans la base de données async function insertRow(data) { const query = { text: `INSERT INTO finess (${columns.join(', ')}) VALUES (${columns.map((col, index) => `$${index + 1}`).join(', ')})`, values: data, }; const client = await pool.connect(); try { await client.query(query); } catch (error) { console.log(data.join(', ')) console.error('Erreur lors de l\'insertion de la ligne:', error.message || error); } finally { client.release(); // Libérer la connexion du pool } } // Fonction pour lire le fichier ligne par ligne et appeler la fonction d'insertion async function processFile(filePath) { const fileStream = fs.createReadStream(filePath); const rl = readline.createInterface({ input: fileStream, crlfDelay: Infinity, }); for await (const [index, line] of rl) { // Supposons que les données dans le fichier soient séparées par des virgules (à ajuster selon votre format) let data = line.split(';'); data.shift(); if (data[27] === '') data[27] = null if (data[28] === '') data[28] = null if (data[29] === '') data[29] = null // Appeler la fonction d'insertion avec la ligne de données await insertRow(data); console.log(index) } // Fermer le pool de connexions à la base de données à la fin du traitement await pool.end(); } // await creerTableFINESS(client); await processFile(nomFichierCSV) } // Fonction pour créer la table FINESS dans PostgreSQL export async function creerTableFINESS(client) { try { // Requête SQL de création de table const requeteCreationTable = ` CREATE TABLE IF NOT EXISTS finess ( nofinesset VARCHAR(255), nofinessej VARCHAR(255), rs VARCHAR(255), rslongue VARCHAR(255), complrs VARCHAR(255), compldistrib VARCHAR(255), numvoie VARCHAR(255), typvoie VARCHAR(255), voie VARCHAR(255), compvoie VARCHAR(255), lieuditbp VARCHAR(255), commune VARCHAR(255), departement VARCHAR(255), libdepartement VARCHAR(255), ligneacheminement VARCHAR(255), telephone VARCHAR(255), telecopie VARCHAR(255), categetab VARCHAR(255), libcategetab VARCHAR(255), categagretab VARCHAR(255), libcategagretab VARCHAR(255), siret VARCHAR(255), codeape VARCHAR(255), codemft VARCHAR(255), libmft VARCHAR(255), codesph VARCHAR(255), libsph VARCHAR(255), dateouv DATE DEFAULT '1900-01-01', dateautor DATE DEFAULT '1900-01-01', datemaj DATE DEFAULT '1900-01-01', numuai VARCHAR(255), coordxet FLOAT DEFAULT 0, coordyet FLOAT DEFAULT 0, PRIMARY KEY (nofinesset) ); `; // Exécution de la requête de création de table await client.query(requeteCreationTable); console.log('Table FINESS créée avec succès.'); } catch (erreur) { console.error(`Erreur lors de la création de la table : ${erreur.message}`); } }