forked from MapComplete/MapComplete
Merge branch 'develop'
This commit is contained in:
commit
bcd9709a49
226 changed files with 5901 additions and 1878 deletions
|
@ -53,9 +53,11 @@ jobs:
|
|||
cd android/app
|
||||
# We assign the version code simply based on the date
|
||||
new_version_code=$(( ( $(date +%s) - $(date -d "2025-07-01" +%s) ) / 86400 ))
|
||||
new_version_code=$(( 1949 + $new_version_code )) # see https://source.mapcomplete.org/MapComplete/MapComplete/issues/2520
|
||||
versionname="${{ github.ref_name }}"
|
||||
versionname="${versionname:1}"
|
||||
sed -i "s/versionCode $version_code/versionCode $new_version_code/" "build.gradle"
|
||||
echo "Versioncode will be $new_version_code ; versionname is $versionname"
|
||||
sed -i "s/versionCode .*$/versionCode $new_version_code/" "build.gradle"
|
||||
sed -i "s/versionName \".*\"/versionName \"$versionname\"/" "build.gradle"
|
||||
cat build.gradle | grep "versionName"
|
||||
cat build.gradle | grep "versionCode"
|
||||
|
|
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
@ -60,5 +60,10 @@
|
|||
"type": "Gitea",
|
||||
"name": "MapComplete Forgejo"
|
||||
}
|
||||
]
|
||||
],
|
||||
"explorer.fileNesting.enabled": true,
|
||||
"explorer.fileNesting.patterns": {
|
||||
"*": "${capture}.license"
|
||||
},
|
||||
"explorer.fileNesting.expand": false
|
||||
}
|
||||
|
|
57
CHANGELOG.md
57
CHANGELOG.md
|
@ -2,6 +2,63 @@
|
|||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
### [0.55.7](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.55.6...v0.55.7) (2025-09-02)
|
||||
|
||||
### [0.55.6](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.55.5...v0.55.6) (2025-09-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add 'download app' item into the menu drawer (if not on Android) ([0a0d3dc](https://source.mapcomplete.org/MapComplete/MapComplete/commits/0a0d3dc8dab91862b93974639a68e1b89ad5789c))
|
||||
* add avatar with offline support ([f671cd3](https://source.mapcomplete.org/MapComplete/MapComplete/commits/f671cd342fd84a669104b2e0f452b450b0329ea4))
|
||||
* add multiTitle, better error handling, improve help text of script ([0d33e18](https://source.mapcomplete.org/MapComplete/MapComplete/commits/0d33e18a593dd6527465cd5e86b2506fceb4d1ed))
|
||||
* include (all) sign languages in the 'LanguageElement' special rendering ([fe31af4](https://source.mapcomplete.org/MapComplete/MapComplete/commits/fe31af4b15446fc7787ba3e2ecc677c46d6c8de2))
|
||||
* offline: more features to be able to work fully offline ([06aa8a3](https://source.mapcomplete.org/MapComplete/MapComplete/commits/06aa8a34061ec1e607b8f0de4ab8cf12213b8dae))
|
||||
* **offline:** attempt to upload pictures when connection is restored ([dd0ed24](https://source.mapcomplete.org/MapComplete/MapComplete/commits/dd0ed24f3b4425676d6f85a4467bb7c1662459fd))
|
||||
* **offline:** better support for making changes while offline ([7155cd7](https://source.mapcomplete.org/MapComplete/MapComplete/commits/7155cd7f6184073bf641f1524ae438a803710b94))
|
||||
* **offline:** don't attempt to upload images if offline ([f1da972](https://source.mapcomplete.org/MapComplete/MapComplete/commits/f1da97285fe68c72b13299ebc97c28428fc95230))
|
||||
* **offline:** more offline hardening ([561e4cb](https://source.mapcomplete.org/MapComplete/MapComplete/commits/561e4cb00990cb1e1e38f9459ff858256b9acfaf))
|
||||
* **offline:** reload data of current view when internet is restored, see [#2111](https://source.mapcomplete.org/MapComplete/MapComplete/issues/2111) ([e44cf02](https://source.mapcomplete.org/MapComplete/MapComplete/commits/e44cf029bdbf50810579b1ae8d7aedfdf63d3df4))
|
||||
* **offline:** UX: add icon ([a5bab8d](https://source.mapcomplete.org/MapComplete/MapComplete/commits/a5bab8d819082dee354eed1fc7bcac998c4f49ab))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* check for type in TagLink ([bd3c266](https://source.mapcomplete.org/MapComplete/MapComplete/commits/bd3c266a4d1ce344b613431e5704a91207347b8c))
|
||||
* fix 'non-loading' due to incorrect caching in service worker ([f6d6ec9](https://source.mapcomplete.org/MapComplete/MapComplete/commits/f6d6ec98859de5665fa0e2a048ebfe92e4f924c0))
|
||||
* fix [#2509](https://source.mapcomplete.org/MapComplete/MapComplete/issues/2509) ([aed6def](https://source.mapcomplete.org/MapComplete/MapComplete/commits/aed6defa168030fb7947271df068fe5feb0b0ba2))
|
||||
* fix crash ([a570e29](https://source.mapcomplete.org/MapComplete/MapComplete/commits/a570e292423785dd7532feb28facc46e4ade5e6d))
|
||||
* fix crash in GRB theme when replacing geometry ([3c5a528](https://source.mapcomplete.org/MapComplete/MapComplete/commits/3c5a528307db102ff24d9d3b82b884bca58ad4c3))
|
||||
* fix crash in GRB theme when replacing geometry ([6e1aaf6](https://source.mapcomplete.org/MapComplete/MapComplete/commits/6e1aaf6be1950a50eee8c01ade244821bb221563))
|
||||
* fix showing splitpoint icons ([9da10a9](https://source.mapcomplete.org/MapComplete/MapComplete/commits/9da10a9b32f91b11fbeafac2d63b7b5d66a1e737))
|
||||
* fix small typing issues ([fd5e390](https://source.mapcomplete.org/MapComplete/MapComplete/commits/fd5e39065d4d6381838b718d34f75d02372f66a1))
|
||||
* fix tests ([42f07bc](https://source.mapcomplete.org/MapComplete/MapComplete/commits/42f07bc1f3f64a63ce7dec0bf22a4a1e5bdbd42f))
|
||||
* fix tests ([8f776bf](https://source.mapcomplete.org/MapComplete/MapComplete/commits/8f776bf0306338f0bac36db20006f7c26ac49f92))
|
||||
* fix tests ([b81f597](https://source.mapcomplete.org/MapComplete/MapComplete/commits/b81f59779dea74ca9c01f8d7df30844d29ec01ae))
|
||||
* panoramax attribution now filters out empty strings (for some edge cases on non-mapcomplete panoramax servers) ([17f0978](https://source.mapcomplete.org/MapComplete/MapComplete/commits/17f097851aafeb4db9c8cc0590abde9efe8bf599))
|
||||
* split values for tag2link ([36b3faf](https://source.mapcomplete.org/MapComplete/MapComplete/commits/36b3faf2d14bf174545d437705a17d3c2917c643))
|
||||
|
||||
|
||||
### Theme improvements
|
||||
|
||||
* **hut:** move 'hut' above shelter, steal shelter type question, also see [#2515](https://source.mapcomplete.org/MapComplete/MapComplete/issues/2515) ([3da62f8](https://source.mapcomplete.org/MapComplete/MapComplete/commits/3da62f8d708c73cd72868db0206ed90cea2b6b98))
|
||||
* move shelter filter to filters ([eb317d0](https://source.mapcomplete.org/MapComplete/MapComplete/commits/eb317d0bdabb0e5cf1dc4a871d65757a432c4de3))
|
||||
* **nature:** Add picnic sites ([#1849](https://source.mapcomplete.org/MapComplete/MapComplete/issues/1849)) ([4294e49](https://source.mapcomplete.org/MapComplete/MapComplete/commits/4294e4930509bb8157597d3d6242046a5fa14e8d))
|
||||
* New arcade theme ([2c65747](https://source.mapcomplete.org/MapComplete/MapComplete/commits/2c6574762c30d60440806ace3f9e3320f771c9a4))
|
||||
* **parking:** Add support for access tags ([#1797](https://source.mapcomplete.org/MapComplete/MapComplete/issues/1797)) ([03d07b6](https://source.mapcomplete.org/MapComplete/MapComplete/commits/03d07b670de7fa84c0e58f647073f67fb6d60046))
|
||||
* **parkings:** Add charge points ([c0ee578](https://source.mapcomplete.org/MapComplete/MapComplete/commits/c0ee578df1b0db3c9670b6c8f722787e6a9b72f3))
|
||||
* **preset_type_select:** fix 'auto-icon' display ([81f98e6](https://source.mapcomplete.org/MapComplete/MapComplete/commits/81f98e62ceec6313256a7864822225efb0b772d1))
|
||||
* **preset_type_select:** preset type select now removes keys set by other presets ([152d93b](https://source.mapcomplete.org/MapComplete/MapComplete/commits/152d93bf4bdc73e4d331e2718181599ccf9a18b1))
|
||||
* **range:** change rendering ([e9f7192](https://source.mapcomplete.org/MapComplete/MapComplete/commits/e9f71924c14bc9d3b9940060775d8edc8311225c))
|
||||
* **shops:** Add self_checkout question ([2cf0bc1](https://source.mapcomplete.org/MapComplete/MapComplete/commits/2cf0bc1866cd8df4bc7006b29a5f49210761ccb3))
|
||||
* **shops:** change conditions for self_checkout question ([aecc36d](https://source.mapcomplete.org/MapComplete/MapComplete/commits/aecc36dfbe0972eec5f76d11a5b526a1992ecb2c))
|
||||
* **shops:** Exlcude shop=no ([06ac28d](https://source.mapcomplete.org/MapComplete/MapComplete/commits/06ac28dab98777ba91c06ec46800f08c52d14bdc))
|
||||
* **shops:** Remove brand tags if marked as without brand ([877dd26](https://source.mapcomplete.org/MapComplete/MapComplete/commits/877dd260aed3a21ffbb1f638b07e35277df835b6))
|
||||
* **surveillance:** add some tweaks to the 'panorama'-camera ([db62329](https://source.mapcomplete.org/MapComplete/MapComplete/commits/db62329d396e067dcb2155a7deed2e466065e383))
|
||||
* **width:** add cyclestreet indication, add icons ([67c5322](https://source.mapcomplete.org/MapComplete/MapComplete/commits/67c5322a80067acb911eb99f6ec876763039f61f))
|
||||
* **width:** add note if street are low on cars, hide 'unknown'-layer by default, add 'separate' as recognized parking type ([9a2b5d0](https://source.mapcomplete.org/MapComplete/MapComplete/commits/9a2b5d0cf7021d369f85b51779cc73ac8c6159fa))
|
||||
* **zhv:** fix broken import ([40bd564](https://source.mapcomplete.org/MapComplete/MapComplete/commits/40bd564f864a73e4b9f476e3347c22134cf3f79b))
|
||||
|
||||
### [0.55.5](https://source.mapcomplete.org/MapComplete/MapComplete/compare/v0.55.4...v0.55.5) (2025-08-19)
|
||||
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@ General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_nam
|
|||
- [UI](#ui)
|
||||
+ [braced](#braced)
|
||||
+ [create_copy](#create_copy)
|
||||
+ [preset_description](#preset_description)
|
||||
+ [show_icons](#show_icons)
|
||||
+ [title](#title)
|
||||
+ [translated](#translated)
|
||||
- [data](#data)
|
||||
|
@ -81,15 +79,13 @@ General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_nam
|
|||
- [tagrendering_manipulation](#tagrendering_manipulation)
|
||||
+ [group](#group)
|
||||
+ [multi](#multi)
|
||||
+ [open_in_iD](#open_in_id)
|
||||
+ [open_in_josm](#open_in_josm)
|
||||
+ [steal](#steal)
|
||||
- [ui](#ui)
|
||||
+ [preset_type_select](#preset_type_select)
|
||||
- [web_and_communication](#web_and_communication)
|
||||
+ [fediverse_link](#fediverse_link)
|
||||
+ [link](#link)
|
||||
+ [mapillary_link](#mapillary_link)
|
||||
+ [open_in_iD](#open_in_id)
|
||||
+ [open_in_josm](#open_in_josm)
|
||||
+ [send_email](#send_email)
|
||||
+ [wikidata_label](#wikidata_label)
|
||||
+ [wikipedia](#wikipedia)
|
||||
|
@ -99,6 +95,8 @@ General usage is `{func_name()}`, `{func_name(arg, someotherarg)}` or `{func_nam
|
|||
+ [histogram](#histogram)
|
||||
+ [language_chooser](#language_chooser)
|
||||
+ [multi_apply](#multi_apply)
|
||||
+ [preset_description](#preset_description)
|
||||
+ [preset_type_select](#preset_type_select)
|
||||
+ [upload_to_osm](#upload_to_osm)
|
||||
|
||||
# Using expanded syntax
|
||||
|
@ -142,7 +140,8 @@ Show a literal text within braces
|
|||
-----|-----|----- |
|
||||
| text | _undefined_ | The value to show |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L296](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L296)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L295](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L295)
|
||||
|
||||
#### Example usage of braced
|
||||
|
||||
|
@ -152,42 +151,19 @@ Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L296](/src/
|
|||
|
||||
Allow to create a copy of the current element
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L315](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L315)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L314](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L314)
|
||||
|
||||
#### Example usage of create_copy
|
||||
|
||||
`{create_copy()}`
|
||||
|
||||
### preset_description
|
||||
|
||||
Shows the extra description from the presets of the layer, if one matches. It will pick the most specific one (e.g. if preset `A` implies `B`, but `B` does not imply `A`, it'll pick B) or the first one if no ordering can be made. Might be empty
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L215](/src/UI/Popup/DataVisualisations.ts#L215)
|
||||
|
||||
#### Example usage of preset_description
|
||||
|
||||
`{preset_description()}`
|
||||
|
||||
### show_icons
|
||||
|
||||
Displays all icons from the specified tagRenderings (if they are known and have an icon) together, e.g. to give a summary of the dietary options
|
||||
|
||||
| name | default | description |
|
||||
-----|-----|----- |
|
||||
| labels | _undefined_ | A ';'-separated list of labels and/or ids of tagRenderings |
|
||||
| class | inline-flex mx-4 | CSS-classes of the container, space-separated |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L307](/src/UI/Popup/DataVisualisations.ts#L307)
|
||||
|
||||
#### Example usage of show_icons
|
||||
|
||||
`{show_icons(,inline-flex mx-4)}`
|
||||
|
||||
### title
|
||||
|
||||
Shows the title of the popup. Useful for some cases, e.g. 'What is phone number of {title()}?'
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L281](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L281)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L280](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L280)
|
||||
|
||||
#### Example usage of title
|
||||
|
||||
|
@ -201,7 +177,8 @@ If the given key can be interpreted as a JSON, only show the key containing the
|
|||
-----|-----|----- |
|
||||
| key | value | The attribute to interpret as json |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L251](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L251)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L250](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L250)
|
||||
|
||||
#### Example usage of translated
|
||||
|
||||
|
@ -215,7 +192,7 @@ Visualises data of a POI, sometimes with data updating capabilities
|
|||
|
||||
Prints all key-value pairs of the object - used for debugging
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L270](/src/UI/Popup/DataVisualisations.ts#L270)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L263](/src/UI/Popup/DataVisualisations.ts#L263)
|
||||
|
||||
#### Example usage of all_tags
|
||||
|
||||
|
@ -229,7 +206,7 @@ Converts a short, canonical value into the long, translated text including the u
|
|||
-----|-----|----- |
|
||||
| key | _undefined_ | The key of the tag to give the canonical text for |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L163](/src/UI/Popup/DataVisualisations.ts#L163)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L155](/src/UI/Popup/DataVisualisations.ts#L155)
|
||||
|
||||
#### Example usage of canonical
|
||||
|
||||
|
@ -244,7 +221,7 @@ Converts compass degrees (with 0° being north, 90° being east, ...) into a hum
|
|||
| key | _direction:centerpoint | The attribute containing the degrees |
|
||||
| offset | 0 | Offset value that is added to the actual value, e.g. `180` to indicate the opposite (backward) direction |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L47](/src/UI/Popup/DataVisualisations.ts#L47)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L39](/src/UI/Popup/DataVisualisations.ts#L39)
|
||||
|
||||
#### Example usage of direction_absolute
|
||||
|
||||
|
@ -254,7 +231,7 @@ Defined in [/src/UI/Popup/DataVisualisations.ts#L47](/src/UI/Popup/DataVisualisa
|
|||
|
||||
Gives a distance indicator and a compass pointing towards the location from your GPS-location. If clicked, centers the map on the object
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L34](/src/UI/Popup/DataVisualisations.ts#L34)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L26](/src/UI/Popup/DataVisualisations.ts#L26)
|
||||
|
||||
#### Example usage of direction_indicator
|
||||
|
||||
|
@ -270,7 +247,7 @@ A small element, showing if the POI is currently open and when the next change i
|
|||
| prefix | _empty string_ | Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__ |
|
||||
| postfix | _empty string_ | Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__ |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L126](/src/UI/Popup/DataVisualisations.ts#L126)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L118](/src/UI/Popup/DataVisualisations.ts#L118)
|
||||
|
||||
#### Example usage of opening_hours_state
|
||||
|
||||
|
@ -286,7 +263,7 @@ Creates an opening-hours table. Usage: {opening_hours_table(opening_hours)} to c
|
|||
| prefix | _empty string_ | Remove this string from the start of the value before parsing. __Note: use `&LPARENs` to indicate `(` if needed__ |
|
||||
| postfix | _empty string_ | Remove this string from the end of the value before parsing. __Note: use `&RPARENs` to indicate `)` if needed__ |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L87](/src/UI/Popup/DataVisualisations.ts#L87)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L81](/src/UI/Popup/DataVisualisations.ts#L81)
|
||||
|
||||
#### Example usage of opening_hours_table
|
||||
|
||||
|
@ -300,7 +277,7 @@ Creates a visualisation for 'points in time', e.g. collection times of a postbox
|
|||
-----|-----|----- |
|
||||
| key | _undefined_ | The key out of which the points_in_time will be parsed |
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L281](/src/UI/Popup/DataVisualisations.ts#L281)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L274](/src/UI/Popup/DataVisualisations.ts#L274)
|
||||
|
||||
#### Example usage of points_in_time
|
||||
|
||||
|
@ -310,7 +287,7 @@ Defined in [/src/UI/Popup/DataVisualisations.ts#L281](/src/UI/Popup/DataVisualis
|
|||
|
||||
Show general statistics about all the elements currently in view. Intended to use on the `current_view`-layer. They will be split per layer
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L203](/src/UI/Popup/DataVisualisations.ts#L203)
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L195](/src/UI/Popup/DataVisualisations.ts#L195)
|
||||
|
||||
#### Example usage of statistics
|
||||
|
||||
|
@ -354,7 +331,8 @@ Gives an interactive element which shows a tag comparison between the OSM-object
|
|||
| host | _undefined_ | The domain name(s) where data might be fetched from - this is needed to set the CSP. A domain must include 'https', e.g. 'https://example.com'. For multiple domains, separate them with ';'. If you don't know the possible domains, use '*'. |
|
||||
| readonly | _undefined_ | If 'yes', will not show 'apply'-buttons |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L243](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L243)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L243](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L243)
|
||||
|
||||
#### Example usage of compare_data
|
||||
|
||||
|
@ -414,7 +392,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
| icon | ./assets/svg/addSmall.svg | A nice icon to show in the button |
|
||||
| way_to_conflate | _undefined_ | The key, of which the corresponding value is the id of the OSM-way that must be conflated; typically a calculatedTag |
|
||||
|
||||
Defined in [/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts#L30](/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts#L30)
|
||||
Defined
|
||||
in [/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts#L30](/src/UI/Popup/ImportButtons/ConflateImportButtonViz.ts#L30)
|
||||
|
||||
#### Example usage of conflate_button
|
||||
|
||||
|
@ -543,7 +522,8 @@ In the case that MapComplete is pointed to the testing grounds, the edit will be
|
|||
| snap_onto_layers | _undefined_ | If no existing nearby point exists, but a line of a specified layer is closeby, snap to this layer instead |
|
||||
| snap_to_layer_max_distance | 0.1 | Distance to distort the geometry to snap to this layer |
|
||||
|
||||
Defined in [/src/UI/Popup/ImportButtons/WayImportButtonViz.ts#L22](/src/UI/Popup/ImportButtons/WayImportButtonViz.ts#L22)
|
||||
Defined
|
||||
in [/src/UI/Popup/ImportButtons/WayImportButtonViz.ts#L22](/src/UI/Popup/ImportButtons/WayImportButtonViz.ts#L22)
|
||||
|
||||
#### Example usage of import_way_button
|
||||
|
||||
|
@ -561,7 +541,8 @@ Attempts to load (via a proxy) the specified website and parsed ld+json from the
|
|||
| mode | _undefined_ | If `display`, only show the data in tabular and readonly form, ignoring already existing tags. This is used to explicitly show all the tags. If unset or anything else, allow to apply/import on OSM |
|
||||
| collapsed | yes | If the containing accordion should be closed |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L105](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L105)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L105](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L105)
|
||||
|
||||
#### Example usage of linked_data_from_website
|
||||
|
||||
|
@ -580,7 +561,8 @@ Change the status of the given MapRoulette task
|
|||
| maproulette_id | mr_taskId | The property name containing the maproulette id |
|
||||
| ask_feedback | _empty string_ | If not an empty string, this will be used as question to ask some additional feedback. A text field will be added |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L25](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L25)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L25](/src/UI/SpecialVisualisations/DataImportSpecialVisualisations.ts#L25)
|
||||
|
||||
#### Example usage of maproulette_set_status
|
||||
|
||||
|
@ -641,7 +623,7 @@ Note that these values can be prepare with javascript in the theme by using a [c
|
|||
| id_of_object_to_apply_this_one | _undefined_ | If specified, applies the the tags onto _another_ object. The id will be read from properties[id_of_object_to_apply_this_one] of the selected object. The tags are still calculated based on the tags of the _selected_ element |
|
||||
| maproulette_id | _undefined_ | If specified, this maproulette-challenge will be closed when the tags are applied. This should be the `id` of the individual task, _not_ the task_id (which corresponds with the challenge). |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagApplyViz.ts#L17](/src/UI/SpecialVisualisations/TagApplyViz.ts#L17)
|
||||
Defined in [/src/UI/SpecialVisualisations/TagApplyViz.ts#L13](/src/UI/SpecialVisualisations/TagApplyViz.ts#L13)
|
||||
|
||||
#### Example usage of tag_apply
|
||||
|
||||
|
@ -655,7 +637,8 @@ These special visualisations are (mostly) interactive components that most eleme
|
|||
|
||||
An element which allows to add a new point on the 'last_click'-location. Only makes sense in the layer `last_click`
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L235](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L235)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L234](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L234)
|
||||
|
||||
#### Example usage of add_new_point
|
||||
|
||||
|
@ -665,7 +648,8 @@ Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L235](/src/
|
|||
|
||||
Adds a button which allows to delete the object at this location. The config will be read from the layer config
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L157](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L157)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L157](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L157)
|
||||
|
||||
#### Example usage of delete_button
|
||||
|
||||
|
@ -680,7 +664,8 @@ Shows a 'nothing is currently known-message if there is at least one unanswered
|
|||
| text | _undefined_ | Text to show |
|
||||
| cssClasses | _undefined_ | Classes to apply onto the text |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L207](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L207)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L206](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L206)
|
||||
|
||||
#### Example usage of if_nothing_known
|
||||
|
||||
|
@ -696,7 +681,8 @@ A small map showing the selected feature.
|
|||
| idKey | id | The key of one or more properties of the feature, semi-colon separated. The corresponding value is interpreted as either the id or the a list of ID's. The features with these ID's will be shown on this minimap. |
|
||||
| class | h-40 rounded | CSS-classes (space-separated) that should be applied onto the container |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L81](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L81)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L81](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L81)
|
||||
|
||||
#### Example usage of minimap
|
||||
|
||||
|
@ -706,7 +692,8 @@ Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L81](/src/U
|
|||
|
||||
Adds a button which allows to move the object to another location. The config will be read from the layer config
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L137](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L137)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L137](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L137)
|
||||
|
||||
#### Example usage of move_button
|
||||
|
||||
|
@ -721,7 +708,8 @@ Generates a QR-code to share the selected object
|
|||
| text | _undefined_ | Extra text on the side of the QR-code |
|
||||
| textClass | _undefined_ | CSS class of the the side text |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L178](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L178)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L178](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L178)
|
||||
|
||||
#### Example usage of qr_code
|
||||
|
||||
|
@ -737,7 +725,8 @@ The special element which shows the questions which are unknown. Added by defaul
|
|||
| blacklisted-labels | _undefined_ | One or more ';'-separated labels of questions which should _not_ be included. Note that the questionbox which is added by default will blacklist 'hidden'. If both a whitelist and a blacklist are given, will show questions having at least one label from the whitelist but none of the blacklist. |
|
||||
| show_all | _undefined_ | Either `no`, `yes` or `user-preference`. Indicates if all questions should be shown at once |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L31](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L31)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L31](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L31)
|
||||
|
||||
#### Example usage of questions
|
||||
|
||||
|
@ -762,7 +751,8 @@ Defined in [/src/UI/Popup/ShareLinkViz.ts#L6](/src/UI/Popup/ShareLinkViz.ts#L6)
|
|||
|
||||
Adds a button which allows to split a way
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L123](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L123)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L123](/src/UI/SpecialVisualisations/UISpecialVisualisations.ts#L123)
|
||||
|
||||
#### Example usage of split_button
|
||||
|
||||
|
@ -776,7 +766,8 @@ Elements relating to marking an object as favourite (giving it a heart). Default
|
|||
|
||||
A small button that allows a (logged in) contributor to mark a location as a favourite location, sized to fit a title-icon
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L19](/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L19)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L19](/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L19)
|
||||
|
||||
#### Example usage of favourite_icon
|
||||
|
||||
|
@ -786,7 +777,8 @@ Defined in [/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L19](/src/U
|
|||
|
||||
A button that allows a (logged in) contributor to mark a location as a favourite location
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L6](/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L6)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L6](/src/UI/SpecialVisualisations/FavouriteVisualisations.ts#L6)
|
||||
|
||||
#### Example usage of favourite_status
|
||||
|
||||
|
@ -804,7 +796,8 @@ Creates an image carousel for the given sources. An attempt will be made to gues
|
|||
-----|-----|----- |
|
||||
| image_key | image;mapillary;image;wikidata;wikimedia_commons;image;panoramax;image;image | The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... Multiple values are allowed if ';'-separated |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L48](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L48)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L48](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L48)
|
||||
|
||||
#### Example usage of image_carousel
|
||||
|
||||
|
@ -820,7 +813,8 @@ Creates a button where a user can upload an image to panoramax
|
|||
| label | _undefined_ | The text to show on the button |
|
||||
| disable_blur | _undefined_ | If set to 'true' or 'yes', then face blurring will be disabled. To be used sparingly |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L82](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L82)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L82](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L82)
|
||||
|
||||
#### Example usage of image_upload
|
||||
|
||||
|
@ -835,7 +829,8 @@ A component showing nearby images loaded from various online services such as Ma
|
|||
| mode | closed | Either `open` or `closed`. If `open`, then the image carousel will always be shown |
|
||||
| readonly | _undefined_ | If 'readonly' or 'yes', will not show the 'link'-button |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L12](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L12)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ImageVisualisations.ts#L12](/src/UI/SpecialVisualisations/ImageVisualisations.ts#L12)
|
||||
|
||||
#### Example usage of nearby_images
|
||||
|
||||
|
@ -853,7 +848,8 @@ Adds an image to a node
|
|||
-----|-----|----- |
|
||||
| Id-key | id | The property name where the ID of the note to close can be found |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L115](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L115)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L111](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L111)
|
||||
|
||||
#### Example usage of add_image_to_note
|
||||
|
||||
|
@ -867,7 +863,8 @@ A textfield to add a comment to a node (with the option to close the note).
|
|||
-----|-----|----- |
|
||||
| Id-key | id | The property name where the ID of the note to close can be found |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L79](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L79)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L75](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L75)
|
||||
|
||||
#### Example usage of add_note_comment
|
||||
|
||||
|
@ -886,7 +883,8 @@ Button to close a note. A predefined text can be defined to close the note with.
|
|||
| minZoom | _undefined_ | If set, only show the closenote button if zoomed in enough |
|
||||
| zoomButton | _undefined_ | Text to show if not zoomed in enough |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L22](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L22)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L18](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L18)
|
||||
|
||||
#### Example usage of close_note
|
||||
|
||||
|
@ -896,7 +894,8 @@ Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L22](/src/UI/Spe
|
|||
|
||||
Creates a new map note on the given location. This options is placed in the 'last_click'-popup automatically if the 'notes'-layer is enabled
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L98](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L98)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L94](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L94)
|
||||
|
||||
#### Example usage of open_note
|
||||
|
||||
|
@ -911,7 +910,8 @@ Visualises the comments for notes
|
|||
| commentsKey | comments | The property name of the comments, which should be stringified json |
|
||||
| start | 0 | Drop the first 'start' comments |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L136](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L136)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/NoteVisualisations.ts#L132](/src/UI/SpecialVisualisations/NoteVisualisations.ts#L132)
|
||||
|
||||
#### Example usage of visualize_note_comments
|
||||
|
||||
|
@ -931,7 +931,8 @@ Invites the contributor to leave a review. Somewhat small UI-element until inter
|
|||
| fallback | _undefined_ | The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value |
|
||||
| question | _undefined_ | The question to ask during the review |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L22](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L22)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L22](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L22)
|
||||
|
||||
#### Example usage of create_review
|
||||
|
||||
|
@ -946,7 +947,8 @@ Adds an overview of the mangrove-reviews of this object. Mangrove.Reviews needs
|
|||
| subjectKey | name | The key to use to determine the subject. If specified, the subject will be <b>tags[subjectKey]</b> |
|
||||
| fallback | _undefined_ | The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L88](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L88)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L88](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L88)
|
||||
|
||||
#### Example usage of list_reviews
|
||||
|
||||
|
@ -961,7 +963,8 @@ Shows stars which represent the average rating on mangrove.
|
|||
| subjectKey | name | The key to use to determine the subject. If the value is specified, the subject will be <b>tags[subjectKey]</b> and will use this to filter the reviews. |
|
||||
| fallback | _undefined_ | The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L125](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L125)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L125](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L125)
|
||||
|
||||
#### Example usage of rating
|
||||
|
||||
|
@ -977,7 +980,8 @@ A pragmatic combination of `create_review` and `list_reviews`
|
|||
| fallback | _undefined_ | The identifier to use, if <i>tags[subjectKey]</i> as specified above is not available. This is effectively a fallback value |
|
||||
| question | _undefined_ | The question to ask in the review form. Optional |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L182](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L182)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L182](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L182)
|
||||
|
||||
#### Example usage of reviews
|
||||
|
||||
|
@ -995,7 +999,8 @@ A button which clears the locally downloaded data and the service worker. Login
|
|||
-----|-----|----- |
|
||||
| text | _undefined_ | The text to show on the button |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L110](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L110)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L110](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L110)
|
||||
|
||||
#### Example usage of clear_caches
|
||||
|
||||
|
@ -1005,7 +1010,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L110](/src/U
|
|||
|
||||
A button to remove the travelled track information from the device
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L215](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L215)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L215](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L215)
|
||||
|
||||
#### Example usage of clear_location_history
|
||||
|
||||
|
@ -1015,7 +1021,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L215](/src/U
|
|||
|
||||
Shows which questions are disabled for every layer. Used in 'settings'
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L46](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L46)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L46](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L46)
|
||||
|
||||
#### Example usage of disabled_questions
|
||||
|
||||
|
@ -1025,7 +1032,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L46](/src/UI
|
|||
|
||||
Shows the current tags of the GPS-representing object, used for debugging
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L69](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L69)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L69](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L69)
|
||||
|
||||
#### Example usage of gps_all_tags
|
||||
|
||||
|
@ -1035,7 +1043,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L69](/src/UI
|
|||
|
||||
Shows the current tags of the GPS-representing object, used for debugging
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L58](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L58)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L58](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L58)
|
||||
|
||||
#### Example usage of gyroscope_all_tags
|
||||
|
||||
|
@ -1049,7 +1058,8 @@ Only makes sense in the usersettings. Allows to import a mangrove public key and
|
|||
-----|-----|----- |
|
||||
| text | _undefined_ | The text that is shown on the button |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L162](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L162)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L162](/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L162)
|
||||
|
||||
#### Example usage of import_mangrove_key
|
||||
|
||||
|
@ -1059,7 +1069,8 @@ Defined in [/src/UI/SpecialVisualisations/ReviewSpecialVisualisations.ts#L162](/
|
|||
|
||||
A component to set the language of the user interface
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L26](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L26)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L26](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L26)
|
||||
|
||||
#### Example usage of language_picker
|
||||
|
||||
|
@ -1074,7 +1085,8 @@ Show a login button
|
|||
| force | _undefined_ | Always show this button, even if logged in |
|
||||
| message | _undefined_ | Message to display on the button |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L131](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L131)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L131](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L131)
|
||||
|
||||
#### Example usage of login_button
|
||||
|
||||
|
@ -1084,7 +1096,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L131](/src/U
|
|||
|
||||
Shows a button where the user can log out
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L192](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L192)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L192](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L192)
|
||||
|
||||
#### Example usage of logout
|
||||
|
||||
|
@ -1094,7 +1107,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L192](/src/U
|
|||
|
||||
A module showing the pending changes, with the option to clear the pending changes
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L204](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L204)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L204](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L204)
|
||||
|
||||
#### Example usage of pending_changes
|
||||
|
||||
|
@ -1109,7 +1123,8 @@ A QR-code which shares the current URL and adds the login token. Anyone with thi
|
|||
| text | _undefined_ | Extra text on the side of the QR-code |
|
||||
| textClass | _undefined_ | CSS class of the the side text |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L161](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L161)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L161](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L161)
|
||||
|
||||
#### Example usage of qr_login
|
||||
|
||||
|
@ -1119,7 +1134,8 @@ Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L161](/src/U
|
|||
|
||||
Shows the current state of storage
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L86](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L86)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L86](/src/UI/SpecialVisualisations/SettingsVisualisations.ts#L86)
|
||||
|
||||
#### Example usage of storage_all_tags
|
||||
|
||||
|
@ -1139,7 +1155,8 @@ A collapsable group (accordion)
|
|||
| labels | _undefined_ | A `;`-separated list of either identifiers or label names. All tagRenderings matching this value will be shown in the accordion |
|
||||
| blacklist | _undefined_ | A `;`-separated list of either identifiers or label names. Matching tagrenderings will _not_ be included, even if they are in `labels` |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L176](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L176)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L176](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L176)
|
||||
|
||||
#### Example usage of group
|
||||
|
||||
|
@ -1155,7 +1172,8 @@ Given an embedded tagRendering (read only) and a key, will read the keyname as a
|
|||
| tagrendering | _undefined_ | An entire tagRenderingConfig |
|
||||
| classes | _undefined_ | CSS-classes to apply on every individual item. Seperated by `space` |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L96](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L96)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L96](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L96)
|
||||
|
||||
#### Example usage of multi
|
||||
|
||||
|
@ -1173,6 +1191,28 @@ Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisuali
|
|||
}
|
||||
```
|
||||
|
||||
### open_in_iD
|
||||
|
||||
Opens the current view in the iD-editor
|
||||
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L212](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L212)
|
||||
|
||||
#### Example usage of open_in_iD
|
||||
|
||||
`{open_in_iD()}`
|
||||
|
||||
### open_in_josm
|
||||
|
||||
Opens the current view in the JOSM-editor
|
||||
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L226](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L226)
|
||||
|
||||
#### Example usage of open_in_josm
|
||||
|
||||
`{open_in_josm()}`
|
||||
|
||||
### steal
|
||||
|
||||
Shows a tagRendering from a different object as if this was the object itself
|
||||
|
@ -1182,26 +1222,13 @@ Shows a tagRendering from a different object as if this was the object itself
|
|||
| featureId | _undefined_ | The key of the attribute which contains the id of the feature from which to use the tags |
|
||||
| tagRenderingId | _undefined_ | The layer-id and tagRenderingId to render. Can be multiple value if ';'-separated (in which case every value must also contain the layerId, e.g. `layerId.tagRendering0; layerId.tagRendering1`). Note: this can cause layer injection |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L23](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L23)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L23](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L23)
|
||||
|
||||
#### Example usage of steal
|
||||
|
||||
`{steal(,)}`
|
||||
|
||||
## ui
|
||||
|
||||
Elements to support the user interface, e.g. 'title', 'translated'
|
||||
|
||||
### preset_type_select
|
||||
|
||||
An editable tag rendering which allows to change the type
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L231](/src/UI/Popup/DataVisualisations.ts#L231)
|
||||
|
||||
#### Example usage of preset_type_select
|
||||
|
||||
`{preset_type_select()}`
|
||||
|
||||
## web_and_communication
|
||||
|
||||
Tools to show data from external websites, which link to external websites or which link to external profiles
|
||||
|
@ -1214,7 +1241,8 @@ Converts a fediverse username or link into a clickable link
|
|||
-----|-----|----- |
|
||||
| key | _undefined_ | The attribute-name containing the link |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L20](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L20)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L16](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L16)
|
||||
|
||||
#### Example usage of fediverse_link
|
||||
|
||||
|
@ -1224,16 +1252,17 @@ Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisatio
|
|||
|
||||
Construct a link. By using the 'special' visualisation notation, translations should be easier
|
||||
|
||||
| name | default | description |
|
||||
-----|-----|----- |
|
||||
| text | _undefined_ | Text to be shown |
|
||||
| href | _undefined_ | The URL to link to. Note that this will be URI-encoded before and (as everything) supports substitutions of attributes |
|
||||
| class | _undefined_ | CSS-classes to add to the element |
|
||||
| download | _undefined_ | Expects a string which denotes the filename to download the contents of `href` into. If set, this link will act as a download-button. |
|
||||
| arialabel | _undefined_ | If set, this text will be used as aria-label |
|
||||
| icon | _undefined_ | If set, show this icon next to the link. You might want to combine this with `class: button` |
|
||||
| name | default | description |
|
||||
-----------|-------------|---------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| text | _undefined_ | Text to be shown |
|
||||
| href | _undefined_ | The URL to link to. Note that this will be URI-encoded before and (as everything) supports substitutions of attributes |
|
||||
| class | _undefined_ | CSS-classes to add to the element |
|
||||
| download | _undefined_ | Expects a string which denotes the filename to download the contents of `href` into. If set, this link will act as a download-button. |
|
||||
| arialabel | _undefined_ | If set, this text will be used as aria-label |
|
||||
| icon | _undefined_ | If set, show this icon next to the link. You might want to combine this with `class: button` |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L147](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L147)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L143](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L143)
|
||||
|
||||
#### Example usage of link
|
||||
|
||||
|
@ -1253,26 +1282,6 @@ Defined in [/src/UI/Popup/MapillaryLinkVis.ts#L7](/src/UI/Popup/MapillaryLinkVis
|
|||
|
||||
`{mapillary_link(18)}`
|
||||
|
||||
### open_in_iD
|
||||
|
||||
Opens the current view in the iD-editor
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L212](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L212)
|
||||
|
||||
#### Example usage of open_in_iD
|
||||
|
||||
`{open_in_iD()}`
|
||||
|
||||
### open_in_josm
|
||||
|
||||
Opens the current view in the JOSM-editor
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L226](/src/UI/SpecialVisualisations/TagrenderingManipulationSpecialVisualisations.ts#L226)
|
||||
|
||||
#### Example usage of open_in_josm
|
||||
|
||||
`{open_in_josm()}`
|
||||
|
||||
### send_email
|
||||
|
||||
Creates a `mailto`-link where some fields are already set and correctly escaped. The user will be promted to send the email
|
||||
|
@ -1284,7 +1293,7 @@ Creates a `mailto`-link where some fields are already set and correctly escaped.
|
|||
| body | _undefined_ | The text in the email |
|
||||
| button_text | _undefined_ | The text shown on the button in the UI |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L109](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L109)
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L105](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L105)
|
||||
|
||||
#### Example usage of send_email
|
||||
|
||||
|
@ -1298,7 +1307,8 @@ Shows the label of the corresponding wikidata-item
|
|||
-----|-----|----- |
|
||||
| keyToShowWikidataFor | wikidata | Use the wikidata entry from this key to show the label |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L68](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L68)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L64](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L64)
|
||||
|
||||
#### Example usage of wikidata_label
|
||||
|
||||
|
@ -1312,7 +1322,8 @@ A box showing the corresponding wikipedia article(s) - based on the **wikidata**
|
|||
-----|-----|----- |
|
||||
| keyToShowWikipediaFor | wikidata;wikipedia | Use the wikidata entry from this key to show the wikipedia article for. Multiple keys can be given (separated by ';'), in which case the first matching value is used |
|
||||
|
||||
Defined in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L39](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L39)
|
||||
Defined
|
||||
in [/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L35](/src/UI/SpecialVisualisations/WebAndCommunicationSpecialVisualisations.ts#L35)
|
||||
|
||||
#### Example usage of wikipedia
|
||||
|
||||
|
@ -1326,7 +1337,7 @@ Various elements
|
|||
|
||||
Exports the selected feature as GeoJson-file
|
||||
|
||||
Defined in [/src/UI/Popup/DataExportVisualisations.ts#L38](/src/UI/Popup/DataExportVisualisations.ts#L38)
|
||||
Defined in [/src/UI/Popup/DataExportVisualisations.ts#L34](/src/UI/Popup/DataExportVisualisations.ts#L34)
|
||||
|
||||
#### Example usage of export_as_geojson
|
||||
|
||||
|
@ -1336,7 +1347,7 @@ Defined in [/src/UI/Popup/DataExportVisualisations.ts#L38](/src/UI/Popup/DataExp
|
|||
|
||||
Exports the selected feature as GPX-file
|
||||
|
||||
Defined in [/src/UI/Popup/DataExportVisualisations.ts#L12](/src/UI/Popup/DataExportVisualisations.ts#L12)
|
||||
Defined in [/src/UI/Popup/DataExportVisualisations.ts#L8](/src/UI/Popup/DataExportVisualisations.ts#L8)
|
||||
|
||||
#### Example usage of export_as_gpx
|
||||
|
||||
|
@ -1350,7 +1361,7 @@ Create a histogram for a list of given values, read from the properties.
|
|||
-----|-----|----- |
|
||||
| key | _undefined_ | The key to be read and to generate a histogram from |
|
||||
|
||||
Defined in [/src/UI/Popup/HistogramViz.ts#L11](/src/UI/Popup/HistogramViz.ts#L11)
|
||||
Defined in [/src/UI/Popup/HistogramViz.ts#L7](/src/UI/Popup/HistogramViz.ts#L7)
|
||||
|
||||
#### Example usage of histogram
|
||||
|
||||
|
@ -1360,14 +1371,14 @@ Defined in [/src/UI/Popup/HistogramViz.ts#L11](/src/UI/Popup/HistogramViz.ts#L11
|
|||
|
||||
The language element allows to show and pick all known (modern) languages. The key can be set
|
||||
|
||||
| name | default | description |
|
||||
-----|-----|----- |
|
||||
| key | _undefined_ | What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `<key>:nl=yes` if _nl_ is picked |
|
||||
| question | _undefined_ | What to ask if no questions are known |
|
||||
| render_list_item | {language()} | How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain). |
|
||||
| render_single_language | _undefined_ | What will be shown if the feature only supports a single language |
|
||||
| render_all | {list()} | The full rendering. U0se `{list}` to show where the list of languages must come. Optional if mode=single |
|
||||
| no_known_languages | _undefined_ | The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead |
|
||||
| name | default | description |
|
||||
------------------------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| key | _undefined_ | What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `<key>:nl=yes` if _nl_ is picked |
|
||||
| question | _undefined_ | What to ask if no questions are known |
|
||||
| render_list_item | {language()} | How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain). |
|
||||
| render_single_language | _undefined_ | What will be shown if the feature only supports a single language |
|
||||
| render_all | {list()} | The full rendering. U0se `{list}` to show where the list of languages must come. Optional if mode=single |
|
||||
| no_known_languages | _undefined_ | The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead |
|
||||
|
||||
Defined in [/src/UI/Popup/LanguageElement/LanguageElement.ts#L5](/src/UI/Popup/LanguageElement/LanguageElement.ts#L5)
|
||||
|
||||
|
@ -1403,6 +1414,31 @@ Defined in [/src/UI/Popup/MultiApplyViz.ts#L7](/src/UI/Popup/MultiApplyViz.ts#L7
|
|||
|
||||
{multi_apply(_features_with_the_same_name_within_100m, name:etymology:wikidata;name:etymology, Apply etymology information on all nearby objects with the same name)}
|
||||
|
||||
### preset_description
|
||||
|
||||
Shows the extra description from the presets of the layer, if one matches. It will pick the most specific one (e.g. if preset `A` implies `B`, but `B` does not imply `A`, it'll pick B) or the first one if no ordering can be made. Might be empty
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L207](/src/UI/Popup/DataVisualisations.ts#L207)
|
||||
|
||||
#### Example usage of preset_description
|
||||
|
||||
`{preset_description()}`
|
||||
|
||||
### preset_type_select
|
||||
|
||||
An editable tag rendering which allows to change the type. The options are the presets of the layer, effectively
|
||||
allowing to change act as if the object was made with a different preset. For example
|
||||
|
||||
How this element looks like (in question mode) for [
|
||||
`tourism_accomodation`](./Layers/tourism_accomodation.md): The
|
||||
presets 
|
||||
|
||||
Defined in [/src/UI/Popup/DataVisualisations.ts#L222](/src/UI/Popup/DataVisualisations.ts#L222)
|
||||
|
||||
#### Example usage of preset_type_select
|
||||
|
||||
`{preset_type_select()}`
|
||||
|
||||
### upload_to_osm
|
||||
|
||||
Uploads the GPS-history as GPX to OpenStreetMap.org; clears the history afterwards. The actual feature is ignored.
|
||||
|
|
BIN
Docs/img/Special_preset_type_select_matching_presets.png
Normal file
BIN
Docs/img/Special_preset_type_select_matching_presets.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 106 KiB |
BIN
Docs/img/Special_preset_type_select_preview.png
Normal file
BIN
Docs/img/Special_preset_type_select_preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 110 KiB |
2
android
2
android
|
@ -1 +1 @@
|
|||
Subproject commit 817e8198b5e4c30572d7d3f082d60fc10a7be21e
|
||||
Subproject commit dc3f3f5ac3d4d42bed7aeb58ff5386a063dbac06
|
115
assets/layers/arcade/arcade.json
Normal file
115
assets/layers/arcade/arcade.json
Normal file
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"id": "arcade",
|
||||
"name": {
|
||||
"en": "Arcades"
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing arcades"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": "leisure=amusement_arcade"
|
||||
},
|
||||
"minzoom": 10,
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Arcade"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "name~*",
|
||||
"then": {
|
||||
"*": "{name}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": "square",
|
||||
"color": "white"
|
||||
},
|
||||
{
|
||||
"icon": "./assets/layers/arcade/arcade.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"width": 3,
|
||||
"color": "#0e8517"
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"title": {
|
||||
"en": "an arcade"
|
||||
},
|
||||
"tags": [
|
||||
"leisure=amusement_arcade"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
"reviews",
|
||||
{
|
||||
"builtin": "name",
|
||||
"override": {
|
||||
"question": {
|
||||
"en": "What is the name of this arcade?"
|
||||
},
|
||||
"render": {
|
||||
"en": "This arcade is called <b>{name}</b>"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "virtual_reality",
|
||||
"question": {
|
||||
"en": "Does this arcade offer virtual-reality gaming?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "virtual_reality=yes",
|
||||
"then": {
|
||||
"en": "This arcade offers virtual-reality gaming."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "virtual_reality=only",
|
||||
"then": {
|
||||
"en": "This arcade <b>only</b> offers virtual-reality gaming."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "virtual_reality=",
|
||||
"then": {
|
||||
"en": "This arcade doesn't offer virtual-reality gaming"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"brand",
|
||||
"opening_hours",
|
||||
"website",
|
||||
"email",
|
||||
"phone",
|
||||
"payment-options",
|
||||
"level",
|
||||
"description",
|
||||
"toilet_at_amenity_lib.all"
|
||||
],
|
||||
"allowMove": {
|
||||
"enableImproveAccuracy": true,
|
||||
"enableRelocation": true
|
||||
},
|
||||
"credits": "Robin van der Linde",
|
||||
"credits:uid": 5093765
|
||||
}
|
3
assets/layers/arcade/arcade.svg
Normal file
3
assets/layers/arcade/arcade.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14">
|
||||
<path fill="#0e8517" d="m0,1 h4 v2 h-4z m10,0 h4 v2 h-4z m-6,2 v2 h-2 v2 h-2 v7 h2 v-2 h2 v2 h2 v-2 h2 v2 h2 v-2 h2 v2 h2 v-7 h-2 v-2 h-2 v-2 h-2 v2 h-2 v-2z m0,4 h2 v2 h-2 z m4,0 h2 v2 h-2 z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 287 B |
2
assets/layers/arcade/arcade.svg.license
Normal file
2
assets/layers/arcade/arcade.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: meased
|
||||
SPDX-License-Identifier: CC0-1.0
|
12
assets/layers/arcade/license_info.json
Normal file
12
assets/layers/arcade/license_info.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
[
|
||||
{
|
||||
"path": "arcade.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"meased"
|
||||
],
|
||||
"sources": [
|
||||
"https://github.com/gravitystorm/openstreetmap-carto/blob/master/symbols/leisure/amusement_arcade.svg"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -280,41 +280,12 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"caravansites.caravansites-toilets",
|
||||
"toilet_at_amenity_lib.all",
|
||||
"questions",
|
||||
"mastodon"
|
||||
],
|
||||
"filter": [
|
||||
{
|
||||
"id": "fee_filter",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Fee",
|
||||
"ca": "Taxa",
|
||||
"cs": "Poplatek",
|
||||
"cy": "Ffi",
|
||||
"de": "Gebühr",
|
||||
"it": "A pagamento"
|
||||
}
|
||||
},
|
||||
{
|
||||
"question": {
|
||||
"en": "free of charge",
|
||||
"ca": "Gratuït",
|
||||
"cs": "zdarma",
|
||||
"de": "kostenlos",
|
||||
"it": "gratuito"
|
||||
},
|
||||
"osmTags": {
|
||||
"and": [
|
||||
"fee=no"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"free",
|
||||
{
|
||||
"id": "capacity_persons_filter",
|
||||
"options": [
|
||||
|
|
|
@ -666,85 +666,7 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "caravansites-toilets",
|
||||
"question": {
|
||||
"en": "Does this place have toilets?",
|
||||
"ca": "Aquest lloc té lavabos?",
|
||||
"cs": "Má toto místo toalety?",
|
||||
"da": "Har dette sted toiletter?",
|
||||
"de": "Verfügt dieser Ort über Toiletten?",
|
||||
"es": "¿Este lugar tiene baños?",
|
||||
"fr": "Y-a-t’il des toilettes sur le site ?",
|
||||
"hu": "Van-e itt WC?",
|
||||
"it": "Questo posto ha servizi igienici?",
|
||||
"ja": "ここにトイレはありますか?",
|
||||
"nb_NO": "Har dette stedet toaletter?",
|
||||
"nl": "Heeft deze plaats toiletten?",
|
||||
"pl": "Czy to miejsce ma toalety?",
|
||||
"pt": "Este lugar tem casas de banho?",
|
||||
"pt_BR": "Este lugar tem banheiros?",
|
||||
"ru": "Здесь есть туалеты?",
|
||||
"zh_Hant": "這個地方有廁所嗎?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"toilets=yes"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"en": "This place has toilets",
|
||||
"ca": "Aquest lloc té lavabos",
|
||||
"cs": "Toto místo má toalety",
|
||||
"da": "Dette sted har toiletter",
|
||||
"de": "Dieser Ort verfügt über Toiletten",
|
||||
"es": "Este lugar tiene baños",
|
||||
"fr": "Ce site a des toilettes",
|
||||
"hu": "Itt van WC",
|
||||
"id": "Tempat sini ada tandas",
|
||||
"it": "Questo posto ha servizi igienici",
|
||||
"ja": "ここにはトイレがある",
|
||||
"nb_NO": "Dette stedet har toalettfasiliteter",
|
||||
"nl": "Deze plaats heeft toiletten",
|
||||
"pl": "To miejsce ma toalety",
|
||||
"pt": "Este lugar tem casa de banho",
|
||||
"pt_BR": "Este lugar tem banheiros",
|
||||
"ru": "В этом месте есть туалеты",
|
||||
"zh_Hant": "這個地方有廁所"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"toilets=no"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"en": "This place does not have toilets",
|
||||
"ca": "Aquest lloc no té lavabos",
|
||||
"cs": "Toto místo nemá toalety",
|
||||
"da": "Dette sted har ikke toiletter",
|
||||
"de": "Dieser Ort verfügt nicht über Toiletten",
|
||||
"es": "Este lugar no tiene baños",
|
||||
"eu": "Toki honek ez dauka komunik",
|
||||
"fr": "Ce site n’a pas de toilettes",
|
||||
"hu": "Itt nincs WC",
|
||||
"id": "Tempat sini tiada tandas",
|
||||
"it": "Questo posto non ha servizi igienici",
|
||||
"ja": "ここにはトイレがない",
|
||||
"nb_NO": "Dette stedet har ikke toalettfasiliteter",
|
||||
"nl": "Deze plaats heeft geen toiletten",
|
||||
"pl": "To miejsce nie ma toalet",
|
||||
"pt": "Este lugar não tem casas de banho",
|
||||
"pt_BR": "Este lugar não tem banheiros",
|
||||
"ru": "В этом месте нет туалетов",
|
||||
"zh_Hant": "這個地方並沒有廁所"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"has_toilets",
|
||||
{
|
||||
"id": "caravansites-website",
|
||||
"question": {
|
||||
|
@ -935,5 +857,8 @@
|
|||
"questions",
|
||||
"reviews"
|
||||
],
|
||||
"filter": [
|
||||
"free"
|
||||
],
|
||||
"allowMove": true
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"shownByDefault": false,
|
||||
"title": "Current View",
|
||||
"popupInFloatover": true,
|
||||
"titleIcons": [],
|
||||
"pointRendering": [],
|
||||
"lineRendering": [
|
||||
{
|
||||
|
|
|
@ -554,6 +554,45 @@
|
|||
"osmTags": "kids_area!=no"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "self_checkout",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "Has self-checkout",
|
||||
"nl": "Heeft zelfscan"
|
||||
},
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"self_checkout=yes",
|
||||
"self_checkout=only"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "shelter",
|
||||
"options": [
|
||||
{
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"shelter=yes",
|
||||
"shelter=separate"
|
||||
]
|
||||
},
|
||||
"question": {
|
||||
"en": "With a shelter",
|
||||
"ca": "Amb refugi",
|
||||
"cs": "S přístřeškem",
|
||||
"de": "Mit Unterstand",
|
||||
"es": "Con refugio",
|
||||
"fr": "Avec un abri",
|
||||
"it": "Con una pensilina"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"allowMove": false
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
"it": "C'è un maniglione?",
|
||||
"nl": "Is er een handgreep of grijpbeugel?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "Left and right are interpreted as when sitting on the toilet"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
|
@ -164,6 +167,10 @@
|
|||
"it": "Il maniglione {{TRANSL}} è pieghevole?",
|
||||
"nl": "Is de grijpbeugel aan de {{TRANSL}}kant opklapbaar?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "Left and right are as seen when sitting on the toilet",
|
||||
"nl": "Links en rechts is wanneer men op de toilet zit"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "grab_rail:foldable:LOCATION=yes",
|
||||
|
|
15
assets/layers/hut/alpine_hut.svg
Normal file
15
assets/layers/hut/alpine_hut.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="14" height="14" viewBox="0 0 14 14" id="svg2">
|
||||
<metadata id="metadata8">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs6"/>
|
||||
<rect width="14" height="14" x="0" y="0" id="canvas" style="fill:none;stroke:none;visibility:hidden"/>
|
||||
<path id="path757" d="M 7 0 L 0 3.5 L 0 5.5 L 1.5 4.8496094 L 1.5 14 L 3 14 L 3 4.1992188 L 7 2.5 L 11 4.1992188 L 11 14 L 12.5 14 L 12.5 4.8496094 L 14 5.5 L 14 3.5 L 7 0 z M 6.9726562 5.0488281 C 6.5840971 5.0488281 6.2675781 5.3630448 6.2675781 5.7519531 C 6.2675781 6.1417342 6.584097 6.4550781 6.9726562 6.4550781 C 7.361041 6.4550781 7.6757812 6.1417342 7.6757812 5.7519531 C 7.6757812 5.3630448 7.3608664 5.0488281 6.9726562 5.0488281 z M 5.0488281 6.1875 C 4.9393822 6.162539 4.8312529 6.2261094 4.8066406 6.3339844 L 4.3144531 8.375 C 4.2879211 8.483224 4.3541425 8.5899565 4.4628906 8.6171875 L 5.0488281 8.7578125 C 5.1556558 8.7859125 5.2664033 8.7195541 5.2910156 8.6113281 L 5.7832031 6.5722656 C 5.8095609 6.4640416 5.7430227 6.355181 5.6367188 6.328125 L 5.0488281 6.1875 z M 6.7675781 6.5644531 C 6.1938161 6.5499631 6.0488281 7.1523437 6.0488281 7.1523438 L 4.5605469 13.40625 C 4.5553069 13.43959 4.5527344 13.472519 4.5527344 13.505859 C 4.5527344 13.78026 4.7744278 14 5.0488281 14 C 5.2720838 14 5.4610884 13.85019 5.5214844 13.646484 L 6.3730469 10.126953 L 7.1816406 13.625 C 7.2340066 13.841273 7.4308241 14 7.6621094 14 C 7.9354624 14 8.1542969 13.780085 8.1542969 13.505859 C 8.1542969 13.468499 8.1525944 13.431918 8.1464844 13.396484 L 7.0332031 8.7480469 L 7.1269531 8.3398438 L 7.1992188 8.6621094 C 7.2652007 8.8720994 7.4570312 8.890625 7.4570312 8.890625 L 8.6015625 9.1835938 C 8.6249525 9.1875937 8.648315 9.1894531 8.671875 9.1894531 C 8.859346 9.1894531 9.0097656 9.0406386 9.0097656 8.8535156 C 9.0097656 8.6934486 8.900292 8.5569194 8.75 8.5214844 L 7.7578125 8.2734375 L 7.4863281 7.1660156 C 7.3564592 6.5486156 6.7675781 6.5644531 6.7675781 6.5644531 z M 9.8300781 7.2792969 C 9.7478581 7.2792969 9.6872029 7.3408519 9.6699219 7.4199219 L 8.4882812 13.826172 C 8.4882812 13.830372 8.4863281 13.833837 8.4863281 13.835938 C 8.4863281 13.925487 8.5592405 13.998047 8.6484375 13.998047 C 8.7296075 13.998047 8.7993749 13.935444 8.8105469 13.857422 L 9.9902344 7.4511719 L 9.9902344 7.4394531 C 9.9902344 7.3521731 9.9192711 7.2792969 9.8300781 7.2792969 z " style="fill:#0092da;stroke-width:0.17455491"/>
|
||||
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
2
assets/layers/hut/alpine_hut.svg.license
Normal file
2
assets/layers/hut/alpine_hut.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Geozeisig
|
||||
SPDX-License-Identifier: CC0-1.0
|
179
assets/layers/hut/hut.json
Normal file
179
assets/layers/hut/hut.json
Normal file
|
@ -0,0 +1,179 @@
|
|||
{
|
||||
"id": "hut",
|
||||
"name": {
|
||||
"en": "Huts"
|
||||
},
|
||||
"description": {
|
||||
"en": "Layer showing basic huts, wilderness huts and alpine huts"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"tourism=wilderness_hut",
|
||||
"tourism=alpine_hut",
|
||||
{
|
||||
"and": [
|
||||
"amenity=shelter",
|
||||
"shelter_type=basic_hut"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"minzoom": 10,
|
||||
"title": {
|
||||
"render": "Hut",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "name~*",
|
||||
"then": "{name}"
|
||||
},
|
||||
{
|
||||
"if": "tourism=wilderness_hut",
|
||||
"then": "wilderness hut"
|
||||
},
|
||||
{
|
||||
"if": "tourism=alpine_hut",
|
||||
"then": "alpine hut"
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"amenity=shelter",
|
||||
"shelter_type=basic_hut"
|
||||
]
|
||||
},
|
||||
"then": "basic hut"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"marker": [
|
||||
{
|
||||
"icon": {
|
||||
"render": "./assets/layers/shelter/shelter.svg",
|
||||
"mappings": [
|
||||
{
|
||||
"if": "tourism=wilderness_hut",
|
||||
"then": "./assets/layers/hut/wilderness_hut.svg"
|
||||
},
|
||||
{
|
||||
"if": "tourism=alpine_hut",
|
||||
"then": "./assets/layers/hut/alpine_hut.svg"
|
||||
},
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"amenity=shelter",
|
||||
"shelter_type=basic_hut"
|
||||
]
|
||||
},
|
||||
"then": "./assets/layers/shelter/shelter.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"lineRendering": [],
|
||||
"presets": [
|
||||
{
|
||||
"tags": [
|
||||
"tourism=wilderness_hut"
|
||||
],
|
||||
"title": {
|
||||
"en": "wilderness hut"
|
||||
},
|
||||
"description": {
|
||||
"en": "An unserviced fully enclosed hut (with roof and walls) with beds or suitable sleeping areas and a fireplace or stove for heating and cooking."
|
||||
}
|
||||
},
|
||||
{
|
||||
"tags": [
|
||||
"tourism=alpine_hut"
|
||||
],
|
||||
"title": {
|
||||
"en": "alpine hut"
|
||||
},
|
||||
"description": {
|
||||
"en": "A serviced remote building located in the mountains intended to provide board and lodging."
|
||||
}
|
||||
},
|
||||
{
|
||||
"tags": [
|
||||
"amenity=shelter",
|
||||
"shelter_type=basic_hut"
|
||||
],
|
||||
"title": {
|
||||
"en": "basic hut"
|
||||
},
|
||||
"description": {
|
||||
"en": "An unserviced fully enclosed hut (with roof and walls) with beds or suitable sleeping areas <b>without</b> a fireplace or stove."
|
||||
}
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
"name",
|
||||
{
|
||||
"builtin": "website",
|
||||
"override": {
|
||||
"condition": "tourism=wilderness_hut",
|
||||
"id": "website-single"
|
||||
}
|
||||
},
|
||||
{
|
||||
"builtin": "contact",
|
||||
"override": {
|
||||
"condition": "tourism=alpine_hut"
|
||||
}
|
||||
},
|
||||
"reservation",
|
||||
"caravansites.caravansites-fee",
|
||||
{
|
||||
"id": "drinking_water",
|
||||
"question": {
|
||||
"en": "Is drinking water available here?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "drinking_water=yes",
|
||||
"then": {
|
||||
"en": "Here is drinking water available."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "drinking_water=no",
|
||||
"then": {
|
||||
"en": "Here is no drinking water available."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"has_toilets",
|
||||
"description",
|
||||
{
|
||||
"id": "preset_type",
|
||||
"render": "{preset_type_select()}"
|
||||
},
|
||||
{
|
||||
"builtin": "shelter.shelter-type",
|
||||
"override": {
|
||||
"condition": "amenity=shelter"
|
||||
}
|
||||
}
|
||||
],
|
||||
"filter":[
|
||||
"free"
|
||||
],
|
||||
"allowMove": {
|
||||
"enableRelocation": false,
|
||||
"enableImproveAccuracy": true
|
||||
}
|
||||
}
|
22
assets/layers/hut/license_info.json
Normal file
22
assets/layers/hut/license_info.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
[
|
||||
{
|
||||
"path": "alpine_hut.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"Geozeisig"
|
||||
],
|
||||
"sources": [
|
||||
"https://wiki.openstreetmap.org/wiki/File:Alpinehut.svg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "wilderness_hut.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"Geozeisig"
|
||||
],
|
||||
"sources": [
|
||||
"https://wiki.openstreetmap.org/wiki/File:Wilderness_hut.svg"
|
||||
]
|
||||
}
|
||||
]
|
15
assets/layers/hut/wilderness_hut.svg
Normal file
15
assets/layers/hut/wilderness_hut.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="14" height="14" viewBox="0 0 14 14" id="svg2">
|
||||
<metadata id="metadata8">
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs id="defs6"/>
|
||||
<rect width="14" height="14" x="0" y="0" id="canvas" style="fill:none;stroke:none;visibility:hidden"/>
|
||||
<path id="wilderness-hut" d="M 8,0 8,2 7,1.5 0,5 0,7 1.5,6.3496094 1.5,14 3,14 3,5.6992188 7,4 8,4.4257812 8,9 4.5,9 c 0.025314,1.65157 -0.034277,3.38952 0,5 l 5,0 C 9.518206,11.046736 9.50603,8.0503867 9.5,5.0625 L 11,5.6992188 11,14 12.5,14 12.5,6.3496094 14,7 14,5 9.5,2.75 C 9.4984477,1.8314022 9.5,0.9158261 9.5,0 L 8,0 Z M 7,11 c 0,0 1,0 1,1 l 0,1 -2,0 0,-1 c 0,-1 1,-1 1,-1 z" style="fill:#0092da;fill-opacity:1;stroke:none"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
2
assets/layers/hut/wilderness_hut.svg.license
Normal file
2
assets/layers/hut/wilderness_hut.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Geozeisig
|
||||
SPDX-License-Identifier: CC0-1.0
|
|
@ -69,6 +69,15 @@
|
|||
"icon": {
|
||||
"render": "./assets/layers/parking_spaces/parking_space.svg",
|
||||
"mappings": [
|
||||
{
|
||||
"if": {
|
||||
"or": [
|
||||
"access=private",
|
||||
"access=no"
|
||||
]
|
||||
},
|
||||
"then": "./assets/layers/parking_spaces/parking_space_private.svg"
|
||||
},
|
||||
{
|
||||
"if": "parking_space=disabled",
|
||||
"then": "./assets/layers/toilet/wheelchair.svg"
|
||||
|
@ -99,7 +108,7 @@
|
|||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"color": "#696969",
|
||||
"color": "dimgray",
|
||||
"width": "1"
|
||||
}
|
||||
],
|
||||
|
@ -295,6 +304,69 @@
|
|||
"it": "Questo è un posto auto riservato al car sharing.",
|
||||
"nl": "Deze parkeerplek is gereserveerd voor autodelen."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "parking_space=women",
|
||||
"then": {
|
||||
"en": "This is a parking space reserved for women.",
|
||||
"nl": "Deze parkeerplek is gereserveerd voor vrouwen."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "access",
|
||||
"question": {
|
||||
"en": "Who can use this parking space?",
|
||||
"nl": "Wie mag deze parkeerplek gebruiken?"
|
||||
},
|
||||
"render": {
|
||||
"en": "Access of parking space: {access}",
|
||||
"nl": "Toegang tot parkeerplek: {access}"
|
||||
},
|
||||
"freeform": {
|
||||
"key": "access",
|
||||
"type": "string",
|
||||
"addExtraTags": [
|
||||
"fixme=Freeform used on 'access'-tag: possibly a wrong value"
|
||||
]
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "access=",
|
||||
"then": {
|
||||
"en": "Anyone can use this parking space.",
|
||||
"nl": "Iedereen kan deze parkeerplek gebruiken."
|
||||
},
|
||||
"hideInAnswer": true
|
||||
},
|
||||
{
|
||||
"if": "access=yes",
|
||||
"then": {
|
||||
"en": "Anyone can use this parking space.",
|
||||
"nl": "Iedereen kan deze parkeerplek gebruiken."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "access=customers",
|
||||
"then": {
|
||||
"en": "This parking space is reserved for customers.",
|
||||
"nl": "Deze parkeerplek is gereserveerd voor klanten."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "access=private",
|
||||
"then": {
|
||||
"en": "This parking space is private and cannot be used by the general public.",
|
||||
"nl": "Deze parkeerplek is privé en mag niet door het grote publiek worden gebruikt."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "access=permit",
|
||||
"then": {
|
||||
"en": "This parking space is reserved for permit holders.",
|
||||
"nl": "Deze parkeerplek is gereserveerd voor vergunninghouders."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -310,6 +382,19 @@
|
|||
"nl": "Deze parkeerplek heeft {capacity} plaatsen."
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "capacity=",
|
||||
"then": {
|
||||
"en": "This parking space has 1 space.",
|
||||
"ca": "Aquest espai d'aparcament té 1 plaça.",
|
||||
"cs": "Toto parkoviště má 1 místo.",
|
||||
"de": "Dieser Parkplatz hat 1 Stellplatz.",
|
||||
"es": "Esta plaza de aparcamiento tiene 1 plaza.",
|
||||
"it": "Questo posto auto ha 1 spazio.",
|
||||
"nl": "Deze parkeerplek heeft 1 plaats."
|
||||
},
|
||||
"hideInAnswer": true
|
||||
},
|
||||
{
|
||||
"if": "capacity=1",
|
||||
"then": {
|
||||
|
|
304
assets/layers/picnic_site/picnic_site.json
Normal file
304
assets/layers/picnic_site/picnic_site.json
Normal file
|
@ -0,0 +1,304 @@
|
|||
{
|
||||
"id": "picnic_site",
|
||||
"name": {
|
||||
"en": "Picnic sites",
|
||||
"nl": "Picknickplaatsen"
|
||||
},
|
||||
"description": {
|
||||
"en": "Picnic sites for eating outdoors, featuring amenities like toilets, water taps, BBQ, benches and shelters",
|
||||
"nl": "Picknickplaatsen voor het eten in de buitenlucht, met voorzieningen zoals toiletten, waterkranen, BBQ, banken en schuilplaatsen"
|
||||
},
|
||||
"source": {
|
||||
"osmTags": "tourism=picnic_site"
|
||||
},
|
||||
"minzoom": 10,
|
||||
"title": {
|
||||
"render": {
|
||||
"en": "Picnic site",
|
||||
"nl": "Picknickplaats"
|
||||
}
|
||||
},
|
||||
"pointRendering": [
|
||||
{
|
||||
"iconSize": "35,35",
|
||||
"location": [
|
||||
"point",
|
||||
"centroid"
|
||||
],
|
||||
"anchor": "center",
|
||||
"marker": [
|
||||
{
|
||||
"color": "#3984e6",
|
||||
"icon": "circle"
|
||||
},
|
||||
{
|
||||
"icon": "./assets/layers/picnic_table/picnic_table.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"lineRendering": [
|
||||
{
|
||||
"color": "#3984e6",
|
||||
"fillColor": "#3984e6bd",
|
||||
"width": 5
|
||||
}
|
||||
],
|
||||
"presets": [
|
||||
{
|
||||
"tags": [
|
||||
"tourism=picnic_site"
|
||||
],
|
||||
"title": {
|
||||
"en": "a picnic site",
|
||||
"nl": "een picknickplaats"
|
||||
},
|
||||
"description": {
|
||||
"en": "A picnic site for eating outdoors, featuring amenities like toilets, water taps, BBQ, benches and shelters",
|
||||
"nl": "Een picknickplaats voor het eten in de buitenlucht, met voorzieningen zoals toiletten, waterkranen, BBQ, banken en schuilplaatsen"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
"images",
|
||||
{
|
||||
"builtin": "name",
|
||||
"override": {
|
||||
"render": {
|
||||
"en": "This picnic site is called {name}",
|
||||
"nl": "Deze picknickplaats heet {name}"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "shelter",
|
||||
"question": {
|
||||
"en": "Does this picnic site have a shelter?",
|
||||
"nl": "Heeft deze picknickplaats een schuilplaats?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "shelter=yes",
|
||||
"then": {
|
||||
"en": "This picnic site has a shelter.",
|
||||
"nl": "Deze picknickplaats heeft een schuilplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "shelter=no",
|
||||
"then": {
|
||||
"en": "This picnic site does not have a shelter.",
|
||||
"nl": "Deze picknickplaats heeft geen schuilplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "shelter=separate",
|
||||
"then": {
|
||||
"en": "This picnic site has a shelter, but is is mapped as a different icon.",
|
||||
"nl": "Deze picknickplaats heeft een schuilplaats, maar deze staat los op de kaart."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "fireplace",
|
||||
"question": {
|
||||
"en": "Does this picnic site have a firepit?",
|
||||
"nl": "Heeft deze picknickplaats een vuurplaats?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "fireplace=yes",
|
||||
"then": {
|
||||
"en": "This picnic site has a firepit.",
|
||||
"nl": "Deze picknickplaats heeft een vuurplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "fireplace=no",
|
||||
"then": {
|
||||
"en": "This picnic site does not have a firepit.",
|
||||
"nl": "Deze picknickplaats heeft geen vuurplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "fireplace=separate",
|
||||
"then": {
|
||||
"en": "This picnic site has a firepit, but it is mapped as a different icon.",
|
||||
"nl": "Deze picknickplaats heeft een vuurplaats, maar deze staat los op de kaart."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "bbq",
|
||||
"question": {
|
||||
"en": "Does this picnic site have a BBQ?",
|
||||
"nl": "Heeft deze picknickplaats een BBQ?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "bbq=yes",
|
||||
"then": {
|
||||
"en": "This picnic site has a BBQ.",
|
||||
"nl": "Deze picknickplaats heeft een BBQ."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "bbq=no",
|
||||
"then": {
|
||||
"en": "This picnic site does not have a BBQ.",
|
||||
"nl": "Deze picknickplaats heeft geen BBQ."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "bbq=separate",
|
||||
"then": {
|
||||
"en": "This picnic site has a BBQ, but it is mapped as a different icon.",
|
||||
"nl": "Deze picknickplaats heeft een BBQ, maar deze staat los op de kaart."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "covered",
|
||||
"question": {
|
||||
"en": "Is this picnic site covered?",
|
||||
"nl": "Is deze picknickplaats overdekt?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "covered=yes",
|
||||
"then": {
|
||||
"en": "This picnic site is covered.",
|
||||
"nl": "Deze picknickplaats is overdekt."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "covered=no",
|
||||
"then": {
|
||||
"en": "This picnic site is not covered.",
|
||||
"nl": "Deze picknickplaats is niet overdekt."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "drinking_water",
|
||||
"question": {
|
||||
"en": "Does this picnic site have drinking water?",
|
||||
"nl": "Heeft deze picknickplaats drinkwater?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "drinking_water=yes",
|
||||
"then": {
|
||||
"en": "This picnic site has drinking water.",
|
||||
"nl": "Deze picknickplaats heeft drinkwater."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "drinking_water=no",
|
||||
"then": {
|
||||
"en": "This picnic site does not have drinking water.",
|
||||
"nl": "Deze picknickplaats heeft geen drinkwater."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "drinking_water=separate",
|
||||
"then": {
|
||||
"en": "This picnic site has drinking water, but it is mapped as a different icon.",
|
||||
"nl": "Deze picknickplaats heeft drinkwater, maar deze staat los op de kaart."
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "openfire",
|
||||
"question": {
|
||||
"en": "Is open fire allowed at this picnic site?",
|
||||
"nl": "Is open vuur toegestaan op deze picknickplaats?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "openfire=yes",
|
||||
"then": {
|
||||
"en": "Open fire is allowed at this picnic site.",
|
||||
"nl": "Open vuur is toegestaan op deze picknickplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "openfire=no",
|
||||
"then": {
|
||||
"en": "Open fire is not allowed at this picnic site.",
|
||||
"nl": "Open vuur is niet toegestaan op deze picknickplaats."
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "openfire=permit",
|
||||
"then": {
|
||||
"en": "Open fire is allowed at this picnic site with a permit.",
|
||||
"nl": "Open vuur is toegestaan op deze picknickplaats met een vergunning."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
"shelter",
|
||||
{
|
||||
"id": "fireplace",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "With a firepit",
|
||||
"nl": "Met een vuurplaats"
|
||||
},
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"fireplace=yes",
|
||||
"fireplace=separate"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "bbq",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "With a BBQ",
|
||||
"nl": "Met een BBQ"
|
||||
},
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"bbq=yes",
|
||||
"bbq=separate"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "drinking_water",
|
||||
"options": [
|
||||
{
|
||||
"question": {
|
||||
"en": "With drinking water",
|
||||
"nl": "Met drinkwater"
|
||||
},
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"drinking_water=yes",
|
||||
"drinking_water=separate"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"allowMove": {
|
||||
"enableImproveAccuracy": true
|
||||
}
|
||||
}
|
|
@ -3118,7 +3118,8 @@
|
|||
"if": "nobrand=yes",
|
||||
"addExtraTags": [
|
||||
"brand=",
|
||||
"brand:wikidata="
|
||||
"brand:wikidata=",
|
||||
"brand:wikipedia="
|
||||
],
|
||||
"then": {
|
||||
"en": "Not part of a bigger brand",
|
||||
|
@ -3567,6 +3568,81 @@
|
|||
"filter": [
|
||||
"filters.kids_area"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "self_checkout",
|
||||
"labels": [
|
||||
"self_checkout_questions"
|
||||
],
|
||||
"question": {
|
||||
"en": "Does this place offer self-checkout?",
|
||||
"nl": "Biedt deze plaats zelfscannen aan?"
|
||||
},
|
||||
"questionHint": {
|
||||
"en": "e.g. handheld scanners or a self-checkout kiosk",
|
||||
"nl": "bijv. handscanners of een zelfscankassa"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "self_checkout=yes",
|
||||
"then": {
|
||||
"en": "This place offers self-checkout",
|
||||
"nl": "Deze plaats biedt zelfscannen aan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "self_checkout=no",
|
||||
"then": {
|
||||
"en": "This place does not offer self-checkout",
|
||||
"nl": "Deze plaats biedt geen zelfscannen aan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "self_checkout=only",
|
||||
"then": {
|
||||
"en": "This place <b>only</b> offers self-checkout",
|
||||
"nl": "Deze plaats biedt <b>enkel</b> zelfscannen aan"
|
||||
}
|
||||
}
|
||||
],
|
||||
"filter": [
|
||||
"filters.self_checkout"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "self_checkout_type",
|
||||
"labels": [
|
||||
"self_checkout_questions"
|
||||
],
|
||||
"question": {
|
||||
"en": "What kind of self-checkout does this place offer?",
|
||||
"nl": "Wat voor soort zelfscannen biedt deze plaats aan?"
|
||||
},
|
||||
"mappings": [
|
||||
{
|
||||
"if": "self_checkout:handheld=yes",
|
||||
"ifnot": "self_checkout:handheld=no",
|
||||
"then": {
|
||||
"en": "This place offers self-checkout using a handheld scanner",
|
||||
"nl": "Deze plaats biedt zelfscannen met een handscanner aan"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "self_checkout:self_scan=yes",
|
||||
"ifnot": "self_checkout:self_scan=no",
|
||||
"then": {
|
||||
"en": "This place offers self-checkout using a self-checkout kiosk",
|
||||
"nl": "Deze plaats biedt zelfscannen met een zelfscankassa aan"
|
||||
}
|
||||
}
|
||||
],
|
||||
"condition": {
|
||||
"or": [
|
||||
"self_checkout=yes",
|
||||
"self_checkout=only"
|
||||
]
|
||||
},
|
||||
"multiAnswer": true
|
||||
}
|
||||
],
|
||||
"allowMove": false,
|
||||
|
|
|
@ -43,7 +43,8 @@
|
|||
"craft=key_cutter"
|
||||
]
|
||||
},
|
||||
"shop!=mall"
|
||||
"shop!=mall",
|
||||
"shop!=no"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -486,7 +487,12 @@
|
|||
"es": "Esta tienda no tiene una marca específica, no forma parte de una cadena más grande",
|
||||
"it": "Questo negozio non ha un marchio specifico, non fa parte di una catena più grande",
|
||||
"uk": "Цей магазин не має певного бренду, він не є частиною великої мережі"
|
||||
}
|
||||
},
|
||||
"addExtraTags": [
|
||||
"brand=",
|
||||
"brand:wikidata=",
|
||||
"brand:wikipedia="
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -1666,6 +1672,28 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"builtin": "self_checkout",
|
||||
"override": {
|
||||
"+mappings": [
|
||||
{
|
||||
"if": {
|
||||
"and": [
|
||||
"self_checkout=",
|
||||
"shop!=supermarket",
|
||||
"shop!=convenience",
|
||||
"shop!=chemist"
|
||||
]
|
||||
},
|
||||
"then": {
|
||||
"en": "This shop (probably) does not offer self-checkout"
|
||||
},
|
||||
"hideInAnswer": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"self_checkout_type",
|
||||
"description",
|
||||
"toilet_at_amenity_lib.all"
|
||||
],
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"labelCss": "background: #ffffffbb",
|
||||
"labelCssClasses": "w-12 text-lg rounded-xl p-1 px-2"
|
||||
"labelCss": "background: #ffffffcc; min-width: 2rem",
|
||||
"labelCssClasses": "text-lg rounded p-1 px-2 border-2 border-gray font-bold"
|
||||
}
|
||||
],
|
||||
"tagRenderings": [
|
||||
|
|
|
@ -87,6 +87,10 @@
|
|||
"if": "camera:type=doorbell",
|
||||
"then": "./assets/layers/surveillance_camera/doorbell.svg"
|
||||
},
|
||||
{
|
||||
"if": "camera:type=panorama",
|
||||
"then": "./assets/themes/surveillance/panorama.svg"
|
||||
},
|
||||
{
|
||||
"if": "_direction:leftright=right",
|
||||
"then": "./assets/themes/surveillance/cam_right.svg"
|
||||
|
@ -110,6 +114,10 @@
|
|||
]
|
||||
},
|
||||
"then": "50,35,center"
|
||||
},
|
||||
{
|
||||
"if": "camera:type=panorama",
|
||||
"then": "55,55,center"
|
||||
}
|
||||
],
|
||||
"render": "35,35,center"
|
||||
|
@ -407,6 +415,16 @@
|
|||
"ru": "Панорамная камера"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "camera:type=panorama",
|
||||
"icon": "./assets/themes/surveillance/panorama.svg",
|
||||
"then": {
|
||||
"en": "A 360° camera",
|
||||
"de": "Eine 360°-Kamera",
|
||||
"es": "Una cámara de 360°",
|
||||
"fr": "Une caméra 360°"
|
||||
}
|
||||
},
|
||||
{
|
||||
"if": "camera:type=doorbell",
|
||||
"icon": {
|
||||
|
@ -530,7 +548,7 @@
|
|||
"da": "Hvilken form for overvågning er dette kamera?",
|
||||
"de": "Was überwacht diese Kamera?",
|
||||
"es": "¿Qué tipo de vigilancia es esta cámara?",
|
||||
"fr": "De quel genre de surveillance cette caméra est-elle ?",
|
||||
"fr": "De quel genre de surveillance cette caméra est-elle ?",
|
||||
"it": "Che tipo di sorveglianza è questa telecamera?",
|
||||
"nl": "Wat soort bewaking wordt hier uitgevoerd?",
|
||||
"sl": "Kaj nadzoruje ta kamera?"
|
||||
|
|
|
@ -548,28 +548,7 @@
|
|||
}
|
||||
],
|
||||
"filter": [
|
||||
{
|
||||
"id": "shelter",
|
||||
"options": [
|
||||
{
|
||||
"osmTags": {
|
||||
"or": [
|
||||
"shelter=yes",
|
||||
"shelter=separate"
|
||||
]
|
||||
},
|
||||
"question": {
|
||||
"en": "With a shelter",
|
||||
"ca": "Amb refugi",
|
||||
"cs": "S přístřeškem",
|
||||
"de": "Mit Unterstand",
|
||||
"es": "Con refugio",
|
||||
"fr": "Avec un abri",
|
||||
"it": "Con una pensilina"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"shelter",
|
||||
{
|
||||
"id": "bench",
|
||||
"options": [
|
||||
|
|
|
@ -1906,6 +1906,46 @@
|
|||
"render": {
|
||||
"*": "{storage_all_tags()}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "debug_serviceworker_accordeon",
|
||||
"render": {
|
||||
"special": {
|
||||
"header": "debug_serviceworker_accordeon_title",
|
||||
"labels": "debug_serviceworker",
|
||||
"type": "group"
|
||||
}
|
||||
},
|
||||
"condition": "mapcomplete-show_debug=yes"
|
||||
},
|
||||
{
|
||||
"id": "debug_serviceworker_accordeon_title",
|
||||
"labels": [
|
||||
"hidden"
|
||||
],
|
||||
"render": {
|
||||
"en": "Debug information about the service worker"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "expl",
|
||||
"labels": [
|
||||
"debug_serviceworker",
|
||||
"hidden"
|
||||
],
|
||||
"render": {
|
||||
"en": "To clear the service worker data, use the 'clear caches' button"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "service_worker_tags",
|
||||
"labels": [
|
||||
"debug_serviceworker",
|
||||
"hidden"
|
||||
],
|
||||
"render": {
|
||||
"*": "{serviceworker_all_tags()}"
|
||||
}
|
||||
}
|
||||
],
|
||||
"allowMove": false
|
||||
|
|
13
assets/themes/arcade/arcade.json
Normal file
13
assets/themes/arcade/arcade.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"id": "arcade",
|
||||
"title": {
|
||||
"en": "Arcades"
|
||||
},
|
||||
"description": {
|
||||
"en": "A map of arcades"
|
||||
},
|
||||
"icon": "./assets/layers/arcade/arcade.svg",
|
||||
"layers": [
|
||||
"arcade"
|
||||
]
|
||||
}
|
|
@ -701,6 +701,7 @@
|
|||
{
|
||||
"builtin": "current_view",
|
||||
"override": {
|
||||
"popupInFloatover": "title",
|
||||
"calculatedTags+": [
|
||||
"_overlapping=Number(feat.properties.zoom) >= 14 ? overlapWith(feat)('grb').map(ff => ff.feat.properties) : undefined",
|
||||
"_applicable_conflate=get(feat)('_overlapping')?.filter(p => p._imported !== 'yes' && (!p['_imported_osm_still_fresh'] || !p['_imported_osm_object_found']) && p['_overlap_absolute'] > 10 && p['_overlap_percentage'] > 80 && p['_reverse_overlap_percentage'] > 80)?.map(p => p.id)",
|
||||
|
|
|
@ -38,6 +38,9 @@
|
|||
"zh_Hant": "顯示由MapComplete進行的變動"
|
||||
},
|
||||
"icon": "./assets/svg/logo.svg",
|
||||
"startZoom": 1,
|
||||
"startLat": 0,
|
||||
"startLon": 0,
|
||||
"hideFromOverview": true,
|
||||
"layers": [
|
||||
{
|
||||
|
|
|
@ -60,12 +60,14 @@
|
|||
"nature_reserve",
|
||||
{
|
||||
"builtin": [
|
||||
"hut",
|
||||
"shelter"
|
||||
],
|
||||
"override": {
|
||||
"minzoom": 11
|
||||
}
|
||||
},
|
||||
"picnic_site",
|
||||
{
|
||||
"builtin": [
|
||||
"map",
|
||||
|
|
|
@ -598,6 +598,7 @@
|
|||
{
|
||||
"builtin": "current_view",
|
||||
"override": {
|
||||
"popupInFloatover": "title",
|
||||
"+pointRendering": [
|
||||
{
|
||||
"location": [
|
||||
|
|
|
@ -65,7 +65,10 @@
|
|||
"parking_spaces",
|
||||
"parking_ticket_machine",
|
||||
{
|
||||
"builtin": "charging_station",
|
||||
"builtin": [
|
||||
"charging_station",
|
||||
"charge_point"
|
||||
],
|
||||
"override": {
|
||||
"minzoom": 18
|
||||
}
|
||||
|
|
|
@ -30,5 +30,13 @@
|
|||
"Pieter Vander Vennet"
|
||||
],
|
||||
"sources": []
|
||||
},
|
||||
{
|
||||
"path": "panorama.svg",
|
||||
"license": "CC0-1.0",
|
||||
"authors": [
|
||||
"Martin Bodin"
|
||||
],
|
||||
"sources": []
|
||||
}
|
||||
]
|
109
assets/themes/surveillance/panorama.svg
Normal file
109
assets/themes/surveillance/panorama.svg
Normal file
|
@ -0,0 +1,109 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="375px"
|
||||
height="375px"
|
||||
viewBox="0 0 375 375"
|
||||
version="1.1"
|
||||
id="svg11"
|
||||
sodipodi:docname="panorama.svg"
|
||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata17">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs15" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffff00"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1005"
|
||||
id="namedview13"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.4737475"
|
||||
inkscape:cx="139.44044"
|
||||
inkscape:cy="113.65583"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="surface1"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<g
|
||||
id="surface1">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:4.36475;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
|
||||
d="M 11.439583,18.537673 H 87.78125 c 12.54792,0.03646 12.93854,8.290452 0,8.132119 H 11.439583 c -11.3604163,0.03333 -11.219791,-8.256077 0,-8.132119 z"
|
||||
id="path2"
|
||||
transform="scale(3.75)"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:20.1633;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
|
||||
d="m 34.717843,101.6866 c -1.27924,30.38368 1.929466,64.43545 24.151706,87.39173 20.294338,20.64802 52.480961,21.69978 78.731761,13.98482 26.2715,-8.688 54.77731,-12.42906 81.94054,-5.61303 20.40318,5.18001 41.09215,12.65231 62.49302,9.2938 25.93999,-2.45941 47.41513,-22.63158 54.71719,-47.13887 6.25508,-18.57863 7.37452,-38.46461 6.50031,-57.91845 -102.84484,0.015 -205.68968,0.015 -308.534527,0 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
id="g889-5"
|
||||
transform="matrix(0.93922526,0,0,0.93922526,79.006064,2.8192093)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6-3"
|
||||
d="m 138.94637,153.12112 c 0,12.14155 -10.48036,21.98508 -23.40956,21.98508 -12.9292,0 -23.40956,-9.84353 -23.40956,-21.98508 0,-12.14156 10.48036,-21.98509 23.40956,-21.98509 12.9292,0 23.40956,9.84353 23.40956,21.98509 z m 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8-5"
|
||||
d="m 129.9261,153.53588 c 0,7.78853 -6.53792,14.1044 -14.60506,14.1044 -8.06503,0 -14.60295,-6.31587 -14.60295,-14.1044 0,-7.78852 6.53792,-14.10228 14.60295,-14.10228 8.06714,0 14.60506,6.31376 14.60506,14.10228 z m 0,0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
</g>
|
||||
<g
|
||||
id="g889-5-6"
|
||||
transform="matrix(0.69882528,0,0,0.93922526,220.19065,2.8192093)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6-3-2"
|
||||
d="m 138.94637,153.12112 c 0,12.14155 -10.48036,21.98508 -23.40956,21.98508 -12.9292,0 -23.40956,-9.84353 -23.40956,-21.98508 0,-12.14156 10.48036,-21.98509 23.40956,-21.98509 12.9292,0 23.40956,9.84353 23.40956,21.98509 z m 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8-5-9"
|
||||
d="m 129.9261,153.53588 c 0,7.78853 -6.53792,14.1044 -14.60506,14.1044 -8.06503,0 -14.60295,-6.31587 -14.60295,-14.1044 0,-7.78852 6.53792,-14.10228 14.60295,-14.10228 8.06714,0 14.60506,6.31376 14.60506,14.10228 z m 0,0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
</g>
|
||||
<g
|
||||
id="g889-5-6-1"
|
||||
transform="matrix(0.69882528,0,0,0.93922526,-6.6284342,2.8192093)">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path6-3-2-2"
|
||||
d="m 138.94637,153.12112 c 0,12.14155 -10.48036,21.98508 -23.40956,21.98508 -12.9292,0 -23.40956,-9.84353 -23.40956,-21.98508 0,-12.14156 10.48036,-21.98509 23.40956,-21.98509 12.9292,0 23.40956,9.84353 23.40956,21.98509 z m 0,0"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8-5-9-7"
|
||||
d="m 129.9261,153.53588 c 0,7.78853 -6.53792,14.1044 -14.60506,14.1044 -8.06503,0 -14.60295,-6.31587 -14.60295,-14.1044 0,-7.78852 6.53792,-14.10228 14.60295,-14.10228 8.06714,0 14.60506,6.31376 14.60506,14.10228 z m 0,0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.536273" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.4 KiB |
2
assets/themes/surveillance/panorama.svg.license
Normal file
2
assets/themes/surveillance/panorama.svg.license
Normal file
|
@ -0,0 +1,2 @@
|
|||
SPDX-FileCopyrightText: Martin Bodin
|
||||
SPDX-License-Identifier: CC0-1.0
|
|
@ -56,7 +56,7 @@
|
|||
"render": {
|
||||
"special": {
|
||||
"type": "import_button",
|
||||
"targetLayer": "transit_stops",
|
||||
"targetLayer": "all_transit_stops",
|
||||
"tags": "_tags",
|
||||
"text": {
|
||||
"en": "Add this stop",
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
<script src="./src/Logic/Web/AndroidPolyfill.ts" type="module"></script>
|
||||
<script type="module" src="./src/all_themes_index.ts"></script>
|
||||
|
||||
<script async src="./src/InstallServiceWorker.ts" type="module"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
"allFilteredAway": "No feature in view meets all filters",
|
||||
"loadingData": "Loading data…",
|
||||
"noData": "There are no relevant features in the current view",
|
||||
"noDataOffline": "No data is loaded and you are offline",
|
||||
"ready": "Done!",
|
||||
"retrying": "Loading data failed. Trying again in {count} seconds…",
|
||||
"zoomIn": "Zoom in to view or edit the data"
|
||||
|
@ -319,6 +320,7 @@
|
|||
"menu": {
|
||||
"aboutCurrentThemeTitle": "About this map",
|
||||
"aboutMapComplete": "About MapComplete",
|
||||
"downloadApp": "Download the app for Android",
|
||||
"filter": "Filter data",
|
||||
"legal": "Legal notices",
|
||||
"moreUtilsTitle": "Discover more",
|
||||
|
@ -339,6 +341,7 @@
|
|||
"next": "Next",
|
||||
"noTagsSelected": "No tags selected",
|
||||
"number": "number",
|
||||
"offline": "Your device is offline",
|
||||
"openTheMap": "Open the map",
|
||||
"openTheMapReason": "to view, edit and add information",
|
||||
"opening_hours": {
|
||||
|
@ -642,6 +645,8 @@
|
|||
"uploading": "{count} images are being uploaded…"
|
||||
},
|
||||
"noBlur": "Images will not be blurred. Do not photograph people",
|
||||
"offline": "You are currently offline. Uploading images be attempted when your internet is back",
|
||||
"offlinePending": "{count} images are currently in the queue",
|
||||
"one": {
|
||||
"done": "Your image was successfully uploaded. Thank you!",
|
||||
"failed": "Sorry, we could not upload your image",
|
||||
|
@ -656,7 +661,7 @@
|
|||
"confirmDeleteTitle": "Delete this image?",
|
||||
"delete": "Delete this image",
|
||||
"intro": "The following images are queued for upload",
|
||||
"menu": "Image upload queue ({count})",
|
||||
"menu": "Pending changes and image uploads ({count})",
|
||||
"noFailedImages": "There are currently no images in the upload queue",
|
||||
"retryAll": "Retry uploading all images"
|
||||
},
|
||||
|
|
|
@ -2278,16 +2278,6 @@
|
|||
"campsite": {
|
||||
"description": "Càmpings",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Taxa"
|
||||
},
|
||||
"1": {
|
||||
"question": "Gratuït"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -2478,17 +2468,6 @@
|
|||
},
|
||||
"question": "Aquest lloc té una estació d'abocament sanitari?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Aquest lloc té lavabos"
|
||||
},
|
||||
"1": {
|
||||
"then": "Aquest lloc no té lavabos"
|
||||
}
|
||||
},
|
||||
"question": "Aquest lloc té lavabos?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Aquest lloc té un lloc web?",
|
||||
"render": "Lloc web oficial: <a href='{website}'>{website}</a>"
|
||||
|
@ -5520,6 +5499,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Amb refugi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -8006,6 +7992,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Aquest espai d'aparcament té 1 plaça."
|
||||
},
|
||||
"1": {
|
||||
"then": "Aquest espai d'aparcament té 1 plaça."
|
||||
}
|
||||
},
|
||||
"render": "Aquests espais d'aparcament tenen {capacity} places."
|
||||
|
@ -11566,7 +11555,7 @@
|
|||
"2": {
|
||||
"then": "Una càmera panoràmica"
|
||||
},
|
||||
"3": {
|
||||
"4": {
|
||||
"then": "Un timbre que es pot activar remotament en qualsevol moment o mitjançant la detecció de moviment. Aquests són típicament <i>Smart</i>, banderes connectades a Internet. Les marques típiques són Ring, Google Nest, Eufy, ..."
|
||||
}
|
||||
},
|
||||
|
@ -12449,13 +12438,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Capa que mostra diferents tipus de parades de transport públic.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Amb refugi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -2454,16 +2454,6 @@
|
|||
"campsite": {
|
||||
"description": "Kempy",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Poplatek"
|
||||
},
|
||||
"1": {
|
||||
"question": "zdarma"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -2673,17 +2663,6 @@
|
|||
},
|
||||
"question": "Má toto místo sanitární skládku?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Toto místo má toalety"
|
||||
},
|
||||
"1": {
|
||||
"then": "Toto místo nemá toalety"
|
||||
}
|
||||
},
|
||||
"question": "Má toto místo toalety?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Má toto místo webové stránky?",
|
||||
"render": "Oficiální webové stránky: <a href='{website}'>{website}</a>"
|
||||
|
@ -5841,6 +5820,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "S přístřeškem"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -8633,6 +8619,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Toto parkoviště má 1 místo."
|
||||
},
|
||||
"1": {
|
||||
"then": "Toto parkoviště má 1 místo."
|
||||
}
|
||||
},
|
||||
"render": "Toto parkoviště má {capacity} míst."
|
||||
|
@ -12510,7 +12499,7 @@
|
|||
"2": {
|
||||
"then": "Otáčecí kamera"
|
||||
},
|
||||
"3": {
|
||||
"4": {
|
||||
"then": "Domovní zvonek, který lze spouštět kdykoli vzdáleně nebo detekcí pohybu. Jsou to typicky <i>chytré</i> zvonky připojené k Internetu. Typické značky jsou Ring, Google Nest, Eufy…"
|
||||
}
|
||||
},
|
||||
|
@ -13556,13 +13545,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Vrstva zobrazující různé typy zastávek veřejné dopravy.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "S přístřeškem"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -225,13 +225,6 @@
|
|||
},
|
||||
"campsite": {
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Ffi"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"7": {
|
||||
|
|
|
@ -1561,17 +1561,6 @@
|
|||
},
|
||||
"question": "Har dette sted en sanitær tømningsstation?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dette sted har toiletter"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dette sted har ikke toiletter"
|
||||
}
|
||||
},
|
||||
"question": "Har dette sted toiletter?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Har dette sted et websted?",
|
||||
"render": "Officiel hjemmeside: <a href='{website}'>{website}</a>"
|
||||
|
@ -3152,7 +3141,7 @@
|
|||
"2": {
|
||||
"then": "Et kamera, der panorerer"
|
||||
},
|
||||
"3": {
|
||||
"4": {
|
||||
"then": "En dørklokke, som kan tændes på afstand når som helst eller ved bevægelsesregistrering. Disse er typisk <i>intelligente</i> internetforbundne dørklokker. Typiske mærker er Ring, Google Nest, Eufy, …"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2241,16 +2241,6 @@
|
|||
"campsite": {
|
||||
"description": "Zeltplätze",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Gebühr"
|
||||
},
|
||||
"1": {
|
||||
"question": "kostenlos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -2460,17 +2450,6 @@
|
|||
},
|
||||
"question": "Hat dieser Ort eine sanitäre Entsorgungsstation?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Ort verfügt über Toiletten"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Ort verfügt nicht über Toiletten"
|
||||
}
|
||||
},
|
||||
"question": "Verfügt dieser Ort über Toiletten?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Hat dieser Ort eine Webseite?",
|
||||
"render": "Offizielle Webseite: <a href='{website}'>{website}</a>"
|
||||
|
@ -5509,6 +5488,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Mit Unterstand"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -7981,6 +7967,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Parkplatz hat 1 Stellplatz."
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Parkplatz hat 1 Stellplatz."
|
||||
}
|
||||
},
|
||||
"render": "Dieser Parkplatz hat {capacity} Stellplätze."
|
||||
|
@ -11581,6 +11570,9 @@
|
|||
"then": "Eine bewegliche Kamera"
|
||||
},
|
||||
"3": {
|
||||
"then": "Eine 360°-Kamera"
|
||||
},
|
||||
"4": {
|
||||
"then": "Eine Türklingel, die jederzeit oder per Bewegungserkennung ferngeschaltet werden kann. Dies sind typischerweise <i>Smart</i>, internetgebundene Türklingeln. Typische Marken sind Ring, Google Nest, Eufy, ..."
|
||||
}
|
||||
},
|
||||
|
@ -12463,13 +12455,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Ebene mit verschiedenen Arten von Haltestellen.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Mit Unterstand"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -531,6 +531,40 @@
|
|||
"render": "Animal shelter"
|
||||
}
|
||||
},
|
||||
"arcade": {
|
||||
"description": "Layer showing arcades",
|
||||
"name": "Arcades",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "an arcade"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"name": {
|
||||
"override": {
|
||||
"question": "What is the name of this arcade?",
|
||||
"render": "This arcade is called <b>{name}</b>"
|
||||
}
|
||||
},
|
||||
"virtual_reality": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This arcade offers virtual-reality gaming."
|
||||
},
|
||||
"1": {
|
||||
"then": "This arcade <b>only</b> offers virtual-reality gaming."
|
||||
},
|
||||
"2": {
|
||||
"then": "This arcade doesn't offer virtual-reality gaming"
|
||||
}
|
||||
},
|
||||
"question": "Does this arcade offer virtual-reality gaming?"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Arcade"
|
||||
}
|
||||
},
|
||||
"artwork": {
|
||||
"description": "An open map of statues, busts, graffitis and other artwork all over the world",
|
||||
"name": "Artworks",
|
||||
|
@ -2454,16 +2488,6 @@
|
|||
"campsite": {
|
||||
"description": "Campsites",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Fee"
|
||||
},
|
||||
"1": {
|
||||
"question": "free of charge"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -2673,17 +2697,6 @@
|
|||
},
|
||||
"question": "Does this place have a sanitary dump station?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This place has toilets"
|
||||
},
|
||||
"1": {
|
||||
"then": "This place does not have toilets"
|
||||
}
|
||||
},
|
||||
"question": "Does this place have toilets?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Does this place have a website?",
|
||||
"render": "Official website: <a href='{website}'>{website}</a>"
|
||||
|
@ -5841,6 +5854,20 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"22": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Has self-checkout"
|
||||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "With a shelter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -7019,6 +7046,37 @@
|
|||
"render": "Hospital"
|
||||
}
|
||||
},
|
||||
"hut": {
|
||||
"description": "Layer showing basic huts, wilderness huts and alpine huts",
|
||||
"name": "Huts",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "An unserviced fully enclosed hut (with roof and walls) with beds or suitable sleeping areas and a fireplace or stove for heating and cooking.",
|
||||
"title": "wilderness hut"
|
||||
},
|
||||
"1": {
|
||||
"description": "A serviced remote building located in the mountains intended to provide board and lodging.",
|
||||
"title": "alpine hut"
|
||||
},
|
||||
"2": {
|
||||
"description": "An unserviced fully enclosed hut (with roof and walls) with beds or suitable sleeping areas <b>without</b> a fireplace or stove.",
|
||||
"title": "basic hut"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"drinking_water": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Here is drinking water available."
|
||||
},
|
||||
"1": {
|
||||
"then": "Here is no drinking water available."
|
||||
}
|
||||
},
|
||||
"question": "Is drinking water available here?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"hydrant": {
|
||||
"description": "Map layer to show fire hydrants.",
|
||||
"name": "Hydrants",
|
||||
|
@ -8629,10 +8687,34 @@
|
|||
"description": "Layer showing individual parking spaces.",
|
||||
"name": "Parking Spaces",
|
||||
"tagRenderings": {
|
||||
"access": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Anyone can use this parking space."
|
||||
},
|
||||
"1": {
|
||||
"then": "Anyone can use this parking space."
|
||||
},
|
||||
"2": {
|
||||
"then": "This parking space is reserved for customers."
|
||||
},
|
||||
"3": {
|
||||
"then": "This parking space is private and cannot be used by the general public."
|
||||
},
|
||||
"4": {
|
||||
"then": "This parking space is reserved for permit holders."
|
||||
}
|
||||
},
|
||||
"question": "Who can use this parking space?",
|
||||
"render": "Access of parking space: {access}"
|
||||
},
|
||||
"capacity": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This parking space has 1 space."
|
||||
},
|
||||
"1": {
|
||||
"then": "This parking space has 1 space."
|
||||
}
|
||||
},
|
||||
"render": "This parking spaces has {capacity} spaces."
|
||||
|
@ -8657,6 +8739,9 @@
|
|||
"13": {
|
||||
"then": "This is a parking space reserved for car sharing."
|
||||
},
|
||||
"14": {
|
||||
"then": "This is a parking space reserved for women."
|
||||
},
|
||||
"2": {
|
||||
"then": "This is a disabled parking space."
|
||||
},
|
||||
|
@ -8788,6 +8873,130 @@
|
|||
"render": "Physiotherapist {name}"
|
||||
}
|
||||
},
|
||||
"picnic_site": {
|
||||
"description": "Picnic sites for eating outdoors, featuring amenities like toilets, water taps, BBQ, benches and shelters",
|
||||
"filter": {
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "With a firepit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "With a BBQ"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "With drinking water"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Picnic sites",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "A picnic site for eating outdoors, featuring amenities like toilets, water taps, BBQ, benches and shelters",
|
||||
"title": "a picnic site"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"bbq": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This picnic site has a BBQ."
|
||||
},
|
||||
"1": {
|
||||
"then": "This picnic site does not have a BBQ."
|
||||
},
|
||||
"2": {
|
||||
"then": "This picnic site has a BBQ, but it is mapped as a different icon."
|
||||
}
|
||||
},
|
||||
"question": "Does this picnic site have a BBQ?"
|
||||
},
|
||||
"covered": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This picnic site is covered."
|
||||
},
|
||||
"1": {
|
||||
"then": "This picnic site is not covered."
|
||||
}
|
||||
},
|
||||
"question": "Is this picnic site covered?"
|
||||
},
|
||||
"drinking_water": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This picnic site has drinking water."
|
||||
},
|
||||
"1": {
|
||||
"then": "This picnic site does not have drinking water."
|
||||
},
|
||||
"2": {
|
||||
"then": "This picnic site has drinking water, but it is mapped as a different icon."
|
||||
}
|
||||
},
|
||||
"question": "Does this picnic site have drinking water?"
|
||||
},
|
||||
"fireplace": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This picnic site has a firepit."
|
||||
},
|
||||
"1": {
|
||||
"then": "This picnic site does not have a firepit."
|
||||
},
|
||||
"2": {
|
||||
"then": "This picnic site has a firepit, but it is mapped as a different icon."
|
||||
}
|
||||
},
|
||||
"question": "Does this picnic site have a firepit?"
|
||||
},
|
||||
"name": {
|
||||
"override": {
|
||||
"render": "This picnic site is called {name}"
|
||||
}
|
||||
},
|
||||
"openfire": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Open fire is allowed at this picnic site."
|
||||
},
|
||||
"1": {
|
||||
"then": "Open fire is not allowed at this picnic site."
|
||||
},
|
||||
"2": {
|
||||
"then": "Open fire is allowed at this picnic site with a permit."
|
||||
}
|
||||
},
|
||||
"question": "Is open fire allowed at this picnic site?"
|
||||
},
|
||||
"shelter": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This picnic site has a shelter."
|
||||
},
|
||||
"1": {
|
||||
"then": "This picnic site does not have a shelter."
|
||||
},
|
||||
"2": {
|
||||
"then": "This picnic site has a shelter, but is is mapped as a different icon."
|
||||
}
|
||||
},
|
||||
"question": "Does this picnic site have a shelter?"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Picnic site"
|
||||
}
|
||||
},
|
||||
"picnic_table": {
|
||||
"description": "The layer showing picnic tables",
|
||||
"name": "Picnic tables",
|
||||
|
@ -9978,6 +10187,32 @@
|
|||
},
|
||||
"question": "What kind of seating does {title()} have?"
|
||||
},
|
||||
"self_checkout": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This place offers self-checkout"
|
||||
},
|
||||
"1": {
|
||||
"then": "This place does not offer self-checkout"
|
||||
},
|
||||
"2": {
|
||||
"then": "This place <b>only</b> offers self-checkout"
|
||||
}
|
||||
},
|
||||
"question": "Does this place offer self-checkout?",
|
||||
"questionHint": "e.g. handheld scanners or a self-checkout kiosk"
|
||||
},
|
||||
"self_checkout_type": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "This place offers self-checkout using a handheld scanner"
|
||||
},
|
||||
"1": {
|
||||
"then": "This place offers self-checkout using a self-checkout kiosk"
|
||||
}
|
||||
},
|
||||
"question": "What kind of self-checkout does this place offer?"
|
||||
},
|
||||
"service:electricity": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
|
@ -11230,6 +11465,15 @@
|
|||
"second_hand": {
|
||||
"question": "Does this shop sell second-hand items?"
|
||||
},
|
||||
"self_checkout": {
|
||||
"override": {
|
||||
"+mappings": {
|
||||
"0": {
|
||||
"then": "This shop (probably) does not offer self-checkout"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"sells_new_bikes": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
|
@ -12511,6 +12755,9 @@
|
|||
"then": "A panning camera"
|
||||
},
|
||||
"3": {
|
||||
"then": "A 360° camera"
|
||||
},
|
||||
"4": {
|
||||
"then": "A doorbell which might be turned on remotely at any time or by motion detection. These are typically <i>Smart</i>, internet-connected doorbells. Typical brands are Ring, Google Nest, Eufy, …"
|
||||
}
|
||||
},
|
||||
|
@ -13556,13 +13803,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Layer showing different types of transit stops.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "With a shelter"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -14108,6 +14348,9 @@
|
|||
"debug_accordeon_title": {
|
||||
"render": "Debug information"
|
||||
},
|
||||
"debug_serviceworker_accordeon_title": {
|
||||
"render": "Debug information about the service worker"
|
||||
},
|
||||
"debug_storage_accordeon_title": {
|
||||
"render": "Debug information about local storage"
|
||||
},
|
||||
|
@ -14118,6 +14361,9 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"expl": {
|
||||
"render": "To clear the service worker data, use the 'clear caches' button"
|
||||
},
|
||||
"fixate-north": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
|
|
|
@ -2270,17 +2270,6 @@
|
|||
},
|
||||
"question": "¿Este lugar tiene un punto de vaciado de aguas grises?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este lugar tiene baños"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este lugar no tiene baños"
|
||||
}
|
||||
},
|
||||
"question": "¿Este lugar tiene baños?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "¿Este lugar tiene una página web?",
|
||||
"render": "Página web oficial: <a href='{website}'>{website}</a>"
|
||||
|
@ -5162,6 +5151,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Con refugio"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -7594,6 +7590,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta plaza de aparcamiento tiene 1 plaza."
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta plaza de aparcamiento tiene 1 plaza."
|
||||
}
|
||||
},
|
||||
"render": "Esta plaza de aparcamiento tiene {capacity} plazas."
|
||||
|
@ -10582,6 +10581,9 @@
|
|||
},
|
||||
"2": {
|
||||
"then": "Una cámara panorámica"
|
||||
},
|
||||
"3": {
|
||||
"then": "Una cámara de 360°"
|
||||
}
|
||||
},
|
||||
"question": "¿Qué tipo de cámara es esta?"
|
||||
|
@ -11317,13 +11319,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Capa que muestra diferentes tipos de paradas de transporte.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Con refugio"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -289,13 +289,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"1": {
|
||||
"then": "Toki honek ez dauka komunik"
|
||||
}
|
||||
}
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Toki honek webgunerik ba al du?"
|
||||
}
|
||||
|
|
|
@ -1873,17 +1873,6 @@
|
|||
},
|
||||
"question": "Ce site possède-t’il un lieu de vidange ?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce site a des toilettes"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce site n’a pas de toilettes"
|
||||
}
|
||||
},
|
||||
"question": "Y-a-t’il des toilettes sur le site ?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Ce lieu a-t’il un site internet ?",
|
||||
"render": "Site officiel : <a href='{website}'>{website}</a>"
|
||||
|
@ -3609,6 +3598,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Avec un abri"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -6519,6 +6515,9 @@
|
|||
},
|
||||
"2": {
|
||||
"then": "Une caméra panoramique"
|
||||
},
|
||||
"3": {
|
||||
"then": "Une caméra 360°"
|
||||
}
|
||||
},
|
||||
"question": "Quel genre de caméra est-ce ?"
|
||||
|
@ -6543,7 +6542,7 @@
|
|||
"then": "Une zone intérieure privée est surveillée, par exemple un magasin, un parking souterrain privé…"
|
||||
}
|
||||
},
|
||||
"question": "De quel genre de surveillance cette caméra est-elle ?"
|
||||
"question": "De quel genre de surveillance cette caméra est-elle ?"
|
||||
},
|
||||
"Surveillance:zone": {
|
||||
"mappings": {
|
||||
|
@ -6916,13 +6915,6 @@
|
|||
},
|
||||
"transit_stops": {
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Avec un abri"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -466,19 +466,6 @@
|
|||
"description": "Új hivatalos lakóautóhely hozzáadása. Ez arra vannak kijelölve, hogy lakóautóval ott éjszakázzunk. Lehet, hogy úgy néz ki, mint egy igazi kemping, de az is lehet, hogy csak olyan, mint egy parkoló. Előfordulhat, hogy egyáltalán nem jelzik őket, hanem csak egy önkormányzati határozatban vannak kijelölve. A lakóautósoknak szánt olyan hagyományos parkolók, ahol nem várhatóan nem fognak éjszakázni, -nem minősül- lakóautóhelynek. ",
|
||||
"title": "lakóautós megállóhely"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Itt van WC"
|
||||
},
|
||||
"1": {
|
||||
"then": "Itt nincs WC"
|
||||
}
|
||||
},
|
||||
"question": "Van-e itt WC?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"charging_station": {
|
||||
|
|
|
@ -196,16 +196,6 @@
|
|||
},
|
||||
"question": "Apakah tempat ini memiliki tempat pembuangan sanitasi?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Tempat sini ada tandas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Tempat sini tiada tandas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Tempat sini terada situs web?",
|
||||
"render": "Situs resmi: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -2423,16 +2423,6 @@
|
|||
"campsite": {
|
||||
"description": "Campeggi",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "A pagamento"
|
||||
},
|
||||
"1": {
|
||||
"question": "gratuito"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -2642,17 +2632,6 @@
|
|||
},
|
||||
"question": "Questo posto ha una stazione di scarico sanitario?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Questo posto ha servizi igienici"
|
||||
},
|
||||
"1": {
|
||||
"then": "Questo posto non ha servizi igienici"
|
||||
}
|
||||
},
|
||||
"question": "Questo posto ha servizi igienici?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Questo posto ha un sito web?",
|
||||
"render": "Sito web ufficiale: <a href='{website}'>{website}</a>"
|
||||
|
@ -5768,6 +5747,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"23": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Con una pensilina"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -8469,6 +8455,9 @@
|
|||
"mappings": {
|
||||
"0": {
|
||||
"then": "Questo posto auto ha 1 spazio."
|
||||
},
|
||||
"1": {
|
||||
"then": "Questo posto auto ha 1 spazio."
|
||||
}
|
||||
},
|
||||
"render": "Questo posto auto ha {capacity} spazi."
|
||||
|
@ -12119,7 +12108,7 @@
|
|||
"2": {
|
||||
"then": "Una telecamera panoramica"
|
||||
},
|
||||
"3": {
|
||||
"4": {
|
||||
"then": "Un campanello che potrebbe essere acceso da remoto in qualsiasi momento o tramite rilevamento del movimento. Questi sono tipicamente campanelli <i>Smart</i>, connessi a Internet. Marchi tipici sono Ring, Google Nest, Eufy, ..."
|
||||
}
|
||||
},
|
||||
|
@ -13134,13 +13123,6 @@
|
|||
"transit_stops": {
|
||||
"description": "Livello che mostra diversi tipi di fermate dei mezzi pubblici.",
|
||||
"filter": {
|
||||
"0": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Con una pensilina"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
|
|
@ -217,17 +217,6 @@
|
|||
},
|
||||
"question": "この場所に衛生的なゴミ捨て場はありますか?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "ここにはトイレがある"
|
||||
},
|
||||
"1": {
|
||||
"then": "ここにはトイレがない"
|
||||
}
|
||||
},
|
||||
"question": "ここにトイレはありますか?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "ここにはウェブサイトがありますか?",
|
||||
"render": "公式Webサイト: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -443,17 +443,6 @@
|
|||
"question": "Hva heter dette stedet?",
|
||||
"render": "Dette stedet heter {name}"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dette stedet har toalettfasiliteter"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dette stedet har ikke toalettfasiliteter"
|
||||
}
|
||||
},
|
||||
"question": "Har dette stedet toaletter?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Har dette stedet en nettside?",
|
||||
"render": "Offisiell nettside: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -2543,17 +2543,6 @@
|
|||
},
|
||||
"question": "Heeft deze plaats een loosplaats?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze plaats heeft toiletten"
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze plaats heeft geen toiletten"
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze plaats toiletten?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Heeft deze plaats een website?",
|
||||
"render": "Officiële website: : <a href='{website}'>{website}</a>"
|
||||
|
@ -5516,6 +5505,13 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"22": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Heeft zelfscan"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"options": {
|
||||
"0": {
|
||||
|
@ -7607,10 +7603,34 @@
|
|||
"description": "Laag met individuele parkeerplekken.",
|
||||
"name": "Parkeerplekken",
|
||||
"tagRenderings": {
|
||||
"access": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Iedereen kan deze parkeerplek gebruiken."
|
||||
},
|
||||
"1": {
|
||||
"then": "Iedereen kan deze parkeerplek gebruiken."
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor klanten."
|
||||
},
|
||||
"3": {
|
||||
"then": "Deze parkeerplek is privé en mag niet door het grote publiek worden gebruikt."
|
||||
},
|
||||
"4": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor vergunninghouders."
|
||||
}
|
||||
},
|
||||
"question": "Wie mag deze parkeerplek gebruiken?",
|
||||
"render": "Toegang tot parkeerplek: {access}"
|
||||
},
|
||||
"capacity": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze parkeerplek heeft 1 plaats."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze parkeerplek heeft 1 plaats."
|
||||
}
|
||||
},
|
||||
"render": "Deze parkeerplek heeft {capacity} plaatsen."
|
||||
|
@ -7635,6 +7655,9 @@
|
|||
"13": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor autodelen."
|
||||
},
|
||||
"14": {
|
||||
"then": "Deze parkeerplek is gereserveerd voor vrouwen."
|
||||
},
|
||||
"2": {
|
||||
"then": "Dit is een gehandicaptenparkeerplaats."
|
||||
},
|
||||
|
@ -7765,6 +7788,130 @@
|
|||
"render": "Kinesist {name}"
|
||||
}
|
||||
},
|
||||
"picnic_site": {
|
||||
"description": "Picknickplaatsen voor het eten in de buitenlucht, met voorzieningen zoals toiletten, waterkranen, BBQ, banken en schuilplaatsen",
|
||||
"filter": {
|
||||
"1": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Met een vuurplaats"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Met een BBQ"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"options": {
|
||||
"0": {
|
||||
"question": "Met drinkwater"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Picknickplaatsen",
|
||||
"presets": {
|
||||
"0": {
|
||||
"description": "Een picknickplaats voor het eten in de buitenlucht, met voorzieningen zoals toiletten, waterkranen, BBQ, banken en schuilplaatsen",
|
||||
"title": "een picknickplaats"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"bbq": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze picknickplaats heeft een BBQ."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze picknickplaats heeft geen BBQ."
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze picknickplaats heeft een BBQ, maar deze staat los op de kaart."
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze picknickplaats een BBQ?"
|
||||
},
|
||||
"covered": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze picknickplaats is overdekt."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze picknickplaats is niet overdekt."
|
||||
}
|
||||
},
|
||||
"question": "Is deze picknickplaats overdekt?"
|
||||
},
|
||||
"drinking_water": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze picknickplaats heeft drinkwater."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze picknickplaats heeft geen drinkwater."
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze picknickplaats heeft drinkwater, maar deze staat los op de kaart."
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze picknickplaats drinkwater?"
|
||||
},
|
||||
"fireplace": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze picknickplaats heeft een vuurplaats."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze picknickplaats heeft geen vuurplaats."
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze picknickplaats heeft een vuurplaats, maar deze staat los op de kaart."
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze picknickplaats een vuurplaats?"
|
||||
},
|
||||
"name": {
|
||||
"override": {
|
||||
"render": "Deze picknickplaats heet {name}"
|
||||
}
|
||||
},
|
||||
"openfire": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Open vuur is toegestaan op deze picknickplaats."
|
||||
},
|
||||
"1": {
|
||||
"then": "Open vuur is niet toegestaan op deze picknickplaats."
|
||||
},
|
||||
"2": {
|
||||
"then": "Open vuur is toegestaan op deze picknickplaats met een vergunning."
|
||||
}
|
||||
},
|
||||
"question": "Is open vuur toegestaan op deze picknickplaats?"
|
||||
},
|
||||
"shelter": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze picknickplaats heeft een schuilplaats."
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze picknickplaats heeft geen schuilplaats."
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze picknickplaats heeft een schuilplaats, maar deze staat los op de kaart."
|
||||
}
|
||||
},
|
||||
"question": "Heeft deze picknickplaats een schuilplaats?"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Picknickplaats"
|
||||
}
|
||||
},
|
||||
"picnic_table": {
|
||||
"description": "Deze laag toont picknicktafels",
|
||||
"name": "Picknicktafels",
|
||||
|
@ -8632,6 +8779,32 @@
|
|||
},
|
||||
"question": "Wat voor zitplaatsen heeft {title()}?"
|
||||
},
|
||||
"self_checkout": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze plaats biedt zelfscannen aan"
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze plaats biedt geen zelfscannen aan"
|
||||
},
|
||||
"2": {
|
||||
"then": "Deze plaats biedt <b>enkel</b> zelfscannen aan"
|
||||
}
|
||||
},
|
||||
"question": "Biedt deze plaats zelfscannen aan?",
|
||||
"questionHint": "bijv. handscanners of een zelfscankassa"
|
||||
},
|
||||
"self_checkout_type": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Deze plaats biedt zelfscannen met een handscanner aan"
|
||||
},
|
||||
"1": {
|
||||
"then": "Deze plaats biedt zelfscannen met een zelfscankassa aan"
|
||||
}
|
||||
},
|
||||
"question": "Wat voor soort zelfscannen biedt deze plaats aan?"
|
||||
},
|
||||
"service:electricity": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
|
|
|
@ -1143,17 +1143,6 @@
|
|||
},
|
||||
"question": "Czy w tym miejscu znajduje się stacja zrzutu ścieków sanitarnych?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "To miejsce ma toalety"
|
||||
},
|
||||
"1": {
|
||||
"then": "To miejsce nie ma toalet"
|
||||
}
|
||||
},
|
||||
"question": "Czy to miejsce ma toalety?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Czy to miejsce ma stronę internetową?",
|
||||
"render": "Official website: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -1418,17 +1418,6 @@
|
|||
},
|
||||
"question": "Este local tem uma estação de aterro sanitário?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este lugar tem casa de banho"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este lugar não tem casas de banho"
|
||||
}
|
||||
},
|
||||
"question": "Este lugar tem casas de banho?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Este lugar tem um website?",
|
||||
"render": "Site oficial: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -1428,17 +1428,6 @@
|
|||
},
|
||||
"question": "Este local tem uma estação de aterro sanitário?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este lugar tem banheiros"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este lugar não tem banheiros"
|
||||
}
|
||||
},
|
||||
"question": "Este lugar tem banheiros?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Este lugar tem um website?",
|
||||
"render": "Site oficial: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -710,17 +710,6 @@
|
|||
},
|
||||
"question": "В этом кемпинге есть место для слива отходов из туалетных резервуаров?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "В этом месте есть туалеты"
|
||||
},
|
||||
"1": {
|
||||
"then": "В этом месте нет туалетов"
|
||||
}
|
||||
},
|
||||
"question": "Здесь есть туалеты?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "Есть ли у этого места веб-сайт?",
|
||||
"render": "Официальный сайт: <a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -594,17 +594,6 @@
|
|||
},
|
||||
"question": "這個地方有衛生設施嗎?"
|
||||
},
|
||||
"caravansites-toilets": {
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "這個地方有廁所"
|
||||
},
|
||||
"1": {
|
||||
"then": "這個地方並沒有廁所"
|
||||
}
|
||||
},
|
||||
"question": "這個地方有廁所嗎?"
|
||||
},
|
||||
"caravansites-website": {
|
||||
"question": "這個地方有網站嗎?",
|
||||
"render": "官方網站:<a href='{website}'>{website}</a>"
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
"description": "On this map, one can find and mark nearby defibrillators",
|
||||
"title": "Defibrillators"
|
||||
},
|
||||
"arcade": {
|
||||
"description": "A map of arcades",
|
||||
"title": "Arcades"
|
||||
},
|
||||
"architecture": {
|
||||
"description": "A map showing the architectural style of buildings",
|
||||
"title": "Buildings with an architectural style"
|
||||
|
|
4
package-lock.json
generated
4
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "mapcomplete",
|
||||
"version": "0.55.5",
|
||||
"version": "0.55.7",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "mapcomplete",
|
||||
"version": "0.55.5",
|
||||
"version": "0.55.7",
|
||||
"hasInstallScript": true,
|
||||
"license": "GPL-3.0-or-later",
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mapcomplete",
|
||||
"version": "0.55.5",
|
||||
"version": "0.55.7",
|
||||
"repository": "https://source.mapcomplete.org/MapComplete/MapComplete",
|
||||
"description": "A small website to edit OSM easily",
|
||||
"bugs": "hhttps://source.mapcomplete.org/MapComplete/MapComplete/issues",
|
||||
|
|
|
@ -5198,23 +5198,22 @@ input[type="range"].range-lg::-moz-range-thumb {
|
|||
--low-interaction-background: #eeeeee;
|
||||
--low-interaction-background-50: #eeeeee90;
|
||||
--low-interaction-foreground: black;
|
||||
--low-interaction-contrast: #ff00ff;
|
||||
--low-interaction-border: #dcdcdc;
|
||||
--interactive-background: #dddddd;
|
||||
--interactive-foreground: black;
|
||||
--interactive-contrast: #ff00ff;
|
||||
--interactive-contrast: #C107C5;
|
||||
--interaction-border: #bfbfbf;
|
||||
--button-background: #282828;
|
||||
--button-background-primary: #191919;
|
||||
--button-background-hover: #484848;
|
||||
--button-primary-background-hover: #353535;
|
||||
--button-primary-background-hover: rgba(48, 47, 47, 0.94);
|
||||
--button-foreground: white;
|
||||
--button-border-color: #F7F7F7;
|
||||
--button-background: #fafafa;
|
||||
--button-border: #B8B8B8;
|
||||
--disabled: #B8B8B8;
|
||||
--disabled-font: #B8B8B8;
|
||||
--catch-detail-color: black;
|
||||
/*#3a3aeb;*/
|
||||
--catch-detail-foregroundcolor: white;
|
||||
--catch-detail-color-contrast: #fb3afb;
|
||||
--catch-detail-color: var(--background-color);
|
||||
--catch-detail-foregroundcolor: var(--foreground-color);
|
||||
--catch-detail-color-contrast: var(--interactive-contrast);
|
||||
--image-carousel-height: 350px;
|
||||
/** Technical value, used by icon.svelte
|
||||
*/
|
||||
|
@ -5323,7 +5322,7 @@ input[type="text"] {
|
|||
}
|
||||
|
||||
.border-interactive {
|
||||
border: 2px dashed var(--catch-detail-color-contrast);
|
||||
border: 2px dashed var(--interactive-contrast);
|
||||
border-radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
@ -5358,11 +5357,14 @@ button, .button {
|
|||
align-items: center;
|
||||
padding: 0.25rem 1rem;
|
||||
margin: 0.25rem;
|
||||
border: 1px solid var(--button-background-hover);
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
border-radius: 15px;
|
||||
background: var(--button-background);
|
||||
border: 2px solid var(--button-border);
|
||||
border-radius: 7px;
|
||||
transition: background-color 200ms;
|
||||
}
|
||||
|
||||
.low-interaction button{
|
||||
background: var(--background-color);
|
||||
transition: all 200ms;
|
||||
}
|
||||
|
||||
.group > button {
|
||||
|
@ -5374,12 +5376,19 @@ button.w-full {
|
|||
margin-left: 0;
|
||||
}
|
||||
|
||||
button:hover:not(.disabled):not(.as-link), .button:hover:not(.disabled):not(.as-link) {
|
||||
button.primary:hover:not(.disabled), .button.primary:hover:not(.disabled) {
|
||||
background-color: var(--button-primary-background-hover);
|
||||
border: 2px solid var(--interactive-contrast)
|
||||
}
|
||||
|
||||
button:hover:not(.disabled):not(.as-link):not(.primary), .button:hover:not(.disabled):not(.as-link):not(.primary) {
|
||||
background-color: var(--low-interaction-background);
|
||||
}
|
||||
|
||||
button:focus, .button:focus {
|
||||
border-color: var(--interactive-contrast);
|
||||
:focus-visible {
|
||||
outline: auto;
|
||||
outline-color: var(--interactive-contrast);
|
||||
outline-style: solid;
|
||||
}
|
||||
|
||||
.focus {
|
||||
|
@ -5388,12 +5397,8 @@ button:focus, .button:focus {
|
|||
|
||||
button.primary, .button.primary {
|
||||
color: var(--button-foreground);
|
||||
background-color: var(--button-background);
|
||||
border-color: var(--button-border-color);
|
||||
}
|
||||
|
||||
button.primary:hover:not(.disabled), .button.primary:hover:not(.disabled) {
|
||||
background-color: var(--button-primary-background-hover);
|
||||
background-color: var(--button-background-primary);
|
||||
border: 2px solid var(--button-background-primary)
|
||||
}
|
||||
|
||||
button.disabled {
|
||||
|
@ -5441,10 +5446,51 @@ button.unstyled, .button-unstyled button {
|
|||
padding: 0;
|
||||
}
|
||||
|
||||
/****** Tablist elements *****/
|
||||
|
||||
.tablist {
|
||||
margin: 0.25rem;
|
||||
padding: 0.5rem;
|
||||
border: 2px dashed var(--button-background-hover);
|
||||
border-radius: 0.5rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.tab {
|
||||
border: unset;
|
||||
border-radius: 0;
|
||||
transition: all;
|
||||
color: var(--foreground-color);
|
||||
border-bottom: 2px solid var(--foreground-color);
|
||||
font-weight: bold;
|
||||
margin: 0.25rem;
|
||||
padding: 0.25rem;
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
|
||||
.tab-selected {
|
||||
opacity: 100%;
|
||||
background: var(--interactive-background);
|
||||
}
|
||||
|
||||
/* Actually used, don't remove*/
|
||||
|
||||
.tab-unselected {
|
||||
background: #00000000 !important;
|
||||
opacity: 60%;
|
||||
}
|
||||
|
||||
.tab-unselected:hover {
|
||||
background: var(--interactive-background);
|
||||
}
|
||||
|
||||
/******* Other input elements ******/
|
||||
|
||||
.hover-alert:hover {
|
||||
color: var(--catch-detail-color-contrast)
|
||||
color: var(--interactive-contrast)
|
||||
}
|
||||
|
||||
.links-w-full a:not(.weblate-link), .links-w-full button.as-link {
|
||||
|
@ -5468,7 +5514,7 @@ select {
|
|||
}
|
||||
|
||||
select:hover {
|
||||
border-color: var(--catch-detail-color-contrast);
|
||||
border-color: var(--interactive-contrast);
|
||||
}
|
||||
|
||||
.neutral-label {
|
||||
|
@ -5570,17 +5616,6 @@ h2.group {
|
|||
background-color: var(--interactive-background);
|
||||
}
|
||||
|
||||
.information {
|
||||
/* The class to convey important information which does _not_ denote an error... */
|
||||
background-color: var(--low-interaction-background);
|
||||
color: var(--alert-foreground-color);
|
||||
border-radius: 1em;
|
||||
margin: 0.25em;
|
||||
text-align: center;
|
||||
padding: 0.15em 0.3em;
|
||||
border: 3px dotted var(--catch-detail-color-contrast);
|
||||
}
|
||||
|
||||
.low-interaction .interactive {
|
||||
background-color: var(--interactive-background);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ interface value<T> {
|
|||
}
|
||||
|
||||
interface LanguageSpecResult {
|
||||
directionalityLabel: value<string | "right-to-left" | "left-to-right">
|
||||
directionalityLabel?: value<string | "right-to-left" | "left-to-right">
|
||||
lang: value<string>
|
||||
code: value<string>
|
||||
label: value<string>
|
||||
|
@ -77,6 +77,29 @@ async function fetchRegularLanguages() {
|
|||
return result.results.bindings
|
||||
}
|
||||
|
||||
async function fetchSignLanguages() {
|
||||
const query = `
|
||||
|
||||
SELECT ?lang ?label ?code
|
||||
WHERE
|
||||
{
|
||||
?lang wdt:P31 wd:Q34228.
|
||||
OPTIONAL {
|
||||
?lang wdt:P1813 ?code.
|
||||
}
|
||||
?lang rdfs:label ?label.
|
||||
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
|
||||
}`
|
||||
const url = Wikidata.wds.sparqlQuery(query)
|
||||
|
||||
// request the generated URL with your favorite HTTP request library
|
||||
const result = await Utils.downloadJson<{ results: { bindings: any[] } }>(url, {
|
||||
"User-Agent": "MapComplete script",
|
||||
})
|
||||
return <LanguageSpecResult[]>result.results.bindings
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the object as is. Sets a 'code' binding as predifined value
|
||||
* @param id
|
||||
|
@ -169,7 +192,20 @@ async function getOfficialLanguagesPerCountryCached(
|
|||
return officialLanguages
|
||||
}
|
||||
|
||||
async function generateSignLanguageOverview(){
|
||||
const signLanguages = await fetchSignLanguages()
|
||||
const signPerId = WikidataUtils.extractLanguageData(signLanguages, WikidataUtils.languageRemapping)
|
||||
const asRecord : Record<string, Record<string, string>> = {}
|
||||
for (const lng of signPerId.keys()) {
|
||||
asRecord[lng.toLowerCase()] = Utils.MapToObj(signPerId.get(lng).translations)
|
||||
}
|
||||
return asRecord
|
||||
|
||||
}
|
||||
|
||||
async function main(wipeCache = false) {
|
||||
const signLanguages = await generateSignLanguageOverview()
|
||||
|
||||
const cacheFile = "./src/assets/generated/languages-wd.json"
|
||||
if (wipeCache || !existsSync(cacheFile)) {
|
||||
console.log("Refreshing cache")
|
||||
|
@ -181,7 +217,8 @@ async function main(wipeCache = false) {
|
|||
const data = JSON.parse(readFileSync(cacheFile, { encoding: "utf8" }))
|
||||
const perId = WikidataUtils.extractLanguageData(data, WikidataUtils.languageRemapping)
|
||||
const nativeList = getNativeList(perId)
|
||||
writeFileSync("./src/assets/language_native.json", JSON.stringify(nativeList, null, " "))
|
||||
writeFileSync("./src/assets/language_native.json", JSON.stringify({ ...nativeList, ...signLanguages }, null, " "))
|
||||
|
||||
const languagesPerCountry = Utils.TransposeMap(
|
||||
await getOfficialLanguagesPerCountryCached(wipeCache)
|
||||
)
|
||||
|
|
|
@ -22,7 +22,6 @@ import ThemeViewState from "../src/Models/ThemeViewState"
|
|||
import Validators from "../src/UI/InputElement/Validators"
|
||||
import questions from "../public/assets/generated/layers/questions.json"
|
||||
import { LayerConfigJson } from "../src/Models/ThemeConfig/Json/LayerConfigJson"
|
||||
import { Utils } from "../src/Utils"
|
||||
import { TagUtils } from "../src/Logic/Tags/TagUtils"
|
||||
import Script from "./Script"
|
||||
import { Changes } from "../src/Logic/Osm/Changes"
|
||||
|
@ -562,7 +561,7 @@ export class GenerateDocs extends Script {
|
|||
item.url.startsWith("pmtiles://")
|
||||
)
|
||||
)
|
||||
const serverInfos = Utils.DedupOnId(serverInfosDupl, (item) => item.url)
|
||||
const serverInfos = Lists.dedupOnId(serverInfosDupl, (item) => item.url)
|
||||
const titles = Lists.dedup(Lists.noEmpty(serverInfos.map((s) => s.category)))
|
||||
titles.sort()
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as fs from "fs"
|
||||
import Script from "./Script"
|
||||
|
||||
function genImages(dryrun = false) {
|
||||
function genImages() {
|
||||
console.log("Generating images")
|
||||
const dir = fs.readdirSync("./assets/svg")
|
||||
for (const path of dir) {
|
||||
|
@ -64,7 +64,7 @@ class GenerateIncludedImages extends Script {
|
|||
super("Converts all images from assets/svg into svelte-classes.")
|
||||
}
|
||||
|
||||
async main(args: string[]): Promise<void> {
|
||||
async main(): Promise<void> {
|
||||
genImages()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {
|
|||
DoesImageExist,
|
||||
PrevalidateTheme,
|
||||
ValidateLayer,
|
||||
ValidateThemeEnsemble,
|
||||
ValidateThemeEnsemble
|
||||
} from "../src/Models/ThemeConfig/Conversion/Validation"
|
||||
import { Translation } from "../src/UI/i18n/Translation"
|
||||
import { OrderLayer, PrepareLayer } from "../src/Models/ThemeConfig/Conversion/PrepareLayer"
|
||||
|
@ -19,7 +19,7 @@ import {
|
|||
DesugaringStep,
|
||||
Each,
|
||||
Fuse,
|
||||
On,
|
||||
On
|
||||
} from "../src/Models/ThemeConfig/Conversion/Conversion"
|
||||
import { Utils } from "../src/Utils"
|
||||
import Script from "./Script"
|
||||
|
@ -191,7 +191,7 @@ class LayerBuilder extends Conversion<object, Map<string, LayerConfigJson>> {
|
|||
return `./assets/layers/${id}/${id}.json`
|
||||
}
|
||||
|
||||
writeLayer(layer: LayerConfigJson) {
|
||||
public writeLayer(layer: LayerConfigJson) {
|
||||
if (layer.labels?.some((l) => this._labelBlacklist.has(l))) {
|
||||
console.log("Not writing layer " + layer.id + ", censored")
|
||||
return
|
||||
|
@ -200,6 +200,15 @@ class LayerBuilder extends Conversion<object, Map<string, LayerConfigJson>> {
|
|||
if (!existsSync(LayerOverviewUtils.layerPath)) {
|
||||
mkdirSync(LayerOverviewUtils.layerPath)
|
||||
}
|
||||
|
||||
const usedImages = Lists.dedup(new ExtractImages(true, new Set(this._desugaringState.tagRenderings.keys()))
|
||||
.convertStrict({ layers: [layer], id: "dummy", icon: undefined, title: undefined })
|
||||
.map((x) => x.path))
|
||||
usedImages.sort()
|
||||
|
||||
layer["_usedImages"] = usedImages
|
||||
|
||||
|
||||
writeFileSync(LayerBuilder.targetPath(layer.id), JSON.stringify(layer, null, " "), {
|
||||
encoding: "utf8",
|
||||
})
|
||||
|
|
|
@ -327,7 +327,7 @@ export class GenerateLicenseInfo extends Script {
|
|||
}
|
||||
|
||||
licenses.sort((a, b) => (a.path < b.path ? -1 : 1))
|
||||
licenses = Utils.DedupOnId(licenses, (l) => l.path)
|
||||
licenses = Lists.dedupOnId(licenses, (l) => l.path)
|
||||
const path = dir + "/license_info.json"
|
||||
if (licenses.length === 0) {
|
||||
console.log("Removing", path, "as it is empty")
|
||||
|
|
|
@ -14,13 +14,20 @@ import { GenerateLicenseInfo } from "./generateLicenseInfo"
|
|||
|
||||
class ImportCustomTheme extends Script {
|
||||
constructor() {
|
||||
super("Given the path of a custom layer, will load the layer into mapcomplete as official")
|
||||
super(["Given the path of a custom layer, will load the layer into mapcomplete as official","",
|
||||
"Usage:",
|
||||
"vite-node scripts/importCustomTheme.ts <path-of-layer-or-theme>"].join("\n"))
|
||||
}
|
||||
|
||||
async main(args: string[]) {
|
||||
if(args.length === 0){
|
||||
this.printHelp()
|
||||
return
|
||||
}
|
||||
const path = args[0]
|
||||
|
||||
const layerconfig = <LayerConfigJson>JSON.parse(readFileSync(path, "utf-8"))
|
||||
const layerconfig = <LayerConfigJson>JSON.parse(
|
||||
readFileSync(path, "utf-8"))
|
||||
const id = layerconfig.id
|
||||
const dirPath = "./assets/layers/" + id
|
||||
if (!existsSync(dirPath)) {
|
||||
|
|
95
scripts/osm_cleanup/FixWikimediaInImageTag.ts
Normal file
95
scripts/osm_cleanup/FixWikimediaInImageTag.ts
Normal file
|
@ -0,0 +1,95 @@
|
|||
import Script from "../Script"
|
||||
import { Overpass } from "../../src/Logic/Osm/Overpass"
|
||||
import Constants from "../../src/Models/Constants"
|
||||
import { BBox } from "../../src/Logic/BBox"
|
||||
import { RegexTag } from "../../src/Logic/Tags/RegexTag"
|
||||
import { Tag } from "../../src/Logic/Tags/Tag"
|
||||
|
||||
import { Feature, FeatureCollection } from "geojson"
|
||||
import { existsSync, readFileSync, writeFileSync } from "fs"
|
||||
import { Changes } from "../../src/Logic/Osm/Changes"
|
||||
import ChangeTagAction from "../../src/Logic/Osm/Actions/ChangeTagAction"
|
||||
import { And } from "../../src/Logic/Tags/And"
|
||||
import { Lists } from "../../src/Utils/Lists"
|
||||
|
||||
export class FixWikimediaInImageTag extends Script {
|
||||
|
||||
constructor() {
|
||||
super("For the given bbox, queries all `image=http(s)://commons.wikimedia.org` tags and replaces it with `commons`-tagging")
|
||||
}
|
||||
|
||||
|
||||
private handleFeature(f: Feature): ChangeTagAction {
|
||||
const p = f.properties
|
||||
const existingCommons = p["wikimedia_commons"]
|
||||
const img = p["image"]
|
||||
const id = p.id
|
||||
if (!img) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const extractedCommons: string = img.match(/^https?:\/\/commons.wikimedia.org\/wiki\/(.*)$/)[1]
|
||||
console.log("Feature " + p.id + ": " + img + ", extr " + extractedCommons + ", old: " + existingCommons)
|
||||
|
||||
|
||||
if (existingCommons === extractedCommons) {
|
||||
return new ChangeTagAction(id,
|
||||
new Tag("image", ""),
|
||||
p,
|
||||
{
|
||||
changeType: "cleanup",
|
||||
theme: "/"
|
||||
}
|
||||
)
|
||||
}
|
||||
if (existingCommons) {
|
||||
return undefined
|
||||
}
|
||||
if (!extractedCommons.startsWith("File:")) {
|
||||
return undefined
|
||||
}
|
||||
return new ChangeTagAction(id,
|
||||
new And([new Tag("image", ""), new Tag("wikimedia_commons", decodeURIComponent(extractedCommons))]),
|
||||
p,
|
||||
{
|
||||
changeType: "cleanup",
|
||||
theme: "/"
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private async fetchData(bbox: BBox): Promise<FeatureCollection> {
|
||||
const pth = "fix_wikimedia_" + bbox.toLngLatFlat().join("_") + ".geojson"
|
||||
if (existsSync(pth)) {
|
||||
return JSON.parse(readFileSync(pth, "utf-8"))
|
||||
}
|
||||
const overpass = new Overpass(Constants.defaultOverpassUrls[0],
|
||||
new RegexTag("image", /https?:\/\/commons.wikimedia.org/)
|
||||
)
|
||||
const [feats] = await overpass.queryGeoJson(bbox)
|
||||
writeFileSync(pth, JSON.stringify(feats), "utf8")
|
||||
return feats
|
||||
}
|
||||
|
||||
async main(args: string[]): Promise<void> {
|
||||
if (args.length < 1) {
|
||||
this.printHelp()
|
||||
//return
|
||||
}
|
||||
|
||||
const bbox = new BBox([3.632100582083325,
|
||||
51.11343904784337, 3.8584183481742116,
|
||||
50.99383861993195])
|
||||
const feats = await this.fetchData(bbox)
|
||||
|
||||
const actions = Lists.noNull(feats.features.map(f => this.handleFeature(f)))
|
||||
|
||||
const xml = await Changes.createChangesetXMLForJosm(actions)
|
||||
const pth = "move_image_to_wikimedia_commons_" + bbox.toLngLatFlat().join("_") + ".osc"
|
||||
writeFileSync(pth, xml, "utf-8")
|
||||
console.log("Written xml to file://" + pth)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
new FixWikimediaInImageTag().run()
|
|
@ -1,13 +1,17 @@
|
|||
export {}
|
||||
window.addEventListener("load", async () => {
|
||||
if (!("serviceWorker" in navigator)) {
|
||||
console.log("Service workers are not supported")
|
||||
return
|
||||
}
|
||||
try {
|
||||
export class InstallServiceWorker {
|
||||
|
||||
static async installServiceWorker() {
|
||||
if (!("serviceWorker" in navigator)) {
|
||||
throw ("Service workers are not supported")
|
||||
}
|
||||
await navigator.serviceWorker.register("/service-worker.js", { type: "module" })
|
||||
console.log("Service worker registration successful")
|
||||
} catch (err) {
|
||||
console.error("Service worker registration failed", err)
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
static async precache(assets: string[]) {
|
||||
if (assets?.length > 0) {
|
||||
await fetch("./service-worker/precache?assets=" + assets.join(";"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { Changes } from "../Osm/Changes"
|
|||
import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig"
|
||||
import FeaturePropertiesStore from "../FeatureSource/Actors/FeaturePropertiesStore"
|
||||
import { WithChangesState } from "../../Models/ThemeViewState/WithChangesState"
|
||||
import Objects from "../../Utils/Objects"
|
||||
|
||||
export default class SelectedElementTagsUpdater {
|
||||
private static readonly metatags = new Set([
|
||||
|
@ -160,7 +161,7 @@ export default class SelectedElementTagsUpdater {
|
|||
const newGeometry = osmObject.asGeoJson()?.geometry
|
||||
const oldFeature = state.indexedFeatures.featuresById.data.get(id)
|
||||
const oldGeometry = oldFeature?.geometry
|
||||
if (oldGeometry !== undefined && !Utils.SameObject(newGeometry, oldGeometry)) {
|
||||
if (oldGeometry !== undefined && !Objects.sameObject(newGeometry, oldGeometry)) {
|
||||
console.log("Detected a difference in geometry for ", id)
|
||||
this.invalidateCache(s)
|
||||
oldFeature.geometry = newGeometry
|
||||
|
|
|
@ -4,9 +4,9 @@ import TileLocalStorage from "./TileLocalStorage"
|
|||
import { GeoOperations } from "../../GeoOperations"
|
||||
import FeaturePropertiesStore from "./FeaturePropertiesStore"
|
||||
import { UIEventSource } from "../../UIEventSource"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { Tiles } from "../../../Models/TileRange"
|
||||
import { BBox } from "../../BBox"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
class SingleTileSaver {
|
||||
private readonly _storage: UIEventSource<Feature[]>
|
||||
|
@ -31,7 +31,7 @@ class SingleTileSaver {
|
|||
}
|
||||
|
||||
public saveFeatures(features: Feature[]) {
|
||||
if (Utils.sameList(features, this._storage.data)) {
|
||||
if (Lists.sameList(features, this._storage.data)) {
|
||||
return
|
||||
}
|
||||
for (const feature of features) {
|
||||
|
|
|
@ -36,6 +36,6 @@ export interface FeatureSourceForTile<T extends Feature = Feature> extends Featu
|
|||
/**
|
||||
* A feature source which is aware of the indexes it contains
|
||||
*/
|
||||
export interface IndexedFeatureSource extends FeatureSource {
|
||||
export interface IndexedFeatureSource<T extends Feature> extends FeatureSource<T> {
|
||||
readonly featuresById: Store<Map<string, Feature>>
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Stores, UIEventSource } from "../../UIEventSource"
|
|||
import { FeatureSource, IndexedFeatureSource } from "../FeatureSource"
|
||||
import { ChangeDescription, ChangeDescriptionTools } from "../../Osm/Actions/ChangeDescription"
|
||||
import { Feature } from "geojson"
|
||||
import { Utils } from "../../../Utils"
|
||||
import Objects from "../../../Utils/Objects"
|
||||
|
||||
export default class ChangeGeometryApplicator implements FeatureSource {
|
||||
public readonly features: UIEventSource<Feature[]> = new UIEventSource<Feature[]>([])
|
||||
|
@ -69,7 +69,7 @@ export default class ChangeGeometryApplicator implements FeatureSource {
|
|||
// We only apply the last change as that one'll have the latest geometry
|
||||
const change = changesForFeature[changesForFeature.length - 1]
|
||||
copy.geometry = ChangeDescriptionTools.getGeojsonGeometry(change)
|
||||
if (Utils.SameObject(copy.geometry, feature.geometry)) {
|
||||
if (Objects.sameObject(copy.geometry, feature.geometry)) {
|
||||
// No actual changes: pass along the original
|
||||
newFeatures.push(feature)
|
||||
continue
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import { Store, UIEventSource } from "../../UIEventSource"
|
||||
import { FeatureSource, IndexedFeatureSource, UpdatableFeatureSource } from "../FeatureSource"
|
||||
import { Feature } from "geojson"
|
||||
import { OsmFeature } from "../../../Models/OsmFeature"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
/**
|
||||
* The featureSourceMerger receives complete geometries from various sources.
|
||||
* If multiple sources contain the same object (as determined by 'id'), only one copy of them is retained
|
||||
*/
|
||||
export default class FeatureSourceMerger<Src extends FeatureSource = FeatureSource>
|
||||
implements IndexedFeatureSource
|
||||
export default class FeatureSourceMerger<T extends Feature, Src extends FeatureSource<T> = FeatureSource<T>>
|
||||
implements IndexedFeatureSource<T>
|
||||
{
|
||||
public features: UIEventSource<Feature[]> = new UIEventSource([])
|
||||
public features: UIEventSource<T[]> = new UIEventSource([])
|
||||
public readonly featuresById: Store<Map<string, Feature>>
|
||||
protected readonly _featuresById: UIEventSource<Map<string, Feature>>
|
||||
protected readonly _sources: Src[]
|
||||
|
@ -55,7 +54,7 @@ export default class FeatureSourceMerger<Src extends FeatureSource = FeatureSour
|
|||
* Returns 'true' if this was a previously unseen item.
|
||||
* If the item was already present, nothing will happen
|
||||
*/
|
||||
public addItem(f: OsmFeature): boolean {
|
||||
public addItem(f: T): boolean {
|
||||
const id = f.properties.id
|
||||
|
||||
const all = this._featuresById.data
|
||||
|
@ -68,10 +67,10 @@ export default class FeatureSourceMerger<Src extends FeatureSource = FeatureSour
|
|||
}
|
||||
}
|
||||
|
||||
protected addData(sources: Feature[][]) {
|
||||
protected addData(sources: T[][]) {
|
||||
sources = Lists.noNull(sources)
|
||||
let somethingChanged = false
|
||||
const all: Map<string, Feature> = new Map()
|
||||
const all: Map<string, T> = new Map()
|
||||
const unseen = new Set<string>()
|
||||
// We seed the dictionary with the previously loaded features
|
||||
const oldValues = this.features.data ?? []
|
||||
|
@ -118,10 +117,11 @@ export default class FeatureSourceMerger<Src extends FeatureSource = FeatureSour
|
|||
}
|
||||
|
||||
export class UpdatableFeatureSourceMerger<
|
||||
Src extends UpdatableFeatureSource = UpdatableFeatureSource
|
||||
T extends Feature,
|
||||
Src extends UpdatableFeatureSource<T> = UpdatableFeatureSource<T>
|
||||
>
|
||||
extends FeatureSourceMerger<Src>
|
||||
implements IndexedFeatureSource, UpdatableFeatureSource
|
||||
extends FeatureSourceMerger<T, Src>
|
||||
implements IndexedFeatureSource<T>, UpdatableFeatureSource<T>
|
||||
{
|
||||
constructor(...sources: Src[]) {
|
||||
super(...sources)
|
||||
|
|
|
@ -3,13 +3,15 @@ import { Utils } from "../../../Utils"
|
|||
import { FeatureSource } from "../FeatureSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
import { Feature } from "geojson"
|
||||
import { Feature, Geometry } from "geojson"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import { Tiles } from "../../../Models/TileRange"
|
||||
|
||||
export default class GeoJsonSource implements FeatureSource {
|
||||
private readonly _features: UIEventSource<Feature[]> = new UIEventSource<Feature[]>(undefined)
|
||||
public readonly features: Store<Feature[]> = this._features
|
||||
export default class GeoJsonSource<T extends Feature<Geometry, {
|
||||
id: string
|
||||
} & Record<string, any>>> implements FeatureSource<T> {
|
||||
private readonly _features: UIEventSource<T[]> = new UIEventSource(undefined)
|
||||
public readonly features: Store<T[]> = this._features
|
||||
private readonly seenids: Set<string>
|
||||
private readonly idKey?: string
|
||||
private readonly url: string
|
||||
|
@ -96,7 +98,7 @@ export default class GeoJsonSource implements FeatureSource {
|
|||
const url = this.url
|
||||
try {
|
||||
const cacheAge = (options?.maxCacheAgeSec ?? 300) * 1000
|
||||
let json = <{ features: Feature[] }>await Utils.downloadJsonCached(url, cacheAge)
|
||||
let json = <{ features: T[] }>await Utils.downloadJsonCached(url, cacheAge)
|
||||
|
||||
if (json.features === undefined || json.features === null) {
|
||||
json.features = []
|
||||
|
@ -106,7 +108,7 @@ export default class GeoJsonSource implements FeatureSource {
|
|||
json = GeoOperations.GeoJsonToWGS84(json)
|
||||
}
|
||||
|
||||
const newFeatures: Feature[] = []
|
||||
const newFeatures: T[] = []
|
||||
let i = 0
|
||||
for (const feature of json.features) {
|
||||
if (feature.geometry.type === "Point") {
|
||||
|
|
|
@ -5,8 +5,8 @@ import { FeatureSourceForTile, UpdatableFeatureSource } from "../FeatureSource"
|
|||
import { MvtToGeojson } from "mvt-to-geojson"
|
||||
import { OsmTags } from "../../../Models/OsmFeature"
|
||||
|
||||
export default class MvtSource implements FeatureSourceForTile, UpdatableFeatureSource {
|
||||
public readonly features: Store<GeojsonFeature<Geometry, OsmTags>[]>
|
||||
export default class MvtSource<T extends Feature<Geometry, OsmTags>> implements FeatureSourceForTile<T>, UpdatableFeatureSource<T> {
|
||||
public readonly features: Store<T[]>
|
||||
public readonly x: number
|
||||
public readonly y: number
|
||||
public readonly z: number
|
||||
|
|
|
@ -4,16 +4,16 @@ import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource"
|
|||
import { Tiles } from "../../../Models/TileRange"
|
||||
import { BBox } from "../../BBox"
|
||||
import { TagsFilter } from "../../Tags/TagsFilter"
|
||||
import { Feature } from "geojson"
|
||||
import FeatureSourceMerger from "../Sources/FeatureSourceMerger"
|
||||
import OsmObjectDownloader from "../../Osm/OsmObjectDownloader"
|
||||
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
import { OsmFeature } from "../../../Models/OsmFeature"
|
||||
|
||||
/**
|
||||
* If a tile is needed (requested via the UIEventSource in the constructor), will download the appropriate tile and pass it via 'handleTile'
|
||||
*/
|
||||
export default class OsmFeatureSource extends FeatureSourceMerger {
|
||||
export default class OsmFeatureSource<T extends OsmFeature> extends FeatureSourceMerger<T> {
|
||||
private readonly _bounds: Store<BBox>
|
||||
private readonly isActive: Store<boolean>
|
||||
private readonly _backend: string
|
||||
|
@ -33,7 +33,7 @@ export default class OsmFeatureSource extends FeatureSourceMerger {
|
|||
public readonly isRunning: UIEventSource<boolean> = new UIEventSource<boolean>(false)
|
||||
|
||||
private readonly _downloadedTiles: Set<number> = new Set<number>()
|
||||
private readonly _downloadedData: Feature[][] = []
|
||||
private readonly _downloadedData: T[][] = []
|
||||
private readonly _patchRelations: boolean
|
||||
/**
|
||||
* Downloads data directly from the OSM-api within the given bounds.
|
||||
|
@ -90,7 +90,7 @@ export default class OsmFeatureSource extends FeatureSourceMerger {
|
|||
}
|
||||
}
|
||||
|
||||
private registerFeatures(features: Feature[]): void {
|
||||
private registerFeatures(features: T[]): void {
|
||||
this._downloadedData.push(features)
|
||||
super.addData(this._downloadedData)
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ export default class OsmFeatureSource extends FeatureSourceMerger {
|
|||
const osmJson = await Utils.downloadJsonCached(url, 2000)
|
||||
try {
|
||||
this.options?.fullNodeDatabase?.handleOsmJson(osmJson, z, x, y)
|
||||
let features = <Feature<any, { id: string }>[]>OsmToGeoJson(osmJson, {
|
||||
let features = <T[]>OsmToGeoJson(osmJson, {
|
||||
flatProperties: true,
|
||||
}).features
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { Feature, FeatureCollection, Geometry } from "geojson"
|
||||
import { UpdatableFeatureSource } from "../FeatureSource"
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
|
@ -7,19 +6,20 @@ import { Overpass } from "../../Osm/Overpass"
|
|||
import { Utils } from "../../../Utils"
|
||||
import { TagsFilter } from "../../Tags/TagsFilter"
|
||||
import { BBox } from "../../BBox"
|
||||
import { OsmTags } from "../../../Models/OsmFeature"
|
||||
import { OsmFeature } from "../../../Models/OsmFeature"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
;("use strict")
|
||||
|
||||
("use strict")
|
||||
|
||||
/**
|
||||
* A wrapper around the 'Overpass'-object.
|
||||
* It has more logic and will automatically fetch the data for the right bbox and the active layers
|
||||
*/
|
||||
export default class OverpassFeatureSource implements UpdatableFeatureSource {
|
||||
export default class OverpassFeatureSource<T extends OsmFeature = OsmFeature> implements UpdatableFeatureSource<T> {
|
||||
/**
|
||||
* The last loaded features, as geojson
|
||||
*/
|
||||
public readonly features: UIEventSource<Feature[]> = new UIEventSource(undefined)
|
||||
public readonly features: UIEventSource<T[]> = new UIEventSource(undefined)
|
||||
|
||||
public readonly runningQuery: UIEventSource<boolean> = new UIEventSource<boolean>(false)
|
||||
public readonly timeout: UIEventSource<number> = new UIEventSource<number>(0)
|
||||
|
@ -110,7 +110,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
|
|||
if (!navigator.onLine) {
|
||||
return
|
||||
}
|
||||
let data: FeatureCollection<Geometry, OsmTags> = undefined
|
||||
let data: { features: T[] } = undefined
|
||||
let lastUsed = 0
|
||||
const start = new Date()
|
||||
const layersToDownload = this._layersToDownload.data
|
||||
|
@ -142,7 +142,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
|
|||
return undefined
|
||||
}
|
||||
this.runningQuery.setData(true)
|
||||
data = (await overpass.queryGeoJson(bounds))[0]
|
||||
data = (await overpass.queryGeoJson<T>(bounds))[0]
|
||||
} catch (e) {
|
||||
this.retries.data++
|
||||
this.retries.ping()
|
||||
|
@ -229,7 +229,7 @@ export default class OverpassFeatureSource implements UpdatableFeatureSource {
|
|||
const requestedBounds = this.state.bounds.data
|
||||
if (
|
||||
this._lastQueryBBox !== undefined &&
|
||||
Utils.sameList(this._layersToDownload.data, this._lastRequestedLayers) &&
|
||||
Lists.sameList(this._layersToDownload.data, this._lastRequestedLayers) &&
|
||||
requestedBounds.isContainedIn(this._lastQueryBBox)
|
||||
) {
|
||||
return undefined
|
||||
|
|
|
@ -26,9 +26,6 @@ export default class StaticFeatureSource<T extends Feature = Feature> implements
|
|||
}
|
||||
}
|
||||
|
||||
public static fromGeojson<T extends Feature>(geojson: T[]): StaticFeatureSource<T> {
|
||||
return new StaticFeatureSource(geojson)
|
||||
}
|
||||
}
|
||||
|
||||
export class WritableStaticFeatureSource<T extends Feature = Feature>
|
||||
|
|
|
@ -12,15 +12,16 @@ import LocalStorageFeatureSource from "../TiledFeatureSource/LocalStorageFeature
|
|||
import FullNodeDatabaseSource from "../TiledFeatureSource/FullNodeDatabaseSource"
|
||||
import DynamicMvtileSource from "../TiledFeatureSource/DynamicMvtTileSource"
|
||||
import FeatureSourceMerger from "./FeatureSourceMerger"
|
||||
import { Feature } from "geojson"
|
||||
import { Feature, Geometry } from "geojson"
|
||||
import { OsmFeature } from "../../../Models/OsmFeature"
|
||||
import { IsOnline } from "../../Web/IsOnline"
|
||||
|
||||
/**
|
||||
* This source will fetch the needed data from various sources for the given layout.
|
||||
*
|
||||
* Note that special layers (with `source=null` will be ignored)
|
||||
*/
|
||||
export default class ThemeSource implements IndexedFeatureSource {
|
||||
export default class ThemeSource<T extends Feature<Geometry, Record<string, any> & {id: string}>> implements IndexedFeatureSource<T> {
|
||||
/**
|
||||
* Indicates if a data source is loading something
|
||||
*/
|
||||
|
@ -28,12 +29,12 @@ export default class ThemeSource implements IndexedFeatureSource {
|
|||
|
||||
public static readonly fromCacheZoomLevel = 15
|
||||
|
||||
public features: UIEventSource<Feature[]> = new UIEventSource([])
|
||||
public readonly featuresById: Store<Map<string, Feature>>
|
||||
private readonly core: Store<ThemeSourceCore>
|
||||
public features: UIEventSource<T[]> = new UIEventSource([])
|
||||
public readonly featuresById: Store<Map<string, T>>
|
||||
private readonly core: Store<ThemeSourceCore<T>>
|
||||
|
||||
private readonly addedSources: FeatureSource[] = []
|
||||
private readonly addedItems: OsmFeature[] = []
|
||||
private readonly addedSources: FeatureSource<T>[] = []
|
||||
private readonly addedItems: T[] = []
|
||||
|
||||
constructor(
|
||||
layers: LayerConfig[],
|
||||
|
@ -47,11 +48,11 @@ export default class ThemeSource implements IndexedFeatureSource {
|
|||
const isLoading = new UIEventSource(true)
|
||||
this.isLoading = isLoading
|
||||
|
||||
const features = (this.features = new UIEventSource<Feature[]>([]))
|
||||
const features = (this.features = new UIEventSource<T[]>([]))
|
||||
const featuresById = (this.featuresById = new UIEventSource(new Map()))
|
||||
this.core = mvtAvailableLayers.mapD((mvtAvailableLayers) => {
|
||||
this.core?.data?.destruct()
|
||||
const core = new ThemeSourceCore(
|
||||
const core = new ThemeSourceCore<T>(
|
||||
layers,
|
||||
featureSwitches,
|
||||
mapProperties,
|
||||
|
@ -67,18 +68,30 @@ export default class ThemeSource implements IndexedFeatureSource {
|
|||
core.featuresById.addCallbackAndRun((data) => featuresById.set(data))
|
||||
return core
|
||||
})
|
||||
|
||||
IsOnline.isOnline.addCallback(async online => {
|
||||
if (online) {
|
||||
// Connectivity is restored - let us try to update the data
|
||||
console.log("Internet got restored - starting to download all data")
|
||||
isLoading.set(true)
|
||||
await this.downloadAll()
|
||||
isLoading.set(false)
|
||||
} else {
|
||||
isLoading.set(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
public async downloadAll() {
|
||||
return this.core.data.downloadAll()
|
||||
}
|
||||
|
||||
public addSource(source: FeatureSource) {
|
||||
public addSource(source: FeatureSource<T>) {
|
||||
this.core.data?.addSource(source)
|
||||
this.addedSources.push(source)
|
||||
}
|
||||
|
||||
public addItem(obj: OsmFeature) {
|
||||
public addItem(obj: T) {
|
||||
this.core.data?.addItem(obj)
|
||||
this.addedItems.push(obj)
|
||||
}
|
||||
|
@ -89,7 +102,7 @@ export default class ThemeSource implements IndexedFeatureSource {
|
|||
*
|
||||
* Note that special layers (with `source=null` will be ignored)
|
||||
*/
|
||||
class ThemeSourceCore extends FeatureSourceMerger {
|
||||
class ThemeSourceCore<T extends OsmFeature> extends FeatureSourceMerger<T> {
|
||||
/**
|
||||
* This source is _only_ triggered when the data is downloaded for CSV export
|
||||
* @private
|
||||
|
@ -113,10 +126,10 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
|
||||
const geojsonlayers = layers.filter((layer) => layer.source.geojsonSource !== undefined)
|
||||
const osmLayers = layers.filter((layer) => layer.source.geojsonSource === undefined)
|
||||
const fromCache = new Map<string, LocalStorageFeatureSource>()
|
||||
const fromCache = new Map<string, LocalStorageFeatureSource<T>>()
|
||||
if (featureSwitches.featureSwitchCache.data) {
|
||||
for (const layer of osmLayers) {
|
||||
const src = new LocalStorageFeatureSource(
|
||||
const src = new LocalStorageFeatureSource<T>(
|
||||
backend,
|
||||
layer,
|
||||
ThemeSource.fromCacheZoomLevel,
|
||||
|
@ -129,13 +142,13 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
fromCache.set(layer.id, src)
|
||||
}
|
||||
}
|
||||
const mvtSources: UpdatableFeatureSource[] = osmLayers
|
||||
const mvtSources: UpdatableFeatureSource<T>[] = osmLayers
|
||||
.filter((f) => mvtAvailableLayers.has(f.id))
|
||||
.map((l) => ThemeSourceCore.setupMvtSource(l, mapProperties, isDisplayed(l.id)))
|
||||
const nonMvtSources: FeatureSource[] = []
|
||||
.map((l) => ThemeSourceCore.setupMvtSource<T>(l, mapProperties, isDisplayed(l.id)))
|
||||
const nonMvtSources: FeatureSource<T>[] = []
|
||||
const nonMvtLayers: LayerConfig[] = osmLayers.filter((l) => !mvtAvailableLayers.has(l.id))
|
||||
|
||||
const osmApiSource = ThemeSourceCore.setupOsmApiSource(
|
||||
const osmApiSource = ThemeSourceCore.setupOsmApiSource<T>(
|
||||
osmLayers,
|
||||
bounds,
|
||||
zoom,
|
||||
|
@ -145,14 +158,14 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
)
|
||||
nonMvtSources.push(osmApiSource)
|
||||
|
||||
let overpassSource: OverpassFeatureSource = undefined
|
||||
let overpassSource: OverpassFeatureSource<T> = undefined
|
||||
if (nonMvtLayers.length > 0) {
|
||||
console.log(
|
||||
"Layers ",
|
||||
nonMvtLayers.map((l) => l.id),
|
||||
" cannot be fetched from the cache server, defaulting to overpass/OSM-api"
|
||||
)
|
||||
overpassSource = ThemeSourceCore.setupOverpass(osmLayers, bounds, zoom, featureSwitches)
|
||||
overpassSource = ThemeSourceCore.setupOverpass<T>(osmLayers, bounds, zoom, featureSwitches)
|
||||
nonMvtSources.push(overpassSource)
|
||||
}
|
||||
|
||||
|
@ -164,11 +177,11 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
overpassSource?.runningQuery?.addCallbackAndRun(() => setIsLoading())
|
||||
osmApiSource?.isRunning?.addCallbackAndRun(() => setIsLoading())
|
||||
|
||||
const geojsonSources: UpdatableFeatureSource[] = geojsonlayers.map((l) =>
|
||||
const geojsonSources: UpdatableFeatureSource<T>[] = geojsonlayers.map((l) =>
|
||||
ThemeSourceCore.setupGeojsonSource(l, mapProperties, isDisplayed(l.id))
|
||||
)
|
||||
|
||||
const downloadAll = new OverpassFeatureSource(
|
||||
const downloadAll = new OverpassFeatureSource<T>(
|
||||
{
|
||||
layers: layers.filter((l) => l.isNormal()),
|
||||
bounds: mapProperties.bounds,
|
||||
|
@ -196,19 +209,19 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
this._mapBounds = mapProperties.bounds
|
||||
}
|
||||
|
||||
private static setupMvtSource(
|
||||
private static setupMvtSource<T extends OsmFeature>(
|
||||
layer: LayerConfig,
|
||||
mapProperties: { zoom: Store<number>; bounds: Store<BBox> },
|
||||
isActive?: Store<boolean>
|
||||
): UpdatableFeatureSource {
|
||||
return new DynamicMvtileSource(layer, mapProperties, { isActive })
|
||||
): UpdatableFeatureSource<T> {
|
||||
return new DynamicMvtileSource<T>(layer, mapProperties, { isActive })
|
||||
}
|
||||
|
||||
private static setupGeojsonSource(
|
||||
private static setupGeojsonSource<T extends OsmFeature>(
|
||||
layer: LayerConfig,
|
||||
mapProperties: { zoom: Store<number>; bounds: Store<BBox> },
|
||||
isActiveByFilter?: Store<boolean>
|
||||
): UpdatableFeatureSource {
|
||||
): UpdatableFeatureSource<T> {
|
||||
const source = layer.source
|
||||
const isActive = mapProperties.zoom.map(
|
||||
(z) => (isActiveByFilter?.data ?? true) && z >= layer.minzoom,
|
||||
|
@ -216,20 +229,20 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
)
|
||||
if (source.geojsonZoomLevel === undefined) {
|
||||
// This is a 'load everything at once' geojson layer
|
||||
return new GeoJsonSource(layer, { isActive })
|
||||
return new GeoJsonSource<T>(layer, { isActive })
|
||||
} else {
|
||||
return new DynamicGeoJsonTileSource(layer, mapProperties, { isActive })
|
||||
return new DynamicGeoJsonTileSource<T>(layer, mapProperties, { isActive })
|
||||
}
|
||||
}
|
||||
|
||||
private static setupOsmApiSource(
|
||||
private static setupOsmApiSource<T extends OsmFeature>(
|
||||
osmLayers: LayerConfig[],
|
||||
bounds: Store<BBox>,
|
||||
zoom: Store<number>,
|
||||
backend: string,
|
||||
featureSwitches: FeatureSwitchState,
|
||||
fullNodeDatabase: FullNodeDatabaseSource
|
||||
): OsmFeatureSource | undefined {
|
||||
): OsmFeatureSource<T> | undefined {
|
||||
if (osmLayers.length == 0) {
|
||||
return undefined
|
||||
}
|
||||
|
@ -248,7 +261,7 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
if (typeof allowedFeatures === "boolean") {
|
||||
throw "Invalid filter to init OsmFeatureSource: it optimizes away to " + allowedFeatures
|
||||
}
|
||||
return new OsmFeatureSource({
|
||||
return new OsmFeatureSource<T>({
|
||||
allowedFeatures,
|
||||
bounds,
|
||||
backend,
|
||||
|
@ -258,12 +271,12 @@ class ThemeSourceCore extends FeatureSourceMerger {
|
|||
})
|
||||
}
|
||||
|
||||
private static setupOverpass(
|
||||
private static setupOverpass<T extends OsmFeature>(
|
||||
osmLayers: LayerConfig[],
|
||||
bounds: Store<BBox>,
|
||||
zoom: Store<number>,
|
||||
featureSwitches: FeatureSwitchState
|
||||
): OverpassFeatureSource | undefined {
|
||||
): OverpassFeatureSource<T> | undefined {
|
||||
if (osmLayers.length == 0) {
|
||||
return undefined
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Feature, Point } from "geojson"
|
|||
import { ImmutableStore, Store, UIEventSource } from "../../UIEventSource"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
import { Tiles } from "../../../Models/TileRange"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
||||
export interface ClusteringOptions {
|
||||
/**
|
||||
|
@ -86,11 +87,10 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
features: Feature<Point>[],
|
||||
tileId: number
|
||||
): Feature<Point, SummaryProperties> {
|
||||
let lon: number
|
||||
let lat: number
|
||||
const [z, x, y] = Tiles.tile_from_index(tileId)
|
||||
let coordinates: [number, number]
|
||||
if (this.showSummaryAt === "tilecenter") {
|
||||
;[lon, lat] = Tiles.centerPointOf(z, x, y)
|
||||
const [z, x, y] = Tiles.tile_from_index(tileId)
|
||||
coordinates = Tiles.centerPointOf(z, x, y)
|
||||
} else {
|
||||
let lonSum = 0
|
||||
let latSum = 0
|
||||
|
@ -99,14 +99,15 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
lonSum += lon
|
||||
latSum += lat
|
||||
}
|
||||
lon = lonSum / features.length
|
||||
lat = latSum / features.length
|
||||
const lon = lonSum / features.length
|
||||
const lat = latSum / features.length
|
||||
coordinates = [lon, lat]
|
||||
}
|
||||
return {
|
||||
type: "Feature",
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates: [lon, lat],
|
||||
coordinates
|
||||
},
|
||||
properties: {
|
||||
id: "summary_" + this.id + "_" + tileId,
|
||||
|
@ -120,10 +121,10 @@ export class ClusteringFeatureSource<T extends Feature<Point> = Feature<Point>>
|
|||
/**
|
||||
* Groups multiple summaries together
|
||||
*/
|
||||
export class ClusterGrouping implements FeatureSource<Feature<Point, { total_metric: string }>> {
|
||||
private readonly _features: UIEventSource<Feature<Point, { total_metric: string }>[]> =
|
||||
export class ClusterGrouping implements FeatureSource<Feature<Point, { total_metric: string, id: string }>> {
|
||||
private readonly _features: UIEventSource<Feature<Point, { total_metric: string, id: string }>[]> =
|
||||
new UIEventSource([])
|
||||
public readonly features: Store<Feature<Point, { total_metric: string }>[]> = this._features
|
||||
public readonly features: Store<Feature<Point, { total_metric: string, id: string }>[]> = this._features
|
||||
|
||||
public static readonly singleton = new ClusterGrouping()
|
||||
|
||||
|
@ -140,27 +141,34 @@ export class ClusterGrouping implements FeatureSource<Feature<Point, { total_met
|
|||
private allSource: Store<Feature<Point, { total: number; tile_id: number }>[]>[] = []
|
||||
|
||||
private update() {
|
||||
const countPerTile = new Map<number, number>()
|
||||
const countPerTile = new Map<number, { lon: number, lat: number, count: number }[]>()
|
||||
for (const source of this.allSource) {
|
||||
for (const f of source.data) {
|
||||
const id = f.properties.tile_id
|
||||
const count = f.properties.total + (countPerTile.get(id) ?? 0)
|
||||
countPerTile.set(id, count)
|
||||
if (!countPerTile.has(id)) {
|
||||
countPerTile.set(id, [])
|
||||
}
|
||||
const ls = countPerTile.get(id)
|
||||
ls.push({ lon: f.geometry.coordinates[0], lat: f.geometry.coordinates[1], count: f.properties.total })
|
||||
}
|
||||
}
|
||||
const features: Feature<Point, { total_metric: string; id: string }>[] = []
|
||||
const now = new Date().getTime() + ""
|
||||
for (const tileId of countPerTile.keys()) {
|
||||
const coordinates = Tiles.centerPointOf(tileId)
|
||||
const data = countPerTile.get(tileId)
|
||||
const total = Lists.sum(data.map(d => d.count))
|
||||
const lon = Lists.sum(data.map(d => d.lon * d.count)) / total
|
||||
const lat = Lists.sum(data.map(d => d.lat * d.count)) / total
|
||||
|
||||
features.push({
|
||||
type: "Feature",
|
||||
properties: {
|
||||
total_metric: "" + countPerTile.get(tileId),
|
||||
total_metric: "" + total,
|
||||
id: "clustered_all_" + tileId + "_" + now, // We add the date to force a fresh ID every time, this makes sure values are updated
|
||||
},
|
||||
geometry: {
|
||||
type: "Point",
|
||||
coordinates,
|
||||
coordinates: [lon, lat]
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -169,6 +177,10 @@ export class ClusterGrouping implements FeatureSource<Feature<Point, { total_met
|
|||
}
|
||||
|
||||
public registerSource(features: Store<Feature<Point, SummaryProperties>[]>) {
|
||||
if (this.allSource.indexOf(features) >= 0) {
|
||||
console.error("This source has already been registered")
|
||||
return
|
||||
}
|
||||
this.allSource.push(features)
|
||||
features.addCallbackAndRun(() => {
|
||||
//this.isDirty.set(true)
|
||||
|
|
|
@ -4,8 +4,9 @@ import { Utils } from "../../../Utils"
|
|||
import GeoJsonSource from "../Sources/GeoJsonSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
import { Feature, Geometry } from "geojson"
|
||||
|
||||
export default class DynamicGeoJsonTileSource extends UpdatableDynamicTileSource {
|
||||
export default class DynamicGeoJsonTileSource<T extends Feature<Geometry, Record<string, any> & {id: string} > > extends UpdatableDynamicTileSource<T> {
|
||||
private static whitelistCache = new Map<string, Map<number, Set<number>>>()
|
||||
|
||||
constructor(
|
||||
|
|
|
@ -9,8 +9,10 @@ import Constants from "../../../Models/Constants"
|
|||
import { UpdatableFeatureSourceMerger } from "../Sources/FeatureSourceMerger"
|
||||
import { LineSourceMerger } from "./LineSourceMerger"
|
||||
import { PolygonSourceMerger } from "./PolygonSourceMerger"
|
||||
import { OsmFeature, OsmTags } from "../../../Models/OsmFeature"
|
||||
import { Feature, Point } from "geojson"
|
||||
|
||||
class PolygonMvtSource extends PolygonSourceMerger {
|
||||
class PolygonMvtSource<P extends Record<string, any> & { id: string }> extends PolygonSourceMerger<P> {
|
||||
constructor(
|
||||
layer: LayerConfig,
|
||||
mapProperties: {
|
||||
|
@ -44,7 +46,7 @@ class PolygonMvtSource extends PolygonSourceMerger {
|
|||
}
|
||||
}
|
||||
|
||||
class LineMvtSource extends LineSourceMerger {
|
||||
class LineMvtSource extends LineSourceMerger<OsmTags> {
|
||||
constructor(
|
||||
layer: LayerConfig,
|
||||
mapProperties: {
|
||||
|
@ -78,7 +80,7 @@ class LineMvtSource extends LineSourceMerger {
|
|||
}
|
||||
}
|
||||
|
||||
class PointMvtSource extends UpdatableDynamicTileSource {
|
||||
class PointMvtSource<T extends Feature<Point, OsmTags>> extends UpdatableDynamicTileSource<T> {
|
||||
constructor(
|
||||
layer: LayerConfig,
|
||||
mapProperties: {
|
||||
|
@ -102,7 +104,7 @@ class PointMvtSource extends UpdatableDynamicTileSource {
|
|||
layer: layer.id,
|
||||
type: "pois",
|
||||
})
|
||||
return new MvtSource(url, x, y, z)
|
||||
return new MvtSource<T>(url, x, y, z)
|
||||
},
|
||||
mapProperties,
|
||||
{
|
||||
|
@ -112,7 +114,7 @@ class PointMvtSource extends UpdatableDynamicTileSource {
|
|||
}
|
||||
}
|
||||
|
||||
export default class DynamicMvtileSource extends UpdatableFeatureSourceMerger {
|
||||
export default class DynamicMvtileSource<T extends OsmFeature> extends UpdatableFeatureSourceMerger<T> {
|
||||
constructor(
|
||||
layer: LayerConfig,
|
||||
mapProperties: {
|
||||
|
@ -124,9 +126,9 @@ export default class DynamicMvtileSource extends UpdatableFeatureSourceMerger {
|
|||
}
|
||||
) {
|
||||
super(
|
||||
new PointMvtSource(layer, mapProperties, options),
|
||||
new LineMvtSource(layer, mapProperties, options),
|
||||
new PolygonMvtSource(layer, mapProperties, options)
|
||||
<any>new PointMvtSource(layer, mapProperties, options),
|
||||
<any>new LineMvtSource(layer, mapProperties, options),
|
||||
<any>new PolygonMvtSource(layer, mapProperties, options),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,15 @@ import { Tiles } from "../../../Models/TileRange"
|
|||
import { BBox } from "../../BBox"
|
||||
import { FeatureSource, UpdatableFeatureSource } from "../FeatureSource"
|
||||
import FeatureSourceMerger from "../Sources/FeatureSourceMerger"
|
||||
import { Feature, Geometry } from "geojson"
|
||||
|
||||
/***
|
||||
* A tiled source which dynamically loads the required tiles at a fixed zoom level.
|
||||
* A single featureSource will be initialized for every tile in view; which will later be merged into this featureSource
|
||||
*/
|
||||
export default class DynamicTileSource<
|
||||
Src extends FeatureSource = FeatureSource
|
||||
> extends FeatureSourceMerger<Src> {
|
||||
export default class DynamicTileSource<T extends Feature,
|
||||
Src extends FeatureSource<T> = FeatureSource<T>
|
||||
> extends FeatureSourceMerger<T, Src> {
|
||||
private readonly loadedTiles = new Set<number>()
|
||||
private readonly zDiff: number
|
||||
private readonly zoomlevel: Store<number>
|
||||
|
@ -97,9 +98,9 @@ export default class DynamicTileSource<
|
|||
}
|
||||
}
|
||||
|
||||
export class UpdatableDynamicTileSource<Src extends UpdatableFeatureSource = UpdatableFeatureSource>
|
||||
extends DynamicTileSource<Src>
|
||||
implements UpdatableFeatureSource
|
||||
export class UpdatableDynamicTileSource<T extends Feature<Geometry, Record<string, any> & {id: string}>, Src extends UpdatableFeatureSource<T> = UpdatableFeatureSource<T>>
|
||||
extends DynamicTileSource<T, Src>
|
||||
implements UpdatableFeatureSource<T>
|
||||
{
|
||||
constructor(
|
||||
zoomlevel: Store<number>,
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { FeatureSourceForTile, UpdatableFeatureSource } from "../FeatureSource"
|
||||
import { Store } from "../../UIEventSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import { Utils } from "../../../Utils"
|
||||
import { Feature, MultiLineString, Position } from "geojson"
|
||||
import { Feature, LineString, MultiLineString, Position } from "geojson"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
import { UpdatableDynamicTileSource } from "./DynamicTileSource"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
@ -11,15 +10,16 @@ import { Lists } from "../../../Utils/Lists"
|
|||
* The PolygonSourceMerger receives various small pieces of bigger polygons and stitches them together.
|
||||
* This is used to reconstruct polygons of vector tiles
|
||||
*/
|
||||
export class LineSourceMerger extends UpdatableDynamicTileSource<
|
||||
FeatureSourceForTile & UpdatableFeatureSource
|
||||
export class LineSourceMerger<P extends Record<string, any> & { id: string }> extends UpdatableDynamicTileSource<
|
||||
Feature<LineString | MultiLineString, P>, FeatureSourceForTile<Feature<LineString | MultiLineString, P>> & UpdatableFeatureSource<Feature<LineString | MultiLineString, P>>
|
||||
> {
|
||||
private readonly _zoomlevel: Store<number>
|
||||
|
||||
constructor(
|
||||
zoomlevel: Store<number>,
|
||||
minzoom: number,
|
||||
constructSource: (tileIndex: number) => FeatureSourceForTile & UpdatableFeatureSource,
|
||||
constructSource: (tileIndex: number) => FeatureSourceForTile<
|
||||
Feature<LineString | MultiLineString, P>> & UpdatableFeatureSource<Feature<LineString | MultiLineString, P>>,
|
||||
mapProperties: {
|
||||
bounds: Store<BBox>
|
||||
zoom: Store<number>
|
||||
|
@ -32,9 +32,9 @@ export class LineSourceMerger extends UpdatableDynamicTileSource<
|
|||
this._zoomlevel = zoomlevel
|
||||
}
|
||||
|
||||
protected addDataFromSources(sources: FeatureSourceForTile[]) {
|
||||
protected addDataFromSources(sources: FeatureSourceForTile<Feature<LineString | MultiLineString, P>>[]) {
|
||||
sources = Lists.noNull(sources)
|
||||
const all: Map<string, Feature<MultiLineString>> = new Map()
|
||||
const all: Map<string, Feature<MultiLineString | LineString, P>> = new Map()
|
||||
const currentZoom = this._zoomlevel?.data ?? 0
|
||||
for (const source of sources) {
|
||||
if (source.z != currentZoom) {
|
||||
|
@ -48,10 +48,10 @@ export class LineSourceMerger extends UpdatableDynamicTileSource<
|
|||
} else if (f.geometry.type === "MultiLineString") {
|
||||
coordinates.push(...f.geometry.coordinates)
|
||||
} else {
|
||||
console.error("Invalid geometry type:", f.geometry.type)
|
||||
console.error("Invalid geometry type:", f.geometry["type"])
|
||||
continue
|
||||
}
|
||||
const oldV = all.get(id)
|
||||
const oldV: Feature<MultiLineString | LineString, P> = all.get(id)
|
||||
if (!oldV) {
|
||||
all.set(id, {
|
||||
type: "Feature",
|
||||
|
@ -63,7 +63,13 @@ export class LineSourceMerger extends UpdatableDynamicTileSource<
|
|||
})
|
||||
continue
|
||||
}
|
||||
oldV.geometry.coordinates.push(...coordinates)
|
||||
for (const coordinate of coordinates) {
|
||||
if (oldV.geometry.type === "LineString") {
|
||||
oldV.geometry.coordinates.push(...coordinate)
|
||||
} else {
|
||||
oldV.geometry.coordinates.push(coordinate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@ import DynamicTileSource from "./DynamicTileSource"
|
|||
import { ImmutableStore, Store } from "../../UIEventSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import TileLocalStorage from "../Actors/TileLocalStorage"
|
||||
import { Feature } from "geojson"
|
||||
import { Feature, Geometry } from "geojson"
|
||||
import StaticFeatureSource from "../Sources/StaticFeatureSource"
|
||||
import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
|
||||
|
||||
export default class LocalStorageFeatureSource extends DynamicTileSource {
|
||||
export default class LocalStorageFeatureSource<T extends Feature<Geometry, { [name: string]: any }>> extends DynamicTileSource<T> {
|
||||
constructor(
|
||||
backend: string,
|
||||
layer: LayerConfig,
|
||||
|
@ -30,8 +30,8 @@ export default class LocalStorageFeatureSource extends DynamicTileSource {
|
|||
new ImmutableStore(zoomlevel),
|
||||
layer.minzoom,
|
||||
(tileIndex) =>
|
||||
new StaticFeatureSource(
|
||||
storage.getTileSource(tileIndex).mapD((features) => {
|
||||
new StaticFeatureSource<T>(
|
||||
<Store<T[]>> storage.getTileSource(tileIndex).mapD((features) => {
|
||||
if (features.length === undefined) {
|
||||
console.trace("These are not features:", features)
|
||||
storage.invalidate(tileIndex)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { FeatureSourceForTile, UpdatableFeatureSource } from "../FeatureSource"
|
||||
import { Store } from "../../UIEventSource"
|
||||
import { BBox } from "../../BBox"
|
||||
import { Feature } from "geojson"
|
||||
import { Feature, Polygon } from "geojson"
|
||||
import { GeoOperations } from "../../GeoOperations"
|
||||
import { UpdatableDynamicTileSource } from "./DynamicTileSource"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
|
@ -10,13 +10,14 @@ import { Lists } from "../../../Utils/Lists"
|
|||
* The PolygonSourceMerger receives various small pieces of bigger polygons and stitches them together.
|
||||
* This is used to reconstruct polygons of vector tiles
|
||||
*/
|
||||
export class PolygonSourceMerger extends UpdatableDynamicTileSource<
|
||||
FeatureSourceForTile & UpdatableFeatureSource
|
||||
export class PolygonSourceMerger<P extends Record<string, any> & { id: string },
|
||||
F extends Feature<Polygon, P> = Feature<Polygon, P>> extends UpdatableDynamicTileSource<
|
||||
F, FeatureSourceForTile<F> & UpdatableFeatureSource<F>
|
||||
> {
|
||||
constructor(
|
||||
zoomlevel: Store<number>,
|
||||
minzoom: number,
|
||||
constructSource: (tileIndex: number) => FeatureSourceForTile & UpdatableFeatureSource,
|
||||
constructSource: (tileIndex: number) => FeatureSourceForTile<F> & UpdatableFeatureSource<F>,
|
||||
mapProperties: {
|
||||
bounds: Store<BBox>
|
||||
zoom: Store<number>
|
||||
|
@ -28,9 +29,9 @@ export class PolygonSourceMerger extends UpdatableDynamicTileSource<
|
|||
super(zoomlevel, minzoom, constructSource, mapProperties, options)
|
||||
}
|
||||
|
||||
protected addDataFromSources(sources: FeatureSourceForTile[]) {
|
||||
protected addDataFromSources(sources: FeatureSourceForTile<F>[]) {
|
||||
sources = Lists.noNull(sources)
|
||||
const all: Map<string, Feature> = new Map()
|
||||
const all: Map<string, F> = new Map()
|
||||
const zooms: Map<string, number> = new Map()
|
||||
|
||||
for (const source of sources) {
|
||||
|
@ -60,7 +61,7 @@ export class PolygonSourceMerger extends UpdatableDynamicTileSource<
|
|||
zooms.set(id, z)
|
||||
continue
|
||||
}
|
||||
const merged = GeoOperations.union(f, oldV)
|
||||
const merged = <F> GeoOperations.union(f, oldV)
|
||||
merged.properties = oldV.properties
|
||||
all.set(id, merged)
|
||||
zooms.set(id, z)
|
||||
|
|
|
@ -53,11 +53,11 @@ export class GeoOperations {
|
|||
/**
|
||||
* Create a union between two features
|
||||
*/
|
||||
public static union(
|
||||
public static union<P >(
|
||||
f0: Feature<Polygon | MultiPolygon>,
|
||||
f1: Feature<Polygon | MultiPolygon>
|
||||
): Feature<Polygon | MultiPolygon> | null {
|
||||
return turf.union(turf.featureCollection([f0, f1]))
|
||||
): Feature<Polygon | MultiPolygon, P> | null {
|
||||
return turf.union<P>(turf.featureCollection([f0, f1]))
|
||||
}
|
||||
|
||||
public static intersect(
|
||||
|
|
|
@ -6,7 +6,6 @@ import { ImmutableStore, Store, Stores } from "../UIEventSource"
|
|||
import ImageProvider, { ProvidedImage } from "./ImageProvider"
|
||||
import { WikidataImageProvider } from "./WikidataImageProvider"
|
||||
import Panoramax from "./Panoramax"
|
||||
import { Utils } from "../../Utils"
|
||||
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
|
@ -151,7 +150,7 @@ export default class AllImageProviders {
|
|||
}
|
||||
const source = Stores.concat(allSources).map((result) => {
|
||||
const all = result.flatMap((x) => x)
|
||||
return Utils.DedupOnId(all, (i) => [i?.id, i?.url, i?.alt_id])
|
||||
return Lists.dedupOnId(all, (i) => [i?.id, i?.url, i?.alt_id])
|
||||
})
|
||||
this._cachedImageStores[cachekey] = source
|
||||
return source
|
||||
|
|
|
@ -15,6 +15,7 @@ import NoteCommentElement from "../../UI/Popup/Notes/NoteCommentElement"
|
|||
import OsmObjectDownloader from "../Osm/OsmObjectDownloader"
|
||||
import ExifReader from "exifreader"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
import { IsOnline } from "../Web/IsOnline"
|
||||
|
||||
/**
|
||||
* The ImageUploadManager has a
|
||||
|
@ -81,10 +82,17 @@ export class ImageUploadManager {
|
|||
this._changes = changes
|
||||
this._gps = gpsLocation
|
||||
this._reportError = reportError
|
||||
Stores.chronic(5 * 60000).addCallback(() => {
|
||||
Stores.chronic(5 * 60000).addCallback(async () => {
|
||||
// If images failed to upload: attempt to reupload
|
||||
this.uploadQueue()
|
||||
await this.uploadQueue()
|
||||
})
|
||||
|
||||
IsOnline.isOnline.addCallback(async (isOnline) => {
|
||||
if (isOnline) {
|
||||
await this.uploadQueue()
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
public async canBeUploaded(file: File): Promise<true | { error: Translation }> {
|
||||
|
@ -171,6 +179,9 @@ export class ImageUploadManager {
|
|||
if (this.uploadingAll) {
|
||||
return
|
||||
}
|
||||
if(!IsOnline.isOnline){
|
||||
return
|
||||
}
|
||||
try {
|
||||
let queue: ImageUploadArguments[]
|
||||
const failed: Set<ImageUploadArguments> = new Set()
|
||||
|
|
|
@ -11,6 +11,9 @@ import { Feature, Point } from "geojson"
|
|||
import { AddImageOptions } from "panoramax-js/dist/Panoramax"
|
||||
import { ServerSourceInfo } from "../../Models/SourceOverview"
|
||||
import { ComponentType } from "svelte/types/runtime/internal/dev"
|
||||
import { Strings } from "../../Utils/Strings"
|
||||
import { Utils } from "../../Utils"
|
||||
import { Lists } from "../../Utils/Lists"
|
||||
|
||||
export default class PanoramaxImageProvider extends ImageProvider {
|
||||
public static readonly singleton: PanoramaxImageProvider = new PanoramaxImageProvider()
|
||||
|
@ -194,9 +197,13 @@ export default class PanoramaxImageProvider extends ImageProvider {
|
|||
|
||||
public async DownloadAttribution(providedImage: { id: string }): Promise<LicenseInfo> {
|
||||
const meta = await this.getInfoFor(providedImage.id)
|
||||
const artists = Lists.noEmpty(meta.data.providers.map(p => p.name))
|
||||
|
||||
// We take the last provider, as that one probably contain the username of the uploader
|
||||
const artist = artists.at(-1)
|
||||
|
||||
return {
|
||||
artist: meta.data.providers.at(-1).name, // We take the last provider, as that one probably contain the username of the uploader
|
||||
artist,
|
||||
date: new Date(meta.data.properties["datetime"]),
|
||||
licenseShortName: meta.data.properties["geovisio:license"],
|
||||
}
|
||||
|
|
|
@ -15,7 +15,9 @@ export class WikimediaImageProvider extends ImageProvider {
|
|||
"https://commons.wikimedia.org/wiki/",
|
||||
"https://upload.wikimedia.org",
|
||||
]
|
||||
public static readonly commonsPrefixes = [...WikimediaImageProvider.apiUrls, "File:"]
|
||||
public static readonly commonsPrefixes = [...WikimediaImageProvider.apiUrls,
|
||||
"http://commons.wikimedia.org/wiki/",
|
||||
"http://upload.wikimedia.org", "File:"]
|
||||
private readonly commons_key = "wikimedia_commons"
|
||||
public readonly defaultKeyPrefixes = [this.commons_key, "image"]
|
||||
public readonly name = "Wikimedia"
|
||||
|
|
|
@ -398,7 +398,6 @@ export class OfflineBasemapManager {
|
|||
console.log("Not found in the archives:", { z, x, y })
|
||||
return undefined
|
||||
}
|
||||
console.log("Served tile", { z, x, y }, "from installed archive")
|
||||
return new Response(tileData.data, {
|
||||
headers: { "Content-Type": "application/x.protobuf" },
|
||||
})
|
||||
|
|
|
@ -12,6 +12,7 @@ import CreateNewWayAction from "./CreateNewWayAction"
|
|||
import ThemeConfig from "../../../Models/ThemeConfig/ThemeConfig"
|
||||
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
|
||||
import { Position } from "geojson"
|
||||
import type { OsmFeature } from "../../../Models/OsmFeature"
|
||||
|
||||
export interface MergePointConfig {
|
||||
withinRangeOfM: number
|
||||
|
@ -71,7 +72,7 @@ export default class CreateWayWithPointReuseAction
|
|||
private readonly _state: {
|
||||
theme: ThemeConfig
|
||||
changes: Changes
|
||||
indexedFeatures: IndexedFeatureSource
|
||||
indexedFeatures: IndexedFeatureSource<OsmFeature>
|
||||
fullNodeDatabase?: FullNodeDatabaseSource
|
||||
}
|
||||
private readonly _config: MergePointConfig[]
|
||||
|
@ -82,7 +83,7 @@ export default class CreateWayWithPointReuseAction
|
|||
state: {
|
||||
theme: ThemeConfig
|
||||
changes: Changes
|
||||
indexedFeatures: IndexedFeatureSource
|
||||
indexedFeatures: IndexedFeatureSource<OsmFeature>
|
||||
fullNodeDatabase?: FullNodeDatabaseSource
|
||||
},
|
||||
config: MergePointConfig[]
|
||||
|
@ -199,7 +200,7 @@ export default class CreateWayWithPointReuseAction
|
|||
}
|
||||
features.push(newGeometry)
|
||||
}
|
||||
return StaticFeatureSource.fromGeojson(features)
|
||||
return new StaticFeatureSource(features)
|
||||
}
|
||||
|
||||
public async CreateChangeDescriptions(changes: Changes): Promise<ChangeDescription[]> {
|
||||
|
|
|
@ -14,6 +14,7 @@ import { OsmConnection } from "../OsmConnection"
|
|||
import { Feature, Geometry, LineString, Point } from "geojson"
|
||||
import FullNodeDatabaseSource from "../../FeatureSource/TiledFeatureSource/FullNodeDatabaseSource"
|
||||
import { Lists } from "../../../Utils/Lists"
|
||||
import { OsmFeature } from "../../../Models/OsmFeature"
|
||||
|
||||
export default class ReplaceGeometryAction extends OsmChangeAction implements PreviewableAction {
|
||||
/**
|
||||
|
@ -90,13 +91,13 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
|
|||
public async getPreview(): Promise<FeatureSource> {
|
||||
const { closestIds, allNodesById, detachedNodes, reprojectedNodes } =
|
||||
await this.GetClosestIds()
|
||||
const preview: Feature<Geometry>[] = closestIds.map((newId, i) => {
|
||||
const preview: Feature<Geometry, {id: string}>[] = closestIds.map((newId, i) => {
|
||||
if (this.identicalTo[i] !== undefined) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
if (newId === undefined) {
|
||||
return {
|
||||
return <OsmFeature> {
|
||||
type: "Feature",
|
||||
properties: {
|
||||
newpoint: "yes",
|
||||
|
@ -127,7 +128,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
|
|||
|
||||
reprojectedNodes.forEach(({ newLat, newLon, nodeId }) => {
|
||||
const origNode = allNodesById.get(nodeId)
|
||||
const feature: Feature<LineString> = {
|
||||
const feature: Feature<LineString, {id: string} & Record<string, any>> = {
|
||||
type: "Feature",
|
||||
properties: {
|
||||
move: "yes",
|
||||
|
@ -149,7 +150,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
|
|||
|
||||
detachedNodes.forEach(({ reason }, id) => {
|
||||
const origNode = allNodesById.get(id)
|
||||
const feature: Feature<Point> = {
|
||||
const feature: OsmFeature & Feature<Point> = {
|
||||
type: "Feature",
|
||||
properties: {
|
||||
detach: "yes",
|
||||
|
@ -165,7 +166,7 @@ export default class ReplaceGeometryAction extends OsmChangeAction implements Pr
|
|||
preview.push(feature)
|
||||
})
|
||||
|
||||
return StaticFeatureSource.fromGeojson(Lists.noNull(preview))
|
||||
return new StaticFeatureSource(Lists.noNull(preview))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue