From afaaaaadb19a975966469f0afbd07e88d620d301 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Thu, 30 Jul 2020 16:34:06 +0200 Subject: [PATCH] Add smoothness, add highlighting of a way --- Customizations/AllKnownLayouts.ts | 5 +- Customizations/LayerDefinition.ts | 1 + Customizations/Layers/Widths.ts | 2 +- Customizations/Layout.ts | 8 ++- Customizations/Layouts/Smoothness.ts | 81 ++++++++++++++++++++++++++++ Logic/FilteredLayer.ts | 29 +++++++--- Logic/LayerUpdater.ts | 5 +- Logic/Osm/OsmConnection.ts | 14 +++++ UI/MoreScreen.ts | 1 + UI/i18n/Translations.ts | 6 +++ index.css | 4 ++ index.ts | 2 +- 12 files changed, 146 insertions(+), 12 deletions(-) create mode 100644 Customizations/Layouts/Smoothness.ts diff --git a/Customizations/AllKnownLayouts.ts b/Customizations/AllKnownLayouts.ts index f502730..c8f2929 100644 --- a/Customizations/AllKnownLayouts.ts +++ b/Customizations/AllKnownLayouts.ts @@ -10,6 +10,7 @@ import {MetaMap} from "./Layouts/MetaMap"; import {StreetWidth} from "./Layouts/StreetWidth"; import {Natuurpunt} from "./Layouts/Natuurpunt"; import {ClimbingTrees} from "./Layouts/ClimbingTrees"; +import {Smoothness} from "./Layouts/Smoothness"; export class AllKnownLayouts { public static allSets = AllKnownLayouts.AllLayouts(); @@ -25,9 +26,9 @@ export class AllKnownLayouts { new StreetWidth(), new Natuurpunt(), new ClimbingTrees(), - new Artworks() + new Artworks(), + new Smoothness() /*new Toilets(), - new Statues(), */ ]; diff --git a/Customizations/LayerDefinition.ts b/Customizations/LayerDefinition.ts index 1431c1a..54d2f2f 100644 --- a/Customizations/LayerDefinition.ts +++ b/Customizations/LayerDefinition.ts @@ -69,6 +69,7 @@ export class LayerDefinition { */ style: (tags: any) => { color: string, + weight?: number, icon: { iconUrl: string, iconSize: number[], diff --git a/Customizations/Layers/Widths.ts b/Customizations/Layers/Widths.ts index df29c7b..ea8c84f 100644 --- a/Customizations/Layers/Widths.ts +++ b/Customizations/Layers/Widths.ts @@ -171,7 +171,7 @@ export class Widths extends LayerDefinition { return { icon: null, color: c, - weight: 7, + weight: 10, dashArray: dashArray } } diff --git a/Customizations/Layout.ts b/Customizations/Layout.ts index 6fb79a4..8dad971 100644 --- a/Customizations/Layout.ts +++ b/Customizations/Layout.ts @@ -39,6 +39,12 @@ export class Layout { public hideFromOverview : boolean = false; + /** + * The BBOX of the currently visible map are widened by this factor, in order to make some panning possible. + * This number influences this + */ + public widenFactor : number = 0.07; + /** * * @param name: The name used in the query string. If in the query "quests=" is defined, it will select this layout @@ -128,7 +134,7 @@ export class WelcomeMessage extends UIElement { } protected InnerUpdate(htmlElement: HTMLElement) { - this.osmConnection.registerActivateOsmAUthenticationClass() + this.osmConnection?.registerActivateOsmAUthenticationClass() } } diff --git a/Customizations/Layouts/Smoothness.ts b/Customizations/Layouts/Smoothness.ts new file mode 100644 index 0000000..6bf3dfc --- /dev/null +++ b/Customizations/Layouts/Smoothness.ts @@ -0,0 +1,81 @@ +import {Layout} from "../Layout"; +import {LayerDefinition} from "../LayerDefinition"; +import {Or, Tag} from "../../Logic/TagsFilter"; +import {TagRenderingOptions} from "../TagRendering"; + + +export class SmoothnessLayer extends LayerDefinition { + + constructor() { + super(); + this.name = "smoothness"; + this.minzoom = 17; + this.overpassFilter = new Or([ + new Tag("highway", "residential"), + new Tag("highway", "cycleway"), + new Tag("highway", "footway"), + new Tag("highway", "path"), + new Tag("highway", "tertiary") + ]); + + this.elementsToShow = [ + new TagRenderingOptions({ + question: "How smooth is this road to rollerskate on", + mappings: [ + {k: new Tag("smoothness","bad"), txt: "It's horrible"}, + {k: new Tag("smoothness","intermediate"), txt: "It is passable by rollerscate, but only if you have to"}, + {k: new Tag("smoothness","good"), txt: "Good, but it has some friction or holes"}, + {k: new Tag("smoothness","very_good"), txt: "Quite good and enjoyable"}, + {k: new Tag("smoothness","excellent"), txt: "Excellent - this is where you'd want to drive 24/7"}, + ] + }) + ] + + this.style = (properties) => { + let color = "#000000"; + if(new Tag("smoothness","bad").matchesProperties(properties)){ + color = "#ff0000"; + } + if(new Tag("smoothness","intermediate").matchesProperties(properties)){ + color = "#ffaa00"; + } + if(new Tag("smoothness","good").matchesProperties(properties)){ + color = "#ccff00"; + } + if(new Tag("smoothness","very_good").matchesProperties(properties)){ + color = "#00aa00"; + } + if(new Tag("smoothness","excellent").matchesProperties(properties)){ + color = "#00ff00"; + } + + return { + color: color, + icon: undefined, + weight: 8 + } + + } + + + } + +} + +export class Smoothness extends Layout { + constructor() { + super( + "smoothness", + ["en" ], + "Smoothness while rollerskating", + [new SmoothnessLayer()], + 17, + 51.2, + 3.2, + "Give smoothness feedback for rollerskating" + ); + this.widenFactor = 0.005 + this.hideFromOverview = true; + this.enableAdd = false; + } +} \ No newline at end of file diff --git a/Logic/FilteredLayer.ts b/Logic/FilteredLayer.ts index 1872b92..b5fd592 100644 --- a/Logic/FilteredLayer.ts +++ b/Logic/FilteredLayer.ts @@ -28,7 +28,7 @@ export class FilteredLayer { private readonly _map: Basemap; private readonly _maxAllowedOverlap: number; - private readonly _style: (properties) => { color: string, icon: { iconUrl: string, iconSize? : number[], popupAnchor?: number[], iconAnchor?:number[] } }; + private readonly _style: (properties) => { color: string, weight?: number, icon: { iconUrl: string, iconSize? : number[], popupAnchor?: number[], iconAnchor?:number[] } }; private readonly _storage: ElementStorage; @@ -239,19 +239,37 @@ export class FilteredLayer { }, onEachFeature: function (feature, layer) { - let eventSource = self._storage.addOrGetElement(feature); - eventSource.addCallback(function () { + + feature.updateStyle = () => { if (layer.setIcon) { layer.setIcon(L.icon(self._style(feature.properties).icon)) } else { self._geolayer.setStyle(function (feature) { - return self._style(feature.properties); + const style = self._style(feature.properties); + if (self._selectedElement.data?.feature === feature) { + if (style.weight !== undefined) { + style.weight = style.weight * 2; + }else{ + style.weight = 20; + } + } + return style; }); } - }); + } + + let eventSource = self._storage.addOrGetElement(feature); + + + eventSource.addCallback(feature.updateStyle); layer.on("click", function (e) { + const previousFeature = self._selectedElement.data?.feature; self._selectedElement.setData({feature: feature}); + feature.updateStyle(); + previousFeature?.updateStyle(); + + if (feature.geometry.type === "Point") { return; // Points bind there own popups } @@ -267,7 +285,6 @@ export class FilteredLayer { uiElement.Update(); uiElement.Activate(); L.DomEvent.stop(e); // Marks the event as consumed - }); } }); diff --git a/Logic/LayerUpdater.ts b/Logic/LayerUpdater.ts index 9f48d2d..385923a 100644 --- a/Logic/LayerUpdater.ts +++ b/Logic/LayerUpdater.ts @@ -8,6 +8,7 @@ import {Basemap} from "./Leaflet/Basemap"; export class LayerUpdater { private _map: Basemap; private _layers: FilteredLayer[]; + private widenFactor: number; public readonly runningQuery: UIEventSource = new UIEventSource(false); public readonly retries: UIEventSource = new UIEventSource(0); @@ -27,7 +28,9 @@ export class LayerUpdater { */ constructor(map: Basemap, minzoom: number, + widenFactor: number, layers: FilteredLayer[]) { + this.widenFactor = widenFactor; this._map = map; this._layers = layers; this._minzoom = minzoom; @@ -97,7 +100,7 @@ export class LayerUpdater { const bounds = this._map.map.getBounds(); - const diff =0.07; + const diff = this.widenFactor; const n = bounds.getNorth() + diff; const e = bounds.getEast() + diff; diff --git a/Logic/Osm/OsmConnection.ts b/Logic/Osm/OsmConnection.ts index f6f4035..8d98cd6 100644 --- a/Logic/Osm/OsmConnection.ts +++ b/Logic/Osm/OsmConnection.ts @@ -91,6 +91,8 @@ export class OsmConnection { } self.UpdatePreferences(); + self.CheckForMessagesContinuously(); + // details is an XML DOM of user details let userInfo = details.getElementsByTagName("user")[0]; @@ -120,9 +122,21 @@ export class OsmConnection { data.unreadMessages = parseInt(messages.getAttribute("unread")); data.totalMessages = parseInt(messages.getAttribute("count")); self.userDetails.ping(); + }); } + + private CheckForMessagesContinuously() { + const self = this; + window.setTimeout(() => { + if (self.userDetails.data.loggedIn) { + console.log("Checking for messages") + this.AttemptLogin(); + } + }, 5 * 60 * 1000); + } + /** * All elements with class 'activate-osm-authentication' are loaded and get an 'onclick' to authenticate */ diff --git a/UI/MoreScreen.ts b/UI/MoreScreen.ts index 5d49f2e..97863d8 100644 --- a/UI/MoreScreen.ts +++ b/UI/MoreScreen.ts @@ -52,6 +52,7 @@ export class MoreScreen extends UIElement { return new VerticalCombine([ tr.intro, + tr.requestATheme, new VerticalCombine(els), tr.streetcomplete ]).Render(); diff --git a/UI/i18n/Translations.ts b/UI/i18n/Translations.ts index 40dd7a8..f021ce7 100644 --- a/UI/i18n/Translations.ts +++ b/UI/i18n/Translations.ts @@ -924,6 +924,12 @@ export default class Translations { fr: "

Plus de thème

Vous aimez collecter des données?
Il y a plus de thèmes disponible.", nl: "

Meer thema's

Vind je het leuk om geodata te verzamelen?
Hier vind je meer opties." }), + + requestATheme: new T({ + en: "If you want a custom-built quest, request it here", + nl: "Wil je een eigen kaartthema, vraag dit hier aan" + }), + streetcomplete: new T({ en: "Another, similar application is StreetComplete", fr: "Une autre application similaire est StreetComplete", diff --git a/index.css b/index.css index 2250009..90cb1ce 100644 --- a/index.css +++ b/index.css @@ -54,6 +54,10 @@ form { display: block; } +.selected-element { + fill: black +} + /**************** GENERIC ****************/ .uielement { diff --git a/index.ts b/index.ts index 5231583..7a2e8b1 100644 --- a/index.ts +++ b/index.ts @@ -186,7 +186,7 @@ const bm = new Basemap("leafletDiv", locationControl, new VariableUiElement( const layerSetup = InitUiElements.InitLayers(layoutToUse, osmConnection, changes, allElements, bm, fullScreenMessage, selectedElement); -const layerUpdater = new LayerUpdater(bm, layerSetup.minZoom, layerSetup.flayers); +const layerUpdater = new LayerUpdater(bm, layerSetup.minZoom, layoutToUse.widenFactor, layerSetup.flayers); // --------------- Setting up layer selection ui --------