Merge develop
35
.vscode/settings.json
vendored
|
@ -7,6 +7,41 @@
|
|||
{
|
||||
"fileMatch": ["/assets/themes/*/*.json", "!/assets/themes/*/license_info.json"],
|
||||
"url": "./Docs/Schemas/LayoutConfigJson.schema.json"
|
||||
},
|
||||
{
|
||||
"fileMatch": ["/assets/themes/*/license_info.json", "/assets/layers/*/license_info.json"],
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"title": "License Info",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "Path to the file"
|
||||
},
|
||||
"authors": {
|
||||
"type": "array",
|
||||
"description": "Authors of the file",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"license": {
|
||||
"type": "string",
|
||||
"description": "License of the file"
|
||||
},
|
||||
"sources": {
|
||||
"type": "array",
|
||||
"description": "Sources of the file",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["path", "authors", "license", "sources"]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"editor.tabSize": 2,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
"osmTags": {
|
||||
"and": [
|
||||
"amenity=vending_machine",
|
||||
"vending=elongated_coin"
|
||||
"vending~.*elongated_coin.*"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -440,8 +440,5 @@
|
|||
"accepts_credit_cards"
|
||||
],
|
||||
"deletion": true,
|
||||
"allowMove": {
|
||||
"enableImproveAccuracy": true,
|
||||
"enableRelocation": true
|
||||
}
|
||||
}
|
||||
"allowMove": true
|
||||
}
|
BIN
assets/layers/playground_equipment/DeimosXL1.jpg
Normal file
After Width: | Height: | Size: 1 MiB |
2
assets/layers/playground_equipment/DeimosXL1.jpg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Damian stawowy
|
||||
SPDX-License-Identifier: CC-BY-SA 4.0
|
BIN
assets/layers/playground_equipment/Funnel_ball.jpg
Normal file
After Width: | Height: | Size: 56 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Pavtron (talk)
|
||||
SPDX-License-Identifier: Public domain
|
BIN
assets/layers/playground_equipment/Hinkelbaan_tegels.jpg
Normal file
After Width: | Height: | Size: 1.1 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: M.Minderhoud
|
||||
SPDX-License-Identifier: Public domain
|
BIN
assets/layers/playground_equipment/Hupfkissen.jpg
Normal file
After Width: | Height: | Size: 313 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Peter Wanders
|
||||
SPDX-License-Identifier: Public domain
|
After Width: | Height: | Size: 6.9 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Reda Kerbouche
|
||||
SPDX-License-Identifier: CC-BY-SA 4.0
|
After Width: | Height: | Size: 3.1 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Jleedev
|
||||
SPDX-License-Identifier: CC-BY-SA 4.0
|
BIN
assets/layers/playground_equipment/Playground_climbingwall.jpg
Normal file
After Width: | Height: | Size: 85 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Mktravel
|
||||
SPDX-License-Identifier: Public Domain
|
After Width: | Height: | Size: 469 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Roger Kidd
|
||||
SPDX-License-Identifier: CC-BY-SA 2.0
|
BIN
assets/layers/playground_equipment/Playground_swing_03.jpg
Normal file
After Width: | Height: | Size: 10 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Kritzolina
|
||||
SPDX-License-Identifier: CC-BY-SA 4.0
|
BIN
assets/layers/playground_equipment/Playhouse.jpg
Normal file
After Width: | Height: | Size: 125 KiB |
2
assets/layers/playground_equipment/Playhouse.jpg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Saku
|
||||
SPDX-License-Identifier: CC-BY-SA 3.0
|
BIN
assets/layers/playground_equipment/Rekstok.JPG
Normal file
After Width: | Height: | Size: 684 KiB |
2
assets/layers/playground_equipment/Rekstok.JPG.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: self
|
||||
SPDX-License-Identifier: Public domain
|
BIN
assets/layers/playground_equipment/Seesaw-aa.jpg
Normal file
After Width: | Height: | Size: 64 KiB |
2
assets/layers/playground_equipment/Seesaw-aa.jpg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Itsmine
|
||||
SPDX-License-Identifier: Public domain
|
BIN
assets/layers/playground_equipment/Spinning_circle.jpg
Normal file
After Width: | Height: | Size: 1 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Jose1711
|
||||
SPDX-License-Identifier: CC0 1.0
|
After Width: | Height: | Size: 110 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Mc on avon
|
||||
SPDX-License-Identifier: Public domain
|
After Width: | Height: | Size: 3.6 MiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Pece
|
||||
SPDX-License-Identifier: CC-BY 3.0
|
After Width: | Height: | Size: 104 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Phil Champion
|
||||
SPDX-License-Identifier: CC-BY-SA 2.0
|
After Width: | Height: | Size: 90 KiB |
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Glogger
|
||||
SPDX-License-Identifier: CC-BY-SA 3.0
|
BIN
assets/layers/playground_equipment/Zandbakw.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
2
assets/layers/playground_equipment/Zandbakw.jpg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Waerth
|
||||
SPDX-License-Identifier: CC-BY-SA 3.0
|
182
assets/layers/playground_equipment/license_info.json
Normal file
|
@ -0,0 +1,182 @@
|
|||
[
|
||||
{
|
||||
"path": "DeimosXL1.jpg",
|
||||
"license": "CC-BY-SA 4.0",
|
||||
"authors": [
|
||||
"Damian stawowy"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:DeimosXL1.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Funnel_ball.jpg",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"Pavtron (talk)"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Funnel_ball.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Hinkelbaan_tegels.jpg",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"M.Minderhoud"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Hinkelbaan_tegels.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Hupfkissen.jpg",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"Peter Wanders"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:H%C3%BCpfkissen.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Manually_powered_carousel_on_a_playground_in_Saint-Petersburg.JPG",
|
||||
"license": "CC-BY-SA 4.0",
|
||||
"authors": [
|
||||
"Reda Kerbouche"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Manually_powered_carousel_on_a_playground_in_Saint-Petersburg.JPG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Playground_Map,_Washington_Elementary.jpg",
|
||||
"license": "CC-BY-SA 4.0",
|
||||
"authors": [
|
||||
"Jleedev"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Playground_Map,_Washington_Elementary.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Playground_climbingwall.jpg",
|
||||
"license": "Public Domain",
|
||||
"authors": [
|
||||
"Mktravel"
|
||||
],
|
||||
"sources": [
|
||||
"https://wiki.openstreetmap.org/wiki/File:Playground_climbingwall.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Playground_in_Muchall_Park,_Wolverhampton_-_geograph.org.uk_-_2735437.jpg",
|
||||
"license": "CC-BY-SA 2.0",
|
||||
"authors": [
|
||||
"Roger Kidd"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Playground_in_Muchall_Park,_Wolverhampton_-_geograph.org.uk_-_2735437.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Playground_swing_03.jpg",
|
||||
"license": "CC-BY-SA 4.0",
|
||||
"authors": [
|
||||
"Kritzolina"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Playground_swing_03.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Playhouse.jpg",
|
||||
"license": "CC-BY-SA 3.0",
|
||||
"authors": [
|
||||
"Saku"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Playhouse.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Rekstok.JPG",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"self"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Rekstok.JPG"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Seesaw-aa.jpg",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"Itsmine"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Seesaw-aa.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Spinning_circle.jpg",
|
||||
"license": "CC0 1.0",
|
||||
"authors": [
|
||||
"Jose1711"
|
||||
],
|
||||
"sources": [
|
||||
"https://wiki.openstreetmap.org/wiki/File:Spinning_circle.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "SunwardCohousingPlayStructure2005.jpg",
|
||||
"license": "Public domain",
|
||||
"authors": [
|
||||
"Mc on avon"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:SunwardCohousingPlayStructure2005.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Szwedy_-_plac_zabaw_-_kotko_i_krzyzyk.jpg",
|
||||
"license": "CC-BY 3.0",
|
||||
"authors": [
|
||||
"Pece"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Szwedy_-_plac_zabaw_-_k%C3%B3%C5%82ko_i_krzy%C5%BCyk.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Teen_shelter_near_former_coastguard_lookout,_Watchet_-_geograph.org.uk_-_1714960.jpg",
|
||||
"license": "CC-BY-SA 2.0",
|
||||
"authors": [
|
||||
"Phil Champion"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Teen_shelter_near_former_coastguard_lookout,_Watchet_-_geograph.org.uk_-_1714960.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Urbeach-high-park-splashpad.jpg",
|
||||
"license": "CC-BY-SA 3.0",
|
||||
"authors": [
|
||||
"Glogger"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Urbeach-high-park-splashpad.jpg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "Zandbakw.jpg",
|
||||
"license": "CC-BY-SA 3.0",
|
||||
"authors": [
|
||||
"Waerth"
|
||||
],
|
||||
"sources": [
|
||||
"https://commons.wikimedia.org/wiki/File:Zandbakw.jpg"
|
||||
]
|
||||
}
|
||||
]
|
337
assets/layers/playground_equipment/playground_equipment.json
Normal file
|
@ -0,0 +1,337 @@
|
|||
{
|
||||
"minzoom": 18,
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": "circle",
|
||||
"color": "white"
|
||||
},
|
||||
{
|
||||
"icon": "./assets/themes/playgrounds/playground.svg"
|
||||
}
|
||||
],
|
||||
"iconSize": "20,20"
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
{
|
||||
"render": {
|
||||
"en": "This is a {playground}"
|
||||
},
|
||||
"id": "type",
|
||||
"freeform": {
|
||||
"key": "playground",
|
||||
"placeholder": {
|
||||
"en": "Type of device"
|
||||
},
|
||||
"addExtraTags": [
|
||||
"fixme=Freeform input used"
|
||||
]
|
||||
},
|
||||
"question": {
|
||||
"en": "What kind of device is this?",
|
||||
"nl": "Wat voor speeltoestel is dit?"
|
||||
},
|
||||
"invalidValues": "playground=yes",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "playground=swing",
|
||||
"then": {
|
||||
"en": "This is a swing",
|
||||
"nl": "Dit is een schommel"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=structure",
|
||||
"then": {
|
||||
"en": "This is a structure consisting of several connected playground devices"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/SunwardCohousingPlayStructure2005.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=slide",
|
||||
"then": {
|
||||
"en": "This is a slide"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=sandpit",
|
||||
"then": {
|
||||
"en": "This is a sand pit",
|
||||
"nl": "Dit is een zandbak"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"sandbox"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Zandbakw.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=springy",
|
||||
"then": {
|
||||
"en": "This is a spring rider",
|
||||
"nl": "Dit is een veertoestel"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"springy"
|
||||
],
|
||||
"nl": [
|
||||
"wipkip"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=climbingframe",
|
||||
"then": {
|
||||
"en": "This is a climbing frame",
|
||||
"nl": "Dit is een klimrek"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"jungle gym",
|
||||
"rope spider"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/DeimosXL1.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=seesaw",
|
||||
"then": {
|
||||
"en": "This is a seesaw",
|
||||
"nl": "Dit is een wipwap"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"teeter-totter",
|
||||
"teeterboard"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Seesaw-aa.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=playhouse",
|
||||
"then": {
|
||||
"en": "This is a playhouse"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"Wendyhouse"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Playhouse.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=roundabout",
|
||||
"then": {
|
||||
"en": "This is a roundabout"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": [
|
||||
"merry-go-round"
|
||||
]
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Manually_powered_carousel_on_a_playground_in_Saint-Petersburg.JPG",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=basketswing",
|
||||
"then": {
|
||||
"en": "This is a basket swing"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Playground_swing_03.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=zipwire",
|
||||
"then": {
|
||||
"en": "This is a zip wire"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=horizontal_bar",
|
||||
"then": {
|
||||
"en": "This is a horizontal bar",
|
||||
"nl": "Dit is een rekstok"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Rekstok.JPG",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=hopscotch",
|
||||
"then": {
|
||||
"en": "This is a hopscotch"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Hinkelbaan_tegels.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=splash_pad",
|
||||
"then": {
|
||||
"en": "This is a splash pad"
|
||||
},
|
||||
"searchTerms": {
|
||||
"en": "spray pool"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Urbeach-high-park-splashpad.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=climbingwall",
|
||||
"then": {
|
||||
"en": "This is a climbing wall"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Playground_climbingwall.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=map",
|
||||
"then": {
|
||||
"en": "This is a map"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Playground_Map,_Washington_Elementary.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=bridge",
|
||||
"then": {
|
||||
"en": "This is a bridge (either as a standalone device or as part of a larger structure)"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Playground_in_Muchall_Park,_Wolverhampton_-_geograph.org.uk_-_2735437.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=cushion",
|
||||
"then": {
|
||||
"en": "This is a bouncy cushion"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Hupfkissen.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=activitypanel",
|
||||
"then": {
|
||||
"en": "This is an activity panel"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Szwedy_-_plac_zabaw_-_kotko_i_krzyzyk.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=teenshelter",
|
||||
"then": {
|
||||
"en": "This is a teen shelter"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Teen_shelter_near_former_coastguard_lookout,_Watchet_-_geograph.org.uk_-_1714960.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=funnel_ball",
|
||||
"then": {
|
||||
"en": "This is a funnel used to play with funnel ball"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Funnel_ball.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "playground=spinning_circle",
|
||||
"then": {
|
||||
"en": "This is a spinning circle"
|
||||
},
|
||||
"icon": {
|
||||
"path": "./assets/layers/playground_equipment/Spinning_circle.jpg",
|
||||
"class": "large"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builtin": "wheelchair-access",
|
||||
"override": {
|
||||
"question": {
|
||||
"en": "Is this device accessible by wheelchair?"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"width": 1,
|
||||
"color": "blue"
|
||||
}
|
||||
],
|
||||
"id": "playground_equipment",
|
||||
"name": {
|
||||
"en": "Playground equipment"
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing playground equipment"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": "playground~*"
|
||||
},
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Playground device"
|
||||
}
|
||||
},
|
||||
"allowMove": true,
|
||||
"presets": [
|
||||
{
|
||||
"tags": [
|
||||
"playground=yes"
|
||||
],
|
||||
"title": {
|
||||
"en": "a playground device"
|
||||
},
|
||||
"description": {
|
||||
"en": "An exact type is asked later"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -552,6 +552,86 @@
|
|||
}
|
||||
],
|
||||
"filter": [
|
||||
"open_now"
|
||||
"open_now",
|
||||
{
|
||||
"id": "letter_from",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Offers letter posting"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"post_office:letter_from~*",
|
||||
"post_office:letter_from!~i~no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "parcel_from",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Offers parcel posting"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"post_office:parcel_from~*",
|
||||
"post_office:parcel_from!~i~no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "parcel_pickup",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Offers pickup of missed parcels"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"post_office:parcel_pickup~*",
|
||||
"post_office:parcel_pickup!~i~no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "parcel_to",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Accepts pickup of parcels sent here"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"post_office:parcel_to~*",
|
||||
"post_office:parcel_to!~i~no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "stamps",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Sells stamps"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"post_office:stamps~*",
|
||||
"post_office:stamps!~i~no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
10
assets/layers/souvenir_coin/license_info.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"path": "souvenir_coin.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"Robin van der Linde"
|
||||
],
|
||||
"sources": []
|
||||
}
|
||||
]
|
160
assets/layers/souvenir_coin/souvenir_coin.json
Normal file
|
@ -0,0 +1,160 @@
|
|||
{
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"iconBadges": [
|
||||
{
|
||||
"if": "opening_hours~*",
|
||||
"then": "icons.isOpen"
|
||||
}
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": "circle",
|
||||
"color": "#FFFFFF00"
|
||||
},
|
||||
{
|
||||
"icon": "./assets/layers/souvenir_coin/souvenir_coin.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
"opening_hours_24_7",
|
||||
{
|
||||
"builtin": "elongated_coin.designs",
|
||||
"id": "designs",
|
||||
"override": {
|
||||
"render": {
|
||||
"en": "This machine has {coin:design_count} designs available"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "coin:design_count=1",
|
||||
"then": {
|
||||
"en": "This machine has one design available"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "coin:design_count=2",
|
||||
"then": {
|
||||
"en": "This machine has two designs available"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "coin:design_count=3",
|
||||
"then": {
|
||||
"en": "This machine has three designs available"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "coin:design_count=4",
|
||||
"then": {
|
||||
"en": "This machine has four designs available"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"payment-options-split",
|
||||
"website",
|
||||
{
|
||||
"question": {
|
||||
"en": "How much does a souvenir coin cost?"
|
||||
},
|
||||
"id": "charge",
|
||||
"render": {
|
||||
"en": "A souvenir coins costs {charge}"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "charge",
|
||||
"placeholder": {
|
||||
"en": "Cost (e.g. 2 EUR)"
|
||||
}
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "charge=2 EUR",
|
||||
"then": {
|
||||
"en": "A souvenir coin costs 2 euro"
|
||||
},
|
||||
"hideInAnswer": "_currency!~.*EUR.*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"denominations-coins",
|
||||
{
|
||||
"question": {
|
||||
"en": "Is this machine located indoors?"
|
||||
},
|
||||
"id": "indoor",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "indoor=yes",
|
||||
"then": {
|
||||
"en": "This machine is located indoors."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "indoor=no",
|
||||
"then": {
|
||||
"en": "This machine is located outdoors."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"level",
|
||||
"check_date"
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"width": 1,
|
||||
"color": "blue"
|
||||
}
|
||||
],
|
||||
"id": "souvenir_coin",
|
||||
"name": {
|
||||
"en": "Souvenir Coin Machines"
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing machines selling souvenir coins"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"amenity=vending_machine",
|
||||
"vending~.*souvenir_coins.*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Souvenir Coin Machine"
|
||||
}
|
||||
},
|
||||
"presets": [
|
||||
{
|
||||
"title": {
|
||||
"en": "a souvenir coin machine"
|
||||
},
|
||||
"description": {
|
||||
"en": "Add a machine selling souvenir coins"
|
||||
},
|
||||
"tags": [
|
||||
"amenity=vending_machine",
|
||||
"vending=souvenir_coins"
|
||||
]
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
"open_now",
|
||||
"accepts_debit_cards",
|
||||
"accepts_credit_cards"
|
||||
],
|
||||
"deletion": true,
|
||||
"allowMove": true
|
||||
}
|
9
assets/layers/souvenir_coin/souvenir_coin.svg
Normal file
|
@ -0,0 +1,9 @@
|
|||
<svg width="250" height="250" viewBox="0 0 250 250" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle cx="125" cy="125" r="121" fill="#CABFB9" stroke="#6D6662" stroke-width="8"/>
|
||||
<rect x="60" y="82.5" width="26" height="39" fill="#6D6662"/>
|
||||
<rect x="164" y="82.5" width="26" height="39" fill="#6D6662"/>
|
||||
<path d="M73 63L84.2583 82.5H61.7417L73 63Z" fill="#6D6662"/>
|
||||
<path d="M177 63L188.258 82.5H165.742L177 63Z" fill="#6D6662"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M60 121.5H190V186.5H138V160.5C138 153.32 132.18 147.5 125 147.5C117.82 147.5 112 153.32 112 160.5V186.5H60V121.5Z" fill="#6D6662"/>
|
||||
<circle cx="125" cy="125" r="109.5" stroke="#6D6662" stroke-dasharray="4 12"/>
|
||||
</svg>
|
After Width: | Height: | Size: 703 B |
2
assets/layers/souvenir_coin/souvenir_coin.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Robin van der Linde
|
||||
SPDX-License-Identifier: CC0-1.0
|
10
assets/layers/souvenir_note/license_info.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
[
|
||||
{
|
||||
"path": "souvenir_note.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"Robin van der Linde"
|
||||
],
|
||||
"sources": []
|
||||
}
|
||||
]
|
178
assets/layers/souvenir_note/souvenir_note.json
Normal file
|
@ -0,0 +1,178 @@
|
|||
{
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"iconBadges": [
|
||||
{
|
||||
"if": "opening_hours~*",
|
||||
"then": "icons.isOpen"
|
||||
}
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": "circle",
|
||||
"color": "#FFFFFF00"
|
||||
},
|
||||
{
|
||||
"icon": "./assets/layers/souvenir_note/souvenir_note.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
"opening_hours_24_7",
|
||||
{
|
||||
"id": "designs",
|
||||
"question": {
|
||||
"en": "How many designs are available?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "note:design_count",
|
||||
"type": "pnat",
|
||||
"placeholder": {
|
||||
"en": "Number of designs (e.g. 5)",
|
||||
"de": "Motivanzahl (z.B. 5)",
|
||||
"es": "Número de diseños (por ejemplo, 5)",
|
||||
"ca": "Nombre de dissenys (p. e. 5)",
|
||||
"cs": "Počet vzorů (např. 5)"
|
||||
}
|
||||
},
|
||||
"render": {
|
||||
"en": "This machine has {note:design_count} designs available."
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "note:design_count=1",
|
||||
"then": {
|
||||
"en": "This machine has one design available."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "note:design_count=2",
|
||||
"then": {
|
||||
"en": "This machine has two designs available."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "note:design_count=3",
|
||||
"then": {
|
||||
"en": "This machine has three designs available."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "note:design_count=4",
|
||||
"then": {
|
||||
"en": "This machine has four designs available."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"payment-options-split",
|
||||
"website",
|
||||
{
|
||||
"question": {
|
||||
"en": "How much does a souvenir note cost?"
|
||||
},
|
||||
"id": "charge",
|
||||
"render": {
|
||||
"en": "A souvenir note costs {charge}"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "charge",
|
||||
"placeholder": {
|
||||
"en": "Cost (e.g. 2 EUR)"
|
||||
}
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "charge=2 EUR",
|
||||
"then": {
|
||||
"en": "A souvenir note costs 2 euro"
|
||||
},
|
||||
"hideInAnswer": "_currency!~.*EUR.*"
|
||||
},
|
||||
{
|
||||
"if": "charge=3 EUR",
|
||||
"then": {
|
||||
"en": "A souvenir note costs 3 euro"
|
||||
},
|
||||
"hideInAnswer": "_currency!~.*EUR.*"
|
||||
}
|
||||
]
|
||||
},
|
||||
"denominations-coins",
|
||||
{
|
||||
"question": {
|
||||
"en": "Is this machine located indoors?"
|
||||
},
|
||||
"id": "indoor",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "indoor=yes",
|
||||
"then": {
|
||||
"en": "This machine is located indoors."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "indoor=no",
|
||||
"then": {
|
||||
"en": "This machine is located outdoors."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"level",
|
||||
"check_date"
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"width": 1,
|
||||
"color": "blue"
|
||||
}
|
||||
],
|
||||
"id": "souvenir_note",
|
||||
"name": {
|
||||
"en": "Souvenir Banknote Machines"
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing machines selling souvenir banknotes"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"amenity=vending_machine",
|
||||
"vending~.*souvenir_notes.*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Souvenir Banknote Machine"
|
||||
}
|
||||
},
|
||||
"presets": [
|
||||
{
|
||||
"title": {
|
||||
"en": "a souvenir banknote machine"
|
||||
},
|
||||
"description": {
|
||||
"en": "Add a machine selling souvenir banknotes"
|
||||
},
|
||||
"tags": [
|
||||
"amenity=vending_machine",
|
||||
"vending=souvenir_notes"
|
||||
]
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
"open_now",
|
||||
"accepts_debit_cards",
|
||||
"accepts_credit_cards"
|
||||
],
|
||||
"deletion": true,
|
||||
"allowMove": true
|
||||
}
|
12
assets/layers/souvenir_note/souvenir_note.svg
Normal file
|
@ -0,0 +1,12 @@
|
|||
<svg width="500" height="250" viewBox="0 0 500 250" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="140" height="250" fill="#F7EBF4"/>
|
||||
<rect x="140" width="360" height="250" fill="#E1BBD9"/>
|
||||
<rect x="4" y="4" width="492" height="242" stroke="black" stroke-width="8"/>
|
||||
<rect x="250" y="82.5" width="26" height="39" fill="#81576D"/>
|
||||
<rect x="354" y="82.5" width="26" height="39" fill="#81576D"/>
|
||||
<path d="M263 63L274.258 82.5H251.742L263 63Z" fill="#81576D"/>
|
||||
<path d="M367 63L378.258 82.5H355.742L367 63Z" fill="#81576D"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M250 121.5H380V186.5H328V160.5C328 153.32 322.18 147.5 315 147.5C307.82 147.5 302 153.32 302 160.5V186.5H250V121.5Z" fill="#81576D"/>
|
||||
<rect x="20" y="30" width="65" height="50" fill="#003399"/>
|
||||
<path d="M139.023 103.705C132.932 103.705 127.682 102.261 123.273 99.375C118.864 96.4659 115.466 92.2955 113.08 86.8636C110.693 81.4091 109.511 74.8523 109.534 67.1932C109.557 59.5341 110.75 53.0341 113.114 47.6932C115.5 42.3295 118.886 38.25 123.273 35.4545C127.682 32.6364 132.932 31.2273 139.023 31.2273C145.114 31.2273 150.364 32.6364 154.773 35.4545C159.205 38.25 162.614 42.3295 165 47.6932C167.386 53.0568 168.568 59.5568 168.545 67.1932C168.545 74.875 167.352 81.4432 164.966 86.8977C162.58 92.3523 159.182 96.5227 154.773 99.4091C150.386 102.273 145.136 103.705 139.023 103.705ZM139.023 89.8977C142.659 89.8977 145.602 88.0455 147.852 84.3409C150.102 80.6136 151.216 74.8977 151.193 67.1932C151.193 62.1477 150.682 57.9886 149.659 54.7159C148.636 51.4205 147.216 48.9659 145.398 47.3523C143.58 45.7386 141.455 44.9318 139.023 44.9318C135.409 44.9318 132.489 46.7614 130.261 50.4205C128.034 54.0568 126.909 59.6477 126.886 67.1932C126.864 72.3068 127.352 76.5455 128.352 79.9091C129.375 83.2727 130.807 85.7841 132.648 87.4432C134.489 89.0795 136.614 89.8977 139.023 89.8977Z" fill="#81576D"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
2
assets/layers/souvenir_note/souvenir_note.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Robin van der Linde
|
||||
SPDX-License-Identifier: CC0-1.0
|
|
@ -21,6 +21,8 @@
|
|||
"startLat": 53.0565,
|
||||
"startLon": 8.7492,
|
||||
"layers": [
|
||||
"elongated_coin"
|
||||
"elongated_coin",
|
||||
"souvenir_coin",
|
||||
"souvenir_note"
|
||||
]
|
||||
}
|
179
assets/themes/ghostsigns/ghostsigns.json
Normal file
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"id": "ghostsigns",
|
||||
"title": {
|
||||
"en": "Ghost Signs"
|
||||
},
|
||||
"description": {
|
||||
"en": "A map showing disused signs on buildings"
|
||||
},
|
||||
"icon": "./assets/themes/advertising/wall_painting.svg",
|
||||
"layers": [
|
||||
{
|
||||
"id": "ghostsigns",
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Ghost Sign"
|
||||
}
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing disused signs on buildings"
|
||||
},
|
||||
"name": {
|
||||
"en": "Ghost Signs"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"historic~*",
|
||||
"advertising=wall_painting"
|
||||
]
|
||||
}
|
||||
},
|
||||
"minzoom": 10,
|
||||
"allowMove": {
|
||||
"enableImproveAccuracy": true
|
||||
},
|
||||
"tagRenderings": [
|
||||
{
|
||||
"id": "historic",
|
||||
"question": {
|
||||
"en": "Is this a ghost sign?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "Is this sign for a business that no longer exists or no longer being maintained?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "historic=advertising",
|
||||
"then": {
|
||||
"en": "This is a ghost sign"
|
||||
},
|
||||
"alsoShowIf": "historic=yes"
|
||||
},
|
||||
{
|
||||
"if": "historic=",
|
||||
"then": {
|
||||
"en": "This is not a ghost sign, answering this will hide the sign from the map"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"images",
|
||||
{
|
||||
"id": "name",
|
||||
"condition": "name~*",
|
||||
"render": {
|
||||
"*": "{name}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "inscription",
|
||||
"question": {
|
||||
"en": "What is the text on the sign?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "inscription",
|
||||
"type": "string",
|
||||
"placeholder": {
|
||||
"en": "Text on the sign"
|
||||
}
|
||||
},
|
||||
"render": {
|
||||
"en": "The text on the sign is: {inscription}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "brand",
|
||||
"question": {
|
||||
"en": "For what business was this sign made?"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "brand",
|
||||
"type": "string",
|
||||
"placeholder": {
|
||||
"en": "Business name"
|
||||
}
|
||||
},
|
||||
"render": {
|
||||
"en": "This sign was made for: {brand}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"color": "blue",
|
||||
"width": 2
|
||||
}
|
||||
],
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": "./assets/themes/advertising/wall_painting.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"tags": [
|
||||
"historic=advertising",
|
||||
"advertising=wall_painting"
|
||||
],
|
||||
"title": {
|
||||
"en": "a ghost sign"
|
||||
},
|
||||
"snapToLayer": [
|
||||
"walls_and_buildings"
|
||||
],
|
||||
"maxSnapDistance": 5
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"builtin": "advertising",
|
||||
"override": {
|
||||
"source": {
|
||||
"osmTags": "advertising=wall_painting"
|
||||
},
|
||||
"minzoom": 18,
|
||||
"+tagRenderings": [
|
||||
{
|
||||
"id": "historic",
|
||||
"question": {
|
||||
"en": "Is this a ghost sign?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "Is this sign for a business that no longer exists or no longer being maintained?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "historic=advertising",
|
||||
"then": {
|
||||
"en": "This is a ghost sign"
|
||||
},
|
||||
"alsoShowIf": "historic=yes"
|
||||
},
|
||||
{
|
||||
"if": "historic=",
|
||||
"then": {
|
||||
"en": "This is not a ghost sign"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"=presets": [],
|
||||
"pointRendering": [
|
||||
{
|
||||
"iconSize": "20,20"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -252,6 +252,10 @@
|
|||
"if": "theme=ghostbikes",
|
||||
"then": "./assets/themes/ghostbikes/logo.svg"
|
||||
},
|
||||
{
|
||||
"if": "theme=ghostsigns",
|
||||
"then": "./assets/themes/advertising/wall_painting.svg"
|
||||
},
|
||||
{
|
||||
"if": "theme=grb",
|
||||
"then": "./assets/themes/grb/logo.svg"
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
"startLon": 4.399,
|
||||
"layers": [
|
||||
"playground",
|
||||
"playground_equipment",
|
||||
{
|
||||
"builtin": [
|
||||
"bench",
|
||||
|
|
|
@ -54,7 +54,54 @@
|
|||
"layers": [
|
||||
"postboxes",
|
||||
"postoffices",
|
||||
"parcel_lockers"
|
||||
"parcel_lockers",
|
||||
{
|
||||
"builtin": "shops",
|
||||
"override": {
|
||||
"minzoom": 18,
|
||||
"minzoomVisible": 18,
|
||||
"description": {
|
||||
"en": "Add a new post partner to the map in an existing shop"
|
||||
},
|
||||
"+tagRenderings": [
|
||||
{
|
||||
"id": "post_partner",
|
||||
"question": {
|
||||
"en": "Is this shop a post partner?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "post_office=post_partner",
|
||||
"then": {
|
||||
"en": "This shop is a post partner"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "post_office=",
|
||||
"then": {
|
||||
"en": "This shop is not a post partner"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"shownByDefault": false,
|
||||
"=presets": [
|
||||
{
|
||||
"tags": [
|
||||
"shop=yes",
|
||||
"post_office=post_partner"
|
||||
],
|
||||
"title": {
|
||||
"en": "a missing shop that is a post partner"
|
||||
},
|
||||
"description": {
|
||||
"en": "If a shop is not yet on the map and is a post partner, you can add it here."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"widenFactor": 1.5,
|
||||
"clustering": {
|
||||
|
|
|
@ -224,6 +224,10 @@
|
|||
"example": "Example",
|
||||
"examples": "Examples",
|
||||
"fewChangesBefore": "Please, answer a few questions of existing features before adding a new feature.",
|
||||
"filterPanel": {
|
||||
"disableAll": "Disable all",
|
||||
"enableAll": "Enable all"
|
||||
},
|
||||
"geopermissionDenied": "Using the geolocation was denied",
|
||||
"getStartedLogin": "Log in with OpenStreetMap to get started",
|
||||
"getStartedNewAccount": " or <a href='https://www.openstreetmap.org/user/new' target='_blank'>create a new account</a>",
|
||||
|
|
45
package-lock.json
generated
|
@ -45,6 +45,7 @@
|
|||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^3.5.0",
|
||||
"monaco-editor": "^0.46.0",
|
||||
"nano-markdown": "^1.2.2",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^2.2.0",
|
||||
|
@ -71,6 +72,7 @@
|
|||
"@babeard/svelte-heroicons": "^2.0.0-rc.0",
|
||||
"@babel/polyfill": "^7.10.4",
|
||||
"@babel/preset-env": "7.13.8",
|
||||
"@monaco-editor/loader": "^1.4.0",
|
||||
"@parcel/service-worker": "^2.6.0",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.0.2",
|
||||
|
@ -2358,6 +2360,18 @@
|
|||
"gl-style-validate": "dist/gl-style-validate.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@monaco-editor/loader": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
|
||||
"integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"state-local": "^1.0.6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"monaco-editor": ">= 0.21.0 < 1"
|
||||
}
|
||||
},
|
||||
"node_modules/@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -9450,6 +9464,11 @@
|
|||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/monaco-editor": {
|
||||
"version": "0.46.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.46.0.tgz",
|
||||
"integrity": "sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ=="
|
||||
},
|
||||
"node_modules/monotone-convex-hull-2d": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz",
|
||||
|
@ -11721,6 +11740,12 @@
|
|||
"node": ">=0.1.14"
|
||||
}
|
||||
},
|
||||
"node_modules/state-local": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
|
||||
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/std-env": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.2.tgz",
|
||||
|
@ -15579,6 +15604,15 @@
|
|||
"sort-object": "^3.0.3"
|
||||
}
|
||||
},
|
||||
"@monaco-editor/loader": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz",
|
||||
"integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"state-local": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
|
@ -20964,6 +20998,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"monaco-editor": {
|
||||
"version": "0.46.0",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.46.0.tgz",
|
||||
"integrity": "sha512-ADwtLIIww+9FKybWscd7OCfm9odsFYHImBRI1v9AviGce55QY8raT+9ihH8jX/E/e6QVSGM+pKj4jSUSRmALNQ=="
|
||||
},
|
||||
"monotone-convex-hull-2d": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz",
|
||||
|
@ -22608,6 +22647,12 @@
|
|||
"integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==",
|
||||
"optional": true
|
||||
},
|
||||
"state-local": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz",
|
||||
"integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==",
|
||||
"dev": true
|
||||
},
|
||||
"std-env": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.3.2.tgz",
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
{
|
||||
"name": "mapcomplete",
|
||||
<<<<<<< HEAD
|
||||
"version": "0.40.0",
|
||||
=======
|
||||
"version": "0.38.1",
|
||||
>>>>>>> develop
|
||||
"repository": "https://github.com/pietervdvn/MapComplete",
|
||||
"description": "A small website to edit OSM easily",
|
||||
"bugs": "https://github.com/pietervdvn/MapComplete/issues",
|
||||
|
@ -146,6 +150,7 @@
|
|||
"lz-string": "^1.4.4",
|
||||
"mangrove-reviews-typescript": "^1.1.0",
|
||||
"maplibre-gl": "^3.5.0",
|
||||
"monaco-editor": "^0.46.0",
|
||||
"nano-markdown": "^1.2.2",
|
||||
"opening_hours": "^3.6.0",
|
||||
"osm-auth": "^2.2.0",
|
||||
|
@ -172,6 +177,7 @@
|
|||
"@babeard/svelte-heroicons": "^2.0.0-rc.0",
|
||||
"@babel/polyfill": "^7.10.4",
|
||||
"@babel/preset-env": "7.13.8",
|
||||
"@monaco-editor/loader": "^1.4.0",
|
||||
"@parcel/service-worker": "^2.6.0",
|
||||
"@rollup/plugin-json": "^6.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^2.0.2",
|
||||
|
|
|
@ -777,6 +777,10 @@ video {
|
|||
float: left;
|
||||
}
|
||||
|
||||
.m-8 {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.m-4 {
|
||||
margin: 1rem;
|
||||
}
|
||||
|
@ -789,10 +793,6 @@ video {
|
|||
margin: 0px;
|
||||
}
|
||||
|
||||
.m-8 {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.m-2 {
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
@ -896,6 +896,10 @@ video {
|
|||
margin-right: 4rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.mt-4 {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
@ -928,10 +932,6 @@ video {
|
|||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.ml-1 {
|
||||
margin-left: 0.25rem;
|
||||
}
|
||||
|
@ -1127,14 +1127,14 @@ video {
|
|||
height: 50%;
|
||||
}
|
||||
|
||||
.h-7 {
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.h-3 {
|
||||
height: 0.75rem;
|
||||
}
|
||||
|
||||
.h-7 {
|
||||
height: 1.75rem;
|
||||
}
|
||||
|
||||
.h-11 {
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
@ -1163,6 +1163,10 @@ video {
|
|||
height: 20rem;
|
||||
}
|
||||
|
||||
.h-5\/6 {
|
||||
height: 83.333333%;
|
||||
}
|
||||
|
||||
.h-56 {
|
||||
height: 14rem;
|
||||
}
|
||||
|
@ -1233,14 +1237,14 @@ video {
|
|||
width: 1rem;
|
||||
}
|
||||
|
||||
.w-7 {
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
.w-3 {
|
||||
width: 0.75rem;
|
||||
}
|
||||
|
||||
.w-7 {
|
||||
width: 1.75rem;
|
||||
}
|
||||
|
||||
.w-11 {
|
||||
width: 2.75rem;
|
||||
}
|
||||
|
@ -1266,6 +1270,14 @@ video {
|
|||
width: 4rem;
|
||||
}
|
||||
|
||||
.w-5\/6 {
|
||||
width: 83.333333%;
|
||||
}
|
||||
|
||||
.w-1\/6 {
|
||||
width: 16.666667%;
|
||||
}
|
||||
|
||||
.w-min {
|
||||
width: -webkit-min-content;
|
||||
width: min-content;
|
||||
|
|
|
@ -69,6 +69,30 @@ interface CategoryQueryAPIResponse {
|
|||
}
|
||||
}
|
||||
|
||||
interface ImagesQueryAPIResponse {
|
||||
continue: {
|
||||
imcontinue: string
|
||||
continue: string
|
||||
}
|
||||
query: {
|
||||
normalized?: {
|
||||
from: string
|
||||
to: string
|
||||
}[]
|
||||
pages: {
|
||||
[key: string]: {
|
||||
pageid: number
|
||||
ns: number
|
||||
title: string
|
||||
images?: {
|
||||
ns: number
|
||||
title: string
|
||||
}[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface TemplateQueryAPIResponse {
|
||||
batchcomplete: string
|
||||
query: {
|
||||
|
@ -96,13 +120,14 @@ const licenseMapping = {}
|
|||
// Map template names to license names
|
||||
const templateMapping = {
|
||||
"Template:PD": "Public Domain",
|
||||
"Template:CC0": "CC0 1.0",
|
||||
}
|
||||
|
||||
async function main(args: string[]) {
|
||||
if (args.length < 2) {
|
||||
console.log("Usage: downloadCommons.ts <output folder> <url> <?url> <?url> .. ")
|
||||
console.log(
|
||||
"Example: npx vite-node downloadCommons.ts -- assets/svg https://commons.wikimedia.org/wiki/File:Example.jpg"
|
||||
"Example: npx vite-node scripts/downloadCommons.ts -- assets/svg https://commons.wikimedia.org/wiki/File:Example.jpg"
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
|
@ -128,8 +153,24 @@ async function main(args: string[]) {
|
|||
for (const member of apiDetails.query.categorymembers) {
|
||||
await downloadImage(member.title, outputFolder, baseUrl)
|
||||
}
|
||||
} else {
|
||||
} else if (url.includes("File:")) {
|
||||
await downloadImage(commonsFileName, outputFolder, baseUrl)
|
||||
} else {
|
||||
// Probably a page url, try to get all images from the page
|
||||
const apiUrl = `${baseUrl}/w/api.php?action=query&format=json&prop=images&titles=${commonsFileName}&imlimit=250`
|
||||
const response = await fetch(apiUrl)
|
||||
const apiDetails: ImagesQueryAPIResponse = await response.json()
|
||||
const page = apiDetails.query.pages[Object.keys(apiDetails.query.pages)[0]]
|
||||
if (page.images) {
|
||||
for (const image of page.images) {
|
||||
await downloadImage(image.title, outputFolder, baseUrl)
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
"\x1b[31m%s\x1b[0m",
|
||||
`URL ${url} doesn't seem to contain any images! Skipping...`
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(
|
||||
|
@ -154,6 +195,12 @@ async function downloadImage(filename: string, outputFolder: string, baseUrl: st
|
|||
const apiDetails: ImageQueryAPIResponse = await response.json()
|
||||
const missingPage = apiDetails.query.pages["-1"]
|
||||
|
||||
// Check if the local file already exists, if it does, skip it
|
||||
if (existsSync(`${outputFolder}/${filename}`)) {
|
||||
console.log(`\x1b[33m%s\x1b[0m`, `${filename} already exists, skipping...`)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the file exists, locally or externally
|
||||
if (missingPage !== undefined) {
|
||||
// Image does not exist locally, check if it exists externally
|
||||
|
@ -271,8 +318,8 @@ async function downloadImage(filename: string, outputFolder: string, baseUrl: st
|
|||
// Save the license information
|
||||
const licenseInfo: SmallLicense = {
|
||||
path: cleanFileName,
|
||||
license: licenseMapping[license] || license,
|
||||
authors: [author],
|
||||
license: licenseMapping[license] || license.replace("CC BY", "CC-BY"),
|
||||
authors: [removeLinks(author)],
|
||||
sources: [wikiUrl],
|
||||
}
|
||||
|
||||
|
@ -293,4 +340,9 @@ async function downloadImage(filename: string, outputFolder: string, baseUrl: st
|
|||
}
|
||||
}
|
||||
|
||||
function removeLinks(text: string): string {
|
||||
// Remove <a> tags
|
||||
return text.replace(/<a.*?>(.*?)<\/a>/g, "$1")
|
||||
}
|
||||
|
||||
main(process.argv.slice(2))
|
||||
|
|
|
@ -5,7 +5,7 @@ import ScriptUtils from "./ScriptUtils"
|
|||
import Script from "./Script"
|
||||
|
||||
const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"]
|
||||
|
||||
const ignoreTerms = ["searchTerms"]
|
||||
class TranslationPart {
|
||||
contents: Map<string, TranslationPart | string> = new Map<string, TranslationPart | string>()
|
||||
|
||||
|
@ -49,6 +49,7 @@ class TranslationPart {
|
|||
if (!translations.hasOwnProperty(translationsKey)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const v = translations[translationsKey]
|
||||
if (typeof v != "string") {
|
||||
console.error(
|
||||
|
@ -106,6 +107,9 @@ class TranslationPart {
|
|||
if (!object.hasOwnProperty(key)) {
|
||||
continue
|
||||
}
|
||||
if (ignoreTerms.indexOf(key) >= 0) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (dontTranslateKeys?.indexOf(key) >= 0) {
|
||||
continue
|
||||
|
|
|
@ -9,7 +9,7 @@ export class Server {
|
|||
handle: {
|
||||
mustMatch: string | RegExp
|
||||
mimetype: string
|
||||
handle: (path: string) => Promise<string>
|
||||
handle: (path: string, queryParams: URLSearchParams) => Promise<string>
|
||||
}[]
|
||||
) {
|
||||
handle.push({
|
||||
|
@ -89,7 +89,7 @@ export class Server {
|
|||
}
|
||||
|
||||
try {
|
||||
const result = await handler.handle(path)
|
||||
const result = await handler.handle(path, url.searchParams)
|
||||
res.writeHead(200, { "Content-Type": handler.mimetype })
|
||||
res.write(result)
|
||||
res.end()
|
||||
|
|
43
scripts/serverLdScrape.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import Script from "../scripts/Script"
|
||||
import { Server } from "../scripts/server"
|
||||
import { Utils } from "../src/Utils"
|
||||
import parse from "node-html-parser"
|
||||
class ServerLdScrape extends Script {
|
||||
constructor() {
|
||||
super("Starts a server which fetches a webpage and returns embedded LD+JSON")
|
||||
}
|
||||
async main(args: string[]): Promise<void> {
|
||||
const port = Number(args[0] ?? 2346)
|
||||
new Server(port, {}, [
|
||||
{
|
||||
mustMatch: "extractgraph",
|
||||
mimetype: "application/ld+json",
|
||||
async handle(content, searchParams: URLSearchParams) {
|
||||
const url = searchParams.get("url")
|
||||
const dloaded = await Utils.download(url, {
|
||||
"User-Agent":
|
||||
"MapComplete/openstreetmap scraper; pietervdvn@posteo.net; https://github.com/pietervdvn/MapComplete",
|
||||
})
|
||||
const parsed = parse(dloaded)
|
||||
const scripts = Array.from(parsed.getElementsByTagName("script"))
|
||||
const snippets = []
|
||||
for (const script of scripts) {
|
||||
const tp = script.attributes["type"]
|
||||
if (tp !== "application/ld+json") {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
snippets.push(JSON.parse(script.textContent))
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
return JSON.stringify(snippets)
|
||||
},
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
new ServerLdScrape().run()
|
|
@ -8,6 +8,9 @@
|
|||
let _c: boolean = selected.data ?? true
|
||||
let id = `checkbox-input-${Math.round(Math.random()*100000000)}`
|
||||
$: selected.set(_c)
|
||||
selected.addCallbackD(s => {
|
||||
_c = s
|
||||
})
|
||||
</script>
|
||||
|
||||
<label class="no-image-background flex items-center gap-1">
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
window.setTimeout(() => tabElements[tab.data].click(), 50)
|
||||
}
|
||||
}
|
||||
export function getTab() {
|
||||
return tab
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="tabbedgroup flex h-full w-full">
|
||||
|
|
|
@ -1,17 +1,49 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* THe panel containing all filter- and layerselection options
|
||||
*/
|
||||
/**
|
||||
* THe panel containing all filter- and layerselection options
|
||||
*/
|
||||
|
||||
import OverlayToggle from "./OverlayToggle.svelte"
|
||||
import Filterview from "./Filterview.svelte"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Filter from "../../assets/svg/Filter.svelte"
|
||||
import OverlayToggle from "./OverlayToggle.svelte"
|
||||
import Filterview from "./Filterview.svelte"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import Filter from "../../assets/svg/Filter.svelte"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let layout = state.layout
|
||||
export let state: ThemeViewState
|
||||
let layout = state.layout
|
||||
|
||||
let allEnabled : boolean
|
||||
let allDisabled: boolean
|
||||
|
||||
function updateEnableState(){
|
||||
allEnabled = true
|
||||
allDisabled = true
|
||||
state.layerState.filteredLayers.forEach((v) => {
|
||||
if(!v.layerDef.name){
|
||||
return
|
||||
}
|
||||
allEnabled &&= v.isDisplayed.data
|
||||
allDisabled &&= !v.isDisplayed.data
|
||||
})
|
||||
}
|
||||
|
||||
updateEnableState()
|
||||
state.layerState.filteredLayers.forEach((v) => {
|
||||
if(!v.layerDef.name){
|
||||
return
|
||||
}
|
||||
v.isDisplayed.addCallbackD(_ => updateEnableState())
|
||||
})
|
||||
function enableAll(doEnable: boolean){
|
||||
state.layerState.filteredLayers.forEach((v) => {
|
||||
if(!v.layerDef.name){
|
||||
return
|
||||
}
|
||||
v.isDisplayed.setData(doEnable)
|
||||
})
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="m-2 flex flex-col">
|
||||
|
@ -27,6 +59,15 @@
|
|||
highlightedLayer={state.guistate.highlightedLayerInFilters}
|
||||
/>
|
||||
{/each}
|
||||
<div class="flex self-end mt-1">
|
||||
<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}
|
||||
|
|
|
@ -13,14 +13,15 @@
|
|||
import SchemaBasedInput from "./SchemaBasedInput.svelte"
|
||||
import FloatOver from "../Base/FloatOver.svelte"
|
||||
import TagRenderingInput from "./TagRenderingInput.svelte"
|
||||
import FromHtml from "../Base/FromHtml.svelte"
|
||||
import AllTagsPanel from "../Popup/AllTagsPanel.svelte"
|
||||
import QuestionPreview from "./QuestionPreview.svelte"
|
||||
import ShowConversionMessages from "./ShowConversionMessages.svelte"
|
||||
import RawEditor from "./RawEditor.svelte"
|
||||
|
||||
const layerSchema: ConfigMeta[] = <any>layerSchemaRaw
|
||||
|
||||
export let state: EditLayerState
|
||||
|
||||
export let backToStudio: () => void
|
||||
let messages = state.messages
|
||||
let hasErrors = messages.mapD(
|
||||
|
@ -59,7 +60,7 @@
|
|||
}
|
||||
|
||||
let requiredFields = ["id", "name", "description", "source"]
|
||||
let currentlyMissing = state.configuration.map((config) => {
|
||||
let currentlyMissing = configuration.map((config) => {
|
||||
if (!config) {
|
||||
return []
|
||||
}
|
||||
|
@ -184,33 +185,34 @@
|
|||
<Region configs={perRegion["expert"]} {state} />
|
||||
</div>
|
||||
<div slot="title5">Configuration file</div>
|
||||
<div slot="content5">
|
||||
<div slot="content5" class="flex h-full flex-col">
|
||||
<div>
|
||||
Below, you'll find the raw configuration file in `.json`-format. This is mostly for
|
||||
debugging purposes
|
||||
debugging purposes, but you can also edit the file directly if you want.
|
||||
</div>
|
||||
<div class="literal-code">
|
||||
<FromHtml src={JSON.stringify($configuration, null, " ").replaceAll("\n", "</br>")} />
|
||||
</div>
|
||||
|
||||
<ShowConversionMessages messages={$messages} />
|
||||
<div>
|
||||
The testobject (which is used to render the questions in the 'information panel' item
|
||||
has the following tags:
|
||||
</div>
|
||||
<div class="flex h-full w-full flex-row justify-between overflow-y-auto">
|
||||
<div class="literal-code h-full w-5/6 overflow-y-auto">
|
||||
<RawEditor {state} />
|
||||
</div>
|
||||
<div class="h-full w-1/6">
|
||||
<div>
|
||||
The testobject (which is used to render the questions in the 'information panel'
|
||||
item has the following tags:
|
||||
</div>
|
||||
|
||||
<AllTagsPanel tags={state.testTags} />
|
||||
<AllTagsPanel tags={state.testTags} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TabbedGroup>
|
||||
</div>
|
||||
{#if $highlightedItem !== undefined}
|
||||
<FloatOver on:close={() => highlightedItem.setData(undefined)}>
|
||||
<div>
|
||||
<TagRenderingInput
|
||||
path={$highlightedItem.path}
|
||||
{state}
|
||||
schema={$highlightedItem.schema}
|
||||
/>
|
||||
<TagRenderingInput path={$highlightedItem.path} {state} />
|
||||
<!--
|
||||
schema={$highlightedItem.schema} -->
|
||||
</div>
|
||||
</FloatOver>
|
||||
{/if}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import TabbedGroup from "../Base/TabbedGroup.svelte"
|
||||
import ShowConversionMessages from "./ShowConversionMessages.svelte"
|
||||
import Region from "./Region.svelte"
|
||||
import RawEditor from "./RawEditor.svelte"
|
||||
|
||||
export let state: EditThemeState
|
||||
let schema: ConfigMeta[] = state.schema.filter((schema) => schema.path.length > 0)
|
||||
|
@ -50,7 +51,7 @@
|
|||
</div>
|
||||
|
||||
<div class="m4 h-full overflow-y-auto">
|
||||
{Object.keys(perRegion).join(";")}
|
||||
<!-- {Object.keys(perRegion).join(";")} -->
|
||||
<TabbedGroup>
|
||||
<div slot="title0">Basic properties</div>
|
||||
<div slot="content0">
|
||||
|
@ -73,12 +74,15 @@
|
|||
</div>
|
||||
|
||||
<div slot="title4">Configuration file</div>
|
||||
<div slot="content4">
|
||||
<div class="literal-code">
|
||||
{JSON.stringify($config)}
|
||||
<div slot="content4" class="flex h-full flex-col">
|
||||
<div>
|
||||
Below, you'll find the raw configuration file in `.json`-format. This is mostly for
|
||||
debugging purposes, but you can also edit the file directly if you want.
|
||||
</div>
|
||||
|
||||
<ShowConversionMessages messages={$messages} />
|
||||
<div class="literal-code h-full w-full">
|
||||
<RawEditor {state} />
|
||||
</div>
|
||||
</div>
|
||||
</TabbedGroup>
|
||||
</div>
|
||||
|
|
101
src/UI/Studio/RawEditor.svelte
Normal file
|
@ -0,0 +1,101 @@
|
|||
<script lang="ts">
|
||||
import { onDestroy, onMount } from "svelte"
|
||||
import EditLayerState, { EditThemeState } from "./EditLayerState"
|
||||
import loader from "@monaco-editor/loader"
|
||||
import type * as Monaco from "monaco-editor/esm/vs/editor/editor.api"
|
||||
import layerSchemaJSON from "../../../Docs/Schemas/LayerConfigJson.schema.json"
|
||||
import layoutSchemaJSON from "../../../Docs/Schemas/LayoutConfigJson.schema.json"
|
||||
|
||||
export let state: EditLayerState | EditThemeState
|
||||
|
||||
let container: HTMLDivElement
|
||||
let monaco: typeof Monaco
|
||||
let editor: Monaco.editor.IStandaloneCodeEditor
|
||||
let model: Monaco.editor.ITextModel
|
||||
|
||||
function save() {
|
||||
try {
|
||||
const newConfig = JSON.parse(editor.getValue())
|
||||
state.configuration.setData(newConfig)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
// Catch keyboard shortcuts
|
||||
onMount(() => {
|
||||
const handler = (e: KeyboardEvent) => {
|
||||
if (e.key === "s" && (e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault()
|
||||
save()
|
||||
}
|
||||
}
|
||||
window.addEventListener("keydown", handler)
|
||||
return () => window.removeEventListener("keydown", handler)
|
||||
})
|
||||
|
||||
onMount(async () => {
|
||||
const monacoEditor = await import("monaco-editor")
|
||||
loader.config({
|
||||
monaco: monacoEditor.default,
|
||||
})
|
||||
|
||||
monaco = await loader.init()
|
||||
|
||||
// Determine schema based on the state
|
||||
let schemaUri: string
|
||||
if (state instanceof EditLayerState) {
|
||||
schemaUri = "https://mapcomplete.org/schemas/layerconfig.json"
|
||||
} else {
|
||||
schemaUri = "https://mapcomplete.org/schemas/layoutconfig.json"
|
||||
}
|
||||
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
schemas: [
|
||||
{
|
||||
uri: schemaUri,
|
||||
fileMatch: ["file.json"],
|
||||
schema:
|
||||
schemaUri === "https://mapcomplete.org/schemas/layerconfig.json"
|
||||
? layerSchemaJSON
|
||||
: layoutSchemaJSON,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
let modelUri = monaco.Uri.parse("inmemory://inmemory/file.json")
|
||||
|
||||
// Create a new model
|
||||
model = monaco.editor.createModel(
|
||||
JSON.stringify(state.configuration.data, null, " "),
|
||||
"json",
|
||||
modelUri
|
||||
)
|
||||
|
||||
editor = monaco.editor.create(container, {
|
||||
model,
|
||||
automaticLayout: true,
|
||||
})
|
||||
|
||||
// When the editor is changed, update the configuration, but only if the user hasn't typed for 500ms and the JSON is valid
|
||||
let timeout: number
|
||||
editor.onDidChangeModelContent(() => {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => {
|
||||
save()
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
if (editor) {
|
||||
editor.dispose()
|
||||
}
|
||||
if (model) {
|
||||
model.dispose()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<div bind:this={container} class="h-full w-full" />
|