From f659bc114157f2439c3f08b29c79ea62b8c77a31 Mon Sep 17 00:00:00 2001 From: pietervdvn Date: Sat, 20 Mar 2021 23:45:52 +0100 Subject: [PATCH] Add possibility to use a cutom overpass script, add 'grassfields in parks'-layer --- Customizations/AllKnownLayers.ts | 6 +- Customizations/JSON/FromJSON.ts | 1 - Customizations/JSON/LayerConfig.ts | 52 ++++++++++--- Customizations/JSON/LayerConfigJson.ts | 17 ++++- Customizations/JSON/SourceConfig.ts | 32 ++++++++ Logic/Actors/UpdateFromOverpass.ts | 35 +++++---- .../FeatureDuplicatorPerLayer.ts | 2 +- Logic/Osm/Overpass.ts | 8 +- Models/Constants.ts | 2 +- assets/layers/benches/benches.json | 4 +- assets/layers/benches/benches_at_pt.json | 12 +-- assets/layers/benches/picnic_tables.json | 4 +- .../bicycle_library/bicycle_library.json | 3 +- .../bicycle_tube_vending_machine.json | 14 ++-- assets/layers/bike_cafe/bike_cafes.json | 26 ++++--- .../layers/bike_cleaning/bike_cleaning.json | 14 ++-- .../bike_monitoring_station.json | 23 +++--- assets/layers/bike_parking/bike_parking.json | 10 ++- .../bike_repair_station.json | 15 ++-- assets/layers/bike_shop/bike_shop.json | 74 +++++++++--------- assets/layers/bird_hide/birdhides.json | 10 ++- .../cycling_themed_objects.json | 18 +++-- assets/layers/direction/direction.json | 12 +-- .../layers/drinking_water/drinking_water.json | 15 ++-- assets/layers/ghost_bike/ghost_bike.json | 6 +- .../information_board/information_board.json | 14 ++-- assets/layers/maps/maps.json | 12 +-- .../layers/nature_reserve/nature_reserve.json | 15 ++-- assets/layers/play_forest/play_forest.json | 10 ++- assets/layers/playground/playground.json | 14 ++-- .../public_bookcases/public_bookcases.json | 13 +++- assets/layers/slow_roads/slow_roads.json | 22 +++--- assets/layers/sport_pitch/sport_pitch.json | 9 ++- .../surveillance_cameras.json | 24 +++--- assets/layers/toilets/toilets.json | 4 +- assets/layers/trees/tree_nodes.json | 76 ++++++++++++++----- assets/layers/viewpoint/viewpoint.json | 4 +- .../layers/village_green/grass_in_parks.json | 48 ++++++++++++ .../layers/village_green/village_green.json | 37 +++++++++ assets/themes/speelplekken/speelplekken.json | 4 +- 40 files changed, 499 insertions(+), 222 deletions(-) create mode 100644 Customizations/JSON/SourceConfig.ts create mode 100644 assets/layers/village_green/grass_in_parks.json create mode 100644 assets/layers/village_green/village_green.json diff --git a/Customizations/AllKnownLayers.ts b/Customizations/AllKnownLayers.ts index 1ef497c..ba5795d 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 7d2fbd0..b019ec3 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 df5a904..2cc3b54 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 07f83c7..9112b58 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 0000000..22b5fab --- /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 f53d33c..5785156 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 f4be692..f69d817 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 b7f1fcb..66df736 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 f563728..2c55c47 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 129d837..7eb2c4e 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 de2e537..5208755 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 e5a9258..2264d72 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 65ec7ac..a729965 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 f798716..099acc4 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 da1274e..5a777a7 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 2665ea1..0aec74d 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 5b19066..38d2ec8 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 2769720..7a0c9ff 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 207dfa1..6667aac 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 f8676ce..0bc027b 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 5c35584..0c99c1f 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 282a62b..007e786 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 a22f428..f4dd164 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 b85ff4f..b59d754 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 d33d7df..98d1bb4 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 90d2cb0..0ab3c89 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 41dba46..6184098 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 da54443..faabad8 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 4fd3eab..016d1d7 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 2d9e27d..81f125d 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 beb1c5c..c159920 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 6fab9b6..032301c 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 f88ea75..84fb83f 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 f65537c..83dc80d 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 7770573..43b2e8e 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 3493c1c..644ce39 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 6014df1..7360f99 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 0000000..9d8bee8 --- /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 0000000..524aa86 --- /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 47372d1..0ab7bb8 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