mirror of
https://forge.chapril.org/tykayn/wololo
synced 2025-06-20 01:34:42 +02:00
add config maxspeed and Echirolles, up script get datasets, start conflation of geojsons
This commit is contained in:
parent
9b5baab032
commit
aa35803a0b
5 changed files with 518 additions and 82 deletions
382
conflate_geojson_with_osm.ts
Normal file
382
conflate_geojson_with_osm.ts
Normal file
|
@ -0,0 +1,382 @@
|
|||
/**
|
||||
* conflate_geojson_with_osm.ts
|
||||
*
|
||||
* Réalise une conflation entre un fichier GeoJSON local et des données OSM via Overpass
|
||||
* en fusionnant les points proches (distance configurable).
|
||||
*
|
||||
* Usage:
|
||||
* npx ts-node conflate_geojson_with_osm.ts <geojson_file> <distance_max_en_metres> <overpass_request>
|
||||
*
|
||||
* Exemple:
|
||||
* npx ts-node conflate_geojson_with_osm.ts data/bornes.geojson 100 "area[name='Limours']->.a;nwr[amenity=charging_station](area.a);"
|
||||
*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import axios from 'axios';
|
||||
import * as turf from '@turf/turf';
|
||||
import * as path from 'path';
|
||||
|
||||
interface GeoJSONGeometry {
|
||||
type: string;
|
||||
coordinates: number[] | number[][] | number[][][] | number[][][][];
|
||||
}
|
||||
|
||||
interface GeoJSONProperties {
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface GeoJSONFeature {
|
||||
type: string;
|
||||
id?: string | number;
|
||||
geometry: GeoJSONGeometry;
|
||||
properties: GeoJSONProperties;
|
||||
}
|
||||
|
||||
interface GeoJSONCollection {
|
||||
type: string;
|
||||
features: GeoJSONFeature[];
|
||||
}
|
||||
|
||||
interface OverpassElement {
|
||||
type: string;
|
||||
id: number;
|
||||
lat?: number;
|
||||
lon?: number;
|
||||
tags?: {
|
||||
[key: string]: string;
|
||||
};
|
||||
nodes?: number[];
|
||||
geometry?: {
|
||||
lat: number;
|
||||
lon: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
interface OverpassResponse {
|
||||
version: number;
|
||||
generator: string;
|
||||
osm3s: {
|
||||
timestamp_osm_base: string;
|
||||
copyright: string;
|
||||
};
|
||||
elements: OverpassElement[];
|
||||
}
|
||||
|
||||
interface MatchedFeaturePair {
|
||||
localFeature: GeoJSONFeature;
|
||||
osmFeature: GeoJSONFeature;
|
||||
distance: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie les arguments et retourne les valeurs
|
||||
*/
|
||||
function checkArguments(): { filePath: string, distance: number, overpassQuery: string } {
|
||||
if (process.argv.length < 5) {
|
||||
console.error("Usage: npx ts-node conflate_geojson_with_osm.ts <geojson_file> <distance_max_en_metres> <overpass_request>");
|
||||
console.error("Exemple: npx ts-node conflate_geojson_with_osm.ts data/bornes.geojson 100 \"area[name='Limours']->.a;nwr[amenity=charging_station](area.a);\"");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const filePath = process.argv[2];
|
||||
const distance = parseFloat(process.argv[3]);
|
||||
const overpassQuery = process.argv[4];
|
||||
|
||||
if (isNaN(distance)) {
|
||||
console.error("La distance doit être un nombre (en mètres)");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return { filePath, distance, overpassQuery };
|
||||
}
|
||||
|
||||
/**
|
||||
* Charge les données GeoJSON à partir d'un fichier
|
||||
*/
|
||||
function loadLocalGeoJSON(filePath: string): GeoJSONCollection {
|
||||
try {
|
||||
const fileContent = fs.readFileSync(filePath, 'utf8');
|
||||
const data = JSON.parse(fileContent);
|
||||
|
||||
if (data.type !== 'FeatureCollection' || !Array.isArray(data.features)) {
|
||||
console.error("Le fichier ne semble pas être un GeoJSON valide avec des features");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
console.error(`Erreur lors du chargement du fichier: ${error}`);
|
||||
process.exit(1);
|
||||
throw error; // Pour TypeScript
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère les données depuis Overpass API
|
||||
*/
|
||||
async function fetchOverpassData(query: string): Promise<GeoJSONCollection> {
|
||||
try {
|
||||
console.log("Récupération des données depuis Overpass API...");
|
||||
console.log(`Requête: ${query}`);
|
||||
|
||||
const encodedQuery = encodeURIComponent(query);
|
||||
const url = `https://overpass-api.de/api/interpreter?data=[out:json][timeout:25];${encodedQuery}out body geom;`;
|
||||
|
||||
const response = await axios.get(url);
|
||||
const overpassData: OverpassResponse = response.data;
|
||||
|
||||
console.log(`${overpassData.elements.length} éléments récupérés depuis Overpass`);
|
||||
|
||||
// Convertir les données Overpass en GeoJSON
|
||||
return convertOverpassToGeoJSON(overpassData);
|
||||
} catch (error) {
|
||||
console.error("Erreur lors de la récupération des données Overpass:", error);
|
||||
process.exit(1);
|
||||
throw error; // Pour TypeScript
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit les données Overpass en GeoJSON
|
||||
*/
|
||||
function convertOverpassToGeoJSON(overpassData: OverpassResponse): GeoJSONCollection {
|
||||
const features: GeoJSONFeature[] = [];
|
||||
|
||||
overpassData.elements.forEach(element => {
|
||||
let geometry: GeoJSONGeometry;
|
||||
let properties: GeoJSONProperties = { ...element.tags, id_osm: element.id, type_osm: element.type };
|
||||
|
||||
// Nœud (point)
|
||||
if (element.type === 'node' && element.lat !== undefined && element.lon !== undefined) {
|
||||
geometry = {
|
||||
type: 'Point',
|
||||
coordinates: [element.lon, element.lat]
|
||||
};
|
||||
}
|
||||
// Chemin (ligne ou polygone)
|
||||
else if (element.type === 'way' && element.geometry) {
|
||||
const coordinates = element.geometry.map(point => [point.lon, point.lat]);
|
||||
|
||||
// Si le premier et le dernier point sont identiques, c'est un polygone
|
||||
if (element.nodes && element.nodes[0] === element.nodes[element.nodes.length - 1]) {
|
||||
geometry = {
|
||||
type: 'Polygon',
|
||||
coordinates: [coordinates]
|
||||
};
|
||||
} else {
|
||||
geometry = {
|
||||
type: 'LineString',
|
||||
coordinates: coordinates
|
||||
};
|
||||
}
|
||||
}
|
||||
// Relation (multipolygon, etc.)
|
||||
else if (element.type === 'relation') {
|
||||
// Pour les relations, on crée un point à partir du centre de la géométrie si disponible
|
||||
// Une gestion complète des relations nécessiterait plus de logique
|
||||
if (element.lat !== undefined && element.lon !== undefined) {
|
||||
geometry = {
|
||||
type: 'Point',
|
||||
coordinates: [element.lon, element.lat]
|
||||
};
|
||||
} else {
|
||||
return; // Skip this element
|
||||
}
|
||||
} else {
|
||||
return; // Skip this element
|
||||
}
|
||||
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
id: element.id,
|
||||
geometry,
|
||||
properties
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Trouve les paires de points correspondants entre local et OSM
|
||||
*/
|
||||
function findMatchingFeatures(localGeoJSON: GeoJSONCollection, osmGeoJSON: GeoJSONCollection, maxDistance: number): MatchedFeaturePair[] {
|
||||
const matches: MatchedFeaturePair[] = [];
|
||||
|
||||
// Pour chaque feature locale, trouver la feature OSM la plus proche
|
||||
localGeoJSON.features.forEach(localFeature => {
|
||||
if (localFeature.geometry.type !== 'Point') return;
|
||||
|
||||
let closestOsmFeature: GeoJSONFeature | null = null;
|
||||
let minDistance = Infinity;
|
||||
|
||||
osmGeoJSON.features.forEach(osmFeature => {
|
||||
// Si ce n'est pas un point, on passe
|
||||
if (osmFeature.geometry.type !== 'Point') return;
|
||||
|
||||
// Calculer la distance
|
||||
const from = turf.point(localFeature.geometry.coordinates as [number, number]);
|
||||
const to = turf.point(osmFeature.geometry.coordinates as [number, number]);
|
||||
const distance = turf.distance(from, to, { units: 'meters' });
|
||||
|
||||
// Mettre à jour si c'est la distance minimale trouvée
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closestOsmFeature = osmFeature;
|
||||
}
|
||||
});
|
||||
|
||||
// Si on a trouvé une feature proche, l'ajouter aux correspondances
|
||||
if (closestOsmFeature && minDistance <= maxDistance) {
|
||||
matches.push({
|
||||
localFeature,
|
||||
osmFeature: closestOsmFeature,
|
||||
distance: minDistance
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fusionne les propriétés de deux features
|
||||
*/
|
||||
function mergeProperties(localProps: GeoJSONProperties, osmProps: GeoJSONProperties): GeoJSONProperties {
|
||||
const result: GeoJSONProperties = { ...localProps };
|
||||
|
||||
// Ajouter les propriétés OSM qui n'existent pas dans les données locales
|
||||
// ou dont la valeur est vide
|
||||
Object.entries(osmProps).forEach(([key, value]) => {
|
||||
// Si la propriété n'existe pas ou est vide localement, on prend celle d'OSM
|
||||
if (result[key] === undefined || result[key] === '' || result[key] === null) {
|
||||
result[key] = value;
|
||||
}
|
||||
// Si les deux ont une valeur, on peut préférer celle d'OSM pour certaines clés
|
||||
else if (['name', 'operator', 'opening_hours', 'website', 'phone', 'brand'].includes(key)) {
|
||||
// On garde l'info qu'il y a une différence
|
||||
result[`local_${key}`] = result[key];
|
||||
result[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Marquer comme ayant été fusionné
|
||||
result.conflated = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Génère le GeoJSON final après conflation
|
||||
*/
|
||||
function generateConflatedGeoJSON(
|
||||
localGeoJSON: GeoJSONCollection,
|
||||
osmGeoJSON: GeoJSONCollection,
|
||||
matches: MatchedFeaturePair[]
|
||||
): GeoJSONCollection {
|
||||
const conflatedFeatures: GeoJSONFeature[] = [];
|
||||
const localFeaturesMatched = new Set<GeoJSONFeature>();
|
||||
const osmFeaturesMatched = new Set<GeoJSONFeature>();
|
||||
|
||||
// 1. Ajouter les features fusionnées
|
||||
matches.forEach(match => {
|
||||
const mergedProps = mergeProperties(match.localFeature.properties, match.osmFeature.properties);
|
||||
mergedProps.conflated_distance = match.distance;
|
||||
|
||||
// On utilise la géométrie d'OSM (plus précise)
|
||||
const conflatedFeature: GeoJSONFeature = {
|
||||
type: 'Feature',
|
||||
geometry: match.osmFeature.geometry,
|
||||
properties: mergedProps
|
||||
};
|
||||
|
||||
conflatedFeatures.push(conflatedFeature);
|
||||
localFeaturesMatched.add(match.localFeature);
|
||||
osmFeaturesMatched.add(match.osmFeature);
|
||||
});
|
||||
|
||||
// 2. Ajouter les features locales non matchées
|
||||
localGeoJSON.features
|
||||
.filter(feature => !localFeaturesMatched.has(feature))
|
||||
.forEach(feature => {
|
||||
const props = { ...feature.properties, source: 'local_only' };
|
||||
conflatedFeatures.push({
|
||||
type: 'Feature',
|
||||
geometry: feature.geometry,
|
||||
properties: props
|
||||
});
|
||||
});
|
||||
|
||||
// 3. Ajouter les features OSM non matchées
|
||||
osmGeoJSON.features
|
||||
.filter(feature => !osmFeaturesMatched.has(feature))
|
||||
.forEach(feature => {
|
||||
const props = { ...feature.properties, source: 'osm_only' };
|
||||
conflatedFeatures.push({
|
||||
type: 'Feature',
|
||||
geometry: feature.geometry,
|
||||
properties: props
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
type: 'FeatureCollection',
|
||||
features: conflatedFeatures
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Écrit le GeoJSON dans un fichier
|
||||
*/
|
||||
function writeGeoJSONToFile(geojson: GeoJSONCollection, filename: string): void {
|
||||
fs.writeFileSync(filename, JSON.stringify(geojson, null, 2));
|
||||
console.log(`Fichier écrit: ${filename}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fonction principale
|
||||
*/
|
||||
async function main(): Promise<void> {
|
||||
// Récupérer les arguments
|
||||
const { filePath, distance, overpassQuery } = checkArguments();
|
||||
|
||||
// Charger les données locales
|
||||
console.log(`Chargement des données depuis ${filePath}...`);
|
||||
const localGeoJSON = loadLocalGeoJSON(filePath);
|
||||
console.log(`${localGeoJSON.features.length} features chargées depuis le fichier local`);
|
||||
|
||||
// Récupérer les données OSM
|
||||
const osmGeoJSON = await fetchOverpassData(overpassQuery);
|
||||
|
||||
// Trouver les correspondances
|
||||
console.log(`Recherche des correspondances (distance max: ${distance}m)...`);
|
||||
const matches = findMatchingFeatures(localGeoJSON, osmGeoJSON, distance);
|
||||
console.log(`${matches.length} correspondances trouvées`);
|
||||
|
||||
// Générer le GeoJSON conflated
|
||||
console.log("Génération du GeoJSON après conflation...");
|
||||
const conflatedGeoJSON = generateConflatedGeoJSON(localGeoJSON, osmGeoJSON, matches);
|
||||
|
||||
// Statistiques
|
||||
const localOnly = conflatedGeoJSON.features.filter(f => f.properties.source === 'local_only').length;
|
||||
const osmOnly = conflatedGeoJSON.features.filter(f => f.properties.source === 'osm_only').length;
|
||||
const conflated = conflatedGeoJSON.features.filter(f => f.properties.conflated).length;
|
||||
|
||||
console.log("\n=== Résultats de la conflation ===");
|
||||
console.log(`Total des features: ${conflatedGeoJSON.features.length}`);
|
||||
console.log(`- Features fusionnées: ${conflated}`);
|
||||
console.log(`- Features locales uniquement: ${localOnly}`);
|
||||
console.log(`- Features OSM uniquement: ${osmOnly}`);
|
||||
|
||||
// Écrire les résultats dans des fichiers
|
||||
const basename = path.basename(filePath, path.extname(filePath));
|
||||
writeGeoJSONToFile(localGeoJSON, `${basename}_local.geojson`);
|
||||
writeGeoJSONToFile(osmGeoJSON, `${basename}_osm.geojson`);
|
||||
writeGeoJSONToFile(conflatedGeoJSON, `${basename}_conflated.geojson`);
|
||||
}
|
||||
|
||||
// Exécuter le programme
|
||||
main().catch(console.error);
|
|
@ -22,6 +22,9 @@ interface Options {
|
|||
hasHeaders: boolean;
|
||||
}
|
||||
let counter = 0;
|
||||
let counter_features = 0;
|
||||
let counter_missing_lat = 0;
|
||||
let counter_missing_lon = 0;
|
||||
function csvToGeoJSON(options: Options): FeatureCollection<Point> {
|
||||
const { dir, file, latColumn, lonColumn, hasHeaders } = options;
|
||||
|
||||
|
@ -38,13 +41,12 @@ function csvToGeoJSON(options: Options): FeatureCollection<Point> {
|
|||
let headers: string[] = [];
|
||||
let headersFound = false;
|
||||
|
||||
let limitOffset = 100;
|
||||
let limitOffset = 30000000;
|
||||
|
||||
console.log(`hasHeaders: ${hasHeaders}`);
|
||||
fs.createReadStream(filePath)
|
||||
.pipe(csvParser({ headers: hasHeaders }))
|
||||
.on('data', (row) => {
|
||||
counter++;
|
||||
counter += 1;
|
||||
if (!headersFound && hasHeaders) {
|
||||
let keys = Object.keys(row);
|
||||
keys.forEach((key) => {
|
||||
|
@ -56,11 +58,7 @@ function csvToGeoJSON(options: Options): FeatureCollection<Point> {
|
|||
if (counter > limitOffset) {
|
||||
return;
|
||||
}
|
||||
if (headers.indexOf(latColumn)) {
|
||||
console.log(`latColumn: ${latColumn}`);
|
||||
console.log(`headers latColumn: ${headers.indexOf(latColumn)}`);
|
||||
console.log(`headers.indexOf(latColumn): `, headers.indexOf(latColumn));
|
||||
console.log('row', row);
|
||||
if (headers.indexOf(latColumn) && headers.indexOf(lonColumn)) {
|
||||
const lat = parseFloat(row['_' + headers.indexOf(latColumn)]);
|
||||
const lon = parseFloat(row['_' + headers.indexOf(lonColumn)]);
|
||||
|
||||
|
@ -83,21 +81,28 @@ function csvToGeoJSON(options: Options): FeatureCollection<Point> {
|
|||
}
|
||||
|
||||
// filtrer la ligne du header si présente
|
||||
if (hasHeaders && counter > 1 || !hasHeaders || counter > limitOffset) {
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [lon, lat],
|
||||
},
|
||||
properties: row,
|
||||
});
|
||||
if (lon && lat) {
|
||||
if (hasHeaders && counter > 1 || !hasHeaders || counter > limitOffset) {
|
||||
features.push({
|
||||
type: 'Feature',
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [lon, lat],
|
||||
},
|
||||
properties: row,
|
||||
});
|
||||
counter_features += 1;
|
||||
}
|
||||
}
|
||||
if (headers.indexOf(latColumn) === -1) {
|
||||
console.log('!!! no latColumn', row);
|
||||
counter_missing_lat += 1;
|
||||
}
|
||||
if (headers.indexOf(lonColumn) === -1) {
|
||||
console.log('!!! no lonColumn', row);
|
||||
counter_missing_lon += 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('!!! no latColumn', row);
|
||||
}
|
||||
|
||||
})
|
||||
.on('end', () => {
|
||||
geoJSON = {
|
||||
|
@ -106,9 +111,12 @@ function csvToGeoJSON(options: Options): FeatureCollection<Point> {
|
|||
};
|
||||
fs.writeFileSync(`${dir}/${file}.geojson`, JSON.stringify(geoJSON, null, 2));
|
||||
console.log(`GeoJSON créé avec succès : ${file}.geojson`);
|
||||
console.log(`geoJSON lines: ${counter}`);
|
||||
console.log(`geoJSON lines missing lat: ${counter_missing_lat}`);
|
||||
console.log(`geoJSON lines missing lon: ${counter_missing_lon}`);
|
||||
console.log(`geoJSON lines features: ${counter_features}`);
|
||||
});
|
||||
|
||||
console.log(`geoJSON lines: ${counter}`);
|
||||
return geoJSON;
|
||||
}
|
||||
|
||||
|
@ -146,7 +154,26 @@ function checkFile(args: Options) {
|
|||
|
||||
|
||||
}
|
||||
function countGeoJSONFeatures(args: Options) {
|
||||
const filePath = path.join(args.dir, `${args.file}.geojson`);
|
||||
|
||||
// Vérifier si le fichier GeoJSON existe
|
||||
if (!fs.existsSync(filePath)) {
|
||||
console.log(`Le fichier GeoJSON ${filePath} n'existe pas`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Lire et parser le fichier GeoJSON
|
||||
const geoJSON = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
|
||||
// Compter le nombre de features
|
||||
const featureCount = geoJSON.features?.length || 0;
|
||||
|
||||
console.log(`Nombre de features dans le GeoJSON : ${featureCount}`);
|
||||
return featureCount;
|
||||
}
|
||||
|
||||
console.log(`args: `, args);
|
||||
checkFile(args);
|
||||
csvToGeoJSON(args);
|
||||
csvToGeoJSON(args);
|
||||
// Appeler la fonction après la création du GeoJSON
|
||||
countGeoJSONFeatures(args);
|
||||
|
|
|
@ -17,7 +17,10 @@ const MappingArbresEchirolles: MappingConfigType = {
|
|||
// source: undefined,
|
||||
config_name: 'Mapping des arbres d\'Echirolles',
|
||||
config_author: 'tykayn <contact+geojson2osm@cipherbliss.com>',
|
||||
default_properties_of_point: {natural: 'tree', source : 'Échirolles Métropole'},
|
||||
default_properties_of_point: {
|
||||
natural: 'tree',
|
||||
source: 'Échirolles Métropole'
|
||||
},
|
||||
tags: {
|
||||
// ******* booléens
|
||||
// ******* nombres
|
||||
|
@ -27,27 +30,27 @@ const MappingArbresEchirolles: MappingConfigType = {
|
|||
"nom_latin": {
|
||||
key_converted: "species",
|
||||
conditional_values: {
|
||||
"Platanus acerifolia": {'tags_to_add': {"species:wikidata": "Q24853030"}},
|
||||
"Tilia cordata": {'tags_to_add': {"wikidata": "species:Q158746"}},
|
||||
"Liriodendron tulipifera": {'tags_to_add': {"species:wikidata": "Q158783"}},
|
||||
"Platanus acerifolia": { 'tags_to_add': { "species:wikidata": "Q24853030" } },
|
||||
"Tilia cordata": { 'tags_to_add': { "wikidata": "species:Q158746" } },
|
||||
"Liriodendron tulipifera": { 'tags_to_add': { "species:wikidata": "Q158783" } },
|
||||
},
|
||||
},
|
||||
|
||||
// - CADUC_PERS : leaf_cycle=evergreen pour persistant , deciduous pour caduque
|
||||
// "caduc_pers": {
|
||||
// conditional_values: {
|
||||
// "Persistant ": {
|
||||
// 'tags_to_add':{
|
||||
// "leaf_cycle": "evergreen",
|
||||
// }
|
||||
// },
|
||||
// "Caduc ": {
|
||||
// 'tags_to_add':{
|
||||
// "leaf_cycle": "deciduous",
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// - CADUC_PERS : leaf_cycle=evergreen pour persistant , deciduous pour caduque
|
||||
// "caduc_pers": {
|
||||
// conditional_values: {
|
||||
// "Persistant ": {
|
||||
// 'tags_to_add':{
|
||||
// "leaf_cycle": "evergreen",
|
||||
// }
|
||||
// },
|
||||
// "Caduc ": {
|
||||
// 'tags_to_add':{
|
||||
// "leaf_cycle": "deciduous",
|
||||
// }
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// - FEUIL_CONI : feuillu leaf_type=broadleaved / connifère leaf_type=needleleaved
|
||||
// "feuil_coni": {
|
||||
// conditional_values: {
|
||||
|
@ -63,7 +66,7 @@ const MappingArbresEchirolles: MappingConfigType = {
|
|||
// },
|
||||
// }
|
||||
// },
|
||||
// - PARTICULAR : Majeur, Remarquable : historic=monument
|
||||
// - PARTICULAR : Majeur, Remarquable : historic=monument
|
||||
|
||||
// "particular": {
|
||||
// conditional_values: {
|
||||
|
@ -80,27 +83,27 @@ const MappingArbresEchirolles: MappingConfigType = {
|
|||
// },
|
||||
// }
|
||||
// },
|
||||
// - FORME: tree_shape = curtain / free / half_free <= Architecturé, rideau / Libre / Semi-libre
|
||||
// "forme": {
|
||||
// key_converted: "tree_shape",
|
||||
// conditional_values: {
|
||||
// "Architecturé, rideau ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "curtain",
|
||||
// },
|
||||
// },
|
||||
// "Semi-libre ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "half_free",
|
||||
// },
|
||||
// },
|
||||
// "Libre ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "free",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// - FORME: tree_shape = curtain / free / half_free <= Architecturé, rideau / Libre / Semi-libre
|
||||
// "forme": {
|
||||
// key_converted: "tree_shape",
|
||||
// conditional_values: {
|
||||
// "Architecturé, rideau ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "curtain",
|
||||
// },
|
||||
// },
|
||||
// "Semi-libre ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "half_free",
|
||||
// },
|
||||
// },
|
||||
// "Libre ": {
|
||||
// 'tags_to_add':{
|
||||
// "tree_shape": "free",
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
|
||||
|
||||
},
|
||||
|
|
40
mappings/converters/configPanneauxMaxSpeed.ts
Normal file
40
mappings/converters/configPanneauxMaxSpeed.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* panneaux de vitesse détectés sur panoramax
|
||||
* utilisation:
|
||||
*/
|
||||
import { constrainedMemory } from "process";
|
||||
import MappingConfigType from "../mapping-config.type";
|
||||
|
||||
const MappingPanneauxMaxSpeed: MappingConfigType = {
|
||||
config_name: "MappingPanneauxMaxSpeed",
|
||||
config_author: "tk",
|
||||
default_properties_of_point: {
|
||||
"traffic_sign": "FR:B14",
|
||||
"maxspeed:source": "panoramax"
|
||||
},
|
||||
source: {
|
||||
geojson_path: '',
|
||||
url: ''
|
||||
},
|
||||
filters: {
|
||||
// exclude_point_if_tag_not_empty: ['id_osm'], // exclure les points ayant déjà un id_osm pour éviter les doublons
|
||||
// offset: 1
|
||||
},
|
||||
add_not_mapped_tags_too: false,
|
||||
boolean_keys: [],
|
||||
tags_to_ignore_if_value_is: ['Non renseigne'],
|
||||
tags: {
|
||||
"SourceFile": {
|
||||
key_converted: 'maxspeed',
|
||||
transform_function: (value: string) => {
|
||||
let explode = value.split('-');
|
||||
if (explode.length > 1) {
|
||||
return explode[1];
|
||||
}
|
||||
return value;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default MappingPanneauxMaxSpeed;
|
|
@ -16,23 +16,12 @@ wget https://www.data.gouv.fr/fr/datasets/r/8d9398ae-3037-48b2-be19-412c24561fbb
|
|||
|
||||
echo "- OK IRVE"
|
||||
echo "- récupérer les données présentes dans OpenStreetMap"
|
||||
curl --header "Content-Type: plain/text" --data @content_irve_geojson.txt --trace-ascii website-data.log "https://overpass-api.de/api/interpreter" > "irve_osm_latest.geojson"
|
||||
curl --header "Content-Type: plain/text" --data @content_irve_geojson.txt --trace-ascii website-data.log "https://overpass-api.de/api/interpreter" >"irve_osm_latest.geojson"
|
||||
|
||||
echo "- récupérer les données présentes dans Osmose"
|
||||
wget "https://osmose.openstreetmap.fr/api/0.3/issues.geojson?full=true&status=open&item=8410&limit=20000" -O "osmose-item-irve-8411-intégrables.json"
|
||||
echo "- OK Osmose"
|
||||
|
||||
##################
|
||||
# moving datasets to the source folder etalab_data
|
||||
##################
|
||||
echo " - déplacement des datasets des IRVE dans le dossier etalab_data/irve_bornes_recharge"
|
||||
mv latest.json ../etalab_data/irve_bornes_recharge/
|
||||
#mv finess_idf.json ../etalab_data/finess/
|
||||
mv irve_osm_latest.geojson ../etalab_data/irve_bornes_recharge/
|
||||
mv clean_french_irve.csv ../etalab_data/irve_bornes_recharge/
|
||||
mv osmose-item-irve-8411-intégrables.json ../etalab_data/irve_bornes_recharge/
|
||||
|
||||
|
||||
##################
|
||||
# other sources of data should be placed in data_other folder
|
||||
##################
|
||||
|
@ -44,11 +33,6 @@ wget "https://data.issy.com/api/explore/v2.1/catalog/datasets/arbres-remarquable
|
|||
echo "- récupérer les données de cyclabilité de Rouen"
|
||||
wget "https://data.metropole-rouen-normandie.fr/api/explore/v2.1/catalog/datasets/liste-des-stationnements-cyclables-metropole-rouen-normandie/exports/geojson?lang=fr&timezone=Europe%2FBerlin" -O "rouen_parking_velos.json"
|
||||
|
||||
mv "issy_les_mx_arbres.json" ../data_other/arbres/issy_les_mx_arbres.json
|
||||
mv "geojson?lang=fr" ../data_other/cyclabilité/issy_les_mx_cyclabilité.json
|
||||
mv "rouen_parking_velos.json" ../data_other/cyclabilité/rouen_parking_velos.json
|
||||
|
||||
|
||||
# clean logs and finish
|
||||
rm website-data.log
|
||||
cd ..
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue