Add smoothness, add highlighting of a way

This commit is contained in:
Pieter Vander Vennet 2020-07-30 16:34:06 +02:00
parent 8af25a9cdf
commit afaaaaadb1
12 changed files with 146 additions and 12 deletions

View file

@ -10,6 +10,7 @@ import {MetaMap} from "./Layouts/MetaMap";
import {StreetWidth} from "./Layouts/StreetWidth"; import {StreetWidth} from "./Layouts/StreetWidth";
import {Natuurpunt} from "./Layouts/Natuurpunt"; import {Natuurpunt} from "./Layouts/Natuurpunt";
import {ClimbingTrees} from "./Layouts/ClimbingTrees"; import {ClimbingTrees} from "./Layouts/ClimbingTrees";
import {Smoothness} from "./Layouts/Smoothness";
export class AllKnownLayouts { export class AllKnownLayouts {
public static allSets = AllKnownLayouts.AllLayouts(); public static allSets = AllKnownLayouts.AllLayouts();
@ -25,9 +26,9 @@ export class AllKnownLayouts {
new StreetWidth(), new StreetWidth(),
new Natuurpunt(), new Natuurpunt(),
new ClimbingTrees(), new ClimbingTrees(),
new Artworks() new Artworks(),
new Smoothness()
/*new Toilets(), /*new Toilets(),
new Statues(),
*/ */
]; ];

View file

@ -69,6 +69,7 @@ export class LayerDefinition {
*/ */
style: (tags: any) => { style: (tags: any) => {
color: string, color: string,
weight?: number,
icon: { icon: {
iconUrl: string, iconUrl: string,
iconSize: number[], iconSize: number[],

View file

@ -171,7 +171,7 @@ export class Widths extends LayerDefinition {
return { return {
icon: null, icon: null,
color: c, color: c,
weight: 7, weight: 10,
dashArray: dashArray dashArray: dashArray
} }
} }

View file

@ -39,6 +39,12 @@ export class Layout {
public hideFromOverview : boolean = false; 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=<name>" is defined, it will select this layout * @param name: The name used in the query string. If in the query "quests=<name>" is defined, it will select this layout
@ -128,7 +134,7 @@ export class WelcomeMessage extends UIElement {
} }
protected InnerUpdate(htmlElement: HTMLElement) { protected InnerUpdate(htmlElement: HTMLElement) {
this.osmConnection.registerActivateOsmAUthenticationClass() this.osmConnection?.registerActivateOsmAUthenticationClass()
} }
} }

View file

@ -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;
}
}

View file

@ -28,7 +28,7 @@ export class FilteredLayer {
private readonly _map: Basemap; private readonly _map: Basemap;
private readonly _maxAllowedOverlap: number; 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; private readonly _storage: ElementStorage;
@ -239,19 +239,37 @@ export class FilteredLayer {
}, },
onEachFeature: function (feature, layer) { onEachFeature: function (feature, layer) {
let eventSource = self._storage.addOrGetElement(feature);
eventSource.addCallback(function () { feature.updateStyle = () => {
if (layer.setIcon) { if (layer.setIcon) {
layer.setIcon(L.icon(self._style(feature.properties).icon)) layer.setIcon(L.icon(self._style(feature.properties).icon))
} else { } else {
self._geolayer.setStyle(function (feature) { 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) { layer.on("click", function (e) {
const previousFeature = self._selectedElement.data?.feature;
self._selectedElement.setData({feature: feature}); self._selectedElement.setData({feature: feature});
feature.updateStyle();
previousFeature?.updateStyle();
if (feature.geometry.type === "Point") { if (feature.geometry.type === "Point") {
return; // Points bind there own popups return; // Points bind there own popups
} }
@ -267,7 +285,6 @@ export class FilteredLayer {
uiElement.Update(); uiElement.Update();
uiElement.Activate(); uiElement.Activate();
L.DomEvent.stop(e); // Marks the event as consumed L.DomEvent.stop(e); // Marks the event as consumed
}); });
} }
}); });

View file

@ -8,6 +8,7 @@ import {Basemap} from "./Leaflet/Basemap";
export class LayerUpdater { export class LayerUpdater {
private _map: Basemap; private _map: Basemap;
private _layers: FilteredLayer[]; private _layers: FilteredLayer[];
private widenFactor: number;
public readonly runningQuery: UIEventSource<boolean> = new UIEventSource<boolean>(false); public readonly runningQuery: UIEventSource<boolean> = new UIEventSource<boolean>(false);
public readonly retries: UIEventSource<number> = new UIEventSource<number>(0); public readonly retries: UIEventSource<number> = new UIEventSource<number>(0);
@ -27,7 +28,9 @@ export class LayerUpdater {
*/ */
constructor(map: Basemap, constructor(map: Basemap,
minzoom: number, minzoom: number,
widenFactor: number,
layers: FilteredLayer[]) { layers: FilteredLayer[]) {
this.widenFactor = widenFactor;
this._map = map; this._map = map;
this._layers = layers; this._layers = layers;
this._minzoom = minzoom; this._minzoom = minzoom;
@ -97,7 +100,7 @@ export class LayerUpdater {
const bounds = this._map.map.getBounds(); const bounds = this._map.map.getBounds();
const diff =0.07; const diff = this.widenFactor;
const n = bounds.getNorth() + diff; const n = bounds.getNorth() + diff;
const e = bounds.getEast() + diff; const e = bounds.getEast() + diff;

View file

@ -91,6 +91,8 @@ export class OsmConnection {
} }
self.UpdatePreferences(); self.UpdatePreferences();
self.CheckForMessagesContinuously();
// details is an XML DOM of user details // details is an XML DOM of user details
let userInfo = details.getElementsByTagName("user")[0]; let userInfo = details.getElementsByTagName("user")[0];
@ -120,9 +122,21 @@ export class OsmConnection {
data.unreadMessages = parseInt(messages.getAttribute("unread")); data.unreadMessages = parseInt(messages.getAttribute("unread"));
data.totalMessages = parseInt(messages.getAttribute("count")); data.totalMessages = parseInt(messages.getAttribute("count"));
self.userDetails.ping(); 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 * All elements with class 'activate-osm-authentication' are loaded and get an 'onclick' to authenticate
*/ */

View file

@ -52,6 +52,7 @@ export class MoreScreen extends UIElement {
return new VerticalCombine([ return new VerticalCombine([
tr.intro, tr.intro,
tr.requestATheme,
new VerticalCombine(els), new VerticalCombine(els),
tr.streetcomplete tr.streetcomplete
]).Render(); ]).Render();

View file

@ -924,6 +924,12 @@ export default class Translations {
fr: "<h3>Plus de thème </h3>Vous aimez collecter des données? <br/>Il y a plus de thèmes disponible.", fr: "<h3>Plus de thème </h3>Vous aimez collecter des données? <br/>Il y a plus de thèmes disponible.",
nl: "<h3>Meer thema's</h3>Vind je het leuk om geodata te verzamelen? <br/> Hier vind je meer opties." nl: "<h3>Meer thema's</h3>Vind je het leuk om geodata te verzamelen? <br/> Hier vind je meer opties."
}), }),
requestATheme: new T({
en: "If you want a custom-built quest, request it <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>here</a>",
nl: "Wil je een eigen kaartthema, vraag dit <a href='https://github.com/pietervdvn/MapComplete/issues' target='_blank'>hier aan</a>"
}),
streetcomplete: new T({ streetcomplete: new T({
en: "Another, similar application is <a href='https://play.google.com/store/apps/details?id=de.westnordost.streetcomplete' target='_blank'>StreetComplete</a>", en: "Another, similar application is <a href='https://play.google.com/store/apps/details?id=de.westnordost.streetcomplete' target='_blank'>StreetComplete</a>",
fr: "Une autre application similaire est <a href='https://play.google.com/store/apps/details?id=de.westnordost.streetcomplete' target='_blank'>StreetComplete</a>", fr: "Une autre application similaire est <a href='https://play.google.com/store/apps/details?id=de.westnordost.streetcomplete' target='_blank'>StreetComplete</a>",

View file

@ -54,6 +54,10 @@ form {
display: block; display: block;
} }
.selected-element {
fill: black
}
/**************** GENERIC ****************/ /**************** GENERIC ****************/
.uielement { .uielement {

View file

@ -186,7 +186,7 @@ const bm = new Basemap("leafletDiv", locationControl, new VariableUiElement(
const layerSetup = InitUiElements.InitLayers(layoutToUse, osmConnection, changes, allElements, bm, fullScreenMessage, selectedElement); 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 -------- // --------------- Setting up layer selection ui --------