2020-08-30 01:13:18 +02:00
import { AndOrTagConfigJson } from "./TagConfigJson" ;
2021-08-07 23:11:34 +02:00
import { TagRenderingConfigJson } from "./TagRenderingConfigJson" ;
2021-07-22 11:29:09 +02:00
import FilterConfigJson from "./FilterConfigJson" ;
2021-08-07 23:11:34 +02:00
import { DeleteConfigJson } from "./DeleteConfigJson" ;
2021-09-13 01:21:47 +02:00
import UnitConfigJson from "./UnitConfigJson" ;
2020-08-30 01:13:18 +02:00
/ * *
* Configuration for a single layer
* /
export interface LayerConfigJson {
/ * *
* The id of this layer .
* This should be a simple , lowercase , human readable string that is used to identify the layer .
* /
id : string ;
2021-03-29 02:53:06 +02:00
2020-08-30 01:13:18 +02:00
/ * *
* The name of this layer
2021-05-04 17:47:00 +02:00
* Used in the layer control panel and the 'Personal theme' .
2021-07-03 14:35:44 +02:00
*
2021-05-04 17:47:00 +02:00
* If not given , will be hidden ( and thus not toggable ) in the layer control
2020-08-30 01:13:18 +02:00
* /
2021-05-04 17:47:00 +02:00
name? : string | any
2020-08-30 01:13:18 +02:00
/ * *
* A description for this layer .
2021-01-05 01:30:59 +01:00
* Shown in the layer selections and in the personel theme
2020-08-30 01:13:18 +02:00
* /
description? : string | any ;
2021-03-20 23:45:52 +01:00
/ * *
* This determines where the data for the layer is fetched .
* There are some options :
2021-03-29 02:53:06 +02:00
*
2021-05-14 02:25:30 +02:00
* # Query OSM directly
2021-07-03 14:35:44 +02:00
* source : { osmTags : "key=value" }
2021-05-14 02:25:30 +02:00
* will fetch all objects with given tags from OSM .
* Currently , this will create a query to overpass and fetch the data - in the future this might fetch from the OSM API
2021-07-03 14:35:44 +02:00
*
2021-05-14 02:25:30 +02:00
* # Query OSM Via the overpass API with a custom script
2021-03-29 02:53:06 +02:00
* source : { overpassScript : "<custom overpass tags>" } when you want to do special things . _This should be really rare_ .
2021-03-20 23:45:52 +01:00
* This means that the data will be pulled from overpass with this script , and will ignore the osmTags for the query
* However , for the rest of the pipeline , the OsmTags will _still_ be used . This is important to enable layers etc . . .
2021-03-29 02:53:06 +02:00
*
*
2021-07-03 14:35:44 +02:00
* # A single geojson - file
* source : { geoJson : "https://my.source.net/some-geo-data.geojson" }
2021-05-14 02:25:30 +02:00
* fetches a geojson from a third party source
2021-07-03 14:35:44 +02:00
*
2021-05-14 02:25:30 +02:00
* # A tiled geojson source
2021-07-03 14:35:44 +02:00
* source : { geoJson : "https://my.source.net/some-tile-geojson-{layer}-{z}-{x}-{y}.geojson" , geoJsonZoomLevel : 14 }
2021-05-14 02:25:30 +02:00
* to use a tiled geojson source . The web server must offer multiple geojsons . { z } , { x } and { y } are substituted by the location ; { layer } is substituted with the id of the loaded layer
*
2021-07-03 14:35:44 +02:00
*
* Note that both geojson - options might set a flag 'isOsmCache' indicating that the data originally comes from OSM too
*
*
2021-07-22 10:00:24 +02:00
* NOTE : the previous format was 'overpassTags: AndOrTagConfigJson | string' , which is interpreted as a shorthand for source : { osmTags : "key=value" }
2021-03-21 00:44:23 +01:00
* While still supported , this is considered deprecated
2021-03-20 23:45:52 +01:00
* /
2021-09-21 02:10:42 +02:00
source : { osmTags : AndOrTagConfigJson | string , overpassScript? : string } |
{ osmTags : AndOrTagConfigJson | string , geoJson : string , geoJsonZoomLevel? : number , isOsmCache? : boolean }
2021-03-24 01:25:57 +01:00
/ * *
2021-03-29 02:53:06 +02:00
*
2021-03-26 03:24:58 +01:00
* A list of extra tags to calculate , specified as "keyToAssignTo=javascript-expression" .
* There are a few extra functions available . Refer to < a > Docs / CalculatedTags . md < / a > for more information
* The functions will be run in order , e . g .
* [
* "_max_overlap_m2=Math.max(...feat.overlapsWith(" someOtherLayer " ) . map ( o = > o . overlap ) )
* " _max_overlap_ratio = Number ( feat . _max_overlap_m2 ) / feat . area
* ]
2021-03-29 02:53:06 +02:00
*
2021-03-24 01:25:57 +01:00
* /
2021-03-29 02:53:06 +02:00
calculatedTags? : string [ ] ;
2021-03-24 01:25:57 +01:00
2020-11-17 02:22:48 +01:00
/ * *
2021-03-29 02:53:06 +02:00
* If set , this layer will not query overpass ; but it ' ll still match the tags above which are by chance returned by other layers .
2020-11-17 02:22:48 +01:00
* Works well together with 'passAllFeatures' , to add decoration
* /
doNotDownload? : boolean ;
2021-03-25 15:19:44 +01:00
/ * *
2021-07-22 10:00:24 +02:00
* This tag rendering should either be 'yes' or 'no' . If 'no' is returned , then the feature will be hidden from view .
2021-09-18 02:32:40 +02:00
* This is useful to hide certain features from view .
*
* Important : hiding features does not work dynamically , but is only calculated when the data is first renders .
2021-03-26 00:55:36 +01:00
* This implies that it is not possible to hide a feature after a tagging change
2021-03-29 02:53:06 +02:00
*
2021-03-25 15:19:44 +01:00
* The default value is 'yes'
* /
isShown? : TagRenderingConfigJson ;
2020-08-30 01:13:18 +02:00
/ * *
2021-07-27 19:39:57 +02:00
* The minimum needed zoomlevel required before loading of the data start
2021-03-21 01:36:34 +01:00
* Default : 0
2020-08-30 01:13:18 +02:00
* /
2021-03-21 01:36:34 +01:00
minzoom? : number ;
2020-08-30 01:13:18 +02:00
2021-03-21 01:36:34 +01:00
/ * *
2021-07-22 10:00:24 +02:00
* The zoom level at which point the data is hidden again
2021-03-21 01:36:34 +01:00
* Default : 100 ( thus : always visible
* /
2021-07-27 19:39:57 +02:00
minzoomVisible? : number ;
2021-03-29 02:53:06 +02:00
2020-08-30 01:13:18 +02:00
/ * *
2020-10-27 01:01:34 +01:00
* The title shown in a popup for elements of this layer .
2020-08-30 01:13:18 +02:00
* /
2020-11-17 02:22:48 +01:00
title? : string | TagRenderingConfigJson ;
/ * *
* Small icons shown next to the title .
* If not specified , the OsmLink and wikipedia links will be used by default .
2021-06-22 03:16:45 +02:00
* Use an empty array to hide them .
* Note that "defaults" will insert all the default titleIcons
2020-11-17 02:22:48 +01:00
* /
2020-10-27 01:01:34 +01:00
titleIcons ? : ( string | TagRenderingConfigJson ) [ ] ;
2020-08-30 01:13:18 +02:00
/ * *
* The icon for an element .
* Note that this also doubles as the icon for this layer ( rendered with the overpass - tags ) á nd the icon in the presets .
2021-03-29 02:53:06 +02:00
*
2020-11-27 13:39:00 +01:00
* The result of the icon is rendered as follows :
2021-07-22 10:00:24 +02:00
* the resulting string is interpreted as a _list_ of items , separated by ";" . The bottommost layer is the first layer .
2020-11-27 13:39:00 +01:00
* As a result , on could use a generic pin , then overlay it with a specific icon .
2021-07-22 10:00:24 +02:00
* To make things even more practical , one can use all SVG ' s from the folder "assets/svg" and _substitute the color_ in it .
2020-11-27 13:39:00 +01:00
* E . g . to draw a red pin , use "pin:#f00" , to have a green circle with your icon on top , use ` circle:#0f0;<path to my icon.svg> `
2021-07-03 14:35:44 +02:00
*
2020-08-30 01:13:18 +02:00
* /
icon? : string | TagRenderingConfigJson ;
2020-08-31 02:59:47 +02:00
2020-11-27 03:05:29 +01:00
/ * *
* IconsOverlays are a list of extra icons / badges to overlay over the icon .
* The 'badge' - toggle changes their behaviour .
* If badge is set , it will be added as a 25 % height icon at the bottom right of the icon , with all the badges in a flex layout .
* If badges is false , it ' ll be a simple overlay
2021-03-29 02:53:06 +02:00
*
2020-11-27 13:39:00 +01:00
* Note : strings are interpreted as icons , so layering and substituting is supported
2020-11-27 03:05:29 +01:00
* /
2021-03-29 02:53:06 +02:00
iconOverlays ? : { if : string | AndOrTagConfigJson , then : string | TagRenderingConfigJson , badge? : boolean } [ ]
2020-11-27 03:05:29 +01:00
2020-08-31 02:59:47 +02:00
/ * *
2021-03-29 02:53:06 +02:00
* A string containing "width,height" or "width,height,anchorpoint" where anchorpoint is any of 'center' , 'top' , 'bottom' , 'left' , 'right' , 'bottomleft' , 'topright' , . . .
2020-08-31 02:59:47 +02:00
* Default is '40,40,center'
* /
iconSize? : string | TagRenderingConfigJson ;
2020-08-30 01:13:18 +02:00
/ * *
2020-11-17 16:29:51 +01:00
* The rotation of an icon , useful for e . g . directions .
* Usage : as if it were a css property for 'rotate' , thus has to end with 'deg' , e . g . ` 90deg ` , ` {direction}deg ` , ` calc(90deg - {camera:direction}deg) ` `
2020-11-17 02:22:48 +01:00
* /
rotation? : string | TagRenderingConfigJson ;
2021-04-10 23:53:13 +02:00
/ * *
2021-07-03 14:35:44 +02:00
* A HTML - fragment that is shown below the icon , for example :
2021-04-11 00:09:19 +02:00
* < div style = "background: white; display: block" > { name } < / div >
2021-07-03 14:35:44 +02:00
*
2021-04-18 14:24:30 +02:00
* If the icon is undefined , then the label is shown in the center of the feature .
* Note that , if the wayhandling hides the icon then no label is shown as well .
2021-04-10 23:53:13 +02:00
* /
2021-07-03 14:35:44 +02:00
label? : string | TagRenderingConfigJson ;
2020-11-17 02:22:48 +01:00
/ * *
* The color for way - elements and SVG - elements .
* If the value starts with "--" , the style of the body element will be queried for the corresponding variable instead
2020-08-30 01:13:18 +02:00
* /
color? : string | TagRenderingConfigJson ;
/ * *
* The stroke - width for way - elements
* /
width? : string | TagRenderingConfigJson ;
2020-10-30 00:56:46 +01:00
/ * *
* A dasharray , e . g . "5 6"
* The dasharray defines 'pixels of line, pixels of gap, pixels of line, pixels of gap' ,
* Default value : "" ( empty string == full line )
* /
dashArray? : string | TagRenderingConfigJson
2020-08-30 01:13:18 +02:00
/ * *
* Wayhandling : should a way / area be displayed as :
* 0 ) The way itself
2020-11-19 10:05:10 +01:00
* 1 ) Only the centerpoint
* 2 ) The centerpoint and the way
2020-08-30 01:13:18 +02:00
* /
wayHandling? : number ;
2020-11-17 02:22:48 +01:00
/ * *
2021-01-03 03:09:52 +01:00
* If set , this layer will pass all the features it receives onto the next layer .
* This is ideal for decoration , e . g . directionss on cameras
2020-11-17 02:22:48 +01:00
* /
2021-03-29 02:53:06 +02:00
passAllFeatures? : boolean
2020-08-30 01:13:18 +02:00
/ * *
2020-12-09 17:30:11 +01:00
* Presets for this layer .
* A preset shows up when clicking the map on a without data ( or when right - clicking / long - pressing ) ;
* it will prompt the user to add a new point .
2021-03-29 02:53:06 +02:00
*
2020-12-09 17:30:11 +01:00
* The most important aspect are the tags , which define which tags the new point will have ;
* The title is shown in the dialog , along with the first sentence of the description .
2021-03-29 02:53:06 +02:00
*
2020-12-09 17:30:11 +01:00
* Upon confirmation , the full description is shown beneath the buttons - perfect to add pictures and examples .
2021-03-29 02:53:06 +02:00
*
2020-12-09 17:30:11 +01:00
* Note : the icon of the preset is determined automatically based on the tags and the icon above . Don ' t worry about that !
* NB : if no presets are defined , the popup to add new points doesn ' t show up at all
2020-08-30 01:13:18 +02:00
* /
presets ? : {
2021-03-14 20:40:54 +01:00
/ * *
* The title - shown on the 'add-new' - button .
* /
2020-08-30 01:13:18 +02:00
title : string | any ,
2021-03-14 20:40:54 +01:00
/ * *
* The tags to add . It determines the icon too
* /
2020-08-31 02:59:47 +02:00
tags : string [ ] ,
2021-03-14 20:40:54 +01:00
/ * *
* The _first sentence_ of the description is shown on the button of the ` add ` menu .
* The full description is shown in the confirmation dialog .
2021-03-29 02:53:06 +02:00
*
2021-03-14 20:40:54 +01:00
* ( The first sentence is until the first '.' - character in the description )
* /
2020-08-30 01:13:18 +02:00
description? : string | any ,
2021-07-14 00:17:15 +02:00
/ * *
* If set , the user will prompted to confirm the location before actually adding the data .
2021-07-22 10:00:24 +02:00
* This will be with a 'drag crosshair' - method .
2021-08-07 23:11:34 +02:00
*
2021-07-14 00:17:15 +02:00
* If 'preferredBackgroundCategory' is set , the element will attempt to pick a background layer of that category .
* /
preciseInput? : true | {
2021-08-07 21:19:01 +02:00
/ * *
* The type of background picture
* /
preferredBackground : "osmbasedmap" | "photo" | "historicphoto" | "map" | string | string [ ] ,
/ * *
* If specified , these layers will be shown to and the new point will be snapped towards it
* /
snapToLayer? : string | string [ ] ,
/ * *
* If specified , a new point will only be snapped if it is within this range .
* Distance in meter
*
* Default : 10
* /
maxSnapDistance? : number
2021-07-14 00:17:15 +02:00
}
2020-08-30 01:13:18 +02:00
} [ ] ,
/ * *
* All the tag renderings .
2020-11-17 02:22:48 +01:00
* A tag rendering is a block that either shows the known value or asks a question .
2021-03-29 02:53:06 +02:00
*
2020-11-18 13:41:31 +01:00
* Refer to the class ` TagRenderingConfigJson ` to see the possibilities .
2021-03-29 02:53:06 +02:00
*
2021-07-22 10:00:24 +02:00
* Note that we can also use a string here - where the string refers to a tag rendering defined in ` assets/questions/questions.json ` ,
2020-11-18 13:41:31 +01:00
* where a few very general questions are defined e . g . website , phone number , . . .
2021-03-29 02:53:06 +02:00
*
2020-12-08 23:44:34 +01:00
* A special value is 'questions' , which indicates the location of the questions box . If not specified , it ' ll be appended to the bottom of the featureInfobox .
2021-03-29 02:53:06 +02:00
*
2020-08-30 01:13:18 +02:00
* /
2021-09-09 20:26:12 +02:00
tagRenderings ? : ( string | { builtin : string , override : any } | TagRenderingConfigJson ) [ ] ,
2021-03-29 02:53:06 +02:00
2021-07-22 11:29:09 +02:00
/ * *
* All the extra questions for filtering
* /
filter ? : ( FilterConfigJson ) [ ] ,
2021-07-03 14:35:44 +02:00
/ * *
* This block defines under what circumstances the delete dialog is shown for objects of this layer .
* If set , a dialog is shown to the user to ( soft ) delete the point .
* The dialog is built to be user friendly and to prevent mistakes .
* If deletion is not possible , the dialog will hide itself and show the reason of non - deletability instead .
*
* To configure , the following values are possible :
*
* - false : never ever show the delete button
* - true : show the default delete button
* - undefined : use the mapcomplete default to show deletion or not . Currently , this is the same as 'false' but this will change in the future
* - or : a hash with options ( see below )
*
* The delete dialog
* === === === === === ==
*
*
*
# # # # Hard deletion if enough experience
A feature can only be deleted from OpenStreetMap by mapcomplete if :
- It is a node
- No ways or relations use the node
- The logged - in user has enough experience OR the user is the only one to have edited the point previously
- The logged - in user has no unread messages ( or has a ton of experience )
- The user did not select one of the 'non-delete-options' ( see below )
In all other cases , a 'soft deletion' is used .
# # # # Soft deletion
A 'soft deletion' is when the point isn 't deleted from OSM but retagged so that it' ll won ' t how up in the mapcomplete theme anymore .
This makes it look like it was deleted , without doing damage . A fixme will be added to the point .
Note that a soft deletion is _only_ possible if these tags are provided by the theme creator , as they ' ll be different for every theme
# # # # No - delete options
In some cases , the contributor might want to delete something for the wrong reason ( e . g . someone who wants to have a path removed "because the path is on their private property" ) .
However , the path exists in reality and should thus be on OSM - otherwise the next contributor will pass by and notice " hey , there is a path missing here ! Let me redraw it in OSM ! )
The correct approach is to retag the feature in such a way that it is semantically correct * and * that it doesn ' t show up on the theme anymore .
A no - delete option is offered as 'reason to delete it' , but secretly retags .
* /
deletion? : boolean | DeleteConfigJson
2021-03-29 02:53:06 +02:00
2021-07-15 20:47:28 +02:00
/ * *
* IF set , a 'split this road' button is shown
* /
allowSplit? : boolean
2021-09-13 01:21:47 +02:00
/ * *
* In some cases , a value is represented in a certain unit ( such as meters for heigt / distance / . . . , km / h for speed , . . . )
*
* Sometimes , multiple denominations are possible ( e . g . km / h vs mile / h ; megawatt vs kilowatt vs gigawatt for power generators , . . . )
*
* This brings in some troubles , as there are multiple ways to write it ( no denomitation , 'm' vs 'meter' 'metre' , . . . )
*
* Not only do we want to write consistent data to OSM , we also want to present this consistently to the user .
* This is handled by defining units .
*
* # Rendering
*
* To render a value with long ( human ) denomination , use { canonical ( key ) }
*
* # Usage
*
* First of all , you define which keys have units applied , for example :
*
* ` ` `
* units : [
* appliesTo : [ "maxspeed" , "maxspeed:hgv" , "maxspeed:bus" ]
* applicableUnits : [
* . . .
* ]
* ]
* ` ` `
*
* ApplicableUnits defines which is the canonical extension , how it is presented to the user , . . . :
*
* ` ` `
* applicableUnits : [
* {
* canonicalDenomination : "km/h" ,
* alternativeDenomination : [ "km/u" , "kmh" , "kph" ]
* default : true ,
* human : {
* en : "kilometer/hour" ,
* nl : "kilometer/uur"
* } ,
* humanShort : {
* en : "km/h" ,
* nl : "km/u"
* }
* } ,
* {
* canoncialDenomination : "mph" ,
* . . . similar for miles an hour . . .
* }
* ]
* ` ` `
*
*
* If this is defined , then every key which the denominations apply to ( ` maxspeed ` , ` maxspeed:hgv ` and ` maxspeed:bus ` ) will be rewritten at the metatagging stage :
* every value will be parsed and the canonical extension will be added add presented to the other parts of the code .
*
* Also , if a freeform text field is used , an extra dropdown with applicable denominations will be given
*
* /
units? : UnitConfigJson [ ]
2020-08-30 01:13:18 +02:00
}