2020-10-19 12:08:42 +02:00
import { GeoOperations } from "./GeoOperations" ;
2021-03-24 01:25:57 +01:00
import LayerConfig from "../Customizations/JSON/LayerConfig" ;
import SimpleMetaTagger from "./SimpleMetaTagger" ;
export class ExtraFunction {
static readonly doc : string = "When the feature is downloaded, some extra tags can be calculated by a javascript snippet. The feature is passed as 'feat'; there are a few functions available on it to handle it - apart from 'feat.tags' which is a classic object containing all the tags."
private static DistanceToFunc = new ExtraFunction (
"distanceTo" ,
"Calculates the distance between the feature and a specified point" ,
[ "longitude" , "latitude" ] ,
( feature ) = > {
return ( lon , lat ) = > {
// Feature._lon and ._lat is conveniently place by one of the other metatags
return GeoOperations . distanceBetween ( [ lon , lat ] , [ feature . _lon , feature . _lat ] ) ;
2020-10-19 12:08:42 +02:00
}
}
2021-03-24 01:25:57 +01:00
)
private static readonly allFuncs : ExtraFunction [ ] = [ ExtraFunction . DistanceToFunc ] ;
private readonly _name : string ;
private readonly _args : string [ ] ;
private readonly _doc : string ;
private readonly _f : ( feat : any ) = > any ;
constructor ( name : string , doc : string , args : string [ ] , f : ( ( feat : any ) = > any ) ) {
this . _name = name ;
this . _doc = doc ;
this . _args = args ;
this . _f = f ;
2020-10-19 12:08:42 +02:00
}
2021-03-24 01:25:57 +01:00
public static FullPatchFeature ( feature ) {
for ( const func of ExtraFunction . allFuncs ) {
func . PatchFeature ( feature ) ;
2020-10-19 12:08:42 +02:00
}
}
2021-03-24 01:25:57 +01:00
public PatchFeature ( feature : any ) {
feature [ this . _name ] = this . _f ( feature ) ;
}
2020-10-19 12:08:42 +02:00
}
/ * *
* Metatagging adds various tags to the elements , e . g . lat , lon , surface area , . . .
*
* All metatags start with an underscore
* /
export default class MetaTagging {
2021-03-24 01:25:57 +01:00
/ * *
* An actor which adds metatags on every feature in the given object
* The features are a list of geojson - features , with a "properties" - field and geometry
* /
static addMetatags ( features : { feature : any ; freshness : Date } [ ] , layers : LayerConfig [ ] ) {
2020-10-30 00:56:46 +01:00
2021-03-24 01:25:57 +01:00
for ( const metatag of SimpleMetaTagger . metatags ) {
try {
metatag . addMetaTags ( features ) ;
} catch ( e ) {
console . error ( "Could not calculate metatag for " , metatag . keys . join ( "," ) , ":" , e )
2020-10-30 00:56:46 +01:00
}
2021-03-24 01:25:57 +01:00
}
2020-10-30 00:56:46 +01:00
2021-03-24 01:25:57 +01:00
// The functions - per layer - which add the new keys
const layerFuncs = new Map < string , ( ( feature : any ) = > void ) > ( ) ;
for ( const layer of layers ) {
layerFuncs . set ( layer . id , this . createRetaggingFunc ( layer ) ) ;
}
2020-10-30 00:56:46 +01:00
2021-03-24 01:25:57 +01:00
for ( const feature of features ) {
// @ts-ignore
const key = feature . feature . _matching_layer_id ;
const f = layerFuncs . get ( key ) ;
if ( f === undefined ) {
continue ;
2020-10-30 00:56:46 +01:00
}
2021-03-24 01:25:57 +01:00
f ( feature . feature )
}
2020-10-30 00:56:46 +01:00
2021-03-24 01:25:57 +01:00
}
2020-10-30 00:56:46 +01:00
2021-03-24 01:25:57 +01:00
private static createRetaggingFunc ( layer : LayerConfig ) : ( ( feature : any ) = > void ) {
const calculatedTags : [ string , string ] [ ] = layer . calculatedTags ;
if ( calculatedTags === undefined ) {
return undefined ;
2020-10-30 00:56:46 +01:00
}
2021-03-22 02:45:22 +01:00
2021-03-24 01:25:57 +01:00
const functions : ( ( feature : any ) = > void ) [ ] = [ ] ;
for ( const entry of calculatedTags ) {
const key = entry [ 0 ]
const code = entry [ 1 ] ;
if ( code === undefined ) {
continue ;
2021-03-22 01:04:25 +01:00
}
2021-03-24 01:25:57 +01:00
const func = new Function ( "feat" , "return " + code + ";" ) ;
2021-03-22 01:04:25 +01:00
2021-03-24 01:25:57 +01:00
const f = ( feature : any ) = > {
feature . properties [ key ] = func ( feature ) ;
2021-03-22 01:04:25 +01:00
}
2021-03-24 01:25:57 +01:00
functions . push ( f )
2021-02-20 03:29:55 +01:00
}
2021-03-24 01:25:57 +01:00
return ( feature ) = > {
const tags = feature . properties
if ( tags === undefined ) {
return ;
2020-11-11 16:23:49 +01:00
}
2021-03-22 02:45:22 +01:00
2021-03-24 01:25:57 +01:00
ExtraFunction . FullPatchFeature ( feature ) ;
2021-03-22 02:45:22 +01:00
2021-03-24 01:25:57 +01:00
for ( const f of functions ) {
try {
f ( feature ) ;
} catch ( e ) {
console . error ( "While calculating a tag value: " , e )
}
2021-03-22 01:04:25 +01:00
2021-03-24 01:25:57 +01:00
}
2021-03-22 01:04:25 +01:00
}
}
2020-10-19 12:08:42 +02:00
}