2023-07-29 14:43:01 +02:00
|
|
|
/**
|
|
|
|
* 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 23:16:36 +02:00
|
|
|
import minimist from 'minimist'
|
2023-07-30 15:52:01 +02:00
|
|
|
import mappingConfigIRVE from 'mappings/configIRVE'
|
2023-07-29 23:16:36 +02:00
|
|
|
|
|
|
|
let mini_arguments = minimist(process.argv.slice(2))
|
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
|
2023-07-29 23:04:11 +02:00
|
|
|
let enableFilterOnDepartment = true
|
2023-07-29 23:16:36 +02:00
|
|
|
let filterDepartment = 91
|
|
|
|
if (mini_arguments['department']) {
|
|
|
|
filterDepartment = mini_arguments['department']
|
|
|
|
}
|
|
|
|
|
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
|
2023-07-29 23:04:11 +02:00
|
|
|
} 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
|
|
|
|
2023-07-29 14:43:01 +02:00
|
|
|
// let sourceFileChargemapJson = './chargemap_data/hurepoix.json'
|
2023-07-29 18:47:20 +02:00
|
|
|
let sourceFileIRVEGeoJson = './etalab_data/latest.json'
|
2023-07-29 23:04:11 +02:00
|
|
|
let defaultPropertiesOfPoint = {
|
|
|
|
'amenity': 'charging_station'
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 14:43:01 +02:00
|
|
|
|
2023-07-29 22:16:36 +02:00
|
|
|
function debugLog (message) {
|
|
|
|
if (!show_debug) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
console.log('debug: ', ...message)
|
2023-07-29 14:43:01 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
})
|
2023-07-29 14:43:01 +02:00
|
|
|
}
|
|
|
|
|
2023-07-29 23:04:11 +02:00
|
|
|
function isBooleanKey (pointKeyName) {
|
|
|
|
|
|
|
|
return listOfBooleanKeys.indexOf(pointKeyName) !== -1
|
|
|
|
}
|
|
|
|
|
2023-07-29 14:43:01 +02:00
|
|
|
/**
|
|
|
|
* 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 14:43:01 +02:00
|
|
|
|
2023-07-29 22:16:36 +02:00
|
|
|
debugLog('keys', mappingKeys, featurePointPropertiesKeys)
|
2023-07-29 14:43:01 +02:00
|
|
|
|
2023-07-29 23:04:11 +02:00
|
|
|
let newProperties = defaultPropertiesOfPoint
|
2023-07-29 14:43:01 +02:00
|
|
|
|
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 14:43:01 +02:00
|
|
|
|
2023-07-29 22:16:36 +02:00
|
|
|
// apply new properties if found in mapping config
|
|
|
|
featurePointPropertiesKeys.forEach(pointKeyName => {
|
2023-07-29 14:43:01 +02:00
|
|
|
|
2023-07-29 22:16:36 +02:00
|
|
|
if (mappingKeys.indexOf(pointKeyName) !== -1) {
|
|
|
|
debugLog('found element', pointKeyName, '=>', mappingConfig[pointKeyName], 'value : ', featurePoint.properties[pointKeyName])
|
2023-07-29 23:04:11 +02:00
|
|
|
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 14:43:01 +02:00
|
|
|
|
2023-07-29 22:16:36 +02:00
|
|
|
debugLog('basePoint', basePoint)
|
|
|
|
return basePoint
|
2023-07-29 14:43:01 +02:00
|
|
|
}
|
|
|
|
|
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 14:43:01 +02:00
|
|
|
}
|
|
|
|
|
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)
|
2023-07-29 14:43:01 +02:00
|
|
|
|
2023-07-29 21:59:51 +02:00
|
|
|
// convertDataFromChargemap(sourceFileChargemapJson, mappingConfigIRVE)
|