-
-
Notifications
You must be signed in to change notification settings - Fork 94
/
ThemeConfigJson.ts
471 lines (439 loc) · 17.5 KB
/
ThemeConfigJson.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
import { LayerConfigJson } from "./LayerConfigJson"
import ExtraLinkConfigJson from "./ExtraLinkConfigJson"
import { RasterLayerProperties } from "../../RasterLayerProperties"
import { Translatable } from "./Translatable"
/**
* Defines the entire theme.
*
* A theme is the collection of the layers that are shown; the intro text, the icon, ...
* It more or less defines the entire experience.
*
* Most of the fields defined here are metadata about the theme, such as its name, description, supported languages, default starting location, ...
*
* The main chunk of the json will however be the 'layers'-array, where the details of your layers are.
*
* General remark: a type (string | any) indicates either a fixed or a translatable string.
*/
export interface ThemeConfigJson {
/**
* question: What is the id of this layout?
*
* The id is a unique string to identify the theme
*
* It should be
* - in english
* - describe the theme in a single word (or a few words)
* - all lowercase and with only [a-z] or underscores (_)
*
* This is used as hashtag in the changeset message, which will read something like "Adding data with #mapcomplete for theme #<the theme id>"
*
* On official themes, it'll become the name of the page, e.g.
* 'cyclestreets' which become 'cyclestreets.html'
*
* type: id
* group: basic
*/
id: string
/**
* question: What is the title of this theme?
*
* The human-readable title, as shown in the welcome message and the index page
* group: basic
*/
title: Translatable
/**
* Only used in 'generateLayerOverview': if present, every translation will be checked to make sure it is fully translated.
*
* This must be a list of two-letter, lowercase codes which identifies the language, e.g. "en", "nl", ...
*/
mustHaveLanguage?: string[]
/**
* question: How would you describe this theme?
* The description, as shown in the welcome message and the more-screen
* group: basic
*
*/
description: Translatable
/**
* A short description, showed as social description and in the 'more theme'-buttons.
* Note that if this one is not defined, the first sentence of 'description' is used
* group: hidden
*/
shortDescription?: Translatable
/**
* A part of the description, shown under the login-button.
* group: hidden
*/
descriptionTail?: Translatable
/**
* question: What icon should be used to represent this theme?
*
* Used as logo in the more-screen and (for official themes) as favicon, webmanifest logo, ...
*
* Either a URL or a base64 encoded value (which should include 'data:image/svg+xml;base64)
*
* Type: icon
* suggestions: return Constants.defaultPinIcons.map(i => ({if: "value="+i, then: i, icon: i}))
* group: basic
*
*/
icon: string
/**
* question: What image should be used as social image preview?
* This is included as og:image-tag on official themes.
*
* See https://www.h3xed.com/web-and-internet/how-to-use-og-image-meta-tag-facebook-reddit for more information
* ifunset: use the default social image of mapcomplete (or generate one based on the icon)
* Type: image
* group: basic
*/
socialImage?: string
/**
* question: should an extra help button be shown in certain circumstances?
* Adds an additional button on the top-left of the application.
* This can link to an arbitrary location.
*
* For example {icon: "./assets/svg/pop-out.svg", href: 'https://mapcomplete.org/{theme}.html?lat={lat}&lon={lon}&z={zoom}, requirements: ["iframe","no-welcome-message]},
*
* group: advanced
* ifunset: show a link to open MapComplete full screen if used in an iframe
*/
extraLink?: ExtraLinkConfigJson
/**
* question: At what zoomlevel should this theme open?
* Default location and zoom to start.
* Note that this is barely used. Once the user has visited mapcomplete at least once, the previous location of the user will be used
* ifunset: Use the default startzoom (0)
* type: float
* group: start_location
*/
startZoom?: number
/**
* question: At what start latitude should this theme open?
* Default location and zoom to start.
* Note that this is barely used. Once the user has visited mapcomplete at least once, the previous location of the user will be used
* ifunset: Use 0 as start latitude
* type: float
* group: start_location
*/
startLat?: number
/**
* question: At what start longitude should this theme open?
* Default location and zoom to start.
* Note that this is barely used. Once the user has visited mapcomplete at least once, the previous location of the user will be used
* ifunset: Use 0 as start longitude
* type: float
* group: start_location
*/
startLon?: number
/**
* The id of the default background. BY default: vanilla OSM
*/
defaultBackgroundId?: string
/**
*
* Who helped to create this theme and should be attributed?
*/
credits?: string | string[]
/**
* If set to true, this layout will not be shown in the overview with more themes
*/
hideFromOverview?: boolean
/**
* question: What layers should this map show?
* type: layer[]
* types: hidden | layer | hidden
* group: layers
* title: value["builtin"] ?? value["id"] ?? value
* suggestions: return Array.from(layers.keys()).map(key => ({if: "value="+key, then: "<b>"+key+"</b> (builtin) - "+layers.get(key).description}))
*
* A theme must contain at least one layer.
*
* A layer contains all features of a single type, for example "shops", "bicycle pumps", "benches".
* Note that every layer contains a specification of attributes that it should match. MapComplete will fetch the relevant data from either overpass, the OSM-API or the cache server.
* If a feature can match multiple layers, the first matching layer in the list will be used.
* This implies that the _order_ of the layers is important.
*
*
* <div class='hidden-in-studio'>
* Note that builtin layers can be reused. Either put in the name of the layer to reuse, or use {builtin: "layername", override: ...}
*
* The 'override'-object will be copied over the original values of the layer, which allows to change certain aspects of the layer
*
* For example: If you would like to use layer nature reserves, but only from a specific operator (eg. Natuurpunt) you would use the following in your theme:
*
* ```
* "layer": {
* "builtin": "nature_reserve",
* "override": {"source":
* {"osmTags": {
* "+and":["operator=Natuurpunt"]
* }
* }
* }
* }
* ```
*
* It's also possible to load multiple layers at once, for example, if you would like for both drinking water and benches to start at the zoomlevel at 12, you would use the following:
*
* ```
* "layer": {
* "builtin": ["benches", "drinking_water"],
* "override": {"minzoom": 12}
* }
*```
* </div>
*/
layers: (
| LayerConfigJson
| string
| {
builtin: string | string[]
override: Partial<LayerConfigJson>
/**
* TagRenderings with any of these labels will be removed from the layer.
* Note that the 'id' and 'group' are considered labels too
*/
hideTagRenderingsWithLabels?: string[]
}
)[]
/**
* An override applied on all layers of the theme.
*
* E.g.: if there are two layers defined:
* ```
* "layers":[
* {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ...}},
* {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ...}}
* ]
* ```
*
* and overrideAll is specified:
* ```
* "overrideAll": {
* "osmSource":{"geoJsonSource":"xyz"}
* }
* then the result will be that all the layers will have these properties applied and result in:
* "layers":[
* {"title": ..., "tagRenderings": [...], "osmSource":{"tags": ..., "geoJsonSource":"xyz"}},
* {"title", ..., "tagRenderings", [...], "osmSource":{"tags" ..., "geoJsonSource":"xyz"}}
* ]
* ```
*
* If the overrideAll contains a list where the keys starts with a plus, the values will be appended (instead of discarding the old list), for example
*
* "overrideAll": {
* "+tagRenderings": [ { ... some tagrendering ... }]
* }
*
* In the above scenario, `sometagrendering` will be added at the beginning of the tagrenderings of every layer
*/
overrideAll?: Partial<any | LayerConfigJson>
/**
* Define some (overlay) slippy map tilesources
*/
tileLayerSources?: (RasterLayerProperties & { defaultState?: true | boolean })[]
/**
* The URL of a custom CSS stylesheet to modify the layout
* group: advanced
*/
customCss?: string
/**
* If set to true, the basemap will not scroll outside of the area visible on initial zoom.
* If set to [[lon, lat], [lon, lat]], the map will not scroll outside of those bounds.
* Off by default, which will enable panning to the entire world
*/
lockLocation?: [[number, number], [number, number]] | number[][]
/**
* question: Should a user be able to login with OpenStreetMap?
*
* If not logged in, will not show the login buttons and hide all the editable elements.
* As such, MapComplete will become read-only and a purely visualisation tool.
*
* ifunset: Enable the possiblity to login with OpenStreetMap (default)
* iffalse: Do not enable to login with OpenStreetMap, have a read-only view of MapComplete.
* iftrue: Enable the possiblity to login with OpenStreetMap
* group: feature_switches
*/
enableUserBadge?: true | boolean
/**
* question: Should the tab with options to share the current screen be enabled?
*
* On can get the iFrame embed code here
*
* ifunset: Enable the sharescreen (default)
* iffalse: Do not enable the share screen
* iftrue: Enable the share screen
* group: feature_switches
*/
enableShareScreen?: true | boolean
/**
* question: Should the user be able to switch to different themes?
*
* Typically enabled in iframes and/or on commisioned themes
*
* iftrue: enable to go back to the index page showing all themes
* iffalse: do not enable to go back to the index page showing all themes; hide the 'more themes' buttons
* ifunset: mapcomplete default: enable to go back to the index page showing all themes
* group: feature_switches
*/
enableMoreQuests?: true | boolean
/**
* question: Should the user be able to enable/disable layers and to filter the layers?
*
* The corresponding URL-parameter is 'fs-filters' instead of 'fs-layers'
* iftrue: enable the filters/layers pane
* iffalse: do not enable to filter or to disable layers; hide the 'filter' tab from the overview and the button at the bottom-left
* ifunset: mapcomplete default: enable to filter or to enable/disable layers
* group: feature_switches
*/
enableLayers?: true | boolean
/**
* question: Should the user be able to search for locations?
*
* ifunset: MapComplete default: allow to search
* iftrue: Allow to search
* iffalse: Do not allow to search; hide the search-bar
* group: feature_switches
*/
enableSearch?: true | boolean
/**
* question: Should the user be able to add new points?
*
* Adding new points is only possible if the loaded layers have presets set.
* Some layers do not have presets. If the theme only has layers without presets, then adding new points will not be possible.
*
* ifunset: MapComplete default: allow to create new points
* iftrue: Allow to create new points
* iffalse: Do not allow to create new points, even if the layers in this theme support creating new points
* group: feature_switches
*/
enableAddNewPoints?: true | boolean
/**
* question: Should the user be able to use their GPS to geolocate themselfes on the map?
* ifunset: MapComplete default: allow to use the GPS
* iftrue: Allow to use the GPS
* iffalse: Do not allow to use the GPS, hide the geolocation-buttons
* group: feature_switches
*/
enableGeolocation?: true | boolean
/**
* Enable switching the backgroundlayer.
* If false, the quickswitch-buttons are removed (bottom left) and the dropdown in the layer selection is removed as well
*
* question: Should the user be able to switch the background layer?
*
* iftrue: Allow to switch the background layer
* iffalse: Do not allow to switch the background layer
* ifunset: MapComplete default: Allow to switch the background layer
* group: feature_switches
*/
enableBackgroundLayerSelection?: true | boolean
/**
* question: Should the questions about a feature be presented one by one or all at once?
* iftrue: Show all unanswered questions at the same time
* iffalse: Show unanswered questions one by one
* ifunset: MapComplete default: Use the preference of the user to show questions at the same time or one by one
* group: feature_switches
*/
enableShowAllQuestions?: false | boolean
/**
* question: Should the 'download as CSV'- and 'download as Geojson'-buttons be enabled?
* iftrue: Enable the option to download the map as CSV and GeoJson
* iffalse: Disable the option to download the map as CSV and GeoJson
* ifunset: MapComplete default: Enable the option to download the map as CSV and GeoJson
* group: feature_switches
*/
enableDownload?: true | boolean
/**
* question: Should the 'download as PDF'-button be enabled?
* iftrue: Enable the option to download the map as PDF
* iffalse: Enable the option to download the map as PDF
* ifunset: MapComplete default: Enable the option to download the map as PDF
* group: feature_switches
*/
enablePdfDownload?: true | boolean
/**
* question: Should the 'notes' from OpenStreetMap be loaded and parsed for import helper notes?
* If true, notes will be loaded and parsed. If a note is an import (as created by the import_helper.html-tool from mapcomplete),
* these notes will be shown if a relevant layer is present.
*
* ifunset: MapComplete default: do not load import notes for sideloaded themes but do load them for official themes
* iftrue: Load notes and show import notes
* iffalse: Do not load import notes
* group: advanced
*/
enableNoteImports?: true | boolean
/**
* question: Should the map use elevation data to give a 3D-feel?
*
* This is especially useful for hiking maps, skiing maps etc...
*
* ifunset: MapComplete default: don't use terrain
* iftrue: Use elevation and render 3D
* iffalse: Do not use terrain
* group: advanced
*/
enableTerrain?: false | boolean
/**
* question: What overpass-api instance should be used for this layout?
*
* ifunset: Use the default, builtin collection of overpass instances
* group: advanced
*/
overpassUrl?: string[]
/**
* question: After how much seconds should the overpass-query stop?
* If a query takes too long, the overpass-server will abort.
* Once can set the amount of time before overpass gives up here.
* ifunset: use the default amount of 30 seconds as timeout
* type: pnat
* group: advanced
*/
overpassTimeout?: number
/**
* At low zoom levels, overpass is used to query features.
* At high zoom level, the OSM api is used to fetch one or more BBOX aligning with a slippy tile.
* The overpassMaxZoom controls the flipoverpoint: if the zoom is this or lower, overpass is used.
*/
overpassMaxZoom?: 17 | number
/**
* When the OSM-api is used to fetch features, it does so in a tiled fashion.
* These tiles are using a ceratin zoom level, that can be controlled here
* Default: overpassMaxZoom + 1
*/
osmApiTileSize?: number
/**
* Enables tracking of all nodes when data is loaded.
* This is useful for the 'ImportWay' and 'ConflateWay'-buttons who need this database.
*
* Note: this flag will be automatically set and can thus be ignored.
* group: hidden
*/
enableNodeDatabase?: boolean
/**
* question: Should this theme leak some location info when making changes?
*
* When a changeset is made, a 'distance to object'-class is written to the changeset.
* For some particular themes and layers, this might leak too much information, and we want to obfuscate this
*
* ifunset: Write 'change_within_x_m' as usual and if GPS is enabled
* iftrue: Do not write 'change_within_x_m' and do not indicate that this was done by survey
*/
enableMorePrivacy?: boolean
/**
* question: Should this theme have the cache enabled?
*
* Should only be dissabled in highly specific cases, such as the GRB-theme
*
* ifunset: Cache is enabled
* iffalse: Do not cache data
* group: hidden
*/
enableCache?: true | boolean
/**
* Set by the preprocessor
* group: hidden
*/
_usedImages?: string[]
}