OpenDataAPI/scripts/helpers/finess.js

263 lines
9.6 KiB
JavaScript
Raw Normal View History

2024-01-24 16:29:09 +01:00
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}`);
}
}