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 {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(),
*/
];

View file

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

View file

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

View file

@ -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=<name>" 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()
}
}

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 _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
});
}
});

View file

@ -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<boolean> = new UIEventSource<boolean>(false);
public readonly retries: UIEventSource<number> = new UIEventSource<number>(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;

View file

@ -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
*/

View file

@ -52,6 +52,7 @@ export class MoreScreen extends UIElement {
return new VerticalCombine([
tr.intro,
tr.requestATheme,
new VerticalCombine(els),
tr.streetcomplete
]).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.",
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({
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>",

View file

@ -54,6 +54,10 @@ form {
display: block;
}
.selected-element {
fill: black
}
/**************** GENERIC ****************/
.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 layerUpdater = new LayerUpdater(bm, layerSetup.minZoom, layerSetup.flayers);
const layerUpdater = new LayerUpdater(bm, layerSetup.minZoom, layoutToUse.widenFactor, layerSetup.flayers);
// --------------- Setting up layer selection ui --------