forked from MapComplete/MapComplete
		
	Fix metatagging and calculated tags in heterogenous data settings
This commit is contained in:
		
							parent
							
								
									93296d5378
								
							
						
					
					
						commit
						d547b9f968
					
				
					 14 changed files with 374 additions and 246 deletions
				
			
		|  | @ -81,7 +81,10 @@ export default class LayerConfig { | ||||||
|                 osmTags = FromJSON.Tag(json.source["osmTags"], context + "source.osmTags"); |                 osmTags = FromJSON.Tag(json.source["osmTags"], context + "source.osmTags"); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| 
 |             if(json.source["geoJsonSource"] !== undefined){ | ||||||
|  |                 throw context + "Use 'geoJson' instead of 'geoJsonSource'" | ||||||
|  |             } | ||||||
|  |              | ||||||
|             this.source = new SourceConfig({ |             this.source = new SourceConfig({ | ||||||
|                 osmTags: osmTags, |                 osmTags: osmTags, | ||||||
|                 geojsonSource: json.source["geoJson"], |                 geojsonSource: json.source["geoJson"], | ||||||
|  | @ -107,7 +110,7 @@ export default class LayerConfig { | ||||||
|                 const index = kv.indexOf("=") |                 const index = kv.indexOf("=") | ||||||
|                 const key = kv.substring(0, index); |                 const key = kv.substring(0, index); | ||||||
|                 const code = kv.substring(index + 1); |                 const code = kv.substring(index + 1); | ||||||
| 
 |                  | ||||||
|                 this.calculatedTags.push([key, code]) |                 this.calculatedTags.push([key, code]) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -172,7 +175,10 @@ export default class LayerConfig { | ||||||
|                         if (shared !== undefined) { |                         if (shared !== undefined) { | ||||||
|                             return shared; |                             return shared; | ||||||
|                         } |                         } | ||||||
|                         throw `Predefined tagRendering ${renderingJson} not found in ${context}`; |                          | ||||||
|  |                         const keys = Array.from(SharedTagRenderings.SharedTagRendering.keys()) | ||||||
|  |                          | ||||||
|  |                         throw `Predefined tagRendering ${renderingJson} not found in ${context}.\n      Try one of ${(keys.join(", "))}`; | ||||||
|                     } |                     } | ||||||
|                     return new TagRenderingConfig(renderingJson, self.source.osmTags, `${context}.tagrendering[${i}]`); |                     return new TagRenderingConfig(renderingJson, self.source.osmTags, `${context}.tagrendering[${i}]`); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ import {UIEventSource} from "./UIEventSource"; | ||||||
| export class ElementStorage { | export class ElementStorage { | ||||||
| 
 | 
 | ||||||
|     private _elements = new Map<string, UIEventSource<any>>(); |     private _elements = new Map<string, UIEventSource<any>>(); | ||||||
|  |     public ContainingFeatures = new Map<string, any>(); | ||||||
| 
 | 
 | ||||||
|     constructor() { |     constructor() { | ||||||
| 
 | 
 | ||||||
|  | @ -24,11 +25,16 @@ export class ElementStorage { | ||||||
|     addOrGetElement(feature: any): UIEventSource<any> { |     addOrGetElement(feature: any): UIEventSource<any> { | ||||||
|         const elementId = feature.properties.id; |         const elementId = feature.properties.id; | ||||||
|         const newProperties = feature.properties; |         const newProperties = feature.properties; | ||||||
| 
 |          | ||||||
|         const es = this.addOrGetById(elementId, newProperties) |         const es = this.addOrGetById(elementId, newProperties) | ||||||
| 
 | 
 | ||||||
|         // At last, we overwrite the tag of the new feature to use the tags in the already existing event source
 |         // At last, we overwrite the tag of the new feature to use the tags in the already existing event source
 | ||||||
|         feature.properties = es.data |         feature.properties = es.data | ||||||
|  |          | ||||||
|  |         if(!this.ContainingFeatures.has(elementId)){ | ||||||
|  |             this.ContainingFeatures.set(elementId, feature); | ||||||
|  |         } | ||||||
|  |          | ||||||
|         return es; |         return es; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,6 +2,8 @@ import {GeoOperations} from "./GeoOperations"; | ||||||
| import {UIElement} from "../UI/UIElement"; | import {UIElement} from "../UI/UIElement"; | ||||||
| import Combine from "../UI/Base/Combine"; | import Combine from "../UI/Base/Combine"; | ||||||
| import {Relation} from "./Osm/ExtractRelations"; | import {Relation} from "./Osm/ExtractRelations"; | ||||||
|  | import State from "../State"; | ||||||
|  | import {Utils} from "../Utils"; | ||||||
| 
 | 
 | ||||||
| export class ExtraFunction { | export class ExtraFunction { | ||||||
| 
 | 
 | ||||||
|  | @ -59,17 +61,25 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
|     ) |     ) | ||||||
|     private static readonly DistanceToFunc = new ExtraFunction( |     private static readonly DistanceToFunc = new ExtraFunction( | ||||||
|         "distanceTo", |         "distanceTo", | ||||||
|         "Calculates the distance between the feature and a specified point", |         "Calculates the distance between the feature and a specified point in kilometer. The input should either be a pair of coordinates, a geojson feature or the ID of an object", | ||||||
|         ["longitude", "latitude"], |         ["longitude", "latitude"], | ||||||
|         (featuresPerLayer, feature) => { |         (featuresPerLayer, feature) => { | ||||||
|             return (arg0, lat) => { |             return (arg0, lat) => { | ||||||
|                 if (typeof arg0 === "number") { |                 if (typeof arg0 === "number") { | ||||||
|                     // Feature._lon and ._lat is conveniently place by one of the other metatags
 |                     // Feature._lon and ._lat is conveniently place by one of the other metatags
 | ||||||
|                     return GeoOperations.distanceBetween([arg0, lat], [feature._lon, feature._lat]); |                     return GeoOperations.distanceBetween([arg0, lat], [feature._lon, feature._lat]); | ||||||
|                 } else { |  | ||||||
|                     // arg0 is probably a feature
 |  | ||||||
|                     return GeoOperations.distanceBetween(GeoOperations.centerpointCoordinates(arg0), [feature._lon, feature._lat]) |  | ||||||
|                 } |                 } | ||||||
|  |                 if (typeof arg0 === "string") { | ||||||
|  |                     // This is an identifier
 | ||||||
|  |                     const feature = State.state.allElements.ContainingFeatures.get(arg0); | ||||||
|  |                     if(feature === undefined){ | ||||||
|  |                         return undefined; | ||||||
|  |                     } | ||||||
|  |                     arg0 = feature; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // arg0 is probably a feature
 | ||||||
|  |                 return GeoOperations.distanceBetween(GeoOperations.centerpointCoordinates(arg0), [feature._lon, feature._lat]) | ||||||
| 
 | 
 | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -82,8 +92,21 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
|         (params, feature) => { |         (params, feature) => { | ||||||
|             return (features) => { |             return (features) => { | ||||||
|                 if (typeof features === "string") { |                 if (typeof features === "string") { | ||||||
|  |                     const name = features | ||||||
|                     features = params.featuresPerLayer.get(features) |                     features = params.featuresPerLayer.get(features) | ||||||
|  |                     if (features === undefined) { | ||||||
|  |                         var keys = Utils.NoNull(Array.from(params.featuresPerLayer.keys())); | ||||||
|  |                         if (keys.length > 0) { | ||||||
|  |                             throw `No features defined for ${name}. Defined layers are ${keys.join(", ")}`; | ||||||
|  |                         } else { | ||||||
|  |                             // This is the first pass over an external dataset
 | ||||||
|  |                             // Other data probably still has to load!
 | ||||||
|  |                             return undefined; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|  | 
 | ||||||
|                 let closestFeature = undefined; |                 let closestFeature = undefined; | ||||||
|                 let closestDistance = undefined; |                 let closestDistance = undefined; | ||||||
|                 for (const otherFeature of features) { |                 for (const otherFeature of features) { | ||||||
|  | @ -120,7 +143,7 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
|         "For example: <code>_part_of_walking_routes=feat.memberships().map(r => r.relation.tags.name).join(';')</code>", |         "For example: <code>_part_of_walking_routes=feat.memberships().map(r => r.relation.tags.name).join(';')</code>", | ||||||
|         [], |         [], | ||||||
|         (params, _) => { |         (params, _) => { | ||||||
|             return () =>   params.relations ?? []; |             return () => params.relations ?? []; | ||||||
|         } |         } | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|  | @ -128,9 +151,9 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
|     private readonly _name: string; |     private readonly _name: string; | ||||||
|     private readonly _args: string[]; |     private readonly _args: string[]; | ||||||
|     private readonly _doc: string; |     private readonly _doc: string; | ||||||
|     private readonly _f: (params: {featuresPerLayer: Map<string, any[]>, relations: {role: string, relation: Relation}[]}, feat: any) => any; |     private readonly _f: (params: { featuresPerLayer: Map<string, any[]>, relations: { role: string, relation: Relation }[] }, feat: any) => any; | ||||||
| 
 | 
 | ||||||
|     constructor(name: string, doc: string, args: string[], f: ((params: {featuresPerLayer: Map<string, any[]>, relations: {role: string, relation: Relation}[]}, feat: any) => any)) { |     constructor(name: string, doc: string, args: string[], f: ((params: { featuresPerLayer: Map<string, any[]>, relations: { role: string, relation: Relation }[] }, feat: any) => any)) { | ||||||
|         this._name = name; |         this._name = name; | ||||||
|         this._doc = doc; |         this._doc = doc; | ||||||
|         this._args = args; |         this._args = args; | ||||||
|  | @ -138,7 +161,7 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static FullPatchFeature(featuresPerLayer: Map<string, any[]>,relations: {role: string, relation: Relation}[], feature) { |     public static FullPatchFeature(featuresPerLayer: Map<string, any[]>, relations: { role: string, relation: Relation }[], feature) { | ||||||
|         for (const func of ExtraFunction.allFuncs) { |         for (const func of ExtraFunction.allFuncs) { | ||||||
|             func.PatchFeature(featuresPerLayer, relations, feature); |             func.PatchFeature(featuresPerLayer, relations, feature); | ||||||
|         } |         } | ||||||
|  | @ -166,8 +189,8 @@ Some advanced functions are available on <b>feat</b> as well: | ||||||
|         ]); |         ]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public PatchFeature(featuresPerLayer: Map<string, any[]>, relations: {role: string, relation: Relation}[], feature: any) { |     public PatchFeature(featuresPerLayer: Map<string, any[]>, relations: { role: string, relation: Relation }[], feature: any) { | ||||||
|       | 
 | ||||||
|         feature[this._name] = this._f({featuresPerLayer: featuresPerLayer, relations: relations}, feature); |         feature[this._name] = this._f({featuresPerLayer: featuresPerLayer, relations: relations}, feature); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								Logic/FeatureSource/DummyFeatureSource.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								Logic/FeatureSource/DummyFeatureSource.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,12 @@ | ||||||
|  | import FeatureSource from "./FeatureSource"; | ||||||
|  | import {UIEventSource} from "../UIEventSource"; | ||||||
|  | 
 | ||||||
|  | export default class DummyFeatureSource implements FeatureSource{ | ||||||
|  |   public readonly  features: UIEventSource<{ feature: any; freshness: Date }[]>; | ||||||
|  |   public readonly  name: string = "Dummy (static) feature source"; | ||||||
|  |      | ||||||
|  |   constructor(features: UIEventSource<{ feature: any; freshness: Date }[]>) { | ||||||
|  |       this.features = features; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | } | ||||||
|  | @ -35,7 +35,7 @@ export default class FeaturePipeline implements FeatureSource { | ||||||
|         const amendedOverpassSource = |         const amendedOverpassSource = | ||||||
|             new RememberingSource( |             new RememberingSource( | ||||||
|                 new LocalStorageSaver( |                 new LocalStorageSaver( | ||||||
|                     new MetaTaggingFeatureSource( |                     new MetaTaggingFeatureSource(this, | ||||||
|                         new FeatureDuplicatorPerLayer(flayers, |                         new FeatureDuplicatorPerLayer(flayers, | ||||||
|                             new RegisteringFeatureSource( |                             new RegisteringFeatureSource( | ||||||
|                                 updater) |                                 updater) | ||||||
|  | @ -43,18 +43,24 @@ export default class FeaturePipeline implements FeatureSource { | ||||||
| 
 | 
 | ||||||
|         const geojsonSources: FeatureSource [] = GeoJsonSource |         const geojsonSources: FeatureSource [] = GeoJsonSource | ||||||
|             .ConstructMultiSource(flayers.data, locationControl) |             .ConstructMultiSource(flayers.data, locationControl) | ||||||
|             .map(geojsonSource => new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource))); |             .map(geojsonSource => { | ||||||
|  |                 let source = new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, geojsonSource)); | ||||||
|  |                 if(!geojsonSource.isOsmCache){ | ||||||
|  |                     source = new MetaTaggingFeatureSource(this, source, updater.features); | ||||||
|  |                 } | ||||||
|  |                 return source | ||||||
|  |             }); | ||||||
| 
 | 
 | ||||||
|         const amendedLocalStorageSource = |         const amendedLocalStorageSource = | ||||||
|             new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout)) |             new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout)) | ||||||
|             )); |             )); | ||||||
| 
 | 
 | ||||||
|         newPoints = new MetaTaggingFeatureSource( |         newPoints = new MetaTaggingFeatureSource(this, | ||||||
|             new FeatureDuplicatorPerLayer(flayers, |             new FeatureDuplicatorPerLayer(flayers, | ||||||
|                 new RegisteringFeatureSource(newPoints))); |                 new RegisteringFeatureSource(newPoints))); | ||||||
| 
 | 
 | ||||||
|         const amendedOsmApiSource = new RememberingSource( |         const amendedOsmApiSource = new RememberingSource( | ||||||
|             new MetaTaggingFeatureSource( |             new MetaTaggingFeatureSource(this, | ||||||
|                 new FeatureDuplicatorPerLayer(flayers, |                 new FeatureDuplicatorPerLayer(flayers, | ||||||
| 
 | 
 | ||||||
|                     new RegisteringFeatureSource(fromOsmApi)))); |                     new RegisteringFeatureSource(fromOsmApi)))); | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ export default class GeoJsonSource implements FeatureSource { | ||||||
|     private onFail: ((errorMsg: any, url: string) => void) = undefined; |     private onFail: ((errorMsg: any, url: string) => void) = undefined; | ||||||
|     private readonly layerId: string; |     private readonly layerId: string; | ||||||
|     private readonly seenids: Set<string> = new Set<string>() |     private readonly seenids: Set<string> = new Set<string>() | ||||||
|  |     public readonly isOsmCache: boolean | ||||||
| 
 | 
 | ||||||
|     private constructor(locationControl: UIEventSource<Loc>, |     private constructor(locationControl: UIEventSource<Loc>, | ||||||
|                         flayer: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }, |                         flayer: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig }, | ||||||
|  | @ -27,6 +28,8 @@ export default class GeoJsonSource implements FeatureSource { | ||||||
|         let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id); |         let url = flayer.layerDef.source.geojsonSource.replace("{layer}", flayer.layerDef.id); | ||||||
|         this.name = "GeoJsonSource of " + url; |         this.name = "GeoJsonSource of " + url; | ||||||
|         const zoomLevel = flayer.layerDef.source.geojsonZoomLevel; |         const zoomLevel = flayer.layerDef.source.geojsonZoomLevel; | ||||||
|  |          | ||||||
|  |         this.isOsmCache = flayer.layerDef.source.isOsmCacheLayer; | ||||||
| 
 | 
 | ||||||
|         this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([]) |         this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([]) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -6,28 +6,38 @@ import MetaTagging from "../MetaTagging"; | ||||||
| import ExtractRelations from "../Osm/ExtractRelations"; | import ExtractRelations from "../Osm/ExtractRelations"; | ||||||
| 
 | 
 | ||||||
| export default class MetaTaggingFeatureSource implements FeatureSource { | export default class MetaTaggingFeatureSource implements FeatureSource { | ||||||
|     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{feature: any; freshness: Date}[]>(undefined); |     public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>(undefined); | ||||||
|      |  | ||||||
|     public readonly name; |  | ||||||
|      |  | ||||||
|     constructor(source: FeatureSource) { |  | ||||||
|         const self = this; |  | ||||||
|         this.name = "MetaTagging of "+source.name |  | ||||||
|         source.features.addCallbackAndRun((featuresFreshness: { feature: any, freshness: Date }[]) => { |  | ||||||
|                 if (featuresFreshness === undefined) { |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|                 featuresFreshness.forEach(featureFresh => { |  | ||||||
|                     const feature = featureFresh.feature; |  | ||||||
|                      |  | ||||||
|                     if (Hash.hash.data === feature.properties.id) { |  | ||||||
|                         State.state.selectedElement.setData(feature); |  | ||||||
|                     } |  | ||||||
|                 }) |  | ||||||
| 
 | 
 | ||||||
|                 MetaTagging.addMetatags(featuresFreshness, State.state.knownRelations.data, State.state.layoutToUse.data.layers); |     public readonly name; | ||||||
|                 self.features.setData(featuresFreshness); | 
 | ||||||
|         }); |     constructor(allFeaturesSource: FeatureSource, source: FeatureSource, updateTrigger?: UIEventSource<any>) { | ||||||
|  |         const self = this; | ||||||
|  |         this.name = "MetaTagging of " + source.name | ||||||
|  | 
 | ||||||
|  |         function update() { | ||||||
|  |             const featuresFreshness = source.features.data | ||||||
|  |             if (featuresFreshness === undefined) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             featuresFreshness.forEach(featureFresh => { | ||||||
|  |                 const feature = featureFresh.feature; | ||||||
|  | 
 | ||||||
|  |                 if (Hash.hash.data === feature.properties.id) { | ||||||
|  |                     State.state.selectedElement.setData(feature); | ||||||
|  |                 } | ||||||
|  |             }) | ||||||
|  | 
 | ||||||
|  |             MetaTagging.addMetatags(featuresFreshness, | ||||||
|  |                 allFeaturesSource, | ||||||
|  |                 State.state.knownRelations.data, State.state.layoutToUse.data.layers); | ||||||
|  |             self.features.setData(featuresFreshness); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         source.features.addCallbackAndRun(_ => update()); | ||||||
|  |         updateTrigger?.addCallback(_ => { | ||||||
|  |             console.debug("Updating because of external call") | ||||||
|  |             update(); | ||||||
|  |         }) | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
| } | } | ||||||
|  | @ -2,6 +2,7 @@ import LayerConfig from "../Customizations/JSON/LayerConfig"; | ||||||
| import SimpleMetaTagger from "./SimpleMetaTagger"; | import SimpleMetaTagger from "./SimpleMetaTagger"; | ||||||
| import {ExtraFunction} from "./ExtraFunction"; | import {ExtraFunction} from "./ExtraFunction"; | ||||||
| import {Relation} from "./Osm/ExtractRelations"; | import {Relation} from "./Osm/ExtractRelations"; | ||||||
|  | import FeatureSource from "./FeatureSource/FeatureSource"; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| interface Params { | interface Params { | ||||||
|  | @ -22,6 +23,7 @@ export default class MetaTagging { | ||||||
|      * The features are a list of geojson-features, with a "properties"-field and geometry |      * The features are a list of geojson-features, with a "properties"-field and geometry | ||||||
|      */ |      */ | ||||||
|     static addMetatags(features: { feature: any; freshness: Date }[], |     static addMetatags(features: { feature: any; freshness: Date }[], | ||||||
|  |                        allKnownFeatures: FeatureSource, | ||||||
|                        relations: Map<string, { role: string, relation: Relation }[]>, |                        relations: Map<string, { role: string, relation: Relation }[]>, | ||||||
|                        layers: LayerConfig[], |                        layers: LayerConfig[], | ||||||
|                        includeDates = true) { |                        includeDates = true) { | ||||||
|  | @ -55,7 +57,7 @@ export default class MetaTagging { | ||||||
|             featuresPerLayer.get(key).push(feature.feature) |             featuresPerLayer.get(key).push(feature.feature) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         for (const feature of features) { |         for (const feature of (allKnownFeatures.features?.data ?? features ?? [])) { | ||||||
|             // @ts-ignore
 |             // @ts-ignore
 | ||||||
|             const key = feature.feature._matching_layer_id; |             const key = feature.feature._matching_layer_id; | ||||||
|             const f = layerFuncs.get(key); |             const f = layerFuncs.get(key); | ||||||
|  |  | ||||||
|  | @ -2,7 +2,7 @@ import { Utils } from "../Utils"; | ||||||
| 
 | 
 | ||||||
| export default class Constants { | export default class Constants { | ||||||
|      |      | ||||||
|     public static vNumber = "0.7.2c"; |     public static vNumber = "0.7.2d"; | ||||||
| 
 | 
 | ||||||
|     // The user journey states thresholds when a new feature gets unlocked
 |     // The user journey states thresholds when a new feature gets unlocked
 | ||||||
|     public static userJourney = { |     public static userJourney = { | ||||||
|  |  | ||||||
							
								
								
									
										202
									
								
								assets/layers/defibrillator/defibrillator.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										202
									
								
								assets/layers/defibrillator/defibrillator.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,202 @@ | ||||||
|  | { | ||||||
|  |   "id": "defibrillator", | ||||||
|  |   "name": { | ||||||
|  |     "en": "Defibrillators", | ||||||
|  |     "ca": "Desfibril·ladors", | ||||||
|  |     "es": "Desfibriladores", | ||||||
|  |     "fr": "Défibrillateurs", | ||||||
|  |     "nl": "Defibrillatoren", | ||||||
|  |     "de": "Defibrillatoren" | ||||||
|  |   }, | ||||||
|  |   "source": { | ||||||
|  |     "osmTags": "emergency=defibrillator" | ||||||
|  |   }, | ||||||
|  |   "minzoom": 12, | ||||||
|  |   "title": { | ||||||
|  |     "render": { | ||||||
|  |       "en": "Defibrillator", | ||||||
|  |       "ca": "Desfibril·lador", | ||||||
|  |       "es": "Desfibrilador", | ||||||
|  |       "fr": "Défibrillateur", | ||||||
|  |       "nl": "Defibrillator", | ||||||
|  |       "de": "Defibrillator" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "icon": "./assets/themes/aed/aed.svg", | ||||||
|  |   "color": "#0000ff", | ||||||
|  |   "presets": [ | ||||||
|  |     { | ||||||
|  |       "title": { | ||||||
|  |         "en": "Defibrillator", | ||||||
|  |         "ca": "Desfibril·lador", | ||||||
|  |         "es": "Desfibrilador", | ||||||
|  |         "fr": "Défibrillateur", | ||||||
|  |         "nl": "Defibrillator", | ||||||
|  |         "de": "Defibrillator" | ||||||
|  |       }, | ||||||
|  |       "tags": [ | ||||||
|  |         "emergency=defibrillator" | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "tagRenderings": [ | ||||||
|  |     "images", | ||||||
|  |     { | ||||||
|  |       "question": { | ||||||
|  |         "en": "Is this defibrillator located indoors?", | ||||||
|  |         "ca": "Està el desfibril·lador a l'interior?", | ||||||
|  |         "es": "¿Esté el desfibrilador en interior?", | ||||||
|  |         "fr": "Ce défibrillateur est-il disposé en intérieur ?", | ||||||
|  |         "nl": "Hangt deze defibrillator binnen of buiten?", | ||||||
|  |         "de": "Befindet sich dieser Defibrillator im Gebäude?" | ||||||
|  |       }, | ||||||
|  |       "mappings": [ | ||||||
|  |         { | ||||||
|  |           "if": "indoor=yes", | ||||||
|  |           "then": { | ||||||
|  |             "en": "This defibrillator is located indoors", | ||||||
|  |             "ca": "Aquest desfibril·lador està a l'interior", | ||||||
|  |             "es": "Este desfibrilador está en interior", | ||||||
|  |             "fr": "Ce défibrillateur est en intérieur (dans un batiment)", | ||||||
|  |             "nl": "Deze defibrillator bevindt zich in een gebouw", | ||||||
|  |             "de": "Dieser Defibrillator befindet sich im Gebäude" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "if": "indoor=no", | ||||||
|  |           "then": { | ||||||
|  |             "en": "This defibrillator is located outdoors", | ||||||
|  |             "ca": "Aquest desfibril·lador està a l'exterior", | ||||||
|  |             "es": "Este desfibrilador está en exterior", | ||||||
|  |             "fr": "Ce défibrillateur est situé en extérieur", | ||||||
|  |             "nl": "Deze defibrillator hangt buiten", | ||||||
|  |             "de": "Dieser Defibrillator befindet sich im Freien" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "question": { | ||||||
|  |         "en": "Is this defibrillator freely accessible?", | ||||||
|  |         "ca": "Està el desfibril·lador accessible lliurement?", | ||||||
|  |         "es": "¿Está el desfibrilador accesible libremente?", | ||||||
|  |         "fr": "Ce défibrillateur est-il librement accessible ?", | ||||||
|  |         "nl": "Is deze defibrillator vrij toegankelijk?", | ||||||
|  |         "de": "Ist dieser Defibrillator frei zugänglich?" | ||||||
|  |       }, | ||||||
|  |       "render": { | ||||||
|  |         "en": "Access is {access}", | ||||||
|  |         "ca": "L'accés és {access}", | ||||||
|  |         "es": "El acceso es {access}", | ||||||
|  |         "fr": "{access} accessible", | ||||||
|  |         "nl": "Toegankelijkheid is {access}", | ||||||
|  |         "de": "Zugang ist {access}" | ||||||
|  |       }, | ||||||
|  |       "condition": { | ||||||
|  |         "or": [ | ||||||
|  |           "indoor=yes", | ||||||
|  |           "access~*" | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       "freeform": { | ||||||
|  |         "key": "access", | ||||||
|  |         "addExtraTags": [ | ||||||
|  |           "fixme=Freeform field used for access - doublecheck the value" | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       "mappings": [ | ||||||
|  |         { | ||||||
|  |           "if": "access=yes", | ||||||
|  |           "then": { | ||||||
|  |             "en": "Publicly accessible", | ||||||
|  |             "ca": "Accés lliure", | ||||||
|  |             "es": "Acceso libre", | ||||||
|  |             "fr": "Librement accessible", | ||||||
|  |             "nl": "Publiek toegankelijk", | ||||||
|  |             "de": "Öffentlich zugänglich" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "if": "access=public", | ||||||
|  |           "then": { | ||||||
|  |             "en": "Publicly accessible", | ||||||
|  |             "ca": "Publicament accessible", | ||||||
|  |             "es": "Publicament accesible", | ||||||
|  |             "fr": "Librement accessible", | ||||||
|  |             "nl": "Publiek toegankelijk", | ||||||
|  |             "de": "Öffentlich zugänglich" | ||||||
|  |           }, | ||||||
|  |           "hideInAnswer": true | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "if": "access=customers", | ||||||
|  |           "then": { | ||||||
|  |             "en": "Only accessible to customers", | ||||||
|  |             "ca": "Només accessible a clients", | ||||||
|  |             "es": "Sólo accesible a clientes", | ||||||
|  |             "fr": "Réservé aux clients du lieu", | ||||||
|  |             "nl": "Enkel toegankelijk voor klanten", | ||||||
|  |             "de": "Nur für Kunden zugänglich" | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "if": "access=private", | ||||||
|  |           "then": { | ||||||
|  |             "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", | ||||||
|  |             "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", | ||||||
|  |             "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", | ||||||
|  |             "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", | ||||||
|  |             "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personneel, de eigenaar, ...)", | ||||||
|  |             "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)" | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "question": { | ||||||
|  |         "en": "On which floor is this defibrillator located?", | ||||||
|  |         "ca": "A quina planta està el desfibril·lador localitzat?", | ||||||
|  |         "es": "¿En qué planta se encuentra el defibrilador localizado?", | ||||||
|  |         "fr": "À quel étage est situé ce défibrillateur ?", | ||||||
|  |         "nl": "Op welke verdieping bevindt deze defibrillator zich?", | ||||||
|  |         "de": "In welchem Stockwerk befindet sich dieser Defibrillator?" | ||||||
|  |       }, | ||||||
|  |       "condition": { | ||||||
|  |         "and": [ | ||||||
|  |           "indoor=yes", | ||||||
|  |           "access!~private" | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       "freeform": { | ||||||
|  |         "key": "level", | ||||||
|  |         "type": "int" | ||||||
|  |       }, | ||||||
|  |       "render": { | ||||||
|  |         "en": "This defibrallator is on floor {level}", | ||||||
|  |         "ca": "Aquest desfibril·lador és a la planta {level}", | ||||||
|  |         "es": "El desfibrilador se encuentra en la planta {level}", | ||||||
|  |         "fr": "Ce défibrillateur est à l'étage {level}", | ||||||
|  |         "nl": "De defibrillator bevindt zicht op verdieping {level}", | ||||||
|  |         "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "render": { | ||||||
|  |         "nl": "<i>Meer informatie over de locatie:</i><br/>{defibrillator:location}", | ||||||
|  |         "en": "<i>Extra information about the location:</i><br/>{defibrillator:location}" | ||||||
|  |       }, | ||||||
|  |       "question": { | ||||||
|  |         "en": "Please give some explanation on where the defibrillator can be found", | ||||||
|  |         "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", | ||||||
|  |         "es": "Da detalles de dónde se puede encontrar el desfibrilador", | ||||||
|  |         "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur", | ||||||
|  |         "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator", | ||||||
|  |         "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist" | ||||||
|  |       }, | ||||||
|  |       "freeform": { | ||||||
|  |         "type": "text", | ||||||
|  |         "key": "defibrillator:location" | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | @ -82,5 +82,9 @@ | ||||||
|     "#": "Gives some metainfo about the last edit and who did edit it - rendering only", |     "#": "Gives some metainfo about the last edit and who did edit it - rendering only", | ||||||
|     "condition": "_last_edit:contributor~*", |     "condition": "_last_edit:contributor~*", | ||||||
|     "render": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>" |     "render": "<div class='subtle' style='font-size: small; margin-top: 2em; margin-bottom: 0.5em;'><a href='https://www.openStreetMap.org/changeset/{_last_edit:changeset}' target='_blank'>Last edited on {_last_edit:timestamp}</a> by <a href='https://www.openStreetMap.org/user/{_last_edit:contributor}' target='_blank'>{_last_edit:contributor}</a></div>" | ||||||
|  |   }, | ||||||
|  |   "all_tags": { | ||||||
|  |     "#": "Prints all the tags", | ||||||
|  |     "render": "{all_tags()}" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -31,207 +31,6 @@ | ||||||
|   "startLon": 0, |   "startLon": 0, | ||||||
|   "startZoom": 12, |   "startZoom": 12, | ||||||
|   "layers": [ |   "layers": [ | ||||||
|     { |     "defibrillator" | ||||||
|       "id": "Defibrillator", |  | ||||||
|       "name": { |  | ||||||
|         "en": "Defibrillators", |  | ||||||
|         "ca": "Desfibril·ladors", |  | ||||||
|         "es": "Desfibriladores", |  | ||||||
|         "fr": "Défibrillateurs", |  | ||||||
|         "nl": "Defibrillatoren", |  | ||||||
|         "de": "Defibrillatoren" |  | ||||||
|       }, |  | ||||||
|       "source": { |  | ||||||
|         "osmTags": "emergency=defibrillator" |  | ||||||
|       }, |  | ||||||
|       "minzoom": 12, |  | ||||||
|       "title": { |  | ||||||
|         "render": { |  | ||||||
|           "en": "Defibrillator", |  | ||||||
|           "ca": "Desfibril·lador", |  | ||||||
|           "es": "Desfibrilador", |  | ||||||
|           "fr": "Défibrillateur", |  | ||||||
|           "nl": "Defibrillator", |  | ||||||
|           "de": "Defibrillator" |  | ||||||
|         } |  | ||||||
|       }, |  | ||||||
|       "icon": "./assets/themes/aed/aed.svg", |  | ||||||
|       "color": "#0000ff", |  | ||||||
|       "presets": [ |  | ||||||
|         { |  | ||||||
|           "title": { |  | ||||||
|             "en": "Defibrillator", |  | ||||||
|             "ca": "Desfibril·lador", |  | ||||||
|             "es": "Desfibrilador", |  | ||||||
|             "fr": "Défibrillateur", |  | ||||||
|             "nl": "Defibrillator", |  | ||||||
|             "de": "Defibrillator" |  | ||||||
|           }, |  | ||||||
|           "tags": [ |  | ||||||
|             "emergency=defibrillator" |  | ||||||
|           ] |  | ||||||
|         } |  | ||||||
|       ], |  | ||||||
|       "tagRenderings": [ |  | ||||||
|         "images", |  | ||||||
|         { |  | ||||||
|           "question": { |  | ||||||
|             "en": "Is this defibrillator located indoors?", |  | ||||||
|             "ca": "Està el desfibril·lador a l'interior?", |  | ||||||
|             "es": "¿Esté el desfibrilador en interior?", |  | ||||||
|             "fr": "Ce défibrillateur est-il disposé en intérieur ?", |  | ||||||
|             "nl": "Hangt deze defibrillator binnen of buiten?", |  | ||||||
|             "de": "Befindet sich dieser Defibrillator im Gebäude?" |  | ||||||
|           }, |  | ||||||
|           "mappings": [ |  | ||||||
|             { |  | ||||||
|               "if": "indoor=yes", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "This defibrillator is located indoors", |  | ||||||
|                 "ca": "Aquest desfibril·lador està a l'interior", |  | ||||||
|                 "es": "Este desfibrilador está en interior", |  | ||||||
|                 "fr": "Ce défibrillateur est en intérieur (dans un batiment)", |  | ||||||
|                 "nl": "Deze defibrillator bevindt zich in een gebouw", |  | ||||||
|                 "de": "Dieser Defibrillator befindet sich im Gebäude" |  | ||||||
|               } |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "indoor=no", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "This defibrillator is located outdoors", |  | ||||||
|                 "ca": "Aquest desfibril·lador està a l'exterior", |  | ||||||
|                 "es": "Este desfibrilador está en exterior", |  | ||||||
|                 "fr": "Ce défibrillateur est situé en extérieur", |  | ||||||
|                 "nl": "Deze defibrillator hangt buiten", |  | ||||||
|                 "de": "Dieser Defibrillator befindet sich im Freien" |  | ||||||
|               } |  | ||||||
|             } |  | ||||||
|           ] |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "question": { |  | ||||||
|             "en": "Is this defibrillator freely accessible?", |  | ||||||
|             "ca": "Està el desfibril·lador accessible lliurement?", |  | ||||||
|             "es": "¿Está el desfibrilador accesible libremente?", |  | ||||||
|             "fr": "Ce défibrillateur est-il librement accessible ?", |  | ||||||
|             "nl": "Is deze defibrillator vrij toegankelijk?", |  | ||||||
|             "de": "Ist dieser Defibrillator frei zugänglich?" |  | ||||||
|           }, |  | ||||||
|           "render": { |  | ||||||
|             "en": "Access is {access}", |  | ||||||
|             "ca": "L'accés és {access}", |  | ||||||
|             "es": "El acceso es {access}", |  | ||||||
|             "fr": "{access} accessible", |  | ||||||
|             "nl": "Toegankelijkheid is {access}", |  | ||||||
|             "de": "Zugang ist {access}" |  | ||||||
|           }, |  | ||||||
|           "condition": { |  | ||||||
|             "or": [ |  | ||||||
|               "indoor=yes", |  | ||||||
|               "access~*" |  | ||||||
|             ] |  | ||||||
|           }, |  | ||||||
|           "freeform": { |  | ||||||
|             "key": "access", |  | ||||||
|             "addExtraTags": [ |  | ||||||
|               "fixme=Freeform field used for access - doublecheck the value" |  | ||||||
|             ] |  | ||||||
|           }, |  | ||||||
|           "mappings": [ |  | ||||||
|             { |  | ||||||
|               "if": "access=yes", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "Publicly accessible", |  | ||||||
|                 "ca": "Accés lliure", |  | ||||||
|                 "es": "Acceso libre", |  | ||||||
|                 "fr": "Librement accessible", |  | ||||||
|                 "nl": "Publiek toegankelijk", |  | ||||||
|                 "de": "Öffentlich zugänglich" |  | ||||||
|               } |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "access=public", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "Publicly accessible", |  | ||||||
|                 "ca": "Publicament accessible", |  | ||||||
|                 "es": "Publicament accesible", |  | ||||||
|                 "fr": "Librement accessible", |  | ||||||
|                 "nl": "Publiek toegankelijk", |  | ||||||
|                 "de": "Öffentlich zugänglich" |  | ||||||
|               }, |  | ||||||
|               "hideInAnswer": true |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "access=customers", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "Only accessible to customers", |  | ||||||
|                 "ca": "Només accessible a clients", |  | ||||||
|                 "es": "Sólo accesible a clientes", |  | ||||||
|                 "fr": "Réservé aux clients du lieu", |  | ||||||
|                 "nl": "Enkel toegankelijk voor klanten", |  | ||||||
|                 "de": "Nur für Kunden zugänglich" |  | ||||||
|               } |  | ||||||
|             }, |  | ||||||
|             { |  | ||||||
|               "if": "access=private", |  | ||||||
|               "then": { |  | ||||||
|                 "en": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)", |  | ||||||
|                 "ca": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)", |  | ||||||
|                 "es": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)", |  | ||||||
|                 "fr": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)", |  | ||||||
|                 "nl": "Niet toegankelijk voor het publiek (bv. enkel voor personneel, de eigenaar, ...)", |  | ||||||
|                 "de": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)" |  | ||||||
|               } |  | ||||||
|             } |  | ||||||
|           ] |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "question": { |  | ||||||
|             "en": "On which floor is this defibrillator located?", |  | ||||||
|             "ca": "A quina planta està el desfibril·lador localitzat?", |  | ||||||
|             "es": "¿En qué planta se encuentra el defibrilador localizado?", |  | ||||||
|             "fr": "À quel étage est situé ce défibrillateur ?", |  | ||||||
|             "nl": "Op welke verdieping bevindt deze defibrillator zich?", |  | ||||||
|             "de": "In welchem Stockwerk befindet sich dieser Defibrillator?" |  | ||||||
|           }, |  | ||||||
|           "condition": { |  | ||||||
|             "and": [ |  | ||||||
|               "indoor=yes", |  | ||||||
|               "access!~private" |  | ||||||
|             ] |  | ||||||
|           }, |  | ||||||
|           "freeform": { |  | ||||||
|             "key": "level", |  | ||||||
|             "type": "int" |  | ||||||
|           }, |  | ||||||
|           "render": { |  | ||||||
|             "en": "This defibrallator is on floor {level}", |  | ||||||
|             "ca": "Aquest desfibril·lador és a la planta {level}", |  | ||||||
|             "es": "El desfibrilador se encuentra en la planta {level}", |  | ||||||
|             "fr": "Ce défibrillateur est à l'étage {level}", |  | ||||||
|             "nl": "De defibrillator bevindt zicht op verdieping {level}", |  | ||||||
|             "de": "Dieser Defibrallator befindet sich im {level}. Stockwerk" |  | ||||||
|           } |  | ||||||
|         }, |  | ||||||
|         { |  | ||||||
|           "render": { |  | ||||||
|             "nl": "<i>Meer informatie over de locatie:</i><br/>{defibrillator:location}", |  | ||||||
|             "en": "<i>Extra information about the location:</i><br/>{defibrillator:location}" |  | ||||||
|           }, |  | ||||||
|           "question": { |  | ||||||
|             "en": "Please give some explanation on where the defibrillator can be found", |  | ||||||
|             "ca": "Dóna detalls d'on es pot trobar el desfibril·lador", |  | ||||||
|             "es": "Da detalles de dónde se puede encontrar el desfibrilador", |  | ||||||
|             "fr": "Veuillez indiquez plus précisément où se situe le défibrillateur", |  | ||||||
|             "nl": "Gelieve meer informatie te geven over de exacte locatie van de defibrillator", |  | ||||||
|             "de": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist" |  | ||||||
|           }, |  | ||||||
|           "freeform": { |  | ||||||
|             "type": "text", |  | ||||||
|             "key": "defibrillator:location" |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       ] |  | ||||||
|     } |  | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										53
									
								
								assets/themes/aed/aed_brugge.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								assets/themes/aed/aed_brugge.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | ||||||
|  | { | ||||||
|  |   "id": "aed_brugge", | ||||||
|  |   "title": { | ||||||
|  |     "nl": "Open AED-kaart - Brugge edition" | ||||||
|  |   }, | ||||||
|  |   "maintainer": "MapComplete", | ||||||
|  |   "icon": "./assets/themes/aed/logo.svg", | ||||||
|  |   "description": { | ||||||
|  |     "nl": "Op deze kaart kan je informatie over AEDs vinden en verbeteren + een export van de brugse defibrillatoren" | ||||||
|  |   }, | ||||||
|  |   "language": [ | ||||||
|  |     "nl" | ||||||
|  |   ], | ||||||
|  |   "version": "2021-05-16", | ||||||
|  |   "startLat": 51.25634, | ||||||
|  |   "startLon": 3.195682, | ||||||
|  |   "startZoom": 12, | ||||||
|  |   "layers": [ | ||||||
|  |     "defibrillator", | ||||||
|  |     { | ||||||
|  |       "id": "Brugge", | ||||||
|  |       "name": "Brugse dataset", | ||||||
|  |       "source": { | ||||||
|  |         "osmTags": "Brugs volgnummer~*", | ||||||
|  |         "geoJson": "https://raw.githubusercontent.com/pietervdvn/pietervdvn.github.io/master/aeds_brugge.json" | ||||||
|  |       }, | ||||||
|  |       "calculatedTags": [ | ||||||
|  |         "_closest_osm_aed=feat.closest('defibrillator')?.properties?.id", | ||||||
|  |         "_closest_osm_aed_distance=feat.distanceTo(feat.properties._closest_osm_aed) * 1000", | ||||||
|  |         "_has_closeby_feature=Number(feat.properties._closest_osm_aed_distance) < 25 ? 'yes' : 'no'" | ||||||
|  |       ], | ||||||
|  |       "title": "AED in Brugse dataset", | ||||||
|  |       "icon": { | ||||||
|  |         "render": "circle:green", | ||||||
|  |         "mappings": [ | ||||||
|  |           { | ||||||
|  |             "if": "_has_closeby_feature=yes", | ||||||
|  |             "then": "circle:#ffff00aa" | ||||||
|  |           }, | ||||||
|  |           { | ||||||
|  |             "if": "Status=oud", | ||||||
|  |             "then": "circle:red" | ||||||
|  |           } | ||||||
|  |         ] | ||||||
|  |       }, | ||||||
|  |       "iconSize": "20,20,center", | ||||||
|  |       "tagRenderings": [ | ||||||
|  |         "all_tags" | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "hideFromOverview": true | ||||||
|  | } | ||||||
|  | @ -17,6 +17,8 @@ import MetaTagging from "../Logic/MetaTagging"; | ||||||
| import LayerConfig from "../Customizations/JSON/LayerConfig"; | import LayerConfig from "../Customizations/JSON/LayerConfig"; | ||||||
| import {GeoOperations} from "../Logic/GeoOperations"; | import {GeoOperations} from "../Logic/GeoOperations"; | ||||||
| import {fail} from "assert"; | import {fail} from "assert"; | ||||||
|  | import {UIEventSource} from "../Logic/UIEventSource"; | ||||||
|  | import DummyFeatureSource from "../Logic/FeatureSource/DummyFeatureSource"; | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| function createOverpassObject(theme: LayoutConfig) { | function createOverpassObject(theme: LayoutConfig) { | ||||||
|  | @ -142,7 +144,7 @@ async function postProcess(targetdir: string, r: TileRange, theme: LayoutConfig, | ||||||
| 
 | 
 | ||||||
|             // We read the raw OSM-file and convert it to a geojson
 |             // We read the raw OSM-file and convert it to a geojson
 | ||||||
|             const rawOsm = JSON.parse(readFileSync(filename, "UTF8")) |             const rawOsm = JSON.parse(readFileSync(filename, "UTF8")) | ||||||
| 
 |   | ||||||
|             // Create and save the geojson file - which is the main chunk of the data
 |             // Create and save the geojson file - which is the main chunk of the data
 | ||||||
|             const geojson = OsmToGeoJson.default(rawOsm); |             const geojson = OsmToGeoJson.default(rawOsm); | ||||||
|             const osmTime = new Date(rawOsm.osm3s.timestamp_osm_base); |             const osmTime = new Date(rawOsm.osm3s.timestamp_osm_base); | ||||||
|  | @ -167,7 +169,7 @@ async function postProcess(targetdir: string, r: TileRange, theme: LayoutConfig, | ||||||
|             // Extract the relationship information
 |             // Extract the relationship information
 | ||||||
|             const relations = ExtractRelations.BuildMembershipTable(ExtractRelations.GetRelationElements(rawOsm)) |             const relations = ExtractRelations.BuildMembershipTable(ExtractRelations.GetRelationElements(rawOsm)) | ||||||
| 
 | 
 | ||||||
|             MetaTagging.addMetatags(featuresFreshness, relations, theme.layers, false); |             MetaTagging.addMetatags(featuresFreshness, new DummyFeatureSource(new UIEventSource<{feature: any; freshness: Date}[]>(featuresFreshness)) , relations, theme.layers, false); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|             for (const feature of geojson.features) { |             for (const feature of geojson.features) { | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue