diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index 1ef497c78..ba5795dfa 100644 --- a/Customizations/AllKnownLayers.ts +++ b/Customizations/AllKnownLayers.ts @@ -28,6 +28,8 @@ import * as sport_pitch from "../assets/layers/sport_pitch/sport_pitch.json" import * as slow_roads from "../assets/layers/slow_roads/slow_roads.json" import LayerConfig from "./JSON/LayerConfig"; import {LayerConfigJson} from "./JSON/LayerConfigJson"; +import * as grass_in_parks from "../assets/layers/village_green/grass_in_parks.json" +import * as village_green from "../assets/layers/village_green/village_green.json" export default class AllKnownLayers { @@ -60,7 +62,9 @@ export default class AllKnownLayers { play_forest, playground, sport_pitch, - slow_roads + slow_roads, + grass_in_parks, + village_green ]; // Must be below the list... diff --git a/Customizations/JSON/FromJSON.ts b/Customizations/JSON/FromJSON.ts index 7d2fbd012..b019ec391 100644 --- a/Customizations/JSON/FromJSON.ts +++ b/Customizations/JSON/FromJSON.ts @@ -9,7 +9,6 @@ export class FromJSON { const tag = Utils.SplitFirst(json, "="); return new Tag(tag[0], tag[1]); } - public static Tag(json: AndOrTagConfigJson | string, context: string = ""): TagsFilter { try{ return this.TagUnsafe(json, context); diff --git a/Customizations/JSON/LayerConfig.ts b/Customizations/JSON/LayerConfig.ts index df5a9040c..2cc3b5496 100644 --- a/Customizations/JSON/LayerConfig.ts +++ b/Customizations/JSON/LayerConfig.ts @@ -15,6 +15,7 @@ import {UIEventSource} from "../../Logic/UIEventSource"; import {FixedUiElement} from "../../UI/Base/FixedUiElement"; import {UIElement} from "../../UI/UIElement"; import {SubstitutedTranslation} from "../../UI/SubstitutedTranslation"; +import SourceConfig from "./SourceConfig"; export default class LayerConfig { @@ -25,7 +26,7 @@ export default class LayerConfig { id: string; name: Translation description: Translation; - overpassTags: TagsFilter; + source: SourceConfig; doNotDownload: boolean; passAllFeatures: boolean; minzoom: number; @@ -49,8 +50,6 @@ export default class LayerConfig { tagRenderings: TagRenderingConfig []; - private readonly configuration_warnings: string[] = [] - constructor(json: LayerConfigJson, context?: string) { context = context + "." + json.id; @@ -58,9 +57,39 @@ export default class LayerConfig { this.id = json.id; this.name = Translations.T(json.name, context + ".name"); this.description = Translations.T(json.description, context + ".description"); - this.overpassTags = FromJSON.Tag(json.overpassTags, context + ".overpasstags"); - this.doNotDownload = json.doNotDownload ?? false, - this.passAllFeatures = json.passAllFeatures ?? false; + + let legacy = undefined; + if (json["overpassTags"] !== undefined) { + // @ts-ignore + legacy = FromJSON.Tag(json["overpassTags"], context + ".overpasstags"); + } + if(json.source !== undefined){ + if (legacy !== undefined ) { + throw context+"Both the legacy 'layer.overpasstags' and the new 'layer.source'-field are defined" + } + + let osmTags: TagsFilter = legacy; + if (json.source["osmTags"]) { + osmTags = FromJSON.Tag(json.source["osmTags"], context + "source.osmTags"); + } + + + this.source = new SourceConfig({ + osmTags: osmTags, + geojsonSource: json.source["geoJsonSource"], + overpassScript: json.source["overpassScript"], + }); + }else{ + this.source = new SourceConfig({ + osmTags : legacy + }) + } + + + + + this.doNotDownload = json.doNotDownload ?? false; + this.passAllFeatures = json.passAllFeatures ?? false; this.minzoom = json.minzoom; this.wayHandling = json.wayHandling ?? 0; this.hideUnderlayingFeaturesMinPercentage = json.hideUnderlayingFeaturesMinPercentage ?? 0; @@ -82,16 +111,15 @@ export default class LayerConfig { if (deflt === undefined) { return undefined; } - return new TagRenderingConfig(deflt, self.overpassTags, `${context}.${key}.default value`); + return new TagRenderingConfig(deflt, self.source.osmTags, `${context}.${key}.default value`); } if (typeof v === "string") { const shared = SharedTagRenderings.SharedTagRendering[v]; if (shared) { - console.log("Got shared TR:", v, "-->", shared) return shared; } } - return new TagRenderingConfig(v, self.overpassTags, `${context}.${key}`); + return new TagRenderingConfig(v, self.source.osmTags, `${context}.${key}`); } /** @@ -119,7 +147,7 @@ export default class LayerConfig { } throw `Predefined tagRendering ${renderingJson} not found in ${context}`; } - return new TagRenderingConfig(renderingJson, self.overpassTags, `${context}.tagrendering[${i}]`); + return new TagRenderingConfig(renderingJson, self.source.osmTags, `${context}.tagrendering[${i}]`); }); } @@ -142,7 +170,7 @@ export default class LayerConfig { this.title = tr("title", undefined); this.icon = tr("icon", Img.AsData(Svg.pin)); this.iconOverlays = (json.iconOverlays ?? []).map((overlay, i) => { - let tr = new TagRenderingConfig(overlay.then, self.overpassTags, `iconoverlays.${i}`); + let tr = new TagRenderingConfig(overlay.then, self.source.osmTags, `iconoverlays.${i}`); if (typeof overlay.then === "string" && SharedTagRenderings.SharedIcons[overlay.then] !== undefined) { tr = SharedTagRenderings.SharedIcons[overlay.then]; } @@ -281,7 +309,7 @@ export default class LayerConfig { const iconUrlStatic = render(this.icon); const self = this; - var mappedHtml = tags.map(tgs => { + const mappedHtml = tags.map(tgs => { // What do you mean, 'tgs' is never read? // It is read implicitly in the 'render' method const iconUrl = render(self.icon); diff --git a/Customizations/JSON/LayerConfigJson.ts b/Customizations/JSON/LayerConfigJson.ts index 07f83c79c..9112b589e 100644 --- a/Customizations/JSON/LayerConfigJson.ts +++ b/Customizations/JSON/LayerConfigJson.ts @@ -26,8 +26,23 @@ export interface LayerConfigJson { /** * The tags to load from overpass. Either a simple 'key=value'-string, otherwise an advanced configuration + * DEPRECATED + * shorthand for source: {osmTags: "key=value"} */ - overpassTags: AndOrTagConfigJson | string; + //overpassTags: AndOrTagConfigJson | string; + + /** + * This determines where the data for the layer is fetched. + * There are some options: + * + * source: {osmTags: "key=value"} will fetch all objects with given tags from OSM. Currently, this will create a query to overpass and fetch the data - in the future this might fetch from the OSM API + * source: {geoJsonSource: "https://my.source.net/some-geo-data.geojson"} to fetch a geojson from a third party source + * + * source: {overpassScript: ""} when you want to do special things. _This should be really rare_. + * This means that the data will be pulled from overpass with this script, and will ignore the osmTags for the query + * However, for the rest of the pipeline, the OsmTags will _still_ be used. This is important to enable layers etc... + */ + source: {osmTags: AndOrTagConfigJson | string} | {geoJsonSource: string} | {overpassScript: string} /** * If set, this layer will not query overpass; but it'll still match the tags above which are by chance returned by other layers. diff --git a/Customizations/JSON/SourceConfig.ts b/Customizations/JSON/SourceConfig.ts new file mode 100644 index 000000000..22b5fabca --- /dev/null +++ b/Customizations/JSON/SourceConfig.ts @@ -0,0 +1,32 @@ +import {TagsFilter} from "../../Logic/Tags"; + +export default class SourceConfig { + + osmTags?: TagsFilter; + overpassScript?: string; + geojsonSource?: string; + + constructor(params: { + osmTags?: TagsFilter, + overpassScript?: string, + geojsonSource?: string + }) { + + let defined = 0; + if (params.osmTags) { + defined++; + } + if (params.overpassScript) { + defined++; + } + if (params.geojsonSource) { + defined++; + } + if (defined == 0) { + throw "Source: nothing correct defined in the source" + } + this.osmTags = params.osmTags; + this.overpassScript = params.overpassScript; + this.geojsonSource = params.geojsonSource; + } +} \ No newline at end of file diff --git a/Logic/Actors/UpdateFromOverpass.ts b/Logic/Actors/UpdateFromOverpass.ts index f53d33c8e..57851568f 100644 --- a/Logic/Actors/UpdateFromOverpass.ts +++ b/Logic/Actors/UpdateFromOverpass.ts @@ -5,6 +5,7 @@ import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import {Overpass} from "../Osm/Overpass"; import Bounds from "../../Models/Bounds"; import FeatureSource from "../FeatureSource/FeatureSource"; +import {Utils} from "../../Utils"; export default class UpdateFromOverpass implements FeatureSource { @@ -71,11 +72,12 @@ export default class UpdateFromOverpass implements FeatureSource { this.update(); } - private GetFilter() { - const filters: TagsFilter[] = []; + private GetFilter(): Overpass { + let filters: TagsFilter[] = []; + let extraScripts: string[] = []; for (const layer of this._layoutToUse.data.layers) { if (typeof (layer) === "string") { - continue; + throw "A layer was not expanded!" } if (this._location.data.zoom < layer.minzoom) { continue; @@ -102,20 +104,21 @@ export default class UpdateFromOverpass implements FeatureSource { if (previouslyLoaded) { continue; } - filters.push(layer.overpassTags); + if (layer.source.overpassScript !== undefined) { + extraScripts.push(layer.source.overpassScript) + } else { + filters.push(layer.source.osmTags); + } } - if (filters.length === 0) { + filters = Utils.NoNull(filters) + extraScripts = Utils.NoNull(extraScripts) + if (filters.length + extraScripts.length === 0) { return undefined; } - return new Or(filters); + return new Overpass(new Or(filters), extraScripts); } private update(): void { - const filter = this.GetFilter(); - if (filter === undefined) { - return; - } - if (this.runningQuery.data) { console.log("Still running a query, skip"); return; @@ -133,9 +136,12 @@ export default class UpdateFromOverpass implements FeatureSource { const z = Math.floor(this._location.data.zoom ?? 0); - this.runningQuery.setData(true); const self = this; - const overpass = new Overpass(filter); + const overpass = this.GetFilter(); + if (overpass === undefined) { + return; + } + this.runningQuery.setData(true); overpass.queryGeoJson(queryBounds, function (data, date) { self._previousBounds.get(z).push(queryBounds); @@ -165,9 +171,10 @@ export default class UpdateFromOverpass implements FeatureSource { self.timeout.setData(0); self.update() } - }, 1000 + }, 1000 ) } + countDown(); } diff --git a/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts b/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts index f4be69228..f69d817bb 100644 --- a/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts +++ b/Logic/FeatureSource/FeatureDuplicatorPerLayer.ts @@ -30,7 +30,7 @@ export default class FeatureDuplicatorPerLayer implements FeatureSource { let foundALayer = false; for (const layer of layers.data) { - if (layer.layerDef.overpassTags.matchesProperties(f.feature.properties)) { + if (layer.layerDef.source.osmTags.matchesProperties(f.feature.properties)) { foundALayer = true; if (layer.layerDef.passAllFeatures) { diff --git a/Logic/Osm/Overpass.ts b/Logic/Osm/Overpass.ts index b7f1fcb8b..66df736c6 100644 --- a/Logic/Osm/Overpass.ts +++ b/Logic/Osm/Overpass.ts @@ -9,9 +9,11 @@ import Bounds from "../../Models/Bounds"; export class Overpass { private _filter: TagsFilter public static testUrl: string = null + private readonly _extraScripts: string[]; - constructor(filter: TagsFilter) { + constructor(filter: TagsFilter, extraScripts: string[]) { this._filter = filter + this._extraScripts = extraScripts; } @@ -21,6 +23,9 @@ export class Overpass { for (const filterOr of filters) { filter += 'nwr' + filterOr + ';' } + for (const extraScript of this._extraScripts){ + filter += '('+extraScript+');'; + } const query = '[out:json][timeout:25]' + bbox + ';(' + filter + ');out body;>;out skel qt;' return "https://overpass-api.de/api/interpreter?data=" + encodeURIComponent(query) @@ -48,6 +53,7 @@ export class Overpass { } // @ts-ignore const geojson = OsmToGeoJson.default(json); + console.log("Received geojson", geojson) const osmTime = new Date(json.osm3s.timestamp_osm_base); continuation(geojson, osmTime); }).fail(onFail) diff --git a/Models/Constants.ts b/Models/Constants.ts index f56372826..2c55c47cf 100644 --- a/Models/Constants.ts +++ b/Models/Constants.ts @@ -2,7 +2,7 @@ import { Utils } from "../Utils"; export default class Constants { - public static vNumber = "0.5.14"; + public static vNumber = "0.6.0"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { diff --git a/assets/layers/benches/benches.json b/assets/layers/benches/benches.json index 129d83714..7eb2c4e3a 100644 --- a/assets/layers/benches/benches.json +++ b/assets/layers/benches/benches.json @@ -6,7 +6,9 @@ "fr": "Bancs" }, "minzoom": 14, - "overpassTags": "amenity=bench", + "source": { + "osmTags": "amenity=bench" + }, "title": { "render": { "en": "Bench", diff --git a/assets/layers/benches/benches_at_pt.json b/assets/layers/benches/benches_at_pt.json index de2e5375f..520875577 100644 --- a/assets/layers/benches/benches_at_pt.json +++ b/assets/layers/benches/benches_at_pt.json @@ -6,11 +6,13 @@ "fr": "Bancs des arrêts de transport en commun" }, "minzoom": 14, - "overpassTags": { - "or": [ - "bench=yes", - "bench=stand_up_bench" - ] + "source": { + "osmTags": { + "or": [ + "bench=yes", + "bench=stand_up_bench" + ] + } }, "title": { "render": { diff --git a/assets/layers/benches/picnic_tables.json b/assets/layers/benches/picnic_tables.json index e5a925857..2264d72f4 100644 --- a/assets/layers/benches/picnic_tables.json +++ b/assets/layers/benches/picnic_tables.json @@ -5,7 +5,9 @@ "nl": "Picnictafels" }, "minzoom": 12, - "overpassTags": "leisure=picnic_table", + "source": { + "osmTags": "leisure=picnic_table" + }, "title": { "render": { "en": "Picnic table", diff --git a/assets/layers/bicycle_library/bicycle_library.json b/assets/layers/bicycle_library/bicycle_library.json index 65ec7acdf..a72996546 100644 --- a/assets/layers/bicycle_library/bicycle_library.json +++ b/assets/layers/bicycle_library/bicycle_library.json @@ -5,7 +5,8 @@ "nl": "Fietsbibliotheek" }, "minzoom": 8 , - "overpassTags": "amenity=bicycle_library", + "source": { + "osmTags": "amenity=bicycle_library"}, "title": { "render": { "en": "Bicycle library", diff --git a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json index f798716c5..099acc42c 100644 --- a/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json +++ b/assets/layers/bicycle_tube_vending_machine/bicycle_tube_vending_machine.json @@ -37,11 +37,13 @@ } ], "iconSize": "50,50,bottom", - "overpassTags": { - "and": [ - "amenity=vending_machine", - "vending~.*bicycle_tube.*" - ] + "source": { + "osmTags": { + "and": [ + "amenity=vending_machine", + "vending~.*bicycle_tube.*" + ] + } }, "minzoom": 13, "wayHandling": 2, @@ -104,7 +106,7 @@ "mappings": [ { "if": "payment:coins=yes", - "ifnot": "payment:coins=no", + "ifnot": "payment:coins=no", "then": "Payment with coins is possible" }, { diff --git a/assets/layers/bike_cafe/bike_cafes.json b/assets/layers/bike_cafe/bike_cafes.json index da1274e7c..5a777a724 100644 --- a/assets/layers/bike_cafe/bike_cafes.json +++ b/assets/layers/bike_cafe/bike_cafes.json @@ -8,18 +8,20 @@ "de": "Fahrrad-Café" }, "minzoom": 13, - "overpassTags": { - "and": [ - "amenity~pub|bar|cafe|restaurant", - { - "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", - "or": [ - "pub~cycling|bicycle", - "theme~cycling|bicycle", - "service:bicycle:.*~~*" - ] - } - ] + "source": { + "osmTags": { + "and": [ + "amenity~pub|bar|cafe|restaurant", + { + "#": "Note the double tilde in 'service:bicycle' which interprets the key as regex too", + "or": [ + "pub~cycling|bicycle", + "theme~cycling|bicycle", + "service:bicycle:.*~~*" + ] + } + ] + } }, "title": { "render": { diff --git a/assets/layers/bike_cleaning/bike_cleaning.json b/assets/layers/bike_cleaning/bike_cleaning.json index 2665ea102..0aec74d4f 100644 --- a/assets/layers/bike_cleaning/bike_cleaning.json +++ b/assets/layers/bike_cleaning/bike_cleaning.json @@ -23,12 +23,14 @@ "render": "./assets/layers/bike_cleaning/bike_cleaning.svg" }, "iconSize": "50,50,bottom", - "overpassTags": { - "or": [ - "service:bicycle:cleaning=yes", - "service:bicycle:cleaning=diy", - "amenity=bicycle_wash" - ] + "source": { + "osmTags": { + "or": [ + "service:bicycle:cleaning=yes", + "service:bicycle:cleaning=diy", + "amenity=bicycle_wash" + ] + } }, "minzoom": 13, "wayHandling": 1, diff --git a/assets/layers/bike_monitoring_station/bike_monitoring_station.json b/assets/layers/bike_monitoring_station/bike_monitoring_station.json index 5b19066b5..38d2ec8a7 100644 --- a/assets/layers/bike_monitoring_station/bike_monitoring_station.json +++ b/assets/layers/bike_monitoring_station/bike_monitoring_station.json @@ -1,14 +1,16 @@ - { +{ "id": "bike_monitoring_station", "name": { "en": "Monitoring stations" }, "minzoom": 12, - "overpassTags": { - "and": [ - "man_made=monitoring_station", - "monitoring:bicycle=yes" - ] + "source": { + "osmTags": { + "and": [ + "man_made=monitoring_station", + "monitoring:bicycle=yes" + ] + } }, "title": { "render": { @@ -32,12 +34,15 @@ } ] }, - "tagRenderings": [ "images", - + "tagRenderings": [ + "images", { "render": "{live({url},{url:format},hour)} cyclists last hour
{live({url},{url:format},day)} cyclists today
{live({url},{url:format},year)} cyclists this year
", "condition": { - "and": ["url~*","url:format~*"] + "and": [ + "url~*", + "url:format~*" + ] } } ], diff --git a/assets/layers/bike_parking/bike_parking.json b/assets/layers/bike_parking/bike_parking.json index 2769720b3..7a0c9ffee 100644 --- a/assets/layers/bike_parking/bike_parking.json +++ b/assets/layers/bike_parking/bike_parking.json @@ -8,10 +8,12 @@ "de": "Fahrrad-Parkplätze" }, "minzoom": 17, - "overpassTags": { - "and": [ - "amenity=bicycle_parking" - ] + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_parking" + ] + } }, "icon": { "render": { diff --git a/assets/layers/bike_repair_station/bike_repair_station.json b/assets/layers/bike_repair_station/bike_repair_station.json index 207dfa110..6667aac05 100644 --- a/assets/layers/bike_repair_station/bike_repair_station.json +++ b/assets/layers/bike_repair_station/bike_repair_station.json @@ -8,10 +8,12 @@ "de": "Fahrradstationen (Reparatur, Pumpe oder beides)" }, "minzoom": 13, - "overpassTags": { - "and": [ - "amenity=bicycle_repair_station" - ] + "source": { + "osmTags": { + "and": [ + "amenity=bicycle_repair_station" + ] + } }, "title": { "render": { @@ -71,7 +73,8 @@ "gl": "Bomba de ar estragada", "de": "Kaputte Pumpe" } - },{ + }, + { "if": { "and": [ "service:bicycle:pump=yes", @@ -107,7 +110,7 @@ "titleIcons": [ { "render": "", - "condition": "operator=De Fietsambassade Gent", + "condition": "operator=De Fietsambassade Gent", "roaming": true }, "defaults" diff --git a/assets/layers/bike_shop/bike_shop.json b/assets/layers/bike_shop/bike_shop.json index f8676ce3a..0bc027bee 100644 --- a/assets/layers/bike_shop/bike_shop.json +++ b/assets/layers/bike_shop/bike_shop.json @@ -8,41 +8,43 @@ "de": "Fahrradwerkstatt/geschäft" }, "minzoom": 13, - "overpassTags": { - "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", - "or": [ - "shop=bicycle", - { - "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", - "and": [ - "amenity=bicycle_rental", - "network=" - ] - }, - { - "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", - "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", - "and": [ - "shop=sports", - "service:bicycle:retail!=no", - "service:bicycle:repair!=no", - { - "or": [ - "sport=bicycle", - "sport=cycling", - "sport=" - ] - } - ] - }, - { - "#": "Any shop with any bicycle service", - "and": [ - "shop~*", - "service:bicycle:.*~~.*" - ] - } - ] + "source": { + "osmTags": { + "#": "We select all bicycle shops, sport shops (but we try to weed out non-bicycle related shops), and any shop with a bicycle related tag", + "or": [ + "shop=bicycle", + { + "#": "A bicycle rental with a network is something such as villo, bluebike, ... We don't want them", + "and": [ + "amenity=bicycle_rental", + "network=" + ] + }, + { + "#": "if sport is defined and is not bicycle, it is retrackted; if bicycle retail/repair is marked as 'no', it is retracted too.", + "##": "There will be a few false-positives with this. They will get filtered out by people marking both 'not selling bikes' and 'not repairing bikes'. Furthermore, the OSMers will add a sports-subcategory on it", + "and": [ + "shop=sports", + "service:bicycle:retail!=no", + "service:bicycle:repair!=no", + { + "or": [ + "sport=bicycle", + "sport=cycling", + "sport=" + ] + } + ] + }, + { + "#": "Any shop with any bicycle service", + "and": [ + "shop~*", + "service:bicycle:.*~~.*" + ] + } + ] + } }, "title": { "render": { @@ -575,7 +577,7 @@ "badge": true }, { - "if": "service:bicycle:pump=yes", + "if": "service:bicycle:pump=yes", "then": "circle:#e2783d;./assets/layers/bike_repair_station/pump.svg", "badge": true } diff --git a/assets/layers/bird_hide/birdhides.json b/assets/layers/bird_hide/birdhides.json index 5c3558419..0c99c1f3f 100644 --- a/assets/layers/bird_hide/birdhides.json +++ b/assets/layers/bird_hide/birdhides.json @@ -4,10 +4,12 @@ "nl": "Vogelkijkhutten" }, "minzoom": 14, - "overpassTags": { - "and": [ - "leisure=bird_hide" - ] + "source": { + "osmTags": { + "and": [ + "leisure=bird_hide" + ] + } }, "title": { "render": { diff --git a/assets/layers/cycling_themed_object/cycling_themed_objects.json b/assets/layers/cycling_themed_object/cycling_themed_objects.json index 282a62b9b..007e786f7 100644 --- a/assets/layers/cycling_themed_object/cycling_themed_objects.json +++ b/assets/layers/cycling_themed_object/cycling_themed_objects.json @@ -7,14 +7,16 @@ "de": "Mit Fahrrad zusammenhängendes Objekt" }, "minzoom": 13, - "overpassTags": { - "or": [ - "theme~cycling|bicycle", - "sport=cycling", - "association~cycling|bicycle", - "ngo~cycling|bicycle", - "club~bicycle|cycling" - ] + "source": { + "osmTags": { + "or": [ + "theme~cycling|bicycle", + "sport=cycling", + "association~cycling|bicycle", + "ngo~cycling|bicycle", + "club~bicycle|cycling" + ] + } }, "title": { "render": { diff --git a/assets/layers/direction/direction.json b/assets/layers/direction/direction.json index a22f42814..f4dd1648f 100644 --- a/assets/layers/direction/direction.json +++ b/assets/layers/direction/direction.json @@ -4,11 +4,13 @@ "en": "Direction visualization" }, "minzoom": 16, - "overpassTags": { - "or": [ - "camera:direction~*", - "direction~*" - ] + "source": { + "osmTags": { + "or": [ + "camera:direction~*", + "direction~*" + ] + } }, "doNotDownload": true, "passAllFeatures": true, diff --git a/assets/layers/drinking_water/drinking_water.json b/assets/layers/drinking_water/drinking_water.json index b85ff4f26..b59d75494 100644 --- a/assets/layers/drinking_water/drinking_water.json +++ b/assets/layers/drinking_water/drinking_water.json @@ -31,14 +31,15 @@ "badge": true } ], - "iconSize": "40,40,bottom", - "overpassTags": { - "and": [ - "amenity=drinking_water", - "access!=permissive", - "access!=private" - ] + "source": { + "osmTags": { + "and": [ + "amenity=drinking_water", + "access!=permissive", + "access!=private" + ] + } }, "minzoom": 13, "wayHandling": 1, diff --git a/assets/layers/ghost_bike/ghost_bike.json b/assets/layers/ghost_bike/ghost_bike.json index d33d7df02..98d1bb4fa 100644 --- a/assets/layers/ghost_bike/ghost_bike.json +++ b/assets/layers/ghost_bike/ghost_bike.json @@ -5,7 +5,9 @@ "nl": "Witte Fietsen", "de": "Geisterrad" }, - "overpassTags": "memorial=ghost_bike", + "source": { + "osmTags": "memorial=ghost_bike" + }, "minzoom": 0, "title": { "render": { @@ -43,7 +45,7 @@ } ], "tagRenderings": [ - { + { "render": { "en": "A ghost bike is a memorial for a cyclist who died in a traffic accident, in the form of a white bicycle placed permanently near the accident location.", "nl": "Een Witte Fiets (of Spookfiets) is een aandenken aan een fietser die bij een verkeersongeval om het leven kwam. Het gaat over een witgeschilderde fiets die geplaatst werd in de buurt van het ongeval.", diff --git a/assets/layers/information_board/information_board.json b/assets/layers/information_board/information_board.json index 90d2cb0e9..0ab3c893e 100644 --- a/assets/layers/information_board/information_board.json +++ b/assets/layers/information_board/information_board.json @@ -5,10 +5,12 @@ "en": "Information boards" }, "minzoom": 12, - "overpassTags": { - "and": [ - "information=board" - ] + "source": { + "osmTags": { + "and": [ + "information=board" + ] + } }, "title": { "render": { @@ -16,7 +18,9 @@ "en": "Information board" } }, - "tagRenderings": [ "images"], + "tagRenderings": [ + "images" + ], "hideUnderlayingFeaturesMinPercentage": 0, "icon": { "render": "./assets/layers/information_board/board.svg" diff --git a/assets/layers/maps/maps.json b/assets/layers/maps/maps.json index 41dba46bd..6184098bc 100644 --- a/assets/layers/maps/maps.json +++ b/assets/layers/maps/maps.json @@ -5,11 +5,13 @@ "nl": "Kaarten" }, "minzoom": 12, - "overpassTags": { - "or": [ - "tourism=map", - "information=map" - ] + "source": { + "osmTags": { + "or": [ + "tourism=map", + "information=map" + ] + } }, "title": { "render": { diff --git a/assets/layers/nature_reserve/nature_reserve.json b/assets/layers/nature_reserve/nature_reserve.json index da5444380..faabad8aa 100644 --- a/assets/layers/nature_reserve/nature_reserve.json +++ b/assets/layers/nature_reserve/nature_reserve.json @@ -4,11 +4,13 @@ "nl": "Natuurgebied" }, "minzoom": 12, - "overpassTags": { - "or": [ - "leisure=nature_reserve", - "boundary=protected_area" - ] + "source": { + "osmTags": { + "or": [ + "leisure=nature_reserve", + "boundary=protected_area" + ] + } }, "title": { "render": { @@ -330,7 +332,8 @@ "key": "description:0" } }, - {"#": "Surface are", + { + "#": "Surface are", "render": { "en": "Surface area: {_surface:ha}Ha", "mappings": { diff --git a/assets/layers/play_forest/play_forest.json b/assets/layers/play_forest/play_forest.json index 4fd3eab25..016d1d777 100644 --- a/assets/layers/play_forest/play_forest.json +++ b/assets/layers/play_forest/play_forest.json @@ -4,10 +4,12 @@ "nl": "Speelbossen" }, "minzoom": 13, - "overpassTags": { - "and": [ - "playground=forest" - ] + "source": { + "osmTags": { + "and": [ + "playground=forest" + ] + } }, "title": { "render": { diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 2d9e27d36..81f125d82 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -5,11 +5,13 @@ "en": "Playgrounds" }, "minzoom": 13, - "overpassTags": { - "and": [ - "leisure=playground", - "playground!=forest" - ] + "source": { + "osmTags": { + "and": [ + "leisure=playground", + "playground!=forest" + ] + } }, "description": { "nl": "Speeltuinen", @@ -299,7 +301,7 @@ "render": "https://upload.wikimedia.org/wikipedia/commons/0/00/Map_icons_by_Scott_de_Jonge_-_playground.svg" }, "width": { - "render": "3" + "render": "1" }, "iconSize": { "render": "40,40,center" diff --git a/assets/layers/public_bookcases/public_bookcases.json b/assets/layers/public_bookcases/public_bookcases.json index beb1c5c85..c159920da 100644 --- a/assets/layers/public_bookcases/public_bookcases.json +++ b/assets/layers/public_bookcases/public_bookcases.json @@ -12,7 +12,9 @@ "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", "fr": "Une armoire ou une boite contenant des livres en libre accès" }, - "overpassTags": "amenity=public_bookcase", + "source": { + "osmTags": "amenity=public_bookcase" + }, "minzoom": 12, "wayHandling": 2, "title": { @@ -256,9 +258,12 @@ "de": "Teil des Netzwerks 'Little Free Library'", "fr": "Fait partie du réseau 'Little Free Library'" }, - "if":{ - "and": ["brand=Little Free Library","nobrand="] - } + "if": { + "and": [ + "brand=Little Free Library", + "nobrand=" + ] + } }, { "if": { diff --git a/assets/layers/slow_roads/slow_roads.json b/assets/layers/slow_roads/slow_roads.json index 6fab9b6ae..032301c4c 100644 --- a/assets/layers/slow_roads/slow_roads.json +++ b/assets/layers/slow_roads/slow_roads.json @@ -4,16 +4,18 @@ "nl": "Trage wegen" }, "minzoom": 14, - "overpassTags": { - "or": [ - "highway=pedestrian", - "highway=cycleway", - "highway=footway", - "highway=path", - "highway=bridleway", - "highway=living_street", - "highway=track" - ] + "source": { + "osmTags": { + "or": [ + "highway=pedestrian", + "highway=cycleway", + "highway=footway", + "highway=path", + "highway=bridleway", + "highway=living_street", + "highway=track" + ] + } }, "title": { "render": { diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index f88ea7575..84fb83f85 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -5,10 +5,11 @@ }, "wayHandling": 2, "minzoom": 12, - "overpassTags": { + "source": { + "osmTags": { "and": [ "leisure=pitch" - ] + ]} }, "title": { "render": { @@ -211,13 +212,13 @@ "render": "./assets/layers/sport_pitch/tabletennis.svg" }, "width": { - "render": "8" + "render": "1" }, "iconSize": { "render": "40,40,center" }, "color": { - "render": "#00f" + "render": "#009" }, "presets": [ { diff --git a/assets/layers/surveillance_cameras/surveillance_cameras.json b/assets/layers/surveillance_cameras/surveillance_cameras.json index f65537c19..83dc80d5c 100644 --- a/assets/layers/surveillance_cameras/surveillance_cameras.json +++ b/assets/layers/surveillance_cameras/surveillance_cameras.json @@ -5,17 +5,19 @@ "nl": "Bewakingscamera's" }, "minzoom": 12, - "overpassTags": { - "and": [ - "man_made=surveillance", - { - "or": [ - "surveillance:type=camera", - "surveillance:type=ALPR", - "surveillance:type=ANPR" - ] - } - ] + "source": { + "osmTags": { + "and": [ + "man_made=surveillance", + { + "or": [ + "surveillance:type=camera", + "surveillance:type=ALPR", + "surveillance:type=ANPR" + ] + } + ] + } }, "title": { "render": { diff --git a/assets/layers/toilets/toilets.json b/assets/layers/toilets/toilets.json index 7770573d6..43b2e8e11 100644 --- a/assets/layers/toilets/toilets.json +++ b/assets/layers/toilets/toilets.json @@ -5,7 +5,9 @@ "de": "Toiletten", "fr": "Toilettes" }, - "overpassTags": "amenity=toilets", + "source": { + "osmTags": "amenity=toilets" + }, "title": { "render": { "en": "Toilet", diff --git a/assets/layers/trees/tree_nodes.json b/assets/layers/trees/tree_nodes.json index 3493c1c8c..644ce3932 100644 --- a/assets/layers/trees/tree_nodes.json +++ b/assets/layers/trees/tree_nodes.json @@ -5,8 +5,12 @@ "en": "Tree" }, "minzoom": 14, - "overpassTags": { - "and": ["natural=tree"] + "source": { + "osmTags": { + "and": [ + "natural=tree" + ] + } }, "title": { "render": { @@ -38,7 +42,9 @@ "mappings": [ { "if": { - "and": ["height~^[0-9.]+$"] + "and": [ + "height~^[0-9.]+$" + ] }, "then": { "nl": "Hoogte: {height} m", @@ -55,7 +61,9 @@ "mappings": [ { "if": { - "and": ["leaf_type=broadleaved"] + "and": [ + "leaf_type=broadleaved" + ] }, "then": { "nl": "\"\"/ Loofboom", @@ -64,7 +72,9 @@ }, { "if": { - "and": ["leaf_type=needleleaved"] + "and": [ + "leaf_type=needleleaved" + ] }, "then": { "nl": "\"\"/ Naaldboom", @@ -73,7 +83,9 @@ }, { "if": { - "and": ["leaf_type=leafless"] + "and": [ + "leaf_type=leafless" + ] }, "then": { "nl": "\"\"/ Permanent bladloos", @@ -91,7 +103,9 @@ "mappings": [ { "if": { - "and": ["denotation=landmark"] + "and": [ + "denotation=landmark" + ] }, "then": { "nl": "De boom valt op door zijn grootte of prominente locatie. Hij is nuttig voor navigatie.", @@ -100,7 +114,9 @@ }, { "if": { - "and": ["denotation=natural_monument"] + "and": [ + "denotation=natural_monument" + ] }, "then": { "nl": "De boom is een natuurlijk monument, bijvoorbeeld doordat hij bijzonder oud of van een waardevolle soort is.", @@ -109,7 +125,9 @@ }, { "if": { - "and": ["denotation=agricultural"] + "and": [ + "denotation=agricultural" + ] }, "then": { "nl": "De boom wordt voor landbouwdoeleinden gebruikt, bijvoorbeeld in een boomgaard.", @@ -118,7 +136,9 @@ }, { "if": { - "and": ["denotation=park"] + "and": [ + "denotation=park" + ] }, "then": { "nl": "De boom staat in een park of dergelijke (begraafplaats, schoolterrein, …).", @@ -127,7 +147,9 @@ }, { "if": { - "and": ["denotation=garden"] + "and": [ + "denotation=garden" + ] }, "then": { "nl": "De boom staat in de tuin bij een woning/flatgebouw.", @@ -136,7 +158,9 @@ }, { "if": { - "and": ["denotation=avenue"] + "and": [ + "denotation=avenue" + ] }, "then": { "nl": "Dit is een laanboom.", @@ -145,7 +169,9 @@ }, { "if": { - "and": ["denotation=urban"] + "and": [ + "denotation=urban" + ] }, "then": { "nl": "De boom staat in een woonkern.", @@ -154,7 +180,9 @@ }, { "if": { - "and": ["denotation=none"] + "and": [ + "denotation=none" + ] }, "then": { "nl": "De boom staat buiten een woonkern.", @@ -171,7 +199,9 @@ "mappings": [ { "if": { - "and": ["leaf_cycle=deciduous"] + "and": [ + "leaf_cycle=deciduous" + ] }, "then": { "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", @@ -180,7 +210,9 @@ }, { "if": { - "and": ["leaf_cycle=evergreen"] + "and": [ + "leaf_cycle=evergreen" + ] }, "then": { "nl": "Groenblijvend.", @@ -189,7 +221,9 @@ } ], "condition": { - "and": ["leaf_type!~^leafless$"] + "and": [ + "leaf_type!~^leafless$" + ] } }, { @@ -351,13 +385,17 @@ "mappings": [ { "if": { - "and": ["leaf_type=broadleaved"] + "and": [ + "leaf_type=broadleaved" + ] }, "then": "circle:#ffffff;./assets/themes/trees/broadleaved.svg" }, { "if": { - "and": ["leaf_type=needleleaved"] + "and": [ + "leaf_type=needleleaved" + ] }, "then": "circle:#ffffff;./assets/themes/trees/needleleaved.svg" } diff --git a/assets/layers/viewpoint/viewpoint.json b/assets/layers/viewpoint/viewpoint.json index 6014df1cf..7360f99b3 100644 --- a/assets/layers/viewpoint/viewpoint.json +++ b/assets/layers/viewpoint/viewpoint.json @@ -10,7 +10,9 @@ "nl": "Een mooi uitzicht - ideaal om een foto toe te voegen wanneer iets niet in een andere categorie past", "de": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt" }, - "overpassTags": "tourism=viewpoint", + "source": { + "osmTags": "tourism=viewpoint" + }, "minzoom": 14, "icon": "./assets/layers/viewpoint/viewpoint.svg", "iconSize": "20,20,center", diff --git a/assets/layers/village_green/grass_in_parks.json b/assets/layers/village_green/grass_in_parks.json new file mode 100644 index 000000000..9d8bee892 --- /dev/null +++ b/assets/layers/village_green/grass_in_parks.json @@ -0,0 +1,48 @@ +{ + "id": "grass_in_parks", + "name": { + "nl": "Toegankelijke grasvelden in parken" + }, + "source": { + "osmTags": { + "and": [ + "landuse=grass", + { + "or": [ + "access=public", + "access=yes" + ] + } + ] + }, + "overpassScript": "way[\"leisure\"=\"park\"];node(w);is_in;area._[\"leisure\"=\"park\"];(way(area)[\"landuse\"=\"grass\"]; node(w); );" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide in een park" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + } + ] + }, + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,bottom", + "width": "1", + "color": "#0f0", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "render": "Op dit grasveld in het park mag je spelen, picnicken, zitten, ..." + }, + { + "render": "{reviews(name, landuse=grass )}" + } + ] +} \ No newline at end of file diff --git a/assets/layers/village_green/village_green.json b/assets/layers/village_green/village_green.json new file mode 100644 index 000000000..524aa86cc --- /dev/null +++ b/assets/layers/village_green/village_green.json @@ -0,0 +1,37 @@ +{ + "id": "village_green", + "name": { + "nl": "Speelweide" + }, + "source": { + "osmTags": "landuse=village_green" + }, + "minzoom": 0, + "title": { + "render": { + "nl": "Speelweide" + }, + "mappings": [ + { + "if": "name~*", + "then": { + "nl": "{name}" + } + } + ] + }, + "icon": "./assets/themes/playgrounds/playground.svg", + "iconSize": "40,40,bottom", + "width": "1", + "color": "#0f0", + "wayHandling": 2, + "tagRenderings": [ + "images", + { + "render": "Dit is een klein stukje openbaar groen waar je mag spelen, picnicken, zitten, ..." + }, + { + "render": "{reviews(name, landuse=village_green )}" + } + ] +} \ No newline at end of file diff --git a/assets/themes/speelplekken/speelplekken.json b/assets/themes/speelplekken/speelplekken.json index 47372d1d0..0ab7bb84c 100644 --- a/assets/themes/speelplekken/speelplekken.json +++ b/assets/themes/speelplekken/speelplekken.json @@ -27,7 +27,9 @@ "play_forest", "playground", "sport_pitch", - "slow_roads" + "slow_roads", + "grass_in_parks", + "village_green" ], "roamingRenderings": [] } \ No newline at end of file