diff --git a/Docs/Making_Your_Own_Theme.md b/Docs/Making_Your_Own_Theme.md index 6483f49631..a16889da02 100644 --- a/Docs/Making_Your_Own_Theme.md +++ b/Docs/Making_Your_Own_Theme.md @@ -294,9 +294,9 @@ There are three important levels in the JSON file: Every field is documented in the source code itself - you can find them here: -- [The top level `LayoutConfig`](/Models/ThemeConfig/Json/LayoutConfigJson.ts) -- [A layer object `LayerConfig`](/Models/ThemeConfig/Json/LayerConfigJson.ts) -- [The `TagRendering`](/Models/ThemeConfig/Json/TagRenderingConfigJson.ts) +- [The top level `LayoutConfig`](/src/Models/ThemeConfig/Json/LayoutConfigJson.ts) +- [A layer object `LayerConfig`](/src/Models/ThemeConfig/Json/LayerConfigJson.ts) +- [The `TagRendering`](/src/Models/ThemeConfig/Json/TagRenderingConfigJson.ts) - At last, the exact semantics of tags are documented [here](Tags_format.md) A JSON schema file is available in `Docs/Schemas` - use `LayoutConfig.schema.json` to validate a theme file. diff --git a/assets/layers/aerialway/aerialway.json b/assets/layers/aerialway/aerialway.json index c956043b3f..bc2427975f 100644 --- a/assets/layers/aerialway/aerialway.json +++ b/assets/layers/aerialway/aerialway.json @@ -106,6 +106,34 @@ } ] }, + { + "id": "duration", + "question": { + "en": "How long takes a single journey with this elevator?" + }, + "questionHint": { + "en": "This excludes the waiting time." + }, + "freeform": { + "key": "duration" + }, + "render": { + "en": "A single journey takes {duration} minutes" + } + }, + { + "id": "occupancy", + "freeform": { + "key": "aerialway:occupancy" + }, + "question": { + "en": "How many people fit a single carriage?" + }, + "render": { + "en": "{aerialway:occupancy} people fit a single carriage" + } + }, + "opening_hours", { "id": "length", "render": { diff --git a/assets/layers/assembly_point/assembly_point.json b/assets/layers/assembly_point/assembly_point.json new file mode 100644 index 0000000000..9ed7fcaa7c --- /dev/null +++ b/assets/layers/assembly_point/assembly_point.json @@ -0,0 +1,145 @@ +{ + "allowMove": { + "enableRelocation": false, + "enableImproveAccuracy": true + }, + "name": { + "en": "Emergency assembly points", + "it": "Punti di raccolta per emergenze" + }, + "description": { + "en": "This layer contains assembly points and waiting areas where all employees, passengers or a large crowd assemble in case of an emergency.", + "it": "Questo livello contiene punti di raccolta e aree di attesa in cui tutti i dipendenti, i passeggeri o una grande folla si riuniscono in caso di emergenza." + }, + "docs": "https://wiki.openstreetmap.org/wiki/Tag:emergency%3Dassembly_point", + "id": "assembly_point", + "minzoom": 10, + "source": { + "osmTags": { + "and": [ + "emergency=assembly_point" + ] + } + }, + "pointRendering": [ + { + "iconSize": "20,20", + "location": [ + "point", + "centroid" + ], + "anchor": "bottom", + "marker": [ + { + "icon": "./assets/layers/assembly_point/assembly_point.svg" + } + ] + } + ], + "presets": [ + { + "title": { + "en": "an assembly point", + "it": "un punto di raccolta" + }, + "tags": [ + "emergency=assembly_point" + ] + } + ], + "title": { + "render": { + "en": "Assembly point during emergencies" + } + }, + "tagRenderings": [ + "images", + { + "id": "assembly_point_name", + "freeform": { + "key": "name" + }, + "question": { + "en": "What is the name of this assembly point?", + "it": "Qual è il nome di questo punto di raccolta?" + }, + "render": { + "en": "This assembly point is named {name}", + "it": "Questo punto di raccolta si chiama {name}" + } + }, + { + "id": "assembly_point_operator", + "render": { + "en": "This assembly point is operated by {operator}", + "it": "Questo punto di raccolta è gestita da {operator}" + }, + "question": { + "en": "What organization operates this assembly point?", + "it": "Quale organizzazione gestisce questo punto di raccolta?" + }, + "freeform": { + "key": "operator", + "type": "string" + } + }, + { + "id": "disaster_type", + "question": { + "en": "For which disaster type is this assembly point meant?", + "it": "Per quali tipi di disastro è pensato questo punto di raccolta?" + }, + "multiAnswer": true, + "mappings": [ + { + "if": "assembly_point:earthquake=yes", + "ifnot": "assembly_point:earthquake=", + "then": { + "en": "Earthquake", + "it": "Terremoto" + }, + "icon": { + "path": "./assets/layers/assembly_point/earthquake.svg", + "class": "medium" + } + }, + { + "if": "assembly_point:flood=yes", + "ifnot": "assembly_point:flood=", + "then": { + "en": "Flood", + "it": "Alluvione" + }, + "icon": { + "path": "./assets/layers/assembly_point/flood.svg", + "class": "medium" + } + }, + { + "if": "assembly_point:fire=yes", + "ifnot": "assembly_point:fire=", + "then": { + "en": "Fire", + "it": "Incendio" + }, + "icon": { + "path": "./assets/layers/assembly_point/fire.svg", + "class": "medium" + } + }, + { + "if": "assembly_point:landslide=yes", + "ifnot": "assembly_point:landslide=", + "then": { + "en": "Landslide", + "it": "Frana" + }, + "icon": { + "path": "./assets/layers/assembly_point/landslide.svg", + "class": "medium" + } + } + ] + } + ] +} diff --git a/assets/layers/assembly_point/assembly_point.svg b/assets/layers/assembly_point/assembly_point.svg new file mode 100644 index 0000000000..83c5ce90e6 --- /dev/null +++ b/assets/layers/assembly_point/assembly_point.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/layers/assembly_point/assembly_point.svg.license b/assets/layers/assembly_point/assembly_point.svg.license new file mode 100644 index 0000000000..25004fa706 --- /dev/null +++ b/assets/layers/assembly_point/assembly_point.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: https://commons.wikimedia.org/wiki/User:Epop +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/layers/assembly_point/earthquake.svg b/assets/layers/assembly_point/earthquake.svg new file mode 100644 index 0000000000..6eadce2e54 --- /dev/null +++ b/assets/layers/assembly_point/earthquake.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/layers/assembly_point/earthquake.svg.license b/assets/layers/assembly_point/earthquake.svg.license new file mode 100644 index 0000000000..a9272c4322 --- /dev/null +++ b/assets/layers/assembly_point/earthquake.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: United Nations Office for the Coordination of Humanitarian Affairs (OCHA) +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/layers/assembly_point/fire.svg b/assets/layers/assembly_point/fire.svg new file mode 100644 index 0000000000..462c299565 --- /dev/null +++ b/assets/layers/assembly_point/fire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/layers/assembly_point/fire.svg.license b/assets/layers/assembly_point/fire.svg.license new file mode 100644 index 0000000000..a9272c4322 --- /dev/null +++ b/assets/layers/assembly_point/fire.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: United Nations Office for the Coordination of Humanitarian Affairs (OCHA) +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/layers/assembly_point/flood.svg b/assets/layers/assembly_point/flood.svg new file mode 100644 index 0000000000..6d041fe972 --- /dev/null +++ b/assets/layers/assembly_point/flood.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/assets/layers/assembly_point/flood.svg.license b/assets/layers/assembly_point/flood.svg.license new file mode 100644 index 0000000000..9e50dbb72f --- /dev/null +++ b/assets/layers/assembly_point/flood.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Iconathon +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/layers/assembly_point/landslide.svg b/assets/layers/assembly_point/landslide.svg new file mode 100644 index 0000000000..509f02b69d --- /dev/null +++ b/assets/layers/assembly_point/landslide.svg @@ -0,0 +1,26 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/layers/assembly_point/landslide.svg.license b/assets/layers/assembly_point/landslide.svg.license new file mode 100644 index 0000000000..1d666bc5c1 --- /dev/null +++ b/assets/layers/assembly_point/landslide.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Development Seed +SPDX-License-Identifier: CC-BY-3.0 \ No newline at end of file diff --git a/assets/layers/assembly_point/license_info.json b/assets/layers/assembly_point/license_info.json new file mode 100644 index 0000000000..087834a741 --- /dev/null +++ b/assets/layers/assembly_point/license_info.json @@ -0,0 +1,56 @@ +[ + { + "path": "assembly_point.svg", + "license": "CC0-1.0", + "authors": [ + "https://commons.wikimedia.org/wiki/User:Epop" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:E011.svg" + ] + }, + { + "path": "earthquake.svg", + "license": "CC0-1.0", + "authors": [ + "United Nations Office for the Coordination of Humanitarian Affairs (OCHA)" + ], + "sources": [ + "https://thenounproject.com/icon/fire-4232/", + "https://commons.wikimedia.org/wiki/File:Earthquake_-_The_Noun_Project.svg" + ] + }, + { + "path": "fire.svg", + "license": "CC0-1.0", + "authors": [ + "United Nations Office for the Coordination of Humanitarian Affairs (OCHA)" + ], + "sources": [ + "https://thenounproject.com/icon/fire-4234/", + "https://commons.wikimedia.org/wiki/File:Fire_-_The_Noun_Project.svg" + ] + }, + { + "path": "flood.svg", + "license": "CC0-1.0", + "authors": [ + "Iconathon" + ], + "sources": [ + "https://thenounproject.com/icon/flood-752/", + "https://commons.wikimedia.org/wiki/File:Flood_(752)_-_The_Noun_Project.svg" + ] + }, + { + "path": "landslide.svg", + "license": "CC-BY-3.0", + "authors": [ + "Development Seed" + ], + "sources": [ + "https://github.com/developmentseed/mapbox/blob/master/icons-maki/maki-icons.svg", + "https://commons.wikimedia.org/wiki/File:Maki1-landslide-15.svg" + ] + } +] \ No newline at end of file diff --git a/assets/layers/disaster_response/CivilDefence.svg b/assets/layers/disaster_response/CivilDefence.svg new file mode 100644 index 0000000000..3cfd381768 --- /dev/null +++ b/assets/layers/disaster_response/CivilDefence.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/assets/layers/disaster_response/CivilDefence.svg.license b/assets/layers/disaster_response/CivilDefence.svg.license new file mode 100644 index 0000000000..54aed41888 --- /dev/null +++ b/assets/layers/disaster_response/CivilDefence.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: https://commons.wikimedia.org/wiki/User:MStankie +SPDX-License-Identifier: LicenseRef-TRIVIAL \ No newline at end of file diff --git a/assets/layers/disaster_response/disaster_response.json b/assets/layers/disaster_response/disaster_response.json new file mode 100644 index 0000000000..f12bd7ee4a --- /dev/null +++ b/assets/layers/disaster_response/disaster_response.json @@ -0,0 +1,75 @@ +{ + "id": "disaster_response", + "title": { + "render": { + "en": "Disaster response organization", + "it": "Organizzazione per la risposta ai disastri" + } + }, + "name": { + "en": "Disaster response organizations" + }, + "description": { + "en": "This layer contains organizations that have the main objective to help the civil population during and after natural or anthropogenic disasters by working in the affected area.", + "it": "Questo livello contiene organizzazioni che hanno come obiettivo principale quello di aiutare la popolazione civile durante e dopo disastri naturali o antropogenici, lavorando nell'area colpita." + }, + "docs": "https://wiki.openstreetmap.org/wiki/Tag:emergency%3Ddisaster_response", + "minzoom": 10, + "lineRendering": [ + { + "color": "#6BC4F7", + "width": 3 + } + ], + "presets": [ + { + "title": { + "en": "a disaster response organization", + "it": "un'organizzazione per la risposta ai disastri" + }, + "tags": [ + "emergency=disaster_response" + ] + } + ], + "source": { + "osmTags": { + "and": [ + "emergency=disaster_response" + ] + } + }, + "pointRendering": [ + { + "iconSize": "40,40", + "location": [ + "point", + "centroid" + ], + "anchor": "bottom", + "marker": [ + { + "icon": "./assets/themes/disaster_response/CivilDefence.svg" + } + ] + } + ], + "tagRenderings": [ + "images", + "website", + { + "id": "disaster_response_name", + "freeform": { + "key": "name" + }, + "question": { + "en": "What is the name of this organization?", + "it": "Qual è il nome di questa organizzazione?" + }, + "render": { + "en": "This organization is named {name}", + "it": "Questa organizzazione si chiama {name}" + } + } + ] +} diff --git a/assets/layers/disaster_response/license_info.json b/assets/layers/disaster_response/license_info.json new file mode 100644 index 0000000000..a11d701d0b --- /dev/null +++ b/assets/layers/disaster_response/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "CivilDefence.svg", + "license": "TRIVIAL", + "authors": [ + "https://commons.wikimedia.org/wiki/User:MStankie" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:CivilDefence.svg" + ] + } +] \ No newline at end of file diff --git a/assets/png/license_info.json b/assets/png/license_info.json new file mode 100644 index 0000000000..d5571eb0ce --- /dev/null +++ b/assets/png/license_info.json @@ -0,0 +1,18 @@ +[ + { + "path": "oneway.png", + "license": "CC0-1.0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] + }, + { + "path": "oneway.svg", + "license": "CC0-1.0", + "authors": [ + "Pieter Vander Vennet" + ], + "sources": [] + } +] \ No newline at end of file diff --git a/assets/png/oneway.png.license b/assets/png/oneway.png.license new file mode 100644 index 0000000000..ed02883002 --- /dev/null +++ b/assets/png/oneway.png.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Pieter Vander Vennet +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/png/oneway.svg.license b/assets/png/oneway.svg.license new file mode 100644 index 0000000000..ed02883002 --- /dev/null +++ b/assets/png/oneway.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Pieter Vander Vennet +SPDX-License-Identifier: CC0-1.0 \ No newline at end of file diff --git a/assets/themes/disaster_response/CivilDefence.svg b/assets/themes/disaster_response/CivilDefence.svg new file mode 100644 index 0000000000..3cfd381768 --- /dev/null +++ b/assets/themes/disaster_response/CivilDefence.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/assets/themes/disaster_response/CivilDefence.svg.license b/assets/themes/disaster_response/CivilDefence.svg.license new file mode 100644 index 0000000000..54aed41888 --- /dev/null +++ b/assets/themes/disaster_response/CivilDefence.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: https://commons.wikimedia.org/wiki/User:MStankie +SPDX-License-Identifier: LicenseRef-TRIVIAL \ No newline at end of file diff --git a/assets/themes/disaster_response/disaster_response.json b/assets/themes/disaster_response/disaster_response.json new file mode 100644 index 0000000000..58e787aa82 --- /dev/null +++ b/assets/themes/disaster_response/disaster_response.json @@ -0,0 +1,19 @@ +{ + "description": { + "en": "This map contains elements meant for disaster preparedness and response.", + "it": "Questa mappa contiene elementi pensati per la preparazione e risposta ai disastri." + }, + "docs": "https://wiki.openstreetmap.org/wiki/Emergency_facilities_and_amenities", + "icon": "./assets/themes/disaster_response/CivilDefence.svg", + "id": "disaster_response", + "socialImage": "./assets/themes/disaster_response/social.svg", + "title": { + "en": "Disaster response", + "it": "Risposta ai disastri" + }, + "layers": [ + "hospital", + "assembly_point", + "disaster_response" + ] +} \ No newline at end of file diff --git a/assets/themes/disaster_response/license_info.json b/assets/themes/disaster_response/license_info.json new file mode 100644 index 0000000000..36d8fd3991 --- /dev/null +++ b/assets/themes/disaster_response/license_info.json @@ -0,0 +1,24 @@ +[ + { + "path": "CivilDefence.svg", + "license": "TRIVIAL", + "authors": [ + "https://commons.wikimedia.org/wiki/User:MStankie" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:CivilDefence.svg" + ] + }, + { + "path": "social.svg", + "license": "TRIVIAL", + "authors": [ + "Geneva Convention", + "https://commons.wikimedia.org/wiki/User:MStankie", + "https://commons.wikimedia.org/wiki/User:The_Navigators" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Geneva_Convention_Civil_Defence_Symbol_-_Flag.svg" + ] + } +] \ No newline at end of file diff --git a/assets/themes/disaster_response/social.svg b/assets/themes/disaster_response/social.svg new file mode 100644 index 0000000000..86a0036b5b --- /dev/null +++ b/assets/themes/disaster_response/social.svg @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/assets/themes/disaster_response/social.svg.license b/assets/themes/disaster_response/social.svg.license new file mode 100644 index 0000000000..ad1a666df4 --- /dev/null +++ b/assets/themes/disaster_response/social.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Geneva Convention; https://commons.wikimedia.org/wiki/User:MStankie; https://commons.wikimedia.org/wiki/User:The_Navigators +SPDX-License-Identifier: LicenseRef-TRIVIAL \ No newline at end of file diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index 4e22c7ae7b..b5286c2f9b 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -216,6 +216,10 @@ "if": "theme=cyclofix", "then": "./assets/themes/cyclofix/logo.svg" }, + { + "if": "theme=disaster_response", + "then": "./assets/themes/disaster_response/CivilDefence.svg" + }, { "if": "theme=drinking_water", "then": "./assets/themes/drinking_water/logo.svg" diff --git a/assets/themes/ski/ski.json b/assets/themes/ski/ski.json index 8e1cad364a..b6565af9b0 100644 --- a/assets/themes/ski/ski.json +++ b/assets/themes/ski/ski.json @@ -11,17 +11,32 @@ "layers": [ "ski_piste", "aerialway", + { + "builtin": [ + "guidepost", + "map", + "information_board" + ], + "override": { + "minzoom": 13 + }, + "pointRendering": [ + { + "=iconSize": "25,25", + "=label": null + } + ] + }, { "builtin": [ "toilet", "drinking_water", "food", - "map", - "information_board", "viewpoint", "binocular" ], "override": { + "minzoom": 16, "pointRendering": [ { "=iconSize": "25,25", diff --git a/langs/layers/en.json b/langs/layers/en.json index 4870a3afe1..49bc5ddbe0 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -246,9 +246,18 @@ } }, "tagRenderings": { + "duration": { + "question": "How long takes a single journey with this elevator?", + "questionHint": "This excludes the waiting time.", + "render": "A single journey takes {duration} minutes" + }, "length": { "render": "This aerialway is {_length:km} kilometer long" }, + "occupancy": { + "question": "How many people fit a single carriage?", + "render": "{aerialway:occupancy} people fit a single carriage" + }, "type": { "mappings": { "0": { @@ -483,6 +492,45 @@ "render": "Artwork" } }, + "assembly_point": { + "description": "This layer contains assembly points and waiting areas where all employees, passengers or a large crowd assemble in case of an emergency.", + "name": "Emergency assembly points", + "presets": { + "0": { + "title": "an assembly point" + } + }, + "tagRenderings": { + "assembly_point_name": { + "question": "What is the name of this assembly point?", + "render": "This assembly point is named {name}" + }, + "assembly_point_operator": { + "question": "What organization operates this assembly point?", + "render": "This assembly point is operated by {operator}" + }, + "disaster_type": { + "mappings": { + "0": { + "then": "Earthquake" + }, + "1": { + "then": "Flood" + }, + "2": { + "then": "Fire" + }, + "3": { + "then": "Landslide" + } + }, + "question": "For which disaster type is this assembly point meant?" + } + }, + "title": { + "render": "Assembly point during emergencies" + } + }, "atm": { "description": "ATMs to withdraw money", "filter": { @@ -3727,6 +3775,24 @@ "description": "This layer visualizes directions", "name": "Direction visualization" }, + "disaster_response": { + "description": "This layer contains organizations that have the main objective to help the civil population during and after natural or anthropogenic disasters by working in the affected area.", + "name": "Disaster response organizations", + "presets": { + "0": { + "title": "a disaster response organization" + } + }, + "tagRenderings": { + "disaster_response_name": { + "question": "What is the name of this organization?", + "render": "This organization is named {name}" + } + }, + "title": { + "render": "Disaster response organization" + } + }, "doctors": { "description": "This layer shows doctor offices", "name": "Doctors", diff --git a/langs/layers/it.json b/langs/layers/it.json index 8652c3e0c0..6ba9467b0c 100644 --- a/langs/layers/it.json +++ b/langs/layers/it.json @@ -142,6 +142,42 @@ "render": "Opera d’arte" } }, + "assembly_point": { + "description": "Questo livello contiene punti di raccolta e aree di attesa in cui tutti i dipendenti, i passeggeri o una grande folla si riuniscono in caso di emergenza.", + "name": "Punti di raccolta per emergenze", + "presets": { + "0": { + "title": "un punto di raccolta" + } + }, + "tagRenderings": { + "assembly_point_name": { + "question": "Qual è il nome di questo punto di raccolta?", + "render": "Questo punto di raccolta si chiama {name}" + }, + "assembly_point_operator": { + "question": "Quale organizzazione gestisce questo punto di raccolta?", + "render": "Questo punto di raccolta è gestita da {operator}" + }, + "disaster_type": { + "mappings": { + "0": { + "then": "Terremoto" + }, + "1": { + "then": "Alluvione" + }, + "2": { + "then": "Incendio" + }, + "3": { + "then": "Frana" + } + }, + "question": "Per quali tipi di disastro è pensato questo punto di raccolta?" + } + } + }, "atm": { "description": "Sportello Bancomat per prelevare denaro", "name": "Sportelli Bancomat", @@ -1279,6 +1315,23 @@ "description": "Questo livello visualizza le direzioni", "name": "Visualizzazione della direzione" }, + "disaster_response": { + "description": "Questo livello contiene organizzazioni che hanno come obiettivo principale quello di aiutare la popolazione civile durante e dopo disastri naturali o antropogenici, lavorando nell'area colpita.", + "presets": { + "0": { + "title": "un'organizzazione per la risposta ai disastri" + } + }, + "tagRenderings": { + "disaster_response_name": { + "question": "Qual è il nome di questa organizzazione?", + "render": "Questa organizzazione si chiama {name}" + } + }, + "title": { + "render": "Organizzazione per la risposta ai disastri" + } + }, "drinking_water": { "name": "Acqua potabile", "presets": { diff --git a/langs/themes/en.json b/langs/themes/en.json index b47384a053..be7c82c189 100644 --- a/langs/themes/en.json +++ b/langs/themes/en.json @@ -631,6 +631,10 @@ "description": "The goal of this map is to present cyclists with an easy-to-use solution to find the appropriate infrastructure for their needs.

You can track your precise location (mobile only) and select layers that are relevant for you in the bottom left corner. You can also use this tool to add or edit pins (points of interest) to the map and provide more data by answering the questions.

All changes you make will automatically be saved in the global database of OpenStreetMap and can be freely re-used by others.

For more information about the cyclofix project, go to cyclofix.osm.be.", "title": "Cyclofix - a map for cyclists" }, + "disaster_response": { + "description": "This map contains elements meant for disaster preparedness and response.", + "title": "Disaster response" + }, "drinking_water": { "description": "On this map, publicly accessible drinking water spots are shown and can be easily added", "title": "Drinking Water" diff --git a/langs/themes/it.json b/langs/themes/it.json index c8eace3e25..6fc0f4e43a 100644 --- a/langs/themes/it.json +++ b/langs/themes/it.json @@ -401,6 +401,10 @@ "description": "Questa mappa offre a chi va in bici una soluzione semplice per trovare tutte le infrastrutture di cui ha bisogno.

Puoi tracciare la tua posizione esatta (solo su mobile) e selezionare i livelli che ti interessano nell'angolo in basso a sinistra. Puoi anche usare questo strumento per aggiungere o modificare punti di interesse alla mappa e aggiungere nuove informazioni rispendendo alle domande.

Tutte le modifiche che apporterai saranno automaticamente salvate nel database mondiale di OpenStreetMap e potranno essere liberamente riutilizzate da tutti e tutte.

Per maggiori informazioni sul progetto ciclofix, visita cyclofix.osm.be.", "title": "Cyclofix - una mappa libera per chi va in bici" }, + "disaster_response": { + "description": "Questa mappa contiene elementi pensati per la preparazione e risposta ai disastri.", + "title": "Risposta ai disastri" + }, "drinking_water": { "description": "Questa mappa mostra tutti i luoghi in cui è disponibile acqua potabile ed è possibile aggiungerne di nuovi", "title": "Acqua potabile" diff --git a/scripts/build.sh b/scripts/build.sh index 7851dd513c..d8a9b60cc4 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -23,6 +23,7 @@ vite build --sourcemap || { echo 'Vite build failed' ; exit 1; } cp -r assets/layers/ dist/assets/layers/ cp -r assets/themes/ dist/assets/themes/ cp -r assets/svg/ dist/assets/svg/ +cp -r assets/png/ dist/assets/png/ mkdir dist/assets/langs mkdir dist/assets/langs/layers cp -r langs/layers/ dist/assets/langs/ diff --git a/scripts/generateLayouts.ts b/scripts/generateLayouts.ts index fba21038e3..9c2bfe8aa9 100644 --- a/scripts/generateLayouts.ts +++ b/scripts/generateLayouts.ts @@ -273,7 +273,6 @@ async function generateCsp( } ): Promise { const apiUrls: string[] = [ - "'self'", ...Constants.defaultOverpassUrls, Constants.countryCoderEndpoint, Constants.nominatimEndpoint, @@ -350,7 +349,7 @@ async function generateCsp( "default-src": "'self'", "child-src": "'self' blob: ", "img-src": "* data:", // maplibre depends on 'data:' to load - "connect-src": connectSrc.join(" "), + "connect-src": "'self' "+connectSrc.join(" "), "report-to": "https://report.mapcomplete.org/csp", "worker-src": "'self' blob:", // Vite somehow loads the worker via a 'blob' "style-src": "'self' 'unsafe-inline'", // unsafe-inline is needed to change the default background pin colours diff --git a/src/Logic/GeoOperations.ts b/src/Logic/GeoOperations.ts index 5d36e28eb8..571a1c4005 100644 --- a/src/Logic/GeoOperations.ts +++ b/src/Logic/GeoOperations.ts @@ -345,11 +345,18 @@ export class GeoOperations { return way } - public static toCSV(features: Feature[] | FeatureCollection): string { + public static toCSV(features: Feature[] | FeatureCollection, options?: { + ignoreTags?: RegExp + }): string { const headerValuesSeen = new Set() const headerValuesOrdered: string[] = [] - function addH(key) { + function addH(key: string) { + if(options?.ignoreTags){ + if(key.match(options.ignoreTags)){ + return + } + } if (!headerValuesSeen.has(key)) { headerValuesSeen.add(key) headerValuesOrdered.push(key) diff --git a/src/Models/ThemeConfig/PointRenderingConfig.ts b/src/Models/ThemeConfig/PointRenderingConfig.ts index 8821adec7a..4f83499c59 100644 --- a/src/Models/ThemeConfig/PointRenderingConfig.ts +++ b/src/Models/ThemeConfig/PointRenderingConfig.ts @@ -312,7 +312,7 @@ export default class PointRenderingConfig extends WithContextLoader { if (cssLabel) { label.SetStyle(cssLabel) } else if (labelOnly) { - return label.SetStyle("transform: translate(-50%, -50%);") + return label?.SetStyle("transform: translate(-50%, -50%);") } return new Combine([label]).SetClass("flex flex-col items-center") }) diff --git a/src/UI/Base/DirectionIndicator.svelte b/src/UI/Base/DirectionIndicator.svelte index 7e859dd3d8..d636ef5a76 100644 --- a/src/UI/Base/DirectionIndicator.svelte +++ b/src/UI/Base/DirectionIndicator.svelte @@ -132,11 +132,11 @@ so we use a 'div' and add on:click manually -->
focusMap()} use:ariaLabelStore={label} > -
+
{:else}
self.update(features.features)) } - private addSymbolLayer(sourceId: string, url: string = "./assets/png/oneway.png"){ + private async addSymbolLayer(sourceId: string, url: string = "./assets/png/oneway.png") { const map = this._map const imgId = url.replaceAll(/[/.-]/g, "_") - map.loadImage(url, (err, image) => { - if (err) { - console.error("Could not add symbol layer to line due to", err); - return - } - map.addImage(imgId, image); - map.addLayer({ - 'id': "symbol-layer"+imgId, + + if (map.getImage(imgId) === undefined) { + await new Promise((resolve, reject) => { + map.loadImage(url, (err, image) => { + if (err) { + console.error("Could not add symbol layer to line due to", err) + reject(err) + return + } + map.addImage(imgId, image) + resolve() + }) + }) + } + + map.addLayer({ + "id": "symbol-layer_" + this._layername + "-" + imgId, 'type': 'symbol', 'source': sourceId, 'layout': { 'symbol-placement': 'line', - 'symbol-spacing': 1, + 'symbol-spacing': 10, 'icon-allow-overlap': true, 'icon-rotation-alignment':'map', 'icon-pitch-alignment':'map', 'icon-image': imgId, - 'icon-size': 0.045, + 'icon-size': 0.055, 'visibility': 'visible' } }); - }); + } public destruct(): void { @@ -347,7 +356,13 @@ class LineRenderingLayer { "line-cap": "round", }, }) - this.addSymbolLayer(this._layername) + + if(this._layername.startsWith("mapcomplete_ski_piste") || this._layername.startsWith("mapcomplete_aerialway")){ + // TODO FIXME properly enable this so that more layers can use this if appropriate + this.addSymbolLayer(this._layername) + }else{ + console.log("No oneway arrow for", this._layername) + } for (const feature of features) { diff --git a/src/UI/StatisticsGUI.ts b/src/UI/StatisticsGUI.ts index 9d27dc5805..8949b715e8 100644 --- a/src/UI/StatisticsGUI.ts +++ b/src/UI/StatisticsGUI.ts @@ -16,6 +16,11 @@ import mcChanges from "../../src/assets/generated/themes/mapcomplete-changes.jso import SvelteUIElement from "./Base/SvelteUIElement" import Filterview from "./BigComponents/Filterview.svelte" import FilteredLayer from "../Models/FilteredLayer" +import DownloadButton from "./DownloadFlow/DownloadButton.svelte" +import { SubtleButton } from "./Base/SubtleButton" +import { GeoOperations } from "../Logic/GeoOperations" +import { Polygon } from "geojson" +import { Feature } from "geojson" class StatsticsForOverviewFile extends Combine { constructor(homeUrl: string, paths: string[]) { @@ -185,6 +190,17 @@ class StatsticsForOverviewFile extends Combine { } } + + elements.push(new SubtleButton( + undefined, "Download as csv" + ).onClick(() => { + const data = GeoOperations.toCSV(overview._meta, + { + ignoreTags: /^((deletion:node)|(import:node)|(move:node)|(soft-delete:))/ + }) + Utils.offerContentsAsDownloadableFile(data , "statistics.csv", {mimetype: "text/csv"}) + })) + return new Combine(elements) }, [filteredLayer.currentFilter] @@ -249,7 +265,7 @@ class ChangesetsOverview { this._meta = Utils.NoNull(meta) } - public static fromDirtyData(meta: ChangeSetData[]) { + public static fromDirtyData(meta: ChangeSetData[]): ChangesetsOverview { return new ChangesetsOverview(meta?.map((cs) => ChangesetsOverview.cleanChangesetData(cs))) } @@ -301,7 +317,7 @@ class ChangesetsOverview { } } -interface ChangeSetData { +interface ChangeSetData extends Feature { id: number type: "Feature" geometry: {