forked from MapComplete/MapComplete
		
	Various small fixes, add AED-layout
This commit is contained in:
		
							parent
							
								
									cce9207a35
								
							
						
					
					
						commit
						734f571b5d
					
				
					 11 changed files with 1742 additions and 168 deletions
				
			
		|  | @ -170,25 +170,26 @@ export class CustomLayoutFromJSON { | ||||||
|         if (json === undefined) { |         if (json === undefined) { | ||||||
|             return undefined; |             return undefined; | ||||||
|         } |         } | ||||||
|         if (typeof (json) === "string") { |         if (typeof (json) !== "string") { | ||||||
|             let kv: string[] = undefined; |             return new Tag(json.k.trim(), json.v.trim()) | ||||||
|             let invert = false; |  | ||||||
|             if (json.indexOf("!=") >= 0) { |  | ||||||
|                 kv = json.split("!="); |  | ||||||
|                 invert = true; |  | ||||||
|             } else { |  | ||||||
|                 kv = json.split("="); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (kv.length !== 2) { |  | ||||||
|                 return undefined; |  | ||||||
|             } |  | ||||||
|             if (kv[0].trim() === "") { |  | ||||||
|                 return undefined; |  | ||||||
|             } |  | ||||||
|             return new Tag(kv[0].trim(), kv[1].trim(), invert); |  | ||||||
|         } |         } | ||||||
|         return new Tag(json.k.trim(), json.v.trim()) | 
 | ||||||
|  |         let kv: string[] = undefined; | ||||||
|  |         let invert = false; | ||||||
|  |         if (json.indexOf("!=") >= 0) { | ||||||
|  |             kv = json.split("!="); | ||||||
|  |             invert = true; | ||||||
|  |         } else { | ||||||
|  |             kv = json.split("="); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (kv.length !== 2) { | ||||||
|  |             return undefined; | ||||||
|  |         } | ||||||
|  |         if (kv[0].trim() === "") { | ||||||
|  |             return undefined; | ||||||
|  |         } | ||||||
|  |         return new Tag(kv[0].trim(), kv[1].trim(), invert); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static TagsFromJson(json: string | { k: string, v: string }[]): Tag[] { |     public static TagsFromJson(json: string | { k: string, v: string }[]): Tag[] { | ||||||
|  |  | ||||||
|  | @ -75,8 +75,6 @@ export class TagRendering extends UIElement implements TagDependantUIElement { | ||||||
|         this.ListenTo(this._editMode); |         this.ListenTo(this._editMode); | ||||||
|         this.ListenTo(State.state?.osmConnection?.userDetails); |         this.ListenTo(State.state?.osmConnection?.userDetails); | ||||||
| 
 | 
 | ||||||
|         console.log("Creating tagRendering with", options) |  | ||||||
| 
 |  | ||||||
|         const self = this; |         const self = this; | ||||||
|         |         | ||||||
|         this._priority = options.priority ?? 0; |         this._priority = options.priority ?? 0; | ||||||
|  |  | ||||||
|  | @ -312,7 +312,7 @@ export class OsmConnection { | ||||||
|             content: [`<osm><changeset>`, |             content: [`<osm><changeset>`, | ||||||
|                 `<tag k="created_by" v="MapComplete ${State.vNumber}" />`, |                 `<tag k="created_by" v="MapComplete ${State.vNumber}" />`, | ||||||
|                 `<tag k="comment" v="Adding data with #MapComplete"/>`, |                 `<tag k="comment" v="Adding data with #MapComplete"/>`, | ||||||
|                 `<tag k="theme" v="${layout.name}">`, |                 `<tag k="theme" v="${layout.name}"/>`, | ||||||
|                 layout.maintainer !== undefined ? `<tag k="theme-creator" v="${layout.maintainer}">` : "", |                 layout.maintainer !== undefined ? `<tag k="theme-creator" v="${layout.maintainer}">` : "", | ||||||
|                 `</changeset></osm>`].join("") |                 `</changeset></osm>`].join("") | ||||||
|         }, function (err, response) { |         }, function (err, response) { | ||||||
|  |  | ||||||
|  | @ -96,7 +96,7 @@ export class Tag extends TagsFilter { | ||||||
|                 } |                 } | ||||||
|                  |                  | ||||||
|                 if(this.value === tag.v){ |                 if(this.value === tag.v){ | ||||||
|                     return true; |                     return !this.invertValue; | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 return Tag.regexOrStrMatches(this.value, tag.v) !== this.invertValue |                 return Tag.regexOrStrMatches(this.value, tag.v) !== this.invertValue | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ import Locale from "./i18n/Locale"; | ||||||
| import {State} from "../State"; | import {State} from "../State"; | ||||||
| 
 | 
 | ||||||
| import {UIEventSource} from "../Logic/UIEventSource"; | import {UIEventSource} from "../Logic/UIEventSource"; | ||||||
|  | import {UserDetails} from "../Logic/Osm/OsmConnection"; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Asks to add a feature at the last clicked location, at least if zoom is sufficient |  * Asks to add a feature at the last clicked location, at least if zoom is sufficient | ||||||
|  | @ -49,13 +50,17 @@ export class SimpleAddUI extends UIElement { | ||||||
|             for (const preset of layer.layerDef.presets) { |             for (const preset of layer.layerDef.presets) { | ||||||
| 
 | 
 | ||||||
|                 let icon: string = "./assets/bug.svg"; |                 let icon: string = "./assets/bug.svg"; | ||||||
|                 if (typeof (preset.icon) !== "string") { |                 if (preset.icon !== undefined) { | ||||||
|                     console.log("Preset icon is:", preset.icon); | 
 | ||||||
|                     icon = preset.icon.GetContent(TagUtils.KVtoProperties(preset.tags)); |                     if (typeof (preset.icon) !== "string") { | ||||||
|                 } else { |                         console.log("Preset icon is:", preset.icon); | ||||||
|                     icon = preset.icon; |                         icon = preset.icon.GetContent(TagUtils.KVtoProperties(preset.tags)); | ||||||
|  |                     } else { | ||||||
|  |                         icon = preset.icon; | ||||||
|  |                     } | ||||||
|  |                 }else{ | ||||||
|  |                     console.warn("No icon defined for preset ", preset, "in layer ",layer.layerDef.id) | ||||||
|                 } |                 } | ||||||
|                 console.log("Preset icon:", icon) |  | ||||||
| 
 | 
 | ||||||
|                 const button = |                 const button = | ||||||
|                     new SubtleButton( |                     new SubtleButton( | ||||||
|  |  | ||||||
|  | @ -605,50 +605,6 @@ export default class Translations { | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|         bookcases: { |  | ||||||
|             title: new T({en: "Open Bookcase Map", nl: "Open Boekenkastjes kaart"}, ), |  | ||||||
|             description: new T({ |  | ||||||
|                     en: "Search a bookcase near you and add information about them in the biggest shared map of the world.", |  | ||||||
|                     nl: "Help mee met het creëeren van een volledige kaart met alle boekenruilkastjes!" + |  | ||||||
|                         "Een boekenruilkastje is een vaste plaats in publieke ruimte waar iedereen een boek in kan zetten of uit kan meenemen." + |  | ||||||
|                         "Meestal een klein kastje of doosje dat op straat staat, maar ook een oude telefooncellen of een schap in een station valt hieronder." |  | ||||||
|                 } |  | ||||||
|             ), |  | ||||||
|             bookcase: new T({ |  | ||||||
|                 nl: "Boekenruilkastje", |  | ||||||
|                 en: "Public bookcase" |  | ||||||
|             }), |  | ||||||
|             questions: { |  | ||||||
|                 hasName: new T( |  | ||||||
|                     { |  | ||||||
|                         nl: "Heeft dit boekenruilkastje een naam?", |  | ||||||
|                         en: "Does this bookcase have a name?" |  | ||||||
|                     }), |  | ||||||
|                 noname: new T({ |  | ||||||
|                         nl: "Neen, er is geen naam aangeduid op het boekenruilkastje", |  | ||||||
|                         en: "No, there is no clearly visible name on the public bookcase" |  | ||||||
|                     }, |  | ||||||
|                 ), |  | ||||||
|                 capacity: new T({ |  | ||||||
|                     nl: "Hoeveel boeken passen in dit boekenruilkastje?", |  | ||||||
|                     en: "How much books fit into this public bookcase?" |  | ||||||
|                 }), |  | ||||||
|                 capacityRender: new T({ |  | ||||||
|                     nl: "Er passen {capacity} boeken in dit boekenruilkastje", |  | ||||||
|                     en: "{capacity} books fit in this bookcase" |  | ||||||
|                 }), |  | ||||||
|                 capacityInput: new T({ |  | ||||||
|                     nl: "Er passen $nat$ boeken in dit boekenruilkastje", |  | ||||||
|                     en: "$nat$ books fit into this public bookcase" |  | ||||||
|                 }), |  | ||||||
|                 bookkinds: new T({ |  | ||||||
|                     nl: "Wat voor soort boeken heeft dit boekenruilkastje?", |  | ||||||
|                     en: "What kind of books can be found in this public bookcase?" |  | ||||||
|                 }) |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         }, |  | ||||||
| 
 | 
 | ||||||
|         image: { |         image: { | ||||||
|             addPicture: new T({en: 'Add picture', nl: 'Voeg foto toe', fr: 'TODO: fr'}), |             addPicture: new T({en: 'Add picture', nl: 'Voeg foto toe', fr: 'TODO: fr'}), | ||||||
|  |  | ||||||
|  | @ -5,7 +5,7 @@ | ||||||
|   "startLat": "0", |   "startLat": "0", | ||||||
|   "startLon": "0", |   "startLon": "0", | ||||||
|   "startZoom": "12", |   "startZoom": "12", | ||||||
|   "maintainer": "Not logged in", |   "maintainer": "Pieter Vander Vennet", | ||||||
|   "layers": [ |   "layers": [ | ||||||
|     { |     { | ||||||
|       "id": "Defibrillator", |       "id": "Defibrillator", | ||||||
|  | @ -30,7 +30,57 @@ | ||||||
|           "description": "A defibrillator" |           "description": "A defibrillator" | ||||||
|         } |         } | ||||||
|       ], |       ], | ||||||
|       "tagRenderings": [], |       "tagRenderings": [ | ||||||
|  |         { | ||||||
|  |           "mappings": [ | ||||||
|  |             { | ||||||
|  |               "then": "This defibrillator is located indoors", | ||||||
|  |               "if": "indoor=yes" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "then": "This defibrillator is located outdoors", | ||||||
|  |               "if": "indoor=no" | ||||||
|  |             } | ||||||
|  |           ], | ||||||
|  |           "question": "Is this defibrillator located indoors?", | ||||||
|  |           "type": "text" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "mappings": [ | ||||||
|  |             { | ||||||
|  |               "then": "Publicly accessible", | ||||||
|  |               "if": "access=yes" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "then": "Only accessible to customers", | ||||||
|  |               "if": "access=customers" | ||||||
|  |             }, | ||||||
|  |             { | ||||||
|  |               "if": "access=private", | ||||||
|  |               "then": "Not accessible to the general public (e.g. only accesible to staff, the owners, ...)" | ||||||
|  |             } | ||||||
|  |           ], | ||||||
|  |           "question": "Is this defibrillator freely accessible", | ||||||
|  |           "type": "text", | ||||||
|  |           "key": "access", | ||||||
|  |           "condition": "indoor=yes" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "key": "level", | ||||||
|  |           "mappings": [], | ||||||
|  |           "question": "On which floor is this defibrillator located?", | ||||||
|  |           "type": "int", | ||||||
|  |           "render": "This defibrallator is on floor {level}", | ||||||
|  |           "condition": "indoor=yes&access!=private" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "key": "defibrillator:location", | ||||||
|  |           "mappings": [], | ||||||
|  |           "question": "Please give some explanation on where the defibrillator can be found", | ||||||
|  |           "type": "text", | ||||||
|  |           "render": "{defibrillator:location}" | ||||||
|  |         } | ||||||
|  |       ], | ||||||
|       "overpassTags": "emergency=defibrillator" |       "overpassTags": "emergency=defibrillator" | ||||||
|     } |     } | ||||||
|   ], |   ], | ||||||
|  |  | ||||||
							
								
								
									
										1695
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										1695
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
										
									
									
									
								
							|  | @ -3,7 +3,7 @@ | ||||||
|   "version": "0.0.5", |   "version": "0.0.5", | ||||||
|   "description": "A small website to edit OSM easily", |   "description": "A small website to edit OSM easily", | ||||||
|   "main": "index.js", |   "main": "index.js", | ||||||
|   "staticFiles": { |   "disabled:staticFiles": { | ||||||
|     "staticPath": [ |     "staticPath": [ | ||||||
|       { |       { | ||||||
|         "staticPath": "tiles", |         "staticPath": "tiles", | ||||||
|  | @ -12,11 +12,10 @@ | ||||||
|     ] |     ] | ||||||
|   }, |   }, | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "start": "parcel *.html UI/** Logic/** assets/** a vendor/* vendor/*/*", |     "start": "parcel *.html UI/** Logic/** assets/** vendor/* vendor/*/*", | ||||||
|     "generate": "ts-node createLayouts.ts", |     "generate": "ts-node createLayouts.ts", | ||||||
|     "build": "rm -rf dist/ && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", |     "build": "rm -rf dist/ && parcel build --public-url ./ *.html assets/** assets/**/** assets/**/**/** vendor/* vendor/*/*", | ||||||
|     "clean": "./clean.sh", |     "test": "ts-node test/*" | ||||||
|     "test": "echo \"Error: no test specified\" && exit 1" |  | ||||||
|   }, |   }, | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "OpenStreetMap", |     "OpenStreetMap", | ||||||
|  | @ -39,11 +38,14 @@ | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@babel/polyfill": "^7.10.4", |     "@babel/polyfill": "^7.10.4", | ||||||
|     "@types/node": "^7.0.5", |     "@types/node": "^7.0.5", | ||||||
|  |     "assert": "^2.0.0", | ||||||
|  |     "chai": "^4.2.0", | ||||||
|     "fs": "0.0.1-security", |     "fs": "0.0.1-security", | ||||||
|     "marked": "^1.1.1", |     "marked": "^1.1.1", | ||||||
|     "parcel-plugin-static-files-copy": "^2.4.3", |     "parcel-plugin-static-files-copy": "^2.4.3", | ||||||
|     "promise-svg2img": "^0.2.0", |     "promise-svg2img": "^0.2.0", | ||||||
|     "read-file": "^0.2.0", |     "read-file": "^0.2.0", | ||||||
|  |     "ts-node": "^9.0.0", | ||||||
|     "typescript": "^3.9.7", |     "typescript": "^3.9.7", | ||||||
|     "write-file": "^1.0.0" |     "write-file": "^1.0.0" | ||||||
|   } |   } | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								test.ts
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								test.ts
									
										
									
									
									
								
							|  | @ -1,4 +1,10 @@ | ||||||
| import {TextField, ValidatedTextField} from "./UI/Input/TextField"; | import {TextField, ValidatedTextField} from "./UI/Input/TextField"; | ||||||
|  | import {CustomLayoutFromJSON} from "./Customizations/JSON/CustomLayoutFromJSON"; | ||||||
|  | import {And} from "./Logic/TagsFilter"; | ||||||
| 
 | 
 | ||||||
| ValidatedTextField.TagTextField().AttachTo("maindiv") | const tags = CustomLayoutFromJSON.TagsFromJson("indoor=yes&access!=private"); | ||||||
|     .GetValue().addCallback(console.log); | console.log(tags); | ||||||
|  | const m0 = new And(tags).matches([{k:"indoor",v:"yes"}, {k:"access",v: "yes"}]); | ||||||
|  | console.log("Matches 0", m0) | ||||||
|  | const m1 = new And(tags).matches([{k:"indoor",v:"yes"}, {k:"access",v: "private"}]); | ||||||
|  | console.log("Matches 1", m1) | ||||||
							
								
								
									
										37
									
								
								test/Tag.spec.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test/Tag.spec.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | import {equal} from "assert"; | ||||||
|  | import {UIElement} from "../UI/UIElement"; | ||||||
|  | UIElement.runningFromConsole = true; | ||||||
|  | import {CustomLayoutFromJSON} from "../Customizations/JSON/CustomLayoutFromJSON"; | ||||||
|  | import {And} from "../Logic/TagsFilter"; | ||||||
|  | 
 | ||||||
|  | let failures = 0; | ||||||
|  | 
 | ||||||
|  | function t(descripiton: string, f: () => void) { | ||||||
|  | 
 | ||||||
|  |     try { | ||||||
|  |         f(); | ||||||
|  |     } catch (e) { | ||||||
|  |         failures++; | ||||||
|  |         console.warn(e); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function done() { | ||||||
|  |     if (failures == 0) { | ||||||
|  |         console.log("All tests done!") | ||||||
|  |     } else { | ||||||
|  |         console.warn(failures, "tests failedd :(") | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | t("Parse and match advanced tagging", () => { | ||||||
|  |     const tags = CustomLayoutFromJSON.TagsFromJson("indoor=yes&access!=private"); | ||||||
|  |     console.log(tags); | ||||||
|  |     const m0 = new And(tags).matches([{k: "indoor", v: "yes"}, {k: "access", v: "yes"}]); | ||||||
|  |     equal(m0, true); | ||||||
|  |     const m1 = new And(tags).matches([{k: "indoor", v: "yes"}, {k: "access", v: "private"}]); | ||||||
|  |     equal(m1, false); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | done(); | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue