/** * convertisseur de données de bornes de recharge électrique à partir de données Chargemap et open data Etalab */ import fs from 'node-fs' let show_debug = 0 // wip filter let filterOnBoundingBox = true filterOnBoundingBox = false let boundingBoxCoordinates = { xMin: 1.91, xMax: 2.38, yMin: 48.7, yMax: 48.4, } let filterCoordinates = true let enableFilterOnDepartment = false let filterDepartment = 91 let filterZipCode = new RegExp(`^${filterDepartment}`) let filterZipCodeAdresse = new RegExp(` ${filterDepartment}`) let filteredName = '' if (enableFilterOnDepartment) { filteredName = '_filtered_zipcode_' + filterDepartment } if (filterOnBoundingBox) { filteredName = '_filtered_bbox_' + boundingBoxCoordinates.xMin + '-' + boundingBoxCoordinates.xMax + '_' + boundingBoxCoordinates.yMin + '-' + boundingBoxCoordinates.yMax } let pointCounterMax = 1000000 let limitConversionToFirstPoint = false // limitConversionToFirstPoint = true; if (limitConversionToFirstPoint) { pointCounterMax = 1 } // let sourceFileChargemapJson = './chargemap_data/hurepoix.json' let sourceFileIRVEGeoJson = './etalab_data/latest.json' /** * plan de conversion des clés du jeu de données vers les tags OSM * 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 = { 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 nbre_pdc: 'capacity', id_station_itinerance: 'ref:EU:EVSE', id_station_local: 'ref', 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', reservation: 'reservation', accessibilite_pmr: 'wheelchair', date_mise_en_service: 'start_date', observations: 'note', date_maj: 'source:date', nom_station: 'name', nom_enseigne: 'network', cable_t2_attache: 'socket:type2_cable', // TODO gestion des types dont on doit convertir la valeur // station_deux_roues => // ajout de trois tags: // bicycle=yes // scooter=yes // motorcar=no // consolidated_code_postal: "zipcode", } function debugLog (message) { if (!show_debug) { return } console.log('debug: ', ...message) } 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 } }) } /** * retuns the converted element from mapping config if present, null otherwise */ function mapElementFromConf (featurePoint, mappingConfig) { let mappingKeys = Object.keys(mappingConfig) let featurePointPropertiesKeys = Object.keys(featurePoint.properties) debugLog('keys', mappingKeys, featurePointPropertiesKeys) let newProperties = {} // 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 => { if (mappingKeys.indexOf(pointKeyName) !== -1) { debugLog('found element', pointKeyName, '=>', mappingConfig[pointKeyName], 'value : ', featurePoint.properties[pointKeyName]) newProperties[mappingConfig[pointKeyName]] = featurePoint.properties[pointKeyName] } }) debugLog('basePoint', basePoint) return basePoint } 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!`) } } ) } console.log('pointCounterMax', pointCounterMax) convertDataForIRVE(sourceFileIRVEGeoJson, mappingConfigIRVE, pointCounterMax, boundingBoxCoordinates) // convertDataFromChargemap(sourceFileChargemapJson, mappingConfigIRVE)