2023-08-09 23:10:45 +02:00
import custom_utils from './utils'
import MappingConfigType from "./mapping-config.type" ;
const { debugLog } = custom_utils
let listOfBooleanKeys = [
"prise_type_ef" ,
"prise_type_2" ,
"prise_type_combo_ccs" ,
"prise_type_chademo" ,
"gratuit" ,
"paiement_acte" ,
"paiement_cb" ,
"cable_t2_attache"
]
export default class {
mapping_config : any = { }
2023-08-30 15:55:45 +02:00
private jardinage = true ;
public stats : any ;
2023-08-09 23:10:45 +02:00
constructor ( mappingConfig : MappingConfigType ) {
2023-08-18 11:25:02 +02:00
2023-08-09 23:10:45 +02:00
this . setConfig ( mappingConfig )
2023-08-30 15:55:45 +02:00
this . stats = {
phones_updated : 0 ,
phones_updated_list : [ ] ,
phones_not_updated : 0
}
2023-08-09 23:10:45 +02:00
}
setConfig ( mappingConfig : MappingConfigType ) {
2023-08-30 15:09:41 +02:00
debugLog ( 'load config' , mappingConfig . config_name )
2023-08-09 23:10:45 +02:00
this . mapping_config = mappingConfig
}
2023-08-18 11:25:02 +02:00
getConfig() {
return this . mapping_config
}
2023-08-09 23:10:45 +02:00
mapFeaturePoint ( featurePointGeoJson : any ) {
let geoJSONConvertedPoint : any = { }
2023-08-30 15:55:45 +02:00
2023-08-09 23:10:45 +02:00
geoJSONConvertedPoint . properties = { . . . this . mapping_config . default_properties_of_point }
geoJSONConvertedPoint . type = featurePointGeoJson . type
geoJSONConvertedPoint . geometry = featurePointGeoJson . geometry
2023-08-30 15:55:45 +02:00
2023-08-09 23:10:45 +02:00
// let props = featurePointGeoJson.properties
// props.forEach((key, value) => {
//
// })
return geoJSONConvertedPoint
}
/ * *
* TODO convert to mapping config property to transform_truthy
* @param pointKeyName
* @returns { boolean }
* /
isBooleanKey ( pointKeyName : string ) : boolean {
return listOfBooleanKeys . indexOf ( pointKeyName ) !== - 1
}
2023-08-18 11:58:52 +02:00
truthyValues = [ true , 'true' , 'True' , 'TRUE' , '1' , 'yes' , 1 ]
falsyValues = [ false , 'false' , 'False' , 'FALSE' , '0' , 'no' , 0 ]
2023-08-09 23:10:45 +02:00
/ * *
* reduce number of features
* @param offsetCount
* @param listOfFeatures
* /
filterFeaturesByOffset ( offsetCount : number , listOfFeatures : any ) : Array < any > {
let filteredList = listOfFeatures
// TODO
return filteredList
}
// filterFeaturesByPropertyRegex(bboxConfig:any, listOfFeatures:any) {
// debugLog('bboxConfig', bboxConfig)
// let filteredList = listOfFeatures
// // TODO
// return filteredList
// }
filterFeaturesByPropertyRegex ( propertyName : string , criteriaRegex : any , listOfFeatures : any ) {
let filteredList = listOfFeatures . filter ( ( feature : any ) = > {
return criteriaRegex . test ( feature ? . properties [ propertyName ] )
} )
return filteredList
}
/ * *
* retuns the converted element from mapping config if present , null otherwise
* /
mapElementFromConf ( featurePoint : any ) : any {
2023-08-18 12:08:25 +02:00
debugLog ( 'mapElementFromConf: mapElementFromConf' , featurePoint )
2023-08-09 23:10:45 +02:00
if ( ! this . mapping_config ) {
2023-08-18 11:25:02 +02:00
throw new Error ( 'no config was loaded in the mapping engine. use setConfig(my_mapping_config) on this instance of mapping engine before using this. Your config should be typed to MappingConfigType Type.' )
2023-08-09 23:10:45 +02:00
}
debugLog ( 'mapElementFromConf: config_name' , this . mapping_config . config_name )
let mappingKeys = Object . keys ( this . mapping_config . tags )
let featurePointPropertiesKeys = Object . keys ( featurePoint . properties )
debugLog ( 'mapElementFromConf: ============= keys mappingKeys:' , this . mapping_config . tags . length , mappingKeys . length )
debugLog ( 'mapElementFromConf: ============= keys featurePointPropertiesKeys :' , featurePoint . properties . length , featurePointPropertiesKeys . length )
let newProperties = { . . . this . mapping_config . default_properties_of_point }
// reinit properties of current point
let basePoint = Object . create ( featurePoint )
basePoint . type = featurePoint . type
basePoint . geometry = featurePoint . geometry
basePoint . properties = { . . . this . mapping_config . default_properties_of_point }
// apply new properties if found in mapping config
featurePointPropertiesKeys . forEach ( pointKeyName = > {
debugLog ( 'mapElementFromConf: convert' , pointKeyName )
2023-08-18 11:39:40 +02:00
debugLog ( 'mapElementFromConf: mapping keys:' , mappingKeys )
2023-08-09 23:10:45 +02:00
this . convertProperty ( pointKeyName , mappingKeys , featurePoint , newProperties )
} )
basePoint . properties = newProperties
// debugLog('mapElementFromConf: basePoint', basePoint)
return basePoint
}
/ * *
* convertit une propriété en une autre selon la config de mapping
* @param pointKeyName
* @param mappingKeys
* @param featurePoint
* @param newProperties
* /
convertProperty ( pointKeyName : string , mappingKeys : any , featurePoint : any , newProperties : any ) {
let originalValue = featurePoint . properties [ pointKeyName ]
let mappingValueObject : any = '' ;
2023-08-18 11:39:40 +02:00
if ( mappingKeys . indexOf ( pointKeyName ) !== - 1 ) {
2023-08-09 23:10:45 +02:00
mappingValueObject = this . mapping_config . tags [ pointKeyName ]
debugLog ( 'convertProperty: mappingValueObject ' , mappingValueObject )
}
debugLog ( ' ------ convertProperty: pointKeyName' , pointKeyName )
// debugLog('convertProperty: mappingKeys', mappingKeys)
2023-08-30 15:55:45 +02:00
if ( this . jardinage ) {
debugLog ( ' ------ on fait du jardinage' )
debugLog ( ' ------ mode mise en qualité activé' )
debugLog ( ' ------ les données en entrée sont des infos geojson extraites depuis overpass turbo.' )
debugLog ( ' ------ les clés des objets sont donc déjà dans le format de tag OSM,' +
'ne pas les convertir pour les mettre en qualité selon le modèle de mapping.' )
}
2023-08-09 23:10:45 +02:00
if ( this . mapping_config . add_not_mapped_tags_too && ( mappingKeys . indexOf ( pointKeyName ) === - 1 ) ) {
/ * *
* add all unmapped tags is enabled
* /
2023-08-18 11:39:40 +02:00
debugLog ( ' ------ add all unmapped tags is enabled' )
2023-08-09 23:10:45 +02:00
newProperties [ pointKeyName ] = originalValue ;
} else {
/ * *
* only use existing keys
* /
2023-08-18 11:39:40 +02:00
if ( mappingKeys . indexOf ( pointKeyName ) !== - 1 ) {
2023-08-09 23:10:45 +02:00
let valueConvertedFromMapping = featurePoint . properties [ pointKeyName ]
let keyConvertedFromMapping = mappingKeys [ mappingKeys . indexOf ( pointKeyName ) ]
let mappingConfigOfTag = this . mapping_config . tags [ pointKeyName ]
debugLog ( '========== mappingConfigOfTag' , mappingConfigOfTag )
debugLog ( 'convertProperty: found element' , pointKeyName , '=>' , keyConvertedFromMapping , 'value : ' , valueConvertedFromMapping )
let convertedValue = originalValue
let typeOfConfigForKey = typeof mappingConfigOfTag
let isStringValue = typeOfConfigForKey === 'string'
let isConfigMappingObject = typeOfConfigForKey === 'object'
debugLog ( 'convertProperty: - typeofValue' , typeOfConfigForKey )
debugLog ( 'convertProperty: - pointKeyName' , pointKeyName )
debugLog ( 'convertProperty: - valueConvertedFromMapping' , valueConvertedFromMapping )
debugLog ( 'typeof valueConvertedFromMapping === \'string\'' , typeOfConfigForKey )
debugLog ( 'convertProperty: isStringValue?' , valueConvertedFromMapping , isStringValue )
debugLog ( 'convertProperty: isStringValue?' , valueConvertedFromMapping , isStringValue )
debugLog ( 'mappingConfigOfTag' , mappingConfigOfTag )
debugLog ( 'typeOfConfigForKey' , typeOfConfigForKey )
/ * *
* conversion si la clé à une config d ' une string , on ne change que la clé , pas la valeur
* /
if ( isStringValue ) {
debugLog ( 'convertProperty: -- string value' )
debugLog ( 'convertProperty: -- string value' )
debugLog ( 'convertProperty: -- simple conversion : ' , pointKeyName , '=> ' , mappingConfigOfTag , '_' , originalValue , '=>' , valueConvertedFromMapping )
debugLog ( 'convertProperty: -- convertedValue' , convertedValue )
convertedValue = valueConvertedFromMapping
if ( convertedValue ) {
newProperties [ mappingConfigOfTag ] = convertedValue
}
} else {
debugLog ( 'convertProperty: no string value' )
}
if ( isConfigMappingObject ) {
let configObject = mappingConfigOfTag
debugLog ( 'convertProperty: is config object' , configObject )
let newKey : any = '' + pointKeyName
let remove_original_key = false ;
if ( configObject . key_converted ) {
newKey = configObject . key_converted
}
if ( configObject . 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'
debugLog ( 'truthy_value' , originalValue )
if ( this . truthyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = configObject . truthy_value
}
}
if ( configObject . falsy_value ) {
if ( this . falsyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = configObject . falsy_value
}
}
/ * *
* conversion booléenne
* /
if ( mappingValueObject . convert_to_boolean_value ) {
debugLog ( 'convertProperty: is boolean_value_conversion' )
debugLog ( 'convertProperty: ==========> original value' , originalValue )
if ( this . truthyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = 'yes'
2023-08-18 11:58:52 +02:00
} else {
debugLog ( 'convertProperty: ==========> !!! NOT in truthy values' , originalValue )
2023-08-09 23:10:45 +02:00
}
if ( this . falsyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = 'no'
2023-08-18 11:58:52 +02:00
} else {
debugLog ( 'convertProperty: ==========> !!! NOT in falsy values' , originalValue )
2023-08-09 23:10:45 +02:00
}
} else {
debugLog ( 'convertProperty: is NOT having boolean_value_conversion' , mappingValueObject )
}
2023-08-18 11:25:02 +02:00
if ( configObject . convert_to_phone ) {
2023-08-30 15:55:45 +02:00
/ * *
* nettoyer les numéros de téléphone en ne gardant que les nombres et le préfixe de pays
* /
2023-08-30 15:09:41 +02:00
debugLog ( 'originalValue' , originalValue . substring ( 1 ) )
2023-08-30 15:55:45 +02:00
let original_without_spaces = originalValue . replace ( / /g , '' )
2023-08-30 15:09:41 +02:00
let cleaned_value = ` ${ original_without_spaces } `
cleaned_value = cleaned_value
. trim ( )
. replace ( 'Stations-e' , '' )
2023-08-30 15:55:45 +02:00
. replace ( /[a-zA-Zéèà]/ig , '' )
2023-08-30 15:09:41 +02:00
. replace ( /[\(\)\.\- ]/g , '' )
let original_array = originalValue . split ( '' )
let add_prefix = false ;
if (
/^\d/ . test ( cleaned_value ) &&
2023-08-30 15:55:45 +02:00
! /^\+33 / . test ( original_without_spaces )
) {
2023-08-30 15:09:41 +02:00
add_prefix = true
}
cleaned_value = cleaned_value . replace ( '+33' , '' )
2023-08-30 15:55:45 +02:00
if ( /^0/ . test ( cleaned_value ) ) {
cleaned_value = cleaned_value . substring ( 1 )
2023-08-30 15:09:41 +02:00
}
let array_of_numbers = cleaned_value
. split ( '' )
let ii = 0 ;
2023-08-30 15:55:45 +02:00
if ( cleaned_value . length == 4 ) {
ii = 1
2023-08-30 15:09:41 +02:00
}
convertedValue = ''
array_of_numbers . forEach ( ( num : string ) = > {
if ( ii % 2 ) {
convertedValue += ' ' ;
}
convertedValue += num ;
ii ++ ;
} )
convertedValue = convertedValue . replace ( ' ' , ' ' ) . trim ( ) ;
console . log ( 'convertedValue' , convertedValue )
if (
/^\d/ . test ( convertedValue ) &&
2023-08-30 15:55:45 +02:00
! /^\+33 / . test ( convertedValue )
) {
2023-08-30 15:09:41 +02:00
add_prefix = true
}
if ( add_prefix ) {
convertedValue = ` +33 ` + convertedValue
}
2023-08-30 15:55:45 +02:00
debugLog ( 'phone: ' , originalValue , '=>' , convertedValue )
if ( originalValue !== convertedValue ) {
this . stats . phones_updated ++
this . stats . phones_updated_list . push ( convertedValue )
} else {
this . stats . phones_not_updated ++
}
2023-08-18 11:25:02 +02:00
}
2023-08-09 23:10:45 +02:00
if ( configObject . remove_original_key ) {
remove_original_key = true
}
if ( configObject . ignore_if_falsy && this . falsyValues . indexOf ( originalValue ) !== - 1 ) {
remove_original_key = true
}
2023-08-18 12:22:07 +02:00
if ( configObject . ignore_if_truthy && this . truthyValues . indexOf ( originalValue ) !== - 1 ) {
remove_original_key = true
}
2023-08-09 23:10:45 +02:00
/ * *
* config pour une clé
* nous pouvons renseigner une string ou un objet décrivant les transformations à réaliser
* /
if ( ! remove_original_key && configObject . conditional_values ) {
debugLog ( 'convertProperty: conditional_values__________' ,
configObject . conditional_values )
let keysConditionnalValues : any = Object . keys ( configObject . conditional_values )
let isFoundValue = keysConditionnalValues . indexOf ( originalValue )
debugLog ( 'isFoundValue' , isFoundValue , originalValue )
debugLog ( 'keysConditionnalValues' , keysConditionnalValues )
if ( isFoundValue > - 1 ) {
let conditionnalConfig : any = configObject . conditional_values [ keysConditionnalValues [ isFoundValue ] ]
/ * * - - - - - - - - - - - - - - - - - - - - - -
* gestion des valeurs conditionnelles
* -- -- -- -- -- -- -- -- -- -- -- * /
debugLog ( 'conditionnalConfig' , conditionnalConfig )
if ( conditionnalConfig . ignore_this_data ) {
debugLog ( ` on ignore cette clé car sa valeur " ${ originalValue } " est à exclure: ` , pointKeyName , '=>' , newKey )
remove_original_key = true ;
}
if ( conditionnalConfig . tags_to_add ) {
// on peut définir un ensemble de tags à rajouter
let tagKeys = Object . keys ( conditionnalConfig . tags_to_add )
debugLog ( 'conditionnalConfig.tags_to_add' , conditionnalConfig . tags_to_add )
conditionnalConfig . tags_to_add . forEach ( ( object : any , pair : any ) = > {
debugLog ( 'object' , object )
debugLog ( 'pair' , pair )
let key : any = Object . keys ( object )
key = key [ 0 ]
let value = object [ key ]
debugLog ( 'key' , key )
debugLog ( 'value' , value )
newProperties [ key ] = value
} )
}
if ( conditionnalConfig . 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 ( this . truthyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = conditionnalConfig . truthy_value
}
}
if ( conditionnalConfig . falsy_value ) {
if ( this . falsyValues . indexOf ( originalValue ) !== - 1 ) {
convertedValue = conditionnalConfig . falsy_value
}
}
if ( conditionnalConfig . transform_function ) {
// une transformation de la valeur
// apply transformation to value
convertedValue = conditionnalConfig . transform_function ( originalValue )
}
// use the value converted
else if ( conditionnalConfig . value_converted ) {
convertedValue = conditionnalConfig . value_converted
}
}
}
debugLog ( 'convertProperty: convertedValue ==========> {' , newKey , ':' , convertedValue , '}' )
2023-08-18 11:25:02 +02:00
debugLog ( ' =============== remove_original_key' , newKey , remove_original_key )
2023-08-09 23:10:45 +02:00
if ( ! remove_original_key && newKey && convertedValue && ! configObject . ignore_this_data ) {
2023-08-18 11:58:52 +02:00
debugLog ( 'convertProperty: added' , newKey , convertedValue )
newProperties [ newKey ] = ( ` ${ convertedValue } ` ) . trim ( )
2023-08-09 23:10:45 +02:00
}
}
2023-08-18 11:58:52 +02:00
} else {
2023-08-18 11:39:40 +02:00
debugLog ( '!!!!!! property not found in mappingKeys: ' , pointKeyName )
2023-08-09 23:10:45 +02:00
}
}
2023-08-30 15:55:45 +02:00
2023-08-18 12:08:25 +02:00
return newProperties ;
2023-08-09 23:10:45 +02:00
}
}