forked from MapComplete/MapComplete
		
	Add smoothness, add highlighting of a way
This commit is contained in:
		
							parent
							
								
									8af25a9cdf
								
							
						
					
					
						commit
						afaaaaadb1
					
				
					 12 changed files with 146 additions and 12 deletions
				
			
		|  | @ -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(), | ||||
|             */ | ||||
|         ]; | ||||
| 
 | ||||
|  |  | |||
|  | @ -69,6 +69,7 @@ export class LayerDefinition { | |||
|      */ | ||||
|     style: (tags: any) => { | ||||
|         color: string, | ||||
|         weight?: number, | ||||
|         icon: {  | ||||
|             iconUrl: string, | ||||
|             iconSize: number[], | ||||
|  |  | |||
|  | @ -171,7 +171,7 @@ export class Widths extends LayerDefinition { | |||
|             return { | ||||
|                 icon: null, | ||||
|                 color: c, | ||||
|                 weight: 7, | ||||
|                 weight: 10, | ||||
|                 dashArray: dashArray | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -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() | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
							
								
								
									
										81
									
								
								Customizations/Layouts/Smoothness.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								Customizations/Layouts/Smoothness.ts
									
										
									
									
									
										Normal 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; | ||||
|     } | ||||
| } | ||||
|  | @ -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
 | ||||
| 
 | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -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 | ||||
|      */ | ||||
|  |  | |||
|  | @ -52,6 +52,7 @@ export class MoreScreen extends UIElement { | |||
| 
 | ||||
|         return new VerticalCombine([ | ||||
|             tr.intro, | ||||
|             tr.requestATheme, | ||||
|             new VerticalCombine(els), | ||||
|             tr.streetcomplete | ||||
|         ]).Render(); | ||||
|  |  | |||
|  | @ -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>", | ||||
|  |  | |||
|  | @ -54,6 +54,10 @@ form { | |||
|     display: block; | ||||
| } | ||||
| 
 | ||||
| .selected-element { | ||||
|     fill: black | ||||
| } | ||||
| 
 | ||||
| /**************** GENERIC ****************/ | ||||
| 
 | ||||
| .uielement { | ||||
|  |  | |||
							
								
								
									
										2
									
								
								index.ts
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								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 --------
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue