forked from MapComplete/MapComplete
		
	Merge branch 'master' into develop
This commit is contained in:
		
						commit
						34e7233498
					
				
					 19 changed files with 706 additions and 46 deletions
				
			
		
							
								
								
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -49,3 +49,7 @@ error_changeset_* | |||
| public/*.webmanifest | ||||
| public/assets/generated/ | ||||
| public/assets/langs/* | ||||
| 
 | ||||
| android/ | ||||
| dist-full/ | ||||
| public/assets/icons/*.webp | ||||
|  |  | |||
|  | @ -596,10 +596,33 @@ | |||
|             "seeNearby": "Bilder in der Nähe durchsuchen", | ||||
|             "title": "Straßenbilder in der Nähe" | ||||
|         }, | ||||
|         "panoramax": { | ||||
|             "deletionRequested": "Der Bericht wurde abgeschickt. Ein Moderator wird sich in Kürze darum kümmern", | ||||
|             "freeform": "Gibt es weitere relevante Informationen?", | ||||
|             "otherFreeform": "Bitte gib an, warum dieses Bild entfernt werden soll:", | ||||
|             "placeholder": "Erkläre, warum das Bild gelöscht werden sollte", | ||||
|             "report": { | ||||
|                 "blur_excess": "Zu viel ist unscharf und macht das Bild unbrauchbar", | ||||
|                 "blur_missing": "Ein Gesicht oder Nummernschild ist auf diesem Bild nicht unscharf", | ||||
|                 "copyright": "Das Bild enthält urheberrechtlich geschützte Inhalte", | ||||
|                 "inappropriate": "Dieses Bild ist unangemessen (es enthält Nacktheit, ruft nach Hass oder ist nicht Streetview)", | ||||
|                 "mislocated": "Das Bild ist von einem anderen Ort", | ||||
|                 "other": "Ein weiterer Grund, bitte angeben", | ||||
|                 "picture_low_quality": "Das Bild ist von geringer Qualität", | ||||
|                 "privacy": "Das Bild zeigt eine private Immobilie" | ||||
|             }, | ||||
|             "requestDeletion": "Bildlöschung beantragen", | ||||
|             "title": "Warum sollte dieses Bild dauerhaft gelöscht werden?" | ||||
|         }, | ||||
|         "pleaseLogin": "Bitte anmelden, um ein Bild hinzuzufügen", | ||||
|         "processing": "Der Server verarbeitet das Bild", | ||||
|         "respectPrivacy": "Laden Sie keine Bilder von Google Maps, Google Streetview oder anderen urheberrechtlich geschützten Quellen hoch.", | ||||
|         "toBig": "Ihr Bild ist mit {actual_size} zu groß. Die maximale Bildgröße ist {max_size}", | ||||
|         "unlink": { | ||||
|             "button": "Bild entkoppeln", | ||||
|             "explanation": "Wenn du die Verknüpfung dieses Bildes aufhebst, wird das Bild nicht mehr mit diesem Objekt angezeigt. Es wird aber weiterhin in den Nachbarschaftsbildern und möglicherweise in anderen Objekten angezeigt.", | ||||
|             "title": "Dieses Bild entkoppeln?" | ||||
|         }, | ||||
|         "upload": { | ||||
|             "failReasons": "Keine Internetverbindung", | ||||
|             "failReasonsAdvanced": "Alternativ dazu können Sie einstellen, dass Ihr Browser und Ihre Erweiterungen die APIs von Drittanbietern nicht blockieren.", | ||||
|  | @ -898,4 +921,4 @@ | |||
|             "startsWithQ": "Ein Wikidata-Identifikator beginnt mit Q und wird von einer Zahl gefolgt" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								langs/el.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								langs/el.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {} | ||||
|  | @ -596,10 +596,33 @@ | |||
|             "seeNearby": "Ver imágenes cercanas", | ||||
|             "title": "Imágenes a nivel calle cercanas" | ||||
|         }, | ||||
|         "panoramax": { | ||||
|             "deletionRequested": "El informe ha sido enviado. Un moderador lo examinará en breve", | ||||
|             "freeform": "¿Hay alguna otra información pertinente?", | ||||
|             "otherFreeform": "Por favor, especifique por qué debe eliminarse esta imagen:", | ||||
|             "placeholder": "Explicar por qué la imagen debe ser eliminada", | ||||
|             "report": { | ||||
|                 "blur_excess": "Demasiado borrosa, haciendo la imagen inútil", | ||||
|                 "blur_missing": "Una cara o placa de matrícula no está borrosa en esta imagen", | ||||
|                 "copyright": "La imagen contiene contenido protegido por derechos de autor", | ||||
|                 "inappropriate": "Esta imagen es inapropiada (contiene desnudez, incita al odio o no es streetview)", | ||||
|                 "mislocated": "La imagen es de una ubicación diferente", | ||||
|                 "other": "Otra razón, por favor especifíquese", | ||||
|                 "picture_low_quality": "La imagen es de baja calidad", | ||||
|                 "privacy": "La imagen muestra una propiedad privada" | ||||
|             }, | ||||
|             "requestDeletion": "Solicitar la eliminación de una imagen", | ||||
|             "title": "¿Por qué debería esta imagen ser eliminada permanentemente?" | ||||
|         }, | ||||
|         "pleaseLogin": "Por favor, inicia sesión para agregar una imagen", | ||||
|         "processing": "El servidor está procesando tu imagen", | ||||
|         "respectPrivacy": "No subas imágenes de Google Maps, Google Street View u otras fuentes con derechos de autor.", | ||||
|         "toBig": "Tu imagen es demasiado grande, tiene {actual_size}. Por favor, usa imágenes de como máximo {max_size}", | ||||
|         "unlink": { | ||||
|             "button": "Desvincular imagen", | ||||
|             "explanation": "Al desvincular esta imagen, esta imagen ya no se mostrará con este objeto. Todavía aparecerá en las imágenes cercanas y posiblemente otros objetos.", | ||||
|             "title": "¿Desvincular esta imagen?" | ||||
|         }, | ||||
|         "upload": { | ||||
|             "failReasons": "Podrías haber perdido la conexión a internet", | ||||
|             "failReasonsAdvanced": "Alternativamente, asegúrate de que tu navegador y extensiones no bloqueen las API de terceros.", | ||||
|  | @ -781,7 +804,7 @@ | |||
|         "title": "{count} reseñas", | ||||
|         "title_singular": "Una reseña", | ||||
|         "too_long": "Se permiten como máximo {max} caracteres. Tu reseña tiene {amount} caracteres.", | ||||
|         "tos": "Si creas una reseña, aceptas <a href='https://mangrove.reviews/terms' target='_blank'>los T&C y la política de privacidad de Mangrove.reviews</a>", | ||||
|         "tos": "Si creas una revisión, aceptas <a href='https://mangrove.reviews/terms' target='_blank'>los TOS y la política de privacidad de Mangrove.reviews</a>", | ||||
|         "write_a_comment": "Deja una reseña…", | ||||
|         "your_reviews": "Tus reseñas anteriores", | ||||
|         "your_reviews_empty": "No pudimos encontrar ninguna de tus reseñas anteriores" | ||||
|  | @ -898,4 +921,4 @@ | |||
|             "startsWithQ": "Un identificador de Wikidata comienza con Q y le sigue un número" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -596,10 +596,33 @@ | |||
|             "seeNearby": "Közeli képek böngészése", | ||||
|             "title": "Közeli utcakép" | ||||
|         }, | ||||
|         "panoramax": { | ||||
|             "deletionRequested": "A jelentés be lett küldve; egy moderátor rövidesen megvizsgálja", | ||||
|             "freeform": "Van-e további lényeges információ?", | ||||
|             "otherFreeform": "Írd le, miért kellene eltávolítani ezt a képet:", | ||||
|             "placeholder": "Fejtsd ki, miért kellene törölni ezt a képet", | ||||
|             "report": { | ||||
|                 "blur_excess": "A kép használhatatlan, mert túl nagy része homályos", | ||||
|                 "blur_missing": "A képen nincs elhomályosítva egy arc vagy egy rendszámtábla", | ||||
|                 "copyright": "A kép szerzői jog hatálya alá tartozó tartalmat jelenít meg", | ||||
|                 "inappropriate": "A kép nem megfelelő (meztelenséget tartalmaz, gyűlöletre hív vagy nem utcakép)", | ||||
|                 "mislocated": "A kép egy másik helyet ábrázol", | ||||
|                 "other": "Más ok, kérjük, fejtsd ki", | ||||
|                 "picture_low_quality": "A kép gyatra minőségű", | ||||
|                 "privacy": "A kép magánterületet ábrázol" | ||||
|             }, | ||||
|             "requestDeletion": "Képtörlés kérése", | ||||
|             "title": "Miért kellene ezt a képet véglegesen törölni?" | ||||
|         }, | ||||
|         "pleaseLogin": "Kép hozzáadásához be kell jelentkezni", | ||||
|         "processing": "A szerver feldolgozza a képet", | ||||
|         "respectPrivacy": "Ne tölts fel képet a Google térképről, a Google Streetview-ról (utcaképről) és egyéb szerzői jog által védett forrásokból.", | ||||
|         "toBig": "A kép túl nagy ({actual_size}). Kérjük, legfeljebb {max_size} méretű képeket használj", | ||||
|         "unlink": { | ||||
|             "button": "Kép leválasztása", | ||||
|             "explanation": "A kép belinkeltségének feloldásával ez a kép nem jelenik meg többé ezzel az objektummal együtt. A közeli képek között és esetleg más objektumokban azonban továbbra is meg fog jelenni.", | ||||
|             "title": "Megszűnjék a kép belinkelése?" | ||||
|         }, | ||||
|         "upload": { | ||||
|             "failReasons": "Lehet, hogy megszakadt az internetkapcsolatod", | ||||
|             "failReasonsAdvanced": "Másik lehetőségként győződj meg arról, hogy a böngésződ vagy bővítményei nem blokkolnak-e harmadik féltől származó API-kat.", | ||||
|  | @ -898,4 +921,4 @@ | |||
|             "startsWithQ": "A Wikidata-azonosító Q-val kezdődik, amelyet egy szám követ" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -9594,4 +9594,4 @@ | |||
|             "render": "Turbina eòlica" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -10187,4 +10187,4 @@ | |||
|             "render": "větrná turbína" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1492,6 +1492,17 @@ | |||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "automated": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Dies ist eine manuelle Fahrradwaschanlage" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Dies ist eine automatische Fahrradwaschanlage" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Ist dieser Fahrradreinigungsdienst automatisiert?" | ||||
|             }, | ||||
|             "bike_cleaning-charge": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|  | @ -1515,6 +1526,17 @@ | |||
|                 }, | ||||
|                 "question": "Wie viel kostet die Nutzung des Reinigungsdienstes?", | ||||
|                 "render": "Der Reinigungsservice kostet {service:bicycle:cleaning:charge}" | ||||
|             }, | ||||
|             "self_service": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Die Reinigung erfolgt selbständig" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Dieser Reinigungsdienst wird von einem Angestellten betrieben" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Muss die Reinigung selbständig erfolgen?" | ||||
|             } | ||||
|         }, | ||||
|         "title": { | ||||
|  | @ -3208,6 +3230,10 @@ | |||
|             "1": { | ||||
|                 "description": "Eine öffentlich sichtbare Uhr an einer Wand", | ||||
|                 "title": "eine an der Wand montierte Uhr" | ||||
|             }, | ||||
|             "2": { | ||||
|                 "description": "Eine öffentlich sichtbare Uhr, die direkt an einer Wand angebracht ist", | ||||
|                 "title": "eine Wanduhr, die direkt an der Wand angebracht ist" | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|  | @ -3288,13 +3314,29 @@ | |||
|                 }, | ||||
|                 "question": "Zeigt diese Uhr auch die Luftfeuchtigkeit an?" | ||||
|             }, | ||||
|             "indoor": { | ||||
|                 "override": { | ||||
|                     "mappings": { | ||||
|                         "0": { | ||||
|                             "then": "Diese Uhr befindet sich in Innenräumen" | ||||
|                         }, | ||||
|                         "1": { | ||||
|                             "then": "Diese Uhr ist im Freien" | ||||
|                         } | ||||
|                     }, | ||||
|                     "question": "Befindet sich diese Uhr in Innenräumen?" | ||||
|                 } | ||||
|             }, | ||||
|             "support": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese Uhr ist auf einem Mast montiert" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Diese Uhr ist an einer Wand montiert" | ||||
|                         "then": "Diese Uhr wird an der Wand befestigt, in der Regel durch einen Träger, der senkrecht zur Wand steht" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Diese Uhr ist direkt an einer Wand montiert" | ||||
|                     }, | ||||
|                     "3": { | ||||
|                         "then": "Diese Uhr ist Teil einer Werbetafel" | ||||
|  | @ -3493,6 +3535,57 @@ | |||
|                     } | ||||
|                 }, | ||||
|                 "question": "Gibt die Ampel ein Vibrationssignal, um das Überqueren zu erleichtern? (in der Regel am unteren Ende der Ampeltaste)" | ||||
|             }, | ||||
|             "markings": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese Kreuzung hat keine Markierungen" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Dieser Übergang ist mit Zebrastreifen markiert" | ||||
|                     }, | ||||
|                     "10": { | ||||
|                         "then": "Dieser Übergang hat Zebrastreifen in wechselnden Farben" | ||||
|                     }, | ||||
|                     "11": { | ||||
|                         "then": "Dieser Übergang hat doppelte Zebrastreifen" | ||||
|                     }, | ||||
|                     "12": { | ||||
|                         "then": "Diese Kreuzung hat Piktogramme auf der Straße" | ||||
|                     }, | ||||
|                     "13": { | ||||
|                         "then": "Diese Kreuzung hat Linien auf beiden Seiten der Kreuzung und Balken, die sie verbinden, mit einer Unterbrechung in jedem Balken" | ||||
|                     }, | ||||
|                     "14": { | ||||
|                         "then": "Dieser Übergang hat doppelte Linien auf beiden Seiten des Übergangs" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Dieser Übergang weist Markierungen unbekannter Art auf" | ||||
|                     }, | ||||
|                     "3": { | ||||
|                         "then": "Dieser Übergang hat Linien auf beiden Seiten des Übergangs" | ||||
|                     }, | ||||
|                     "4": { | ||||
|                         "then": "Diese Kreuzung hat Linien auf beiden Seiten der Kreuzung, zusammen mit Stangen, die sie verbinden" | ||||
|                     }, | ||||
|                     "5": { | ||||
|                         "then": "Dieser Übergang hat gestrichelte Linien auf beiden Seiten des Übergangs" | ||||
|                     }, | ||||
|                     "6": { | ||||
|                         "then": "Dieser Übergang hat gestrichelte Linien auf beiden Seiten des Übergangs" | ||||
|                     }, | ||||
|                     "7": { | ||||
|                         "then": "Dieser Übergang wird durch eine andersfarbige Oberfläche gekennzeichnet" | ||||
|                     }, | ||||
|                     "8": { | ||||
|                         "then": "Diese Kreuzung hat Linien auf beiden Seiten der Kreuzung, zusammen mit abgewinkelten Stangen, die sie verbinden" | ||||
|                     }, | ||||
|                     "9": { | ||||
|                         "then": "Dieser Übergang hat Zebrastreifen mit einer Unterbrechung in jedem Balken" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Welche Art von Markierungen gibt es an diesem Übergang?", | ||||
|                 "render": "Dieser Übergang hat {crossing:markings} Markierungen" | ||||
|             } | ||||
|         }, | ||||
|         "title": { | ||||
|  | @ -3908,6 +4001,57 @@ | |||
|             "render": "Weg" | ||||
|         } | ||||
|     }, | ||||
|     "cyclist_waiting_aid": { | ||||
|         "description": "Verschiedene Infrastruktureinrichtungen, die Radfahrern helfen, während sie an einer Ampel warten.", | ||||
|         "name": "Radfahrer-Wartehilfen", | ||||
|         "presets": { | ||||
|             "0": { | ||||
|                 "description": "Eine Fußstütze, ein Handlauf oder ein anderes Hilfsmittel zur Verbesserung des Komforts beim Warten an der Ampel", | ||||
|                 "title": "eine Radfahrer-Wartehilfe" | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "direction": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese Wartehilfe kann bei der Weiterfahrt auf diesem Weg genutzt werden" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Diese Wartehilfe kann beim Rückwärtsfahren auf diesem Weg benutzt werden" | ||||
|                     } | ||||
|                 }, | ||||
|                 "render": "Diese Wartehilfe kann in Fahrtrichtung {direction} benutzt werden" | ||||
|             }, | ||||
|             "side": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese Wartehilfe befindet sich auf der linken Seite" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Diese Wartehilfe befindet sich auf der rechten Seite" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Auf beiden Seiten der Straße gibt es Wartehilfen" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Auf welcher Straßenseite befindet sich dies?" | ||||
|             }, | ||||
|             "type": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Hier gibt es ein Brett oder einen Pflock zum Abstützen des Fußes" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Hier gibt es eine Schiene oder einen Griff zum Festhalten" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Aus welchen Bestandteilen besteht diese Wartehilfe?" | ||||
|             } | ||||
|         }, | ||||
|         "title": { | ||||
|             "render": "Radfahrer-Wartehilfe" | ||||
|         } | ||||
|     }, | ||||
|     "defibrillator": { | ||||
|         "description": "Eine Ebene mit Defibrillatoren, die in Notfällen eingesetzt werden können. Diese Ebene enthält öffentliche Defibrillatoren, aber auch Defibrillatoren, bei denen möglicherweise Personal benötigt wird, um das Gerät zu holen", | ||||
|         "name": "Defibrillatoren", | ||||
|  | @ -7891,6 +8035,15 @@ | |||
|         "presets": { | ||||
|             "0": { | ||||
|                 "title": "ein Briefkasten" | ||||
|             }, | ||||
|             "1": { | ||||
|                 "title": "ein Briefkasten an einer Wand" | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "operator": { | ||||
|                 "question": "Wer betreibt diesen Briefkasten?", | ||||
|                 "render": "Dieser Briefkasten wird von <b>{operator}</b> betrieben" | ||||
|             } | ||||
|         }, | ||||
|         "title": { | ||||
|  | @ -8386,6 +8539,17 @@ | |||
|                 }, | ||||
|                 "question": "Verkauft das Geschäft glutenfreie Produkte?" | ||||
|             }, | ||||
|             "indoor": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Dieses Objekt befindet sich in einem Innenraum" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Dieses Objekt befindet sich im Freien" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Befindet sich das Objekt in einem Innenraum?" | ||||
|             }, | ||||
|             "induction-loop": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|  | @ -10476,6 +10640,133 @@ | |||
|             "render": "Überwachungskamera" | ||||
|         } | ||||
|     }, | ||||
|     "tactile_map": { | ||||
|         "description": "Ebene mit taktilen Karten, die von sehbehinderten Menschen zur Navigation in der Stadt verwendet werden können.", | ||||
|         "name": "Taktile Karten", | ||||
|         "presets": { | ||||
|             "0": { | ||||
|                 "description": "Eine taktile Karte, die durch Berühren gelesen werden kann. Im Gegensatz zu einem taktilen Modell ist diese Karte relativ flach und enthält keine dreidimensionalen Gebäude oder ähnliches.", | ||||
|                 "title": "eine taktile Karte" | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "braille": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese taktile Karte hat einen Text in Blindenschrift." | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Diese taktile Karte hat keinen Text in Blindenschrift." | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Gibt es einen Text in Blindenschrift auf dieser taktilen Karte?" | ||||
|             }, | ||||
|             "braille_languages": { | ||||
|                 "render": { | ||||
|                     "special": { | ||||
|                         "question": "In welchen Sprachen ist der Text in Blindenschrift auf dieser taktilen Karte?", | ||||
|                         "render_list_item": "Diese Karte hat Text in Blindenschrift in {language}", | ||||
|                         "render_single_language": "Diese Karte hat Text in Blindenschrift in {language}" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "description": { | ||||
|                 "freeform": { | ||||
|                     "placeholder": "z.B. Taktile Karte des Stadtzentrums" | ||||
|                 }, | ||||
|                 "question": "Was zeigt diese taktile Karte?", | ||||
|                 "render": "Beschreibung: {blind:description:en}." | ||||
|             }, | ||||
|             "embossed_letters": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Diese taktile Karte hat geprägte Buchstaben." | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Diese taktile Karte hat keine geprägten Buchstaben." | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Gibt es auf dieser taktilen Karte geprägte Buchstaben?" | ||||
|             }, | ||||
|             "embossed_letters_languages": { | ||||
|                 "render": { | ||||
|                     "special": { | ||||
|                         "question": "In welchen Sprachen sind die geprägten Buchstaben auf dieser taktilen Karte?", | ||||
|                         "render_list_item": "Diese Karte hat geprägte Buchstaben in {language}", | ||||
|                         "render_single_language": "Diese Karte hat geprägte Buchstaben in {language}" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "title": "Taktile Karte" | ||||
|     }, | ||||
|     "tactile_model": { | ||||
|         "description": "Ebene mit dreidimensionalen ertastbaren Modellen der Umgebung.", | ||||
|         "name": "Taktile Modelle", | ||||
|         "presets": { | ||||
|             "0": { | ||||
|                 "description": "Ein taktiles Modell ist ein dreidimensionales Modell eines Gebiets, das es den Menschen ermöglicht, ein Gebiet durch Berührung zu erkunden/sehen.", | ||||
|                 "title": "ein taktiles Modell" | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "braille": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Es gibt eine Beschreibung in Blindenschrift." | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Es gibt keine Beschreibung in Blindenschrift." | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Gibt es eine Beschreibung in Blindenschrift?" | ||||
|             }, | ||||
|             "braille_languages": { | ||||
|                 "render": { | ||||
|                     "special": { | ||||
|                         "question": "In welchen Sprachen gibt es eine Beschreibung in Blindenschrift?", | ||||
|                         "render_list_item": "Dieses Modell hat eine Beschreibung in Brailleschrift in {language()}", | ||||
|                         "render_single_language": "Dieses Modell hat eine Beschreibung in Brailleschrift in {language}" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "description": { | ||||
|                 "freeform": { | ||||
|                     "placeholder": "z.B. Taktiles Modell des Stadtzentrums" | ||||
|                 }, | ||||
|                 "question": "Was zeigt dieses taktile Modell?", | ||||
|                 "render": "Beschreibung: {blind:description:en}." | ||||
|             }, | ||||
|             "embossed_letters": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Das Modell ist mit geprägten Buchstaben beschrieben." | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Es gibt keine eingeprägten Buchstaben, die das Modell beschreiben." | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Gibt es eingeprägte Buchstaben, die das Modell beschreiben?" | ||||
|             }, | ||||
|             "embossed_letters_languages": { | ||||
|                 "render": { | ||||
|                     "special": { | ||||
|                         "question": "In welchen Sprachen gibt es geprägte Buchstaben?", | ||||
|                         "render_list_item": "Dieses Modell hat geprägte Buchstaben in {language()}", | ||||
|                         "render_single_language": "Dieses Modell hat geprägte Buchstaben in {language}" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "scale": { | ||||
|                 "freeform": { | ||||
|                     "placeholder": "z.B. 1:1000" | ||||
|                 }, | ||||
|                 "question": "Welchen Maßstab hat das Modell?", | ||||
|                 "render": "Der Maßstab dieses Modells ist {scale}." | ||||
|             } | ||||
|         }, | ||||
|         "title": "Taktiles Modell" | ||||
|     }, | ||||
|     "tertiary_education": { | ||||
|         "name": "Hochschulen und Universitäten", | ||||
|         "presets": { | ||||
|  | @ -12491,4 +12782,4 @@ | |||
|             "render": "Windrad" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								langs/layers/el.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								langs/layers/el.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {} | ||||
|  | @ -3294,12 +3294,15 @@ | |||
|                         "then": "Este reloj está montado en un poste" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Este reloj está montado en una pared" | ||||
|                         "then": "Este reloj está montado en una pared, generalmente a través de un soporte perpendicular a la pared" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Este reloj forma parte de una cartelera" | ||||
|                         "then": "Este reloj está montado directamente en una pared" | ||||
|                     }, | ||||
|                     "3": { | ||||
|                         "then": "Este reloj es parte de un cartel" | ||||
|                     }, | ||||
|                     "4": { | ||||
|                         "then": "Este reloj está en el suelo" | ||||
|                     }, | ||||
|                     "4": { | ||||
|  |  | |||
|  | @ -7556,4 +7556,4 @@ | |||
|             "render": "éolienne" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -3707,4 +3707,4 @@ | |||
|             "render": "turbina wiatrowa" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -291,6 +291,28 @@ | |||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "assisted_repair": { | ||||
|         "tagRenderings": { | ||||
|             "item:repair": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Тут ремонтують мобільні телефони" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "atm": { | ||||
|         "tagRenderings": { | ||||
|             "speech_output": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Цей банкомат має мовний вихід, зазвичай доступний через роз'єм для навушників" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "bench": { | ||||
|         "tagRenderings": { | ||||
|             "bench-armrest": { | ||||
|  | @ -468,7 +490,8 @@ | |||
|                 "question": "Яка електронна адреса оператора цієї велопарковки?" | ||||
|             }, | ||||
|             "operator_phone": { | ||||
|                 "question": "Який номер телефону оператора цієї велопарковки?" | ||||
|                 "question": "Який номер телефону оператора цієї велопарковки?", | ||||
|                 "questionHint": "За цим номером можна буде зателефонувати у разі виникнення проблем, наприклад, щоб прибрати недоглянуті велосипеди" | ||||
|             }, | ||||
|             "operator_website": { | ||||
|                 "question": "Яка адреса веб-сайту оператора цієї велопарковки?" | ||||
|  | @ -587,7 +610,37 @@ | |||
|         } | ||||
|     }, | ||||
|     "charging_station": { | ||||
|         "filter": { | ||||
|             "2": { | ||||
|                 "options": { | ||||
|                     "14": { | ||||
|                         "question": "Має <div style='display: inline-block'><b><b>USB</b> для зарядки телефонів і малої електроніки</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/usb_port.svg'/></div> роз'єм" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         }, | ||||
|         "tagRenderings": { | ||||
|             "Auth phone": { | ||||
|                 "question": "Який номер телефону для аутентифікаційного дзвінка або SMS?", | ||||
|                 "render": "Авторизуйтесь, зателефонувавши або надіславши SMS на <a href='tel:{authentication:phone_call:number}'>{authentication:phone_call:number}</a>" | ||||
|             }, | ||||
|             "Authentication": { | ||||
|                 "mappings": { | ||||
|                     "2": { | ||||
|                         "then": "Доступна автентифікація за допомогою телефонного дзвінка" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "Available_charging_stations (generated)": { | ||||
|                 "mappings": { | ||||
|                     "26": { | ||||
|                         "then": "<b>USB</b> для зарядки телефонів і дрібної електроніки" | ||||
|                     }, | ||||
|                     "27": { | ||||
|                         "then": "<b>USB</b> для зарядки телефонів і дрібної електроніки" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "Network": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|  | @ -605,6 +658,19 @@ | |||
|             }, | ||||
|             "email": { | ||||
|                 "question": "Яка електронна адреса оператора?" | ||||
|             }, | ||||
|             "phone": { | ||||
|                 "question": "За яким номером можна зателефонувати, якщо виникла проблема з цією зарядною станцією?", | ||||
|                 "render": "У разі виникнення проблем телефонуйте <a href='tel:{phone}'>{phone}</a>" | ||||
|             }, | ||||
|             "rewritten-questions": { | ||||
|                 "rewrite": { | ||||
|                     "into": { | ||||
|                         "13": { | ||||
|                             "2": "<b>USB</b> для зарядки телефонів і дрібної електроніки" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | @ -644,6 +710,10 @@ | |||
|         "tagRenderings": { | ||||
|             "defibrillator-access": { | ||||
|                 "render": "Доступ – {access}" | ||||
|             }, | ||||
|             "defibrillator-phone": { | ||||
|                 "question": "Який номер телефону для запитань щодо цього дефібрилятора?", | ||||
|                 "render": "Телефонуйте з питань щодо цього дефібрилятора: <a href='tel:{phone}'>{phone}</a>" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | @ -896,6 +966,26 @@ | |||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "icons": { | ||||
|         "tagRenderings": { | ||||
|             "phonelink": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": { | ||||
|                             "special": { | ||||
|                                 "arialabel": "телефон" | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 }, | ||||
|                 "render": { | ||||
|                     "special": { | ||||
|                         "arialabel": "телефон" | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     "indoors": { | ||||
|         "tagRenderings": { | ||||
|             "name": { | ||||
|  | @ -941,6 +1031,10 @@ | |||
|         "tagRenderings": { | ||||
|             "Access tag": { | ||||
|                 "render": "Доступ до цього природного заповідника: {access:description}" | ||||
|             }, | ||||
|             "phone": { | ||||
|                 "question": "За яким номером телефону можна звертатися з питаннями та проблемами, пов'язаними з цим заповідником?", | ||||
|                 "questionHint": "Поважайте приватність - вказуйте особистий номер телефону лише в тому випадку, якщо він є загальнодоступним" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | @ -981,7 +1075,8 @@ | |||
|                 "question": "Яка електронна адреса доглядача дитячого майданчика?" | ||||
|             }, | ||||
|             "playground-phone": { | ||||
|                 "question": "Який номер телефону доглядача дитячого майданчика?" | ||||
|                 "question": "Який номер телефону доглядача дитячого майданчика?", | ||||
|                 "render": "<a href='tel:{phone}'>{phone}</a>" | ||||
|             }, | ||||
|             "playground-surface": { | ||||
|                 "mappings": { | ||||
|  | @ -1073,6 +1168,9 @@ | |||
|                         "then": "Ця локація пропонує послуги для bpost" | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "post_offic_brand": { | ||||
|                 "render": "Це поштове відділення {brand}" | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | @ -1151,7 +1249,43 @@ | |||
|                 "question": "Які години роботи {title()}?", | ||||
|                 "render": "<h3>Години роботи</h3>{opening_hours_table(opening_hours)}" | ||||
|             }, | ||||
|             "opening_hours_24_7": { | ||||
|                 "override": { | ||||
|                     "+mappings": { | ||||
|                         "0": { | ||||
|                             "then": "Працює 24/7 (включаючи святкові дні)" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "payment-options": { | ||||
|                 "mappings": { | ||||
|                     "2": { | ||||
|                         "then": "Оплата за допомогою QR-коду можлива тут" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Які способи оплати тут приймаються?" | ||||
|             }, | ||||
|             "payment-options-split": { | ||||
|                 "override": { | ||||
|                     "mappings+": { | ||||
|                         "0": { | ||||
|                             "then": "Монети приймаються тут" | ||||
|                         }, | ||||
|                         "1": { | ||||
|                             "then": "Тут приймаються банкноти" | ||||
|                         }, | ||||
|                         "2": { | ||||
|                             "then": "Тут приймаються дебетові картки" | ||||
|                         }, | ||||
|                         "3": { | ||||
|                             "then": "Тут приймаються кредитні картки" | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|             "phone": { | ||||
|                 "editButtonAriaLabel": "Редагувати номер телефону", | ||||
|                 "question": "Який номер телефону {title()}?" | ||||
|             }, | ||||
|             "qr_code": { | ||||
|  | @ -1886,18 +2020,137 @@ | |||
|     }, | ||||
|     "vending_machine": { | ||||
|         "tagRenderings": { | ||||
|             "indoor": { | ||||
|                 "mappings": { | ||||
|                     "1": { | ||||
|                         "then": "Цей торговий автомат знаходиться в приміщенні" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Цей торговий автомат знаходиться на відкритому повітрі" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Цей торговий автомат знаходиться в приміщенні?" | ||||
|             }, | ||||
|             "operational_status": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Цей торговий автомат працює" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Цей торговий автомат несправний" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Цей торговий автомат закрито" | ||||
|                     }, | ||||
|                     "3": { | ||||
|                         "then": "Робочий стан - це <i>{operational_status}</i>" | ||||
|                     } | ||||
|                 } | ||||
|                 }, | ||||
|                 "question": "Чи працює цей торговий автомат досі?" | ||||
|             }, | ||||
|             "operator": { | ||||
|                 "question": "Хто керує цим автоматом?", | ||||
|                 "render": "Цим торговим автоматом керує {operator}" | ||||
|             }, | ||||
|             "phone": { | ||||
|                 "override": { | ||||
|                     "question": "Який номер телефону оператора цього торгового автомата?" | ||||
|                     "question": "Який номер телефону оператора цього торгового автомата?", | ||||
|                     "questionHint": "Це номер, за яким ви можете зателефонувати у разі виникнення проблем з торговим автоматом" | ||||
|                 } | ||||
|             }, | ||||
|             "vending": { | ||||
|                 "mappings": { | ||||
|                     "0": { | ||||
|                         "then": "Напої" | ||||
|                     }, | ||||
|                     "1": { | ||||
|                         "then": "Солодощі" | ||||
|                     }, | ||||
|                     "10": { | ||||
|                         "then": "Хліб" | ||||
|                     }, | ||||
|                     "11": { | ||||
|                         "then": "Яйця" | ||||
|                     }, | ||||
|                     "12": { | ||||
|                         "then": "Морозиво" | ||||
|                     }, | ||||
|                     "13": { | ||||
|                         "then": "Твердий сир" | ||||
|                     }, | ||||
|                     "14": { | ||||
|                         "then": "Мед" | ||||
|                     }, | ||||
|                     "15": { | ||||
|                         "then": "Картопля" | ||||
|                     }, | ||||
|                     "16": { | ||||
|                         "then": "М'ясо" | ||||
|                     }, | ||||
|                     "17": { | ||||
|                         "then": "Фрукти" | ||||
|                     }, | ||||
|                     "18": { | ||||
|                         "then": "Полуниця" | ||||
|                     }, | ||||
|                     "19": { | ||||
|                         "then": "Квіти" | ||||
|                     }, | ||||
|                     "2": { | ||||
|                         "then": "Продукти харчування" | ||||
|                     }, | ||||
|                     "20": { | ||||
|                         "then": "Паркувальні талони" | ||||
|                     }, | ||||
|                     "21": { | ||||
|                         "then": "Пресовані монети" | ||||
|                     }, | ||||
|                     "22": { | ||||
|                         "then": "Квитки на громадський транспорт" | ||||
|                     }, | ||||
|                     "23": { | ||||
|                         "then": "Велосипедні ліхтарі" | ||||
|                     }, | ||||
|                     "24": { | ||||
|                         "then": "Рукавички" | ||||
|                     }, | ||||
|                     "25": { | ||||
|                         "then": "Набори для ремонту велосипедів" | ||||
|                     }, | ||||
|                     "26": { | ||||
|                         "then": "Велосипедні насоси" | ||||
|                     }, | ||||
|                     "27": { | ||||
|                         "then": "Велосипедні замки" | ||||
|                     }, | ||||
|                     "3": { | ||||
|                         "then": "Сигарети" | ||||
|                     }, | ||||
|                     "4": { | ||||
|                         "then": "Презервативи" | ||||
|                     }, | ||||
|                     "5": { | ||||
|                         "then": "Кава" | ||||
|                     }, | ||||
|                     "6": { | ||||
|                         "then": "Питна вода" | ||||
|                     }, | ||||
|                     "7": { | ||||
|                         "then": "Газети" | ||||
|                     }, | ||||
|                     "8": { | ||||
|                         "then": "Велосипедні внутрішні трубки" | ||||
|                     }, | ||||
|                     "9": { | ||||
|                         "then": "Молоко" | ||||
|                     } | ||||
|                 }, | ||||
|                 "question": "Що продає цей автомат?", | ||||
|                 "render": "Цей торговий автомат продає {vending}" | ||||
|             } | ||||
|         }, | ||||
|         "title": { | ||||
|             "render": "Торговий автомат" | ||||
|         } | ||||
|     }, | ||||
|     "waste_disposal": { | ||||
|  | @ -1947,4 +2200,4 @@ | |||
|             "render": "Утилізація відходів" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,10 @@ | |||
| { | ||||
|     "advanced": { | ||||
|         "title": "Advanced features" | ||||
|         "title": "高级功能" | ||||
|     }, | ||||
|     "centerMessage": { | ||||
|         "allFilteredAway": "当前视图中没有满足过滤条件的要素" | ||||
|         "allFilteredAway": "当前视图中没有满足过滤条件的要素", | ||||
|         "loadingData": "加载数据…" | ||||
|     }, | ||||
|     "validation": { | ||||
|         "wikidata": { | ||||
|  | @ -11,4 +12,4 @@ | |||
|             "startsWithQ": "A wikidata identifier starts with Q and is followed by a number" | ||||
|         } | ||||
|     } | ||||
| } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								langs/themes/el.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								langs/themes/el.json
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| {} | ||||
|  | @ -49,14 +49,15 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | |||
|         }, | ||||
|         options?: { | ||||
|             padToTiles?: Store<number> | ||||
|             isActive?: Store<boolean> | ||||
|             isActive?: Store<boolean>, | ||||
|             ignoreZoom?: boolean | ||||
|         } | ||||
|     ) { | ||||
|         this.state = state | ||||
|         this._isActive = options?.isActive ?? new ImmutableStore(true) | ||||
|         this.padToZoomLevel = options?.padToTiles | ||||
|         const self = this | ||||
|         this._layersToDownload = state.zoom.map((zoom) => this.layersToDownload(zoom)) | ||||
|         this._layersToDownload = options?.ignoreZoom? new ImmutableStore(state.layers) : state.zoom.map((zoom) => this.layersToDownload(zoom)) | ||||
| 
 | ||||
|         state.bounds.mapD( | ||||
|             (_) => { | ||||
|  | @ -103,7 +104,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | |||
|      * Download the relevant data from overpass. Attempt to use a different server if one fails; only downloads the relevant layers | ||||
|      * @private | ||||
|      */ | ||||
|     public async updateAsync(): Promise<void> { | ||||
|     public async updateAsync(overrideBounds?: BBox): Promise<void> { | ||||
|         let data: any = undefined | ||||
|         let lastUsed = 0 | ||||
|         const start = new Date() | ||||
|  | @ -122,7 +123,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource { | |||
|         let bounds: BBox | ||||
|         do { | ||||
|             try { | ||||
|                 bounds = this.state.bounds.data | ||||
|                 bounds = overrideBounds ?? this.state.bounds.data | ||||
|                     ?.pad(this.state.widenFactor) | ||||
|                     ?.expandToTileBounds(this.padToZoomLevel?.data) | ||||
|                 if (!bounds) { | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ import { FeatureSource, UpdatableFeatureSource } from "../FeatureSource" | |||
| import { Or } from "../../Tags/Or" | ||||
| import FeatureSwitchState from "../../State/FeatureSwitchState" | ||||
| import OverpassFeatureSource from "./OverpassFeatureSource" | ||||
| import { Store, UIEventSource } from "../../UIEventSource" | ||||
| import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource" | ||||
| import OsmFeatureSource from "./OsmFeatureSource" | ||||
| import DynamicGeoJsonTileSource from "../TiledFeatureSource/DynamicGeoJsonTileSource" | ||||
| import { BBox } from "../../BBox" | ||||
|  | @ -28,6 +28,13 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
| 
 | ||||
|     public static readonly fromCacheZoomLevel = 15 | ||||
| 
 | ||||
|     /** | ||||
|      * This source is _only_ triggered when the data is downloaded for CSV export | ||||
|      * @private | ||||
|      */ | ||||
|     private readonly _downloadAll: OverpassFeatureSource | ||||
|     private readonly _mapBounds: Store<BBox> | ||||
| 
 | ||||
|     constructor( | ||||
|         layers: LayerConfig[], | ||||
|         featureSwitches: FeatureSwitchState, | ||||
|  | @ -35,7 +42,7 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|         backend: string, | ||||
|         isDisplayed: (id: string) => Store<boolean>, | ||||
|         mvtAvailableLayers: Set<string>, | ||||
|         fullNodeDatabaseSource?: FullNodeDatabaseSource | ||||
|         fullNodeDatabaseSource?: FullNodeDatabaseSource, | ||||
|     ) { | ||||
|         const supportsForceDownload: UpdatableFeatureSource[] = [] | ||||
| 
 | ||||
|  | @ -56,7 +63,7 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|                     { | ||||
|                         isActive: isDisplayed(layer.id), | ||||
|                         maxAge: layer.maxAgeOfCache, | ||||
|                     } | ||||
|                     }, | ||||
|                 ) | ||||
|                 fromCache.set(layer.id, src) | ||||
|             } | ||||
|  | @ -75,7 +82,7 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|             zoom, | ||||
|             backend, | ||||
|             featureSwitches, | ||||
|             fullNodeDatabaseSource | ||||
|             fullNodeDatabaseSource, | ||||
|         ) | ||||
|         nonMvtSources.push(osmApiSource) | ||||
| 
 | ||||
|  | @ -84,13 +91,14 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|             console.log( | ||||
|                 "Layers ", | ||||
|                 nonMvtLayers.map((l) => l.id), | ||||
|                 " cannot be fetched from the cache server, defaulting to overpass/OSM-api" | ||||
|                 " cannot be fetched from the cache server, defaulting to overpass/OSM-api", | ||||
|             ) | ||||
|             overpassSource = ThemeSource.setupOverpass(osmLayers, bounds, zoom, featureSwitches) | ||||
|             nonMvtSources.push(overpassSource) | ||||
|             supportsForceDownload.push(overpassSource) | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         function setIsLoading() { | ||||
|             const loading = overpassSource?.runningQuery?.data || osmApiSource?.isRunning?.data | ||||
|             isLoading.setData(loading) | ||||
|  | @ -100,21 +108,40 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|         osmApiSource?.isRunning?.addCallbackAndRun(() => setIsLoading()) | ||||
| 
 | ||||
|         const geojsonSources: UpdatableFeatureSource[] = geojsonlayers.map((l) => | ||||
|             ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)) | ||||
|             ThemeSource.setupGeojsonSource(l, mapProperties, isDisplayed(l.id)), | ||||
|         ) | ||||
| 
 | ||||
|         super(...geojsonSources, ...Array.from(fromCache.values()), ...mvtSources, ...nonMvtSources) | ||||
|         const downloadAllBounds: UIEventSource<BBox> = new UIEventSource<BBox>(undefined) | ||||
|        const downloadAll=  new OverpassFeatureSource({ | ||||
|             layers: layers.filter(l => l.isNormal()), | ||||
|             bounds: mapProperties.bounds, | ||||
|             zoom: mapProperties.zoom, | ||||
|             overpassUrl: featureSwitches.overpassUrl, | ||||
|             overpassTimeout: featureSwitches.overpassTimeout, | ||||
|             overpassMaxZoom: new ImmutableStore(99), | ||||
|             widenFactor: 0, | ||||
|         },{ | ||||
|           ignoreZoom: true | ||||
|       }) | ||||
| 
 | ||||
|         super(...geojsonSources, ...Array.from(fromCache.values()), ...mvtSources, ...nonMvtSources, downloadAll) | ||||
| 
 | ||||
|         this.isLoading = isLoading | ||||
|         supportsForceDownload.push(...geojsonSources) | ||||
|         supportsForceDownload.push(...mvtSources) // Non-mvt sources are handled by overpass
 | ||||
| 
 | ||||
| 
 | ||||
|         this._mapBounds = mapProperties.bounds | ||||
|         this._downloadAll = downloadAll | ||||
| 
 | ||||
|         this.supportsForceDownload = supportsForceDownload | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static setupMvtSource( | ||||
|         layer: LayerConfig, | ||||
|         mapProperties: { zoom: Store<number>; bounds: Store<BBox> }, | ||||
|         isActive?: Store<boolean> | ||||
|         isActive?: Store<boolean>, | ||||
|     ): UpdatableFeatureSource { | ||||
|         return new DynamicMvtileSource(layer, mapProperties, { isActive }) | ||||
|     } | ||||
|  | @ -122,12 +149,12 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|     private static setupGeojsonSource( | ||||
|         layer: LayerConfig, | ||||
|         mapProperties: { zoom: Store<number>; bounds: Store<BBox> }, | ||||
|         isActiveByFilter?: Store<boolean> | ||||
|         isActiveByFilter?: Store<boolean>, | ||||
|     ): UpdatableFeatureSource { | ||||
|         const source = layer.source | ||||
|         const isActive = mapProperties.zoom.map( | ||||
|             (z) => (isActiveByFilter?.data ?? true) && z >= layer.minzoom, | ||||
|             [isActiveByFilter] | ||||
|             [isActiveByFilter], | ||||
|         ) | ||||
|         if (source.geojsonZoomLevel === undefined) { | ||||
|             // This is a 'load everything at once' geojson layer
 | ||||
|  | @ -143,7 +170,7 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|         zoom: Store<number>, | ||||
|         backend: string, | ||||
|         featureSwitches: FeatureSwitchState, | ||||
|         fullNodeDatabase: FullNodeDatabaseSource | ||||
|         fullNodeDatabase: FullNodeDatabaseSource, | ||||
|     ): OsmFeatureSource | undefined { | ||||
|         if (osmLayers.length == 0) { | ||||
|             return undefined | ||||
|  | @ -177,7 +204,7 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|         osmLayers: LayerConfig[], | ||||
|         bounds: Store<BBox>, | ||||
|         zoom: Store<number>, | ||||
|         featureSwitches: FeatureSwitchState | ||||
|         featureSwitches: FeatureSwitchState, | ||||
|     ): OverpassFeatureSource | undefined { | ||||
|         if (osmLayers.length == 0) { | ||||
|             return undefined | ||||
|  | @ -206,13 +233,14 @@ export default class ThemeSource extends FeatureSourceMerger { | |||
|             { | ||||
|                 padToTiles: zoom.map((zoom) => Math.min(15, zoom + 1)), | ||||
|                 isActive, | ||||
|             } | ||||
|             }, | ||||
|         ) | ||||
|     } | ||||
| 
 | ||||
|     public async downloadAll() { | ||||
|         console.log("Downloading all data") | ||||
|         await Promise.all(this.supportsForceDownload.map((i) => i.updateAsync())) | ||||
|         console.log("Downloading all data:") | ||||
|         await this._downloadAll.updateAsync(this._mapBounds.data) | ||||
|        // await Promise.all(this.supportsForceDownload.map((i) => i.updateAsync()))
 | ||||
|         console.log("Done") | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -371,6 +371,10 @@ export default class LinkedDataLoader { | |||
|             const match = maxstay.match(/P([0-9]+)D/) | ||||
|             if (match) { | ||||
|                 const days = Number(match[1]) | ||||
|                 if(days === 30){ | ||||
|                     // 30 is the default which is set if velopark didn't know the actual value
 | ||||
|                     return undefined | ||||
|                 } | ||||
|                 if (days === 1) { | ||||
|                     return "1 day" | ||||
|                 } | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ export default class VeloparkLoader { | |||
| 
 | ||||
|     private static readonly coder = new CountryCoder( | ||||
|         Constants.countryCoderEndpoint, | ||||
|         Utils.downloadJson | ||||
|         Utils.downloadJson, | ||||
|     ) | ||||
| 
 | ||||
|     public static convert(veloparkData: VeloparkData): Feature { | ||||
|  | @ -46,14 +46,14 @@ export default class VeloparkLoader { | |||
| 
 | ||||
|         if (veloparkData.contactPoint?.email) { | ||||
|             properties["operator:email"] = VeloparkLoader.emailReformatting.reformat( | ||||
|                 veloparkData.contactPoint?.email | ||||
|                 veloparkData.contactPoint?.email, | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|         if (veloparkData.contactPoint?.telephone) { | ||||
|             properties["operator:phone"] = VeloparkLoader.phoneValidator.reformat( | ||||
|                 veloparkData.contactPoint?.telephone, | ||||
|                 () => "be" | ||||
|                 () => "be", | ||||
|             ) | ||||
|         } | ||||
| 
 | ||||
|  | @ -78,9 +78,12 @@ export default class VeloparkLoader { | |||
|             ) { | ||||
|                 const duration = g.maximumParkingDuration.substring( | ||||
|                     1, | ||||
|                     g.maximumParkingDuration.length - 1 | ||||
|                     g.maximumParkingDuration.length - 1, | ||||
|                 ) | ||||
|                 properties.maxstay = duration + " days" | ||||
|                 if (duration !== "30") { | ||||
|                     // We don't set maxstay if it is 30, they are the default value that velopark chose for "unknown"
 | ||||
|                     properties.maxstay = duration + " days" | ||||
|                 } | ||||
|             } | ||||
|             properties.access = g.publicAccess ?? "yes" ? "yes" : "no" | ||||
|             const prefix = "http://schema.org/" | ||||
|  | @ -94,11 +97,11 @@ export default class VeloparkLoader { | |||
|                             const startHour = spec.opens | ||||
|                             const endHour = spec.closes === "23:59" ? "24:00" : spec.closes | ||||
|                             const merged = OH.MergeTimes( | ||||
|                                 OH.ParseRule(dayOfWeek + " " + startHour + "-" + endHour) | ||||
|                                 OH.ParseRule(dayOfWeek + " " + startHour + "-" + endHour), | ||||
|                             ) | ||||
|                             return OH.ToString(merged) | ||||
|                         }) | ||||
|                         .join("; ") | ||||
|                         .join("; "), | ||||
|                 ) | ||||
|                 properties.opening_hours = oh | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue