diff --git a/Models/ThemeConfig/Conversion/Validation.ts b/Models/ThemeConfig/Conversion/Validation.ts index 22400569e6..bcc24c6b79 100644 --- a/Models/ThemeConfig/Conversion/Validation.ts +++ b/Models/ThemeConfig/Conversion/Validation.ts @@ -246,6 +246,10 @@ class OverrideShadowingCheck extends DesugaringStep { for (const layer of withOverride) { for (const key in overrideAll) { + if(key.endsWith("+") || key.startsWith("+")){ + // This key will _add_ to the list, not overwrite it - so no warning is needed + continue + } if (layer["override"][key] !== undefined || layer["override"]["=" + key] !== undefined) { const w = "The override of layer " + JSON.stringify(layer["builtin"]) + " has a shadowed property: " + key + " is overriden by overrideAll of the theme"; errors.push(w) diff --git a/Models/ThemeConfig/Json/UnitConfigJson.ts b/Models/ThemeConfig/Json/UnitConfigJson.ts index bde2683b23..f69212f000 100644 --- a/Models/ThemeConfig/Json/UnitConfigJson.ts +++ b/Models/ThemeConfig/Json/UnitConfigJson.ts @@ -1,7 +1,9 @@ export default interface UnitConfigJson { /** - * Every key from this list will be normalized + * Every key from this list will be normalized. + * + * To render a united value properly, use */ appliesToKey: string[], /** diff --git a/assets/layers/entrance/entrance.json b/assets/layers/entrance/entrance.json index c5df0bb8d3..0533936342 100644 --- a/assets/layers/entrance/entrance.json +++ b/assets/layers/entrance/entrance.json @@ -340,6 +340,31 @@ "key": "width", "type": "distance" } + }, + { + "id": "kerb-height", + "question": { + "en": "What is the height of this kerb?" + }, + "render": { + "en": "The kerb height of this door is {kerb:height}" + }, + "freeform": { + "key": "kerb:height", + "placeholder": { + "en": "Height of the door kerb" + }, + "type": "pnat" + }, + "mappings": [ + { + "if": "kerb-height=", + "then": { + "en": "This door does not have a kerb", + "nl": "Deze deur heeft geen drempel" + } + } + ] } ], "mapRendering": [ @@ -375,5 +400,33 @@ "entrance=yes" ] } + ], + "units": [ + { + "appliesToKey": [ + "kerb:height" + ], + "applicableUnits": [ + { + "canonicalDenomination": "m", + "alternativeDenomination": [ + "meter" + ], + "human": { + "en": "meter" + } + }, + { + "canonicalDenomination": "cm", + "alternativeDenomination": [ + "centimeter", + "cms" + ], + "human": { + "en": "centimeter" + } + } + ] + } ] } \ No newline at end of file diff --git a/assets/layers/indoors/indoors.json b/assets/layers/indoors/indoors.json new file mode 100644 index 0000000000..1c14a47e8f --- /dev/null +++ b/assets/layers/indoors/indoors.json @@ -0,0 +1,81 @@ +{ + "id": "indoors", + "name": { + "en": "indoors" + }, + "source": { + "osmTags": { + "or": [ + "indoor=room", + "indoor=area", + "indoor=wall", + "indoor=door", + "indoor=level" + ] + } + }, + "title": { + "render": { + "en": "Indoor area {name}" + }, + "mappings": [ + { + "if": "indoor=room", + "then": "Indoor Room {name}" + }, + { + "if": "indoor=area", + "then": "Indoor Area {name}" + }, + { + "if": "indoor=wall", + "then": "Indoor Wall {name}" + }, + { + "if": "indoor=corridor", + "then": "Indoor Corridor {name}" + }, + { + "if": "indoor=door", + "then": "Indoor Door {name}" + }, + { + "if": "indoor=level", + "then": "Indoor Level {name}" + } + ] + }, + "minzoom": 13, + "tagRenderings": [ + "images" + ], + "mapRendering": [ + { + "color": { + "render": "#bb004488" + }, + "width": { + "render": "8" + }, + "offset": { + "render": "-4" + }, + "fill": "no" + }, + { + "color": "red", + "fill": "no", + "width": "2" + }, + { + "label": { + "render": "
{name}
", + "condition": "name~*" + }, + "location": [ + "point", + "centroid" + ] + } + ] +} \ No newline at end of file diff --git a/assets/layers/pharmacy/pharmacy.json b/assets/layers/pharmacy/pharmacy.json index cfac37ca2a..4f440aac0d 100644 --- a/assets/layers/pharmacy/pharmacy.json +++ b/assets/layers/pharmacy/pharmacy.json @@ -68,5 +68,29 @@ "centroid" ] } - ] + ], + "filter": [ + { + "id": "drive-through", + "options": [ + { + "question": { + "en": "Has drive through" + }, + "osmTags": "drive_through=yes" + } + ] + }, + { + "id": "dispensing", + "options": [ + { + "question": { + "en": "Pharmacy able to provide prescription drugs" + }, + "osmTags": "dispensing=yes" + } + ] + } + ] } \ No newline at end of file diff --git a/assets/layers/reception_desk/license_info.json b/assets/layers/reception_desk/license_info.json new file mode 100644 index 0000000000..5afdc20e73 --- /dev/null +++ b/assets/layers/reception_desk/license_info.json @@ -0,0 +1,12 @@ +[ + { + "path": "reception_desk.svg", + "license": "CC-BY-SA", + "authors": [ + "Robin Julien" + ], + "sources": [ + "https://www.ctsteward.com/" + ] + } +] \ No newline at end of file diff --git a/assets/layers/reception_desk/reception_desk.json b/assets/layers/reception_desk/reception_desk.json new file mode 100644 index 0000000000..a9d3228c24 --- /dev/null +++ b/assets/layers/reception_desk/reception_desk.json @@ -0,0 +1,79 @@ +{ + "id": "reception_desk", + "name": { + "en": "Reception desks" + }, + "title": { + "render": { + "en": "Reception desk" + } + }, + "source": { + "osmTags": "amenity=reception_desk" + }, + "mapRendering": [ + { + "location": [ + "point", + "centroid" + ], + "icon": "circle:white;./assets/layers/reception_desk/reception_desk.svg", + "iconSize": "40,40,center" + } + ], + "tagRenderings": [ + "images", + { + "id": "desk-height", + "question": { + "en": "What is the height of the reception desk?
This is measured from the floor to the lowest usable part of the desk
" + }, + "render": { + "en": "The height of the desk is {canonical(desk:height)}" + }, + "freeform": { + "key": "desk:height", + "type": "pfloat" + } + }, + "induction-loop" + ], + "presets": [ + { + "tags": [ + "amenity=reception_desk" + ], + "title": { + "en": "a reception desk" + } + } + ], + "units": [ + { + "appliesToKey": [ + "desk:height" + ], + "applicableUnits": [ + { + "canonicalDenomination": "m", + "alternativeDenomination": [ + "meter" + ], + "human": { + "en": "meter" + } + }, + { + "canonicalDenomination": "cm", + "alternativeDenomination": [ + "centimeter", + "cms" + ], + "human": { + "en": "centimeter" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/assets/layers/reception_desk/reception_desk.svg b/assets/layers/reception_desk/reception_desk.svg new file mode 100644 index 0000000000..e8dd150704 --- /dev/null +++ b/assets/layers/reception_desk/reception_desk.svg @@ -0,0 +1,29 @@ + + + + + + + + + + diff --git a/assets/layers/walls_and_buildings/walls_and_buildings.json b/assets/layers/walls_and_buildings/walls_and_buildings.json index 133a2bf0f2..4ef1816e6a 100644 --- a/assets/layers/walls_and_buildings/walls_and_buildings.json +++ b/assets/layers/walls_and_buildings/walls_and_buildings.json @@ -47,7 +47,7 @@ "calculatedTags": [ "_entrance_properties=feat.overlapWith('entrance')?.map(e => e.feat.properties).filter(p => p !== undefined).filter(p => p.width !== undefined)", "_entrance:id=feat.get('_entrance_properties')?.map(e => e.id)?.at(0)", - "_entrance:width=feat.get('_entrance_properties')?.map(e => e.width)" + "_entrance:width=feat.get('_entrance_properties')?.map(e => e.width)?.at(0)" ], "tagRenderings": [ { diff --git a/assets/tagRenderings/audio_induction_loop.svg b/assets/tagRenderings/audio_induction_loop.svg new file mode 100644 index 0000000000..b56e877be2 --- /dev/null +++ b/assets/tagRenderings/audio_induction_loop.svg @@ -0,0 +1,44 @@ + + diff --git a/assets/tagRenderings/audio_induction_loop_missing.svg b/assets/tagRenderings/audio_induction_loop_missing.svg new file mode 100644 index 0000000000..b35a316069 --- /dev/null +++ b/assets/tagRenderings/audio_induction_loop_missing.svg @@ -0,0 +1,53 @@ + + diff --git a/assets/tagRenderings/license_info.json b/assets/tagRenderings/license_info.json index c65bd6f938..1f92135a1c 100644 --- a/assets/tagRenderings/license_info.json +++ b/assets/tagRenderings/license_info.json @@ -1,4 +1,24 @@ [ + { + "path": "audio_induction_loop.svg", + "license": "CC-BY 4.0", + "authors": [ + "Carl Holderness" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Noun_telecoil_audio_induction_hearing_loop_symbol_2011213.svg" + ] + }, + { + "path": "audio_induction_loop_missing.svg", + "license": "CC-BY 4.0", + "authors": [ + "Carl Holderness" + ], + "sources": [ + "https://commons.wikimedia.org/wiki/File:Noun_telecoil_audio_induction_hearing_loop_symbol_2011213.svg" + ] + }, { "path": "cash.svg", "license": "CC-BY 3.0", diff --git a/assets/tagRenderings/questions.json b/assets/tagRenderings/questions.json index aeafac6f44..ec5ee874af 100644 --- a/assets/tagRenderings/questions.json +++ b/assets/tagRenderings/questions.json @@ -1086,5 +1086,33 @@ } } ] + }, + "induction-loop": { + "description": "An accessibility feature: induction loops are for hard-hearing persons which have an FM-receiver.", + "question": { + "en": "Does this place have an audio induction loop for people with reduced hearing?" + }, + "mappings": [ + { + "if": "hearing_loop=yes", + "then": { + "en": "This place has an audio induction loop" + }, + "icon": { + "path": "./assets/tagRenderings/audio_induction_loop.svg", + "class": "medium" + } + }, + { + "if": "hearing_loop=no", + "then": { + "en": "This place does not has an audio induction loop" + }, + "icon": { + "path": "./assets/tagRenderings/audio_induction_loop_missing.svg", + "class": "medium" + } + } + ] } } \ No newline at end of file diff --git a/assets/themes/indoors/crest.svg b/assets/themes/indoors/crest.svg new file mode 100644 index 0000000000..383b543b1e --- /dev/null +++ b/assets/themes/indoors/crest.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/themes/indoors/indoors.json b/assets/themes/indoors/indoors.json new file mode 100644 index 0000000000..c8964878e2 --- /dev/null +++ b/assets/themes/indoors/indoors.json @@ -0,0 +1,20 @@ +{ + "id": "indoors", + "title": { + "en": "Indoors" + }, + "description": { + "en": "On this map, publicly accessible indoor places are shown" + }, + "maintainer": "MapComplete", + "icon": "./assets/themes/onwheels/crest.svg", + "version": "0", + "startLat": 51.17181, + "defaultBackgroundId": "CartoDB.Voyager", + "startLon": 4.144383, + "startZoom": 14, + "widenFactor": 2, + "layers": [ + "indoors" + ] +} \ No newline at end of file diff --git a/assets/themes/indoors/license_info.json b/assets/themes/indoors/license_info.json new file mode 100644 index 0000000000..9f2dcf81aa --- /dev/null +++ b/assets/themes/indoors/license_info.json @@ -0,0 +1,10 @@ +[ + { + "path": "crest.svg", + "license": "CC0", + "authors": [ + "Free Wheelies" + ], + "sources": [] + } +] \ 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 6f98148a53..7b3690cb79 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -1,19 +1,13 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete", - "de": "Mit MapComplete vorgenommene Änderungen", - "nl": "Wijzigingen gemaakt met MapComplete" + "en": "Changes made with MapComplete" }, "shortDescription": { - "en": "Shows changes made by MapComplete", - "de": "Zeigt die mit MapComplete vorgenommenen Änderungen", - "nl": "Toont wijzigingen gemaakt met MapComplete" + "en": "Shows changes made by MapComplete" }, "description": { - "en": "This maps shows all the changes made with MapComplete", - "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", - "nl": "Deze kaart toont alle wijzigingen die met MapComplete werden gemaakt" + "en": "This maps shows all the changes made with MapComplete" }, "maintainer": "", "icon": "./assets/svg/logo.svg", @@ -28,8 +22,7 @@ { "id": "mapcomplete-changes", "name": { - "en": "Changeset centers", - "de": "Zentrum der Änderungssätze" + "en": "Changeset centers" }, "minzoom": 0, "source": { @@ -43,47 +36,35 @@ ], "title": { "render": { - "en": "Changeset for {theme}", - "de": "Änderungssatz für {theme}", - "nl": "Wijzigingset voor {theme}" + "en": "Changeset for {theme}" } }, "description": { - "en": "Shows all MapComplete changes", - "de": "Zeigt alle MapComplete Änderungen", - "nl": "Toont alle wijzigingen met MapComplete" + "en": "Shows all MapComplete changes" }, "tagRenderings": [ { "id": "render_id", "render": { - "en": "Changeset {id}", - "de": "Änderungssatz {id}", - "nl": "Wijzigingset {id}" + "en": "Changeset {id}" } }, { "id": "contributor", "render": { - "en": "Change made by {_last_edit:contributor}", - "de": "Geändert von {_last_edit:contributor}", - "nl": "Wijziging gemaakt door {_last_edit:contributor}" + "en": "Change made by {_last_edit:contributor}" } }, { "id": "theme", "render": { - "en": "Change with theme {theme}", - "de": "Änderung mit Thema {theme}", - "nl": "Wijziging met thema {theme}" + "en": "Change with theme {theme}" }, "mappings": [ { "if": "theme~http.*", "then": { - "en": "Change with unofficial theme {theme}", - "de": "Änderung mit inoffiziellem Thema {theme}", - "nl": "Wijziging met officieus thema {theme}" + "en": "Change with unofficial theme {theme}" } } ] @@ -230,6 +211,10 @@ "if": "theme=healthcare", "then": "./assets/layers/doctors/doctors.svg" }, + { + "if": "theme=indoors", + "then": "./assets/themes/onwheels/crest.svg" + }, { "if": "theme=kerbs_and_crossings", "then": "./assets/layers/kerbs/KerbIcon.svg" @@ -383,9 +368,7 @@ } ], "question": { - "en": "Themename contains {search}", - "de": "Themenname enthält {search}", - "nl": "Themanaam bevat {search}" + "en": "Themename contains {search}" } } ] @@ -401,9 +384,7 @@ } ], "question": { - "en": "Made by contributor {search}", - "de": "Erstellt von {search}", - "nl": "Gemaakt door bijdrager {search}" + "en": "Made by contributor {search}" } } ] @@ -419,9 +400,7 @@ } ], "question": { - "en": "Not made by contributor {search}", - "de": "Nicht erstellt von {search}", - "nl": "Niet gemaakt door bijdrager {search}" + "en": "Not made by contributor {search}" } } ] @@ -436,9 +415,7 @@ { "id": "link_to_more", "render": { - "en": "More statistics can be found here", - "de": "Weitere Statistiken finden Sie hier", - "nl": "Meer statistieken kunnen hier gevonden worden" + "en": "More statistics can be found here" } }, { diff --git a/assets/themes/onwheels/onwheels.json b/assets/themes/onwheels/onwheels.json index 74496f104a..6a3928c459 100644 --- a/assets/themes/onwheels/onwheels.json +++ b/assets/themes/onwheels/onwheels.json @@ -29,22 +29,29 @@ "toilet", "viewpoint", "doctors", + "reception_desk", "walls_and_buildings" ], "overrideAll": { "+calculatedTags": [ "_poi_walls_and_buildings_entrance_properties=feat.closestn('walls_and_buildings', 1, undefined, 1000).map(w => ({id: w.feat.properties.id, width: w.feat.properties['_entrance:width']}))[0]", + "_poi_entrance:id=JSON.parce(feat.properties._poi_walls_and_buildings_entrance_properteis)?.id", "_poi_entrance:width=JSON.parse(feat.properties._poi_walls_and_buildings_entrance_properties)?.width" ], "+tagRenderings": [ { "id": "_poi_entrance:width", - "condition": "entrance=", + "condition": { + "and": [ + "entrance=", + "kerb=" + ] + }, "render": { - "en": "This door has a width of {canonical(_poi_entrance:width)} meter", - "nl": "Deze deur heeft een breedte van {canonical(_poi_entrance:width)} meter", - "de": "Diese Tür hat eine Durchgangsbreite von {canonical(_poi_entrance:width)} Meter", - "es": "Esta puerta tiene una ancho de {canonical(_poi_entrance:width)} metros" + "en": "This door has a width of {canonical(_poi_entrance:width)} meters", + "nl": "Deze deur heeft een breedte van {canonical(_poi_entrance:width)} meter", + "de": "Diese Tür hat eine Durchgangsbreite von {canonical(_poi_entrance:width)} Meter", + "es": "Esta puerta tiene una ancho de {canonical(_poi_entrance:width)} metros" }, "freeform": { "key": "_poi_entrance:width",