forked from MapComplete/MapComplete
		
	Various small fixes
This commit is contained in:
		
							parent
							
								
									261cde3e28
								
							
						
					
					
						commit
						1af5e44ad4
					
				
					 6 changed files with 176 additions and 20 deletions
				
			
		|  | @ -7,7 +7,6 @@ import FeatureSource from "../FeatureSource"; | |||
| import PointRenderingConfig from "../../../Models/ThemeConfig/PointRenderingConfig"; | ||||
| import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"; | ||||
| 
 | ||||
| 
 | ||||
| export default class RenderingMultiPlexerFeatureSource { | ||||
|     public readonly features: UIEventSource<(any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[]>; | ||||
| 
 | ||||
|  | @ -29,7 +28,7 @@ export default class RenderingMultiPlexerFeatureSource { | |||
| 
 | ||||
|                 const lineRenderObjects = layer.lineRendering | ||||
| 
 | ||||
|                 const withIndex: (any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined })[] = []; | ||||
|                 const withIndex: (any & { pointRenderingIndex: number | undefined, lineRenderingIndex: number | undefined, multiLineStringIndex: number | undefined })[] = []; | ||||
| 
 | ||||
| 
 | ||||
|                 function addAsPoint(feat, rendering, coordinate) { | ||||
|  | @ -69,11 +68,18 @@ export default class RenderingMultiPlexerFeatureSource { | |||
|                                 const coordinate = coordinates[coordinates.length - 1] | ||||
|                                 addAsPoint(feat, rendering, coordinate) | ||||
|                             } | ||||
|                             for (let i = 0; i < lineRenderObjects.length; i++) { | ||||
|                                 withIndex.push({ | ||||
|                                     ...feat, | ||||
|                                     lineRenderingIndex: i | ||||
|                                 }) | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
|                         if (feat.geometry.type === "MultiLineString") { | ||||
|                             const lineList = feat.geometry.coordinates | ||||
|                             for (const coordinates of lineList) { | ||||
|                             const lineList: [number, number][][] = feat.geometry.coordinates | ||||
|                             for (let i1 = 0; i1 < lineList.length; i1++) { | ||||
|                                 const coordinates = lineList[i1]; | ||||
| 
 | ||||
|                                 for (const rendering of startRenderings) { | ||||
|                                     const coordinate = coordinates[0] | ||||
|  | @ -83,19 +89,25 @@ export default class RenderingMultiPlexerFeatureSource { | |||
|                                     const coordinate = coordinates[coordinates.length - 1] | ||||
|                                     addAsPoint(feat, rendering, coordinate) | ||||
|                                 } | ||||
| 
 | ||||
| 
 | ||||
|                                 for (let i = 0; i < lineRenderObjects.length; i++) { | ||||
|                                     const orig = { | ||||
|                                         ...feat, | ||||
|                                         lineRenderingIndex: i, | ||||
|                                         multiLineStringIndex: i1 | ||||
|                                     } | ||||
|                                     orig.geometry.coordinates = coordinates | ||||
|                                     orig.geometry.type = "LineString" | ||||
|                                     withIndex.push(orig) | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
| 
 | ||||
| 
 | ||||
|                         for (let i = 0; i < lineRenderObjects.length; i++) { | ||||
|                             withIndex.push({ | ||||
|                                 ...feat, | ||||
|                                 lineRenderingIndex: i | ||||
|                             }) | ||||
|                         } | ||||
| 
 | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|                 return withIndex; | ||||
|             } | ||||
|         ); | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ import {BBox} from "./BBox"; | |||
| import togpx from "togpx" | ||||
| import Constants from "../Models/Constants"; | ||||
| import LayerConfig from "../Models/ThemeConfig/LayerConfig"; | ||||
| import {meta} from "@turf/turf"; | ||||
| 
 | ||||
| export class GeoOperations { | ||||
| 
 | ||||
|  | @ -465,6 +464,151 @@ export class GeoOperations { | |||
|         }) | ||||
|     } | ||||
|      | ||||
|     public static IdentifieCommonSegments(coordinatess: [number,number][][] ): { | ||||
|         originalIndex: number, | ||||
|         segmentShardWith: number[], | ||||
|         coordinates: [] | ||||
|     }[]{ | ||||
|          | ||||
|         // An edge. Note that the edge might be reversed to fix the sorting condition:  start[0] < end[0] && (start[0] != end[0] || start[0] < end[1])
 | ||||
|         type edge = {start: [number, number], end: [number, number], intermediate: [number,number][], members: {index:number, isReversed: boolean}[]} | ||||
| 
 | ||||
|         // The strategy:
 | ||||
|         // 1. Index _all_ edges from _every_ linestring. Index them by starting key, gather which relations run over them
 | ||||
|         // 2. Join these edges back together - as long as their membership groups are the same
 | ||||
|         // 3. Convert to results
 | ||||
|          | ||||
|         const allEdgesByKey = new Map<string, edge>() | ||||
| 
 | ||||
|         for (let index = 0; index < coordinatess.length; index++){ | ||||
|             const coordinates = coordinatess[index]; | ||||
|             for (let i = 0; i < coordinates.length - 1; i++){ | ||||
|                  | ||||
|                 const c0 = coordinates[i]; | ||||
|                 const c1 = coordinates[i + 1] | ||||
|                 const isReversed = (c0[0] > c1[0]) || (c0[0] == c1[0] && c0[1] > c1[1]) | ||||
|                  | ||||
|                 let key : string | ||||
|                 if(isReversed){ | ||||
|                     key = ""+c1+";"+c0 | ||||
|                 }else{ | ||||
|                     key = ""+c0+";"+c1 | ||||
|                 } | ||||
|                 const member = {index, isReversed} | ||||
|                 if(allEdgesByKey.has(key)){ | ||||
|                     allEdgesByKey.get(key).members.push(member) | ||||
|                     continue | ||||
|                 } | ||||
|                  | ||||
|                 let edge : edge; | ||||
|                 if(!isReversed){ | ||||
|                     edge = { | ||||
|                         start : c0, | ||||
|                         end: c1, | ||||
|                         members: [member], | ||||
|                         intermediate: [] | ||||
|                     } | ||||
|                 }else{ | ||||
|                     edge = { | ||||
|                         start : c1, | ||||
|                         end: c0, | ||||
|                         members: [member], | ||||
|                         intermediate: [] | ||||
|                     } | ||||
|                 } | ||||
|                 allEdgesByKey.set(key, edge) | ||||
|                  | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Lets merge them back together!
 | ||||
|          | ||||
|         let didMergeSomething = false; | ||||
|         let allMergedEdges = Array.from(allEdgesByKey.values()) | ||||
|         const allEdgesByStartPoint = new Map<string, edge[]>() | ||||
|         for (const edge of allMergedEdges) { | ||||
|              | ||||
|             edge.members.sort((m0, m1) => m0.index - m1.index) | ||||
|              | ||||
|             const kstart = edge.start+"" | ||||
|             if(!allEdgesByStartPoint.has(kstart)){ | ||||
|                 allEdgesByStartPoint.set(kstart, []) | ||||
|             } | ||||
|             allEdgesByStartPoint.get(kstart).push(edge) | ||||
|         } | ||||
|          | ||||
|          | ||||
|         function membersAreCompatible(first:edge, second:edge): boolean{ | ||||
|             // There must be an exact match between the members
 | ||||
|             if(first.members === second.members){ | ||||
|                 return true | ||||
|             } | ||||
|              | ||||
|             if(first.members.length !== second.members.length){ | ||||
|                 return false | ||||
|             } | ||||
|              | ||||
|             // Members are sorted and have the same length, so we can check quickly
 | ||||
|             for (let i = 0; i < first.members.length; i++) { | ||||
|                 const m0 = first.members[i] | ||||
|                 const m1 = second.members[i] | ||||
|                 if(m0.index !== m1.index || m0.isReversed !== m1.isReversed){ | ||||
|                     return false | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             // Allrigth, they are the same, lets mark this permanently
 | ||||
|             second.members = first.members | ||||
|             return true | ||||
|              | ||||
|         } | ||||
|          | ||||
|         do{ | ||||
|             didMergeSomething = false | ||||
|             // We use 'allMergedEdges' as our running list
 | ||||
|             const consumed = new Set<edge>() | ||||
|             for (const edge of allMergedEdges) { | ||||
|                 // Can we make this edge longer at the end?
 | ||||
|                 if(consumed.has(edge)){ | ||||
|                     continue | ||||
|                 } | ||||
|                  | ||||
|                 console.log("Considering edge", edge) | ||||
|                 const matchingEndEdges = allEdgesByStartPoint.get(edge.end+"")  | ||||
|                 console.log("Matchign endpoints:", matchingEndEdges) | ||||
|                 if(matchingEndEdges === undefined){ | ||||
|                     continue | ||||
|                 } | ||||
|                  | ||||
|                  | ||||
|                 for (let i = 0; i < matchingEndEdges.length; i++){ | ||||
|                     const endEdge = matchingEndEdges[i]; | ||||
|                      | ||||
|                     if(consumed.has(endEdge)){ | ||||
|                         continue | ||||
|                     } | ||||
|                      | ||||
|                     if(!membersAreCompatible(edge, endEdge)){ | ||||
|                         continue | ||||
|                     } | ||||
|                      | ||||
|                     // We can make the segment longer!
 | ||||
|                     didMergeSomething = true | ||||
|                     console.log("Merging ", edge, "with ", endEdge) | ||||
|                     edge.intermediate.push(edge.end) | ||||
|                     edge.end = endEdge.end | ||||
|                     consumed.add(endEdge) | ||||
|                     matchingEndEdges.splice(i, 1) | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             allMergedEdges = allMergedEdges.filter(edge => !consumed.has(edge)); | ||||
|              | ||||
|         }while(didMergeSomething) | ||||
|          | ||||
|         return [] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -55,7 +55,7 @@ export default class ScrollableFullScreen extends UIElement { | |||
|             if (!isShown.data) { | ||||
|                 return; | ||||
|             } | ||||
|             if (hash === undefined || hash === "") { | ||||
|             if (hash === undefined || hash === "" || hash !== hashToShow) { | ||||
|                 isShown.setData(false) | ||||
|             } | ||||
|         }) | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ export default class LocationInput extends InputElement<Loc> implements MinimapO | |||
|                 osmTags: {and: []} | ||||
|             }, | ||||
|             mapRendering: [{ | ||||
|                 location: ["point"], | ||||
|                 location: ["point","centroid"], | ||||
|                 icon: "./assets/svg/crosshair-empty.svg" | ||||
|             }] | ||||
|         }, "matchpoint icon", true | ||||
|  |  | |||
|  | @ -152,7 +152,7 @@ export default class ShowDataLayer { | |||
|                 continue | ||||
|             } | ||||
|             try { | ||||
|                 if ((feat.geometry.type === "LineString" || feat.geometry.type === "MultiLineString")) { | ||||
|                 if (feat.geometry.type === "LineString") { | ||||
|                     const self = this; | ||||
|                     const coords = L.GeoJSON.coordsToLatLngs(feat.geometry.coordinates) | ||||
|                     const tagsSource = this.allElements?.addOrGetElement(feat) ?? new UIEventSource<any>(feat.properties); | ||||
|  | @ -270,7 +270,7 @@ export default class ShowDataLayer { | |||
| 
 | ||||
|         let infobox: FeatureInfoBox = undefined; | ||||
| 
 | ||||
|         const id = `popup-${feature.properties.id}-${feature.geometry.type}-${this.showDataLayerid}-${this._cleanCount}-${feature.pointRenderingIndex ?? feature.lineRenderingIndex}` | ||||
|         const id = `popup-${feature.properties.id}-${feature.geometry.type}-${this.showDataLayerid}-${this._cleanCount}-${feature.pointRenderingIndex ?? feature.lineRenderingIndex}-${feature.multiLineStringIndex ?? ""}` | ||||
|         popup.setContent(`<div style='height: 65vh' id='${id}'>Popup for ${feature.properties.id} ${feature.geometry.type} ${id} is loading</div>`) | ||||
|         leafletLayer.on("popupopen", () => { | ||||
|             if (infobox === undefined) { | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
|     "osmTags": "user:location=yes", | ||||
|     "maxCacheAge": 0 | ||||
|   }, | ||||
|   "title": { | ||||
|   "#title": { | ||||
|     "render": "Your travelled path" | ||||
|   }, | ||||
|   "tagRenderings": [ | ||||
|  | @ -18,10 +18,10 @@ | |||
|     }, | ||||
|     "export_as_gpx" | ||||
|   ], | ||||
|   "name": "Your track", | ||||
|   "#name": "Your track", | ||||
|   "mapRendering": [ | ||||
|     { | ||||
|       "width": 3, | ||||
|       "width": 0, | ||||
|       "color": "#bb000077" | ||||
|     } | ||||
|   ] | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue