diff --git a/InitUiElements.ts b/InitUiElements.ts index 8fe9e9085..e3e61ce2e 100644 --- a/InitUiElements.ts +++ b/InitUiElements.ts @@ -38,6 +38,7 @@ import {LayoutConfigJson} from "./Models/ThemeConfig/Json/LayoutConfigJson"; import LayoutConfig from "./Models/ThemeConfig/LayoutConfig"; import LayerConfig from "./Models/ThemeConfig/LayerConfig"; import Minimap from "./UI/Base/Minimap"; +import Constants from "./Models/Constants"; export class InitUiElements { static InitAll( @@ -400,7 +401,8 @@ export class InitUiElements { state.layoutToUse, state.leafletMap, state.overpassUrl, - state.overpassTimeout + state.overpassTimeout, + Constants.useOsmApiAt ); State.state.layerUpdater = updater; diff --git a/Logic/Actors/OverpassFeatureSource.ts b/Logic/Actors/OverpassFeatureSource.ts index 2a32e60f6..b650d819b 100644 --- a/Logic/Actors/OverpassFeatureSource.ts +++ b/Logic/Actors/OverpassFeatureSource.ts @@ -23,6 +23,7 @@ export default class OverpassFeatureSource implements FeatureSource { public readonly sufficientlyZoomed: UIEventSource; public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly timeout: UIEventSource = new UIEventSource(0); + private readonly retries: UIEventSource = new UIEventSource(0); /** * The previous bounds for which the query has been run at the given zoom level @@ -46,7 +47,8 @@ export default class OverpassFeatureSource implements FeatureSource { layoutToUse: UIEventSource, leafletMap: UIEventSource, interpreterUrl: UIEventSource, - timeout: UIEventSource,) { + timeout: UIEventSource, + maxZoom = undefined) { this._location = location; this._layoutToUse = layoutToUse; this._leafletMap = leafletMap; @@ -59,7 +61,14 @@ export default class OverpassFeatureSource implements FeatureSource { return false; } let minzoom = Math.min(...layoutToUse.data.layers.map(layer => layer.minzoom ?? 18)); - return location.zoom >= minzoom; + if(location.zoom < minzoom){ + return false; + } + if(maxZoom !== undefined && location.zoom > maxZoom){ + return false; + } + + return true; }, [layoutToUse] ); for (let i = 0; i < 25; i++) { diff --git a/Logic/FeatureSource/OsmApiFeatureSource.ts b/Logic/FeatureSource/OsmApiFeatureSource.ts index de90274d2..d48cc5f4b 100644 --- a/Logic/FeatureSource/OsmApiFeatureSource.ts +++ b/Logic/FeatureSource/OsmApiFeatureSource.ts @@ -1,16 +1,34 @@ import FeatureSource from "./FeatureSource"; import {UIEventSource} from "../UIEventSource"; import {OsmObject} from "../Osm/OsmObject"; -import State from "../../State"; import {Utils} from "../../Utils"; +import Loc from "../../Models/Loc"; +import FilteredLayer from "../../Models/FilteredLayer"; +import Constants from "../../Models/Constants"; export default class OsmApiFeatureSource implements FeatureSource { public readonly features: UIEventSource<{ feature: any; freshness: Date }[]> = new UIEventSource<{ feature: any; freshness: Date }[]>([]); public readonly name: string = "OsmApiFeatureSource"; private readonly loadedTiles: Set = new Set(); + private readonly _state: { + leafletMap: UIEventSource; + locationControl: UIEventSource, filteredLayers: UIEventSource}; - constructor() { + constructor(minZoom = undefined, state: {locationControl: UIEventSource, filteredLayers: UIEventSource, leafletMap: UIEventSource}) { + this._state = state; + if(minZoom !== undefined){ + if(minZoom < 14){ + throw "MinZoom should be at least 14 or higher, OSM-api won't work otherwise" + } + const self = this; + state.locationControl.addCallbackAndRunD(location => { + if(location.zoom > minZoom){ + return; + } + self.loadArea() + }) + } } @@ -34,21 +52,21 @@ export default class OsmApiFeatureSource implements FeatureSource { /** * Loads the current inview-area */ - public loadArea(z: number = 16): boolean { - const layers = State.state.filteredLayers.data; + public loadArea(z: number = 14): boolean { + const layers = this._state.filteredLayers.data; const disabledLayers = layers.filter(layer => layer.layerDef.source.overpassScript !== undefined || layer.layerDef.source.geojsonSource !== undefined) if (disabledLayers.length > 0) { return false; } - const loc = State.state.locationControl.data; - if (loc.zoom < 16) { + const loc = this._state.locationControl.data; + if (loc.zoom < Constants.useOsmApiAt) { return false; } - if (State.state.leafletMap.data === undefined) { + if (this._state.leafletMap.data === undefined) { return false; // Not yet inited } - const bounds = State.state.leafletMap.data.getBounds() + const bounds = this._state.leafletMap.data.getBounds() const tileRange = Utils.TileRangeBetween(z, bounds.getNorth(), bounds.getEast(), bounds.getSouth(), bounds.getWest()) const self = this; Utils.MapRange(tileRange, (x, y) => { diff --git a/Models/Constants.ts b/Models/Constants.ts index 13d72da09..ed934f085 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.9.8"; + public static vNumber = "0.9.9"; // The user journey states thresholds when a new feature gets unlocked public static userJourney = { @@ -26,6 +26,12 @@ export default class Constants { */ static updateTimeoutSec: number = 30; + /** + * If zoom >= useOsmApiAt, then the OSM api will be used directly. + * If undefined, use overpass exclusively + */ + static useOsmApiAt = undefined; + private static isRetina(): boolean { if (Utils.runningFromConsole) { return; diff --git a/State.ts b/State.ts index 6ef07ff74..27e9a251f 100644 --- a/State.ts +++ b/State.ts @@ -398,7 +398,7 @@ export default class State { new ChangeToElementsActor(this.changes, this.allElements) - this.osmApiFeatureSource = new OsmApiFeatureSource() + this.osmApiFeatureSource = new OsmApiFeatureSource(Constants.useOsmApiAt, this) new PendingChangesUploader(this.changes, this.selectedElement); diff --git a/assets/layers/bench/bench.json b/assets/layers/bench/bench.json index e984dddaa..a2cf274dd 100644 --- a/assets/layers/bench/bench.json +++ b/assets/layers/bench/bench.json @@ -605,6 +605,9 @@ "pt_BR": "Adicionar um novo banco", "fi": "Lisää uusi penkki", "pl": "Dodaj nową ławkę" + }, + "presiceInput": { + "preferredBackground": "photo" } } ] diff --git a/assets/layers/waste_basket/waste_basket.json b/assets/layers/waste_basket/waste_basket.json index bab604f46..1dd17348b 100644 --- a/assets/layers/waste_basket/waste_basket.json +++ b/assets/layers/waste_basket/waste_basket.json @@ -22,7 +22,60 @@ "en": "This is a public waste basket, thrash can, where you can throw away your thrash.", "nl": "Dit is een publieke vuilnisbak waar je je afval kan weggooien." }, - "tagRenderings": [], + "tagRenderings": [ + { + "question": { + "en": "What kind of waste basket is this?", + "nl": "Wat voor soort vuilnisbak is dit?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "waste=", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + }, + "hideInAnswer": true + }, + { + "if": "waste=trash", + "then": { + "en": "A waste basket for general waste", + "nl": "Een vuilnisbak voor zwerfvuil" + } + }, + { + "if": "waste=dog_excrement", + "then": { + "en": "A waste basket for dog excrements", + "nl": "Een vuilnisbak specifiek voor hondenuitwerpselen" + } + }, + { + "if": "waste=cigarettes", + "then": { + "en": "A waste basket for cigarettes", + "nl": "Een vuilnisbak voor sigarettenpeuken" + } + }, + { + "if": "waste=drugs", + "then": { + "en": "A waste basket for drugs", + "nl": "Een vuilnisbak voor (vervallen) medicatie en drugs" + } + }, + { + "if": "waste=sharps", + "then": { + "en": "A waste basket for needles and other sharp objects", + "nl": "Een vuilnisbak voor injectienaalden en andere scherpe voorwerpen" + } + } + ] + } + ], "icon": { "render": "./assets/themes/waste_basket/waste_basket.svg" }, @@ -56,6 +109,9 @@ "title": { "en": "Waste Basket", "nl": "Vuilnisbak" + }, + "presiceInput": { + "preferredBackground": "photo" } } ]