chore: automated housekeeping...
This commit is contained in:
parent
14b2799f08
commit
4add2d1aff
151 changed files with 4561 additions and 3315 deletions
|
@ -810,6 +810,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
@ -1436,6 +1443,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -1667,6 +1681,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -803,6 +803,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1423,6 +1430,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -1653,6 +1667,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -701,6 +701,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
@ -1327,6 +1334,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -1558,6 +1572,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -694,6 +694,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1314,6 +1321,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -1544,6 +1558,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -482,6 +482,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -475,6 +475,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -509,6 +509,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -502,6 +502,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -556,6 +556,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -549,6 +549,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,6 +223,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -618,6 +625,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -223,6 +223,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
|
@ -611,6 +618,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -436,6 +436,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
|
@ -429,6 +429,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -167,6 +167,13 @@
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
|
|
@ -167,6 +167,13 @@ export default {
|
|||
"classes": {
|
||||
"description": "question: What css-classes should be applied to showing this attribute?\n\nA list of css-classes to apply to the entire tagRendering.\nThese classes are applied in 'answer'-mode, not in question mode\nThis is only for advanced users.\n\nValues are split on ` ` (space)",
|
||||
"type": "string"
|
||||
},
|
||||
"filter": {
|
||||
"description": "This tagRendering can introduce this builtin filter",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
|
|
@ -29,6 +29,7 @@ Available languages:
|
|||
- pl
|
||||
- it
|
||||
- da
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -35,6 +35,7 @@ Available languages:
|
|||
- it
|
||||
- pl
|
||||
- da
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Table of contents
|
||||
|
|
|
@ -28,6 +28,7 @@ Available languages:
|
|||
- cs
|
||||
- zh_Hant
|
||||
- pl
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Table of contents
|
||||
|
|
|
@ -21,6 +21,8 @@ Available languages:
|
|||
- fr
|
||||
- pl
|
||||
- da
|
||||
- es
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -29,6 +29,7 @@ Available languages:
|
|||
- zh_Hant
|
||||
- eu
|
||||
- pl
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -35,6 +35,7 @@ Available languages:
|
|||
- es
|
||||
- eu
|
||||
- pt
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -30,6 +30,7 @@ Available languages:
|
|||
- cs
|
||||
- eu
|
||||
- pl
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -33,6 +33,7 @@ Available languages:
|
|||
- it
|
||||
- pl
|
||||
- da
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -33,6 +33,7 @@ Available languages:
|
|||
- eu
|
||||
- pl
|
||||
- da
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -34,6 +34,7 @@ Available languages:
|
|||
- cs
|
||||
- eu
|
||||
- pl
|
||||
- zh_Hans
|
||||
|
||||
|
||||
# Layers defined in this theme configuration file
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/cafes_and_pubs cafes_and_pubs]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:da|en}}, {{#language:nb_NO|en}}, {{#language:pa_PK|en}}, {{#language:cs|en}}, {{#language:it|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:ca|en}}, {{#language:es|en}}, {{#language:fr|en}}, {{#language:da|en}}, {{#language:nb_NO|en}}, {{#language:pa_PK|en}}, {{#language:cs|en}}, {{#language:it|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: Coffeehouses, pubs and bars
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -103,7 +103,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/bookcases bookcases]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:hu|en}}, {{#language:es|en}}, {{#language:da|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:zh_Hant|en}}, {{#language:it|en}}, {{#language:hu|en}}, {{#language:es|en}}, {{#language:da|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: A public bookcase is a small streetside cabinet, box, old phone booth or some other objects where books are stored
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -112,7 +112,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/advertising advertising]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:ca|en}}, {{#language:es|en}}, {{#language:en|en}}, {{#language:de|en}}, {{#language:cs|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:ca|en}}, {{#language:es|en}}, {{#language:en|en}}, {{#language:de|en}}, {{#language:cs|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: Where I can find advertising features?
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -130,7 +130,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/atm atm]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:nb_NO|en}}, {{#language:es|en}}, {{#language:id|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:it|en}}, {{#language:pl|en}}, {{#language:da|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:fr|en}}, {{#language:nl|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:nb_NO|en}}, {{#language:es|en}}, {{#language:id|en}}, {{#language:zh_Hant|en}}, {{#language:eu|en}}, {{#language:it|en}}, {{#language:pl|en}}, {{#language:da|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: This map shows ATMs to withdraw or deposit money
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -148,7 +148,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/bicycle_parkings bicycle_parkings]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:es|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: A map showing all types of bicycle parkings
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -157,7 +157,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/bicycle_rental bicycle_rental]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:id|en}}, {{#language:fr|en}}, {{#language:es|en}}, {{#language:nb_NO|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:id|en}}, {{#language:fr|en}}, {{#language:es|en}}, {{#language:nb_NO|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: A map with bicycle rental stations and bicycle rental shops
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -166,7 +166,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/bicyclelib bicyclelib]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:nb_NO|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:es|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:nl|en}}, {{#language:en|en}}, {{#language:it|en}}, {{#language:ru|en}}, {{#language:ja|en}}, {{#language:fr|en}}, {{#language:zh_Hant|en}}, {{#language:de|en}}, {{#language:hu|en}}, {{#language:nb_NO|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:es|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: A bicycle library is a place where bicycles can be lent, often for a small yearly fee
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -175,7 +175,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/binoculars binoculars]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:it|en}}, {{#language:nb_NO|en}}, {{#language:zh_Hant|en}}, {{#language:hu|en}}, {{#language:fr|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:nl|en}}, {{#language:de|en}}, {{#language:it|en}}, {{#language:nb_NO|en}}, {{#language:zh_Hant|en}}, {{#language:hu|en}}, {{#language:fr|en}}, {{#language:es|en}}, {{#language:ca|en}}, {{#language:da|en}}, {{#language:cs|en}}, {{#language:eu|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: A map with fixed binoculars
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
@ -184,7 +184,7 @@
|
|||
{{service_item
|
||||
|name= [https://mapcomplete.org/blind_osm blind_osm]
|
||||
|region= Worldwide
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:nb_NO|en}}, {{#language:es|en}}, {{#language:eu|en}}, {{#language:it|en}}, {{#language:pl|en}}
|
||||
|lang= {{#language:en|en}}, {{#language:de|en}}, {{#language:nl|en}}, {{#language:fr|en}}, {{#language:ca|en}}, {{#language:cs|en}}, {{#language:nb_NO|en}}, {{#language:es|en}}, {{#language:eu|en}}, {{#language:it|en}}, {{#language:pl|en}}, {{#language:zh_Hans|en}}
|
||||
|descr= A MapComplete theme: Help to map features relevant for the blind
|
||||
|material= {{yes|[https://mapcomplete.org/ Yes]}}
|
||||
|image= MapComplete_Screenshot.png
|
||||
|
|
|
@ -471,7 +471,8 @@
|
|||
"if": "rental=cargo_bike",
|
||||
"then": {
|
||||
"en": "Cargo bikes can be rented here",
|
||||
"nl": "Bakfietsen kunnen hier gehuurd worden"
|
||||
"nl": "Bakfietsen kunnen hier gehuurd worden",
|
||||
"de": "Lastenräder können hier gemietet werden"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -87,7 +87,9 @@
|
|||
}
|
||||
],
|
||||
"lineRendering": [],
|
||||
"titleIcons": ["icons.defaults"],
|
||||
"titleIcons": [
|
||||
"icons.defaults"
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"title": {
|
||||
|
|
|
@ -526,10 +526,12 @@
|
|||
"type": "text",
|
||||
"key": "defibrillator:location:fr"
|
||||
},
|
||||
"condition": {"or":[
|
||||
"_country=be",
|
||||
"defibrillator:location:fr~*"
|
||||
]},
|
||||
"condition": {
|
||||
"or": [
|
||||
"_country=be",
|
||||
"defibrillator:location:fr~*"
|
||||
]
|
||||
},
|
||||
"id": "defibrillator-defibrillator:location:fr"
|
||||
},
|
||||
"wheelchair-access",
|
||||
|
|
|
@ -113,7 +113,8 @@
|
|||
"override": {
|
||||
"question": {
|
||||
"en": "Is the firepit available all around the year?",
|
||||
"nl": "Is deze kampvuurplaats heel het jaar door beschikbaar?"
|
||||
"nl": "Is deze kampvuurplaats heel het jaar door beschikbaar?",
|
||||
"de": "Ist diese Feuerstelle rund um das Jahr nutzbar?"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{"id": "lactosefree",
|
||||
{
|
||||
"id": "lactosefree",
|
||||
"labels": [
|
||||
"defaults",
|
||||
"in_favourite"
|
||||
|
@ -264,14 +265,19 @@
|
|||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"or":["diet:lactose_free=only","diet:lactose_free=yes","diet:lactose_free=limited"]
|
||||
"or": [
|
||||
"diet:lactose_free=only",
|
||||
"diet:lactose_free=yes",
|
||||
"diet:lactose_free=limited"
|
||||
]
|
||||
},
|
||||
"#": "ignore-image-in-then",
|
||||
"then": "<img alt='lactose free' src='./assets/layers/questions/lactose_free.svg'>"
|
||||
}
|
||||
]
|
||||
},
|
||||
{"id": "glutenfree",
|
||||
{
|
||||
"id": "glutenfree",
|
||||
"labels": [
|
||||
"defaults",
|
||||
"in_favourite"
|
||||
|
@ -279,14 +285,17 @@
|
|||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"or":["diet:gluten_free=only","diet:gluten_free=yes","diet:gluten_free=limited"]
|
||||
"or": [
|
||||
"diet:gluten_free=only",
|
||||
"diet:gluten_free=yes",
|
||||
"diet:gluten_free=limited"
|
||||
]
|
||||
},
|
||||
"#": "ignore-image-in-then",
|
||||
"then": "<img alt='gluten free' src='./assets/layers/questions/glutenfree.svg'>"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"id": "sharelink",
|
||||
"labels": [
|
||||
|
|
|
@ -439,7 +439,8 @@
|
|||
"en": "You can pick up missed parcels here",
|
||||
"de": "Hier können Sie verpasste Pakete abholen",
|
||||
"ca": "Podeu recollir els paquets perduts aquí",
|
||||
"cs": "Zmeškané zásilky si můžete vyzvednout zde"
|
||||
"cs": "Zmeškané zásilky si můžete vyzvednout zde",
|
||||
"nl": "Je kunt hier gemiste pakjes ophalen"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -463,7 +464,8 @@
|
|||
"question": {
|
||||
"en": "Can you send parcels to here for pickup?",
|
||||
"de": "Können Sie Pakete zur Abholung hierher schicken?",
|
||||
"ca": "Pots enviar paquets aquí per a arreplegar-los?"
|
||||
"ca": "Pots enviar paquets aquí per a arreplegar-los?",
|
||||
"nl": "Kun je deze plaats gebruiken als afhaalpunt?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "post_office:parcel_to",
|
||||
|
|
|
@ -633,7 +633,9 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.dogs"]
|
||||
"filter": [
|
||||
"filters.dogs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "description",
|
||||
|
@ -758,7 +760,9 @@
|
|||
"hideInAnswer": true
|
||||
}
|
||||
],
|
||||
"filter": ["filters.open_now"]
|
||||
"filter": [
|
||||
"filters.open_now"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "opening_hours_24_7",
|
||||
|
@ -1043,7 +1047,10 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.accepts_cash","filters.accepts_cards"]
|
||||
"filter": [
|
||||
"filters.accepts_cash",
|
||||
"filters.accepts_cards"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "payment-options-split",
|
||||
|
@ -2124,7 +2131,9 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.has_internet"]
|
||||
"filter": [
|
||||
"filters.has_internet"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "internet-fee",
|
||||
|
@ -2456,7 +2465,9 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.sugar_free"]
|
||||
"filter": [
|
||||
"filters.sugar_free"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "lactose_free",
|
||||
|
@ -2477,7 +2488,6 @@
|
|||
"cs": "<b>Prodává pouze výrobky bez laktózy</b>"
|
||||
},
|
||||
"icon": "./assets/layers/questions/lactose_free.svg"
|
||||
|
||||
},
|
||||
{
|
||||
"if": "diet:lactose_free=yes",
|
||||
|
@ -2487,7 +2497,6 @@
|
|||
"cs": "Velká nabídka bez laktózy"
|
||||
},
|
||||
"icon": "./assets/layers/questions/lactose_free.svg"
|
||||
|
||||
},
|
||||
{
|
||||
"if": "diet:lactose_free=limited",
|
||||
|
@ -2506,8 +2515,9 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.lactose_free"]
|
||||
|
||||
"filter": [
|
||||
"filters.lactose_free"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "gluten_free",
|
||||
|
@ -2555,8 +2565,9 @@
|
|||
}
|
||||
}
|
||||
],
|
||||
"filter": ["filters.gluten_free"]
|
||||
|
||||
"filter": [
|
||||
"filters.gluten_free"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "vegan",
|
||||
|
@ -2785,7 +2796,8 @@
|
|||
"id": "seasonal",
|
||||
"question": {
|
||||
"en": "Is {title()} available all around the year?",
|
||||
"nl": "Is {title()} heel het jaar beschikbaar?"
|
||||
"nl": "Is {title()} heel het jaar beschikbaar?",
|
||||
"de": "Ist {title()} rund um das Jahr nutzbar?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -2842,7 +2854,6 @@
|
|||
"en": "This facility does have showers"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"if": "shower=no",
|
||||
"icon": "invalid;./assets/layers/shower/shower.svg",
|
||||
|
|
|
@ -283,66 +283,77 @@
|
|||
{
|
||||
"id": "pedagogy",
|
||||
"question": {
|
||||
"en": "What educational theory is applied on this school?"
|
||||
"en": "What educational theory is applied on this school?",
|
||||
"de": "Welche Bildungstheorie wird auf dieser Schule angewendet?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "pedagogy=mainstream",
|
||||
"then": {
|
||||
"en": "This school does not use a specific pedagogy"
|
||||
"en": "This school does not use a specific pedagogy",
|
||||
"de": "Diese Schule benutzt keine spezifische Pädagogik"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=montessori",
|
||||
"then": {
|
||||
"en": "This school uses the Montessori method of education"
|
||||
"en": "This school uses the Montessori method of education",
|
||||
"de": "Diese Schule nutzt die Montessori Methode der Bildung"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=freinet",
|
||||
"then": {
|
||||
"en": "This school is associated with the Freinet Modern School Movement"
|
||||
"en": "This school is associated with the Freinet Modern School Movement",
|
||||
"de": "Diese Schule ist mit der Freinet Modern School Movement verbunden"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=jenaplan",
|
||||
"then": {
|
||||
"en": "This school uses the Jenaplan teaching concept"
|
||||
"en": "This school uses the Jenaplan teaching concept",
|
||||
"de": "Diese Schule nutzt das Lehrkonzept von Jenaplan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=waldorf",
|
||||
"then": {
|
||||
"en": "This school uses the Steiner/Waldorf educational philosophy"
|
||||
"en": "This school uses the Steiner/Waldorf educational philosophy",
|
||||
"de": "Diese Schule nutzt die Steiner/Waldorfer Bildungsphilosophie"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=dalton",
|
||||
"then": {
|
||||
"en": "This school uses the Dalton plan teaching concept"
|
||||
"en": "This school uses the Dalton plan teaching concept",
|
||||
"de": "Diese Schule nutzt das Dalton Plan Lehrkonzept"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=outdoor",
|
||||
"then": {
|
||||
"en": "This school uses outdoor learning"
|
||||
"en": "This school uses outdoor learning",
|
||||
"de": "Diese Schule nutzt Outdoor-Lernen"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=reggio_emilia",
|
||||
"then": {
|
||||
"en": "This school uses the Reggio Emilia approach"
|
||||
"en": "This school uses the Reggio Emilia approach",
|
||||
"de": "Diese Schule nutzt den Reggio Emilia-Ansatz"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "pedagogy=sudbury",
|
||||
"then": {
|
||||
"en": "This school uses the Sudbury system"
|
||||
"en": "This school uses the Sudbury system",
|
||||
"de": "Diese Schule nutzt das Sudbury-System"
|
||||
}
|
||||
}
|
||||
],
|
||||
"render": {
|
||||
"en": "This school uses {pedagogy}"
|
||||
"en": "This school uses {pedagogy}",
|
||||
"de": "Diese Schule benutzt {pedagogy}"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "pedagogy"
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"eu": "Publizitatea",
|
||||
"pl": "Reklamy",
|
||||
"it": "Pubblicità",
|
||||
"da": "Reklamer"
|
||||
"da": "Reklamer",
|
||||
"zh_Hans": "广告"
|
||||
},
|
||||
"description": {
|
||||
"ca": "Alguna vegada t'has preguntat quanta publictat hi ha als nostres carrers i carreteres? Amb aquest mapa podràs trobar i afegir informació de tots els elements publictaris que t'hi trobes pel carrer",
|
||||
|
@ -27,7 +28,8 @@
|
|||
"eu": "Inoiz pentsatu duzu zenbat iragarki dauden gure kale eta errepideetan? Mapa honekin, kalean aurki ditzakezun publizitate-ezaugarri guztiei buruzko informazioa aurkitu eta erants dezakezu",
|
||||
"pl": "Czy zastanawiałeś się kiedyś, ile reklam jest na naszych ulicach i drogach? Dzięki tej mapie możesz znaleźć i dodać informacje o wszystkich funkcjach reklamowych, które możesz znaleźć na ulicy",
|
||||
"pt": "Já se perguntou quantas propagandas existem nas nossas ruas e estradas? Com este mapa pode encontrar e adicionar informações sobre todos os recursos de publicidade que pode encontrar na rua",
|
||||
"it": "Vi siete mai chiesti quante pubblicità ci sono nelle nostre strade e strade? Con questa mappa è possibile trovare e aggiungere informazioni su tutte le caratteristiche pubblicitarie che si possono trovare sulla strada"
|
||||
"it": "Vi siete mai chiesti quante pubblicità ci sono nelle nostre strade e strade? Con questa mappa è possibile trovare e aggiungere informazioni su tutte le caratteristiche pubblicitarie che si possono trovare sulla strada",
|
||||
"zh_Hans": "你是否曾经想过我们的街道和道路上有多少广告?通过这张地图,你可以查找并添加有关街道上所有广告特征的信息"
|
||||
},
|
||||
"shortDescription": {
|
||||
"ca": "On puc trobar elements publicitaris?",
|
||||
|
@ -39,7 +41,8 @@
|
|||
"nl": "Waar zijn er reclameborden?",
|
||||
"zh_Hant": "我能夠在那裡找到廣告物件?",
|
||||
"eu": "Non aurki ditzaket publizitate ezaugarriak?",
|
||||
"pl": "Gdzie mogę znaleźć obiekty reklamowe?"
|
||||
"pl": "Gdzie mogę znaleźć obiekty reklamowe?",
|
||||
"zh_Hans": "我可以在哪里找到广告功能?"
|
||||
},
|
||||
"icon": "./assets/themes/advertising/icon.svg",
|
||||
"credits": [
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
"eu": "Kutxazain automatikoa",
|
||||
"it": "Sportelli bancomat",
|
||||
"pl": "Bankomaty",
|
||||
"da": "Hæveautomater"
|
||||
"da": "Hæveautomater",
|
||||
"zh_Hans": "自动取款机"
|
||||
},
|
||||
"description": {
|
||||
"en": "This map shows ATMs to withdraw or deposit money",
|
||||
|
@ -31,7 +32,8 @@
|
|||
"eu": "Mapa honek dirua atera edo sartzeko kutxazain automatikoak erakusten ditu",
|
||||
"it": "Questa mappa mostra gli sportelli Bancomat per ritirare o depositare del denaro",
|
||||
"pl": "Ta mapa pokazuje bankomaty, w których można wypłacać lub wpłacać pieniądze",
|
||||
"da": "Dette kort viser hæveautomater, hvor du kan hæve og indsætte kontanter"
|
||||
"da": "Dette kort viser hæveautomater, hvor du kan hæve og indsætte kontanter",
|
||||
"zh_Hans": "这张地图显示了可以取款或存款的自动取款机"
|
||||
},
|
||||
"icon": "./assets/themes/atm/logo.svg",
|
||||
"layers": [
|
||||
|
@ -99,7 +101,8 @@
|
|||
"it": "Importa questo sportello bancomat",
|
||||
"pl": "Importuj ten bankomat",
|
||||
"cs": "Importovat tento bankomat",
|
||||
"da": "Importer denne hæveautomat"
|
||||
"da": "Importer denne hæveautomat",
|
||||
"zh_Hans": "导入这个ATM"
|
||||
},
|
||||
"icon": "./assets/svg/addSmall.svg"
|
||||
}
|
||||
|
@ -116,7 +119,8 @@
|
|||
"cs": "OpenStreetMap ví o <a href='#{_closest_osm_poi}'> bankomatu, který je {_closest_osm_poi_distance} metr daleko.</a> ",
|
||||
"pl": "OpenStreetMap wie o <a href='#{_closest_osm_poi}'>bankomacie oddalonym o {_closest_osm_poi_distance} metry.</a> ",
|
||||
"nl": "OpenStreetMap kent <a href='#{_closest_osm_poi}'>een geldautomaat die {_closest_osm_poi_distance} meter weg is</a> ",
|
||||
"da": "OpenStreetMap kender <a href='#{_closest_osm_poi}'>en hæveautomatet, som ligger {_closest_osm_poi_distance} meter væk.</a> "
|
||||
"da": "OpenStreetMap kender <a href='#{_closest_osm_poi}'>en hæveautomatet, som ligger {_closest_osm_poi_distance} meter væk.</a> ",
|
||||
"zh_Hans": "OpenStreetMap 知道有一个<a href='#{_closest_osm_poi}'>自动取款机,它距离你 {_closest_osm_poi_distance} 米。</a> "
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -137,7 +141,8 @@
|
|||
"pl": "Dodaj wszystkie sugerowane znaczniki do najbliższego bankomatu",
|
||||
"cs": "Přidání všech navrhovaných značek do nejbližšího bankomatu",
|
||||
"nl": "Voeg alle gesuggereerde tags toe aan de dichtstbijzijnde geldautomaat",
|
||||
"da": "Tilføj alle foreslåede tags til den nærmeste hæveautomat"
|
||||
"da": "Tilføj alle foreslåede tags til den nærmeste hæveautomat",
|
||||
"zh_Hans": "将所有建议的标签添加到距离最近的自动取款机"
|
||||
},
|
||||
"image": "./assets/svg/addSmall.svg",
|
||||
"maproulette_id": "mr_taskId"
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
"es": "Ayudante de importación BAG",
|
||||
"cs": "Pomocník pro import BAG",
|
||||
"zh_Hant": "BAG 匯入助手",
|
||||
"pl": "Pomocnik importowy BAG"
|
||||
"pl": "Pomocnik importowy BAG",
|
||||
"zh_Hans": "BAG 导入助手"
|
||||
},
|
||||
"description": {
|
||||
"nl": "Dit thema helpt het importeren van BAG data",
|
||||
|
@ -22,7 +23,8 @@
|
|||
"zgh": "ⵉⵜⵜⴰⵡⵙ ⵉⵎⵔⵙⵉ ⴰⴷ ⴳ ⵡⴰⵎⵎⴰⵥ ⵏ ⵜⵎⵓⵛⴰ ⵙⴳ BAG",
|
||||
"es": "Este tema ayuda a importar datos de BAG",
|
||||
"eu": "Gai honek BAGeko datuak inportatzen laguntzen du",
|
||||
"pl": "Motyw ten pomaga w importowaniu danych z BAG"
|
||||
"pl": "Motyw ten pomaga w importowaniu danych z BAG",
|
||||
"zh_Hans": "这个主题帮助导入来自BAG的数据"
|
||||
},
|
||||
"shortDescription": {
|
||||
"nl": "BAG import helper tool",
|
||||
|
@ -33,7 +35,8 @@
|
|||
"es": "Herramienta de ayuda a la importación BAG",
|
||||
"cs": "Pomocný nástroj pro import BAG",
|
||||
"eu": "BAGak inportatzen laguntzeko tresna",
|
||||
"pl": "Narzędzie wspomagające import BAG"
|
||||
"pl": "Narzędzie wspomagające import BAG",
|
||||
"zh_Hans": "BAG 导入辅助工具"
|
||||
},
|
||||
"icon": "./assets/themes/bag/logo.svg",
|
||||
"startZoom": 9,
|
||||
|
@ -69,7 +72,8 @@
|
|||
"zgh": "ⵜⴳⴰ ⵜⵙⴰⵖⵓⵍⵜ ⴳ BAG <b>{ref:bag}</b>",
|
||||
"es": "La referencia de BAG es <b>{ref:bag}</b>",
|
||||
"cs": "Reference v BAG je <b>{ref:bag}</b>",
|
||||
"pl": "Numer referencyjny w BAG to <b>{ref:bag}</b>"
|
||||
"pl": "Numer referencyjny w BAG to <b>{ref:bag}</b>",
|
||||
"zh_Hans": "在 BAG 中的参考是 <b>{ref:bag}</b>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -83,7 +87,8 @@
|
|||
"ca": "Aquest edifici no té referència al BAG",
|
||||
"zgh": "ⵜⵓⵚⴽⴰ ⴰⴷ ⵓⵔ ⵖⵓⵔⵙ ⵜⴰⵙⴰⵖⵓⵍⵜ ⴳ BAG",
|
||||
"es": "Este edificio no tiene referencia en el BAG",
|
||||
"pl": "Budynek ten nie ma odniesienia w BAG"
|
||||
"pl": "Budynek ten nie ma odniesienia w BAG",
|
||||
"zh_Hans": "这栋建筑在BAG中没有参考信息"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -197,7 +202,8 @@
|
|||
"zgh": "ⵜⵓⵚⴽⴰⵡⵉⵏ ⵙⴳ ⵡⴰⵔⵔⴰ ⵏ BAG",
|
||||
"es": "Edificios del registro BAG",
|
||||
"cs": "Budovy z registru BAG",
|
||||
"pl": "Budynki z rejestru BAG"
|
||||
"pl": "Budynki z rejestru BAG",
|
||||
"zh_Hans": "BAG 注册中的建筑物"
|
||||
},
|
||||
"source": {
|
||||
"geoJson": "https://service.pdok.nl/lv/bag/wfs/v2_0?request=GetFeature&service=WFS&version=2.0.0&outputFormat=application%2Fjson%3B%20subtype%3Dgeojson&typeName=bag%3Apand&bbox={x_min}%2C{y_min}%2C{x_max}%2C{y_max}%2CCRS84&srsName=EPSG%3A4326",
|
||||
|
@ -252,7 +258,8 @@
|
|||
"cs": "Zatím nebyly vypočteny správné hodnoty. Aktualizujte stránku",
|
||||
"nb_NO": "Har ikke regnet ut riktige verdier enda. Gjenoppfrisk siden.",
|
||||
"es": "Aún no se han calculado los valores correctos. Actualice esta página",
|
||||
"pl": "Jeszcze nie obliczono poprawnych wartości. Odśwież tę stronę"
|
||||
"pl": "Jeszcze nie obliczono poprawnych wartości. Odśwież tę stronę",
|
||||
"zh_Hans": "尚未计算出正确的值。请刷新此页面"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -281,7 +288,8 @@
|
|||
"ca": "La referència a BAG és <b>{_bag_obj:ref:bag}</b>",
|
||||
"es": "La referencia en BAG es <b>{_bag_obj:ref:bag}</b>",
|
||||
"cs": "Reference v BAG je <b>{_bag_obj:ref:bag}</b>",
|
||||
"pl": "Odniesienie w BAG to <b>{_bag_obj:ref:bag}</b>"
|
||||
"pl": "Odniesienie w BAG to <b>{_bag_obj:ref:bag}</b>",
|
||||
"zh_Hans": "在 BAG 中的参考文献是 <b>{_bag_obj:ref:bag}</b>"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -297,7 +305,8 @@
|
|||
"cs": "Tato budova byla postavena v <b>{_bag_obj:start_date}</b>",
|
||||
"nb_NO": "Bygning oppført <b>{_bag_obj:start_date}</b>",
|
||||
"pl": "Ten budynek zbudowano w <b>{_bag_obj:start_date}</b>",
|
||||
"pt": "Esta construção é de <b>{_bag_obj:start_date}</b>"
|
||||
"pt": "Esta construção é de <b>{_bag_obj:start_date}</b>",
|
||||
"zh_Hans": "这座建筑建于 <b>{_bag_obj:start_date}</b>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -311,7 +320,8 @@
|
|||
"cs": "Stavba byla zahájena v <b>{_bag_obj:start_date}</b>",
|
||||
"nb_NO": "Oppføring startet <b>{_bag_obj:start_date}</b>",
|
||||
"es": "Este edificio se empezó a construir en <b>{_bag_obj:start_date}</b>",
|
||||
"pl": "Budynek został zbudowany w <b>{_bag_obj:start_date}</b>"
|
||||
"pl": "Budynek został zbudowany w <b>{_bag_obj:start_date}</b>",
|
||||
"zh_Hans": "该建筑始建于 <b>{_bag_obj:start_date}</b>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -327,7 +337,8 @@
|
|||
"cs": "Typ budovy je <b>{_bag_obj:building}.</b>",
|
||||
"nb_NO": "Dette er en bygning av typen <b>{_bag_obj:building}</b>",
|
||||
"es": "El edificio es de tipo <b>{_bag_obj:building}</b>",
|
||||
"pl": "Rodzaj budynku to <b>{_bag_obj:building}</b>"
|
||||
"pl": "Rodzaj budynku to <b>{_bag_obj:building}</b>",
|
||||
"zh_Hans": "建筑类型是 <b>{_bag_obj:building}</b>"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -340,7 +351,8 @@
|
|||
"ca": "El tipus d'edifici serà <b>{_bag_obj:construction}</b>",
|
||||
"cs": "Typ budovy bude <b>{_bag_obj:construction}</b>",
|
||||
"es": "El tipo de edificio será un <b>{_bag_obj:construction}</b>",
|
||||
"pl": "Budynek będzie o typie <b>{_bag_obj:construction}</b>"
|
||||
"pl": "Budynek będzie o typie <b>{_bag_obj:construction}</b>",
|
||||
"zh_Hans": "建筑类型将是 <b>{_bag_obj:construction}</b>"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
"da": "Dette kort viser alle bænke, der er registreret i OpenStreetMap: Individuelle bænke og bænke, der hører til offentlige transportpladser eller shelters. Med en OpenStreetMap-konto kan du kortlægge nye bænke eller redigere detaljer om eksisterende bænke.",
|
||||
"cs": "Tato mapa zobrazuje všechny lavičky, které jsou zaznamenány v OpenStreetMap: samostatné lavičky a lavičky patřící k zastávkám veřejné dopravy nebo přístřeškům.",
|
||||
"eu": "OpenStreetMap-en erregistratzen diren banku guztiak erakusten ditu mapa honek: garraio publikoko geralekuetako edo babeslekuetako banakako bankuak eta bankuak.",
|
||||
"pl": "Mapa ta pokazuje wszystkie ławki zarejestrowane w OpenStreetMap: ławki indywidualne oraz ławki należące do przystanków komunikacji miejskiej lub wiat."
|
||||
"pl": "Mapa ta pokazuje wszystkie ławki zarejestrowane w OpenStreetMap: ławki indywidualne oraz ławki należące do przystanków komunikacji miejskiej lub wiat.",
|
||||
"zh_Hans": "这张地图显示了所有记录在 OpenStreetMap 中的长椅:包括独立长椅和属于公共交通站点或候车亭的长椅。"
|
||||
},
|
||||
"shortDescription": {
|
||||
"en": "A map of benches",
|
||||
|
|
|
@ -6,11 +6,15 @@
|
|||
"ca": "Aparcament de bicicletes",
|
||||
"fr": "Stationnement vélo",
|
||||
"pl": "Parkingi dla rowerów",
|
||||
"da": "Cykelparkering"
|
||||
"da": "Cykelparkering",
|
||||
"es": "Aparcamiento de bicicletas",
|
||||
"zh_Hans": "自行车停车场"
|
||||
},
|
||||
"description": {
|
||||
"en": "A map showing all types of bicycle parkings",
|
||||
"de": "Eine Karte mit allen Arten von Fahrradabstellplätzen"
|
||||
"de": "Eine Karte mit allen Arten von Fahrradabstellplätzen",
|
||||
"es": "Un mapa que muestra todos los tipos de aparcamientos de bicicletas",
|
||||
"zh_Hans": "一张显示所有类型自行车停车设施的地图"
|
||||
},
|
||||
"icon": "./assets/themes/bicycle_parkings/logo.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
"cs": "Půjčovna kol",
|
||||
"zh_Hant": "單車租借站",
|
||||
"eu": "Bizikleta alokairua",
|
||||
"pl": "Wypożyczanie rowerów"
|
||||
"pl": "Wypożyczanie rowerów",
|
||||
"zh_Hans": "自行车租赁"
|
||||
},
|
||||
"description": {
|
||||
"en": "On this map, you'll find the many bicycle rental stations as they are known by OpenStreetMap",
|
||||
|
@ -28,7 +29,8 @@
|
|||
"cs": "Na této mapě najdete půjčovny jízdních kol, jak jsou uvedeny v OpenStreetMap",
|
||||
"eu": "Mapa honetan aurkituko dituzu bizikletak alokatzeko OpenStreetMap-ek ezagutzen dituen estazio ugari",
|
||||
"it": "In questa mappa trovi i luoghi conosciuti da OpenStreetMap dove puoi noleggiare delle biciclette",
|
||||
"pl": "Na tej mapie znajdziesz wiele stacji wynajmu rowerów, znanych w OpenStreetMap"
|
||||
"pl": "Na tej mapie znajdziesz wiele stacji wynajmu rowerów, znanych w OpenStreetMap",
|
||||
"zh_Hans": "在这张地图上,你可以找到许多由 OpenStreetMap 记录的自行车租赁站点"
|
||||
},
|
||||
"shortDescription": {
|
||||
"en": "A map with bicycle rental stations and bicycle rental shops",
|
||||
|
@ -42,7 +44,8 @@
|
|||
"da": "Et kort med cykeludlejningsstationer og cykeludlejningsbutikker",
|
||||
"cs": "Mapa se stanicemi a obchody pro vypůjčení kol",
|
||||
"eu": "Bizikletak alokatzeko estazioen eta bizikletak alokatzeko denden mapa",
|
||||
"pl": "Mapa ze stacjami wypożyczania rowerów i wypożyczalniami rowerów"
|
||||
"pl": "Mapa ze stacjami wypożyczania rowerów i wypożyczalniami rowerów",
|
||||
"zh_Hans": "一张包含自行车租赁站点和自行车租赁商店的地图"
|
||||
},
|
||||
"icon": "./assets/themes/bicycle_rental/logo.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
"cs": "Bicycle libraries",
|
||||
"es": "Bibliotecas de bicicletas",
|
||||
"eu": "Bizikleta liburutegia",
|
||||
"pt": "Bibliotecas de bicicletas"
|
||||
"pt": "Bibliotecas de bicicletas",
|
||||
"zh_Hans": "自行车图书馆"
|
||||
},
|
||||
"description": {
|
||||
"nl": "Een fietsbibliotheek is een plaats waar men een fiets kan lenen, vaak voor een klein bedrag per jaar. Een typisch voorbeeld zijn kinderfietsbibliotheken, waar men een fiets op maat van het kind kan lenen. Is het kind de fiets ontgroeid, dan kan het te kleine fietsje omgeruild worden voor een grotere.",
|
||||
|
@ -38,7 +39,8 @@
|
|||
"cs": "\"Bicycle library\" je místo, kde si lze půjčit jízdní kola, často za malý roční poplatek. Významným případem použití jsou \"bicycle libraries\" pro děti, které jim umožňují vyměnit kolo za větší, když ze svého stávajícího kola vyrostou",
|
||||
"es": "Una biblioteca de bicicletas es un lugar donde se prestan bicicletas, a menudo por una pequeña cuota anual. Un caso de uso notable son las bibliotecas de bicicletas para niños, que les permiten cambiar por una bicicleta más grande cuando les queda pequeña",
|
||||
"eu": "Bizikletak uzteko lekua da bizikleta-liburutegia, askotan urteko kuota txiki baten truke. Kasu aipagarri bat haurrentzako bizikleta-liburutegiak dira, egungo bizikleta gainditu dutenean bizikleta handiago baterako aldatzeko aukera ematen dietenak",
|
||||
"pl": "Biblioteka rowerowa to miejsce, w którym można wypożyczyć rowery, często za niewielką opłatą roczną. Godnym uwagi przypadkiem zastosowania są biblioteki rowerowe dla dzieci, które pozwalają im zmienić rower na większy, gdy wyrosną z obecnego roweru"
|
||||
"pl": "Biblioteka rowerowa to miejsce, w którym można wypożyczyć rowery, często za niewielką opłatą roczną. Godnym uwagi przypadkiem zastosowania są biblioteki rowerowe dla dzieci, które pozwalają im zmienić rower na większy, gdy wyrosną z obecnego roweru",
|
||||
"zh_Hans": "自行车图书馆是一个可以借用自行车的地方,通常需要支付小额的年度费用。一个显著的使用场景是儿童自行车图书馆,这允许孩子们在长大后更换成更大的自行车"
|
||||
},
|
||||
"icon": "./assets/themes/bicyclelib/logo.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
"pa_PK": "بائینوکولر",
|
||||
"cs": "Dalekohledy",
|
||||
"eu": "Binokularrak",
|
||||
"pl": "Lornetki"
|
||||
"pl": "Lornetki",
|
||||
"zh_Hans": "望远镜"
|
||||
},
|
||||
"description": {
|
||||
"en": "A map with binoculars fixed in place with a pole. It can typically be found on touristic locations, viewpoints, on top of panoramic towers or occasionally on a nature reserve.",
|
||||
|
@ -31,7 +32,8 @@
|
|||
"da": "Et kort over udsigtskikkert fastgjort på en stang. Det kan typisk findes på turistmæssige steder, udsigtspunkter, på toppen af panoramatårne eller lejlighedsvis på et naturreservat.",
|
||||
"cs": "Mapa s dalekohledem upevněným na místě pomocí tyče. Obvykle se nachází na turistických místech, rozhlednách, vrcholech panoramatických věží nebo příležitostně v přírodních rezervacích.",
|
||||
"eu": "Zutoin batean prismatiko finkoak dituen mapa. Leku turistikoetan, begiratokietan, dorre panoramikoen gainean edo, batzuetan, erreserba natural batean egoten da.",
|
||||
"pl": "Mapa z lornetkami zamocowanymi na słupku. Zwykle można je odnaleźć w lokalizacjach turystycznych, punktach widokowych, na szczytach wież panoramicznych lub czasami w rezerwacie przyrody."
|
||||
"pl": "Mapa z lornetkami zamocowanymi na słupku. Zwykle można je odnaleźć w lokalizacjach turystycznych, punktach widokowych, na szczytach wież panoramicznych lub czasami w rezerwacie przyrody.",
|
||||
"zh_Hans": "一张显示固定在杆子上的望远镜的地图。这种望远镜通常可以在旅游景点、观景点、全景塔顶部或偶尔在自然保护区找到。"
|
||||
},
|
||||
"shortDescription": {
|
||||
"en": "A map with fixed binoculars",
|
||||
|
@ -47,7 +49,8 @@
|
|||
"da": "Et kort over fastgjorte kikkerter",
|
||||
"cs": "Mapa s pevnými dalekohledy",
|
||||
"eu": "Prismatiko finkoak dituen mapa",
|
||||
"pl": "Mapa ze stałymi lornetkami"
|
||||
"pl": "Mapa ze stałymi lornetkami",
|
||||
"zh_Hans": "一张显示固定望远镜的地图"
|
||||
},
|
||||
"icon": "./assets/layers/binocular/telescope.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
"eu": "OSM itsuentzat",
|
||||
"it": "OSM per i non vedenti",
|
||||
"pl": "OSM dla niewidomych",
|
||||
"da": "OSM for blinde"
|
||||
"da": "OSM for blinde",
|
||||
"zh_Hans": "为盲人设计的OSM"
|
||||
},
|
||||
"description": {
|
||||
"en": "Help to map features relevant for the blind",
|
||||
|
@ -26,7 +27,8 @@
|
|||
"es": "Ayuda para cartografiar elementos relevantes para invidentes",
|
||||
"eu": "Itsuentzako elementu garrantzitsuak kartografiatzeko laguntza",
|
||||
"it": "Aiuta a mappare le caratteristiche importanti per i non vedenti",
|
||||
"pl": "Pomóż umieszczać na mapie obiekty ważne dla niewidomych"
|
||||
"pl": "Pomóż umieszczać na mapie obiekty ważne dla niewidomych",
|
||||
"zh_Hans": "帮助绘制与盲人相关的设施"
|
||||
},
|
||||
"icon": "./assets/themes/blind_osm/Blindicon.svg",
|
||||
"startZoom": 20,
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
"cs": "Veřejné knihovničky",
|
||||
"eu": "Apalategi publikoak",
|
||||
"pl": "Publiczne regały na książki",
|
||||
"da": "Bogbytteskabe"
|
||||
"da": "Bogbytteskabe",
|
||||
"zh_Hans": "公共书柜"
|
||||
},
|
||||
"description": {
|
||||
"en": "A public bookcase is a small streetside cabinet, box, old phone booth or some other objects where books are stored. Everyone can place or take a book. This map aims to collect all these bookcases.",
|
||||
|
@ -35,7 +36,8 @@
|
|||
"ca": "Una llibreria pública és un xicotet armari al carrer, una caixa, una vella cabina telefònica o algun altre objecte on es guarden llibres. Tothom pot col·locar o agafar un llibre. Aquest mapa pretén recollir totes aquestes llibreries.",
|
||||
"cs": "Veřejná knihovna je malá pouliční skříňka, krabice, stará telefonní budka nebo jiný předmět, ve kterém jsou uloženy knihy. Kdokoliv do ní může umístit, nebo si z ní vzít knihu. Cílem této mapy je shromáždit všechny tyto knihovny.",
|
||||
"eu": "Kale-liburutegi publiko bat kale-armairu txiki bat da, kaxa, telefono-kabina zaharra edo liburuak gordetzeko beste objektu batzuk. Guztiek jar edo har dezakete liburu bat. Koaderno horiek guztiak biltzea da mapa honen helburua.",
|
||||
"pl": "Publiczny regał na książki to mała przyuliczna szafka, pudełko, stara budka telefoniczna lub inne przedmioty, w których przechowywane są książki. Każdy może w nich zostawić lub zabrać książkę. Celem tej mapy jest zebranie wszystkich tych regałów."
|
||||
"pl": "Publiczny regał na książki to mała przyuliczna szafka, pudełko, stara budka telefoniczna lub inne przedmioty, w których przechowywane są książki. Każdy może w nich zostawić lub zabrać książkę. Celem tej mapy jest zebranie wszystkich tych regałów.",
|
||||
"zh_Hans": "公共书柜是一个小型街边橱柜、盒子、旧电话亭或其他储存书籍的物品。任何人都可以放置或取走一本书。这张地图旨在收集所有这些书柜。"
|
||||
},
|
||||
"icon": "./assets/themes/bookcases/bookcase.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
"pa_PK": "کیفے یا پب",
|
||||
"cs": "Kavárny a hospody",
|
||||
"eu": "Kafetegiak eta pubak",
|
||||
"pl": "Kawiarnie i puby"
|
||||
"pl": "Kawiarnie i puby",
|
||||
"zh_Hans": "咖啡馆和酒吧"
|
||||
},
|
||||
"description": {
|
||||
"en": "Coffeehouses, pubs and bars",
|
||||
|
@ -33,7 +34,8 @@
|
|||
"it": "Pub e bar",
|
||||
"zh_Hant": "咖啡廳、俱樂部與酒吧",
|
||||
"eu": "Kafetegiak, pubak eta tabernak",
|
||||
"pl": "Kawiarnie, puby i bary"
|
||||
"pl": "Kawiarnie, puby i bary",
|
||||
"zh_Hans": "咖啡馆、酒吧和酒吧"
|
||||
},
|
||||
"icon": "./assets/layers/cafe_pub/pub.svg",
|
||||
"layers": [
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
"da": "Denne side samler alle officielle camper-stopsteder og steder, hvor du kan dumpe gråt og sort vand. Du kan tilføje detaljer om de leverede tjenester og omkostningerne. Tilføj billeder og anmeldelser. Dette er en hjemmeside og en webapp. Dataene gemmes i OpenStreetMap, så de vil være gratis for evigt og kan genbruges af enhver app.",
|
||||
"cs": "Na této stránce jsou shromážděna všechna oficiální místa pro zastavení karavanů a místa, kde můžete vypouštět šedou a černou vodu. Můžete přidat podrobnosti o poskytovaných službách a cenách. Přidávejte fotografie a recenze.",
|
||||
"eu": "Karabanak gelditzeko leku ofizial guztiak eta ur gris eta beltzak botatzeko lekuak biltzen ditu. Emandako zerbitzuei eta kostuari buruzko xehetasunak gehitu ditzakezu. Erantsi argazkiak eta aipamenak.",
|
||||
"pl": "Na tej stronie zebrano wszystkie oficjalne miejsca postoju kamperów oraz miejsca, w których można wylać zanieczyszczoną wodę. Możesz dodać szczegóły dotyczące świadczonych usług i kosztów. Dodaj zdjęcia i recenzje."
|
||||
"pl": "Na tej stronie zebrano wszystkie oficjalne miejsca postoju kamperów oraz miejsca, w których można wylać zanieczyszczoną wodę. Możesz dodać szczegóły dotyczące świadczonych usług i kosztów. Dodaj zdjęcia i recenzje.",
|
||||
"zh_Hans": "该网站汇总了所有官方的露营车停留点以及可以倾倒灰水和黑水的地点。你可以添加有关提供的服务和费用的详细信息,并且可以上传图片和撰写评论。"
|
||||
},
|
||||
"shortDescription": {
|
||||
"en": "Find sites to spend the night with your camper",
|
||||
|
@ -83,7 +84,8 @@
|
|||
"pa_PK": "کیمبسائیٹاں",
|
||||
"cs": "Kempovací místa",
|
||||
"eu": "Akanpatzeko tokiak",
|
||||
"pl": "Miejsca kamperowe"
|
||||
"pl": "Miejsca kamperowe",
|
||||
"zh_Hans": "露营地"
|
||||
},
|
||||
"minzoom": 7,
|
||||
"source": {
|
||||
|
@ -159,7 +161,8 @@
|
|||
"pa_PK": "کیمبسائیٹاں",
|
||||
"cs": "kempovací místa",
|
||||
"eu": "Kanpatzeko tokiak",
|
||||
"pl": "miejsca dla kamperów"
|
||||
"pl": "miejsca dla kamperów",
|
||||
"zh_Hans": "露营地"
|
||||
},
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
|
@ -226,7 +229,8 @@
|
|||
"cs": "Účtuje si toto místo poplatek?",
|
||||
"eu": "Leku horrek kuota bat kobratzen du?",
|
||||
"pl": "Czy to miejsce pobiera opłatę?",
|
||||
"pt": "Este lugar cobra alguma taxa?"
|
||||
"pt": "Este lugar cobra alguma taxa?",
|
||||
"zh_Hans": "这个地方是否收费?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -253,7 +257,8 @@
|
|||
"cs": "Použití je zpoplatněno",
|
||||
"eu": "Erabiltzeko ordaindu behar duzu",
|
||||
"pl": "Wymagana jest opłata, aby skorzystać",
|
||||
"pt": "Deve pagar para usar"
|
||||
"pt": "Deve pagar para usar",
|
||||
"zh_Hans": "需要付费使用"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -275,7 +280,8 @@
|
|||
"ca": "Es pot utilitzar gratuïtament",
|
||||
"cs": "Lze použít zdarma",
|
||||
"pl": "Można skorzystać za darmo",
|
||||
"pt": "Pode ser usado de graça"
|
||||
"pt": "Pode ser usado de graça",
|
||||
"zh_Hans": "可免费使用"
|
||||
},
|
||||
"addExtraTags": [
|
||||
"charge="
|
||||
|
@ -301,7 +307,8 @@
|
|||
"cs": "Toto místo si účtuje {charge}",
|
||||
"eu": "Leku honek {charge} kobratzen du",
|
||||
"pl": "To miejsce pobiera opłatę w wysokości {charge}",
|
||||
"pt": "Este lugar cobra {charge}"
|
||||
"pt": "Este lugar cobra {charge}",
|
||||
"zh_Hans": "这个地方收费 {charge}"
|
||||
},
|
||||
"question": {
|
||||
"en": "How much does this place charge?",
|
||||
|
@ -320,7 +327,8 @@
|
|||
"cs": "Kolik si toto místo účtuje?",
|
||||
"eu": "Zenbat kobratzen du leku honek?",
|
||||
"pl": "Ile kosztuje to miejsce?",
|
||||
"pt": "Quanto este lugar cobra?"
|
||||
"pt": "Quanto este lugar cobra?",
|
||||
"zh_Hans": "这个地方的收费是多少?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "charge"
|
||||
|
@ -422,7 +430,8 @@
|
|||
"cs": "{capacity} táborníků může toto místo využívat současně",
|
||||
"eu": "{capacity} kanpinlariek aldi berean erabil dezakete leku hau",
|
||||
"pl": "{capacity} kamperów może z tego miejsca korzystać jednocześnie",
|
||||
"pt": "{capacity} campistas podem usar este lugar ao mesmo tempo"
|
||||
"pt": "{capacity} campistas podem usar este lugar ao mesmo tempo",
|
||||
"zh_Hans": "{capacity} 名露营者可以同时使用这个地方"
|
||||
},
|
||||
"question": {
|
||||
"en": "How many campers can stay here? (skip if there is no obvious number of spaces or allowed vehicles)",
|
||||
|
@ -440,7 +449,8 @@
|
|||
"cs": "Kolik táborníků zde může zůstat? (přeskočte, pokud není zjevný počet míst nebo povolených vozidel)",
|
||||
"eu": "Zenbat kanpinlari gera daitezke hemen? (jauzi egin leku edo ibilgailu kopuru nabaririk ez badago)",
|
||||
"pl": "Ile kamperów może tu przebywać? (pomiń, jeśli nie ma oczywistej liczby miejsc lub dozwolonych pojazdów)",
|
||||
"pt": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)"
|
||||
"pt": "Quantos campistas podem ficar aqui? (pule se não houver um número óbvio de vagas ou veículos permitidos)",
|
||||
"zh_Hans": "这里可以容纳多少辆露营车?(如果没有明显的车位数量或允许的车辆数,请跳过)"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "capacity",
|
||||
|
@ -468,7 +478,8 @@
|
|||
"cs": "Poskytuje toto místo připojení k internetu?",
|
||||
"eu": "Leku honek Interneterako sarbidea eskaintzen du?",
|
||||
"pl": "Czy to miejsce oferuje dostęp do internetu?",
|
||||
"pt": "Este lugar fornece acesso a internet?"
|
||||
"pt": "Este lugar fornece acesso a internet?",
|
||||
"zh_Hans": "这里有网络连接吗?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
|
@ -494,7 +505,8 @@
|
|||
"nb_NO": "Det finnes tilgang til Internett",
|
||||
"cs": "Připojení k internetu je k dispozici",
|
||||
"pl": "Jest dostęp do internetu",
|
||||
"pt": "Há acesso à internet"
|
||||
"pt": "Há acesso à internet",
|
||||
"zh_Hans": "这里有网络连接"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -521,7 +533,8 @@
|
|||
"ca": "Hi ha accés a Internet",
|
||||
"cs": "Připojení k internetu je k dispozici",
|
||||
"pl": "Jest dostęp do internetu",
|
||||
"pt": "Há acesso à Internet"
|
||||
"pt": "Há acesso à Internet",
|
||||
"zh_Hans": "这里有网络连接"
|
||||
},
|
||||
"hideInAnswer": true
|
||||
},
|
||||
|
@ -548,7 +561,8 @@
|
|||
"ca": "No hi ha accés a Internet",
|
||||
"cs": "Připojení k internetu není k dispozici",
|
||||
"pl": "Nie ma dostępu do internetu",
|
||||
"pt": "Não há acesso à internet"
|
||||
"pt": "Não há acesso à internet",
|
||||
"zh_Hans": "这里没有网络连接"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -596,7 +610,8 @@
|
|||
"ca": "Heu de pagar un extra per accedir a Internet",
|
||||
"cs": "Přístup k internetu je možný za poplatek",
|
||||
"pl": "Dostęp do internetu jest dodatkowo płatny",
|
||||
"pt": "Deve pagar um suplemento pelo acesso à internet"
|
||||
"pt": "Deve pagar um suplemento pelo acesso à internet",
|
||||
"zh_Hans": "互联网访问需要额外付费"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -621,7 +636,8 @@
|
|||
"ca": "No cal pagar extra per l'accés a Internet",
|
||||
"cs": "Přístup k internetu je možný bez poplatku",
|
||||
"pl": "Dostęp do internetu nie jest dodatkowo płatny",
|
||||
"pt": "Não precisa pagar um suplemento pelo acesso à internet"
|
||||
"pt": "Não precisa pagar um suplemento pelo acesso à internet",
|
||||
"zh_Hans": "互联网访问无需额外付费"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
@ -868,7 +884,8 @@
|
|||
"ca": "Més detalls sobre aquest lloc: {description}",
|
||||
"cs": "Další podrobnosti o tomto místě: {description}",
|
||||
"pl": "Więcej szczegółów o tym miejscu: {description}",
|
||||
"pt": "Mais pormenores sobre este lugar: {description}"
|
||||
"pt": "Mais pormenores sobre este lugar: {description}",
|
||||
"zh_Hans": "关于此地的更多细节:{description}"
|
||||
},
|
||||
"question": {
|
||||
"en": "Would you like to add a general description of this place? (Do not repeat information previously asked or shown above. Please keep it objective - opinions go into the reviews)",
|
||||
|
@ -885,7 +902,8 @@
|
|||
"nb_NO": "Vil du legge til en generell beskrivelse av dette stedet? (Ikke gjenta info det har blitt spurt om eller som vises ovenfor. Hold det objektivt. Meninger henvises til vurderingene.)",
|
||||
"cs": "Chcete přidat obecný popis tohoto místa? (Neopakujte informace, na které jsme se ptali dříve, nebo které byly uvedeny výše. Zachovejte prosím objektivitu - názory patří do hodnocení)",
|
||||
"eu": "Gustatuko litzaizuke toki honen deskribapen orokorra gehitzea? (Ez errepikatu aurretik eskatutako edo adierazitako informazioa. Mesedez, eutsi helburuari - berrikuspenetarako iritziak)",
|
||||
"pl": "Chcesz dodać ogólny opis tego miejsca? (Nie powtarzaj informacji zadanych wcześniej lub pokazanych powyżej. Zachowaj obiektywizm – opinie trafiają do recenzji)"
|
||||
"pl": "Chcesz dodać ogólny opis tego miejsca? (Nie powtarzaj informacji zadanych wcześniej lub pokazanych powyżej. Zachowaj obiektywizm – opinie trafiają do recenzji)",
|
||||
"zh_Hans": "您想添加一个关于此地的一般描述吗?(请勿重复之前询问或显示的信息。请保持客观——意见和评价请在评论中提供)"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "description",
|
||||
|
@ -919,7 +937,8 @@
|
|||
"cs": "kempovací místa",
|
||||
"eu": "Kanpin bat",
|
||||
"pl": "miejsce dla kampera",
|
||||
"pt": "uma local de acampamento"
|
||||
"pt": "uma local de acampamento",
|
||||
"zh_Hans": "露营地"
|
||||
},
|
||||
"description": {
|
||||
"en": "Add a new official camper site. These are designated places to stay overnight with your camper. They might look like a real camping or just look like a parking. They might not be signposted at all, but just be defined in a municipal decision. A regular parking intended for campers where it is not expected to spend the night, is -not- a camper site ",
|
||||
|
@ -936,7 +955,8 @@
|
|||
"da": "Tilføj en ny officiel campingplads. Disse er udpegede steder at overnatte med din autocamper. De kan ligne en rigtig campingplads eller bare ligne en parkeringsplads. De er måske slet ikke skiltet, men er blot defineret i en kommunal beslutning. En almindelig parkering beregnet til campister, hvor det ikke forventes at overnatte, er -ikke- en autocamperplads ",
|
||||
"cs": "Přidejte nové oficiální kempovací místo. Jedná se o místa, určená pro přenocování s karavanem. Mohou vypadat jako skutečný kemp nebo jen jako parkoviště. Takováto místa nemusí být označena, ale stačí, pokud jsou pouze definována v rozhodnutí obce. Běžné parkoviště určené pro táborníky, kde se nepovažuje za kempovací místo. ",
|
||||
"eu": "Kanpaleku ofizialeko beste leku bat gehitu du. Gaua zure karabanarekin igarotzeko lekuak dira. Benetako kanpin baten edo, besterik gabe, aparkaleku baten itxura izan dezakete. Baliteke ez egotea inola ere seinaleztatuta, baizik eta udal erabaki batean definitzea. Kanpinlarientzako aparkaleku arrunt bat ez da kanpin bat, gaua bertan pasatzea espero ez bada ere. ",
|
||||
"pl": "Dodaj nowe oficjalne miejsce dla kamperów. Są to wyznaczone miejsca, w których można przenocować w swoim kamperze. Mogą wyglądać jak prawdziwy kemping lub po prostu wyglądać jak parking. Mogą one w ogóle nie być oznakowane, a jedynie określone w decyzji gminy. Zwykły parking przeznaczony dla kamperów, na którym nie przewiduje się nocowania, nie jest miejscem dla kamperów "
|
||||
"pl": "Dodaj nowe oficjalne miejsce dla kamperów. Są to wyznaczone miejsca, w których można przenocować w swoim kamperze. Mogą wyglądać jak prawdziwy kemping lub po prostu wyglądać jak parking. Mogą one w ogóle nie być oznakowane, a jedynie określone w decyzji gminy. Zwykły parking przeznaczony dla kamperów, na którym nie przewiduje się nocowania, nie jest miejscem dla kamperów ",
|
||||
"zh_Hans": "添加一个新的官方露营车场地。这些是专门设置的供露营车过夜的地点。它们可能看起来像真正的露营地,也可能只是看起来像一个停车场。它们可能没有任何标识,仅在市政决策中定义。普通的停车场,尽管可能供露营车使用,但不期望在其中过夜的,不算作露营车场地 "
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"da": "Etymology - hvad er et sted opkaldt efter?",
|
||||
"nb_NO": "Åpent etymologikart",
|
||||
"cs": "Etymologie - podle čeho se ulice jmenuje?",
|
||||
"es": "Etimología - a qué se debe el nombre de una calle?",
|
||||
"es": "Etimología: ¿De qué recibe el nombre un lugar?",
|
||||
"pl": "Etymologia - od czego pochodzi nazwa ulicy?"
|
||||
},
|
||||
"description": {
|
||||
|
|
|
@ -45,18 +45,21 @@
|
|||
"id": "historic",
|
||||
"question": {
|
||||
"en": "Is this a ghost sign?",
|
||||
"de": "Ist das ein Geisterzeichen?"
|
||||
"de": "Ist das ein Geisterzeichen?",
|
||||
"es": "¿Es esto una señal fantasma?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "Is this sign for a business that no longer exists or no longer being maintained?",
|
||||
"de": "Ist dieses Schild für ein Geschäft, das nicht mehr existiert oder nicht mehr gepflegt wird?"
|
||||
"de": "Ist dieses Schild für ein Geschäft, das nicht mehr existiert oder nicht mehr gepflegt wird?",
|
||||
"es": "¿Este cartel es para una empresa que ya no existe o que ya no recibe mantenimiento?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "historic=advertising",
|
||||
"then": {
|
||||
"en": "This is a ghost sign",
|
||||
"de": "Das ist ein Geisterzeichen"
|
||||
"de": "Das ist ein Geisterzeichen",
|
||||
"es": "Esta es una señal fantasma"
|
||||
},
|
||||
"alsoShowIf": "historic=yes"
|
||||
},
|
||||
|
@ -64,7 +67,8 @@
|
|||
"if": "historic=",
|
||||
"then": {
|
||||
"en": "This is not a ghost sign, answering this will hide the sign from the map",
|
||||
"de": "Dies ist kein Geisterzeichen, die Antwort darauf wird das Schild von der Karte verstecken"
|
||||
"de": "Dies ist kein Geisterzeichen, die Antwort darauf wird das Schild von der Karte verstecken",
|
||||
"es": "Esta no es una señal fantasma, al responder esto se ocultará la señal del mapa"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@ -81,19 +85,22 @@
|
|||
"id": "inscription",
|
||||
"question": {
|
||||
"en": "What is the text on the sign?",
|
||||
"de": "Was ist der Text auf dem Schild?"
|
||||
"de": "Was ist der Text auf dem Schild?",
|
||||
"es": "¿Cuál es el texto del cartel?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "inscription",
|
||||
"type": "string",
|
||||
"placeholder": {
|
||||
"en": "Text on the sign",
|
||||
"de": "Text auf dem Schild"
|
||||
"de": "Text auf dem Schild",
|
||||
"es": "Texto en el cartel"
|
||||
}
|
||||
},
|
||||
"render": {
|
||||
"en": "The text on the sign is: {inscription}",
|
||||
"de": "Der Text auf dem Schild ist: {inscription}"
|
||||
"de": "Der Text auf dem Schild ist: {inscription}",
|
||||
"es": "El texto del cartel es: {inscription}"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
"layers": [
|
||||
{
|
||||
"builtin": "food",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -27,11 +31,14 @@
|
|||
},
|
||||
{
|
||||
"builtin": "food",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
||||
"isCounted": false,
|
||||
"filter": {
|
||||
"sameAs": "food_glutenfree"
|
||||
|
@ -40,7 +47,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "ice_cream",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -57,7 +68,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "ice_cream",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
@ -69,7 +84,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "shops",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -86,7 +105,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "shops",
|
||||
"hideTagRenderingsWithLabels": ["gluten_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"gluten_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
"layers": [
|
||||
{
|
||||
"builtin": "food",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -27,11 +31,14 @@
|
|||
},
|
||||
{
|
||||
"builtin": "food",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
||||
"isCounted": false,
|
||||
"filter": {
|
||||
"sameAs": "food_lactosefree"
|
||||
|
@ -40,7 +47,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "ice_cream",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -57,7 +68,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "ice_cream",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
@ -69,7 +84,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "shops",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": {
|
||||
|
@ -86,7 +105,11 @@
|
|||
},
|
||||
{
|
||||
"builtin": "shops",
|
||||
"hideTagRenderingsWithLabels": ["lactose_free","images","reviews"],
|
||||
"hideTagRenderingsWithLabels": [
|
||||
"lactose_free",
|
||||
"images",
|
||||
"reviews"
|
||||
],
|
||||
"override": {
|
||||
"name": null,
|
||||
"minzoom": 17,
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -27,13 +27,6 @@
|
|||
"advertising": {
|
||||
"name": "Reclame",
|
||||
"presets": {
|
||||
"10": {
|
||||
"description": "Een stuk groot, weerbestendig textiel met opgedrukte reclameboodschap die permanent aan de muur hangt",
|
||||
"title": "een spandoek"
|
||||
},
|
||||
"14": {
|
||||
"title": "een muurschildering"
|
||||
},
|
||||
"4": {
|
||||
"description": "Een klein uithangbord voor buurtadvertenties, meestal gericht op voetgangers",
|
||||
"title": "een uithangbord"
|
||||
|
@ -50,6 +43,13 @@
|
|||
},
|
||||
"8": {
|
||||
"title": "een scherm op een muur"
|
||||
},
|
||||
"10": {
|
||||
"description": "Een stuk groot, weerbestendig textiel met opgedrukte reclameboodschap die permanent aan de muur hangt",
|
||||
"title": "een spandoek"
|
||||
},
|
||||
"14": {
|
||||
"title": "een muurschildering"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
|
@ -107,9 +107,6 @@
|
|||
},
|
||||
"title": {
|
||||
"mappings": {
|
||||
"10": {
|
||||
"then": "Muurschildering"
|
||||
},
|
||||
"3": {
|
||||
"then": "Aanplakzuil"
|
||||
},
|
||||
|
@ -127,6 +124,9 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Aanplakzuil"
|
||||
},
|
||||
"10": {
|
||||
"then": "Muurschildering"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,15 +208,6 @@
|
|||
"1": {
|
||||
"then": "Muurschildering"
|
||||
},
|
||||
"10": {
|
||||
"then": "Azulejo (Spaanse siertegels)"
|
||||
},
|
||||
"11": {
|
||||
"then": "Tegelwerk"
|
||||
},
|
||||
"12": {
|
||||
"then": "Houtsculptuur"
|
||||
},
|
||||
"2": {
|
||||
"then": "Schilderij"
|
||||
},
|
||||
|
@ -240,6 +231,15 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Reliëf"
|
||||
},
|
||||
"10": {
|
||||
"then": "Azulejo (Spaanse siertegels)"
|
||||
},
|
||||
"11": {
|
||||
"then": "Tegelwerk"
|
||||
},
|
||||
"12": {
|
||||
"then": "Houtsculptuur"
|
||||
}
|
||||
},
|
||||
"question": "Wat voor soort kunstwerk is dit?",
|
||||
|
@ -561,6 +561,17 @@
|
|||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"bench-armrest": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze bank heeft armleuningen"
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze bank heeft <b>geen</b> armleuningen"
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze bank armleuningen?"
|
||||
},
|
||||
"bench-artwork": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
|
@ -1757,6 +1768,30 @@
|
|||
"1": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Schuko stekker</b> zonder aardingspin (CEE7/4 type F)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/CEE7_4F.svg'/></div>"
|
||||
},
|
||||
"2": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Europese stekker</b> met aardingspin (CEE7/4 type E)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/TypeE.svg'/></div>"
|
||||
},
|
||||
"3": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Chademo</b></b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Chademo_type4.svg'/></div>"
|
||||
},
|
||||
"4": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 met kabel</b> (J1772)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1_J1772.svg'/></div>"
|
||||
},
|
||||
"5": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 <i>zonder</i> kabel</b> (J1772)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1_J1772.svg'/></div>"
|
||||
},
|
||||
"6": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 CCS</b> (ook gekend als Type 1 Combo)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1-ccs.svg'/></div>"
|
||||
},
|
||||
"7": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Tesla Supercharger</b></b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Tesla-hpwc-model-s.svg'/></div>"
|
||||
},
|
||||
"8": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 2</b> (mennekes)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type2_socket.svg'/></div>"
|
||||
},
|
||||
"9": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 2 CCS</b> (mennekes)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type2_CCS.svg'/></div>"
|
||||
},
|
||||
"10": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 2 met kabel</b> (J1772)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type2_tethered.svg'/></div>"
|
||||
},
|
||||
|
@ -1787,35 +1822,11 @@
|
|||
"19": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>SEV 1011 T23</b> (Zwitserse 3-pin)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/typej.svg'/></div>"
|
||||
},
|
||||
"2": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Europese stekker</b> met aardingspin (CEE7/4 type E)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/TypeE.svg'/></div>"
|
||||
},
|
||||
"20": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>AS3112</b> (Australische 3-pin)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/as3112.svg'/></div>"
|
||||
},
|
||||
"21": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>NEMA 5-20</b> (VS 3-pin)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/nema-5-20.svg'/></div>"
|
||||
},
|
||||
"3": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Chademo</b></b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Chademo_type4.svg'/></div>"
|
||||
},
|
||||
"4": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 met kabel</b> (J1772)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1_J1772.svg'/></div>"
|
||||
},
|
||||
"5": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 <i>zonder</i> kabel</b> (J1772)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1_J1772.svg'/></div>"
|
||||
},
|
||||
"6": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 1 CCS</b> (ook gekend als Type 1 Combo)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type1-ccs.svg'/></div>"
|
||||
},
|
||||
"7": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Tesla Supercharger</b></b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Tesla-hpwc-model-s.svg'/></div>"
|
||||
},
|
||||
"8": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 2</b> (mennekes)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type2_socket.svg'/></div>"
|
||||
},
|
||||
"9": {
|
||||
"question": "Heeft een <div style='display: inline-block'><b><b>Type 2 CCS</b> (mennekes)</b> <img style='width:1rem; display: inline-block' src='./assets/layers/charging_station/Type2_CCS.svg'/></div>"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1871,6 +1882,30 @@
|
|||
"1": {
|
||||
"then": "<b>Schuko stekker</b> zonder aardingspin (CEE7/4 type F)"
|
||||
},
|
||||
"2": {
|
||||
"then": "<b>Europese stekker</b> met aardingspin (CEE7/4 type E)"
|
||||
},
|
||||
"3": {
|
||||
"then": "<b>Europese stekker</b> met aardingspin (CEE7/4 type E)"
|
||||
},
|
||||
"4": {
|
||||
"then": "<b>Chademo</b>"
|
||||
},
|
||||
"5": {
|
||||
"then": "<b>Chademo</b>"
|
||||
},
|
||||
"6": {
|
||||
"then": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"7": {
|
||||
"then": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"8": {
|
||||
"then": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
},
|
||||
"9": {
|
||||
"then": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
},
|
||||
"10": {
|
||||
"then": "<b>Type 1 CCS</b> (ook gekend als Type 1 Combo)"
|
||||
},
|
||||
|
@ -1901,9 +1936,6 @@
|
|||
"19": {
|
||||
"then": "<b>Type 2 met kabel</b> (J1772)"
|
||||
},
|
||||
"2": {
|
||||
"then": "<b>Europese stekker</b> met aardingspin (CEE7/4 type E)"
|
||||
},
|
||||
"20": {
|
||||
"then": "<b>Tesla Supercharger CCS</b> (een type2 CCS met Tesla-logo)"
|
||||
},
|
||||
|
@ -1934,9 +1966,6 @@
|
|||
"29": {
|
||||
"then": "<b>Bosch Active Connect met 3 pinnen</b> aan een kabel"
|
||||
},
|
||||
"3": {
|
||||
"then": "<b>Europese stekker</b> met aardingspin (CEE7/4 type E)"
|
||||
},
|
||||
"30": {
|
||||
"then": "<b>Bosch Active Connect met 5 pinnen</b> aan een kabel"
|
||||
},
|
||||
|
@ -1967,29 +1996,11 @@
|
|||
"39": {
|
||||
"then": "<b>AS3112</b> (Australische 3-pin)"
|
||||
},
|
||||
"4": {
|
||||
"then": "<b>Chademo</b>"
|
||||
},
|
||||
"40": {
|
||||
"then": "<b>NEMA 5-20</b> (VS 3-pin)"
|
||||
},
|
||||
"41": {
|
||||
"then": "<b>NEMA 5-20</b> (VS 3-pin)"
|
||||
},
|
||||
"5": {
|
||||
"then": "<b>Chademo</b>"
|
||||
},
|
||||
"6": {
|
||||
"then": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"7": {
|
||||
"then": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"8": {
|
||||
"then": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
},
|
||||
"9": {
|
||||
"then": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
}
|
||||
},
|
||||
"question": "Welke aansluitingen zijn hier beschikbaar?"
|
||||
|
@ -2183,6 +2194,30 @@
|
|||
"1": {
|
||||
"2": "<b>Europese stekker</b> met aardingspin (CEE7/4 type E)"
|
||||
},
|
||||
"2": {
|
||||
"2": "<b>Chademo</b>"
|
||||
},
|
||||
"3": {
|
||||
"2": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"4": {
|
||||
"2": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
},
|
||||
"5": {
|
||||
"2": "<b>Type 1 CCS</b> (ook gekend als Type 1 Combo)"
|
||||
},
|
||||
"6": {
|
||||
"2": "<b>Tesla Supercharger</b>"
|
||||
},
|
||||
"7": {
|
||||
"2": "<b>Type 2</b> (mennekes)"
|
||||
},
|
||||
"8": {
|
||||
"2": "<b>Type 2 CCS</b> (mennekes)"
|
||||
},
|
||||
"9": {
|
||||
"2": "<b>Type 2 met kabel</b> (J1772)"
|
||||
},
|
||||
"10": {
|
||||
"2": "<b>Tesla Supercharger CCS</b> (een type2 CCS met Tesla-logo)"
|
||||
},
|
||||
|
@ -2213,32 +2248,8 @@
|
|||
"19": {
|
||||
"2": "<b>AS3112</b> (Australische 3-pin)"
|
||||
},
|
||||
"2": {
|
||||
"2": "<b>Chademo</b>"
|
||||
},
|
||||
"20": {
|
||||
"2": "<b>NEMA 5-20</b> (VS 3-pin)"
|
||||
},
|
||||
"3": {
|
||||
"2": "<b>Type 1 met kabel</b> (J1772)"
|
||||
},
|
||||
"4": {
|
||||
"2": "<b>Type 1 <i>zonder</i> kabel</b> (J1772)"
|
||||
},
|
||||
"5": {
|
||||
"2": "<b>Type 1 CCS</b> (ook gekend als Type 1 Combo)"
|
||||
},
|
||||
"6": {
|
||||
"2": "<b>Tesla Supercharger</b>"
|
||||
},
|
||||
"7": {
|
||||
"2": "<b>Type 2</b> (mennekes)"
|
||||
},
|
||||
"8": {
|
||||
"2": "<b>Type 2 CCS</b> (mennekes)"
|
||||
},
|
||||
"9": {
|
||||
"2": "<b>Type 2 met kabel</b> (J1772)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3004,15 +3015,6 @@
|
|||
"1": {
|
||||
"then": "Dit fietspad is geplaveid"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit fietspad is gemaakt van fijn grind"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit fietspad is gemaakt van kiezelsteentjes"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit fietspad is gemaakt van aarde"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit fietspad is gemaakt van asfalt"
|
||||
},
|
||||
|
@ -3036,6 +3038,15 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Dit fietspad is gemaakt van grind"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit fietspad is gemaakt van fijn grind"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit fietspad is gemaakt van kiezelsteentjes"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit fietspad is gemaakt van aarde"
|
||||
}
|
||||
},
|
||||
"question": "Waaruit is het oppervlak van het fietspad van gemaakt?",
|
||||
|
@ -3084,15 +3095,6 @@
|
|||
"1": {
|
||||
"then": "Dit fietspad is geplaveid"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit fietspad is gemaakt van fijn grind"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit fietspad is gemaakt van kiezelsteentjes"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit fietspad is gemaakt van aarde"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit fietspad is gemaakt van asfalt"
|
||||
},
|
||||
|
@ -3116,6 +3118,15 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Dit fietspad is gemaakt van grind"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit fietspad is gemaakt van fijn grind"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit fietspad is gemaakt van kiezelsteentjes"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit fietspad is gemaakt van aarde"
|
||||
}
|
||||
},
|
||||
"question": "Waaruit is het oppervlak van de straat gemaakt?",
|
||||
|
@ -4171,21 +4182,6 @@
|
|||
"1": {
|
||||
"then": "Dit is een frituur"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit is een Chinees restaurant"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit is een Grieks restaurant"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit is een Indisch restaurant"
|
||||
},
|
||||
"13": {
|
||||
"then": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)"
|
||||
},
|
||||
"14": {
|
||||
"then": "Dit is een Thaïs restaurant"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit is een pastazaak"
|
||||
},
|
||||
|
@ -4209,6 +4205,21 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Dit is een Frans restaurant"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit is een Chinees restaurant"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit is een Grieks restaurant"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit is een Indisch restaurant"
|
||||
},
|
||||
"13": {
|
||||
"then": "Dit is een Turks restaurant (dat meer dan enkel kebab verkoopt)"
|
||||
},
|
||||
"14": {
|
||||
"then": "Dit is een Thaïs restaurant"
|
||||
}
|
||||
},
|
||||
"question": "Welk soort gerechten worden hier geserveerd?",
|
||||
|
@ -5260,12 +5271,6 @@
|
|||
"0": {
|
||||
"then": "Dit is een standbeeld"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit is een kruis"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit is een historische tank, permanent in de publieke ruimte geplaatst als gedenkteken"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit is een zitbank die ook als herdenking dienst doet"
|
||||
},
|
||||
|
@ -5277,6 +5282,12 @@
|
|||
},
|
||||
"8": {
|
||||
"then": "Dit is een sculptuur"
|
||||
},
|
||||
"10": {
|
||||
"then": "Dit is een kruis"
|
||||
},
|
||||
"12": {
|
||||
"then": "Dit is een historische tank, permanent in de publieke ruimte geplaatst als gedenkteken"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5428,19 +5439,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Alle Notes"
|
||||
},
|
||||
"1": {
|
||||
"question": "Verberg import Notes"
|
||||
},
|
||||
"2": {
|
||||
"question": "Toon enkel import Notes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -5496,6 +5494,19 @@
|
|||
"question": "Toon enkel open Notes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Alle Notes"
|
||||
},
|
||||
"1": {
|
||||
"question": "Verberg import Notes"
|
||||
},
|
||||
"2": {
|
||||
"question": "Toon enkel import Notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "OpenStreetMap Notes",
|
||||
|
@ -5773,18 +5784,6 @@
|
|||
"1": {
|
||||
"then": "Dit is een normale parkeerplek."
|
||||
},
|
||||
"10": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor personeel."
|
||||
},
|
||||
"11": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor taxis."
|
||||
},
|
||||
"12": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor voertuigen met een aanhanger."
|
||||
},
|
||||
"13": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor autodelen."
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit is een gehandicaptenparkeerplaats."
|
||||
},
|
||||
|
@ -5808,6 +5807,18 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor ouders met kinderen."
|
||||
},
|
||||
"10": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor personeel."
|
||||
},
|
||||
"11": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor taxis."
|
||||
},
|
||||
"12": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor voertuigen met een aanhanger."
|
||||
},
|
||||
"13": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor autodelen."
|
||||
}
|
||||
},
|
||||
"question": "Wat voor parkeerplek is dit?"
|
||||
|
@ -6122,9 +6133,6 @@
|
|||
"0": {
|
||||
"then": "Dit is een schommel"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit is een rekstok"
|
||||
},
|
||||
"3": {
|
||||
"then": "Dit is een zandbak"
|
||||
},
|
||||
|
@ -6136,6 +6144,9 @@
|
|||
},
|
||||
"6": {
|
||||
"then": "Dit is een wipwap"
|
||||
},
|
||||
"11": {
|
||||
"then": "Dit is een rekstok"
|
||||
}
|
||||
},
|
||||
"question": "Wat voor speeltoestel is dit?"
|
||||
|
@ -6411,21 +6422,6 @@
|
|||
"1": {
|
||||
"then": "Munten van 2 cent worden geaccepteerd"
|
||||
},
|
||||
"10": {
|
||||
"then": "Munten van 20 rappen worden geaccepteerd"
|
||||
},
|
||||
"11": {
|
||||
"then": "Munten van ½ frank worden geaccepteerd"
|
||||
},
|
||||
"12": {
|
||||
"then": "Munten van 1 frank worden geaccepteerd"
|
||||
},
|
||||
"13": {
|
||||
"then": "Munten van 2 frank worden geaccepteerd"
|
||||
},
|
||||
"14": {
|
||||
"then": "Munten van 5 frank worden geaccepteerd"
|
||||
},
|
||||
"2": {
|
||||
"then": "Munten van 5 cent worden geaccepteerd"
|
||||
},
|
||||
|
@ -6449,6 +6445,21 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Munten van 10 rappen worden geaccepteerd"
|
||||
},
|
||||
"10": {
|
||||
"then": "Munten van 20 rappen worden geaccepteerd"
|
||||
},
|
||||
"11": {
|
||||
"then": "Munten van ½ frank worden geaccepteerd"
|
||||
},
|
||||
"12": {
|
||||
"then": "Munten van 1 frank worden geaccepteerd"
|
||||
},
|
||||
"13": {
|
||||
"then": "Munten van 2 frank worden geaccepteerd"
|
||||
},
|
||||
"14": {
|
||||
"then": "Munten van 5 frank worden geaccepteerd"
|
||||
}
|
||||
},
|
||||
"question": "Met welke munten kan je hier betalen?"
|
||||
|
@ -6461,15 +6472,6 @@
|
|||
"1": {
|
||||
"then": "Biljetten van 10 euro worden geaccepteerd"
|
||||
},
|
||||
"10": {
|
||||
"then": "Biljetten van 100 frank worden geaccepteerd"
|
||||
},
|
||||
"11": {
|
||||
"then": "Biljetten van 200 frank worden geaccepteerd"
|
||||
},
|
||||
"12": {
|
||||
"then": "Biljetten van 1000 frank worden geaccepteerd"
|
||||
},
|
||||
"2": {
|
||||
"then": "Biljetten van 20 euro worden geaccepteerd"
|
||||
},
|
||||
|
@ -6493,6 +6495,15 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Biljetten van 50 frank worden geaccepteerd"
|
||||
},
|
||||
"10": {
|
||||
"then": "Biljetten van 100 frank worden geaccepteerd"
|
||||
},
|
||||
"11": {
|
||||
"then": "Biljetten van 200 frank worden geaccepteerd"
|
||||
},
|
||||
"12": {
|
||||
"then": "Biljetten van 1000 frank worden geaccepteerd"
|
||||
}
|
||||
},
|
||||
"question": "Met welke bankbiljetten kan je hier betalen?"
|
||||
|
@ -6837,6 +6848,30 @@
|
|||
"1": {
|
||||
"question": "Recycling van batterijen"
|
||||
},
|
||||
"2": {
|
||||
"question": "Recycling van drankpakken"
|
||||
},
|
||||
"3": {
|
||||
"question": "Recycling van blikken"
|
||||
},
|
||||
"4": {
|
||||
"question": "Recycling van kleding"
|
||||
},
|
||||
"5": {
|
||||
"question": "Recycling van frituurvet"
|
||||
},
|
||||
"6": {
|
||||
"question": "Recycling van motorolie"
|
||||
},
|
||||
"7": {
|
||||
"question": "Recycling van tl-buizen"
|
||||
},
|
||||
"8": {
|
||||
"question": "Recycling van groen afval"
|
||||
},
|
||||
"9": {
|
||||
"question": "Recycling van glazen flessen"
|
||||
},
|
||||
"10": {
|
||||
"question": "Recycling van glas"
|
||||
},
|
||||
|
@ -6867,9 +6902,6 @@
|
|||
"19": {
|
||||
"question": "Recycling van restafval"
|
||||
},
|
||||
"2": {
|
||||
"question": "Recycling van drankpakken"
|
||||
},
|
||||
"20": {
|
||||
"question": "Recycling van inktpatronen"
|
||||
},
|
||||
|
@ -6878,27 +6910,6 @@
|
|||
},
|
||||
"22": {
|
||||
"question": "Recycling van plastic verkpakkingen, metalen verkpakkingen en drankpakken (PMD)"
|
||||
},
|
||||
"3": {
|
||||
"question": "Recycling van blikken"
|
||||
},
|
||||
"4": {
|
||||
"question": "Recycling van kleding"
|
||||
},
|
||||
"5": {
|
||||
"question": "Recycling van frituurvet"
|
||||
},
|
||||
"6": {
|
||||
"question": "Recycling van motorolie"
|
||||
},
|
||||
"7": {
|
||||
"question": "Recycling van tl-buizen"
|
||||
},
|
||||
"8": {
|
||||
"question": "Recycling van groen afval"
|
||||
},
|
||||
"9": {
|
||||
"question": "Recycling van glazen flessen"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -6966,6 +6977,30 @@
|
|||
"1": {
|
||||
"then": "Drankpakken kunnen hier gerecycled worden"
|
||||
},
|
||||
"2": {
|
||||
"then": "Blikken kunnen hier gerecycled worden"
|
||||
},
|
||||
"3": {
|
||||
"then": "Kleren kunnen hier gerecycled worden"
|
||||
},
|
||||
"4": {
|
||||
"then": "Frituurvet kan hier gerecycled worden"
|
||||
},
|
||||
"5": {
|
||||
"then": "Motorolie kan hier gerecycled worden"
|
||||
},
|
||||
"6": {
|
||||
"then": "TL-buizen kunnen hier gerecycled worden"
|
||||
},
|
||||
"7": {
|
||||
"then": "Groen afval kan hier gerecycled worden"
|
||||
},
|
||||
"8": {
|
||||
"then": "Organisch afval kan hier gerecycled worden"
|
||||
},
|
||||
"9": {
|
||||
"then": "Glazen flessen kunnen hier gerecycled worden"
|
||||
},
|
||||
"10": {
|
||||
"then": "Glas kan hier gerecycled worden"
|
||||
},
|
||||
|
@ -6996,9 +7031,6 @@
|
|||
"19": {
|
||||
"then": "Oud metaal kan hier gerecycled worden"
|
||||
},
|
||||
"2": {
|
||||
"then": "Blikken kunnen hier gerecycled worden"
|
||||
},
|
||||
"20": {
|
||||
"then": "Schoenen kunnen hier gerecycled worden"
|
||||
},
|
||||
|
@ -7016,27 +7048,6 @@
|
|||
},
|
||||
"25": {
|
||||
"then": "Fietsen (en fietswrakken) kunnen hier gerecycled worden"
|
||||
},
|
||||
"3": {
|
||||
"then": "Kleren kunnen hier gerecycled worden"
|
||||
},
|
||||
"4": {
|
||||
"then": "Frituurvet kan hier gerecycled worden"
|
||||
},
|
||||
"5": {
|
||||
"then": "Motorolie kan hier gerecycled worden"
|
||||
},
|
||||
"6": {
|
||||
"then": "TL-buizen kunnen hier gerecycled worden"
|
||||
},
|
||||
"7": {
|
||||
"then": "Groen afval kan hier gerecycled worden"
|
||||
},
|
||||
"8": {
|
||||
"then": "Organisch afval kan hier gerecycled worden"
|
||||
},
|
||||
"9": {
|
||||
"then": "Glazen flessen kunnen hier gerecycled worden"
|
||||
}
|
||||
},
|
||||
"question": "Wat kan hier gerecycled worden?"
|
||||
|
@ -7762,12 +7773,6 @@
|
|||
"1": {
|
||||
"then": "Deze lantaarn gebruikt LEDs"
|
||||
},
|
||||
"10": {
|
||||
"then": "Deze lantaarn gebruikt hogedruknatriumlampen (oranje met wit)"
|
||||
},
|
||||
"11": {
|
||||
"then": "Deze lantaarn wordt verlicht met gas"
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze lantaarn gebruikt gloeilampen"
|
||||
},
|
||||
|
@ -7791,6 +7796,12 @@
|
|||
},
|
||||
"9": {
|
||||
"then": "Deze lantaarn gebruikt lagedruknatriumlampen (monochroom oranje)"
|
||||
},
|
||||
"10": {
|
||||
"then": "Deze lantaarn gebruikt hogedruknatriumlampen (oranje met wit)"
|
||||
},
|
||||
"11": {
|
||||
"then": "Deze lantaarn wordt verlicht met gas"
|
||||
}
|
||||
},
|
||||
"question": "Wat voor verlichting gebruikt deze lantaarn?"
|
||||
|
@ -9037,6 +9048,30 @@
|
|||
"1": {
|
||||
"question": "Verkoop van dranken"
|
||||
},
|
||||
"2": {
|
||||
"question": "Verkoop van snoep"
|
||||
},
|
||||
"3": {
|
||||
"question": "Verkoop van eten"
|
||||
},
|
||||
"4": {
|
||||
"question": "Verkoop van sigaretten"
|
||||
},
|
||||
"5": {
|
||||
"question": "Verkoop van condooms"
|
||||
},
|
||||
"6": {
|
||||
"question": "Verkoop van koffie"
|
||||
},
|
||||
"7": {
|
||||
"question": "Verkoop van water"
|
||||
},
|
||||
"8": {
|
||||
"question": "Verkoop van kranten"
|
||||
},
|
||||
"9": {
|
||||
"question": "Verkoop van fietsbinnenbanden"
|
||||
},
|
||||
"10": {
|
||||
"question": "Verkoop van melk"
|
||||
},
|
||||
|
@ -9067,9 +9102,6 @@
|
|||
"19": {
|
||||
"question": "Verkoop van bloemen"
|
||||
},
|
||||
"2": {
|
||||
"question": "Verkoop van snoep"
|
||||
},
|
||||
"23": {
|
||||
"question": "Verkoop van fietslampjes"
|
||||
},
|
||||
|
@ -9084,27 +9116,6 @@
|
|||
},
|
||||
"27": {
|
||||
"question": "Verkoop van fietssloten"
|
||||
},
|
||||
"3": {
|
||||
"question": "Verkoop van eten"
|
||||
},
|
||||
"4": {
|
||||
"question": "Verkoop van sigaretten"
|
||||
},
|
||||
"5": {
|
||||
"question": "Verkoop van condooms"
|
||||
},
|
||||
"6": {
|
||||
"question": "Verkoop van koffie"
|
||||
},
|
||||
"7": {
|
||||
"question": "Verkoop van water"
|
||||
},
|
||||
"8": {
|
||||
"question": "Verkoop van kranten"
|
||||
},
|
||||
"9": {
|
||||
"question": "Verkoop van fietsbinnenbanden"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9195,6 +9206,30 @@
|
|||
"1": {
|
||||
"then": "Snoep wordt verkocht"
|
||||
},
|
||||
"2": {
|
||||
"then": "Eten wordt verkocht"
|
||||
},
|
||||
"3": {
|
||||
"then": "Sigaretten worden verkocht"
|
||||
},
|
||||
"4": {
|
||||
"then": "Condooms worden verkocht"
|
||||
},
|
||||
"5": {
|
||||
"then": "Koffie wordt verkocht"
|
||||
},
|
||||
"6": {
|
||||
"then": "Drinkwater wordt verkocht"
|
||||
},
|
||||
"7": {
|
||||
"then": "Kranten worden verkocht"
|
||||
},
|
||||
"8": {
|
||||
"then": "Binnenbanden voor fietsen worden verkocht"
|
||||
},
|
||||
"9": {
|
||||
"then": "Melk wordt verkocht"
|
||||
},
|
||||
"10": {
|
||||
"then": "Brood wordt verkocht"
|
||||
},
|
||||
|
@ -9225,9 +9260,6 @@
|
|||
"19": {
|
||||
"then": "Parkeerkaarten worden verkocht"
|
||||
},
|
||||
"2": {
|
||||
"then": "Eten wordt verkocht"
|
||||
},
|
||||
"21": {
|
||||
"then": "Openbaar vervoerkaartjes worden verkocht"
|
||||
},
|
||||
|
@ -9245,27 +9277,6 @@
|
|||
},
|
||||
"26": {
|
||||
"then": "Fietssloten worden verkocht"
|
||||
},
|
||||
"3": {
|
||||
"then": "Sigaretten worden verkocht"
|
||||
},
|
||||
"4": {
|
||||
"then": "Condooms worden verkocht"
|
||||
},
|
||||
"5": {
|
||||
"then": "Koffie wordt verkocht"
|
||||
},
|
||||
"6": {
|
||||
"then": "Drinkwater wordt verkocht"
|
||||
},
|
||||
"7": {
|
||||
"then": "Kranten worden verkocht"
|
||||
},
|
||||
"8": {
|
||||
"then": "Binnenbanden voor fietsen worden verkocht"
|
||||
},
|
||||
"9": {
|
||||
"then": "Melk wordt verkocht"
|
||||
}
|
||||
},
|
||||
"question": "Wat verkoopt deze verkoopautomaat?",
|
||||
|
|
|
@ -983,6 +983,10 @@
|
|||
},
|
||||
"title": "Kerbs and crossings"
|
||||
},
|
||||
"lactosefree": {
|
||||
"description": "A crowdsourced map with lactose free shops and restaurants",
|
||||
"title": "Lactose free shops and restaurants"
|
||||
},
|
||||
"lighthouses": {
|
||||
"description": "Lighthouses are tall buildings with a light on top to guide marine traffic.",
|
||||
"title": "Lighthouses"
|
||||
|
|
|
@ -979,33 +979,6 @@
|
|||
"onwheels": {
|
||||
"description": "En este mapa se muestran los lugares accesibles al público en silla de ruedas, que pueden añadirse fácilmente",
|
||||
"layers": {
|
||||
"19": {
|
||||
"override": {
|
||||
"=title": {
|
||||
"render": "Estadísticas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
"override": {
|
||||
"+tagRenderings": {
|
||||
"0": {
|
||||
"render": {
|
||||
"special": {
|
||||
"text": "Importar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"render": {
|
||||
"special": {
|
||||
"message": "Añadir todas las etiquetas sugeridas"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"override": {
|
||||
"filter": {
|
||||
|
@ -1048,6 +1021,33 @@
|
|||
"override": {
|
||||
"name": "Plazas de aparcamiento para discapacitados"
|
||||
}
|
||||
},
|
||||
"19": {
|
||||
"override": {
|
||||
"=title": {
|
||||
"render": "Estadísticas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
"override": {
|
||||
"+tagRenderings": {
|
||||
"0": {
|
||||
"render": {
|
||||
"special": {
|
||||
"text": "Importar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"render": {
|
||||
"special": {
|
||||
"message": "Añadir todas las etiquetas sugeridas"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Sobre ruedas"
|
||||
|
@ -1263,6 +1263,10 @@
|
|||
"stations": {
|
||||
"description": "Ver, editar y añadir detalles a una estación de tren",
|
||||
"layers": {
|
||||
"3": {
|
||||
"description": "Capa que muestra las estaciones de tren",
|
||||
"name": "Estación de Tren"
|
||||
},
|
||||
"16": {
|
||||
"description": "Pantallas que muestran los trenes que saldrán de esta estación",
|
||||
"name": "Tableros de salidas",
|
||||
|
@ -1294,10 +1298,6 @@
|
|||
"title": {
|
||||
"render": "Tablero de salidas"
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"description": "Capa que muestra las estaciones de tren",
|
||||
"name": "Estación de Tren"
|
||||
}
|
||||
},
|
||||
"title": "Estaciones de tren"
|
||||
|
|
|
@ -54,15 +54,15 @@ class ToSlideshowJson {
|
|||
sections.push(currentSection)
|
||||
currentSection = []
|
||||
}
|
||||
line = line.replace("src=\"../../public/", "src=\"./")
|
||||
line = line.replace("src=\"../../", "src=\"./")
|
||||
line = line.replace('src="../../public/', 'src="./')
|
||||
line = line.replace('src="../../', 'src="./')
|
||||
currentSection.push(line)
|
||||
}
|
||||
sections.push(currentSection)
|
||||
writeFileSync(
|
||||
this._target,
|
||||
JSON.stringify({
|
||||
sections: sections.map((s) => s.join("\n")).filter((s) => s.length > 0)
|
||||
sections: sections.map((s) => s.join("\n")).filter((s) => s.length > 0),
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class WikiPageGenerator {
|
|||
|
||||
generate() {
|
||||
let wikiPage =
|
||||
"{|class=\"wikitable sortable\"\n" +
|
||||
'{|class="wikitable sortable"\n' +
|
||||
"! Name, link !! Genre !! Covered region !! Language !! Description !! Free materials !! Image\n" +
|
||||
"|-"
|
||||
|
||||
|
@ -139,7 +139,7 @@ export class GenerateDocs extends Script {
|
|||
}
|
||||
|
||||
this.WriteMarkdownFile("./Docs/Tags_format.md", TagUtils.generateDocs(), [
|
||||
"src/Logic/Tags/TagUtils.ts"
|
||||
"src/Logic/Tags/TagUtils.ts",
|
||||
])
|
||||
|
||||
new ToSlideshowJson(
|
||||
|
@ -165,24 +165,20 @@ export class GenerateDocs extends Script {
|
|||
})
|
||||
|
||||
this.WriteMarkdownFile("./Docs/SpecialRenderings.md", SpecialVisualizations.HelpMessage(), [
|
||||
"src/UI/SpecialVisualizations.ts"
|
||||
"src/UI/SpecialVisualizations.ts",
|
||||
])
|
||||
this.WriteMarkdownFile(
|
||||
"./Docs/CalculatedTags.md",
|
||||
[
|
||||
"# Metatags",
|
||||
SimpleMetaTaggers.HelpText(),
|
||||
ExtraFunctions.HelpText()
|
||||
].join("\n"),
|
||||
["# Metatags", SimpleMetaTaggers.HelpText(), ExtraFunctions.HelpText()].join("\n"),
|
||||
["src/Logic/SimpleMetaTagger.ts", "src/Logic/ExtraFunctions.ts"]
|
||||
)
|
||||
this.WriteMarkdownFile("./Docs/SpecialInputElements.md", Validators.HelpText(), [
|
||||
"src/UI/InputElement/Validators.ts"
|
||||
"src/UI/InputElement/Validators.ts",
|
||||
])
|
||||
|
||||
this.WriteMarkdownFile("./Docs/ChangesetMeta.md", Changes.getDocs(), [
|
||||
"src/Logic/Osm/Changes.ts",
|
||||
"src/Logic/Osm/ChangesetHandler.ts"
|
||||
"src/Logic/Osm/ChangesetHandler.ts",
|
||||
])
|
||||
new WikiPageGenerator().generate()
|
||||
|
||||
|
@ -225,20 +221,21 @@ export class GenerateDocs extends Script {
|
|||
const warnAutomated =
|
||||
"[//]: # (WARNING: this file is automatically generated. Please find the sources at the bottom and edit those sources)\n\n"
|
||||
|
||||
const generatedFrom =
|
||||
[
|
||||
|
||||
"This document is autogenerated from",
|
||||
autogenSource.map(s => `[${s}](https://github.com/pietervdvn/MapComplete/blob/develop/${s})`).join(", ")
|
||||
].join(" ")
|
||||
|
||||
const generatedFrom = [
|
||||
"This document is autogenerated from",
|
||||
autogenSource
|
||||
.map((s) => `[${s}](https://github.com/pietervdvn/MapComplete/blob/develop/${s})`)
|
||||
.join(", "),
|
||||
].join(" ")
|
||||
|
||||
writeFileSync(filename, warnAutomated + md + "\n\n" + generatedFrom + "\n")
|
||||
}
|
||||
|
||||
private generateHotkeyDocs() {
|
||||
new ThemeViewState(new LayoutConfig(<any>bookcases), new Set())
|
||||
this.WriteMarkdownFile("./Docs/Hotkeys.md", Hotkeys.generateDocumentation(), ["src/UI/Base/Hotkeys.ts"])
|
||||
this.WriteMarkdownFile("./Docs/Hotkeys.md", Hotkeys.generateDocumentation(), [
|
||||
"src/UI/Base/Hotkeys.ts",
|
||||
])
|
||||
}
|
||||
|
||||
private generateBuiltinUnits() {
|
||||
|
@ -271,7 +268,7 @@ export class GenerateDocs extends Script {
|
|||
}
|
||||
|
||||
this.WriteMarkdownFile("./Docs/builtin_units.md", ["# Units", ...els].join("\n\n"), [
|
||||
`assets/layers/unit/unit.json`
|
||||
`assets/layers/unit/unit.json`,
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -438,39 +435,41 @@ export class GenerateDocs extends Script {
|
|||
}
|
||||
|
||||
private generateForTheme(theme: LayoutConfig): void {
|
||||
|
||||
const allLayers = AllSharedLayers.getSharedLayersConfigs()
|
||||
const layersToShow = theme.layers
|
||||
.filter((l) => !l.id.startsWith("note_import_") && l.id !== "favourite" && Constants.added_by_default.indexOf(<any>l.id) < 0)
|
||||
const layersToInline = layersToShow.filter(l => !allLayers.has(l.id))
|
||||
const layersToShow = theme.layers.filter(
|
||||
(l) =>
|
||||
!l.id.startsWith("note_import_") &&
|
||||
l.id !== "favourite" &&
|
||||
Constants.added_by_default.indexOf(<any>l.id) < 0
|
||||
)
|
||||
const layersToInline = layersToShow.filter((l) => !allLayers.has(l.id))
|
||||
const el = [
|
||||
["##",
|
||||
[
|
||||
"##",
|
||||
theme.title,
|
||||
"(",
|
||||
`[${theme.id}](https://mapcomplete.org/${theme.id})`,
|
||||
")"
|
||||
")",
|
||||
].join(" "),
|
||||
|
||||
"_This document details some technical information about this MapComplete theme, mostly about the attributes used in the theme. Various links point toward more information about the attributes, e.g. to the OpenStreetMap-wiki, to TagInfo or tools creating statistics_",
|
||||
"The theme introduction reads:\n",
|
||||
"> "+parse_html(theme.description.textFor("en")).textContent.replace(/\n/g, " "),
|
||||
"> " + parse_html(theme.description.textFor("en")).textContent.replace(/\n/g, " "),
|
||||
"",
|
||||
"This theme contains the following layers:",
|
||||
MarkdownUtils.list(
|
||||
layersToShow
|
||||
.map((l) => {
|
||||
if (allLayers.has(l.id)) {
|
||||
|
||||
return (`[${l.id}](../Layers/${l.id}.md)`)
|
||||
}
|
||||
return (`[${l.id} (defined in this theme)](#${l.id.trim().replace(/ /g, "-")})`)
|
||||
})
|
||||
layersToShow.map((l) => {
|
||||
if (allLayers.has(l.id)) {
|
||||
return `[${l.id}](../Layers/${l.id}.md)`
|
||||
}
|
||||
return `[${l.id} (defined in this theme)](#${l.id.trim().replace(/ /g, "-")})`
|
||||
})
|
||||
),
|
||||
"Available languages:",
|
||||
MarkdownUtils.list(theme.language.filter((ln) => ln !== "_context")),
|
||||
"# Layers defined in this theme configuration file",
|
||||
"These layers can not be reused in different themes.",
|
||||
...layersToInline.map(l => l.GenerateDocumentation(null))
|
||||
...layersToInline.map((l) => l.GenerateDocumentation(null)),
|
||||
].join("\n")
|
||||
this.WriteMarkdownFile(
|
||||
"./Docs/Themes/" + theme.id + ".md",
|
||||
|
@ -530,7 +529,9 @@ export class GenerateDocs extends Script {
|
|||
"# Special and other useful layers",
|
||||
"MapComplete has a few data layers available in the theme which have special properties through builtin-hooks. Furthermore, there are some normal layers (which are built from normal Theme-config files) but are so general that they get a mention here.",
|
||||
"# Priviliged layers",
|
||||
MarkdownUtils.list(Constants.priviliged_layers.map((id) => "[" + id + "](#" + id + ")")),
|
||||
MarkdownUtils.list(
|
||||
Constants.priviliged_layers.map((id) => "[" + id + "](#" + id + ")")
|
||||
),
|
||||
...Utils.NoNull(
|
||||
Constants.priviliged_layers.map((id) => AllSharedLayers.sharedLayers.get(id))
|
||||
).map((l) =>
|
||||
|
@ -548,9 +549,11 @@ export class GenerateDocs extends Script {
|
|||
Array.from(AllSharedLayers.sharedLayers.keys()).map(
|
||||
(id) => `[${id}](./Layers/${id}.md)`
|
||||
)
|
||||
)
|
||||
),
|
||||
].join("\n\n")
|
||||
this.WriteMarkdownFile("./Docs/BuiltinLayers.md", el, ["src/Customizations/AllKnownLayouts.ts"])
|
||||
this.WriteMarkdownFile("./Docs/BuiltinLayers.md", el, [
|
||||
"src/Customizations/AllKnownLayouts.ts",
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -73,9 +73,13 @@ export class GenerateFavouritesLayer extends Script {
|
|||
}
|
||||
|
||||
private addTagRenderings(proto: LayerConfigJson) {
|
||||
const addedByDefault = (<{labels: string[], id: string}[]> questions.tagRenderings)
|
||||
.filter(tr => tr?.["labels"]?.indexOf("added_by_default") > 0 || tr?.["labels"]?.indexOf("added_by_default_top") > 0 )
|
||||
.map(tr => tr.id)
|
||||
const addedByDefault = (<{ labels: string[]; id: string }[]>questions.tagRenderings)
|
||||
.filter(
|
||||
(tr) =>
|
||||
tr?.["labels"]?.indexOf("added_by_default") > 0 ||
|
||||
tr?.["labels"]?.indexOf("added_by_default_top") > 0
|
||||
)
|
||||
.map((tr) => tr.id)
|
||||
const blacklistedIds = new Set([
|
||||
"images",
|
||||
"questions",
|
||||
|
@ -87,7 +91,7 @@ export class GenerateFavouritesLayer extends Script {
|
|||
"delete-button",
|
||||
"all-tags",
|
||||
"all_tags",
|
||||
...addedByDefault
|
||||
...addedByDefault,
|
||||
])
|
||||
|
||||
const generatedTagRenderings: (string | QuestionableTagRenderingConfigJson)[] = []
|
||||
|
@ -236,8 +240,8 @@ export class GenerateFavouritesLayer extends Script {
|
|||
if (seenTitleIcons.has(titleIcon.id)) {
|
||||
continue
|
||||
}
|
||||
if(titleIcon.id === undefined){
|
||||
continue
|
||||
if (titleIcon.id === undefined) {
|
||||
continue
|
||||
}
|
||||
seenTitleIcons.add(titleIcon.id)
|
||||
console.log("Adding title icon", titleIcon.id)
|
||||
|
|
|
@ -24,7 +24,7 @@ function genImages(dryrun = false) {
|
|||
.replace(/\n/g, " ")
|
||||
.replace(/\r/g, "")
|
||||
.replace(/\\/g, "\\")
|
||||
.replace(/"/g, "\\\"")
|
||||
.replace(/"/g, '\\"')
|
||||
.replaceAll(" ", " ")
|
||||
|
||||
let hasNonAsciiChars = Array.from(svg)
|
||||
|
@ -38,20 +38,18 @@ function genImages(dryrun = false) {
|
|||
|
||||
const nameUC = name.toUpperCase().at(0) + name.substring(1)
|
||||
const svelteCode =
|
||||
"<script>\nexport let color = \"#000000\"\n</script>\n" +
|
||||
'<script>\nexport let color = "#000000"\n</script>\n' +
|
||||
svg
|
||||
.replace(
|
||||
"<svg ",
|
||||
"<svg {...$$$$restProps} on:click on:mouseover on:mouseenter on:mouseleave on:keydown on:focus ",
|
||||
"<svg {...$$$$restProps} on:click on:mouseover on:mouseenter on:mouseleave on:keydown on:focus "
|
||||
)
|
||||
.replace(/\\"/g, "\"")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(rgb\(0%,0%,0%\)|#000000|#000)/g, "{color}")
|
||||
fs.writeFileSync("./src/assets/svg/" + nameUC + ".svelte", svelteCode, "utf8")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GenerateIncludedImages extends Script {
|
||||
constructor() {
|
||||
super("Converts all images from assets/svg into svelte-classes.")
|
||||
|
@ -59,7 +57,6 @@ class GenerateIncludedImages extends Script {
|
|||
|
||||
async main(args: string[]): Promise<void> {
|
||||
genImages()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -332,7 +332,6 @@ class LayerOverviewUtils extends Script {
|
|||
return <QuestionableTagRenderingConfigJson[]>sharedQuestions.tagRenderings
|
||||
}
|
||||
|
||||
|
||||
return this.getSharedTagRenderings(
|
||||
doesImageExist,
|
||||
dict,
|
||||
|
@ -807,7 +806,11 @@ class LayerOverviewUtils extends Script {
|
|||
ScriptUtils.ReadSvgSync(themeFile.icon, (svg) => {
|
||||
const width: string = svg["$"].width
|
||||
if (width === undefined) {
|
||||
throw "The logo at " + themeFile.icon + " does not have a defined width"
|
||||
throw (
|
||||
"The logo at " +
|
||||
themeFile.icon +
|
||||
" does not have a defined width"
|
||||
)
|
||||
}
|
||||
const height: string = svg["$"].height
|
||||
const err = themeFile.hideFromOverview ? console.warn : console.error
|
||||
|
@ -818,9 +821,12 @@ class LayerOverviewUtils extends Script {
|
|||
err(e)
|
||||
}
|
||||
|
||||
|
||||
if (width?.endsWith("%")) {
|
||||
throw "The logo at " + themeFile.icon + " has a relative width; this is not supported"
|
||||
throw (
|
||||
"The logo at " +
|
||||
themeFile.icon +
|
||||
" has a relative width; this is not supported"
|
||||
)
|
||||
}
|
||||
|
||||
const w = parseInt(width)
|
||||
|
|
|
@ -457,27 +457,26 @@ class GenerateLayouts extends Script {
|
|||
let ogImage = layout.socialImage
|
||||
let twitterImage = ogImage
|
||||
if (ogImage === LayoutConfig.defaultSocialImage && layout.official) {
|
||||
try{
|
||||
try {
|
||||
ogImage = (await this.createSocialImage(layout, "")) ?? layout.socialImage
|
||||
twitterImage = (await this.createSocialImage(layout, "Wide")) ?? layout.socialImage
|
||||
}catch (e) {
|
||||
} catch (e) {
|
||||
console.error("Could not generate image:", e)
|
||||
}
|
||||
}
|
||||
if (twitterImage.endsWith(".svg")) {
|
||||
try{
|
||||
|
||||
// svgs are badly supported as social image, we use a generated svg instead
|
||||
twitterImage = await this.createIcon(twitterImage, 512, alreadyWritten)
|
||||
}catch (e) {
|
||||
try {
|
||||
// svgs are badly supported as social image, we use a generated svg instead
|
||||
twitterImage = await this.createIcon(twitterImage, 512, alreadyWritten)
|
||||
} catch (e) {
|
||||
console.error("Could not generate image:", e)
|
||||
}
|
||||
}
|
||||
|
||||
if (ogImage.endsWith(".svg")) {
|
||||
try{
|
||||
try {
|
||||
ogImage = await this.createIcon(ogImage, 512, alreadyWritten)
|
||||
}catch (e) {
|
||||
} catch (e) {
|
||||
console.error("Could not generate image:", e)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import { ImmutableStore } from "../src/Logic/UIEventSource"
|
|||
import { Utils } from "../src/Utils"
|
||||
|
||||
class HandleErrors extends Script {
|
||||
|
||||
constructor() {
|
||||
super("Inspects the errors made on a given day. Argument: path to errors")
|
||||
}
|
||||
|
@ -29,9 +28,10 @@ class HandleErrors extends Script {
|
|||
continue
|
||||
}
|
||||
try {
|
||||
|
||||
const parsed: {
|
||||
ip: string, index: number, date: string,
|
||||
ip: string
|
||||
index: number
|
||||
date: string
|
||||
message: {
|
||||
stacktrace: string
|
||||
message: string
|
||||
|
@ -50,18 +50,25 @@ class HandleErrors extends Script {
|
|||
}
|
||||
console.log(e.username, e.layout, e.message, parsed.date)
|
||||
for (const pendingChange of e.pendingChanges) {
|
||||
console.log("\t https://osm.org/" + pendingChange.type + "/" + pendingChange.id, pendingChange.meta.changeType, pendingChange.doDelete ? "DELETE" : "")
|
||||
console.log(
|
||||
"\t https://osm.org/" + pendingChange.type + "/" + pendingChange.id,
|
||||
pendingChange.meta.changeType,
|
||||
pendingChange.doDelete ? "DELETE" : ""
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const neededIds = Changes.GetNeededIds(e.pendingChanges)
|
||||
// We _do not_ pass in the Changes object itself - we want the data from OSM directly in order to apply the changes
|
||||
const osmObjects: { id: string, osmObj: OsmObject | "deleted" }[] = await Promise.all<{
|
||||
id: string;
|
||||
osmObj: OsmObject | "deleted"
|
||||
}>(
|
||||
neededIds.map(async id => ({ id, osmObj: await downloader.DownloadObjectAsync(id) }))
|
||||
)
|
||||
const osmObjects: { id: string; osmObj: OsmObject | "deleted" }[] =
|
||||
await Promise.all<{
|
||||
id: string
|
||||
osmObj: OsmObject | "deleted"
|
||||
}>(
|
||||
neededIds.map(async (id) => ({
|
||||
id,
|
||||
osmObj: await downloader.DownloadObjectAsync(id),
|
||||
}))
|
||||
)
|
||||
|
||||
const objects = osmObjects
|
||||
.filter((obj) => obj.osmObj !== "deleted")
|
||||
|
@ -69,40 +76,53 @@ class HandleErrors extends Script {
|
|||
|
||||
const { toUpload, refused } = Changes.fragmentChanges(e.pendingChanges, objects)
|
||||
|
||||
|
||||
const changes: {
|
||||
newObjects: OsmObject[]
|
||||
modifiedObjects: OsmObject[]
|
||||
deletedObjects: OsmObject[]
|
||||
} = new Changes({
|
||||
dryRun: new ImmutableStore(true),
|
||||
osmConnection
|
||||
osmConnection,
|
||||
}).CreateChangesetObjects(toUpload, objects)
|
||||
|
||||
const changeset = Changes.createChangesetFor("", changes)
|
||||
const path = "error_changeset_" + parsed.index + "_" + e.layout + "_" + e.username + ".osc"
|
||||
if(changeset === "<osmChange version='0.6' generator='Mapcomplete 0.44.7'></osmChange>"){
|
||||
console.log("Changes for "+parsed.index+": empty changeset, not creating a file for it")
|
||||
}else if (createdChangesets.has(changeset)) {
|
||||
console.log("Changeset " + parsed.index + " is identical to previously seen changeset, not writing to file")
|
||||
const path =
|
||||
"error_changeset_" + parsed.index + "_" + e.layout + "_" + e.username + ".osc"
|
||||
if (
|
||||
changeset ===
|
||||
"<osmChange version='0.6' generator='Mapcomplete 0.44.7'></osmChange>"
|
||||
) {
|
||||
console.log(
|
||||
"Changes for " +
|
||||
parsed.index +
|
||||
": empty changeset, not creating a file for it"
|
||||
)
|
||||
} else if (createdChangesets.has(changeset)) {
|
||||
console.log(
|
||||
"Changeset " +
|
||||
parsed.index +
|
||||
" is identical to previously seen changeset, not writing to file"
|
||||
)
|
||||
} else {
|
||||
writeFileSync(path, changeset, "utf8")
|
||||
createdChangesets.add(changeset)
|
||||
}
|
||||
const refusedContent = JSON.stringify(refused)
|
||||
if (refusedFiles.has(refusedContent)) {
|
||||
console.log("Refused changes for " + parsed.index + " is identical to previously seen changeset, not writing to file")
|
||||
console.log(
|
||||
"Refused changes for " +
|
||||
parsed.index +
|
||||
" is identical to previously seen changeset, not writing to file"
|
||||
)
|
||||
} else {
|
||||
writeFileSync(path + ".refused.json", refusedContent, "utf8")
|
||||
refusedFiles.add(refusedContent)
|
||||
}
|
||||
console.log("Written", path, "with " + e.pendingChanges.length + " changes")
|
||||
|
||||
} catch (e) {
|
||||
console.log("Parsing line failed:", e)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import ScriptUtils from "./ScriptUtils"
|
|||
import { IncomingMessage } from "node:http"
|
||||
|
||||
class ServerErrorReport extends Script {
|
||||
|
||||
private errorReport = 0
|
||||
|
||||
constructor() {
|
||||
|
@ -14,7 +13,8 @@ class ServerErrorReport extends Script {
|
|||
}
|
||||
|
||||
private getFilename(logDirectory: string, d: Date): string {
|
||||
return logDirectory +
|
||||
return (
|
||||
logDirectory +
|
||||
"/" +
|
||||
d.getUTCFullYear() +
|
||||
"_" +
|
||||
|
@ -22,11 +22,18 @@ class ServerErrorReport extends Script {
|
|||
"_" +
|
||||
d.getUTCDate() +
|
||||
".lines.json"
|
||||
)
|
||||
}
|
||||
|
||||
public reportError(path: string, queryParams: URLSearchParams, req: IncomingMessage, body: string | undefined, logDirectory: string): string {
|
||||
public reportError(
|
||||
path: string,
|
||||
queryParams: URLSearchParams,
|
||||
req: IncomingMessage,
|
||||
body: string | undefined,
|
||||
logDirectory: string
|
||||
): string {
|
||||
if (!body) {
|
||||
throw "{\"error\": \"No body; use a post request\"}"
|
||||
throw '{"error": "No body; use a post request"}'
|
||||
}
|
||||
console.log(body)
|
||||
const ip = <string>req.headers["x-forwarded-for"]
|
||||
|
@ -39,14 +46,13 @@ class ServerErrorReport extends Script {
|
|||
const d = new Date()
|
||||
const file = this.getFilename(logDirectory, d)
|
||||
const date = d.toISOString()
|
||||
const contents =
|
||||
"\n" + JSON.stringify({ ip, index: this.errorReport, date, message: body })
|
||||
const contents = "\n" + JSON.stringify({ ip, index: this.errorReport, date, message: body })
|
||||
if (!existsSync(file)) {
|
||||
writeFileSync(file, contents)
|
||||
} else {
|
||||
appendFileSync(file, contents)
|
||||
}
|
||||
this. errorReport++
|
||||
this.errorReport++
|
||||
return `{"status":"ok", "nr": ${this.errorReport}}`
|
||||
}
|
||||
|
||||
|
@ -58,8 +64,8 @@ class ServerErrorReport extends Script {
|
|||
console.log("Created this directory")
|
||||
}
|
||||
|
||||
if (!existsSync(logDirectory+"/csp")) {
|
||||
mkdirSync(logDirectory+"/csp")
|
||||
if (!existsSync(logDirectory + "/csp")) {
|
||||
mkdirSync(logDirectory + "/csp")
|
||||
console.log("Created this directory")
|
||||
}
|
||||
|
||||
|
@ -75,23 +81,33 @@ class ServerErrorReport extends Script {
|
|||
errorsToday = contents.split("\n").length
|
||||
}
|
||||
return JSON.stringify({
|
||||
"online": true,
|
||||
"errors_today": errorsToday,
|
||||
online: true,
|
||||
errors_today: errorsToday,
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
mustMatch: "report",
|
||||
mimetype: "application/json",
|
||||
handle: async (path: string, queryParams: URLSearchParams, req: IncomingMessage, body: string | undefined) => {
|
||||
handle: async (
|
||||
path: string,
|
||||
queryParams: URLSearchParams,
|
||||
req: IncomingMessage,
|
||||
body: string | undefined
|
||||
) => {
|
||||
return this.reportError(path, queryParams, req, body, logDirectory)
|
||||
},
|
||||
},
|
||||
{
|
||||
mustMatch: "csp",
|
||||
mimetype: "application/json",
|
||||
handle: async (path: string, queryParams: URLSearchParams, req: IncomingMessage, body: string | undefined) => {
|
||||
return this.reportError(path, queryParams, req, body, logDirectory+"/csp")
|
||||
handle: async (
|
||||
path: string,
|
||||
queryParams: URLSearchParams,
|
||||
req: IncomingMessage,
|
||||
body: string | undefined
|
||||
) => {
|
||||
return this.reportError(path, queryParams, req, body, logDirectory + "/csp")
|
||||
},
|
||||
},
|
||||
])
|
||||
|
|
|
@ -54,16 +54,18 @@ class ServerLdScrape extends Script {
|
|||
const start = new Date()
|
||||
const cache: Record<string, { date: Date; contents: any }> = {}
|
||||
new Server(port, {}, [
|
||||
{mustMatch: "status",
|
||||
mimetype: "application/json",
|
||||
handle: async () => {
|
||||
return JSON.stringify({
|
||||
online: true,
|
||||
cached_entries: Object.keys(cache).length,
|
||||
booted: start,
|
||||
uptime: Math.floor((new Date().getTime() - start.getTime()) / 1000)
|
||||
})
|
||||
}},
|
||||
{
|
||||
mustMatch: "status",
|
||||
mimetype: "application/json",
|
||||
handle: async () => {
|
||||
return JSON.stringify({
|
||||
online: true,
|
||||
cached_entries: Object.keys(cache).length,
|
||||
booted: start,
|
||||
uptime: Math.floor((new Date().getTime() - start.getTime()) / 1000),
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
mustMatch: "extractgraph",
|
||||
mimetype: "application/ld+json",
|
||||
|
|
|
@ -521,12 +521,14 @@ export class ExtraFunctions {
|
|||
public static HelpText(): string {
|
||||
const elems: string[] = []
|
||||
for (const func of ExtraFunctions.allFuncs) {
|
||||
elems.push("### "+func._name, func._doc, MarkdownUtils.list(func._args))
|
||||
elems.push("### " + func._name, func._doc, MarkdownUtils.list(func._args))
|
||||
}
|
||||
|
||||
return [
|
||||
ExtraFunctions.intro,
|
||||
MarkdownUtils.list(ExtraFunctions.allFuncs.map((func) => `[${func._name}](#${func._name})`)),
|
||||
MarkdownUtils.list(
|
||||
ExtraFunctions.allFuncs.map((func) => `[${func._name}](#${func._name})`)
|
||||
),
|
||||
...elems,
|
||||
].join("\n")
|
||||
}
|
||||
|
|
|
@ -57,9 +57,7 @@ export class LastClickFeatureSource implements FeatureSource {
|
|||
this._features = new UIEventSource<Feature[]>([])
|
||||
this.features = this._features
|
||||
clickSource.addCallbackAndRunD(({ lon, lat, mode }) => {
|
||||
this._features.setData([
|
||||
this.createFeature(lon, lat, mode)
|
||||
])
|
||||
this._features.setData([this.createFeature(lon, lat, mode)])
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -68,7 +68,10 @@ export default abstract class ImageProvider {
|
|||
|
||||
public abstract ExtractUrls(key: string, value: string): Promise<Promise<ProvidedImage>[]>
|
||||
|
||||
public abstract DownloadAttribution(providedImage: {url: string, id: string}): Promise<LicenseInfo>
|
||||
public abstract DownloadAttribution(providedImage: {
|
||||
url: string
|
||||
id: string
|
||||
}): Promise<LicenseInfo>
|
||||
|
||||
public abstract apiUrls(): string[]
|
||||
}
|
||||
|
|
|
@ -129,8 +129,6 @@ export class ImageUploadManager {
|
|||
tags?.data?.["_orig_theme"]
|
||||
)
|
||||
|
||||
|
||||
|
||||
if (!action) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -97,7 +97,9 @@ export class Imgur extends ImageProvider implements ImageUploader {
|
|||
const hash = url.substr("https://i.imgur.com/".length).split(/\.jpe?g/i)[0]
|
||||
|
||||
const apiUrl = "https://api.imgur.com/3/image/" + hash
|
||||
const response = await Utils.downloadJsonCached<{data: {description: string, datetime: string, views: number}}>(apiUrl, 365 * 24 * 60 * 60, {
|
||||
const response = await Utils.downloadJsonCached<{
|
||||
data: { description: string; datetime: string; views: number }
|
||||
}>(apiUrl, 365 * 24 * 60 * 60, {
|
||||
Authorization: "Client-ID " + Constants.ImgurApiKey,
|
||||
})
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ export class Mapillary extends ImageProvider {
|
|||
return [this.PrepareUrlAsync(key, value)]
|
||||
}
|
||||
|
||||
public async DownloadAttribution(providedImage: {id: string}): Promise<LicenseInfo> {
|
||||
public async DownloadAttribution(providedImage: { id: string }): Promise<LicenseInfo> {
|
||||
const mapillaryId = providedImage.id
|
||||
const metadataUrl =
|
||||
"https://graph.mapillary.com/" +
|
||||
|
|
|
@ -82,8 +82,8 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
public PrepUrl(value: undefined): undefined
|
||||
|
||||
public PrepUrl(value: string): ProvidedImage
|
||||
public PrepUrl(value: string | undefined): ProvidedImage | undefined{
|
||||
if(value === undefined){
|
||||
public PrepUrl(value: string | undefined): ProvidedImage | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined
|
||||
}
|
||||
value = WikimediaImageProvider.removeCommonsPrefix(value)
|
||||
|
@ -120,7 +120,7 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
return [Promise.resolve(this.UrlForImage("File:" + value))]
|
||||
}
|
||||
|
||||
public async DownloadAttribution(img: {url: string}): Promise<LicenseInfo> {
|
||||
public async DownloadAttribution(img: { url: string }): Promise<LicenseInfo> {
|
||||
const filename = WikimediaImageProvider.ExtractFileName(img.url)
|
||||
|
||||
if (filename === "") {
|
||||
|
|
|
@ -203,6 +203,6 @@ export class ChangeDescriptionTools {
|
|||
changes: ChangeDescription[],
|
||||
mappings: Map<string, string>
|
||||
): ChangeDescription[] {
|
||||
return changes.map(c =>ChangeDescriptionTools.rewriteIds(c, mappings))
|
||||
return changes.map((c) => ChangeDescriptionTools.rewriteIds(c, mappings))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,4 @@ export default class LinkImageAction extends OsmChangeAction {
|
|||
this._currentTags.ping()
|
||||
return tagChangeAction.CreateChangeDescriptions()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -133,50 +133,50 @@ export class Changes {
|
|||
[
|
||||
{
|
||||
key: "comment",
|
||||
docs: "The changeset comment. Will be a fixed string, mentioning the theme"
|
||||
docs: "The changeset comment. Will be a fixed string, mentioning the theme",
|
||||
},
|
||||
{
|
||||
key: "theme",
|
||||
docs: "The name of the theme that was used to create this change. "
|
||||
docs: "The name of the theme that was used to create this change. ",
|
||||
},
|
||||
{
|
||||
key: "source",
|
||||
value: "survey",
|
||||
docs: "The contributor had their geolocation enabled while making changes"
|
||||
docs: "The contributor had their geolocation enabled while making changes",
|
||||
},
|
||||
{
|
||||
key: "change_within_{distance}",
|
||||
docs: "If the contributor enabled their geolocation, this will hint how far away they were from the objects they edited. This gives an indication of proximity and if they truly surveyed or were armchair-mapping"
|
||||
docs: "If the contributor enabled their geolocation, this will hint how far away they were from the objects they edited. This gives an indication of proximity and if they truly surveyed or were armchair-mapping",
|
||||
},
|
||||
{
|
||||
key: "change_over_{distance}",
|
||||
docs: "If the contributor enabled their geolocation, this will hint how far away they were from the objects they edited. If they were over 5000m away, the might have been armchair-mapping"
|
||||
docs: "If the contributor enabled their geolocation, this will hint how far away they were from the objects they edited. If they were over 5000m away, the might have been armchair-mapping",
|
||||
},
|
||||
{
|
||||
key: "created_by",
|
||||
value: "MapComplete <version>",
|
||||
docs: "The piece of software used to create this changeset; will always start with MapComplete, followed by the version number"
|
||||
docs: "The piece of software used to create this changeset; will always start with MapComplete, followed by the version number",
|
||||
},
|
||||
{
|
||||
key: "locale",
|
||||
value: "en|nl|de|...",
|
||||
docs: "The code of the language that the contributor used MapComplete in. Hints what language the user speaks."
|
||||
docs: "The code of the language that the contributor used MapComplete in. Hints what language the user speaks.",
|
||||
},
|
||||
{
|
||||
key: "host",
|
||||
value: "https://mapcomplete.org/<theme>",
|
||||
docs: "The URL that the contributor used to make changes. One can see the used instance with this"
|
||||
docs: "The URL that the contributor used to make changes. One can see the used instance with this",
|
||||
},
|
||||
{
|
||||
key: "imagery",
|
||||
docs: "The identifier of the used background layer, this will probably be an identifier from the [editor layer index](https://github.com/osmlab/editor-layer-index)"
|
||||
}
|
||||
docs: "The identifier of the used background layer, this will probably be an identifier from the [editor layer index](https://github.com/osmlab/editor-layer-index)",
|
||||
},
|
||||
],
|
||||
"default"
|
||||
),
|
||||
...addSource(ChangeTagAction.metatags, "ChangeTag"),
|
||||
...addSource(ChangeLocationAction.metatags, "ChangeLocation"),
|
||||
...addSource(DeleteAction.metatags, "DeleteAction")
|
||||
...addSource(DeleteAction.metatags, "DeleteAction"),
|
||||
// TODO
|
||||
/*
|
||||
...DeleteAction.metatags,
|
||||
|
@ -198,11 +198,11 @@ export class Changes {
|
|||
docs,
|
||||
specialMotivation
|
||||
? "This might give a reason per modified node or way"
|
||||
: ""
|
||||
: "",
|
||||
].join("\n"),
|
||||
source
|
||||
source,
|
||||
])
|
||||
)
|
||||
),
|
||||
].join("\n\n")
|
||||
}
|
||||
|
||||
|
@ -248,12 +248,12 @@ export class Changes {
|
|||
|
||||
public async applyAction(action: OsmChangeAction): Promise<void> {
|
||||
const changeDescriptions = await action.Perform(this)
|
||||
const remapped = ChangeDescriptionTools.rewriteAllIds(changeDescriptions, this._changesetHandler._remappings)
|
||||
|
||||
remapped[0].meta.distanceToObject = this.calculateDistanceToChanges(
|
||||
action,
|
||||
remapped
|
||||
const remapped = ChangeDescriptionTools.rewriteAllIds(
|
||||
changeDescriptions,
|
||||
this._changesetHandler._remappings
|
||||
)
|
||||
|
||||
remapped[0].meta.distanceToObject = this.calculateDistanceToChanges(action, remapped)
|
||||
this.applyChanges(remapped)
|
||||
}
|
||||
|
||||
|
@ -420,12 +420,11 @@ export class Changes {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------- SORT OBJECTS -------------------
|
||||
const result = {
|
||||
newObjects: [],
|
||||
modifiedObjects: [],
|
||||
deletedObjects: []
|
||||
deletedObjects: [],
|
||||
}
|
||||
|
||||
objects.forEach((v, id) => {
|
||||
|
@ -534,12 +533,12 @@ export class Changes {
|
|||
private async getOsmObject(id: string, downloader: OsmObjectDownloader) {
|
||||
try {
|
||||
try {
|
||||
|
||||
// Important: we do **not** cache this request, we _always_ need a fresh version!
|
||||
const osmObj = await downloader.DownloadObjectAsync(id, 0)
|
||||
return { id, osmObj }
|
||||
} catch (e) {
|
||||
const msg = "Could not download OSM-object " +
|
||||
const msg =
|
||||
"Could not download OSM-object " +
|
||||
id +
|
||||
" trying again before dropping it from the changes (" +
|
||||
e +
|
||||
|
@ -549,11 +548,8 @@ export class Changes {
|
|||
return { id, osmObj }
|
||||
}
|
||||
} catch (e) {
|
||||
const msg = "Could not download OSM-object " +
|
||||
id +
|
||||
" dropping it from the changes (" +
|
||||
e +
|
||||
")"
|
||||
const msg =
|
||||
"Could not download OSM-object " + id + " dropping it from the changes (" + e + ")"
|
||||
this._reportError(msg)
|
||||
this.errors.data.push(e)
|
||||
this.errors.ping()
|
||||
|
@ -561,26 +557,33 @@ export class Changes {
|
|||
}
|
||||
}
|
||||
|
||||
public static fragmentChanges(pending: ChangeDescription[], objects: OsmObject[]): {
|
||||
refused: ChangeDescription[];
|
||||
public static fragmentChanges(
|
||||
pending: ChangeDescription[],
|
||||
objects: OsmObject[]
|
||||
): {
|
||||
refused: ChangeDescription[]
|
||||
toUpload: ChangeDescription[]
|
||||
} {
|
||||
const refused: ChangeDescription[] = []
|
||||
const toUpload: ChangeDescription[] = []
|
||||
|
||||
// All ids which have an 'update'
|
||||
const createdIds =
|
||||
new Set(pending.filter(cd => cd.changes !== undefined).map(cd => cd.id))
|
||||
pending.forEach(c => {
|
||||
const createdIds = new Set(
|
||||
pending.filter((cd) => cd.changes !== undefined).map((cd) => cd.id)
|
||||
)
|
||||
pending.forEach((c) => {
|
||||
if (c.id < 0) {
|
||||
if (createdIds.has(c.id)) {
|
||||
toUpload.push(c)
|
||||
} else {
|
||||
reportError(`Got an orphaned change. The 'creation'-change description for ${c.type}/${c.id} got lost. Permanently dropping this change:`+JSON.stringify(c))
|
||||
reportError(
|
||||
`Got an orphaned change. The 'creation'-change description for ${c.type}/${c.id} got lost. Permanently dropping this change:` +
|
||||
JSON.stringify(c)
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
const matchFound = !!objects.find(o => o.id === c.id && o.type === c.type)
|
||||
const matchFound = !!objects.find((o) => o.id === c.id && o.type === c.type)
|
||||
if (matchFound) {
|
||||
toUpload.push(c)
|
||||
} else {
|
||||
|
@ -588,8 +591,7 @@ export class Changes {
|
|||
}
|
||||
})
|
||||
|
||||
return {refused, toUpload}
|
||||
|
||||
return { refused, toUpload }
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -604,7 +606,7 @@ export class Changes {
|
|||
// We _do not_ pass in the Changes object itself - we want the data from OSM directly in order to apply the changes
|
||||
const downloader = new OsmObjectDownloader(this.backend, undefined)
|
||||
let osmObjects = await Promise.all<{ id: string; osmObj: OsmObject | "deleted" }>(
|
||||
neededIds.map(id => this.getOsmObject(id, downloader))
|
||||
neededIds.map((id) => this.getOsmObject(id, downloader))
|
||||
)
|
||||
|
||||
osmObjects = Utils.NoNull(osmObjects)
|
||||
|
@ -640,14 +642,14 @@ export class Changes {
|
|||
([key, count]) => ({
|
||||
key: key,
|
||||
value: count,
|
||||
aggregate: true
|
||||
aggregate: true,
|
||||
})
|
||||
)
|
||||
const motivations = pending
|
||||
.filter((descr) => descr.meta.specialMotivation !== undefined)
|
||||
.map((descr) => ({
|
||||
key: descr.meta.changeType + ":" + descr.type + "/" + descr.id,
|
||||
value: descr.meta.specialMotivation
|
||||
value: descr.meta.specialMotivation,
|
||||
}))
|
||||
|
||||
const distances = Utils.NoNull(pending.map((descr) => descr.meta.distanceToObject))
|
||||
|
@ -678,7 +680,7 @@ export class Changes {
|
|||
return {
|
||||
key,
|
||||
value: count,
|
||||
aggregate: true
|
||||
aggregate: true,
|
||||
}
|
||||
})
|
||||
)
|
||||
|
@ -693,26 +695,25 @@ export class Changes {
|
|||
const metatags: ChangesetTag[] = [
|
||||
{
|
||||
key: "comment",
|
||||
value: comment
|
||||
value: comment,
|
||||
},
|
||||
{
|
||||
key: "theme",
|
||||
value: theme
|
||||
value: theme,
|
||||
},
|
||||
...perType,
|
||||
...motivations,
|
||||
...perBinMessage
|
||||
...perBinMessage,
|
||||
]
|
||||
|
||||
|
||||
let {toUpload, refused} = Changes.fragmentChanges(
|
||||
pending, objects
|
||||
)
|
||||
let { toUpload, refused } = Changes.fragmentChanges(pending, objects)
|
||||
|
||||
await this._changesetHandler.UploadChangeset(
|
||||
(csId, remappings) => {
|
||||
if (remappings.size > 0) {
|
||||
toUpload = toUpload.map((ch) => ChangeDescriptionTools.rewriteIds(ch, remappings))
|
||||
toUpload = toUpload.map((ch) =>
|
||||
ChangeDescriptionTools.rewriteIds(ch, remappings)
|
||||
)
|
||||
}
|
||||
|
||||
const changes: {
|
||||
|
@ -756,9 +757,9 @@ export class Changes {
|
|||
)
|
||||
console.log(
|
||||
"Using current-open-changeset-" +
|
||||
theme +
|
||||
" from the preferences, got " +
|
||||
openChangeset.data
|
||||
theme +
|
||||
" from the preferences, got " +
|
||||
openChangeset.data
|
||||
)
|
||||
|
||||
const refused = await self.flushSelectChanges(pendingChanges, openChangeset)
|
||||
|
@ -777,7 +778,7 @@ export class Changes {
|
|||
)
|
||||
|
||||
// We keep all the refused changes to try them again
|
||||
this.pendingChanges.setData(refusedChanges.flatMap(c => c))
|
||||
this.pendingChanges.setData(refusedChanges.flatMap((c) => c))
|
||||
} catch (e) {
|
||||
console.error(
|
||||
"Could not handle changes - probably an old, pending changeset in localstorage with an invalid format; erasing those",
|
||||
|
|
|
@ -94,7 +94,6 @@ export class ChangesetHandler {
|
|||
return hasChange
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The full logic to upload a change to one or more elements.
|
||||
*
|
||||
|
@ -155,7 +154,11 @@ export class ChangesetHandler {
|
|||
if (this._reportError) {
|
||||
this._reportError(e)
|
||||
}
|
||||
console.warn("Could not open/upload changeset due to ", e, "trying again with a another fresh changeset ")
|
||||
console.warn(
|
||||
"Could not open/upload changeset due to ",
|
||||
e,
|
||||
"trying again with a another fresh changeset "
|
||||
)
|
||||
openChangeset.setData(undefined)
|
||||
|
||||
throw e
|
||||
|
@ -188,7 +191,12 @@ export class ChangesetHandler {
|
|||
await this.UpdateTags(csId, rewrittenTags)
|
||||
} catch (e) {
|
||||
if (this._reportError) {
|
||||
this._reportError("Could not reuse changeset " + csId + ", might be closed: " + (e.stacktrace ?? ("" + e)))
|
||||
this._reportError(
|
||||
"Could not reuse changeset " +
|
||||
csId +
|
||||
", might be closed: " +
|
||||
(e.stacktrace ?? "" + e)
|
||||
)
|
||||
}
|
||||
console.warn("Could not upload, changeset is probably closed: ", e)
|
||||
openChangeset.setData(undefined)
|
||||
|
@ -237,7 +245,7 @@ export class ChangesetHandler {
|
|||
if (newMetaTag === undefined) {
|
||||
extraMetaTags.push({
|
||||
key: key,
|
||||
value: oldCsTags[key]
|
||||
value: oldCsTags[key],
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
@ -374,11 +382,11 @@ export class ChangesetHandler {
|
|||
["locale", Locale.language.data],
|
||||
["host", `${window.location.origin}${window.location.pathname}`],
|
||||
["source", setSourceAsSurvey ? "survey" : undefined],
|
||||
["imagery", this.changes.state["backgroundLayer"]?.data?.id]
|
||||
["imagery", this.changes.state["backgroundLayer"]?.data?.id],
|
||||
].map(([key, value]) => ({
|
||||
key,
|
||||
value,
|
||||
aggregate: false
|
||||
aggregate: false,
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ export class OsmConnection {
|
|||
this.auth.xhr(
|
||||
{
|
||||
method: "GET",
|
||||
path: "/api/0.6/user/details"
|
||||
path: "/api/0.6/user/details",
|
||||
},
|
||||
(err, details: XMLDocument) => {
|
||||
if (err != null) {
|
||||
|
@ -326,9 +326,9 @@ export class OsmConnection {
|
|||
method,
|
||||
headers: header,
|
||||
content,
|
||||
path: `/api/0.6/${path}`
|
||||
path: `/api/0.6/${path}`,
|
||||
},
|
||||
function(err, response) {
|
||||
function (err, response) {
|
||||
if (err !== null) {
|
||||
error(err)
|
||||
} else {
|
||||
|
@ -408,7 +408,7 @@ export class OsmConnection {
|
|||
"notes.json",
|
||||
content,
|
||||
{
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
||||
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
|
||||
},
|
||||
true
|
||||
)
|
||||
|
@ -449,7 +449,7 @@ export class OsmConnection {
|
|||
file: gpx,
|
||||
description: options.description,
|
||||
tags: options.labels?.join(",") ?? "",
|
||||
visibility: options.visibility
|
||||
visibility: options.visibility,
|
||||
}
|
||||
|
||||
if (!contents.description) {
|
||||
|
@ -457,9 +457,9 @@ export class OsmConnection {
|
|||
}
|
||||
const extras = {
|
||||
file:
|
||||
"; filename=\"" +
|
||||
'; filename="' +
|
||||
(options.filename ?? "gpx_track_mapcomplete_" + new Date().toISOString()) +
|
||||
"\"\r\nContent-Type: application/gpx+xml"
|
||||
'"\r\nContent-Type: application/gpx+xml',
|
||||
}
|
||||
|
||||
const boundary = "987654"
|
||||
|
@ -467,7 +467,7 @@ export class OsmConnection {
|
|||
let body = ""
|
||||
for (const key in contents) {
|
||||
body += "--" + boundary + "\r\n"
|
||||
body += "Content-Disposition: form-data; name=\"" + key + "\""
|
||||
body += 'Content-Disposition: form-data; name="' + key + '"'
|
||||
if (extras[key] !== undefined) {
|
||||
body += extras[key]
|
||||
}
|
||||
|
@ -478,7 +478,7 @@ export class OsmConnection {
|
|||
|
||||
const response = await this.post("gpx/create", body, {
|
||||
"Content-Type": "multipart/form-data; boundary=" + boundary,
|
||||
"Content-Length": "" + body.length
|
||||
"Content-Length": "" + body.length,
|
||||
})
|
||||
const parsed = JSON.parse(response)
|
||||
console.log("Uploaded GPX track", parsed)
|
||||
|
@ -499,9 +499,9 @@ export class OsmConnection {
|
|||
{
|
||||
method: "POST",
|
||||
|
||||
path: `/api/0.6/notes/${id}/comment?text=${encodeURIComponent(text)}`
|
||||
path: `/api/0.6/notes/${id}/comment?text=${encodeURIComponent(text)}`,
|
||||
},
|
||||
function(err) {
|
||||
function (err) {
|
||||
if (err !== null) {
|
||||
error(err)
|
||||
} else {
|
||||
|
@ -516,7 +516,7 @@ export class OsmConnection {
|
|||
* To be called by land.html
|
||||
*/
|
||||
public finishLogin(callback: (previousURL: string) => void) {
|
||||
this.auth.authenticate(function() {
|
||||
this.auth.authenticate(function () {
|
||||
// Fully authed at this point
|
||||
console.log("Authentication successful!")
|
||||
const previousLocation = LocalStorageSource.Get("location_before_login")
|
||||
|
@ -534,7 +534,7 @@ export class OsmConnection {
|
|||
: window.location.protocol + "//" + window.location.host + "/land.html",
|
||||
singlepage: true, // We always use 'singlePage', it is the most stable - including in PWA
|
||||
auto: true,
|
||||
apiUrl: this._oauth_config.api_url ?? this._oauth_config.url
|
||||
apiUrl: this._oauth_config.api_url ?? this._oauth_config.url,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -635,7 +635,7 @@ export default class SimpleMetaTaggers {
|
|||
isLazy: true,
|
||||
},
|
||||
(feature: Feature, layer: LayerConfig, tagsStore: UIEventSource<OsmTags>) => {
|
||||
if(tagsStore === undefined){
|
||||
if (tagsStore === undefined) {
|
||||
return
|
||||
}
|
||||
Utils.AddLazyPropertyAsync(feature.properties, "_currency", async () => {
|
||||
|
@ -780,11 +780,11 @@ export default class SimpleMetaTaggers {
|
|||
|
||||
subElements.push("## Metatags calculated by MapComplete")
|
||||
subElements.push(
|
||||
"The following values are always calculated, by default, by MapComplete and are available automatically on all elements in every theme"
|
||||
"The following values are always calculated, by default, by MapComplete and are available automatically on all elements in every theme"
|
||||
)
|
||||
for (const metatag of SimpleMetaTaggers.metatags) {
|
||||
subElements.push(
|
||||
"### "+metatag.keys.join(", "),
|
||||
"### " + metatag.keys.join(", "),
|
||||
metatag.doc,
|
||||
metatag.isLazy ? "This is a lazy metatag and is only calculated when needed" : ""
|
||||
)
|
||||
|
|
|
@ -1,14 +1,42 @@
|
|||
import { Utils } from "../../Utils"
|
||||
/** This code is autogenerated - do not edit. Edit ./assets/layers/usersettings/usersettings.json instead */
|
||||
export class ThemeMetaTagging {
|
||||
public static readonly themeName = "usersettings"
|
||||
public static readonly themeName = "usersettings"
|
||||
|
||||
public metaTaggging_for_usersettings(feat: {properties: Record<string, string>}) {
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_md', () => feat.properties._description.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)?.at(1) )
|
||||
Utils.AddLazyProperty(feat.properties, '_d', () => feat.properties._description?.replace(/</g,'<')?.replace(/>/g,'>') ?? '' )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate_a', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.href.match(/mastodon|en.osm.town/) !== null)[0]?.href }) (feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_link', () => (feat => {const e = document.createElement('div');e.innerHTML = feat.properties._d;return Array.from(e.getElementsByTagName("a")).filter(a => a.getAttribute("rel")?.indexOf('me') >= 0)[0]?.href})(feat) )
|
||||
Utils.AddLazyProperty(feat.properties, '_mastodon_candidate', () => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a )
|
||||
feat.properties['__current_backgroun'] = 'initial_value'
|
||||
}
|
||||
public metaTaggging_for_usersettings(feat: { properties: Record<string, string> }) {
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_md", () =>
|
||||
feat.properties._description
|
||||
.match(/\[[^\]]*\]\((.*(mastodon|en.osm.town).*)\).*/)
|
||||
?.at(1)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_d",
|
||||
() => feat.properties._description?.replace(/</g, "<")?.replace(/>/g, ">") ?? ""
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_candidate_a", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.href.match(/mastodon|en.osm.town/) !== null
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(feat.properties, "_mastodon_link", () =>
|
||||
((feat) => {
|
||||
const e = document.createElement("div")
|
||||
e.innerHTML = feat.properties._d
|
||||
return Array.from(e.getElementsByTagName("a")).filter(
|
||||
(a) => a.getAttribute("rel")?.indexOf("me") >= 0
|
||||
)[0]?.href
|
||||
})(feat)
|
||||
)
|
||||
Utils.AddLazyProperty(
|
||||
feat.properties,
|
||||
"_mastodon_candidate",
|
||||
() => feat.properties._mastodon_candidate_md ?? feat.properties._mastodon_candidate_a
|
||||
)
|
||||
feat.properties["__current_backgroun"] = "initial_value"
|
||||
}
|
||||
}
|
|
@ -17,14 +17,15 @@ interface ImageFetcher {
|
|||
fetchImages(lat: number, lon: number): Promise<P4CPicture[]>
|
||||
|
||||
readonly name: string
|
||||
|
||||
}
|
||||
|
||||
|
||||
class CachedFetcher implements ImageFetcher {
|
||||
private readonly _fetcher: ImageFetcher
|
||||
private readonly _zoomlevel: number
|
||||
private readonly cache: Map<number, Promise<P4CPicture[]>> = new Map<number, Promise<P4CPicture[]>>()
|
||||
private readonly cache: Map<number, Promise<P4CPicture[]>> = new Map<
|
||||
number,
|
||||
Promise<P4CPicture[]>
|
||||
>()
|
||||
public readonly name: string
|
||||
|
||||
constructor(fetcher: ImageFetcher, zoomlevel: number = 19) {
|
||||
|
@ -71,20 +72,17 @@ class NearbyImageUtils {
|
|||
const da = GeoOperations.distanceBetween([a.coordinates.lng, a.coordinates.lat], c)
|
||||
const db = GeoOperations.distanceBetween([b.coordinates.lng, b.coordinates.lat], c)
|
||||
return da - db
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class P4CImageFetcher implements ImageFetcher {
|
||||
|
||||
public static readonly services = ["mapillary", "flickr", "kartaview", "wikicommons"] as const
|
||||
public static readonly apiUrls = ["https://api.flickr.com"]
|
||||
private _options: { maxDaysOld: number, searchRadius: number }
|
||||
private _options: { maxDaysOld: number; searchRadius: number }
|
||||
public readonly name: P4CService
|
||||
|
||||
constructor(service: P4CService, options?: { maxDaysOld: number, searchRadius: number }) {
|
||||
constructor(service: P4CService, options?: { maxDaysOld: number; searchRadius: number }) {
|
||||
this.name = service
|
||||
this._options = options
|
||||
}
|
||||
|
@ -95,22 +93,19 @@ class P4CImageFetcher implements ImageFetcher {
|
|||
const searchRadius = this._options?.searchRadius ?? 100
|
||||
|
||||
try {
|
||||
|
||||
return await picManager.startPicsRetrievalAround(
|
||||
new P4C.LatLng(lat, lon),
|
||||
searchRadius,
|
||||
{
|
||||
mindate: new Date().getTime() - maxAgeSeconds,
|
||||
towardscenter: false,
|
||||
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (e) {
|
||||
console.log("P4C image fetcher failed with", e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,9 +160,7 @@ class ImagesInLoadedDataFetcher implements ImageFetcher {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
class MapillaryFetcher implements ImageFetcher {
|
||||
|
||||
public readonly name = "mapillary_new"
|
||||
private readonly _panoramas: "only" | "no" | undefined
|
||||
private readonly _max_images: 100 | number
|
||||
|
@ -176,9 +169,9 @@ class MapillaryFetcher implements ImageFetcher {
|
|||
private readonly end_captured_at?: Date
|
||||
|
||||
constructor(options?: {
|
||||
panoramas: undefined | "only" | "no",
|
||||
max_images?: 100 | number,
|
||||
start_captured_at?: Date,
|
||||
panoramas: undefined | "only" | "no"
|
||||
max_images?: 100 | number
|
||||
start_captured_at?: Date
|
||||
end_captured_at?: Date
|
||||
}) {
|
||||
this._panoramas = options?.panoramas
|
||||
|
@ -188,12 +181,19 @@ class MapillaryFetcher implements ImageFetcher {
|
|||
}
|
||||
|
||||
async fetchImages(lat: number, lon: number): Promise<P4CPicture[]> {
|
||||
|
||||
const boundingBox = new BBox([[lon, lat]]).padAbsolute(0.003)
|
||||
let url = "https://graph.mapillary.com/images?fields=computed_geometry,creator,id,thumb_256_url,thumb_original_url,compass_angle&bbox="
|
||||
+ [boundingBox.getWest(), boundingBox.getSouth(), boundingBox.getEast(), boundingBox.getNorth()].join(",")
|
||||
+ "&access_token=" + encodeURIComponent(Constants.mapillary_client_token_v4)
|
||||
+ "&limit=" + this._max_images
|
||||
let url =
|
||||
"https://graph.mapillary.com/images?fields=computed_geometry,creator,id,thumb_256_url,thumb_original_url,compass_angle&bbox=" +
|
||||
[
|
||||
boundingBox.getWest(),
|
||||
boundingBox.getSouth(),
|
||||
boundingBox.getEast(),
|
||||
boundingBox.getNorth(),
|
||||
].join(",") +
|
||||
"&access_token=" +
|
||||
encodeURIComponent(Constants.mapillary_client_token_v4) +
|
||||
"&limit=" +
|
||||
this._max_images
|
||||
{
|
||||
if (this._panoramas === "no") {
|
||||
url += "&is_pano=false"
|
||||
|
@ -201,21 +201,28 @@ class MapillaryFetcher implements ImageFetcher {
|
|||
url += "&is_pano=true"
|
||||
}
|
||||
if (this.start_captured_at) {
|
||||
url += "&start_captured_at="+ this.start_captured_at?.toISOString()
|
||||
url += "&start_captured_at=" + this.start_captured_at?.toISOString()
|
||||
}
|
||||
if (this.end_captured_at) {
|
||||
url += "&end_captured_at="+ this.end_captured_at?.toISOString()
|
||||
url += "&end_captured_at=" + this.end_captured_at?.toISOString()
|
||||
}
|
||||
}
|
||||
|
||||
const response = await Utils.downloadJson<{
|
||||
data: { id: string, creator: string, computed_geometry: Point, is_pano: boolean,thumb_256_url: string, thumb_original_url: string, compass_angle: number }[]
|
||||
data: {
|
||||
id: string
|
||||
creator: string
|
||||
computed_geometry: Point
|
||||
is_pano: boolean
|
||||
thumb_256_url: string
|
||||
thumb_original_url: string
|
||||
compass_angle: number
|
||||
}[]
|
||||
}>(url)
|
||||
const pics: P4CPicture[] = []
|
||||
for (const img of response.data) {
|
||||
|
||||
const c = img.computed_geometry.coordinates
|
||||
if(img.thumb_original_url === undefined){
|
||||
if (img.thumb_original_url === undefined) {
|
||||
continue
|
||||
}
|
||||
pics.push({
|
||||
|
@ -224,7 +231,7 @@ class MapillaryFetcher implements ImageFetcher {
|
|||
coordinates: { lng: c[0], lat: c[1] },
|
||||
thumbUrl: img.thumb_256_url,
|
||||
osmTags: {
|
||||
"mapillary":img.id
|
||||
mapillary: img.id,
|
||||
},
|
||||
details: {
|
||||
isSpherical: img.is_pano,
|
||||
|
@ -241,22 +248,24 @@ export class CombinedFetcher {
|
|||
private readonly sources: ReadonlyArray<CachedFetcher>
|
||||
public static apiUrls = P4CImageFetcher.apiUrls
|
||||
|
||||
|
||||
constructor(radius: number, maxage: Date, indexedFeatures: IndexedFeatureSource) {
|
||||
this.sources = [
|
||||
new ImagesInLoadedDataFetcher(indexedFeatures, radius),
|
||||
new MapillaryFetcher({
|
||||
panoramas: "no",
|
||||
max_images: 25,
|
||||
start_captured_at : maxage
|
||||
start_captured_at: maxage,
|
||||
}),
|
||||
new P4CImageFetcher("mapillary"),
|
||||
new P4CImageFetcher("wikicommons"),
|
||||
].map(f => new CachedFetcher(f))
|
||||
].map((f) => new CachedFetcher(f))
|
||||
}
|
||||
|
||||
public getImagesAround(lon: number, lat: number): {
|
||||
images: Store<P4CPicture[]>,
|
||||
public getImagesAround(
|
||||
lon: number,
|
||||
lat: number
|
||||
): {
|
||||
images: Store<P4CPicture[]>
|
||||
state: Store<Record<string, "loading" | "done" | "error">>
|
||||
} {
|
||||
const src = new UIEventSource<P4CPicture[]>([])
|
||||
|
@ -264,9 +273,9 @@ export class CombinedFetcher {
|
|||
for (const source of this.sources) {
|
||||
state.data[source.name] = "loading"
|
||||
state.ping()
|
||||
source.fetchImages(lat, lon)
|
||||
.then(pics => {
|
||||
console.log(source.name,"==>>",pics)
|
||||
source.fetchImages(lat, lon).then(
|
||||
(pics) => {
|
||||
console.log(source.name, "==>>", pics)
|
||||
state.data[source.name] = "done"
|
||||
state.ping()
|
||||
if (src.data === undefined) {
|
||||
|
@ -276,27 +285,26 @@ export class CombinedFetcher {
|
|||
const seenIds = new Set<string>()
|
||||
for (const p4CPicture of [...src.data, ...pics]) {
|
||||
const id = p4CPicture.pictureUrl
|
||||
if(seenIds.has(id)){
|
||||
if (seenIds.has(id)) {
|
||||
continue
|
||||
}
|
||||
newList.push(p4CPicture)
|
||||
seenIds.add(id)
|
||||
if(id === undefined){
|
||||
|
||||
console.log("Img:", p4CPicture)
|
||||
if (id === undefined) {
|
||||
console.log("Img:", p4CPicture)
|
||||
}
|
||||
}
|
||||
NearbyImageUtils.sortByDistance(newList, lon, lat)
|
||||
src.setData(newList)
|
||||
}
|
||||
}, err => {
|
||||
},
|
||||
(err) => {
|
||||
console.error("Could not load images from", source.name, "due to", err)
|
||||
state.data[source.name] = "error"
|
||||
state.ping()
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
return { images: src, state }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,9 @@ export interface WikidataAdvancedSearchoptions extends WikidataSearchoptions {
|
|||
notInstanceOf?: number[]
|
||||
}
|
||||
|
||||
interface SparqlResult {results: { bindings: {item, label, description, num}[] }}
|
||||
interface SparqlResult {
|
||||
results: { bindings: { item; label; description; num }[] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility functions around wikidata
|
||||
|
@ -422,7 +424,7 @@ export default class Wikidata {
|
|||
}
|
||||
|
||||
const url = "https://www.wikidata.org/wiki/Special:EntityData/" + id + ".json"
|
||||
const entities = (await Utils.downloadJsonCached<{entities}>(url, 10000)).entities
|
||||
const entities = (await Utils.downloadJsonCached<{ entities }>(url, 10000)).entities
|
||||
const firstKey = <string>Array.from(Object.keys(entities))[0] // Roundabout way to fetch the entity; it might have been a redirect
|
||||
const response = entities[firstKey]
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ export abstract class Conversion<TIn, TOut> {
|
|||
fixed = this.convert(json, context)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
context.err("ERROR WHILE RUNNING STEP " + this.name+": "+e)
|
||||
context.err("ERROR WHILE RUNNING STEP " + this.name + ": " + e)
|
||||
fixed = undefined
|
||||
}
|
||||
for (const msg of context.messages) {
|
||||
|
@ -54,12 +54,11 @@ export abstract class Conversion<TIn, TOut> {
|
|||
throw new Error(
|
||||
[
|
||||
"Detected one or more errors, stopping now:",
|
||||
context.getAll("error").map((e) => e.context.path.join(".") + ": " + e.message)
|
||||
context.getAll("error").map((e) => e.context.path.join(".") + ": " + e.message),
|
||||
].join("\n\t")
|
||||
)
|
||||
}
|
||||
return fixed
|
||||
|
||||
}
|
||||
|
||||
public andThenF<X>(f: (tout: TOut) => X): Conversion<TIn, X> {
|
||||
|
@ -69,8 +68,7 @@ export abstract class Conversion<TIn, TOut> {
|
|||
public abstract convert(json: TIn, context: ConversionContext): TOut
|
||||
}
|
||||
|
||||
export abstract class DesugaringStep<T> extends Conversion<T, T> {
|
||||
}
|
||||
export abstract class DesugaringStep<T> extends Conversion<T, T> {}
|
||||
|
||||
export class Pipe<TIn, TInter, TOut> extends Conversion<TIn, TOut> {
|
||||
private readonly _step0: Conversion<TIn, TInter>
|
||||
|
@ -257,7 +255,7 @@ export class Cached<TIn, TOut> extends Conversion<TIn, TOut> {
|
|||
const converted = this._step.convert(json, context)
|
||||
Object.defineProperty(json, this.key, {
|
||||
value: converted,
|
||||
enumerable: false
|
||||
enumerable: false,
|
||||
})
|
||||
return converted
|
||||
}
|
||||
|
@ -270,8 +268,8 @@ export class Fuse<T> extends DesugaringStep<T> {
|
|||
constructor(doc: string, ...steps: DesugaringStep<T>[]) {
|
||||
super(
|
||||
(doc ?? "") +
|
||||
"This fused pipeline of the following steps: " +
|
||||
steps.map((s) => s.name).join(", "),
|
||||
"This fused pipeline of the following steps: " +
|
||||
steps.map((s) => s.name).join(", "),
|
||||
Utils.Dedup([].concat(...steps.map((step) => step.modifiedAttributes))),
|
||||
"Fuse(" + steps.map((s) => s.name).join(", ") + ")"
|
||||
)
|
||||
|
|
|
@ -55,13 +55,12 @@ export class ExtractImages extends Conversion<
|
|||
}
|
||||
|
||||
static isImageType(metapath: any): boolean {
|
||||
if (metapath.hints.typehint === "icon" ||
|
||||
metapath.hints.typehint === "image") {
|
||||
if (metapath.hints.typehint === "icon" || metapath.hints.typehint === "image") {
|
||||
return true
|
||||
}
|
||||
|
||||
const types = metapath.hints.types?.split(";").map(x => x.trim())
|
||||
if (types?.some(t => t === "icon" || t === "image")) {
|
||||
const types = metapath.hints.types?.split(";").map((x) => x.trim())
|
||||
if (types?.some((t) => t === "icon" || t === "image")) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -120,7 +119,7 @@ export class ExtractImages extends Conversion<
|
|||
const allRenderedValuesAreImages = ExtractImages.isImageType(metapath)
|
||||
|
||||
const found = Utils.CollectPath(metapath.path, json)
|
||||
if(found.length === 0){
|
||||
if (found.length === 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -177,7 +176,7 @@ export class ExtractImages extends Conversion<
|
|||
} else {
|
||||
allFoundImages.push({
|
||||
path: img.leaf,
|
||||
context: context + "." + path
|
||||
context: context + "." + path,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -191,7 +190,7 @@ export class ExtractImages extends Conversion<
|
|||
.ExtractImages(false)
|
||||
.map((path) => ({
|
||||
path,
|
||||
context: context + "." + path
|
||||
context: context + "." + path,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
@ -211,7 +210,7 @@ export class ExtractImages extends Conversion<
|
|||
}
|
||||
allFoundImages.push({
|
||||
context: context.path.join(".") + "." + foundElement.path.join("."),
|
||||
path: foundElement.leaf
|
||||
path: foundElement.leaf,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,10 +7,13 @@ import {
|
|||
FirstOf,
|
||||
Fuse,
|
||||
On,
|
||||
SetDefault
|
||||
SetDefault,
|
||||
} from "./Conversion"
|
||||
import { LayerConfigJson } from "../Json/LayerConfigJson"
|
||||
import { MinimalTagRenderingConfigJson, TagRenderingConfigJson } from "../Json/TagRenderingConfigJson"
|
||||
import {
|
||||
MinimalTagRenderingConfigJson,
|
||||
TagRenderingConfigJson,
|
||||
} from "../Json/TagRenderingConfigJson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import RewritableConfigJson from "../Json/RewritableConfigJson"
|
||||
import SpecialVisualizations from "../../../UI/SpecialVisualizations"
|
||||
|
@ -63,24 +66,27 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
|
|||
const newFilters: FilterConfigJson[] = []
|
||||
const filters = <(FilterConfigJson | string)[]>json.filter
|
||||
|
||||
for (let i = 0; i < json.tagRenderings?.length; i++){
|
||||
const tagRendering = <TagRenderingConfigJson> json.tagRenderings[i]
|
||||
if(!tagRendering?.filter){
|
||||
for (let i = 0; i < json.tagRenderings?.length; i++) {
|
||||
const tagRendering = <TagRenderingConfigJson>json.tagRenderings[i]
|
||||
if (!tagRendering?.filter) {
|
||||
continue
|
||||
}
|
||||
for (const filterName of tagRendering.filter ?? []) {
|
||||
if(typeof filterName !== "string"){
|
||||
context.enters("tagRenderings",i,"filter").err("Not a string: "+ filterName)
|
||||
if (typeof filterName !== "string") {
|
||||
context.enters("tagRenderings", i, "filter").err("Not a string: " + filterName)
|
||||
}
|
||||
const exists = filters.some(existing => {
|
||||
const id : string = existing["id"] ?? existing
|
||||
return filterName === id || (filterName.startsWith("filters.") && filterName.endsWith("."+id))
|
||||
const exists = filters.some((existing) => {
|
||||
const id: string = existing["id"] ?? existing
|
||||
return (
|
||||
filterName === id ||
|
||||
(filterName.startsWith("filters.") && filterName.endsWith("." + id))
|
||||
)
|
||||
})
|
||||
if(exists){
|
||||
if (exists) {
|
||||
continue
|
||||
}
|
||||
if(!filterName){
|
||||
context.err("Got undefined as filter expansion in "+tagRendering["id"])
|
||||
if (!filterName) {
|
||||
context.err("Got undefined as filter expansion in " + tagRendering["id"])
|
||||
continue
|
||||
}
|
||||
filters.push(filterName)
|
||||
|
@ -89,7 +95,7 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
|
|||
|
||||
for (let i = 0; i < filters.length; i++) {
|
||||
const filter = filters[i]
|
||||
if(filter === undefined){
|
||||
if (filter === undefined) {
|
||||
continue
|
||||
}
|
||||
if (typeof filter !== "string") {
|
||||
|
@ -141,9 +147,9 @@ class ExpandFilter extends DesugaringStep<LayerConfigJson> {
|
|||
const expandedFilter = (<(FilterConfigJson | string)[]>layer.filter).find(
|
||||
(f) => typeof f !== "string" && f.id === expectedId
|
||||
)
|
||||
if(expandedFilter === undefined){
|
||||
context.err("Did not find filter with name "+filter)
|
||||
}else{
|
||||
if (expandedFilter === undefined) {
|
||||
context.err("Did not find filter with name " + filter)
|
||||
} else {
|
||||
newFilters.push(<FilterConfigJson>expandedFilter)
|
||||
}
|
||||
} else {
|
||||
|
@ -644,7 +650,6 @@ export class AddQuestionBox extends DesugaringStep<LayerConfigJson> {
|
|||
}
|
||||
|
||||
export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
||||
|
||||
private readonly _desugaring: DesugaringContext
|
||||
private readonly _addedByDefaultAtTop: QuestionableTagRenderingConfigJson[]
|
||||
private readonly _addedByDefault: QuestionableTagRenderingConfigJson[]
|
||||
|
@ -669,7 +674,6 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
|||
return Utils.NoNull(idsInOrder.map((id) => this._desugaring.tagRenderings.get(id)))
|
||||
}
|
||||
|
||||
|
||||
convert(json: LayerConfigJson, _: ConversionContext): LayerConfigJson {
|
||||
if (this._desugaring.tagRenderings === null) {
|
||||
return json
|
||||
|
@ -734,7 +738,7 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
|
|||
const trc: QuestionableTagRenderingConfigJson = {
|
||||
id: "all-tags",
|
||||
render: { "*": "{all_tags()}" },
|
||||
labels:["ignore_docs"],
|
||||
labels: ["ignore_docs"],
|
||||
metacondition: {
|
||||
or: [
|
||||
"__featureSwitchIsDebugging=true",
|
||||
|
|
|
@ -71,8 +71,8 @@ class SubstituteLayer extends Conversion<string | LayerConfigJson, LayerConfigJs
|
|||
|
||||
for (const name of names) {
|
||||
const found = Utils.Clone(state.sharedLayers.get(name))
|
||||
if(found === undefined){
|
||||
context.err("Layer with name "+name+" not found")
|
||||
if (found === undefined) {
|
||||
context.err("Layer with name " + name + " not found")
|
||||
continue
|
||||
}
|
||||
found["_basedOn"] = name
|
||||
|
@ -393,7 +393,6 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
}[] = []
|
||||
|
||||
for (const layerConfig of alreadyLoaded) {
|
||||
|
||||
try {
|
||||
const layerDeps = DependencyCalculator.getLayerDependencies(
|
||||
new LayerConfig(layerConfig, themeId + "(dependencies)")
|
||||
|
@ -402,7 +401,10 @@ class AddDependencyLayersToTheme extends DesugaringStep<LayoutConfigJson> {
|
|||
} catch (e) {
|
||||
console.error(e)
|
||||
throw (
|
||||
"Detecting layer dependencies for " + layerConfig?.id + " failed due to " + e
|
||||
"Detecting layer dependencies for " +
|
||||
layerConfig?.id +
|
||||
" failed due to " +
|
||||
e
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1761,7 +1761,7 @@ export class ValidateFilter extends DesugaringStep<FilterConfigJson> {
|
|||
// Calling another filter, we skip
|
||||
return filter
|
||||
}
|
||||
if(filter === undefined){
|
||||
if (filter === undefined) {
|
||||
context.err("Trying to validate a filter, but this filter is undefined")
|
||||
return undefined
|
||||
}
|
||||
|
@ -1990,7 +1990,7 @@ export class ValidateThemeEnsemble extends Conversion<
|
|||
>()
|
||||
|
||||
for (const theme of json) {
|
||||
if(theme.id === "personal"){
|
||||
if (theme.id === "personal") {
|
||||
continue
|
||||
}
|
||||
for (const layer of theme.layers) {
|
||||
|
|
|
@ -25,11 +25,13 @@ export default class FilterConfig {
|
|||
public readonly defaultSelection?: number
|
||||
|
||||
constructor(json: FilterConfigJson, context: string) {
|
||||
if(typeof json === "string"){
|
||||
throw "Got a non-expanded filter, just a string: "+json
|
||||
if (typeof json === "string") {
|
||||
throw "Got a non-expanded filter, just a string: " + json
|
||||
}
|
||||
if (json.options === undefined) {
|
||||
throw `A filter without options was given at ${context}. The ID is ${JSON.stringify(json)}`
|
||||
throw `A filter without options was given at ${context}. The ID is ${JSON.stringify(
|
||||
json
|
||||
)}`
|
||||
}
|
||||
if (json.id === undefined) {
|
||||
throw `A filter without id was found at ${context}`
|
||||
|
@ -209,16 +211,16 @@ export default class FilterConfig {
|
|||
Utils.NoNull(["id", "question", "osmTags", hasField ? "fields" : undefined]),
|
||||
this.options.map((opt, i) => {
|
||||
const isDefault = this.options.length > 1 && (this.defaultSelection ?? 0) == i
|
||||
return <string[]> Utils.NoNull([
|
||||
this.id + "." + i,
|
||||
isDefault
|
||||
? `*${opt.question.txt}* (default)`
|
||||
: opt.question,
|
||||
opt.osmTags?.asHumanString() ?? "",
|
||||
opt.fields?.length > 0
|
||||
? (opt.fields.map((f) => f.name + " (" + f.type + ")")).join(" ")
|
||||
: undefined,
|
||||
])
|
||||
return <string[]>(
|
||||
Utils.NoNull([
|
||||
this.id + "." + i,
|
||||
isDefault ? `*${opt.question.txt}* (default)` : opt.question,
|
||||
opt.osmTags?.asHumanString() ?? "",
|
||||
opt.fields?.length > 0
|
||||
? opt.fields.map((f) => f.name + " (" + f.type + ")").join(" ")
|
||||
: undefined,
|
||||
])
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
overpassScript: json.source["overpassScript"],
|
||||
isOsmCache: json.source["isOsmCache"],
|
||||
mercatorCrs: json.source["mercatorCrs"],
|
||||
idKey: json.source["idKey"]
|
||||
idKey: json.source["idKey"],
|
||||
},
|
||||
json.id
|
||||
)
|
||||
|
@ -162,7 +162,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
let preciseInput: PreciseInput = {
|
||||
preferredBackground: ["photo"],
|
||||
snapToLayers: undefined,
|
||||
maxSnapDistance: undefined
|
||||
maxSnapDistance: undefined,
|
||||
}
|
||||
if (pr["preciseInput"] !== undefined) {
|
||||
throw (
|
||||
|
@ -175,7 +175,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
let snapToLayers = pr.snapToLayer
|
||||
preciseInput = {
|
||||
snapToLayers,
|
||||
maxSnapDistance: pr.maxSnapDistance ?? 10
|
||||
maxSnapDistance: pr.maxSnapDistance ?? 10,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +187,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
`${translationContext}.presets.${i}.description`
|
||||
),
|
||||
preciseInput: preciseInput,
|
||||
exampleImages: pr.exampleImages
|
||||
exampleImages: pr.exampleImages,
|
||||
}
|
||||
return config
|
||||
})
|
||||
|
@ -293,10 +293,10 @@ export default class LayerConfig extends WithContextLoader {
|
|||
this.filters = []
|
||||
} else {
|
||||
this.filters = (<FilterConfigJson[]>json.filter ?? [])
|
||||
.filter(f => typeof f !== "string")
|
||||
.filter((f) => typeof f !== "string")
|
||||
.map((option, i) => {
|
||||
return new FilterConfig(option, `layers:${this.id}.filter.${i}`)
|
||||
})
|
||||
return new FilterConfig(option, `layers:${this.id}.filter.${i}`)
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -311,7 +311,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
}
|
||||
|
||||
this.titleIcons = this.ParseTagRenderings(<TagRenderingConfigJson[]>json.titleIcons ?? [], {
|
||||
readOnlyMode: true
|
||||
readOnlyMode: true,
|
||||
})
|
||||
|
||||
this.title = this.tr("title", undefined, translationContext)
|
||||
|
@ -412,7 +412,7 @@ export default class LayerConfig extends WithContextLoader {
|
|||
[
|
||||
"<img src='../warning.svg' height='1rem'/>",
|
||||
"This layer is loaded from an external source, namely ",
|
||||
"`" + this.source.geojsonSource + "`"
|
||||
"`" + this.source.geojsonSource + "`",
|
||||
].join("\n\n")
|
||||
)
|
||||
}
|
||||
|
@ -428,10 +428,8 @@ export default class LayerConfig extends WithContextLoader {
|
|||
usingLayer = [
|
||||
"## Themes using this layer",
|
||||
MarkdownUtils.list(
|
||||
(usedInThemes ?? []).map(
|
||||
(id) => (`[${id}](https://mapcomplete.org/${id})`)
|
||||
)
|
||||
)
|
||||
(usedInThemes ?? []).map((id) => `[${id}](https://mapcomplete.org/${id})`)
|
||||
),
|
||||
]
|
||||
} else if (this.source !== null) {
|
||||
usingLayer = ["No themes use this layer"]
|
||||
|
@ -442,45 +440,46 @@ export default class LayerConfig extends WithContextLoader {
|
|||
extraProps.push(
|
||||
[
|
||||
"This layer will automatically load ",
|
||||
(`[${dep.neededLayer}](./${dep.neededLayer}.md)`),
|
||||
`[${dep.neededLayer}](./${dep.neededLayer}.md)`,
|
||||
" into the layout as it depends on it: ",
|
||||
dep.reason,
|
||||
"(" + dep.context + ")"
|
||||
"(" + dep.context + ")",
|
||||
].join(" ")
|
||||
)
|
||||
}
|
||||
|
||||
for (const revDep of Utils.Dedup(layerIsNeededBy?.get(this.id) ?? [])) {
|
||||
extraProps.push(
|
||||
[
|
||||
"This layer is needed as dependency for layer",
|
||||
(`[${revDep}](#${revDep})`)
|
||||
].join(" ")
|
||||
["This layer is needed as dependency for layer", `[${revDep}](#${revDep})`].join(
|
||||
" "
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
const tableRows: string[][] = Utils.NoNull(
|
||||
this.tagRenderings
|
||||
.map((tr) => tr.FreeformValues())
|
||||
.filter(values => values !== undefined)
|
||||
.filter(values => values.key !== "id")
|
||||
.filter((values) => values !== undefined)
|
||||
.filter((values) => values.key !== "id")
|
||||
.map((values) => {
|
||||
const embedded: (string)[] = values.values?.map((v) =>
|
||||
const embedded: string[] = values.values?.map((v) =>
|
||||
Link.OsmWiki(values.key, v, true).SetClass("mr-2").AsMarkdown()
|
||||
) ?? ["_no preset options defined, or no values in them_"]
|
||||
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(values.key)}/`
|
||||
const statistics = `https://taghistory.raifer.tech/?#***/${encodeURIComponent(
|
||||
values.key
|
||||
)}/`
|
||||
const tagInfo = `https://taginfo.openstreetmap.org/keys/${values.key}#values`
|
||||
return [
|
||||
[
|
||||
`<a target="_blank" href='${tagInfo}'><img src='https://mapcomplete.org/assets/svg/search.svg' height='18px'></a>`,
|
||||
`<a target="_blank" href='${statistics}'><img src='https://mapcomplete.org/assets/svg/statistics.svg' height='18px'></a>`,
|
||||
|
||||
Link.OsmWiki(values.key).AsMarkdown()
|
||||
Link.OsmWiki(values.key).AsMarkdown(),
|
||||
].join(" "),
|
||||
values.type === undefined
|
||||
? "Multiple choice"
|
||||
: `[${values.type}](../SpecialInputElements.md#${values.type})`,
|
||||
embedded.join(" ")
|
||||
embedded.join(" "),
|
||||
]
|
||||
})
|
||||
)
|
||||
|
@ -488,31 +487,30 @@ export default class LayerConfig extends WithContextLoader {
|
|||
let quickOverview: string[] = []
|
||||
if (tableRows.length > 0) {
|
||||
quickOverview = [
|
||||
("**Warning:**"),
|
||||
"**Warning:**",
|
||||
"this quick overview is incomplete",
|
||||
MarkdownUtils.table(
|
||||
["attribute", "type", "values which are supported by this layer"],
|
||||
tableRows
|
||||
)
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
let overpassLink: string = undefined
|
||||
if (this.source !== undefined) {
|
||||
try {
|
||||
overpassLink = (
|
||||
overpassLink =
|
||||
"[Execute on overpass](" +
|
||||
Overpass.AsOverpassTurboLink(<TagsFilter>this.source.osmTags.optimize())
|
||||
.replaceAll("(", "%28")
|
||||
.replaceAll(")", "%29")
|
||||
+ ")"
|
||||
)
|
||||
.replaceAll(")", "%29") +
|
||||
")"
|
||||
} catch (e) {
|
||||
console.error("Could not generate overpasslink for " + this.id)
|
||||
}
|
||||
}
|
||||
|
||||
const filterDocs: (string)[] = []
|
||||
const filterDocs: string[] = []
|
||||
if (this.filters.length > 0) {
|
||||
filterDocs.push("## Filters")
|
||||
filterDocs.push(...this.filters.map((filter) => filter.GenerateDocs()))
|
||||
|
@ -538,8 +536,8 @@ export default class LayerConfig extends WithContextLoader {
|
|||
} else {
|
||||
tagsDescription.push(
|
||||
"Elements must match the expression **" +
|
||||
neededTags.asHumanString(true, false, {}) +
|
||||
"**"
|
||||
neededTags.asHumanString(true, false, {}) +
|
||||
"**"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -551,17 +549,21 @@ export default class LayerConfig extends WithContextLoader {
|
|||
return [
|
||||
[
|
||||
"# " + this.id + "\n",
|
||||
this._basedOn ? `This layer is based on [${this._basedOn}](../Layers/${this._basedOn}.md)` : "",
|
||||
this.description, "\n"].join("\n\n"),
|
||||
this._basedOn
|
||||
? `This layer is based on [${this._basedOn}](../Layers/${this._basedOn}.md)`
|
||||
: "",
|
||||
this.description,
|
||||
"\n",
|
||||
].join("\n\n"),
|
||||
MarkdownUtils.list(extraProps),
|
||||
...usingLayer,
|
||||
...tagsDescription,
|
||||
"## Supported attributes",
|
||||
quickOverview,
|
||||
...this.tagRenderings
|
||||
.filter(tr => tr.labels.indexOf("ignore_docs") < 0)
|
||||
.filter((tr) => tr.labels.indexOf("ignore_docs") < 0)
|
||||
.map((tr) => tr.GenerateDocumentation()),
|
||||
...filterDocs
|
||||
...filterDocs,
|
||||
].join("\n\n")
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Tag } from "../../Logic/Tags/Tag"
|
|||
import Link from "../../UI/Base/Link"
|
||||
import {
|
||||
MappingConfigJson,
|
||||
QuestionableTagRenderingConfigJson
|
||||
QuestionableTagRenderingConfigJson,
|
||||
} from "./Json/QuestionableTagRenderingConfigJson"
|
||||
import Validators, { ValidatorType } from "../../UI/InputElement/Validators"
|
||||
import { TagRenderingConfigJson } from "./Json/TagRenderingConfigJson"
|
||||
|
@ -204,7 +204,7 @@ export default class TagRenderingConfig {
|
|||
inline: json.freeform.inline ?? false,
|
||||
default: json.freeform.default,
|
||||
postfixDistinguished: json.freeform.postfixDistinguished?.trim(),
|
||||
args: json.freeform.helperArgs
|
||||
args: json.freeform.helperArgs,
|
||||
}
|
||||
if (json.freeform["extraTags"] !== undefined) {
|
||||
throw `Freeform.extraTags is defined. This should probably be 'freeform.addExtraTag' (at ${context})`
|
||||
|
@ -416,7 +416,7 @@ export default class TagRenderingConfig {
|
|||
iconClass,
|
||||
addExtraTags,
|
||||
searchTerms: mapping.searchTerms,
|
||||
priorityIf: prioritySearch
|
||||
priorityIf: prioritySearch,
|
||||
}
|
||||
if (isQuestionable) {
|
||||
if (hideInAnswer !== true && mp.if !== undefined && !mp.if.isUsableAsAnswer()) {
|
||||
|
@ -517,7 +517,7 @@ export default class TagRenderingConfig {
|
|||
then: new TypedTranslation<object>(
|
||||
this.render.replace("{" + this.freeform.key + "}", leftover).translations,
|
||||
this.render.context
|
||||
)
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -567,7 +567,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
then: this.render.PartialSubs({ [this.freeform.key]: v.trim() }),
|
||||
icon: this.renderIcon,
|
||||
iconClass: this.renderIconClass
|
||||
iconClass: this.renderIconClass,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -622,7 +622,7 @@ export default class TagRenderingConfig {
|
|||
key: commonKey,
|
||||
values: Utils.NoNull(
|
||||
values.map((arr) => arr.filter((item) => item.k === commonKey)[0]?.v)
|
||||
)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,7 +637,7 @@ export default class TagRenderingConfig {
|
|||
return {
|
||||
key,
|
||||
type: this.freeform.type,
|
||||
values
|
||||
values,
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Could not create FreeformValues for tagrendering", this.id)
|
||||
|
@ -743,7 +743,7 @@ export default class TagRenderingConfig {
|
|||
// Either no mappings, or this is a radio-button selected freeform value
|
||||
const tag = new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
const newProperties = tag.applyOn(currentProperties)
|
||||
if (this.invalidValues?.matchesProperties(newProperties)) {
|
||||
|
@ -767,7 +767,7 @@ export default class TagRenderingConfig {
|
|||
selectedMappings.push(
|
||||
new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
)
|
||||
}
|
||||
|
@ -795,12 +795,12 @@ export default class TagRenderingConfig {
|
|||
if (useFreeform) {
|
||||
return new And([
|
||||
new Tag(this.freeform.key, freeformValue),
|
||||
...(this.freeform.addExtraTags ?? [])
|
||||
...(this.freeform.addExtraTags ?? []),
|
||||
])
|
||||
} else if (singleSelectedMapping !== undefined) {
|
||||
return new And([
|
||||
this.mappings[singleSelectedMapping].if,
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? [])
|
||||
...(this.mappings[singleSelectedMapping].addExtraTags ?? []),
|
||||
])
|
||||
} else {
|
||||
console.error("TagRenderingConfig.ConstructSpecification has a weird fallback for", {
|
||||
|
@ -808,7 +808,7 @@ export default class TagRenderingConfig {
|
|||
singleSelectedMapping,
|
||||
multiSelectedMapping,
|
||||
currentProperties,
|
||||
useFreeform
|
||||
useFreeform,
|
||||
})
|
||||
|
||||
return undefined
|
||||
|
@ -838,11 +838,11 @@ export default class TagRenderingConfig {
|
|||
}
|
||||
const msgs: string[] = [
|
||||
icon +
|
||||
" " +
|
||||
"*" +
|
||||
m.then.textFor(lang) +
|
||||
"* is shown if with " +
|
||||
m.if.asHumanString(true, false, {})
|
||||
" " +
|
||||
"*" +
|
||||
m.then.textFor(lang) +
|
||||
"* is shown if with " +
|
||||
m.if.asHumanString(true, false, {}),
|
||||
]
|
||||
|
||||
if (m.hideInAnswer === true) {
|
||||
|
@ -851,7 +851,7 @@ export default class TagRenderingConfig {
|
|||
if (m.ifnot !== undefined) {
|
||||
msgs.push(
|
||||
"Unselecting this answer will add " +
|
||||
m.ifnot.asHumanString(true, false, {})
|
||||
m.ifnot.asHumanString(true, false, {})
|
||||
)
|
||||
}
|
||||
return msgs.join(". ")
|
||||
|
@ -875,7 +875,7 @@ export default class TagRenderingConfig {
|
|||
if (this.labels?.length > 0) {
|
||||
labels = [
|
||||
"This tagrendering has labels ",
|
||||
...this.labels.map((label) => "`" + label + "`")
|
||||
...this.labels.map((label) => "`" + label + "`"),
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
|
@ -888,15 +888,13 @@ export default class TagRenderingConfig {
|
|||
freeform,
|
||||
mappings,
|
||||
condition,
|
||||
labels
|
||||
labels,
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
public
|
||||
|
||||
usedTags()
|
||||
:
|
||||
TagsFilter[] {
|
||||
usedTags(): TagsFilter[] {
|
||||
const tags: TagsFilter[] = []
|
||||
tags.push(
|
||||
this.metacondition,
|
||||
|
@ -924,9 +922,7 @@ export default class TagRenderingConfig {
|
|||
*/
|
||||
public
|
||||
|
||||
settableKeys()
|
||||
:
|
||||
string[] | undefined {
|
||||
settableKeys(): string[] | undefined {
|
||||
const toDelete = new Set<string>()
|
||||
if (this.freeform) {
|
||||
toDelete.add(this.freeform.key)
|
||||
|
@ -975,7 +971,7 @@ export class TagRenderingConfigUtils {
|
|||
const oldMappingsCloned =
|
||||
clone.mappings?.map((m) => ({
|
||||
...m,
|
||||
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*")
|
||||
priorityIf: m.priorityIf ?? TagUtils.Tag("id~*"),
|
||||
})) ?? []
|
||||
clone.mappings = [...oldMappingsCloned, ...extraMappings]
|
||||
return clone
|
||||
|
|
|
@ -161,7 +161,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.featureSwitches = new FeatureSwitchState(layout)
|
||||
this.guistate = new MenuState(
|
||||
this.featureSwitches.featureSwitchWelcomeMessage.data,
|
||||
layout.id,
|
||||
layout.id
|
||||
)
|
||||
this.map = new UIEventSource<MlMap>(undefined)
|
||||
const geolocationState = new GeoLocationState()
|
||||
|
@ -177,14 +177,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
oauth_token: QueryParameters.GetQueryParameter(
|
||||
"oauth_token",
|
||||
undefined,
|
||||
"Used to complete the login",
|
||||
"Used to complete the login"
|
||||
),
|
||||
})
|
||||
this.userRelatedState = new UserRelatedState(
|
||||
this.osmConnection,
|
||||
layout,
|
||||
this.featureSwitches,
|
||||
this.mapProperties,
|
||||
this.mapProperties
|
||||
)
|
||||
this.userRelatedState.fixateNorth.addCallbackAndRunD((fixated) => {
|
||||
this.mapProperties.allowRotating.setData(fixated !== "yes")
|
||||
|
@ -195,13 +195,13 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
geolocationState,
|
||||
this.selectedElement,
|
||||
this.mapProperties,
|
||||
this.userRelatedState.gpsLocationHistoryRetentionTime,
|
||||
this.userRelatedState.gpsLocationHistoryRetentionTime
|
||||
)
|
||||
this.geolocationControl = new GeolocationControlState(this.geolocation, this.mapProperties)
|
||||
|
||||
this.availableLayers = AvailableRasterLayers.layersAvailableAt(
|
||||
this.mapProperties.location,
|
||||
this.osmConnection.isLoggedIn,
|
||||
this.osmConnection.isLoggedIn
|
||||
)
|
||||
|
||||
const self = this
|
||||
|
@ -209,7 +209,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.osmConnection,
|
||||
layout.layers,
|
||||
layout.id,
|
||||
this.featureSwitches.featureSwitchLayerDefault,
|
||||
this.featureSwitches.featureSwitchLayerDefault
|
||||
)
|
||||
|
||||
{
|
||||
|
@ -218,7 +218,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
const isDisplayed = QueryParameters.GetBooleanQueryParameter(
|
||||
"overlay-" + rasterInfo.id,
|
||||
rasterInfo.defaultState ?? true,
|
||||
"Whether or not overlay layer " + rasterInfo.id + " is shown",
|
||||
"Whether or not overlay layer " + rasterInfo.id + " is shown"
|
||||
)
|
||||
const state = { isDisplayed }
|
||||
overlayLayerStates.set(rasterInfo.id, state)
|
||||
|
@ -243,7 +243,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.osmConnection.Backend(),
|
||||
(id) => self.layerState.filteredLayers.get(id).isDisplayed,
|
||||
mvtAvailableLayers,
|
||||
this.fullNodeDatabase,
|
||||
this.fullNodeDatabase
|
||||
)
|
||||
|
||||
let currentViewIndex = 0
|
||||
|
@ -261,7 +261,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
id: "current_view_" + currentViewIndex,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
})
|
||||
)
|
||||
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
|
||||
|
||||
|
@ -279,19 +279,19 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
featureSwitches: this.featureSwitches,
|
||||
},
|
||||
layout?.isLeftRightSensitive() ?? false,
|
||||
(e) => this.reportError(e),
|
||||
(e) => this.reportError(e)
|
||||
)
|
||||
this.historicalUserLocations = this.geolocation.historicalUserLocations
|
||||
this.newFeatures = new NewGeometryFromChangesFeatureSource(
|
||||
this.changes,
|
||||
layoutSource,
|
||||
this.featureProperties,
|
||||
this.featureProperties
|
||||
)
|
||||
layoutSource.addSource(this.newFeatures)
|
||||
|
||||
const perLayer = new PerLayerFeatureSourceSplitter(
|
||||
Array.from(this.layerState.filteredLayers.values()).filter(
|
||||
(l) => l.layerDef?.source !== null,
|
||||
(l) => l.layerDef?.source !== null
|
||||
),
|
||||
new ChangeGeometryApplicator(this.indexedFeatures, this.changes),
|
||||
{
|
||||
|
@ -302,10 +302,10 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
"Got ",
|
||||
features.length,
|
||||
"leftover features, such as",
|
||||
features[0].properties,
|
||||
features[0].properties
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
this.perLayer = perLayer.perLayer
|
||||
}
|
||||
|
@ -345,12 +345,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.lastClickObject = new LastClickFeatureSource(
|
||||
this.layout,
|
||||
this.mapProperties.lastClickLocation,
|
||||
this.userRelatedState.addNewFeatureMode,
|
||||
this.userRelatedState.addNewFeatureMode
|
||||
)
|
||||
|
||||
this.osmObjectDownloader = new OsmObjectDownloader(
|
||||
this.osmConnection.Backend(),
|
||||
this.changes,
|
||||
this.changes
|
||||
)
|
||||
|
||||
this.perLayerFiltered = this.showNormalDataOn(this.map)
|
||||
|
@ -361,7 +361,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
currentZoom: this.mapProperties.zoom,
|
||||
layerState: this.layerState,
|
||||
bounds: this.visualFeedbackViewportBounds,
|
||||
},
|
||||
}
|
||||
)
|
||||
this.hasDataInView = new NoElementsInViewDetector(this).hasFeatureInView
|
||||
this.imageUploadManager = new ImageUploadManager(
|
||||
|
@ -369,15 +369,15 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
Imgur.singleton,
|
||||
this.featureProperties,
|
||||
this.osmConnection,
|
||||
this.changes,
|
||||
this.changes
|
||||
)
|
||||
this.favourites = new FavouritesFeatureSource(this)
|
||||
const longAgo = new Date()
|
||||
longAgo.setTime(new Date().getTime() - 5 * 365 * 24 * 60 * 60 * 1000 )
|
||||
longAgo.setTime(new Date().getTime() - 5 * 365 * 24 * 60 * 60 * 1000)
|
||||
this.nearbyImageSearcher = new CombinedFetcher(50, longAgo, this.indexedFeatures)
|
||||
|
||||
this.featureSummary = this.setupSummaryLayer(
|
||||
new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer", true),
|
||||
new LayerConfig(<LayerConfigJson>summaryLayer, "summaryLayer", true)
|
||||
)
|
||||
this.toCacheSavers = this.initSaveToLocalStorage()
|
||||
this.initActors()
|
||||
|
@ -417,7 +417,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
LayoutSource.fromCacheZoomLevel,
|
||||
fs,
|
||||
this.featureProperties,
|
||||
fs.layer.layerDef.maxAgeOfCache,
|
||||
fs.layer.layerDef.maxAgeOfCache
|
||||
)
|
||||
toLocalStorage.set(layerId, storage)
|
||||
})
|
||||
|
@ -430,7 +430,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
const doShowLayer = this.mapProperties.zoom.map(
|
||||
(z) =>
|
||||
(fs.layer.isDisplayed?.data ?? true) && z >= (fs.layer.layerDef?.minzoom ?? 0),
|
||||
[fs.layer.isDisplayed],
|
||||
[fs.layer.isDisplayed]
|
||||
)
|
||||
|
||||
if (!doShowLayer.data && this.featureSwitches.featureSwitchFilter.data === false) {
|
||||
|
@ -447,7 +447,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
fs.layer,
|
||||
fs,
|
||||
(id) => this.featureProperties.getStore(id),
|
||||
this.layerState.globalFilters,
|
||||
this.layerState.globalFilters
|
||||
)
|
||||
filteringFeatureSource.set(layerName, filtered)
|
||||
|
||||
|
@ -591,7 +591,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
return
|
||||
}
|
||||
this.selectClosestAtCenter(0)
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
for (let i = 1; i < 9; i++) {
|
||||
|
@ -609,7 +609,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
onUp: true,
|
||||
},
|
||||
doc,
|
||||
() => this.selectClosestAtCenter(i - 1),
|
||||
() => this.selectClosestAtCenter(i - 1)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -626,7 +626,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
if (this.featureSwitches.featureSwitchBackgroundSelection.data) {
|
||||
this.guistate.backgroundLayerSelectionIsOpened.setData(true)
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
Hotkeys.RegisterHotkey(
|
||||
{
|
||||
|
@ -638,14 +638,14 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
if (this.featureSwitches.featureSwitchFilter.data) {
|
||||
this.guistate.openFilterView()
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
Hotkeys.RegisterHotkey(
|
||||
{ shift: "O" },
|
||||
Translations.t.hotkeyDocumentation.selectMapnik,
|
||||
() => {
|
||||
this.mapProperties.rasterLayer.setData(AvailableRasterLayers.osmCarto)
|
||||
},
|
||||
}
|
||||
)
|
||||
const setLayerCategory = (category: EliCategory) => {
|
||||
const available = this.availableLayers.data
|
||||
|
@ -653,7 +653,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
const best = RasterLayerUtils.SelectBestLayerAccordingTo(
|
||||
available,
|
||||
category,
|
||||
current.data,
|
||||
current.data
|
||||
)
|
||||
console.log("Best layer for category", category, "is", best.properties.id)
|
||||
current.setData(best)
|
||||
|
@ -662,26 +662,26 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
Hotkeys.RegisterHotkey(
|
||||
{ nomod: "O" },
|
||||
Translations.t.hotkeyDocumentation.selectOsmbasedmap,
|
||||
() => setLayerCategory("osmbasedmap"),
|
||||
() => setLayerCategory("osmbasedmap")
|
||||
)
|
||||
|
||||
Hotkeys.RegisterHotkey(
|
||||
{ nomod: "M" },
|
||||
Translations.t.hotkeyDocumentation.selectMap,
|
||||
() => setLayerCategory("map"),
|
||||
() => setLayerCategory("map")
|
||||
)
|
||||
|
||||
Hotkeys.RegisterHotkey(
|
||||
{ nomod: "P" },
|
||||
Translations.t.hotkeyDocumentation.selectAerial,
|
||||
() => setLayerCategory("photo"),
|
||||
() => setLayerCategory("photo")
|
||||
)
|
||||
Hotkeys.RegisterHotkey(
|
||||
{ nomod: "L" },
|
||||
Translations.t.hotkeyDocumentation.geolocate,
|
||||
() => {
|
||||
this.geolocationControl.handleClick()
|
||||
},
|
||||
}
|
||||
)
|
||||
return true
|
||||
})
|
||||
|
@ -693,7 +693,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
Translations.t.hotkeyDocumentation.translationMode,
|
||||
() => {
|
||||
Locale.showLinkToWeblate.setData(!Locale.showLinkToWeblate.data)
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -704,7 +704,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
const normalLayers = this.layout.layers.filter(
|
||||
(l) =>
|
||||
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
|
||||
!l.id.startsWith("note_import"),
|
||||
!l.id.startsWith("note_import")
|
||||
)
|
||||
const maxzoom = Math.min(...normalLayers.map((l) => l.minzoom))
|
||||
|
||||
|
@ -712,7 +712,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
(l) =>
|
||||
Constants.priviliged_layers.indexOf(<any>l.id) < 0 &&
|
||||
l.source.geojsonSource === undefined &&
|
||||
l.doCount,
|
||||
l.doCount
|
||||
)
|
||||
const summaryTileSource = new SummaryTileSource(
|
||||
Constants.SummaryServer,
|
||||
|
@ -721,7 +721,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.mapProperties,
|
||||
{
|
||||
isActive: this.mapProperties.zoom.map((z) => z < maxzoom),
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
const src = new SummaryTileSourceRewriter(summaryTileSource, this.layerState.filteredLayers)
|
||||
|
@ -743,12 +743,12 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
gps_location_history: this.geolocation.historicalUserLocations,
|
||||
gps_track: this.geolocation.historicalUserLocationsTrack,
|
||||
selected_element: new StaticFeatureSource(
|
||||
this.selectedElement.map((f) => (f === undefined ? empty : [f])),
|
||||
this.selectedElement.map((f) => (f === undefined ? empty : [f]))
|
||||
),
|
||||
range: new StaticFeatureSource(
|
||||
this.mapProperties.maxbounds.map((bbox) =>
|
||||
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })],
|
||||
),
|
||||
bbox === undefined ? empty : <Feature[]>[bbox.asGeoJson({ id: "range" })]
|
||||
)
|
||||
),
|
||||
current_view: this.currentView,
|
||||
favourite: this.favourites,
|
||||
|
@ -763,7 +763,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
ShowDataLayer.showRange(
|
||||
this.map,
|
||||
new StaticFeatureSource([bbox.asGeoJson({ id: "range" })]),
|
||||
this.featureSwitches.featureSwitchIsTesting,
|
||||
this.featureSwitches.featureSwitchIsTesting
|
||||
)
|
||||
}
|
||||
const currentViewLayer = this.layout.layers.find((l) => l.id === "current_view")
|
||||
|
@ -777,7 +777,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
currentViewLayer,
|
||||
this.layout,
|
||||
this.osmObjectDownloader,
|
||||
this.featureProperties,
|
||||
this.featureProperties
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -821,20 +821,20 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
|
||||
const lastClickLayerConfig = new LayerConfig(
|
||||
<LayerConfigJson>last_click_layerconfig,
|
||||
"last_click",
|
||||
"last_click"
|
||||
)
|
||||
const lastClickFiltered =
|
||||
lastClickLayerConfig.isShown === undefined
|
||||
? specialLayers.last_click
|
||||
: specialLayers.last_click.features.mapD((fs) =>
|
||||
fs.filter((f) => {
|
||||
const matches = lastClickLayerConfig.isShown.matchesProperties(
|
||||
f.properties,
|
||||
)
|
||||
console.debug("LastClick ", f, "matches", matches)
|
||||
return matches
|
||||
}),
|
||||
)
|
||||
fs.filter((f) => {
|
||||
const matches = lastClickLayerConfig.isShown.matchesProperties(
|
||||
f.properties
|
||||
)
|
||||
console.debug("LastClick ", f, "matches", matches)
|
||||
return matches
|
||||
})
|
||||
)
|
||||
new ShowDataLayer(this.map, {
|
||||
features: new StaticFeatureSource(lastClickFiltered),
|
||||
layer: lastClickLayerConfig,
|
||||
|
@ -859,7 +859,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.selectedElement.addCallback((selected) => {
|
||||
if (selected === undefined) {
|
||||
this.focusOnMap()
|
||||
}else{
|
||||
} else {
|
||||
this.lastClickObject.clear()
|
||||
}
|
||||
})
|
||||
|
@ -881,7 +881,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.mapProperties.rasterLayer,
|
||||
this.availableLayers,
|
||||
this.featureSwitches.backgroundLayerId,
|
||||
this.userRelatedState.preferredBackgroundLayer,
|
||||
this.userRelatedState.preferredBackgroundLayer
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -892,7 +892,13 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
|
||||
public async reportError(message: string | Error | XMLHttpRequest) {
|
||||
const isTesting = this.featureSwitchIsTesting.data
|
||||
console.log(isTesting ? ">>> _Not_ reporting error to report server as testmode is on" : ">>> Reporting error to", Constants.ErrorReportServer, message)
|
||||
console.log(
|
||||
isTesting
|
||||
? ">>> _Not_ reporting error to report server as testmode is on"
|
||||
: ">>> Reporting error to",
|
||||
Constants.ErrorReportServer,
|
||||
message
|
||||
)
|
||||
if (isTesting) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -38,12 +38,12 @@
|
|||
<slot name="close-button">
|
||||
<!-- The close button is placed _after_ the default slot in order to always paint it on top -->
|
||||
<div
|
||||
class="absolute right-10 top-10 cursor-pointer border-none p-0 m-0 bg-white rounded-full border-0"
|
||||
class="absolute right-10 top-10 m-0 cursor-pointer rounded-full border-0 border-none bg-white p-0"
|
||||
style="margin: -0.25rem"
|
||||
on:click={() => dispatch("close")}
|
||||
use:ariaLabel={Translations.t.general.backToMap}
|
||||
>
|
||||
<XCircleIcon class="w-8 h-8" />
|
||||
<XCircleIcon class="h-8 w-8" />
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
|
|
|
@ -30,18 +30,18 @@ export default class Hotkeys {
|
|||
public static RegisterHotkey(
|
||||
key: (
|
||||
| {
|
||||
ctrl: string
|
||||
}
|
||||
ctrl: string
|
||||
}
|
||||
| {
|
||||
shift: string
|
||||
}
|
||||
shift: string
|
||||
}
|
||||
| {
|
||||
alt: string
|
||||
}
|
||||
alt: string
|
||||
}
|
||||
| {
|
||||
nomod: string
|
||||
}
|
||||
) & {
|
||||
nomod: string
|
||||
}
|
||||
) & {
|
||||
onUp?: boolean
|
||||
},
|
||||
documentation: string | Translation,
|
||||
|
@ -63,7 +63,7 @@ export default class Hotkeys {
|
|||
return
|
||||
}
|
||||
if (key["ctrl"] !== undefined) {
|
||||
document.addEventListener("keydown", function(event) {
|
||||
document.addEventListener("keydown", function (event) {
|
||||
if (event.ctrlKey && event.key === keycode) {
|
||||
if (action() !== false) {
|
||||
event.preventDefault()
|
||||
|
@ -71,7 +71,7 @@ export default class Hotkeys {
|
|||
}
|
||||
})
|
||||
} else if (key["shift"] !== undefined) {
|
||||
document.addEventListener(type, function(event) {
|
||||
document.addEventListener(type, function (event) {
|
||||
if (Hotkeys.textElementSelected(event)) {
|
||||
// A text element is selected, we don't do anything special
|
||||
return
|
||||
|
@ -83,7 +83,7 @@ export default class Hotkeys {
|
|||
}
|
||||
})
|
||||
} else if (key["alt"] !== undefined) {
|
||||
document.addEventListener(type, function(event) {
|
||||
document.addEventListener(type, function (event) {
|
||||
if (event.altKey && event.key === keycode) {
|
||||
if (action() !== false) {
|
||||
event.preventDefault()
|
||||
|
@ -91,7 +91,7 @@ export default class Hotkeys {
|
|||
}
|
||||
})
|
||||
} else if (key["nomod"] !== undefined) {
|
||||
document.addEventListener(type, function(event) {
|
||||
document.addEventListener(type, function (event) {
|
||||
if (Hotkeys.textElementSelected(event) && keycode !== "Escape") {
|
||||
// A text element is selected, we don't do anything special
|
||||
return
|
||||
|
@ -106,18 +106,17 @@ export default class Hotkeys {
|
|||
}
|
||||
}
|
||||
|
||||
static prepareDocumentation(docs: {
|
||||
key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean }
|
||||
documentation: string | Translation
|
||||
alsoTriggeredBy: Translation[]
|
||||
}[]){
|
||||
static prepareDocumentation(
|
||||
docs: {
|
||||
key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean }
|
||||
documentation: string | Translation
|
||||
alsoTriggeredBy: Translation[]
|
||||
}[]
|
||||
) {
|
||||
let byKey: [string, string | Translation, Translation[] | undefined][] = docs
|
||||
.map(({ key, documentation, alsoTriggeredBy }) => {
|
||||
const modifiers = Object.keys(key).filter(
|
||||
(k) => k !== "nomod" && k !== "onUp"
|
||||
)
|
||||
let keycode: string =
|
||||
key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"]
|
||||
const modifiers = Object.keys(key).filter((k) => k !== "nomod" && k !== "onUp")
|
||||
let keycode: string = key["ctrl"] ?? key["shift"] ?? key["alt"] ?? key["nomod"]
|
||||
if (keycode.length == 1) {
|
||||
keycode = keycode.toUpperCase()
|
||||
}
|
||||
|
@ -128,7 +127,7 @@ export default class Hotkeys {
|
|||
return <[string, string | Translation, Translation[] | undefined]>[
|
||||
modifiers.join("+"),
|
||||
documentation,
|
||||
alsoTriggeredBy
|
||||
alsoTriggeredBy,
|
||||
]
|
||||
})
|
||||
.sort()
|
||||
|
@ -141,36 +140,41 @@ export default class Hotkeys {
|
|||
return byKey
|
||||
}
|
||||
|
||||
static generateDocumentationFor(docs: {
|
||||
key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean }
|
||||
documentation: string | Translation
|
||||
alsoTriggeredBy: Translation[]
|
||||
}[], language: string): string {
|
||||
|
||||
static generateDocumentationFor(
|
||||
docs: {
|
||||
key: { ctrl?: string; shift?: string; alt?: string; nomod?: string; onUp?: boolean }
|
||||
documentation: string | Translation
|
||||
alsoTriggeredBy: Translation[]
|
||||
}[],
|
||||
language: string
|
||||
): string {
|
||||
const tr = Translations.t.hotkeyDocumentation
|
||||
function t(t: Translation | string){
|
||||
if(typeof t === "string"){
|
||||
function t(t: Translation | string) {
|
||||
if (typeof t === "string") {
|
||||
return t
|
||||
}
|
||||
return t.textFor(language)
|
||||
}
|
||||
const contents: string[][] = this.prepareDocumentation(docs)
|
||||
.map(([key, doc, alsoTriggeredBy]) => {
|
||||
let keyEl: string = [key, ...(alsoTriggeredBy??[])].map(k => "`"+t(k)+"`").join(" ")
|
||||
return [keyEl, t(doc)]
|
||||
})
|
||||
const contents: string[][] = this.prepareDocumentation(docs).map(
|
||||
([key, doc, alsoTriggeredBy]) => {
|
||||
let keyEl: string = [key, ...(alsoTriggeredBy ?? [])]
|
||||
.map((k) => "`" + t(k) + "`")
|
||||
.join(" ")
|
||||
return [keyEl, t(doc)]
|
||||
}
|
||||
)
|
||||
return [
|
||||
"# "+t(tr.title),
|
||||
"# " + t(tr.title),
|
||||
t(tr.intro),
|
||||
MarkdownUtils.table(
|
||||
[t(tr.key), t(tr.action)],
|
||||
contents
|
||||
)
|
||||
].join("\n")
|
||||
MarkdownUtils.table([t(tr.key), t(tr.action)], contents),
|
||||
].join("\n")
|
||||
}
|
||||
|
||||
public static generateDocumentation(language?: string){
|
||||
return Hotkeys.generateDocumentationFor(Hotkeys._docs.data, language?? Locale.language.data)
|
||||
public static generateDocumentation(language?: string) {
|
||||
return Hotkeys.generateDocumentationFor(
|
||||
Hotkeys._docs.data,
|
||||
language ?? Locale.language.data
|
||||
)
|
||||
}
|
||||
|
||||
private static textElementSelected(event: KeyboardEvent): boolean {
|
||||
|
|
|
@ -2,7 +2,7 @@ import Combine from "./Combine"
|
|||
import Translations from "../i18n/Translations"
|
||||
import BaseUIElement from "../BaseUIElement"
|
||||
import SvelteUIElement from "./SvelteUIElement"
|
||||
import {default as LoadingSvg} from "../../assets/svg/Loading.svelte"
|
||||
import { default as LoadingSvg } from "../../assets/svg/Loading.svelte"
|
||||
export default class Loading extends Combine {
|
||||
constructor(msg?: BaseUIElement | string) {
|
||||
const t = Translations.W(msg) ?? Translations.t.general.loading
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class SvelteUIElement<
|
|||
|
||||
constructor(svelteElement, props?: Props, events?: Events, slots?: Slots) {
|
||||
super()
|
||||
this._svelteComponent = <any> svelteElement
|
||||
this._svelteComponent = <any>svelteElement
|
||||
this._props = props ?? <Props>{}
|
||||
this._events = events
|
||||
this._slots = slots
|
||||
|
@ -49,15 +49,15 @@ export default class SvelteUIElement<
|
|||
return el
|
||||
}
|
||||
|
||||
public getClass(){
|
||||
if(this.clss.size === 0){
|
||||
public getClass() {
|
||||
if (this.clss.size === 0) {
|
||||
return undefined
|
||||
}
|
||||
return this.clss
|
||||
}
|
||||
|
||||
public getStyle(){
|
||||
if(this.style === ""){
|
||||
public getStyle() {
|
||||
if (this.style === "") {
|
||||
return undefined
|
||||
}
|
||||
return this.style
|
||||
|
|
|
@ -98,7 +98,7 @@ export default class TableOfContents {
|
|||
const intro = md.substring(0, firstTitleIndex)
|
||||
const splitPoint = intro.lastIndexOf("\n")
|
||||
|
||||
return md.substring(0, splitPoint) +"\n" + toc + md.substring(splitPoint)
|
||||
return md.substring(0, splitPoint) + "\n" + toc + md.substring(splitPoint)
|
||||
}
|
||||
|
||||
public static generateStructure(
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
|
||||
import Translations from "../i18n/Translations"
|
||||
</script>
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
let elem: HTMLElement
|
||||
let html: HTMLElement
|
||||
let isSvelte = false
|
||||
let uiElement : BaseUIElement | SvelteUIElement | undefined
|
||||
let uiElement: BaseUIElement | SvelteUIElement | undefined
|
||||
let svelteElem: SvelteUIElement
|
||||
onMount(() => {
|
||||
uiElement = typeof construct === "function" ? construct() : construct
|
||||
|
||||
if (uiElement?.["isSvelte"]) {
|
||||
isSvelte = true
|
||||
svelteElem = <SvelteUIElement> uiElement
|
||||
svelteElem = <SvelteUIElement>uiElement
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,12 @@
|
|||
</script>
|
||||
|
||||
{#if isSvelte}
|
||||
<svelte:component this={svelteElem?._svelteComponent} {...svelteElem._props} class={svelteElem.getClass()} style={svelteElem.getStyle()}/>
|
||||
<svelte:component
|
||||
this={svelteElem?._svelteComponent}
|
||||
{...svelteElem._props}
|
||||
class={svelteElem.getClass()}
|
||||
style={svelteElem.getStyle()}
|
||||
/>
|
||||
{:else}
|
||||
<span bind:this={elem} />
|
||||
{/if}
|
||||
|
|
|
@ -53,31 +53,28 @@
|
|||
<Tr t={Translations.t.general.menu.filter} />
|
||||
</div>
|
||||
|
||||
{#each layout.layers as layer}
|
||||
<Filterview
|
||||
zoomlevel={state.mapProperties.zoom}
|
||||
filteredLayer={state.layerState.filteredLayers.get(layer.id)}
|
||||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||
/>
|
||||
{/each}
|
||||
<div class="mt-1 flex self-end">
|
||||
<button class="small" class:disabled={allEnabled} on:click={() => enableAll(true)}>
|
||||
<Tr t={Translations.t.general.filterPanel.enableAll} />
|
||||
</button>
|
||||
<button class="small" class:disabled={allDisabled} on:click={() => enableAll(false)}>
|
||||
<Tr t={Translations.t.general.filterPanel.disableAll} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#each layout.tileLayerSources as tilesource}
|
||||
<OverlayToggle
|
||||
layerproperties={tilesource}
|
||||
state={state.overlayLayerStates.get(tilesource.id)}
|
||||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||
zoomlevel={state.mapProperties.zoom}
|
||||
/>
|
||||
{/each}
|
||||
{#each layout.layers as layer}
|
||||
<Filterview
|
||||
zoomlevel={state.mapProperties.zoom}
|
||||
filteredLayer={state.layerState.filteredLayers.get(layer.id)}
|
||||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||
/>
|
||||
{/each}
|
||||
<div class="mt-1 flex self-end">
|
||||
<button class="small" class:disabled={allEnabled} on:click={() => enableAll(true)}>
|
||||
<Tr t={Translations.t.general.filterPanel.enableAll} />
|
||||
</button>
|
||||
<button class="small" class:disabled={allDisabled} on:click={() => enableAll(false)}>
|
||||
<Tr t={Translations.t.general.filterPanel.disableAll} />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{#each layout.tileLayerSources as tilesource}
|
||||
<OverlayToggle
|
||||
layerproperties={tilesource}
|
||||
state={state.overlayLayerStates.get(tilesource.id)}
|
||||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||
zoomlevel={state.mapProperties.zoom}
|
||||
/>
|
||||
{/each}
|
||||
</TitledPanel>
|
||||
|
||||
|
||||
|
|
|
@ -43,13 +43,10 @@
|
|||
{#if filteredLayer.layerDef.name}
|
||||
<div class:focus={$highlightedLayer === filteredLayer.layerDef.id} class="mb-1.5">
|
||||
<Checkbox selected={isDisplayed}>
|
||||
<div class="block h-6 w-6 no-image-background" class:opacity-50={!$isDisplayed}>
|
||||
<ToSvelte
|
||||
construct={() => layer.defaultIcon()}
|
||||
/>
|
||||
<div class="no-image-background block h-6 w-6" class:opacity-50={!$isDisplayed}>
|
||||
<ToSvelte construct={() => layer.defaultIcon()} />
|
||||
</div>
|
||||
|
||||
|
||||
<Tr t={filteredLayer.layerDef.name} />
|
||||
|
||||
{#if $zoomlevel < layer.minzoom}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script lang="ts">
|
||||
|
||||
import Hotkeys from "../Base/Hotkeys"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
import { Utils } from "../../Utils"
|
||||
|
@ -10,14 +9,13 @@
|
|||
let keys = Hotkeys._docs
|
||||
const t = Translations.t.hotkeyDocumentation
|
||||
|
||||
|
||||
let byKey = Hotkeys.prepareDocumentation($keys)
|
||||
$: {
|
||||
byKey = Hotkeys.prepareDocumentation($keys)
|
||||
}
|
||||
</script>
|
||||
<AccordionSingle>
|
||||
|
||||
<AccordionSingle>
|
||||
<div slot="header">
|
||||
<Tr t={t.title} />
|
||||
</div>
|
||||
|
@ -25,30 +23,27 @@
|
|||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
<Tr t={t.key}></Tr>
|
||||
</th>
|
||||
<th>
|
||||
<Tr t={t.action} />
|
||||
</th>
|
||||
<Tr t={t.key} />
|
||||
</th>
|
||||
<th>
|
||||
<Tr t={t.action} />
|
||||
</th>
|
||||
</tr>
|
||||
{#each byKey as [key, doc, alsoTriggeredBy] }
|
||||
{#each byKey as [key, doc, alsoTriggeredBy]}
|
||||
<tr>
|
||||
<td class="flex items-center justify-center">
|
||||
{#if alsoTriggeredBy}
|
||||
<div class="flex items-center justify-center gap-x-1">
|
||||
|
||||
<div class="literal-code w-fit h-fit">{key}</div>
|
||||
<div class="literal-code w-fit h-fit">{alsoTriggeredBy}</div>
|
||||
|
||||
<div class="literal-code h-fit w-fit">{key}</div>
|
||||
<div class="literal-code h-fit w-fit">{alsoTriggeredBy}</div>
|
||||
</div>
|
||||
|
||||
{:else}
|
||||
<div class="literal-code w-fit h-fit flex items-center w-full">{key}</div>
|
||||
<div class="literal-code flex h-fit w-fit w-full items-center">{key}</div>
|
||||
{/if}
|
||||
</td>
|
||||
<td>
|
||||
<Tr t={doc} />
|
||||
</td>
|
||||
<Tr t={doc} />
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</table>
|
||||
|
|
|
@ -9,22 +9,19 @@
|
|||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import { Translation } from "../i18n/Translation"
|
||||
|
||||
|
||||
const dispatch = createEventDispatcher<{search: string}>()
|
||||
const dispatch = createEventDispatcher<{ search: string }>()
|
||||
|
||||
export let searchValue: UIEventSource<string>
|
||||
export let placeholderText: Translation = Translations.t.general.search.search
|
||||
export let feedback = new UIEventSource<string>(undefined)
|
||||
|
||||
|
||||
let isRunning: boolean = false
|
||||
|
||||
let inputElement: HTMLInputElement
|
||||
|
||||
function _performSearch(){
|
||||
function _performSearch() {
|
||||
dispatch("search", searchValue.data)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="normal-background flex justify-between rounded-full">
|
||||
|
@ -32,21 +29,24 @@
|
|||
{#if isRunning}
|
||||
<Loading>{Translations.t.general.search.searching}</Loading>
|
||||
{:else}
|
||||
<div class="flex w-full border border-gray-300 rounded-full">
|
||||
|
||||
<input
|
||||
type="search"
|
||||
class="w-full outline-none mx-2"
|
||||
bind:this={inputElement}
|
||||
on:keypress={(keypr) => {
|
||||
feedback.set(undefined)
|
||||
return keypr.key === "Enter" ? _performSearch() : undefined
|
||||
}}
|
||||
bind:value={$searchValue}
|
||||
use:placeholder={placeholderText}
|
||||
use:ariaLabel={Translations.t.general.search.search}
|
||||
/>
|
||||
<SearchIcon aria-hidden="true" class="h-6 w-6 self-end" on:click={event => _performSearch()} />
|
||||
<div class="flex w-full rounded-full border border-gray-300">
|
||||
<input
|
||||
type="search"
|
||||
class="mx-2 w-full outline-none"
|
||||
bind:this={inputElement}
|
||||
on:keypress={(keypr) => {
|
||||
feedback.set(undefined)
|
||||
return keypr.key === "Enter" ? _performSearch() : undefined
|
||||
}}
|
||||
bind:value={$searchValue}
|
||||
use:placeholder={placeholderText}
|
||||
use:ariaLabel={Translations.t.general.search.search}
|
||||
/>
|
||||
<SearchIcon
|
||||
aria-hidden="true"
|
||||
class="h-6 w-6 self-end"
|
||||
on:click={(event) => _performSearch()}
|
||||
/>
|
||||
</div>
|
||||
{#if $feedback !== undefined}
|
||||
<!-- The feedback is _always_ shown for screenreaders and to make sure that the searchfield can still be selected by tabbing-->
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue