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,6 +81,9 @@ export default class LayerConfig {
|
|||
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({
|
||||
osmTags: osmTags,
|
||||
|
@ -172,7 +175,10 @@ export default class LayerConfig {
|
|||
if (shared !== undefined) {
|
||||
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}]`);
|
||||
});
|
||||
|
|
|
@ -6,6 +6,7 @@ import {UIEventSource} from "./UIEventSource";
|
|||
export class ElementStorage {
|
||||
|
||||
private _elements = new Map<string, UIEventSource<any>>();
|
||||
public ContainingFeatures = new Map<string, any>();
|
||||
|
||||
constructor() {
|
||||
|
||||
|
@ -29,6 +30,11 @@ export class ElementStorage {
|
|||
|
||||
// At last, we overwrite the tag of the new feature to use the tags in the already existing event source
|
||||
feature.properties = es.data
|
||||
|
||||
if(!this.ContainingFeatures.has(elementId)){
|
||||
this.ContainingFeatures.set(elementId, feature);
|
||||
}
|
||||
|
||||
return es;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@ import {GeoOperations} from "./GeoOperations";
|
|||
import {UIElement} from "../UI/UIElement";
|
||||
import Combine from "../UI/Base/Combine";
|
||||
import {Relation} from "./Osm/ExtractRelations";
|
||||
import State from "../State";
|
||||
import {Utils} from "../Utils";
|
||||
|
||||
export class ExtraFunction {
|
||||
|
||||
|
@ -59,17 +61,25 @@ Some advanced functions are available on <b>feat</b> as well:
|
|||
)
|
||||
private static readonly DistanceToFunc = new ExtraFunction(
|
||||
"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"],
|
||||
(featuresPerLayer, feature) => {
|
||||
return (arg0, lat) => {
|
||||
if (typeof arg0 === "number") {
|
||||
// Feature._lon and ._lat is conveniently place by one of the other metatags
|
||||
return GeoOperations.distanceBetween([arg0, lat], [feature._lon, feature._lat]);
|
||||
} else {
|
||||
}
|
||||
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) => {
|
||||
return (features) => {
|
||||
if (typeof features === "string") {
|
||||
const name = 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 closestDistance = undefined;
|
||||
for (const otherFeature of features) {
|
||||
|
|
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 =
|
||||
new RememberingSource(
|
||||
new LocalStorageSaver(
|
||||
new MetaTaggingFeatureSource(
|
||||
new MetaTaggingFeatureSource(this,
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
new RegisteringFeatureSource(
|
||||
updater)
|
||||
|
@ -43,18 +43,24 @@ export default class FeaturePipeline implements FeatureSource {
|
|||
|
||||
const geojsonSources: FeatureSource [] = GeoJsonSource
|
||||
.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 =
|
||||
new RememberingSource(new RegisteringFeatureSource(new FeatureDuplicatorPerLayer(flayers, new LocalStorageSource(layout))
|
||||
));
|
||||
|
||||
newPoints = new MetaTaggingFeatureSource(
|
||||
newPoints = new MetaTaggingFeatureSource(this,
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
new RegisteringFeatureSource(newPoints)));
|
||||
|
||||
const amendedOsmApiSource = new RememberingSource(
|
||||
new MetaTaggingFeatureSource(
|
||||
new MetaTaggingFeatureSource(this,
|
||||
new FeatureDuplicatorPerLayer(flayers,
|
||||
|
||||
new RegisteringFeatureSource(fromOsmApi))));
|
||||
|
|
|
@ -19,6 +19,7 @@ export default class GeoJsonSource implements FeatureSource {
|
|||
private onFail: ((errorMsg: any, url: string) => void) = undefined;
|
||||
private readonly layerId: string;
|
||||
private readonly seenids: Set<string> = new Set<string>()
|
||||
public readonly isOsmCache: boolean
|
||||
|
||||
private constructor(locationControl: UIEventSource<Loc>,
|
||||
flayer: { isDisplayed: UIEventSource<boolean>, layerDef: LayerConfig },
|
||||
|
@ -28,6 +29,8 @@ export default class GeoJsonSource implements FeatureSource {
|
|||
this.name = "GeoJsonSource of " + url;
|
||||
const zoomLevel = flayer.layerDef.source.geojsonZoomLevel;
|
||||
|
||||
this.isOsmCache = flayer.layerDef.source.isOsmCacheLayer;
|
||||
|
||||
this.features = new UIEventSource<{ feature: any; freshness: Date }[]>([])
|
||||
|
||||
if (zoomLevel === undefined) {
|
||||
|
|
|
@ -10,10 +10,12 @@ export default class MetaTaggingFeatureSource implements FeatureSource {
|
|||
|
||||
public readonly name;
|
||||
|
||||
constructor(source: FeatureSource) {
|
||||
constructor(allFeaturesSource: FeatureSource, source: FeatureSource, updateTrigger?: UIEventSource<any>) {
|
||||
const self = this;
|
||||
this.name = "MetaTagging of " + source.name
|
||||
source.features.addCallbackAndRun((featuresFreshness: { feature: any, freshness: Date }[]) => {
|
||||
|
||||
function update() {
|
||||
const featuresFreshness = source.features.data
|
||||
if (featuresFreshness === undefined) {
|
||||
return;
|
||||
}
|
||||
|
@ -25,9 +27,17 @@ export default class MetaTaggingFeatureSource implements FeatureSource {
|
|||
}
|
||||
})
|
||||
|
||||
MetaTagging.addMetatags(featuresFreshness, State.state.knownRelations.data, State.state.layoutToUse.data.layers);
|
||||
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 {ExtraFunction} from "./ExtraFunction";
|
||||
import {Relation} from "./Osm/ExtractRelations";
|
||||
import FeatureSource from "./FeatureSource/FeatureSource";
|
||||
|
||||
|
||||
interface Params {
|
||||
|
@ -22,6 +23,7 @@ export default class MetaTagging {
|
|||
* The features are a list of geojson-features, with a "properties"-field and geometry
|
||||
*/
|
||||
static addMetatags(features: { feature: any; freshness: Date }[],
|
||||
allKnownFeatures: FeatureSource,
|
||||
relations: Map<string, { role: string, relation: Relation }[]>,
|
||||
layers: LayerConfig[],
|
||||
includeDates = true) {
|
||||
|
@ -55,7 +57,7 @@ export default class MetaTagging {
|
|||
featuresPerLayer.get(key).push(feature.feature)
|
||||
}
|
||||
|
||||
for (const feature of features) {
|
||||
for (const feature of (allKnownFeatures.features?.data ?? features ?? [])) {
|
||||
// @ts-ignore
|
||||
const key = feature.feature._matching_layer_id;
|
||||
const f = layerFuncs.get(key);
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Utils } from "../Utils";
|
|||
|
||||
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
|
||||
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",
|
||||
"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>"
|
||||
},
|
||||
"all_tags": {
|
||||
"#": "Prints all the tags",
|
||||
"render": "{all_tags()}"
|
||||
}
|
||||
}
|
|
@ -31,207 +31,6 @@
|
|||
"startLon": 0,
|
||||
"startZoom": 12,
|
||||
"layers": [
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
"defibrillator"
|
||||
]
|
||||
}
|
||||
|
|
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 {GeoOperations} from "../Logic/GeoOperations";
|
||||
import {fail} from "assert";
|
||||
import {UIEventSource} from "../Logic/UIEventSource";
|
||||
import DummyFeatureSource from "../Logic/FeatureSource/DummyFeatureSource";
|
||||
|
||||
|
||||
function createOverpassObject(theme: LayoutConfig) {
|
||||
|
@ -167,7 +169,7 @@ async function postProcess(targetdir: string, r: TileRange, theme: LayoutConfig,
|
|||
// Extract the relationship information
|
||||
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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue