Main categories of OpenStreetBrowser
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

460 lines
13 KiB

  1. query:
  2. (
  3. way[highway=cycleway];
  4. way[cyclestreet=yes];
  5. way[bicycle_road=yes];
  6. way[highway=path][bicycle][bicycle!=no];
  7. way["cycleway"]["cycleway"!~"(no|separate)"];
  8. way["cycleway:left"]["cycleway:left"!~"(no|separate)"];
  9. way["cycleway:right"]["cycleway:right"!~"(no|separate)"];
  10. way["cycleway:both"]["cycleway:both"!~"(no|separate)"];
  11. )
  12. feature:
  13. pre: |
  14. {% set type = tags.highway %}
  15. {% if tags.highway == 'path' and tags.bicycle and tags.bicycle != 'no' %}
  16. {% set type = 'cycleway' %}
  17. {% endif %}
  18. {% if tags.cyclestreet == 'yes' %}
  19. {% set type = 'cyclestreet' %}
  20. {% elseif tags.bicycle_road in ['yes', 'designated'] %}
  21. {% set type = 'bicycle_road' %}
  22. {% endif %}
  23. {% set oneway = attribute(tags, 'oneway:bicycle')|default(tags.oneway) %}
  24. {% if oneway == 'yes' %}
  25. {% set oneway = 1 %}
  26. {% elseif oneway == 'no' %}
  27. {% set oneway = 0 %}
  28. {% endif %}
  29. {% set leftCycle = '' %}{% set rightCycle = '' %}
  30. {% if tags.cycleway %}
  31. {% if tags.cycleway in ['crossing'] %}
  32. {% elseif (tags.oneway in ['yes', 1] and map.driving_side == 'right') or (tags.oneway in [-1] and map.driving_side == 'left') %}
  33. {{ tags.cycleway|debug }}
  34. {% if tags.cycleway matches '/^opposite/' %}
  35. {% set leftCycle = tags.cycleway %}
  36. {% else %}
  37. {% set rightCycle = tags.cycleway %}
  38. {% endif %}
  39. {% elseif (tags.oneway in ['yes', 1] and map.driving_side == 'left') or (tags.oneway in [-1] and map.driving_side == 'right') %}
  40. {% if tags.cycleway matches '/^opposite/' %}
  41. {% set rightCycle = tags.cycleway %}
  42. {% else %}
  43. {% set leftCycle = tags.cycleway %}
  44. {% endif %}
  45. {% else %}
  46. {% set leftCycle = tags.cycleway %}
  47. {% set rightCycle = tags.cycleway %}
  48. {% endif %}
  49. {% endif %}
  50. {% set leftCycle1 = attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both')) %}
  51. {% if leftCycle1 %}{% set leftCycle = leftCycle1 %}{% endif %}
  52. {% if const.hiddenTypes[leftCycle] %}
  53. {% set leftCycle = '' %}
  54. {% endif %}
  55. {% set leftOneway = attribute(tags, 'cycleway:left:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %}
  56. {% if not leftOneway or leftOneway in ['yes'] %}
  57. {% set leftOneway = map.driving_side == 'left' ? 1 : -1 %}
  58. {% elseif leftOneway in ['no'] %}
  59. {% set leftOneway = 0 %}
  60. {% endif %}
  61. {% set rightCycle1 = attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both')) %}
  62. {% if rightCycle1 %}{% set rightCycle = rightCycle1 %}{% endif %}
  63. {% if const.hiddenTypes[rightCycle] %}
  64. {% set rightCycle = '' %}
  65. {% endif %}
  66. {% set rightOneway = attribute(tags, 'cycleway:right:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %}
  67. {% if not rightOneway or rightOneway in ['yes'] %}
  68. {% set rightOneway = map.driving_side == 'left' ? -1 : 1 %}
  69. {% elseif rightOneway in ['no'] %}
  70. {% set rightOneway = 0 %}
  71. {% endif %}
  72. styles: |
  73. {% if tags.bridge and tags.bridge != 'no' %}
  74. bridge,
  75. {% endif %}
  76. {% if tags.cycleway in ['crossing'] or tags.path in ['crossing'] %}
  77. crossing,
  78. {% endif %}
  79. {% if tags.segregated %}
  80. footway,
  81. {% endif %}
  82. default
  83. {% if leftCycle %}
  84. ,left
  85. {% endif %}
  86. {% if rightCycle %}
  87. ,right
  88. {% endif %}
  89. style:
  90. width: |
  91. {% if tags.segregated == 'yes' %}
  92. {{ const.types[type].width / 2 }}
  93. {% else %}
  94. {{ const.types[type].width }}
  95. {% endif %}
  96. dashArray: |
  97. {% if oneway and tags.segregated == 'no' %}
  98. 5,5,5,20
  99. {% elseif oneway %}
  100. 25,10
  101. {% elseif tags.segregated == 'no' %}
  102. 5,5
  103. {% endif %}
  104. dashOffset: |
  105. {% if oneway and tags.segregated == 'no' %}
  106. 5
  107. {% elseif oneway %}
  108. 10
  109. {% elseif tags.segregated == 'no' %}
  110. 0
  111. {% endif %}
  112. lineCap: |
  113. {% if tags.segregated == 'no' or oneway %}
  114. butt
  115. {% else %}
  116. round
  117. {% endif %}
  118. color: |
  119. {{ const.types[type].color }}
  120. offset: |
  121. {% if tags.segregated == 'yes' %}
  122. {{ const.types[type].width / 2 - 1 }}
  123. {% endif %}
  124. pattern: |
  125. {% if oneway -%}
  126. arrowHead
  127. {%- endif %}
  128. pattern-repeat: |
  129. 35
  130. pattern-offset: |
  131. {{ oneway == -1 ? 17 : 22 }}
  132. noClip: |
  133. {{ oneway != 0 }}
  134. pattern-polygon: true
  135. pattern-pixelSize: 9
  136. pattern-angleCorrection: |
  137. {{ oneway == -1 ? 180 : 0 }}
  138. pattern-path-color: |
  139. {{ const.types[type].color }}
  140. pattern-path-width: 0
  141. pattern-path-fillOpacity: 1
  142. zIndex: |-
  143. {{ tags.layer|default(0) }}
  144. style:footway:
  145. color: |
  146. {{ const.types.footway.color }}
  147. width: |
  148. {% if tags.segregated == 'yes' %}
  149. {{ const.types.footway.width / 2 }}
  150. {% else %}
  151. {{ const.types.footway.width }}
  152. {% endif %}
  153. dashArray: |
  154. {% if oneway and tags.segregated == 'no' %}
  155. 5,5,5,5,5,10
  156. {% elseif oneway %}
  157. 25,10
  158. {% elseif tags.segregated == 'no' %}
  159. 5,5
  160. {% endif %}
  161. dashOffset: |
  162. {% if oneway %}
  163. 10
  164. {% elseif tags.segregated == 'no' %}
  165. 5
  166. {% endif %}
  167. noClip: |
  168. {{ oneway != 0 }}
  169. lineCap: |
  170. {% if tags.segregated == 'no' or oneway %}
  171. butt
  172. {% else %}
  173. round
  174. {% endif %}
  175. offset: |
  176. {% if tags.segregated == 'yes' %}
  177. {{ (const.types.footway.width / 2 - 1) * -1 }}
  178. {% endif %}
  179. zIndex: |-
  180. {{ tags.layer|default(0) }}
  181. style:left:
  182. offset: -5
  183. color: |
  184. {{ const.types[leftCycle].color|default('#ff0000') }}
  185. width: 3
  186. lineCap: |
  187. {{ leftOneway ? 'butt' : 'round' }}
  188. dashArray: |
  189. {{ leftOneway ? '27,8' : '' }}
  190. dashOffset: |
  191. {{ leftOneway == -1 ? 28 : 0 }}
  192. noClip: true
  193. # {{ leftOneway }}
  194. pattern: |
  195. {% if leftOneway %}arrowHead{% endif %}
  196. pattern-offset: |
  197. {{ leftOneway == -1 ? 4 : 30.5 }}
  198. pattern-lineOffset: -5
  199. pattern-repeat: 35
  200. pattern-polygon: true
  201. pattern-pixelSize: 9
  202. pattern-angleCorrection: |
  203. {{ leftOneway == -1 ? 180 : 0 }}
  204. pattern-path-width: 0
  205. pattern-path-color: |
  206. {{ const.types[leftCycle].color|default('#ff0000') }}
  207. pattern-path-fillOpacity: 1
  208. zIndex: |-
  209. {{ tags.layer|default(0) }}
  210. style:right:
  211. offset: 5
  212. color: |
  213. {{ const.types[rightCycle].color|default('#ff0000') }}
  214. width: 3
  215. lineCap: |
  216. {{ rightOneway ? 'butt' : 'round' }}
  217. dashArray: |
  218. {{ rightOneway ? '27,8' : '' }}
  219. dashOffset: |
  220. {{ rightOneway == -1 ? 28 : 0 }}
  221. noClip: true
  222. # {{ rightOneway }}
  223. pattern: |
  224. {% if rightOneway %}arrowHead{% endif %}
  225. pattern-offset: |
  226. {{ rightOneway == -1 ? 4 : 30.5 }}
  227. pattern-lineOffset: 5
  228. pattern-repeat: 35
  229. pattern-polygon: true
  230. pattern-pixelSize: 9
  231. pattern-angleCorrection: |
  232. {{ rightOneway == -1 ? 180 : 0 }}
  233. pattern-path-width: 0
  234. pattern-path-color: |
  235. {{ const.types[rightCycle].color|default('#ff0000') }}
  236. pattern-path-fillOpacity: 1
  237. zIndex: |-
  238. {{ tags.layer|default(0) }}
  239. style:crossing:
  240. width: |
  241. {{ const.types[type].width + 4 }}
  242. color: black
  243. lineCap: butt
  244. dashArray: "4,4"
  245. zIndex: |-
  246. {{ tags.layer|default(0) - 0.1 }}
  247. style:bridge:
  248. width: |
  249. {{ const.types[type].width|default(5) + 4 }}
  250. color: black
  251. lineCap: butt
  252. zIndex: |-
  253. {{ tags.layer|default(0) - 0.2 }}
  254. description: |
  255. {% if tags.cyclestreet == 'yes' %}
  256. {{ keyTrans('cyclestreet') }}
  257. {% elseif tags.bicycle_road in ['yes', 'designated'] %}
  258. {{ keyTrans('bicycle_road') }}
  259. {% elseif tags.segregated %}
  260. {{ tagTrans('highway', 'cycleway segregated=' ~ tags.segregated) }}
  261. {% elseif tags.highway %}
  262. {{ tagTrans('highway', tags.highway) }}
  263. {% endif %}
  264. body: |
  265. <ul>
  266. {% if tags.cycleway in ['crossing'] %}
  267. <li>
  268. {{ keyTrans('cycleway') }}: {{ tagTrans('cycleway', tags.cycleway) }}
  269. </li>
  270. {% elseif tags.cycleway and not tags.cycleway in ['crossing'] %}
  271. <li>
  272. {{ keyTrans('cycleway') }}:
  273. <div class='warning'>Recommendation: Indicate side of way by using 'cycleway:left' and/or 'cycleway:right'.</div>
  274. <ul>
  275. <li>{{ keyTrans('cycleway') }}: {{ tagTrans('cycleway', tags.cycleway) }}</li>
  276. </ul>
  277. </li>
  278. {% endif %}
  279. {% if tags.highway in ['cycleway'] or attribute(tags, 'cycleway:width') %}
  280. <li>
  281. {{ keyTrans('cycleway:width') }}:
  282. {% if not attribute(tags, 'cycleway:width') %}
  283. {{ trans('unknown') }}
  284. {% elseif attribute(tags, 'cycleway:width') matches "/(m|')$/" %}
  285. {{ attribute(tags, 'cycleway:width') }}
  286. {% else %}
  287. {{ attribute(tags, 'cycleway:width') }}m
  288. {% endif %}
  289. </li>
  290. {% endif %}
  291. {% if leftCycle %}
  292. <li>{{ keyTrans('cycleway:left') }}:
  293. {% if const.types[leftCycle].warning %}
  294. <div class='warning'>{{ const.types[leftCycle].warning|replace({'%driving_side%': map.driving_side, '%other_driving_side%': map.driving_side == 'right' ? 'left': 'right', '%current%': 'left'}) }}</div>
  295. {% elseif not const.types[leftCycle] %}
  296. <div class='warning'>Invalid tag cycleway:left={{ attribute(tags, 'cycleway:left') }}.</div>
  297. {% endif %}
  298. <ul>
  299. <li>{{ keyTrans('cycleway') }}: {{ tagTrans('cycleway', attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both'))) }}</li>
  300. <li>
  301. {{ keyTrans('cycleway:width') }}:
  302. {% if not leftWidth %}
  303. {{ trans('unknown') }}
  304. {% elseif attribute(tags, 'cycleway:left:width')|default(attribute(tags, 'cycleway:both:width')) matches "/(m|')$/" %}
  305. {{ attribute(tags, 'cycleway:left:width')|default(attribute(tags, 'cycleway:both:width')) }}
  306. {% else %}
  307. {{ leftWidth }}m
  308. {% endif %}
  309. </li>
  310. </ul></li>
  311. {% elseif attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both')) %}
  312. <li>{{ keyTrans('cycleway:left') }}: {{ tagTrans('cycleway', attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both'))) }}</li>
  313. {% endif %}
  314. {% if rightCycle %}
  315. <li>{{ keyTrans('cycleway:right') }}:
  316. {% if const.types[rightCycle].warning %}
  317. <div class='warning'>{{ const.types[rightCycle].warning|replace({'%driving_side%': map.driving_side, '%other_driving_side%': map.driving_side == 'right' ? 'left': 'right', '%current%': 'right'}) }}</div>
  318. {% elseif not const.types[rightCycle] %}
  319. <div class='warning'>Invalid tag cycleway:right={{ attribute(tags, 'cycleway:right') }}.</div>
  320. <div class='warning'>Unknown</div>
  321. {% endif %}
  322. <ul>
  323. <li>{{ keyTrans('cycleway') }}: {{ tagTrans('cycleway', attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both'))) }}</li>
  324. <li>
  325. {{ keyTrans('cycleway:width') }}:
  326. {% if not rightWidth %}
  327. {{ trans('unknown') }}
  328. {% elseif attribute(tags, 'cycleway:right:width')|default(attribute(tags, 'cycleway:both:width')) matches "/(m|')$/" %}
  329. {{ attribute(tags, 'cycleway:right:width')|default(attribute(tags, 'cycleway:both:width')) }}
  330. {% else %}
  331. {{ rightWidth }}m
  332. {% endif %}
  333. </li>
  334. </ul></li>
  335. {% elseif attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both')) %}
  336. <li>{{ keyTrans('cycleway:right') }}: {{ tagTrans('cycleway', attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both'))) }}</li>
  337. {% endif %}
  338. </ul>
  339. markerSymbol: ''
  340. listMarkerSymbol: line
  341. info: |
  342. <table>
  343. <tr>
  344. <th>Symbol</th>
  345. <th></th>
  346. </tr>
  347. {% for k, v in const.types %}
  348. <tr>
  349. <td>
  350. {{ markerLine({ width: 4, color: v.color }) }}
  351. </td>
  352. <td>
  353. {{ k }}
  354. </td>
  355. </tr>
  356. {% endfor %}
  357. </table>
  358. const:
  359. types:
  360. cycleway:
  361. color: '#009f00'
  362. width: 4
  363. footway:
  364. color: '#ff9f00'
  365. width: 4
  366. cyclestreet:
  367. color: '#006f3f'
  368. width: 8
  369. bicycle_road:
  370. color: '#006f4f'
  371. width: 8
  372. lane:
  373. color: '#00df3f'
  374. track:
  375. color: '#009f00'
  376. shared:
  377. color: '#ff0000'
  378. warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway=lane, cycleway:oneway=-1 instead.'
  379. shared_lane:
  380. color: '#003faf'
  381. share_busway:
  382. color: '#ff7f00'
  383. opposite:
  384. color: '#ff0000'
  385. warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=lane, cycleway:%other_driving_side%:oneway=-1 instead.'
  386. opposite_lane:
  387. color: '#ff0000'
  388. warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=lane, cycleway:%other_driving_side%:oneway=-1 instead.'
  389. opposite_share_busway:
  390. color: '#ff0000'
  391. warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=share_busway, cycleway:%other_driving_side%:oneway=-1 instead.'
  392. opposite_track:
  393. color: '#ff0000'
  394. warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=track, cycleway:%other_driving_side%:oneway=-1 instead.'
  395. hiddenTypes:
  396. 'no': true
  397. separate: true