forked from MapComplete/MapComplete
Merge branch 'develop' into Robin-patch-1
This commit is contained in:
commit
904b628a81
22 changed files with 660 additions and 385 deletions
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,15 @@
|
||||||
"nl": "Wijzigingen gemaakt met MapComplete",
|
"nl": "Wijzigingen gemaakt met MapComplete",
|
||||||
"ko": "MapComplete로 이루어진 변경 사항"
|
"ko": "MapComplete로 이루어진 변경 사항"
|
||||||
},
|
},
|
||||||
|
"shortDescription": {
|
||||||
|
"en": "Shows changes made by MapComplete",
|
||||||
|
"de": "Zeigt die von MapComplete vorgenommenen Änderungen an",
|
||||||
|
"cs": "Zobrazuje změny provedené nástrojem MapComplete",
|
||||||
|
"es": "Muestra los cambios realizados por MapComplete",
|
||||||
|
"fr": "Afficher les modifications faites avec MapComplete",
|
||||||
|
"nl": "Toont wijzigingen gemaakt met MapComplete",
|
||||||
|
"ko": "MapComplete를 통해 이루어진 변경 사항을 표시합니다"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"en": "This maps shows all the changes made with MapComplete",
|
"en": "This maps shows all the changes made with MapComplete",
|
||||||
"de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen",
|
"de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen",
|
||||||
|
@ -19,17 +28,11 @@
|
||||||
"nl": "Deze kaarten tonen alle wijzigingen die zijn gemaakt met MapComplete",
|
"nl": "Deze kaarten tonen alle wijzigingen die zijn gemaakt met MapComplete",
|
||||||
"ko": "이 지도는 MapComplete를 사용하여 이루어진 모든 변경 사항을 표시합니다"
|
"ko": "이 지도는 MapComplete를 사용하여 이루어진 모든 변경 사항을 표시합니다"
|
||||||
},
|
},
|
||||||
"shortDescription": {
|
|
||||||
"en": "Shows changes made by MapComplete",
|
|
||||||
"de": "Zeigt die von MapComplete vorgenommenen Änderungen an",
|
|
||||||
"cs": "Zobrazuje změny provedené nástrojem MapComplete",
|
|
||||||
"es": "Muestra los cambios realizados por MapComplete",
|
|
||||||
"fr": "Afficher les modifications faites avec MapComplete",
|
|
||||||
"nl": "Toont wijzigingen gemaakt met MapComplete",
|
|
||||||
"ko": "MapComplete를 통해 이루어진 변경 사항을 표시합니다"
|
|
||||||
},
|
|
||||||
"icon": "./assets/svg/logo.svg",
|
"icon": "./assets/svg/logo.svg",
|
||||||
"hideFromOverview": true,
|
"hideFromOverview": true,
|
||||||
|
"startLat": 0,
|
||||||
|
"startLon": 0,
|
||||||
|
"startZoom": 1,
|
||||||
"layers": [
|
"layers": [
|
||||||
{
|
{
|
||||||
"id": "mapcomplete-changes",
|
"id": "mapcomplete-changes",
|
||||||
|
@ -182,19 +185,22 @@
|
||||||
{
|
{
|
||||||
"id": "platform",
|
"id": "platform",
|
||||||
"question": {
|
"question": {
|
||||||
"en": "With what platform was the change made?"
|
"en": "With what platform was the change made?",
|
||||||
|
"cs": "S jakou platformou byly změny provedeny?"
|
||||||
},
|
},
|
||||||
"mappings": [
|
"mappings": [
|
||||||
{
|
{
|
||||||
"if": "android=",
|
"if": "android=",
|
||||||
"then": {
|
"then": {
|
||||||
"en": "Made on the web"
|
"en": "Made on the web",
|
||||||
|
"cs": "Vytvořeno na webu"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"if": "android=yes",
|
"if": "android=yes",
|
||||||
"then": {
|
"then": {
|
||||||
"en": "Made with the android app"
|
"en": "Made with the android app",
|
||||||
|
"cs": "Vytvořeno s aplikací pro Android"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -851,19 +857,22 @@
|
||||||
"options": [
|
"options": [
|
||||||
{
|
{
|
||||||
"question": {
|
"question": {
|
||||||
"en": "All platforms"
|
"en": "All platforms",
|
||||||
|
"cs": "Všechny platformy"
|
||||||
},
|
},
|
||||||
"quesiton": "All platforms"
|
"quesiton": "All platforms"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"question": {
|
"question": {
|
||||||
"en": "Made with Android"
|
"en": "Made with Android",
|
||||||
|
"cs": "Vytvořeno s Androidem"
|
||||||
},
|
},
|
||||||
"osmTags": "android=yes"
|
"osmTags": "android=yes"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"question": {
|
"question": {
|
||||||
"en": "Made on the web"
|
"en": "Made on the web",
|
||||||
|
"cs": "Vytvořeno na webu"
|
||||||
},
|
},
|
||||||
"osmTags": "android="
|
"osmTags": "android="
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,16 +27,21 @@
|
||||||
"=presets": [],
|
"=presets": [],
|
||||||
"source": {
|
"source": {
|
||||||
"=osmTags": {
|
"=osmTags": {
|
||||||
"and": [
|
"or":[
|
||||||
"tourism=camp_site",
|
"leisure=summer_camp",
|
||||||
"scout!=no",
|
|
||||||
"group!=no",
|
|
||||||
{
|
{
|
||||||
"or": [
|
"and": [
|
||||||
"scout=yes",
|
"tourism=camp_site",
|
||||||
"scout=only",
|
"scout!=no",
|
||||||
"group=yes",
|
"group!=no",
|
||||||
"group_only=yes"
|
{
|
||||||
|
"or": [
|
||||||
|
"scout=yes",
|
||||||
|
"scout=only",
|
||||||
|
"group=yes",
|
||||||
|
"group_only=yes"
|
||||||
|
]
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -669,6 +669,29 @@
|
||||||
"onwheels": {
|
"onwheels": {
|
||||||
"description": "En aquest mapa, es mostren llocs públics accessibles per a cadira de rodes i es poden afegir fàcilment",
|
"description": "En aquest mapa, es mostren llocs públics accessibles per a cadira de rodes i es poden afegir fàcilment",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "No s'ha senyalitzat cap entrada"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Cap de les {_entrance_count} entrades té informació d'amplada encara"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} entrades encara no tenen informació d'amplada",
|
||||||
|
"before": "<h3>Entrades</h3>Aquest edifici té {_entrances_count} entrades:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "Una <a href='#{id}'>entrada </a> de {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -889,6 +889,29 @@
|
||||||
"0": {
|
"0": {
|
||||||
"description": "Všechny objekty, které mají data vstupu mapována na vybavení namísto objektu vstupu"
|
"description": "Všechny objekty, které mají data vstupu mapována na vybavení namísto objektu vstupu"
|
||||||
},
|
},
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Nebyl označen žádný vchod"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Žádný z {_entrance_count} vchodů zatím nemá informace o šířce"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} vchody zatím nemají informace o šířce",
|
||||||
|
"before": "<h3>Vchody</h3>Tato budova má {_entrances_count} vchodů:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "<a href='#{id}'>vchod</a> {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -505,6 +505,29 @@
|
||||||
"onwheels": {
|
"onwheels": {
|
||||||
"description": "På dette kort vises steder, der er offentligt tilgængelige for kørestolsbrugere, og de kan nemt tilføjes",
|
"description": "På dette kort vises steder, der er offentligt tilgængelige for kørestolsbrugere, og de kan nemt tilføjes",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Der er ikke markeret nogen indgang"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Ingen af {_entrance_count}-indgangene har oplysninger om bredde endnu"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} indgange har endnu ikke oplysninger om bredde",
|
||||||
|
"before": "<h3>Indgange</h3>Denne bygning har {_entrances_count} indgange:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "En <a href='#{id}'>indgang</a> på {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -862,6 +862,29 @@
|
||||||
"onwheels": {
|
"onwheels": {
|
||||||
"description": "Auf dieser Karte können Sie öffentlich zugängliche Orte für Rollstuhlfahrer ansehen, bearbeiten oder hinzufügen",
|
"description": "Auf dieser Karte können Sie öffentlich zugängliche Orte für Rollstuhlfahrer ansehen, bearbeiten oder hinzufügen",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Es wurde kein Eingang markiert"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Keiner der {_entrance_count} Eingänge hat bisher Angaben zur Breite"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} Eingänge haben keine Angaben zur Breite",
|
||||||
|
"before": "<h3>Eingänge</h3>Das Gebäude hat {_entrances_count} Eingänge:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "Ein <a href='#{id}'>Eingang</a> von {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -889,6 +889,29 @@
|
||||||
"0": {
|
"0": {
|
||||||
"description": "All objects which have entrance data mapped on the amenity instead of the entrance object"
|
"description": "All objects which have entrance data mapped on the amenity instead of the entrance object"
|
||||||
},
|
},
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "No entrance has been marked"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "None of the {_entrance_count} entrances have width information yet"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} entrances don't have width information yet",
|
||||||
|
"before": "<h3>Entrances</h3>This building has {_entrances_count} entrances:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "An <a href='#{id}'>entrance</a> of {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
@ -1377,6 +1400,10 @@
|
||||||
"shortDescription": "A map with waste baskets",
|
"shortDescription": "A map with waste baskets",
|
||||||
"title": "Waste Baskets"
|
"title": "Waste Baskets"
|
||||||
},
|
},
|
||||||
|
"wayside_shrines": {
|
||||||
|
"description": "This map shows shrines found on the side of roads and paths, and allows adding new ones",
|
||||||
|
"title": "Wayside shrines"
|
||||||
|
},
|
||||||
"winter_service": {
|
"winter_service": {
|
||||||
"description": "A map showing roads and whether they're cleared in winter",
|
"description": "A map showing roads and whether they're cleared in winter",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
|
|
@ -849,6 +849,29 @@
|
||||||
"onwheels": {
|
"onwheels": {
|
||||||
"description": "En este mapa, se muestran y se pueden agregar fácilmente lugares accesibles para sillas de ruedas",
|
"description": "En este mapa, se muestran y se pueden agregar fácilmente lugares accesibles para sillas de ruedas",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "No se ha marcado ninguna entrada"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Ninguna de las {_entrance_count} entradas tiene información de ancho todavía"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} entradas aún no tienen información de ancho",
|
||||||
|
"before": "<h3>Entradas</h3>Este edificio tiene {_entrances_count} entradas:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "Una <a href='#{id}'>entrada</a> de {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -909,6 +909,29 @@
|
||||||
"onwheels": {
|
"onwheels": {
|
||||||
"description": "Op deze kaart kan je rolstoeltoegankelijke plaatsen vinden en toevoegen",
|
"description": "Op deze kaart kan je rolstoeltoegankelijke plaatsen vinden en toevoegen",
|
||||||
"layers": {
|
"layers": {
|
||||||
|
"16": {
|
||||||
|
"override": {
|
||||||
|
"tagRenderings+": {
|
||||||
|
"0": {
|
||||||
|
"mappings": {
|
||||||
|
"0": {
|
||||||
|
"then": "Geen ingang is gemarkeerd"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"then": "Geen van de {_entrance_count} ingangen hebben al informatie over de breedte"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"render": {
|
||||||
|
"after": "{_entrances_count_without_width_count} ingangen hebben nog geen informatie over de breedte",
|
||||||
|
"before": "<h3>Ingangen</h3>Dit gebouw heeft {_entrances_count} ingangen:",
|
||||||
|
"special": {
|
||||||
|
"tagrendering": "Een <a href='#{id}'>ingang</a> van {canonical(width)}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"20": {
|
"20": {
|
||||||
"override": {
|
"override": {
|
||||||
"=title": {
|
"=title": {
|
||||||
|
|
|
@ -2006,6 +2006,10 @@ input[type="range"].range-lg::-moz-range-thumb {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.w-1\/4 {
|
||||||
|
width: 25%;
|
||||||
|
}
|
||||||
|
|
||||||
.w-10 {
|
.w-10 {
|
||||||
width: 2.5rem;
|
width: 2.5rem;
|
||||||
}
|
}
|
||||||
|
@ -5565,6 +5569,12 @@ code {
|
||||||
background-color: #b3b3b3;
|
background-color: #b3b3b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.frozen-glass {
|
||||||
|
-webkit-backdrop-filter: blur(1px);
|
||||||
|
backdrop-filter: blur(1px);
|
||||||
|
background: rgba(100, 100, 100, 0.50);
|
||||||
|
}
|
||||||
|
|
||||||
/************************** UTILITY ************************/
|
/************************** UTILITY ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -746,12 +746,14 @@ export default class TagRenderingConfig {
|
||||||
if (freeformValue === "") {
|
if (freeformValue === "") {
|
||||||
freeformValue = undefined
|
freeformValue = undefined
|
||||||
}
|
}
|
||||||
if (this.freeform?.postfixDistinguished) {
|
const pf = this.freeform?.postfixDistinguished
|
||||||
const allValues = currentProperties[this.freeform.key].split(";").map((s) => s.trim())
|
if (pf) {
|
||||||
|
const v = currentProperties[this.freeform.key] ?? ""
|
||||||
|
const allValues = v.split(";").map((s) => s.trim())
|
||||||
const perPostfix: Record<string, string> = {}
|
const perPostfix: Record<string, string> = {}
|
||||||
for (const value of allValues) {
|
for (const value of allValues) {
|
||||||
const [v, postfix] = value.split("/")
|
const [v, postfix] = value.split("/").map(s => s.trim())
|
||||||
perPostfix[postfix.trim()] = v.trim()
|
perPostfix[postfix ?? pf] = v.trim()
|
||||||
}
|
}
|
||||||
if (freeformValue === "" || freeformValue === undefined) {
|
if (freeformValue === "" || freeformValue === undefined) {
|
||||||
delete perPostfix[this.freeform.postfixDistinguished]
|
delete perPostfix[this.freeform.postfixDistinguished]
|
||||||
|
@ -1042,7 +1044,8 @@ export default class TagRenderingConfig {
|
||||||
*/
|
*/
|
||||||
public markUnknown(layer: LayerConfig, currentProperties: Record<string, string>): UploadableTag[] {
|
public markUnknown(layer: LayerConfig, currentProperties: Record<string, string>): UploadableTag[] {
|
||||||
if (this.freeform?.postfixDistinguished) {
|
if (this.freeform?.postfixDistinguished) {
|
||||||
const allValues = currentProperties[this.freeform.key].split(";").filter(
|
const v = currentProperties[this.freeform.key] ?? ""
|
||||||
|
const allValues = v.split(";").filter(
|
||||||
part => part.split("/")[1]?.trim() !== this.freeform.postfixDistinguished
|
part => part.split("/")[1]?.trim() !== this.freeform.postfixDistinguished
|
||||||
)
|
)
|
||||||
return [new Tag(this.freeform.key, allValues.join(";"))]
|
return [new Tag(this.freeform.key, allValues.join(";"))]
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
placement="left"
|
placement="left"
|
||||||
transitionType="fly"
|
transitionType="fly"
|
||||||
{transitionParams}
|
{transitionParams}
|
||||||
|
bgColor="frozen-glass"
|
||||||
divClass="overflow-y-auto z-50 "
|
divClass="overflow-y-auto z-50 "
|
||||||
bind:hidden
|
bind:hidden
|
||||||
>
|
>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
let height = 0
|
let height = 0
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let topbar = document.getElementById("top-bar")
|
let topbar = document.getElementById("top-bar")
|
||||||
height = topbar.clientHeight
|
height = topbar?.clientHeight ?? 0
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,13 @@
|
||||||
defaultClass = shared
|
defaultClass = shared
|
||||||
}
|
}
|
||||||
let dialogClass =
|
let dialogClass =
|
||||||
"fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex class-marker-dialog " + zIndex
|
"fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex border-none " + zIndex
|
||||||
|
|
||||||
|
export let backdropClass = "fixed inset-0 z-40 bg-gray-900 bg-opacity-50 dark:bg-opacity-80 frozen-glass"
|
||||||
if (fullscreen) {
|
if (fullscreen) {
|
||||||
dialogClass += " h-full-child"
|
dialogClass += " h-full-child"
|
||||||
}
|
}
|
||||||
let bodyClass = bodyPadding + " h-full space-y-4 flex-1 overflow-y-auto overscroll-contain"
|
let bodyClass = bodyPadding + " h-full space-y-4 flex-1 overflow-y-auto overscroll-contain background-normal"
|
||||||
|
|
||||||
let headerClass = "flex justify-between items-center p-2 px-4 md:px-5 rounded-t-lg"
|
let headerClass = "flex justify-between items-center p-2 px-4 md:px-5 rounded-t-lg"
|
||||||
if (!$$slots.header) {
|
if (!$$slots.header) {
|
||||||
|
@ -48,6 +50,7 @@
|
||||||
{bodyClass}
|
{bodyClass}
|
||||||
{dialogClass}
|
{dialogClass}
|
||||||
{headerClass}
|
{headerClass}
|
||||||
|
{backdropClass}
|
||||||
color="none"
|
color="none"
|
||||||
>
|
>
|
||||||
<svelte:fragment slot="header">
|
<svelte:fragment slot="header">
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
import { MapLibreAdaptor } from "./Map/MapLibreAdaptor"
|
import { MapLibreAdaptor } from "./Map/MapLibreAdaptor"
|
||||||
import { Map as MlMap } from "maplibre-gl"
|
import { Map as MlMap } from "maplibre-gl"
|
||||||
import ShowDataLayer from "./Map/ShowDataLayer"
|
import ShowDataLayer from "./Map/ShowDataLayer"
|
||||||
|
|
||||||
import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
|
import StaticFeatureSource from "../Logic/FeatureSource/Sources/StaticFeatureSource"
|
||||||
import type { Feature } from "geojson"
|
import type { Feature } from "geojson"
|
||||||
import Loading from "./Base/Loading.svelte"
|
import Loading from "./Base/Loading.svelte"
|
||||||
|
@ -24,9 +23,16 @@
|
||||||
import Page from "./Base/Page.svelte"
|
import Page from "./Base/Page.svelte"
|
||||||
import PreviouslySpiedUsers from "./History/PreviouslySpiedUsers.svelte"
|
import PreviouslySpiedUsers from "./History/PreviouslySpiedUsers.svelte"
|
||||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
||||||
import MagnifyingGlassCircle from "@babeard/svelte-heroicons/outline/MagnifyingGlassCircle"
|
|
||||||
import Translations from "./i18n/Translations"
|
import Translations from "./i18n/Translations"
|
||||||
import Tr from "./Base/Tr.svelte"
|
import Tr from "./Base/Tr.svelte"
|
||||||
|
import Searchbar from "../UI/Base/Searchbar.svelte"
|
||||||
|
import CombinedSearcher from "../Logic/Search/CombinedSearcher"
|
||||||
|
import CoordinateSearch from "../Logic/Search/CoordinateSearch"
|
||||||
|
import OpenLocationCodeSearch from "../Logic/Search/OpenLocationCodeSearch"
|
||||||
|
import PhotonSearch from "../Logic/Search/PhotonSearch"
|
||||||
|
import GeocodeResults from "./Search/GeocodeResults.svelte"
|
||||||
|
import MagnifyingGlassCircle from "@babeard/svelte-heroicons/mini/MagnifyingGlassCircle"
|
||||||
|
import type { GeocodeResult } from "../Logic/Search/GeocodingProvider"
|
||||||
|
|
||||||
console.log("Loading inspector GUI")
|
console.log("Loading inspector GUI")
|
||||||
let username = QueryParameters.GetQueryParameter("user", undefined, "Inspect this user")
|
let username = QueryParameters.GetQueryParameter("user", undefined, "Inspect this user")
|
||||||
|
@ -37,16 +43,45 @@
|
||||||
let lon = UIEventSource.asFloat(QueryParameters.GetQueryParameter("lon", "0"))
|
let lon = UIEventSource.asFloat(QueryParameters.GetQueryParameter("lon", "0"))
|
||||||
let loadingData = false
|
let loadingData = false
|
||||||
let selectedElement = new UIEventSource<Feature>(undefined)
|
let selectedElement = new UIEventSource<Feature>(undefined)
|
||||||
|
let searchvalue = new UIEventSource<string>("")
|
||||||
|
|
||||||
|
let geocoder = new CombinedSearcher(
|
||||||
|
new CoordinateSearch(),
|
||||||
|
new OpenLocationCodeSearch(),
|
||||||
|
new PhotonSearch(true, 2),
|
||||||
|
new PhotonSearch()
|
||||||
|
)
|
||||||
|
let showSearchDrawer = new UIEventSource(true)
|
||||||
|
let searchIsFocussed = new UIEventSource(false)
|
||||||
|
let searchIsRunning = new UIEventSource(false)
|
||||||
let maplibremap: MapLibreAdaptor = new MapLibreAdaptor(map, {
|
let maplibremap: MapLibreAdaptor = new MapLibreAdaptor(map, {
|
||||||
zoom,
|
zoom,
|
||||||
location: new UIEventSource<{ lon: number; lat: number }>({ lat: lat.data, lon: lon.data }),
|
location: new UIEventSource<{ lon: number; lat: number }>({ lat: lat.data, lon: lon.data })
|
||||||
})
|
})
|
||||||
maplibremap.location.stabilized(500).addCallbackAndRunD((l) => {
|
maplibremap.location.stabilized(500).addCallbackAndRunD((l) => {
|
||||||
lat.set(l.lat)
|
lat.set(l.lat)
|
||||||
lon.set(l.lon)
|
lon.set(l.lon)
|
||||||
})
|
})
|
||||||
|
let searchSuggestions = searchvalue.bindD(search => {
|
||||||
|
searchIsRunning.set(true)
|
||||||
|
try {
|
||||||
|
return UIEventSource.FromPromise(geocoder.search(search))
|
||||||
|
} finally {
|
||||||
|
searchIsRunning.set(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let state = {
|
||||||
|
mapProperties: maplibremap,
|
||||||
|
searchState: {
|
||||||
|
searchTerm: searchvalue,
|
||||||
|
suggestions: searchSuggestions,
|
||||||
|
suggestionsSearchRunning: searchIsRunning,
|
||||||
|
showSearchDrawer,
|
||||||
|
applyGeocodeResult(geocodeResult: GeocodeResult) {
|
||||||
|
maplibremap.location.set({ lon: geocodeResult.lon, lat: geocodeResult.lat })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let allLayers = HistoryUtils.personalTheme.layers
|
let allLayers = HistoryUtils.personalTheme.layers
|
||||||
let layersNoFixme = allLayers.filter((l) => l.id !== "fixme")
|
let layersNoFixme = allLayers.filter((l) => l.id !== "fixme")
|
||||||
let fixme = allLayers.find((l) => l.id === "fixme")
|
let fixme = allLayers.find((l) => l.id === "fixme")
|
||||||
|
@ -59,7 +94,7 @@
|
||||||
Utils.waitFor(200).then(() => {
|
Utils.waitFor(200).then(() => {
|
||||||
selectedElement.set(f)
|
selectedElement.set(f)
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
let osmConnection = new OsmConnection()
|
let osmConnection = new OsmConnection()
|
||||||
|
@ -91,7 +126,7 @@
|
||||||
inspectedData.push({
|
inspectedData.push({
|
||||||
label: undefined,
|
label: undefined,
|
||||||
visitedTime: new Date().toISOString(),
|
visitedTime: new Date().toISOString(),
|
||||||
name: user,
|
name: user
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
inspectedContributors.ping()
|
inspectedContributors.ping()
|
||||||
|
@ -101,7 +136,7 @@
|
||||||
featuresStore.set([])
|
featuresStore.set([])
|
||||||
const overpass = new Overpass(
|
const overpass = new Overpass(
|
||||||
undefined,
|
undefined,
|
||||||
user.split(";").map((user) => 'nw(user_touched:"' + user + '");'),
|
user.split(";").map((user) => "nw(user_touched:\"" + user + "\");"),
|
||||||
Constants.defaultOverpassUrls[0]
|
Constants.defaultOverpassUrls[0]
|
||||||
)
|
)
|
||||||
if (!maplibremap.bounds.data) {
|
if (!maplibremap.bounds.data) {
|
||||||
|
@ -137,7 +172,7 @@
|
||||||
<h1 class="m-0 mx-2 flex-shrink-0">
|
<h1 class="m-0 mx-2 flex-shrink-0">
|
||||||
<Tr t={t.title} />
|
<Tr t={t.title} />
|
||||||
</h1>
|
</h1>
|
||||||
<ValidatedInput type="string" value={username} on:submit={() => load()} />
|
<ValidatedInput placeholder={t.previouslySpied.username} type="string" value={username} on:submit={() => load()} />
|
||||||
{#if loadingData}
|
{#if loadingData}
|
||||||
<Loading />
|
<Loading />
|
||||||
{:else}
|
{:else}
|
||||||
|
@ -207,8 +242,16 @@
|
||||||
</Drawer>
|
</Drawer>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="m-1 flex-grow overflow-hidden rounded-xl">
|
|
||||||
|
<div class="relative m-1 flex-grow overflow-hidden rounded-xl">
|
||||||
<MaplibreMap {map} mapProperties={maplibremap} autorecovery={true} />
|
<MaplibreMap {map} mapProperties={maplibremap} autorecovery={true} />
|
||||||
|
<div class="absolute right-0 top-0 w-1/4 p-4">
|
||||||
|
<Searchbar isFocused={searchIsFocussed} value={searchvalue}
|
||||||
|
on:focus={() => state.searchState.showSearchDrawer.set(true)} />
|
||||||
|
{#if $searchSuggestions?.length > 0 || $searchIsFocussed}
|
||||||
|
<GeocodeResults {state} />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else if mode === "table"}
|
{:else if mode === "table"}
|
||||||
<div class="m-2 h-full overflow-y-auto">
|
<div class="m-2 h-full overflow-y-auto">
|
||||||
|
|
|
@ -252,6 +252,8 @@
|
||||||
} else if (selectedTags instanceof And) {
|
} else if (selectedTags instanceof And) {
|
||||||
// Add the extraTags to the existing And
|
// Add the extraTags to the existing And
|
||||||
selectedTags = [...TagTypes.uploadableAnd(selectedTags), ...extraTagsArray]
|
selectedTags = [...TagTypes.uploadableAnd(selectedTags), ...extraTagsArray]
|
||||||
|
} else if (Array.isArray(selectedTags)) {
|
||||||
|
// pass
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
"selectedTags is not of type Tag or And, it is a " + JSON.stringify(selectedTags)
|
"selectedTags is not of type Tag or And, it is a " + JSON.stringify(selectedTags)
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { GeocodingUtils } from "../../Logic/Search/GeocodingProvider"
|
|
||||||
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
|
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
|
||||||
|
import { GeocodingUtils } from "../../Logic/Search/GeocodingProvider"
|
||||||
import { GeoOperations } from "../../Logic/GeoOperations"
|
import { GeoOperations } from "../../Logic/GeoOperations"
|
||||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
import TagRenderingConfig from "../../Models/ThemeConfig/TagRenderingConfig"
|
||||||
import Icon from "../Map/Icon.svelte"
|
import Icon from "../Map/Icon.svelte"
|
||||||
import TagRenderingAnswer from "../Popup/TagRendering/TagRenderingAnswer.svelte"
|
import TagRenderingAnswer from "../Popup/TagRendering/TagRenderingAnswer.svelte"
|
||||||
import ArrowUp from "@babeard/svelte-heroicons/mini/ArrowUp"
|
|
||||||
import DefaultIcon from "../Map/DefaultIcon.svelte"
|
import DefaultIcon from "../Map/DefaultIcon.svelte"
|
||||||
import { WithSearchState } from "../../Models/ThemeViewState/WithSearchState"
|
import type { MapProperties } from "../../Models/MapProperties"
|
||||||
|
import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
|
||||||
|
import FeaturePropertiesStore from "../../Logic/FeatureSource/Actors/FeaturePropertiesStore"
|
||||||
|
import SearchState from "../../Logic/State/SearchState"
|
||||||
|
import ArrowUp from "@babeard/svelte-heroicons/mini/ArrowUp"
|
||||||
|
|
||||||
export let entry: GeocodeResult
|
export let entry: GeocodeResult
|
||||||
export let state: WithSearchState
|
export let state: {
|
||||||
|
mapProperties: MapProperties,
|
||||||
|
theme?: ThemeConfig,
|
||||||
|
featureProperties?: FeaturePropertiesStore,
|
||||||
|
searchState: Partial<SearchState>
|
||||||
|
}
|
||||||
|
|
||||||
let layer: LayerConfig
|
let layer: LayerConfig
|
||||||
let tags: UIEventSource<Record<string, string>>
|
let tags: UIEventSource<Record<string, string>>
|
||||||
let descriptionTr: TagRenderingConfig = undefined
|
let descriptionTr: TagRenderingConfig = undefined
|
||||||
if (entry.feature?.properties?.id) {
|
if (entry.feature?.properties?.id) {
|
||||||
layer = state.theme.getMatchingLayer(entry.feature.properties)
|
layer = state.theme.getMatchingLayer(entry.feature.properties)
|
||||||
tags = state.featureProperties.getStore(entry.feature.properties.id)
|
tags = state.featureProperties?.getStore(entry.feature.properties.id)
|
||||||
descriptionTr = layer?.tagRenderings?.find((tr) => tr.labels.indexOf("description") >= 0)
|
descriptionTr = layer?.tagRenderings?.find((tr) => tr.labels.indexOf("description") >= 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,29 +3,34 @@
|
||||||
* Shows all the location-results
|
* Shows all the location-results
|
||||||
*/
|
*/
|
||||||
import Translations from "../i18n/Translations"
|
import Translations from "../i18n/Translations"
|
||||||
import { Store } from "../../Logic/UIEventSource"
|
|
||||||
import SidebarUnit from "../Base/SidebarUnit.svelte"
|
import SidebarUnit from "../Base/SidebarUnit.svelte"
|
||||||
import Loading from "../Base/Loading.svelte"
|
import Loading from "../Base/Loading.svelte"
|
||||||
import { default as GeocodeResultSvelte } from "./GeocodeResult.svelte"
|
import { default as GeocodeResultSvelte } from "./GeocodeResult.svelte"
|
||||||
import Tr from "../Base/Tr.svelte"
|
import Tr from "../Base/Tr.svelte"
|
||||||
import DotMenu from "../Base/DotMenu.svelte"
|
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||||
import { CogIcon } from "@rgossiaux/svelte-heroicons/solid"
|
|
||||||
import { TrashIcon } from "@babeard/svelte-heroicons/mini"
|
|
||||||
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
|
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
|
||||||
import { WithSearchState } from "../../Models/ThemeViewState/WithSearchState"
|
import type { MapProperties } from "../../Models/MapProperties"
|
||||||
|
|
||||||
export let state: WithSearchState
|
export let state: {
|
||||||
|
searchState: {
|
||||||
|
searchTerm: UIEventSource<string>
|
||||||
|
suggestions: Store<GeocodeResult[]>
|
||||||
|
suggestionsSearchRunning: Store<boolean>
|
||||||
|
}, mapProperties: MapProperties
|
||||||
|
}
|
||||||
|
|
||||||
let searchTerm = state.searchState.searchTerm
|
let searchTerm = state.searchState.searchTerm
|
||||||
let results = state.searchState.suggestions
|
let results = state.searchState.suggestions
|
||||||
let isSearching = state.searchState.suggestionsSearchRunning
|
let isSearching = state.searchState.suggestionsSearchRunning ?? new ImmutableStore(false)
|
||||||
let recentlySeen: Store<GeocodeResult[]> = state.userRelatedState.recentlyVisitedSearch.value
|
|
||||||
const t = Translations.t.general.search
|
const t = Translations.t.general.search
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if $searchTerm.length > 0}
|
{#if $searchTerm.length > 0}
|
||||||
<SidebarUnit>
|
<SidebarUnit>
|
||||||
<h3><Tr t={t.locations} /></h3>
|
<h3>
|
||||||
|
<Tr t={t.locations} />
|
||||||
|
</h3>
|
||||||
|
|
||||||
{#if $results?.length > 0}
|
{#if $results?.length > 0}
|
||||||
{#each $results as entry (entry)}
|
{#each $results as entry (entry)}
|
||||||
|
@ -41,35 +46,12 @@
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if !$isSearching && $results.length === 0}
|
{#if !$isSearching && $results?.length === 0}
|
||||||
<b class="flex justify-center p-4">
|
<b class="flex justify-center p-4">
|
||||||
<Tr t={t.nothingFor.Subs({ term: "<i>" + $searchTerm + "</i>" })} />
|
<Tr t={t.nothingFor.Subs({ term: "<i>" + $searchTerm + "</i>" })} />
|
||||||
</b>
|
</b>
|
||||||
{/if}
|
{/if}
|
||||||
</SidebarUnit>
|
</SidebarUnit>
|
||||||
{:else if $recentlySeen?.length > 0}
|
{:else}
|
||||||
<SidebarUnit>
|
<slot name="if-no-results" />
|
||||||
<div class="flex justify-between">
|
|
||||||
<h3 class="m-2">
|
|
||||||
<Tr t={t.recents} />
|
|
||||||
</h3>
|
|
||||||
<DotMenu>
|
|
||||||
<button
|
|
||||||
on:click={() => {
|
|
||||||
state.userRelatedState.recentlyVisitedSearch.clear()
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TrashIcon />
|
|
||||||
<Tr t={t.deleteSearchHistory} />
|
|
||||||
</button>
|
|
||||||
<button on:click={() => state.guistate.openUsersettings("sync-visited-locations")}>
|
|
||||||
<CogIcon />
|
|
||||||
<Tr t={t.editSearchSyncSettings} />
|
|
||||||
</button>
|
|
||||||
</DotMenu>
|
|
||||||
</div>
|
|
||||||
{#each $recentlySeen as entry (entry)}
|
|
||||||
<GeocodeResultSvelte {entry} {state} on:select />
|
|
||||||
{/each}
|
|
||||||
</SidebarUnit>
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -10,6 +10,12 @@
|
||||||
import Translations from "../i18n/Translations"
|
import Translations from "../i18n/Translations"
|
||||||
import type { FilterSearchResult } from "../../Logic/Search/FilterSearch"
|
import type { FilterSearchResult } from "../../Logic/Search/FilterSearch"
|
||||||
import { WithSearchState } from "../../Models/ThemeViewState/WithSearchState"
|
import { WithSearchState } from "../../Models/ThemeViewState/WithSearchState"
|
||||||
|
import { TrashIcon } from "@babeard/svelte-heroicons/mini"
|
||||||
|
import { CogIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||||
|
import SidebarUnit from "../Base/SidebarUnit.svelte"
|
||||||
|
import DotMenu from "../Base/DotMenu.svelte"
|
||||||
|
import type { GeocodeResult } from "../../Logic/Search/GeocodingProvider"
|
||||||
|
import { default as GeocodeResultSvelte } from "./GeocodeResult.svelte"
|
||||||
|
|
||||||
export let state: WithSearchState
|
export let state: WithSearchState
|
||||||
let activeFilters: Store<(ActiveFilter & FilterSearchResult)[]> =
|
let activeFilters: Store<(ActiveFilter & FilterSearchResult)[]> =
|
||||||
|
@ -26,7 +32,9 @@
|
||||||
return r
|
return r
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
let searchTerm = state.searchState.searchTerm
|
let searchTerm = state.searchState.searchTerm
|
||||||
|
let recentlySeen: Store<GeocodeResult[]> = state.userRelatedState.recentlyVisitedSearch.value
|
||||||
|
|
||||||
let allowOtherThemes = state.featureSwitches.featureSwitchBackToThemeOverview
|
let allowOtherThemes = state.featureSwitches.featureSwitchBackToThemeOverview
|
||||||
let allowFilters = state.featureSwitches.featureSwitchFilter
|
let allowFilters = state.featureSwitches.featureSwitchFilter
|
||||||
|
@ -47,7 +55,38 @@
|
||||||
{#if $allowFilters}
|
{#if $allowFilters}
|
||||||
<FilterResults {state} />
|
<FilterResults {state} />
|
||||||
{/if}
|
{/if}
|
||||||
<GeocodeResults {state} />
|
<GeocodeResults {state}>
|
||||||
|
<svelte:fragment slot="if-no-results">
|
||||||
|
|
||||||
|
{#if $recentlySeen?.length > 0}
|
||||||
|
<SidebarUnit>
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<h3 class="m-2">
|
||||||
|
<Tr t={Translations.t.general.search.recents} />
|
||||||
|
</h3>
|
||||||
|
<DotMenu>
|
||||||
|
<button
|
||||||
|
on:click={() => {
|
||||||
|
state.userRelatedState.recentlyVisitedSearch.clear()
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TrashIcon />
|
||||||
|
<Tr t={Translations.t.general.search.deleteSearchHistory} />
|
||||||
|
</button>
|
||||||
|
<button on:click={() => state.guistate.openUsersettings("sync-visited-locations")}>
|
||||||
|
<CogIcon />
|
||||||
|
<Tr t={Translations.t.general.search.editSearchSyncSettings} />
|
||||||
|
</button>
|
||||||
|
</DotMenu>
|
||||||
|
</div>
|
||||||
|
{#each $recentlySeen as entry (entry)}
|
||||||
|
<GeocodeResultSvelte {entry} {state} on:select />
|
||||||
|
{/each}
|
||||||
|
</SidebarUnit>
|
||||||
|
{/if}
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
</GeocodeResults>
|
||||||
|
|
||||||
{#if $allowOtherThemes}
|
{#if $allowOtherThemes}
|
||||||
<ThemeResults {state} />
|
<ThemeResults {state} />
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"properties":{"name":"Bing Maps Aerial","id":"Bing","url":"https://ecn.t2.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=15066&pr=odbl&n=f","type":"bing","category":"photo","min_zoom":1,"max_zoom":22},"type":"Feature","geometry":null}
|
{"properties":{"name":"Bing Maps Aerial","id":"Bing","url":"https://ecn.t2.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=15075&pr=odbl&n=f","type":"bing","category":"photo","min_zoom":1,"max_zoom":22},"type":"Feature","geometry":null}
|
|
@ -465,6 +465,11 @@ code {
|
||||||
background-color: #b3b3b3;
|
background-color: #b3b3b3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.frozen-glass {
|
||||||
|
backdrop-filter: blur(1px);
|
||||||
|
background: rgba(100, 100, 100, 0.50);
|
||||||
|
}
|
||||||
|
|
||||||
/************************** UTILITY ************************/
|
/************************** UTILITY ************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue