scripts/mapping_geojson_to_osm_tags/convert_to_osm_tags.mjs

274 lines
7.6 KiB
JavaScript
Raw Normal View History

/**
* convertisseur de données de bornes de recharge électrique à partir de données Chargemap et open data Etalab
*/
2023-07-29 22:16:36 +02:00
import fs from 'node-fs'
2023-07-29 17:19:56 +02:00
2023-07-29 22:16:36 +02:00
let show_debug = 0
2023-07-29 22:10:50 +02:00
// wip filter
let filterOnBoundingBox = true
2023-07-29 22:16:36 +02:00
filterOnBoundingBox = false
2023-07-29 22:10:50 +02:00
2023-07-29 22:16:36 +02:00
let boundingBoxCoordinates = {
xMin: 1.91,
xMax: 2.38,
yMin: 48.7,
yMax: 48.4,
2023-07-29 22:10:50 +02:00
}
2023-07-29 22:16:36 +02:00
let filterCoordinates = true
let enableFilterOnDepartment = true
let filterDepartment = 974
2023-07-29 22:16:36 +02:00
let filterZipCode = new RegExp(`^${filterDepartment}`)
let filterZipCodeAdresse = new RegExp(` ${filterDepartment}`)
let filteredName = ''
2023-07-29 17:19:56 +02:00
2023-07-29 22:16:36 +02:00
if (enableFilterOnDepartment) {
filteredName = '_filtered_zipcode_' + filterDepartment
} else if (filterOnBoundingBox) {
2023-07-29 22:16:36 +02:00
filteredName = '_filtered_bbox_' + boundingBoxCoordinates.xMin + '-' + boundingBoxCoordinates.xMax + '_' + boundingBoxCoordinates.yMin + '-' + boundingBoxCoordinates.yMax
2023-07-29 22:10:50 +02:00
}
2023-07-29 22:16:36 +02:00
let pointCounterMax = 1000000
2023-07-29 17:19:56 +02:00
2023-07-29 22:16:36 +02:00
let limitConversionToFirstPoint = false
2023-07-29 22:10:50 +02:00
// limitConversionToFirstPoint = true;
if (limitConversionToFirstPoint) {
2023-07-29 22:16:36 +02:00
pointCounterMax = 1
2023-07-29 22:10:50 +02:00
}
2023-07-29 17:19:56 +02:00
// let sourceFileChargemapJson = './chargemap_data/hurepoix.json'
2023-07-29 18:47:20 +02:00
let sourceFileIRVEGeoJson = './etalab_data/latest.json'
let defaultPropertiesOfPoint = {
'amenity': 'charging_station'
}
/**
* plan de conversion des clés du jeu de données vers les tags OSM
2023-07-29 19:03:52 +02:00
* détail dans le tableau
* https://wiki.openstreetmap.org/wiki/France/data.gouv.fr/Bornes_de_Recharge_pour_V%C3%A9hicules_%C3%89lectriques
*/
let mappingConfigIRVE = {
// ******* nombres
nbre_pdc: 'capacity',
// ******* textes
2023-07-29 22:16:36 +02:00
amenity: 'amenity', // conserver le tag de base
capacity: 'capacity', // conserver le tag de base
nom_amenageur: 'operator',
siren_amenageur: 'owner:ref:FR:SIREN',
nom_operateur: 'operator',
telephone_operateur: 'phone',
contact_operateur: 'email', // ici, on souhaite convertir la clé contact_operateur=bidule en email=bidule
2023-07-29 22:16:36 +02:00
id_station_itinerance: 'ref:EU:EVSE',
id_station_local: 'ref',
2023-07-29 22:16:36 +02:00
gratuit: 'fee',
paiement_acte: 'authentication:none',
2023-07-29 22:16:36 +02:00
reservation: 'reservation',
observations: 'note',
nom_station: 'name',
nom_enseigne: 'network',
// ******* dates
date_mise_en_service: 'start_date',
date_maj: 'source:date',
2023-07-29 22:16:36 +02:00
// TODO gestion des types dont on doit convertir la valeur
// ******** champs booléens
cable_t2_attache: 'socket:type2_cable',
prise_type_ef: 'socket:typee',
prise_type_2: 'socket:type2',
prise_type_combo_ccs: 'socket:type2_combo',
prise_type_chademo: 'socket:chademo',
// ******** champs plus complexes
horaires: 'opening_hours', // déjà au bon format
// accessibilite_pmr: 'wheelchair',
// paiement_cb: 'payment:credit_cards',
2023-07-29 22:16:36 +02:00
// station_deux_roues =>
// ajout de trois tags:
// bicycle=yes
// scooter=yes
// motorcar=no
// consolidated_code_postal: "zipcode",
}
let listOfBooleanKeys = Object.keys({
prise_type_ef: 'socket:typee',
prise_type_2: 'socket:type2',
prise_type_combo_ccs: 'socket:type2_combo',
prise_type_chademo: 'socket:chademo',
gratuit: 'fee',
paiement_acte: 'authentication:none',
paiement_cb: 'payment:credit_cards',
cable_t2_attache: 'socket:type2_cable',
})
2023-07-29 22:16:36 +02:00
function debugLog (message) {
if (!show_debug) {
return
}
console.log('debug: ', ...message)
}
2023-07-29 22:16:36 +02:00
function convertDataForIRVE (sourceFilePath, mapping, pointCounterMax, boundingBoxCoordinates) {
debugLog('convertDataFromChargemap from ', sourceFilePath)
let convertedGeoJson = {
type: 'FeatureCollection',
features: []
}
fs.readFile(sourceFilePath, 'utf8', function (err, data) {
let pointcounter = 0
if (err) {
return debugLog(err)
}
let dataTransformed = JSON.parse(data)
// debug('data keys ', Object.keys(dataTransformed))
debugLog('debug: properties of point 0', dataTransformed.features[0])
if (dataTransformed.features) {
debugLog('data found, features:', dataTransformed.features.length)
// find interesting list of points to use
let listOfPoints = dataTransformed.features
// for each point from the data source, convert with the mapping
console.log('listOfPoints.length', listOfPoints.length)
listOfPoints.forEach(featurePoint => {
let regextestresult = true
if (enableFilterOnDepartment) {
console.log('filtre sur les départements activé')
regextestresult = (
filterZipCode.test(featurePoint.properties.consolidated_code_postal)
||
filterZipCodeAdresse.test(featurePoint.properties.adresse_station)
)
} else if (filterOnBoundingBox) {
console.log('filtre sur les coordonnées activé')
let x = featurePoint.properties.coordonneesXY[0]
let xMin = boundingBoxCoordinates.xMin
let xMax = boundingBoxCoordinates.xMax
let yMin = boundingBoxCoordinates.yMin
let yMax = boundingBoxCoordinates.yMax
let y = featurePoint.properties.coordonneesXY[1]
regextestresult = (
(x >= xMin && x <= xMax)
&&
(y >= yMin && y <= yMax)
)
}
// filter points depending on zipcode
if (filterCoordinates && regextestresult) {
debugLog('featurePoint.properties.consolidated_code_postal', featurePoint.properties.consolidated_code_postal)
// limit results number of points
// if (pointcounter < pointCounterMax) {
debugLog('add point')
debugLog('featurePoint', featurePoint)
let mappedPoint = mapElementFromConf(featurePoint, mapping)
debugLog('map one point', featurePoint, mappedPoint)
if (mappedPoint) {
convertedGeoJson.features.push(mappedPoint)
}
}
// }
pointcounter++
})
// output new geojson
console.log('convertedGeoJson.features.length', convertedGeoJson.features.length)
// write file on disk
let fileNameToWrite = 'my_converted_data_set' + filteredName + '.json'
console.log('write file ', fileNameToWrite)
writeJsonFile(fileNameToWrite, JSON.stringify(convertedGeoJson, null, 2))
debugLog('mapped output:', convertedGeoJson.features)
return convertedGeoJson
}
})
}
function isBooleanKey (pointKeyName) {
return listOfBooleanKeys.indexOf(pointKeyName) !== -1
}
/**
* retuns the converted element from mapping config if present, null otherwise
*/
2023-07-29 22:16:36 +02:00
function mapElementFromConf (featurePoint, mappingConfig) {
let mappingKeys = Object.keys(mappingConfig)
let featurePointPropertiesKeys = Object.keys(featurePoint.properties)
2023-07-29 22:16:36 +02:00
debugLog('keys', mappingKeys, featurePointPropertiesKeys)
let newProperties = defaultPropertiesOfPoint
2023-07-29 22:16:36 +02:00
// reinit properties of current point
let basePoint = Object.create(featurePoint)
basePoint.type = featurePoint.type
basePoint.geometry = featurePoint.geometry
basePoint.properties = newProperties
2023-07-29 22:16:36 +02:00
// apply new properties if found in mapping config
featurePointPropertiesKeys.forEach(pointKeyName => {
2023-07-29 22:16:36 +02:00
if (mappingKeys.indexOf(pointKeyName) !== -1) {
debugLog('found element', pointKeyName, '=>', mappingConfig[pointKeyName], 'value : ', featurePoint.properties[pointKeyName])
let convertedValue = ''
if (isBooleanKey(pointKeyName)) {
convertedValue = featurePoint.properties[pointKeyName].toLowerCase() == 'true' ? 'yes' : 'no'
} else {
convertedValue = featurePoint.properties[pointKeyName]
}
if (convertedValue) {
newProperties[mappingConfig[pointKeyName]] = convertedValue
}
2023-07-29 22:16:36 +02:00
}
})
2023-07-29 22:16:36 +02:00
debugLog('basePoint', basePoint)
return basePoint
}
2023-07-29 22:16:36 +02:00
function writeJsonFile (fileName, fileContent) {
debugLog('write file ', fileName)
return fs.writeFile(
`./output/${fileName}`,
fileContent,
'utf8',
(err) => {
if (err) {
debugLog(`Error writing file: ${err}`)
} else {
debugLog(`File ${fileName} is written successfully!`)
}
}
)
}
2023-07-29 17:19:56 +02:00
console.log('pointCounterMax', pointCounterMax)
2023-07-29 22:16:36 +02:00
convertDataForIRVE(sourceFileIRVEGeoJson, mappingConfigIRVE, pointCounterMax, boundingBoxCoordinates)
// convertDataFromChargemap(sourceFileChargemapJson, mappingConfigIRVE)