WIP
This commit is contained in:
262
scripts/helpers/finess.js
Normal file
262
scripts/helpers/finess.js
Normal file
@ -0,0 +1,262 @@
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
|
72
scripts/helpers/functions.js
Normal file
72
scripts/helpers/functions.js
Normal file
@ -0,0 +1,72 @@
|
||||
import path from 'path';
|
||||
import fs from 'fs'
|
||||
import { writeFile, mkdir } from 'fs/promises'
|
||||
import readline from 'readline';
|
||||
|
||||
export const loadEnvFile = () => {
|
||||
// Charger les variables d'environnement à partir du fichier .env
|
||||
const envPath = './.env'; // Spécifiez le chemin correct si différent
|
||||
const envFile = fs.readFileSync(envPath, 'utf-8');
|
||||
const envVariables = envFile.split('\n').reduce((acc, line) => {
|
||||
const [key, value] = line.split('=');
|
||||
if (key && value) {
|
||||
acc[key.trim()] = value.trim();
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
return envVariables
|
||||
}
|
||||
|
||||
export const downloadAndSaveFile = async (url, filename) => {
|
||||
const folder = path.dirname(filename)
|
||||
if (!fs.existsSync(folder)) await mkdir(folder)
|
||||
const response = await fetch(url)
|
||||
const buffer = Buffer.from(await response.arrayBuffer())
|
||||
await writeFile(filename, buffer)
|
||||
}
|
||||
|
||||
export const downloadJSON = async (url) => (await fetch(url)).json()
|
||||
|
||||
// Fonction pour lire un fichier ligne par ligne et filtrer les lignes en fonction de la condition
|
||||
export async function filtrerEtEnregistrerLignes(fichierEntree, fichierSortie1, fichierSortie2, condition) {
|
||||
try {
|
||||
// Créer un flux de lecture pour le fichier d'entrée
|
||||
const lecteur = readline.createInterface({
|
||||
input: fs.createReadStream(fichierEntree),
|
||||
crlfDelay: Infinity
|
||||
});
|
||||
|
||||
// Créer un flux d'écriture pour le fichier de sortie 1
|
||||
const fichierSortieStream1 = fs.createWriteStream(fichierSortie1);
|
||||
|
||||
// Créer un flux d'écriture pour le fichier de sortie 2
|
||||
const fichierSortieStream2 = fs.createWriteStream(fichierSortie2);
|
||||
|
||||
// Fonction pour traiter chaque ligne du fichier
|
||||
const traiterLigne = (ligne) => {
|
||||
// Appliquer la condition à la ligne
|
||||
if (condition(ligne)) {
|
||||
// Écrire la ligne dans le fichier de sortie 1
|
||||
fichierSortieStream1.write(`${ligne}\n`);
|
||||
} else {
|
||||
// Écrire la ligne dans le fichier de sortie 2
|
||||
fichierSortieStream2.write(`${ligne}\n`);
|
||||
}
|
||||
};
|
||||
|
||||
// Lire chaque ligne du fichier
|
||||
for await (const ligne of lecteur) {
|
||||
traiterLigne(ligne);
|
||||
}
|
||||
|
||||
console.log('Filtrage et enregistrement des lignes terminés.');
|
||||
|
||||
// Fermer les flux d'écriture
|
||||
fichierSortieStream1.end();
|
||||
fichierSortieStream2.end();
|
||||
|
||||
} catch (erreur) {
|
||||
console.error(`Erreur lors du filtrage et de l'enregistrement des lignes : ${erreur.message}`);
|
||||
}
|
||||
}
|
88
scripts/helpers/gps.js
Normal file
88
scripts/helpers/gps.js
Normal file
@ -0,0 +1,88 @@
|
||||
import proj4 from 'proj4'
|
||||
|
||||
// Définir les paramètres de la projection WGS84 (EPSG:4326) (GPS)
|
||||
proj4.defs('EPSG:4326', '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection Lambert 93 (EPSG:2154)
|
||||
proj4.defs('EPSG:2154', '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection UTM Zone 20N (EPSG:32620)
|
||||
proj4.defs('EPSG:32620', '+proj=utm +zone=20 +ellps=WGS84 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection UTM_N21 (exemple)
|
||||
proj4.defs('EPSG:32621', '+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection UTM_N22 (exemple)
|
||||
proj4.defs('EPSG:32622', '+proj=utm +zone=22 +ellps=WGS84 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection UTM_S38 (exemple)
|
||||
proj4.defs('EPSG:32638', '+proj=utm +zone=38 +ellps=WGS84 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
// Définir les paramètres de la projection UTM_S40 (exemple)
|
||||
proj4.defs('EPSG:32740', '+proj=utm +zone=40 +ellps=WGS84 +datum=WGS84 +units=m +no_defs');
|
||||
|
||||
|
||||
export const transformToGPS = (system, coordX, coordY, ) => {
|
||||
if (system.includes('LAMBERT_93')) {
|
||||
return lambert93toGPS(coordX, coordY)
|
||||
}
|
||||
if (system.includes('UTM_N20')) {
|
||||
return utmN20toGPS(coordX, coordY)
|
||||
}
|
||||
if (system.includes('UTM_N21')) {
|
||||
return utmN21toGPS(coordX, coordY)
|
||||
}
|
||||
if (system.includes('UTM_N22')) {
|
||||
return utmN22toGPS(coordX, coordY)
|
||||
}
|
||||
if (system.includes('UTM_S38')) {
|
||||
return utmS38toGPS(coordX, coordY)
|
||||
}
|
||||
if (system.includes('UTM_S40')) {
|
||||
return utmS40toGPS(coordX, coordY)
|
||||
}
|
||||
|
||||
console.error(system);
|
||||
}
|
||||
|
||||
function lambert93toGPS(easting, northing) {
|
||||
// Convertir les coordonnées Lambert 93 en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:2154', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
||||
|
||||
function utmN20toGPS(easting, northing) {
|
||||
// Convertir les coordonnées UTM en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:32620', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
||||
|
||||
function utmN21toGPS(easting, northing) {
|
||||
// Convertir les coordonnées UTM_N21 en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:32621', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
||||
|
||||
function utmN22toGPS(easting, northing) {
|
||||
// Convertir les coordonnées UTM_N22 en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:32622', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
||||
|
||||
function utmS38toGPS(easting, northing) {
|
||||
// Convertir les coordonnées UTM_S38 en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:32638', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
||||
|
||||
function utmS40toGPS(easting, northing) {
|
||||
// Convertir les coordonnées UTM_S40 en WGS84 (GPS)
|
||||
const [longitude, latitude] = proj4('EPSG:32740', 'EPSG:4326', [easting, northing]);
|
||||
|
||||
return { latitude, longitude };
|
||||
}
|
Reference in New Issue
Block a user