mirror of
https://forge.chapril.org/tykayn/wololo
synced 2025-06-20 01:34:42 +02:00
add tests and failsafe for values true and false
This commit is contained in:
parent
5b0271716c
commit
cb6075fc61
10 changed files with 376 additions and 230 deletions
10
config.ts
10
config.ts
|
@ -38,7 +38,15 @@ let listOfBooleanKeys = [
|
|||
"gratuit",
|
||||
"paiement_acte",
|
||||
"paiement_cb",
|
||||
"cable_t2_attache"
|
||||
"cable_t2_attache",
|
||||
"paiement_acte",
|
||||
"paiement_cb",
|
||||
"cable_t2_attache",
|
||||
"socket:typee",
|
||||
"socket:type2_combo",
|
||||
"socket:chademo",
|
||||
"socket:type2",
|
||||
"socket:type2_cable",
|
||||
]
|
||||
let irve_max_output = 401 // limite de kW de puissance pour une borne de recharge publique
|
||||
|
||||
|
|
|
@ -12,8 +12,13 @@
|
|||
* --outname=nom_fichier : Alias pour --output-file
|
||||
* --testingConfig : Active le mode test avec la configuration mappingTest
|
||||
*/
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
import * as fs from 'fs'
|
||||
|
||||
import mapping_engine from './mappings/engine'
|
||||
import MappingConfigType, { BoundingBoxCoordinatesType, FeatureCollection } from "./mappings/mapping-config.type";
|
||||
import utils from './mappings/utils'
|
||||
import config from './config'
|
||||
/**
|
||||
* Mesure de l'utilisation de la RAM
|
||||
*/
|
||||
|
@ -42,12 +47,6 @@ process.on('exit', () => {
|
|||
});
|
||||
|
||||
|
||||
import * as fs from 'fs'
|
||||
|
||||
import mapping_engine from './mappings/engine'
|
||||
import MappingConfigType, { BoundingBoxCoordinatesType, FeatureCollection } from "./mappings/mapping-config.type";
|
||||
import utils from './mappings/utils'
|
||||
import config from './config'
|
||||
|
||||
|
||||
|
||||
|
@ -125,29 +124,6 @@ if (mini_arguments['wget']) {
|
|||
|
||||
|
||||
|
||||
async function replaceFile(sourceFilePathGeoJson: string, url: string) {
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur lors du téléchargement: ${response.status} ${response.statusText}`)
|
||||
}
|
||||
// afficher la taille du fichier téléchargé
|
||||
const contentLength = response.headers.get('content-length')
|
||||
|
||||
const data = await response.text()
|
||||
if (contentLength) {
|
||||
const sizeInMB = (parseInt(contentLength) / (1024 * 1024)).toFixed(2)
|
||||
console.log(`Taille du fichier téléchargé: ${sizeInMB} Mo`)
|
||||
} else {
|
||||
|
||||
// mesurer la taille des données
|
||||
const sizeInMB = (data.length / (1024 * 1024)).toFixed(2)
|
||||
console.log(`Taille des données: ${sizeInMB} Mo`)
|
||||
}
|
||||
|
||||
fs.writeFileSync(sourceFilePathGeoJson, data)
|
||||
console.log('fichier téléchargé avec succès:', sourceFilePathGeoJson)
|
||||
|
||||
}
|
||||
|
||||
let filterZipCode = new RegExp(`^${filterDepartment}`)
|
||||
let filterZipCodeAdresse = new RegExp(` ${filterDepartment}`)
|
||||
|
@ -281,7 +257,6 @@ function convertDataFromSource(sourceFilePath: string, mapping: MappingConfigTyp
|
|||
let remove_original_key = false;
|
||||
|
||||
// fix des jeux de données qui ne sont pas des geojson
|
||||
|
||||
let properties_list: any = []
|
||||
|
||||
if (feature_point.geo_point_2d) {
|
||||
|
@ -362,8 +337,6 @@ function convertDataFromSource(sourceFilePath: string, mapping: MappingConfigTyp
|
|||
debugLog('pas de filtre sur les coordonnées bounding box')
|
||||
}
|
||||
|
||||
|
||||
// TODO add filter offset max
|
||||
// filter points depending on zipcode
|
||||
if (regex_filter_test_result) {
|
||||
feature_points_after_filter.push(feature_point)
|
||||
|
@ -385,13 +358,9 @@ function convertDataFromSource(sourceFilePath: string, mapping: MappingConfigTyp
|
|||
debugLog('convert : work on 1 point')
|
||||
let mapped_point: any = {}
|
||||
|
||||
if (use_mapping_engine) {
|
||||
mapped_point = Mapping_engine.mapElementFromConf(feature_point)
|
||||
debugLog('mapped_point', mapped_point)
|
||||
} else {
|
||||
debugLog('convert :using simple converter on feature point', feature_point)
|
||||
mapped_point = mapElementFromConfSimple(feature_point, mapping)
|
||||
}
|
||||
// if (use_mapping_engine) {
|
||||
mapped_point = Mapping_engine.mapElementFromConf(feature_point)
|
||||
debugLog('mapped_point', mapped_point)
|
||||
if (mapped_point) {
|
||||
converted_geo_json.features.push(mapped_point)
|
||||
debugLog('convert : added one point to converted_geo_json')
|
||||
|
@ -435,104 +404,50 @@ function convertDataFromSource(sourceFilePath: string, mapping: MappingConfigTyp
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* retuns the converted element from mapping config if present, null otherwise
|
||||
*/
|
||||
function mapElementFromConfSimple(featurePoint: any, mappingConfig: any) {
|
||||
let mappingKeys = Object.keys(mappingConfig)
|
||||
let featurePointPropertiesKeys = Object.keys(featurePoint.properties)
|
||||
|
||||
debugLog('keys', mappingKeys, featurePointPropertiesKeys)
|
||||
|
||||
let newProperties: any = defaultPropertiesOfPoint
|
||||
|
||||
// reinit properties of current point
|
||||
let basePoint = Object.create(featurePoint)
|
||||
basePoint.type = featurePoint.type
|
||||
basePoint.geometry = featurePoint.geometry
|
||||
basePoint.properties = newProperties
|
||||
|
||||
// apply new properties if found in mapping config
|
||||
featurePointPropertiesKeys.forEach((pointKeyName: string) => {
|
||||
|
||||
if (mappingKeys.indexOf(pointKeyName) !== -1) {
|
||||
// debugLog('found element', pointKeyName, '=>', mappingConfig[pointKeyName], 'value : ', featurePoint.properties[pointKeyName])
|
||||
let convertedValue: any = ''
|
||||
if (utils.isBooleanKey(pointKeyName)) {
|
||||
|
||||
let copyOfValue: any = '' + featurePoint.properties[pointKeyName]
|
||||
if (typeof copyOfValue === typeof Object && copyOfValue.key_converted) {
|
||||
copyOfValue = copyOfValue.key_converted
|
||||
}
|
||||
convertedValue = copyOfValue.toLowerCase() == 'true' ? 'yes' : 'no'
|
||||
} else {
|
||||
convertedValue = featurePoint.properties[pointKeyName]
|
||||
}
|
||||
|
||||
if (convertedValue) {
|
||||
let convertedKey: any = mappingConfig[pointKeyName]
|
||||
newProperties[convertedKey] = convertedValue
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
debugLog('basePoint', basePoint)
|
||||
return basePoint
|
||||
}
|
||||
|
||||
function setMappingConfigFromName(engine_conf_choice: string) {
|
||||
console.log('------- geojson source', sourceFilePathGeoJson)
|
||||
console.log('------- conversion engine', engine_conf_choice)
|
||||
|
||||
if (use_mapping_engine) {
|
||||
debugLog(' - using mapping engine')
|
||||
debugLog(' - pointCounterMax', pointCounterMax)
|
||||
|
||||
if (osmoseFormat) {
|
||||
Mapping_engine.setConfig(config.allowed_configs.mappingConfigIRVEFromOsmose)
|
||||
debugLog(' - pointCounterMax', pointCounterMax)
|
||||
|
||||
} else {
|
||||
|
||||
if (engine_conf_choice !== default_engine_conf_choice && Object.keys(config.allowed_configs).indexOf("mappingIssy2Roues") !== -1) {
|
||||
Mapping_engine.setConfig(config.allowed_configs[engine_conf_choice])
|
||||
} else {
|
||||
console.error('mauvais paramètre de Mapping_engine: ' + engine_conf_choice, '.\n Veuillez en sélectionner un parmi ceux autorisés avec l option --engine-config=MaConfigQuiVaBien parmi ceux ci :', Object.keys(config.allowed_configs))
|
||||
return
|
||||
}
|
||||
}
|
||||
let currentMappingConfig = Mapping_engine.getConfig() as MappingConfigType;
|
||||
|
||||
// si on a wget et que le mapping config a une source, on récupère la source définie dans le mapping config
|
||||
if (wget) {
|
||||
// console.log('wget enabled', currentMappingConfig.source)
|
||||
// let geojson_path = currentMappingConfig.source.geojson_path
|
||||
// let filename = sourceFilePathGeoJson.split('/').pop()
|
||||
// télécharger le fichier source depuis l'url du mapping config
|
||||
if (currentMappingConfig.source.geojson_path) {
|
||||
console.log('téléchargement du fichier source depuis', currentMappingConfig.source.geojson_path)
|
||||
console.log('la documentation de la ressource est disponible sur ', currentMappingConfig.source.url)
|
||||
try {
|
||||
|
||||
replaceFile(sourceFilePathGeoJson, currentMappingConfig.source.geojson_path)
|
||||
convertDataFromSource(sourceFilePathGeoJson, currentMappingConfig, pointCounterMax, boundingBoxCoordinates)
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du téléchargement du fichier source:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
console.log('wget enabled, but no geojson_path found in mapping config', currentMappingConfig.source)
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
convertDataFromSource(sourceFilePathGeoJson, currentMappingConfig, pointCounterMax, boundingBoxCoordinates)
|
||||
}
|
||||
if (osmoseFormat) {
|
||||
Mapping_engine.setConfig(config.allowed_configs.mappingConfigIRVEFromOsmose)
|
||||
|
||||
} else {
|
||||
|
||||
console.log(' ------ on utilise mappingConfigIRVE_simple')
|
||||
let mappingConfigIRVE = config.allowed_configs.mappingConfigIRVE_simple
|
||||
convertDataFromSource(sourceFilePathGeoJson, mappingConfigIRVE, pointCounterMax, boundingBoxCoordinates)
|
||||
if (engine_conf_choice !== default_engine_conf_choice && Object.keys(config.allowed_configs).indexOf("mappingIssy2Roues") !== -1) {
|
||||
Mapping_engine.setConfig(config.allowed_configs[engine_conf_choice])
|
||||
} else {
|
||||
console.error('mauvais paramètre de Mapping_engine: ' + engine_conf_choice, '.\n Veuillez en sélectionner un parmi ceux autorisés avec l option --engine-config=MaConfigQuiVaBien parmi ceux ci :', Object.keys(config.allowed_configs))
|
||||
return
|
||||
}
|
||||
}
|
||||
let currentMappingConfig = Mapping_engine.getConfig() as MappingConfigType;
|
||||
|
||||
// si on a wget et que le mapping config a une source, on récupère la source définie dans le mapping config
|
||||
if (wget) {
|
||||
console.log('wget enabled')
|
||||
// télécharger le fichier source depuis l'url du mapping config
|
||||
if (currentMappingConfig.source.geojson_path) {
|
||||
console.log('téléchargement du fichier source depuis', currentMappingConfig.source.geojson_path)
|
||||
console.log('la documentation de la ressource est disponible sur ', currentMappingConfig.source.url)
|
||||
try {
|
||||
|
||||
utils.replaceFile(sourceFilePathGeoJson, currentMappingConfig.source.geojson_path)
|
||||
convertDataFromSource(sourceFilePathGeoJson, currentMappingConfig, pointCounterMax, boundingBoxCoordinates)
|
||||
} catch (error) {
|
||||
console.error('Erreur lors du téléchargement du fichier source:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
} else {
|
||||
console.log('wget enabled, but no geojson_path found in mapping config', currentMappingConfig.source)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
|
||||
convertDataFromSource(sourceFilePathGeoJson, currentMappingConfig, pointCounterMax, boundingBoxCoordinates)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
152
docs/website/index.html
Normal file
152
docs/website/index.html
Normal file
|
@ -0,0 +1,152 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Wololo - Convertisseur de données vers OSM</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
line-height: 1.6;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.container {
|
||||
background-color: white;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #2c3e50;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.mapping-config {
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.mapping-config h2 {
|
||||
color: #3498db;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.mapping-config i {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.contact {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
padding: 20px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.sources {
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #3498db;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🌍 Wololo - Convertisseur de données vers OpenStreetMap</h1>
|
||||
|
||||
<p>Wololo est un outil de conversion de données qui permet de transformer différents formats de données en tags
|
||||
OpenStreetMap. Il facilite l'import de données provenant de diverses sources vers la base de données OSM.</p>
|
||||
|
||||
<h2><i class="fas fa-cogs"></i> Configurations de mapping disponibles</h2>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>⚡ IRVE (Bornes de recharge)</h2>
|
||||
<p>Configuration pour la conversion des données de bornes de recharge électrique.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🚲 Stationnements vélos</h2>
|
||||
<p>Configuration pour la conversion des données de stationnements vélos.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🗄️ Osmose</h2>
|
||||
<p>Configuration pour la conversion des données issues d'Osmose.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🏛️ Musées</h2>
|
||||
<p>Configuration pour la conversion des données de musées et lieux culturels.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🪧 Plaques commémoratives</h2>
|
||||
<p>Configuration pour la conversion des données de plaques commémoratives et historiques.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🌳 Arbres</h2>
|
||||
<p>Configuration pour la conversion des données d'arbres et d'espaces verts.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🚦 Panneaux de signalisation routière</h2>
|
||||
<p>Configuration pour la conversion des données de panneaux de signalisation et de sécurité routière.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>♻️ Points d'apport volontaire</h2>
|
||||
<p>Configuration pour la conversion des données de points de collecte et de recyclage.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🦸 Demandez Angela</h2>
|
||||
<p>Configuration pour la conversion des lieux partenaires du dispositif "Demandez Angela" contre le harcèlement.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🎥 Appareils de surveillance</h2>
|
||||
<p>Configuration pour la conversion des données de caméras et dispositifs de surveillance.</p>
|
||||
</div>
|
||||
|
||||
<div class="mapping-config">
|
||||
<h2>🏥 Lieux de soin</h2>
|
||||
<p>Configuration pour la conversion des données de centres de santé, hôpitaux et lieux de soin.</p>
|
||||
</div>
|
||||
|
||||
<div class="sources">
|
||||
<h2><i class="fas fa-code-branch"></i> Sources du projet</h2>
|
||||
<p>Le code source de Wololo est disponible sur GitHub : <a href="https://github.com/osm-fr/osmose-to-osm"
|
||||
target="_blank">osmose-to-osm</a></p>
|
||||
</div>
|
||||
|
||||
<div class="contact">
|
||||
<h2><i class="fas fa-envelope"></i> Contact</h2>
|
||||
<p>Pour toute question ou suggestion, n'hésitez pas à me contacter :</p>
|
||||
<a href="mailto:contact+wololo@cipherbliss.com">contact+wololo@cipherbliss.com</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -29,7 +29,7 @@ const MappingIRVE: MappingConfigType = {
|
|||
enable_properties_filter: true,
|
||||
// filter_points_older_than_year: 2024,
|
||||
// filter_points_by_year_property: 'date_mise_en_service',
|
||||
// filter_points_lesser_than_NkW: 50 // ne pas sortir les points qui ont moins de ce nombre de puissance nominale
|
||||
// filter_points_lesser_than_NkW: 20 // ne pas sortir les points qui ont moins de ce nombre de puissance nominale
|
||||
// add only geojson points who are found having this regex in the zipcode properties
|
||||
// properties: {
|
||||
// consolidated_code_postal: '^[76|27]'
|
||||
|
@ -50,7 +50,12 @@ const MappingIRVE: MappingConfigType = {
|
|||
"gratuit",
|
||||
"paiement_acte",
|
||||
"paiement_cb",
|
||||
"cable_t2_attache"
|
||||
"cable_t2_attache",
|
||||
"socket:typee",
|
||||
"socket:type2_combo",
|
||||
"socket:chademo",
|
||||
"socket:type2",
|
||||
"socket:type2_cable",
|
||||
],
|
||||
tags: {
|
||||
// ******* nombres
|
||||
|
@ -90,12 +95,12 @@ const MappingIRVE: MappingConfigType = {
|
|||
paiement_acte:
|
||||
{
|
||||
key_converted: 'authentication:none',
|
||||
convert_to_boolean_value: true, // convertit en yes ou no
|
||||
convert_to_boolean_value: true,
|
||||
|
||||
},
|
||||
reservation: {
|
||||
key_converted: 'reservation',
|
||||
convert_to_boolean_value: true, // convertit en yes ou no
|
||||
convert_to_boolean_value: true,
|
||||
},
|
||||
// observations: 'note',
|
||||
nom_station: 'description',
|
||||
|
@ -116,27 +121,21 @@ const MappingIRVE: MappingConfigType = {
|
|||
,
|
||||
prise_type_ef: {
|
||||
key_converted: 'socket:typee',
|
||||
ignore_if_falsy: true,
|
||||
convert_to_boolean_value: true,
|
||||
keep_only_max_in_enum: true,
|
||||
keep_only_truthy_yes_or_no_without_enum: true,
|
||||
},
|
||||
prise_type_2: {
|
||||
key_converted: 'socket:type2',
|
||||
ignore_if_falsy: true,
|
||||
convert_to_boolean_value: true,
|
||||
keep_only_max_in_enum: true,
|
||||
// on convertit en yes ou no, sans enum, et on ne garde que si on obtient "yes"
|
||||
keep_only_truthy_yes_or_no_without_enum: true,
|
||||
|
||||
},
|
||||
prise_type_combo_ccs: {
|
||||
key_converted: 'socket:type2_combo',
|
||||
ignore_if_falsy: true,
|
||||
convert_to_boolean_value: true,
|
||||
keep_only_max_in_enum: true,
|
||||
keep_only_truthy_yes_or_no_without_enum: true,
|
||||
},
|
||||
prise_type_chademo: {
|
||||
key_converted: 'socket:chademo',
|
||||
ignore_if_falsy: true,
|
||||
convert_to_boolean_value: true,
|
||||
keep_only_max_in_enum: true,
|
||||
keep_only_truthy_yes_or_no_without_enum: true,
|
||||
},
|
||||
// ******** champs plus complexes
|
||||
horaires: 'opening_hours', // déjà au bon format, enfin, en général. vérifier avec le validateur josm.
|
||||
|
@ -149,9 +148,7 @@ const MappingIRVE: MappingConfigType = {
|
|||
accessibilite_pmr: {
|
||||
key_converted: "wheelchair",
|
||||
conditional_values: {
|
||||
"Accessibilité inconnue": {
|
||||
ignore_this_data: true, // ne pas ajouter de tag si la valeur est égale à Accessibilité inconnue.
|
||||
},
|
||||
|
||||
"Accessible mais non réservé PMR": {
|
||||
value_converted: "yes"
|
||||
},
|
||||
|
|
|
@ -53,15 +53,6 @@ export default class MappingEngine {
|
|||
return geoJSONConvertedPoint
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO convert to mapping config property to transform_truthy
|
||||
* @param pointKeyName
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isBooleanKey(pointKeyName: string): boolean {
|
||||
|
||||
return config.listOfBooleanKeys.indexOf(pointKeyName) !== -1
|
||||
}
|
||||
|
||||
/**
|
||||
* filter: reduce number of features
|
||||
|
@ -174,8 +165,6 @@ export default class MappingEngine {
|
|||
}
|
||||
|
||||
|
||||
// console.log('mapElementFromConf: ============= keys mappingKeys:', featurePointPropertiesKeys.length, mappingKeys)
|
||||
|
||||
let newProperties = { ...this.mapping_config.default_properties_of_point }
|
||||
|
||||
|
||||
|
@ -185,23 +174,17 @@ export default class MappingEngine {
|
|||
basePoint.geometry = featurePoint.geometry
|
||||
basePoint.properties = { ...this.mapping_config.default_properties_of_point }
|
||||
|
||||
|
||||
// apply new properties if found in mapping config
|
||||
featurePointPropertiesKeys.forEach(pointKeyName => {
|
||||
|
||||
// if (featurePointPropertiesKeys.indexOf(pointKeyName) !== -1) {
|
||||
|
||||
this.convertProperty({
|
||||
pointKeyName, mappingKeys, featurePoint, newProperties
|
||||
})
|
||||
// }
|
||||
|
||||
|
||||
})
|
||||
|
||||
basePoint.properties = newProperties
|
||||
|
||||
// debugLog('mapElementFromConf: basePoint', basePoint)
|
||||
return basePoint
|
||||
}
|
||||
|
||||
|
@ -245,7 +228,7 @@ export default class MappingEngine {
|
|||
let remove_original_key = false;
|
||||
debugLog('tags_to_ignore_if_value_is', this.mapping_config.tags_to_ignore_if_value_is)
|
||||
if (this.mapping_config.tags_to_ignore_if_value_is && this.mapping_config.tags_to_ignore_if_value_is.length && this.mapping_config.tags_to_ignore_if_value_is?.indexOf(originalValue) !== -1) {
|
||||
debugLog('(x) => ignore', originalValue, ' in ', pointKeyName)
|
||||
console.log('(x) => ignore', originalValue, ' in ', pointKeyName)
|
||||
remove_original_key = true;
|
||||
|
||||
}
|
||||
|
@ -353,13 +336,44 @@ export default class MappingEngine {
|
|||
/**
|
||||
* conversion booléenne
|
||||
*/
|
||||
if (mappingValueObject.keep_only_truthy_yes_or_no_without_enum) {
|
||||
if (originalValue.indexOf(";") === -1 && custom_utils.truthyValues.indexOf(originalValue) !== -1) {
|
||||
convertedValue = 'yes'
|
||||
} else {
|
||||
|
||||
remove_original_key = true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (mappingValueObject.convert_to_boolean_value) {
|
||||
debugLog('convertProperty: is boolean_value_conversion')
|
||||
|
||||
// debugLog('convertProperty: is boolean_value_conversion')
|
||||
|
||||
convertedValue = custom_utils.convertToYesOrNo(originalValue)
|
||||
|
||||
// if (pointKeyName === 'prise_type_2') {
|
||||
// console.log('convertProperty: is boolean_value_conversion', pointKeyName, keyConvertedFromMapping, originalValue, '=>', convertedValue)
|
||||
|
||||
// newProperties[keyConvertedFromMapping] = convertedValue
|
||||
// }
|
||||
|
||||
// console.log('convertProperty: is boolean_value_conversion', pointKeyName, keyConvertedFromMapping, originalValue, '=>', convertedValue)
|
||||
if (configObject.ignore_if_falsy && !custom_utils.convertToBoolean(originalValue)) {
|
||||
return newProperties
|
||||
}
|
||||
if (configObject.ignore_if_truthy && custom_utils.convertToBoolean(originalValue)) {
|
||||
return newProperties
|
||||
}
|
||||
|
||||
} else {
|
||||
debugLog('convertProperty: is NOT having boolean_value_conversion', mappingValueObject)
|
||||
}
|
||||
if (configObject.invert_boolean_value) {
|
||||
convertedValue = !custom_utils.convertToBoolean(originalValue) ? 'yes' : 'no'
|
||||
debugLog('invert boolean', convertedValue, originalValue)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// gestion des puissances de bornes
|
||||
|
@ -381,13 +395,10 @@ export default class MappingEngine {
|
|||
})
|
||||
|
||||
}
|
||||
if (configObject.invert_boolean_value) {
|
||||
convertedValue = !custom_utils.convertToBoolean(originalValue) ? 'yes' : 'no'
|
||||
debugLog('invert boolean', convertedValue, originalValue)
|
||||
}
|
||||
|
||||
if (configObject.remove_stars) {
|
||||
// Remplace toutes les occurrences de * de manière greedy
|
||||
convertedValue = originalValue.replaceAll('*', '')
|
||||
convertedValue = originalValue.replace('*', '')
|
||||
debugLog('remove_stars', convertedValue, originalValue)
|
||||
}
|
||||
|
||||
|
@ -409,7 +420,9 @@ export default class MappingEngine {
|
|||
if (configObject.remove_original_key) {
|
||||
remove_original_key = true
|
||||
}
|
||||
if (configObject.ignore_if_falsy && !custom_utils.convertToBoolean(originalValue)) {
|
||||
|
||||
|
||||
if (configObject.ignore_if_falsy && (false === custom_utils.convertToBoolean(originalValue))) {
|
||||
remove_original_key = true
|
||||
}
|
||||
if (configObject.ignore_if_truthy && custom_utils.convertToBoolean(originalValue)) {
|
||||
|
@ -423,11 +436,16 @@ export default class MappingEngine {
|
|||
}
|
||||
|
||||
let conditionalConfig: any = ''
|
||||
|
||||
// console.log('/////////// configObject.ignore_if_falsy', configObject.ignore_if_falsy, "converti en booléen", custom_utils.convertToBoolean(originalValue), "remove?", remove_original_key)
|
||||
|
||||
|
||||
/**
|
||||
* config pour une clé
|
||||
* nous pouvons renseigner une string ou un objet décrivant les transformations à réaliser
|
||||
*/
|
||||
if (configObject.conditional_values) {
|
||||
|
||||
if (!remove_original_key && configObject.conditional_values) {
|
||||
|
||||
// convert numbers from json to string to compare them correctly
|
||||
originalValue = '' + originalValue
|
||||
|
@ -440,13 +458,14 @@ export default class MappingEngine {
|
|||
// sauf si on a activé l'option allow_unspecified_conditional_values dans la MappingConfigType
|
||||
if (!this.mapping_config.allow_unspecified_conditional_values && foundValue === -1) {
|
||||
|
||||
// console.log('(x) => ignore', originalValue, ' in ', pointKeyName)
|
||||
// console.log('!!!!!!!!!! (x) => ignore', originalValue, ' in ', pointKeyName, 'on vire ', keyConvertedFromMapping)
|
||||
remove_original_key = true
|
||||
}
|
||||
|
||||
|
||||
if (!remove_original_key) {
|
||||
|
||||
// console.log('-------- on garde la valeur', originalValue, ' dans ', pointKeyName)
|
||||
|
||||
if (foundValue !== -1) {
|
||||
debugLog('found condition', foundValue)
|
||||
|
@ -462,48 +481,47 @@ export default class MappingEngine {
|
|||
remove_original_key = true;
|
||||
}
|
||||
|
||||
let lowerKey = (originalValue + '').toLowerCase()
|
||||
if (conditionalConfig.truthy_value) {
|
||||
// convertir la valeur, si elle est truthy, la transformer en ce que donne la propriété truthy_value
|
||||
// exemple: le jeu de données dit que la colonne cable_t2_attache vaut "True", mais on veut le convertir en "1".
|
||||
// on met donc truthy_value: '1'
|
||||
if (custom_utils.truthyValues.indexOf(originalValue) !== -1) {
|
||||
if (custom_utils.truthyValues.indexOf(lowerKey) !== -1) {
|
||||
convertedValue = conditionalConfig.truthy_value
|
||||
}
|
||||
}
|
||||
if (conditionalConfig.falsy_value) {
|
||||
if (custom_utils.falsyValues.indexOf(originalValue) !== -1) {
|
||||
if (custom_utils.falsyValues.indexOf(lowerKey) !== -1) {
|
||||
convertedValue = conditionalConfig.falsy_value
|
||||
}
|
||||
}
|
||||
|
||||
// use the value converted
|
||||
else if (conditionalConfig.value_converted) {
|
||||
if (conditionalConfig.value_converted) {
|
||||
convertedValue = conditionalConfig.value_converted
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
// console.log('convertedValue =>', convertedValue)
|
||||
if (conditionalConfig?.tags_to_add) {
|
||||
debugLog('on ajoute des tags', conditionalConfig.tags_to_add)
|
||||
// on peut définir un ensemble de tags à rajouter
|
||||
let tagKeys = Object.keys(conditionalConfig.tags_to_add)
|
||||
debugLog('conditionnalConfig.tags_to_add', conditionalConfig.tags_to_add)
|
||||
tagKeys.forEach((index: any) => {
|
||||
debugLog('key', index)
|
||||
debugLog('value', conditionalConfig.tags_to_add[index])
|
||||
newProperties[index] = conditionalConfig.tags_to_add[index]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// console.log('convertedValue =>', convertedValue)
|
||||
if (conditionalConfig?.tags_to_add) {
|
||||
debugLog('on ajoute des tags', conditionalConfig.tags_to_add)
|
||||
// on peut définir un ensemble de tags à rajouter
|
||||
let tagKeys = Object.keys(conditionalConfig.tags_to_add)
|
||||
debugLog('conditionnalConfig.tags_to_add', conditionalConfig.tags_to_add)
|
||||
tagKeys.forEach((index: any) => {
|
||||
debugLog('key', index)
|
||||
debugLog('value', conditionalConfig.tags_to_add[index])
|
||||
newProperties[index] = conditionalConfig.tags_to_add[index]
|
||||
})
|
||||
}
|
||||
|
||||
} else {
|
||||
debugLog('no conditional values', configObject)
|
||||
}
|
||||
// console.log('conditionnalConfig', conditionnalConfig, convertedValue)
|
||||
|
||||
|
||||
debugLog('convertProperty: convertedValue ==========> {', newKey, ':', convertedValue, '}')
|
||||
debugLog(' =============== remove_original_key', newKey, remove_original_key)
|
||||
|
@ -514,21 +532,32 @@ export default class MappingEngine {
|
|||
keysOfConfigObject = Object.keys(configObject)
|
||||
debugLog('keysOfConfigObject', keysOfConfigObject)
|
||||
hasKeyIgnoreThisData = (keysOfConfigObject.indexOf('ignore_this_data') !== -1)
|
||||
// console.log('-------- hasKeyIgnoreThisData', hasKeyIgnoreThisData)
|
||||
}
|
||||
|
||||
debugLog('remove_original_key && newKey && convertedValue && hasKeyIgnoreThisData', remove_original_key, newKey, convertedValue, hasKeyIgnoreThisData)
|
||||
|
||||
// console.log('newKey && convertedValue && !hasKeyIgnoreThisData', newKey && convertedValue && !hasKeyIgnoreThisData, newKey, convertedValue, !hasKeyIgnoreThisData)
|
||||
if (remove_original_key) {
|
||||
delete newProperties[pointKeyName];
|
||||
|
||||
// failsafe for boolean values, OSM never returns true or false
|
||||
if (convertedValue == 'true') {
|
||||
convertedValue = 'yes'
|
||||
}
|
||||
if (newKey && convertedValue && !hasKeyIgnoreThisData
|
||||
if (convertedValue == 'false') {
|
||||
convertedValue = 'no'
|
||||
}
|
||||
|
||||
if (newKey && convertedValue && !hasKeyIgnoreThisData && !remove_original_key
|
||||
) {
|
||||
debugLog('convertedValue', convertedValue)
|
||||
|
||||
debugLog('convertProperty: added', newKey, (`${convertedValue}`).trim())
|
||||
newProperties[newKey] = (`${convertedValue}`).trim()
|
||||
}
|
||||
if (remove_original_key) {
|
||||
// console.log('remove_original_key', pointKeyName, originalValue, '=>', convertedValue)
|
||||
delete newProperties[pointKeyName];
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
@ -539,8 +568,6 @@ export default class MappingEngine {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// console.log('pointKeyName', pointKeyName)
|
||||
return newProperties;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ export interface FeaturePropertyMappingConfigType {
|
|||
conditional_values?: ConditionnalValuesConfigType,
|
||||
transform_function?: Function,
|
||||
keep_only_max_in_enum?: boolean,
|
||||
keep_only_truthy_yes_or_no_without_enum?: boolean,
|
||||
|
||||
[key: string]: any,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as fs from 'node:fs'
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
let show_debug = 0
|
||||
// show_debug = 1
|
||||
|
@ -18,8 +19,8 @@ function debugLog(...args: any[]) {
|
|||
}
|
||||
}
|
||||
|
||||
const truthyValues = [true, 'true', 'True', 'TRUE', '1', 'yes', 1]
|
||||
const falsyValues = [false, 'false', 'False', 'FALSE', '0', 'no', 0]
|
||||
const truthyValues = [true, 'true', '1', 'yes', 1]
|
||||
const falsyValues = [false, 'false', '0', 'no', 0]
|
||||
|
||||
let listOfBooleanKeys = [
|
||||
"prise_type_ef",
|
||||
|
@ -39,10 +40,10 @@ function boolToAddable(someBooleanValue: boolean) {
|
|||
|
||||
function isTruthyValue(someValue: string) {
|
||||
let convertedValue;
|
||||
if (truthyValues.indexOf(someValue) !== -1) {
|
||||
if (truthyValues.indexOf(someValue + ''.toLowerCase()) !== -1) {
|
||||
convertedValue = true
|
||||
}
|
||||
if (falsyValues.indexOf(someValue) !== -1) {
|
||||
if (falsyValues.indexOf(someValue + ''.toLowerCase()) !== -1) {
|
||||
convertedValue = false
|
||||
}
|
||||
return convertedValue
|
||||
|
@ -138,39 +139,35 @@ function truncate_enums_to_limit(str: string, limit: number = 255) {
|
|||
}
|
||||
|
||||
function convertToBoolean(originalValue: any): boolean {
|
||||
if (truthyValues.indexOf(originalValue) !== -1) {
|
||||
if (truthyValues.indexOf(originalValue + ''.toLowerCase()) !== -1) {
|
||||
return true;
|
||||
}
|
||||
if (falsyValues.indexOf(originalValue) !== -1) {
|
||||
if (falsyValues.indexOf(originalValue + ''.toLowerCase()) !== -1) {
|
||||
return false;
|
||||
}
|
||||
return false; // valeur par défaut
|
||||
}
|
||||
|
||||
function convertToYesOrNo(originalValue: any) {
|
||||
function convertToYesOrNo(originalValue: any): string {
|
||||
let intermediateValue = '' + originalValue
|
||||
let isEnumeration = false;
|
||||
let convertedValue = '';
|
||||
|
||||
// handle lists with ; as separator
|
||||
if (intermediateValue.includes(';')) {
|
||||
isEnumeration = true;
|
||||
intermediateValue = intermediateValue.split(';')[0]
|
||||
}
|
||||
// on ne peut pas conclure ce que l'on doit garder avec une liste
|
||||
if (isEnumeration) {
|
||||
|
||||
if (intermediateValue.indexOf(';') !== -1) {
|
||||
return ''
|
||||
}
|
||||
|
||||
intermediateValue = intermediateValue.split(';')[0]
|
||||
|
||||
debugLog('convertProperty: ==========> original value', originalValue, intermediateValue)
|
||||
if (truthyValues.indexOf(originalValue) !== -1) {
|
||||
convertedValue = 'yes'
|
||||
if (truthyValues.indexOf((originalValue + '').toLowerCase()) !== -1) {
|
||||
return 'yes'
|
||||
} else {
|
||||
debugLog('convertProperty: ==========> !!! NOT in truthy values', originalValue)
|
||||
}
|
||||
if (falsyValues.indexOf(originalValue) !== -1) {
|
||||
convertedValue = 'no'
|
||||
if (falsyValues.indexOf((originalValue + '').toLowerCase()) !== -1) {
|
||||
return 'no'
|
||||
} else {
|
||||
debugLog('convertProperty: ==========> !!! NOT in falsy values', originalValue)
|
||||
}
|
||||
|
@ -178,6 +175,30 @@ function convertToYesOrNo(originalValue: any) {
|
|||
return convertedValue;
|
||||
}
|
||||
|
||||
async function replaceFile(sourceFilePathGeoJson: string, url: string) {
|
||||
const response = await fetch(url)
|
||||
if (!response.ok) {
|
||||
throw new Error(`Erreur lors du téléchargement: ${response.status} ${response.statusText}`)
|
||||
}
|
||||
// afficher la taille du fichier téléchargé
|
||||
const contentLength = response.headers.get('content-length')
|
||||
|
||||
const data = await response.text()
|
||||
if (contentLength) {
|
||||
const sizeInMB = (parseInt(contentLength) / (1024 * 1024)).toFixed(2)
|
||||
console.log(`Taille du fichier téléchargé: ${sizeInMB} Mo`)
|
||||
} else {
|
||||
|
||||
// mesurer la taille des données
|
||||
const sizeInMB = (data.length / (1024 * 1024)).toFixed(2)
|
||||
console.log(`Taille des données: ${sizeInMB} Mo`)
|
||||
}
|
||||
|
||||
fs.writeFileSync(sourceFilePathGeoJson, data)
|
||||
console.log('fichier téléchargé avec succès:', sourceFilePathGeoJson)
|
||||
|
||||
}
|
||||
|
||||
export default {
|
||||
// debug tools
|
||||
debugLog,
|
||||
|
@ -198,4 +219,5 @@ export default {
|
|||
prefix_phone_fr_only,
|
||||
// file tools
|
||||
writeFile,
|
||||
replaceFile,
|
||||
}
|
||||
|
|
|
@ -70,6 +70,10 @@ export const mappingBoolean: MappingConfigType = {
|
|||
consolidated_is_lon_lat_correct: {
|
||||
convert_to_boolean_value: true,
|
||||
},
|
||||
prise_type_chademo: {
|
||||
key_converted: 'socket:chademo',
|
||||
convert_to_boolean_value: true,
|
||||
},
|
||||
},
|
||||
add_not_mapped_tags_too: false,
|
||||
source: {
|
||||
|
|
|
@ -21,6 +21,26 @@
|
|||
"osm_id": 1234567890,
|
||||
"non_spécifié": "non spécifié"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
4.822159,
|
||||
45.635079
|
||||
]
|
||||
},
|
||||
"properties": {
|
||||
"boolean_enum": "True;false",
|
||||
"boolean_simple": "True",
|
||||
"boolean_simple_false": "False",
|
||||
"boolean_simple_false_uppercase": "FALSE",
|
||||
"boolean_simple_true": "TRUE",
|
||||
"boolean_simple_one": "1",
|
||||
"boolean_simple_zero": "0",
|
||||
"id": "0000002"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -83,19 +83,19 @@ describe('convert boolean keys', () => {
|
|||
expect(mapped_point.properties).toStrictEqual({ consolidated_is_lon_lat_correct: 'yes' })
|
||||
})
|
||||
|
||||
// test('ignore one value if it is truthy', () => {
|
||||
// let Mapping_engine = new MappingEngine(mappings.mappingIgnoreTruthy)
|
||||
// Mapping_engine.setConfig(mappings.mappingIgnoreTruthy)
|
||||
// let feature_to_test = testingGeoJson.features[0]
|
||||
// let mapped_point = Mapping_engine.mapElementFromConf(feature_to_test)
|
||||
// expect(mapped_point.properties).toStrictEqual({})
|
||||
// })
|
||||
// test('ignore one value if it is falsy', () => {
|
||||
// let Mapping_engine = new MappingEngine(mappings.mappingIgnoreFalsy)
|
||||
// let feature_to_test = testingGeoJson.features[0]
|
||||
// let mapped_point = Mapping_engine.mapElementFromConf(feature_to_test)
|
||||
// expect(mapped_point.properties).toStrictEqual({})
|
||||
// })
|
||||
test('no result with enum transform', () => {
|
||||
// on ne doit rien garder en cas d'énumération dans une propriété censée être booléenne si elle est une énumération
|
||||
expect(utils.convertToYesOrNo("True;FALSE")).toStrictEqual('')
|
||||
})
|
||||
|
||||
test('no result with simple transform', () => {
|
||||
expect(utils.convertToYesOrNo("1")).toStrictEqual('yes')
|
||||
})
|
||||
|
||||
test('no result with simple transform', () => {
|
||||
expect(utils.convertToYesOrNo("False")).toStrictEqual('no')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
describe('ignore points having osm id', () => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue