diff --git a/cycleway_types.yaml b/cycleway_types.yaml new file mode 100644 index 0000000..07835b7 --- /dev/null +++ b/cycleway_types.yaml @@ -0,0 +1,553 @@ +query: + ( + way[highway=cycleway]; + way[cyclestreet=yes]; + way[bicycle_road=yes]; + way[highway=path][bicycle][bicycle!=no]; + way[highway=living_street]; + way["cycleway"]["cycleway"!~"(no|separate)"]; + way["cycleway:left"]["cycleway:left"!~"(no|separate)"]; + way["cycleway:right"]["cycleway:right"!~"(no|separate)"]; + way["cycleway:both"]["cycleway:both"!~"(no|separate)"]; + ) +feature: + pre: | + {% set type = tags.highway %} + + {% if tags.highway == 'path' and tags.bicycle and tags.bicycle != 'no' %} + {% set type = 'cycleway' %} + {% endif %} + + {% if tags.cyclestreet == 'yes' %} + {% set type = 'cyclestreet' %} + {% elseif tags.bicycle_road in ['yes', 'designated'] %} + {% set type = 'bicycle_road' %} + {% elseif tags.highway and const.types['highway=' ~ tags.highway] %} + {% set type = 'highway=' ~ tags.highway %} + {% endif %} + + {% set mainOneway = tags.oneway %} + {% if mainOneway == 'yes' %} + {% set mainOneway = 1 %} + {% elseif mainOneway == 'no' %} + {% set mainOneway = 0 %} + {% endif %} + + {% set oneway = attribute(tags, 'oneway:bicycle')|default(tags.oneway) %} + {% if oneway == 'yes' %} + {% set oneway = 1 %} + {% elseif oneway == 'no' %} + {% set oneway = 0 %} + {% endif %} + + {% set leftCycle = '' %}{% set rightCycle = '' %} + + {% if tags.cycleway %} + {% if const.otherInfrastructure[tags.cycleway] %} + {# skip #} + {% elseif (tags.oneway in ['yes', 1] and map.driving_side == 'right') or (tags.oneway in [-1] and map.driving_side == 'left') %} + {{ tags.cycleway|debug }} + {% if tags.cycleway matches '/^opposite/' %} + {% set leftCycle = tags.cycleway %} + {% else %} + {% set rightCycle = tags.cycleway %} + {% endif %} + {% elseif (tags.oneway in ['yes', 1] and map.driving_side == 'left') or (tags.oneway in [-1] and map.driving_side == 'right') %} + {% if tags.cycleway matches '/^opposite/' %} + {% set rightCycle = tags.cycleway %} + {% else %} + {% set leftCycle = tags.cycleway %} + {% endif %} + {% else %} + {% set leftCycle = tags.cycleway %} + {% set rightCycle = tags.cycleway %} + {% endif %} + {% endif %} + + {% set leftCycle1 = attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both')) %} + {% if leftCycle1 %}{% set leftCycle = leftCycle1 %}{% endif %} + {% if const.hiddenTypes[leftCycle] %} + {% set leftCycle = '' %} + {% endif %} + + {% set leftOneway = attribute(tags, 'cycleway:left:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %} + {% if not leftOneway or leftOneway in ['yes'] %} + {% set leftOneway = map.driving_side == 'left' ? 1 : -1 %} + {% elseif leftOneway in ['no'] %} + {% set leftOneway = 0 %} + {% endif %} + + {% set rightCycle1 = attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both')) %} + {% if rightCycle1 %}{% set rightCycle = rightCycle1 %}{% endif %} + {% if const.hiddenTypes[rightCycle] %} + {% set rightCycle = '' %} + {% endif %} + + {% set rightOneway = attribute(tags, 'cycleway:right:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %} + {% if not rightOneway or rightOneway in ['yes'] %} + {% set rightOneway = map.driving_side == 'left' ? -1 : 1 %} + {% elseif rightOneway in ['no'] %} + {% set rightOneway = 0 %} + {% endif %} + + {% if mainOneway and ((not rightCycle and mainOneway == rightOneway) or (not leftCycle and mainOneway == leftOneway)) %} + {% set oneway = mainOneway %} + {% elseif mainOneway == oneway and ((rightCycle and mainOneway == rightOneway) or (leftCycle and mainOneway == leftOneway)) %} + {% set oneway = 0 %} + {% endif %} + + {% if oneway and attribute(tags, 'oneway:bicycle') == 'no' and not rightCycle and not leftCycle %} + {% set oneway = 0 %} + {% endif %} + + styles: | + {% if tags.bridge and tags.bridge != 'no' %} + bridge_outer,bridge_inner, + {% endif %} + + {% if const.otherInfrastructure[tags.cycleway|default(tags.path)] %} + other, + {% endif %} + + {% if tags.segregated %} + footway, + {% endif %} + default + {% if leftCycle %} + ,left + {% endif %} + {% if rightCycle %} + ,right + {% endif %} + style: + width: | + {% if tags.segregated == 'yes' %} + {{ const.types[type].width / 2 }} + {% else %} + {{ const.types[type].width }} + {% endif %} + + dashArray: | + {% if oneway and tags.segregated == 'no' %} + 5,5,5,20 + {% elseif oneway %} + 25,10 + {% elseif tags.segregated == 'no' %} + 5,5 + {% endif %} + + dashOffset: | + {% if oneway and tags.segregated == 'no' %} + 5 + {% elseif oneway %} + 10 + {% elseif tags.segregated == 'no' %} + 0 + {% endif %} + + lineCap: | + {% if tags.segregated == 'no' or oneway %} + butt + {% else %} + round + {% endif %} + + color: | + {{ const.types[type].color }} + + offset: | + {% if tags.segregated == 'yes' %} + {{ const.types[type].width / 2 - 1 }} + {% else %} + 0 + {% endif %} + + pattern: | + {% if oneway -%} + arrowHead + {%- endif %} + + pattern-repeat: | + 35 + + pattern-offset: | + {{ oneway == -1 ? 17 : 22 }} + + noClip: | + {{ oneway != 0 }} + + pattern-polygon: true + + pattern-pixelSize: 9 + + pattern-angleCorrection: | + {{ oneway == -1 ? 180 : 0 }} + + pattern-path-color: | + {{ const.types[type].color }} + + pattern-path-width: 0 + + pattern-path-fillOpacity: 1 + + zIndex: |- + {{ tags.layer|default(0) }} + + style:footway: + color: | + {{ const.types.footway.color }} + + width: | + {% if tags.segregated == 'yes' %} + {{ const.types.footway.width / 2 }} + {% else %} + {{ const.types.footway.width }} + {% endif %} + + dashArray: | + {% if oneway and tags.segregated == 'no' %} + 5,5,5,5,5,10 + {% elseif oneway %} + 25,10 + {% elseif tags.segregated == 'no' %} + 5,5 + {% endif %} + + dashOffset: | + {% if oneway %} + 10 + {% elseif tags.segregated == 'no' %} + 5 + {% endif %} + + noClip: | + {{ oneway != 0 }} + + lineCap: | + {% if tags.segregated == 'no' or oneway %} + butt + {% else %} + round + {% endif %} + + offset: | + {% if tags.segregated == 'yes' %} + {{ (const.types.footway.width / 2 - 1) * -1 }} + {% endif %} + + zIndex: |- + {{ tags.layer|default(0) }} + + style:left: + offset: -5 + + color: | + {{ const.types[leftCycle].color|default('#ff0000') }} + + width: 3 + + lineCap: | + {{ leftOneway ? 'butt' : 'round' }} + dashArray: | + {{ leftOneway ? '27,8' : '' }} + dashOffset: | + {{ leftOneway == -1 ? 28 : 0 }} + noClip: true +# {{ leftOneway }} + pattern: | + {% if leftOneway %}arrowHead{% endif %} + pattern-offset: | + {{ leftOneway == -1 ? 4 : 30.5 }} + pattern-lineOffset: -5 + pattern-repeat: 35 + pattern-polygon: true + pattern-pixelSize: 9 + pattern-angleCorrection: | + {{ leftOneway == -1 ? 180 : 0 }} + pattern-path-width: 0 + + pattern-path-color: | + {{ const.types[leftCycle].color|default('#ff0000') }} + + pattern-path-fillOpacity: 1 + + zIndex: |- + {{ tags.layer|default(0) }} + + style:right: + offset: 5 + + color: | + {{ const.types[rightCycle].color|default('#ff0000') }} + + width: 3 + + lineCap: | + {{ rightOneway ? 'butt' : 'round' }} + dashArray: | + {{ rightOneway ? '27,8' : '' }} + dashOffset: | + {{ rightOneway == -1 ? 28 : 0 }} + noClip: true +# {{ rightOneway }} + pattern: | + {% if rightOneway %}arrowHead{% endif %} + pattern-offset: | + {{ rightOneway == -1 ? 4 : 30.5 }} + pattern-lineOffset: 5 + pattern-repeat: 35 + pattern-polygon: true + pattern-pixelSize: 9 + pattern-angleCorrection: | + {{ rightOneway == -1 ? 180 : 0 }} + pattern-path-width: 0 + + pattern-path-color: | + {{ const.types[rightCycle].color|default('#ff0000') }} + + pattern-path-fillOpacity: 1 + + zIndex: |- + {{ tags.layer|default(0) }} + + style:other: + width: | + {{ const.types[type].width + const.otherInfrastructure[tags.cycleway].extraWidth }} + color: | + {{ const.otherInfrastructure[tags.cycleway].color }} + lineCap: | + {{ const.otherInfrastructure[tags.cycleway].lineCap|default('round') }} + dashArray: | + {{ const.otherInfrastructure[tags.cycleway].dashArray|default('') }} + offset: 0 + zIndex: |- + {{ tags.layer|default(0) - 0.1 }} + + style:bridge_outer: + width: | + {{ const.types[type].width|default(5) + 8 }} + color: black + lineCap: butt + zIndex: |- + {{ tags.layer|default(0) - 0.21 }} + + style:bridge_inner: + width: | + {{ const.types[type].width|default(5) + 4 }} + color: white + lineCap: butt + zIndex: |- + {{ tags.layer|default(0) - 0.2 }} + + description: | + {% if tags.cyclestreet == 'yes' %} + {{ keyTrans('cyclestreet') }} + {% elseif tags.bicycle_road in ['yes', 'designated'] %} + {{ keyTrans('bicycle_road') }} + {% elseif tags.highway and const.types['highway=' ~ tags.highway] %} + {{ tagTrans('highway', tags.highway) }} + {% elseif tags.segregated %} + {{ tagTrans('highway', 'cycleway segregated=' ~ tags.segregated) }} + {% elseif tags.highway %} + {{ tagTrans('highway', tags.highway) }} + {% endif %} + + body: | + + + markerSymbol: '' + listMarkerSymbol: line + +info: | + + + + + + {% for k, v in const.types %} + {% if not v.hideInfo %} + + + + + {% endif %} + {% endfor %} + + {% for k, v in const.otherInfrastructure %} + + + + + {% endfor %} + + + + + +
Symbol
+ {{ markerLine({ width: v.width|default(4), color: v.color }) }} + + {% set label = v.label|default(k|split('=') > 1 ? k : ('cycleway=' ~ k)) %} + {% if label|split('=') > 1 %} + {{ tagTrans(label|split('=')[0], label|split('=')[1]) }} + {% else %} + {{ keyTrans(label) }} + {% endif %} +
+ {{ markerLine(evaluate({ highway: 'cycleway', cycleway: k })) }} + + {{ tagTrans('cycleway', k) }} +
+ {{ markerLine({ width: 4, color: '#ff0000' }) }} + + Deprecated or invalid tag! +
+const: + types: + cyclestreet: + color: '#006f3f' + width: 8 + label: cyclestreet + bicycle_road: + color: '#006f4f' + width: 8 + label: bicycle_road + highway=living_street: + color: '#ff9f00' + width: 8 + cycleway: + color: '#009f00' + width: 4 + footway: + color: '#ff9f00' + width: 4 + lane: + color: '#00df3f' + track: + color: '#009f00' + shared: + color: '#ff0000' + warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway=lane, cycleway:oneway=-1 instead.' + hideInfo: true + shared_lane: + color: '#003faf' + share_busway: + color: '#007faf' + shoulder: + color: '#7f00ff' + opposite: + color: '#ff0000' + warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=lane, cycleway:%other_driving_side%:oneway=-1 instead.' + hideInfo: true + opposite_lane: + color: '#ff0000' + warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=lane, cycleway:%other_driving_side%:oneway=-1 instead.' + hideInfo: true + opposite_share_busway: + color: '#ff0000' + warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=share_busway, cycleway:%other_driving_side%:oneway=-1 instead.' + hideInfo: true + opposite_track: + color: '#ff0000' + warning: 'Deprecated tag! Use oneway:bicycle=no and cycleway:%other_driving_side%=track, cycleway:%other_driving_side%:oneway=-1 instead.' + hideInfo: true + otherInfrastructure: + crossing: + extraWidth: 4 + lineCap: butt + dashArray: '4,4' + color: black + traffic_island: + extraWidth: 2 + lineCap: butt + color: 'black' + hiddenTypes: + 'no': true + 'yes': true + separate: true + sidepath: true + link: true diff --git a/cycleway_width.yaml b/cycleway_width.yaml new file mode 100644 index 0000000..b93d417 --- /dev/null +++ b/cycleway_width.yaml @@ -0,0 +1,266 @@ +query: | + ( + way[highway=cycleway]; + way[highway=path][bicycle][bicycle!=no]; + way["cycleway:width"]; + way["cycleway:left"]["cycleway:left"!~"(no|separate)"]; + way["cycleway:right"]["cycleway:right"!~"(no|separate)"]; + way["cycleway:both"]["cycleway:both"!~"(no|separate)"]; + ) +feature: + pre: | + {% set driving_side = 'right' %} + + {% set type = tags.highway %} + + {% if tags.highway == 'path' and tags.bicycle and tags.bicycle != 'no' %} + {% set type = 'cycleway' %} + {% endif %} + + {% set width = attribute(tags, 'cycleway:width')|default(tags.width) %} + {% if width matches "/'$/" %} + {% set width = (width|slice(0, -1)) * 0.3048 %} + {% endif %} + + {% set leftCycle = attribute(tags, 'cycleway:left')|default(attribute(tags, 'cycleway:both')) %} + {% if leftCycle in ['no', 'separate'] %} + {% set leftCycle = '' %} + {% endif %} + {% set leftOneway = attribute(tags, 'cycleway:left:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %} + {% if not leftOneway or leftOneway in ['yes'] %} + {% set leftOneway = driving_side ? -1 : 1 %} + {% elseif leftOneway in ['no'] %} + {% set leftOneway = 0 %} + {% endif %} + {% set leftWidth = attribute(tags, 'cycleway:left:width')|default(attribute(tags, 'cycleway:both:width')) %} + {% if leftWidth matches "/'$/" %} + {% set leftWidth = (leftWidth|slice(0, -1)) * 0.3048 %} + {% endif %} + + {% set rightCycle = attribute(tags, 'cycleway:right')|default(attribute(tags, 'cycleway:both')) %} + {% if rightCycle in ['no', 'separate'] %} + {% set rightCycle = '' %} + {% endif %} + {% set rightOneway = attribute(tags, 'cycleway:right:oneway')|default(attribute(tags, 'cycleway:both:oneway')) %} + {% if not rightOneway or rightOneway in ['yes'] %} + {% set rightOneway = driving_side ? 1 : -1 %} + {% elseif rightOneway in ['no'] %} + {% set rightOneway = 0 %} + {% endif %} + {% set rightWidth = attribute(tags, 'cycleway:right:width')|default(attribute(tags, 'cycleway:both:width')) %} + {% if rightWidth matches "/'$/" %} + {% set rightWidth = (rightWidth|slice(0, -1)) * 0.3048 %} + {% endif %} + + styles: default{% if leftCycle %},left{% endif %}{% if rightCycle %},right{% endif %} + style: + width: 4 + opacity: | + {{ type == 'cycleway' or attribute(tags, 'cycleway:width') ? 1 : 0 }} + color: | + {% set minWidth = tags.oneway in ['yes', 1, -1] ? const.minWidthOneway : const.minWidthBoth %} + {% set optWidth = tags.oneway in ['yes', 1, -1] ? const.optWidthOneway : const.optWidthBoth %} + + {% if width %} + {{ colorInterpolate(const.colorScheme, (width - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + lineCap: | + {{ tags.oneway in ['yes', 1, -1] ? 'butt' : 'round' }} + dashArray: | + {{ tags.oneway in ['yes', 1, -1] ? '27,8' : '' }} + dashOffset: | + {{ tags.oneway in [-1] ? 28 : 0 }} + noClip: | + {{ tags.oneway in ['yes', 1, -1] }} + pattern: | + {% if type == 'cycleway' or attribute(tags, 'cycleway:width') %} + {% if tags.oneway in ['yes', 1, -1] %}arrowHead{% endif %} + {% endif %} + pattern-offset: | + {{ tags.oneway in [-1] ? 4 : 30.5 }} + pattern-repeat: 35 + pattern-polygon: true + pattern-pixelSize: 9 + pattern-angleCorrection: | + {{ tags.oneway in [-1] ? 180 : 0 }} + pattern-path-width: 0 + pattern-path-color: | + {% if width %} + {{ colorInterpolate(const.colorScheme, (width - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + pattern-path-fillOpacity: 1 + style:left: + offset: -5 + width: | + {{ leftCycle in ['no', 'separate'] ? 0 : 3 }} + color: | + {% set minWidth = const.minWidthOneway %} + {% set optWidth = const.optWidthOneway %} + + {% if leftWidth %} + {{ colorInterpolate(const.colorScheme, (leftWidth - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + lineCap: | + {{ leftOneway ? 'butt' : 'round' }} + dashArray: | + {{ leftOneway ? '27,8' : '' }} + dashOffset: | + {{ leftOneway in [-1] ? 28 : 0 }} + noClip: | + {{ leftOneway }} + pattern: | + {% if leftOneway %}arrowHead{% endif %} + pattern-offset: | + {{ leftOneway == -1 ? 4 : 30.5 }} + pattern-lineOffset: -5 + pattern-repeat: 35 + pattern-polygon: true + pattern-pixelSize: 9 + pattern-angleCorrection: | + {{ leftOneway == -1 ? 180 : 0 }} + pattern-path-width: 0 + pattern-path-color: | + {% if leftWidth %} + {{ colorInterpolate(const.colorScheme, (leftWidth - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + pattern-path-fillOpacity: 1 + style:right: + offset: 5 + width: | + {{ rightCycle in ['no', 'separate'] ? 0 : 3 }} + color: | + {% set minWidth = const.minWidthOneway %} + {% set optWidth = const.optWidthOneway %} + + {% if rightWidth %} + {{ colorInterpolate(const.colorScheme, (rightWidth - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + lineCap: | + {{ rightOneway ? 'butt' : 'round' }} + dashArray: | + {{ rightOneway ? '27,8' : '' }} + dashOffset: | + {{ rightOneway in [-1] ? 28 : 0 }} + noClip: | + {{ rightOneway }} + pattern: | + {% if rightOneway %}arrowHead{% endif %} + pattern-offset: | + {{ rightOneway == -1 ? 4 : 30.5 }} + pattern-lineOffset: 5 + pattern-repeat: 35 + pattern-polygon: true + pattern-pixelSize: 9 + pattern-angleCorrection: | + {{ rightOneway == -1 ? 180 : 0 }} + pattern-path-width: 0 + pattern-path-color: | + {% if rightWidth %} + {{ colorInterpolate(const.colorScheme, (rightWidth - minWidth) / (optWidth - minWidth)) }} + {% else %}{{ const.unknownColor }} + {% endif %} + pattern-path-fillOpacity: 1 + markerSymbol: false + listMarkerSymbol: line + description: | + {{ tagTrans('highway', type) }} + details: | + {% if not attribute(tags, 'cycleway:width') %} + {% elseif attribute(tags, 'cycleway:width') matches "/'$/" %} + {{ attribute(tags, 'cycleway:width') }} + {% else %} + {{ attribute(tags, 'cycleway:width') }}m + {% endif %} + body: | + +info: | + + + + + + + + + + + + {% for v in range(0, 1, 0.25) %} + + + + + + {% endfor %} +
Symbol{{ keyTrans('oneway') }}={{ tagTrans('oneway', 'yes') }}{{ keyTrans('oneway') }}={{ tagTrans('oneway', 'no') }}
+ {{ markerLine({ width: 4, color: const.unknownColor }) }} + + {{ trans('unknown') }} + + {{ trans('unknown') }} +
+ {{ markerLine({ width: 4, color: colorInterpolate(const.colorScheme, v) }) }} + + {% if v == 0 %}<={% elseif v == 1 %}>={% endif %} + {{ (const.minWidthOneway + (v * (const.optWidthOneway - const.minWidthOneway)))|number_format(2) }}m + + {% if v == 0 %}<={% elseif v == 1 %}>={% endif %} + {{ (const.minWidthBoth + (v * (const.optWidthBoth - const.minWidthBoth)))|number_format(2) }}m +
+const: + minWidthBoth: 1.5 + optWidthBoth: 5 + minWidthOneway: 0.75 + optWidthOneway: 3 + colorScheme: ['#ff0000', '#ff00ff', '#0000ff'] + unknownColor: black diff --git a/index.json b/index.json index 2d2f924..eebf557 100644 --- a/index.json +++ b/index.json @@ -243,6 +243,9 @@ }, { "id": "cycle_routes" + }, + { + "id": "cycleway_types" } ] }, diff --git a/lang/en.json b/lang/en.json index 70f0da6..5785941 100644 --- a/lang/en.json +++ b/lang/en.json @@ -92,6 +92,8 @@ "category:cycle_amenities": "Amenities", "category:cycle_directions": "Directions", "category:cycle_routes": "Cycle Routes", + "category:cycleway_types": "Cycleway Types", + "category:cycleway_width": "Cycleway Width", "category:developable_areas": "Developable Areas", "category:education": "Educational Services", "category:electric_power": "Electric Power",