forked from MapComplete/MapComplete
		
	Properly render a downloaded way, fix #297
This commit is contained in:
		
							parent
							
								
									9cb591dfc3
								
							
						
					
					
						commit
						8aa830f15e
					
				
					 4 changed files with 218 additions and 5 deletions
				
			
		|  | @ -130,7 +130,7 @@ export abstract class OsmObject { | ||||||
|                     osmObject.SaveExtraData(element, []) |                     osmObject.SaveExtraData(element, []) | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
|             osmObject.LoadData(element) |             osmObject?.LoadData(element) | ||||||
|             objects.push(osmObject) |             objects.push(osmObject) | ||||||
|         } |         } | ||||||
|         return objects; |         return objects; | ||||||
|  | @ -321,7 +321,15 @@ export class OsmWay extends OsmObject { | ||||||
|         let latSum = 0 |         let latSum = 0 | ||||||
|         let lonSum = 0 |         let lonSum = 0 | ||||||
| 
 | 
 | ||||||
|  |         console.log("element is", element, "nodes are", allNodes) | ||||||
|  | 
 | ||||||
|  |         const nodeDict = new Map<number, OsmNode>() | ||||||
|         for (const node of allNodes) { |         for (const node of allNodes) { | ||||||
|  |             nodeDict.set(node.id, node) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         for (const nodeId of element.nodes) { | ||||||
|  |             const node = nodeDict.get(nodeId) | ||||||
|             const cp = node.centerpoint(); |             const cp = node.centerpoint(); | ||||||
|             this.coordinates.push(cp); |             this.coordinates.push(cp); | ||||||
|             latSum = cp[0] |             latSum = cp[0] | ||||||
|  | @ -338,11 +346,19 @@ export class OsmWay extends OsmObject { | ||||||
|             "type": "Feature", |             "type": "Feature", | ||||||
|             "properties": this.tags, |             "properties": this.tags, | ||||||
|             "geometry": { |             "geometry": { | ||||||
|                 "type": "LineString", |                 "type": this.isPolygon() ? "Polygon" : "LineString", | ||||||
|                 "coordinates": this.coordinates.map(c => [c[1], c[0]]) |                 "coordinates": this.coordinates.map(c => [c[1], c[0]]) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     private isPolygon(): boolean { | ||||||
|  |         if (this.coordinates[0] !== this.coordinates[this.coordinates.length - 1]) { | ||||||
|  |             return false; // Not closed
 | ||||||
|  |         } | ||||||
|  |         return Utils.isPolygon(this.tags) | ||||||
|  | 
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class OsmRelation extends OsmObject { | export class OsmRelation extends OsmObject { | ||||||
|  |  | ||||||
							
								
								
									
										43
									
								
								Utils.ts
									
										
									
									
									
								
							
							
						
						
									
										43
									
								
								Utils.ts
									
										
									
									
									
								
							|  | @ -1,4 +1,5 @@ | ||||||
| import * as colors from "./assets/colors.json" | import * as colors from "./assets/colors.json" | ||||||
|  | import * as polygon_features from "./assets/polygon-features.json" | ||||||
| 
 | 
 | ||||||
| export class Utils { | export class Utils { | ||||||
| 
 | 
 | ||||||
|  | @ -8,11 +9,30 @@ export class Utils { | ||||||
|      * This is a workaround and yet another hack |      * This is a workaround and yet another hack | ||||||
|      */ |      */ | ||||||
|     public static runningFromConsole = false; |     public static runningFromConsole = false; | ||||||
| 
 |  | ||||||
|     public static readonly assets_path = "./assets/svg/"; |     public static readonly assets_path = "./assets/svg/"; | ||||||
|  |     // Empty
 | ||||||
|  |     private static polygonFeatures = Utils.constructPolygonFeatures() | ||||||
|     private static knownKeys = ["addExtraTags", "and", "calculatedTags", "changesetmessage", "clustering", "color", "condition", "customCss", "dashArray", "defaultBackgroundId", "description", "descriptionTail", "doNotDownload", "enableAddNewPoints", "enableBackgroundLayerSelection", "enableGeolocation", "enableLayers", "enableMoreQuests", "enableSearch", "enableShareScreen", "enableUserBadge", "freeform", "hideFromOverview", "hideInAnswer", "icon", "iconOverlays", "iconSize", "id", "if", "ifnot", "isShown", "key", "language", "layers", "lockLocation", "maintainer", "mappings", "maxzoom", "maxZoom", "minNeededElements", "minzoom", "multiAnswer", "name", "or", "osmTags", "passAllFeatures", "presets", "question", "render", "roaming", "roamingRenderings", "rotation", "shortDescription", "socialImage", "source", "startLat", "startLon", "startZoom", "tagRenderings", "tags", "then", "title", "titleIcons", "type", "version", "wayHandling", "widenFactor", "width"] |     private static knownKeys = ["addExtraTags", "and", "calculatedTags", "changesetmessage", "clustering", "color", "condition", "customCss", "dashArray", "defaultBackgroundId", "description", "descriptionTail", "doNotDownload", "enableAddNewPoints", "enableBackgroundLayerSelection", "enableGeolocation", "enableLayers", "enableMoreQuests", "enableSearch", "enableShareScreen", "enableUserBadge", "freeform", "hideFromOverview", "hideInAnswer", "icon", "iconOverlays", "iconSize", "id", "if", "ifnot", "isShown", "key", "language", "layers", "lockLocation", "maintainer", "mappings", "maxzoom", "maxZoom", "minNeededElements", "minzoom", "multiAnswer", "name", "or", "osmTags", "passAllFeatures", "presets", "question", "render", "roaming", "roamingRenderings", "rotation", "shortDescription", "socialImage", "source", "startLat", "startLon", "startZoom", "tagRenderings", "tags", "then", "title", "titleIcons", "type", "version", "wayHandling", "widenFactor", "width"] | ||||||
|     private static extraKeys = ["nl", "en", "fr", "de", "pt", "es", "name", "phone", "email", "amenity", "leisure", "highway", "building", "yes", "no", "true", "false"] |     private static extraKeys = ["nl", "en", "fr", "de", "pt", "es", "name", "phone", "email", "amenity", "leisure", "highway", "building", "yes", "no", "true", "false"] | ||||||
| 
 | 
 | ||||||
|  |     public static isPolygon(tags: any): boolean { | ||||||
|  |         for (const tagsKey in tags) { | ||||||
|  |             if (!tags.hasOwnProperty(tagsKey)) { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             const polyGuide = Utils.polygonFeatures.get(tagsKey) | ||||||
|  |             if (polyGuide === undefined) { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             if ((polyGuide.values === null)) { | ||||||
|  |                 // We match all
 | ||||||
|  |                 return !polyGuide.blacklist | ||||||
|  |             } | ||||||
|  |             // is the key contained?
 | ||||||
|  |             return polyGuide.values.has(tags[tagsKey]) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     static EncodeXmlValue(str) { |     static EncodeXmlValue(str) { | ||||||
|         if (typeof str !== "string") { |         if (typeof str !== "string") { | ||||||
|             str = "" + str |             str = "" + str | ||||||
|  | @ -161,7 +181,7 @@ export class Utils { | ||||||
| 
 | 
 | ||||||
|     static Merge(source: any, target: any) { |     static Merge(source: any, target: any) { | ||||||
|         for (const key in source) { |         for (const key in source) { | ||||||
|             if(!source.hasOwnProperty(key)){ |             if (!source.hasOwnProperty(key)) { | ||||||
|                 continue |                 continue | ||||||
|             } |             } | ||||||
|             const sourceV = source[key]; |             const sourceV = source[key]; | ||||||
|  | @ -326,6 +346,25 @@ export class Utils { | ||||||
|         return bestColor ?? hex; |         return bestColor ?? hex; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private static constructPolygonFeatures(): Map<string, { values: Set<string>, blacklist: boolean }> { | ||||||
|  |         const result = new Map<string, { values: Set<string>, blacklist: boolean }>(); | ||||||
|  | 
 | ||||||
|  |         for (const polygonFeature of polygon_features) { | ||||||
|  |             const key = polygonFeature.key; | ||||||
|  | 
 | ||||||
|  |             if (polygonFeature.polygon === "all") { | ||||||
|  |                 result.set(key, {values: null, blacklist: false}) | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             const blacklist = polygonFeature.polygon === "blacklist" | ||||||
|  |             result.set(key, {values: new Set<string>(polygonFeature.values), blacklist: blacklist}) | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private static tile2long(x, z) { |     private static tile2long(x, z) { | ||||||
|         return (x / Math.pow(2, z) * 360 - 180); |         return (x / Math.pow(2, z) * 360 - 180); | ||||||
|     } |     } | ||||||
|  |  | ||||||
							
								
								
									
										157
									
								
								assets/polygon-features.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								assets/polygon-features.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | [ | ||||||
|  |     { | ||||||
|  |         "key": "building", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "highway", | ||||||
|  |         "polygon": "whitelist", | ||||||
|  |         "values": [ | ||||||
|  |             "services", | ||||||
|  |             "rest_area", | ||||||
|  |             "escape", | ||||||
|  |             "elevator" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "natural", | ||||||
|  |         "polygon": "blacklist", | ||||||
|  |         "values": [ | ||||||
|  |             "coastline", | ||||||
|  |             "cliff", | ||||||
|  |             "ridge", | ||||||
|  |             "arete", | ||||||
|  |             "tree_row" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "landuse", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "waterway", | ||||||
|  |         "polygon": "whitelist", | ||||||
|  |         "values": [ | ||||||
|  |             "riverbank", | ||||||
|  |             "dock", | ||||||
|  |             "boatyard", | ||||||
|  |             "dam" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "amenity", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "leisure", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "barrier", | ||||||
|  |         "polygon": "whitelist", | ||||||
|  |         "values": [ | ||||||
|  |             "city_wall", | ||||||
|  |             "ditch", | ||||||
|  |             "hedge", | ||||||
|  |             "retaining_wall", | ||||||
|  |             "wall", | ||||||
|  |             "spikes" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "railway", | ||||||
|  |         "polygon": "whitelist", | ||||||
|  |         "values": [ | ||||||
|  |             "station", | ||||||
|  |             "turntable", | ||||||
|  |             "roundhouse", | ||||||
|  |             "platform" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "area", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "boundary", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "man_made", | ||||||
|  |         "polygon": "blacklist", | ||||||
|  |         "values": [ | ||||||
|  |             "cutline", | ||||||
|  |             "embankment", | ||||||
|  |             "pipeline" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "power", | ||||||
|  |         "polygon": "whitelist", | ||||||
|  |         "values": [ | ||||||
|  |             "plant", | ||||||
|  |             "substation", | ||||||
|  |             "generator", | ||||||
|  |             "transformer" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "place", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "shop", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "aeroway", | ||||||
|  |         "polygon": "blacklist", | ||||||
|  |         "values": [ | ||||||
|  |             "taxiway" | ||||||
|  |         ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "tourism", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "historic", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "public_transport", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "office", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "building:part", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "military", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "ruins", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "area:highway", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "craft", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "golf", | ||||||
|  |         "polygon": "all" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |         "key": "indoor", | ||||||
|  |         "polygon": "all" | ||||||
|  |     } | ||||||
|  | ] | ||||||
|  | @ -12,6 +12,7 @@ | ||||||
|     "test": "ts-node test/TestAll.ts", |     "test": "ts-node test/TestAll.ts", | ||||||
|     "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", |     "init": "npm ci && npm run generate && npm run generate:editor-layer-index && npm run generate:layouts && npm run clean", | ||||||
|     "generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json", |     "generate:editor-layer-index": "cd assets/ && wget https://osmlab.github.io/editor-layer-index/imagery.geojson --output-document=editor-layer-index.json", | ||||||
|  |     "generate:polygon-features": "cd assets/ && wget https://raw.githubusercontent.com/tyrasd/osm-polygon-features/master/polygon-features.json --output-document=polygon-features.json", | ||||||
|     "generate:images": "ts-node scripts/generateIncludedImages.ts", |     "generate:images": "ts-node scripts/generateIncludedImages.ts", | ||||||
|     "generate:translations": "ts-node scripts/generateTranslations.ts", |     "generate:translations": "ts-node scripts/generateTranslations.ts", | ||||||
|     "generate:layouts": "ts-node scripts/generateLayouts.ts", |     "generate:layouts": "ts-node scripts/generateLayouts.ts", | ||||||
|  | @ -27,7 +28,7 @@ | ||||||
|     "reset:layeroverview": "echo '{\"layers\":[], \"themes\":[]}' > ./assets/generated/known_layers_and_themes.json", |     "reset:layeroverview": "echo '{\"layers\":[], \"themes\":[]}' > ./assets/generated/known_layers_and_themes.json", | ||||||
|     "generate": "mkdir -p ./assets/generated && npm run reset:layeroverview && npm run generate:images && npm run generate:translations && npm run generate:licenses && npm run generate:licenses && npm run generate:layeroverview", |     "generate": "mkdir -p ./assets/generated && npm run reset:layeroverview && npm run generate:images && npm run generate:translations && npm run generate:licenses && npm run generate:licenses && npm run generate:layeroverview", | ||||||
|     "build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", |     "build": "rm -rf dist/ && npm run generate && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", | ||||||
|     "prepare-deploy": "npm run generate && npm run test && npm run generate:editor-layer-index && npm run generate:layeroverview && npm run generate:layouts && npm run build && rm -rf .cache && npm run generate:docs", |     "prepare-deploy": "npm run generate:contributor-list && npm run generate && npm run test && npm run generate:editor-layer-index && npm run generate:layeroverview && npm run generate:layouts && npm run build && rm -rf .cache && npm run generate:docs", | ||||||
|     "deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", |     "deploy:staging": "npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/Staging/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/Staging/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", | ||||||
|     "deploy:pietervdvn": "cd /home/pietervdvn/git/pietervdvn.github.io/ && git pull && cd - && npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", |     "deploy:pietervdvn": "cd /home/pietervdvn/git/pietervdvn.github.io/ && git pull && cd - && npm run prepare-deploy && rm -rf /home/pietervdvn/git/pietervdvn.github.io/MapComplete/* && cp -r dist/* /home/pietervdvn/git/pietervdvn.github.io/MapComplete/ && cd /home/pietervdvn/git/pietervdvn.github.io/ && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean", | ||||||
|     "deploy:production": "cd /home/pietervdvn/git/pietervdvn.github.io/ && git pull && cd - && rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME  && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean && npm run gittag", |     "deploy:production": "cd /home/pietervdvn/git/pietervdvn.github.io/ && git pull && cd - && rm -rf ./assets/generated && npm run prepare-deploy && npm run optimize-images && rm -rf /home/pietervdvn/git/mapcomplete.github.io/* && cp -r dist/* /home/pietervdvn/git/mapcomplete.github.io/ && cd /home/pietervdvn/git/mapcomplete.github.io/ && echo \"mapcomplete.osm.be\" > CNAME  && git add * && git commit -m 'New MapComplete Version' && git push && cd - && npm run clean && npm run gittag", | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue