diff --git a/css/app.css b/css/app.css index bc5c07269..39a6b2c76 100644 --- a/css/app.css +++ b/css/app.css @@ -1234,6 +1234,21 @@ a:hover .icon.out-link { background-position: -500px -14px;} border-bottom-right-radius: 4px; } +/* preset form cycleway */ + +.form-field-cycleway .preset-input-wrap li { + border-bottom: 1px solid #CCC; +} +.form-field-cycleway .preset-input-wrap li:last-child { + border-bottom: 0; +} + +.preset-input-cycleway-wrap input { + border-radius: 0; + border-width: 0; + border-left-width: 1px; +} + /* preset form numbers */ input[type=number] { diff --git a/data/presets.yaml b/data/presets.yaml index 1878cfe8f..c7d84bcc1 100644 --- a/data/presets.yaml +++ b/data/presets.yaml @@ -251,6 +251,44 @@ en: cuisine: # 'cuisine=*' label: Cuisine + cycleway: + # 'cycleway=*, cycleway:left=*, cycleway:right=*' + label: Bike Lanes + options: + # lane=yes + lane: + description: A bike lane separated from auto traffic by a painted line + title: Standard bike lane + # no=yes + 'no': + description: No bike lane + title: None + # opposite=yes + opposite: + description: A bike lane that travels in both directions on a one-way street + title: Contraflow bike lane + # opposite_lane=yes + opposite_lane: + description: A bike lane that travels in the opposite direction of traffic + title: Opposite bike lane + # share_busway=yes + share_busway: + description: A bike lane shared with a bus lane + title: Bike lane shared with bus + # shared_lane=yes + shared_lane: + description: A bike lane with no separation from auto traffic + title: Shared bike lane + # track=yes + track: + description: A bike lane separated from traffic by a physical barrier + title: Bike track + # cycleway field placeholder + placeholder: 'lane, shared lane' + types: + cycleway: Both sides + 'cycleway:left': Left side + 'cycleway:right': Right side delivery: # 'delivery=*' label: Delivery diff --git a/data/presets/fields.json b/data/presets/fields.json index 518aacbeb..ec6c1957e 100644 --- a/data/presets/fields.json +++ b/data/presets/fields.json @@ -321,6 +321,56 @@ "type": "combo", "label": "Cuisine" }, + "cycleway": { + "keys": [ + "cycleway", + "cycleway:left", + "cycleway:right" + ], + "reference": { + "key": "cycleway" + }, + "type": "cycleway", + "label": "Bike Lanes", + "placeholder": "lane, shared lane", + "strings": { + "types": { + "cycleway": "Both sides", + "cycleway:left": "Left side", + "cycleway:right": "Right side" + }, + "options": { + "no": { + "title": "None", + "description": "No bike lane" + }, + "lane": { + "title": "Standard bike lane", + "description": "A bike lane separated from auto traffic by a painted line" + }, + "shared_lane": { + "title": "Shared bike lane", + "description": "A bike lane with no separation from auto traffic" + }, + "track": { + "title": "Bike track", + "description": "A bike lane separated from traffic by a physical barrier" + }, + "share_busway": { + "title": "Bike lane shared with bus", + "description": "A bike lane shared with a bus lane" + }, + "opposite_lane": { + "title": "Opposite bike lane", + "description": "A bike lane that travels in the opposite direction of traffic" + }, + "opposite": { + "title": "Contraflow bike lane", + "description": "A bike lane that travels in both directions on a one-way street" + } + } + } + }, "delivery": { "key": "delivery", "type": "check", diff --git a/data/presets/fields/cycleway.json b/data/presets/fields/cycleway.json new file mode 100644 index 000000000..7465f9bee --- /dev/null +++ b/data/presets/fields/cycleway.json @@ -0,0 +1,44 @@ +{ + "keys": ["cycleway", "cycleway:left", "cycleway:right"], + "reference": {"key": "cycleway"}, + "type": "cycleway", + "label": "Bike Lanes", + "placeholder": "lane, shared lane", + "strings": { + "types": { + "cycleway": "Both sides", + "cycleway:left": "Left side", + "cycleway:right": "Right side" + }, + "options": { + "no": { + "title": "None", + "description": "No bike lane" + }, + "lane": { + "title": "Standard bike lane", + "description": "A bike lane separated from auto traffic by a painted line" + }, + "shared_lane": { + "title": "Shared bike lane", + "description": "A bike lane with no separation from auto traffic" + }, + "track": { + "title": "Bike track", + "description": "A bike lane separated from traffic by a physical barrier" + }, + "share_busway": { + "title": "Bike lane shared with bus", + "description": "A bike lane shared with a bus lane" + }, + "opposite_lane": { + "title": "Opposite bike lane", + "description": "A bike lane that travels in the opposite direction of traffic" + }, + "opposite": { + "title": "Contraflow bike lane", + "description": "A bike lane that travels in both directions on a one-way street" + } + } + } +} diff --git a/data/presets/presets.json b/data/presets/presets.json index c13c60590..db8acd9d5 100644 --- a/data/presets/presets.json +++ b/data/presets/presets.json @@ -3937,7 +3937,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -4035,7 +4036,8 @@ "mtb/scale", "mtb/scale/uphill", "mtb/scale/imba", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4080,7 +4082,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4099,7 +4102,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4146,7 +4150,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -4198,7 +4203,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4217,7 +4223,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4240,7 +4247,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -4410,7 +4418,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4429,7 +4438,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -4456,7 +4466,8 @@ "smoothness", "mtb/scale", "mtb/scale/uphill", - "mtb/scale/imba" + "mtb/scale/imba", + "cycleway" ], "geometry": [ "line" @@ -4547,7 +4558,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/living_street.json b/data/presets/presets/highway/living_street.json index ac0202587..8a9b70aec 100644 --- a/data/presets/presets/highway/living_street.json +++ b/data/presets/presets/highway/living_street.json @@ -5,7 +5,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/path.json b/data/presets/presets/highway/path.json index a38306333..78ceeab0d 100644 --- a/data/presets/presets/highway/path.json +++ b/data/presets/presets/highway/path.json @@ -11,7 +11,8 @@ "mtb/scale", "mtb/scale/uphill", "mtb/scale/imba", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/primary.json b/data/presets/presets/highway/primary.json index e09c87433..a9d54ac8c 100644 --- a/data/presets/presets/highway/primary.json +++ b/data/presets/presets/highway/primary.json @@ -7,7 +7,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -17,4 +18,4 @@ }, "terms": [], "name": "Primary Road" -} \ No newline at end of file +} diff --git a/data/presets/presets/highway/primary_link.json b/data/presets/presets/highway/primary_link.json index aeb87dd2c..3972c3aea 100644 --- a/data/presets/presets/highway/primary_link.json +++ b/data/presets/presets/highway/primary_link.json @@ -6,7 +6,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/residential.json b/data/presets/presets/highway/residential.json index bca93dba5..f17d5e565 100644 --- a/data/presets/presets/highway/residential.json +++ b/data/presets/presets/highway/residential.json @@ -5,7 +5,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -15,4 +16,4 @@ }, "terms": [], "name": "Residential Road" -} \ No newline at end of file +} diff --git a/data/presets/presets/highway/secondary.json b/data/presets/presets/highway/secondary.json index ed698a66f..244e3aaf9 100644 --- a/data/presets/presets/highway/secondary.json +++ b/data/presets/presets/highway/secondary.json @@ -7,7 +7,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -17,4 +18,4 @@ }, "terms": [], "name": "Secondary Road" -} \ No newline at end of file +} diff --git a/data/presets/presets/highway/secondary_link.json b/data/presets/presets/highway/secondary_link.json index ce24d2d3a..d791f3aec 100644 --- a/data/presets/presets/highway/secondary_link.json +++ b/data/presets/presets/highway/secondary_link.json @@ -6,7 +6,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/service.json b/data/presets/presets/highway/service.json index c379d2997..46efb695a 100644 --- a/data/presets/presets/highway/service.json +++ b/data/presets/presets/highway/service.json @@ -6,7 +6,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -16,4 +17,4 @@ }, "terms": [], "name": "Service Road" -} \ No newline at end of file +} diff --git a/data/presets/presets/highway/tertiary.json b/data/presets/presets/highway/tertiary.json index 2cdaa3800..42e4aa43b 100644 --- a/data/presets/presets/highway/tertiary.json +++ b/data/presets/presets/highway/tertiary.json @@ -7,7 +7,8 @@ "access", "lanes", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" @@ -17,4 +18,4 @@ }, "terms": [], "name": "Tertiary Road" -} \ No newline at end of file +} diff --git a/data/presets/presets/highway/tertiary_link.json b/data/presets/presets/highway/tertiary_link.json index 4f2398285..8985e1336 100644 --- a/data/presets/presets/highway/tertiary_link.json +++ b/data/presets/presets/highway/tertiary_link.json @@ -6,7 +6,8 @@ "structure", "access", "surface", - "ref" + "ref", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/track.json b/data/presets/presets/highway/track.json index 951e3c741..1c341b22e 100644 --- a/data/presets/presets/highway/track.json +++ b/data/presets/presets/highway/track.json @@ -10,7 +10,8 @@ "smoothness", "mtb/scale", "mtb/scale/uphill", - "mtb/scale/imba" + "mtb/scale/imba", + "cycleway" ], "geometry": [ "line" diff --git a/data/presets/presets/highway/unclassified.json b/data/presets/presets/highway/unclassified.json index 8b49c9092..9ae82d8ae 100644 --- a/data/presets/presets/highway/unclassified.json +++ b/data/presets/presets/highway/unclassified.json @@ -5,7 +5,8 @@ "maxspeed", "structure", "access", - "surface" + "surface", + "cycleway" ], "geometry": [ "line" @@ -15,4 +16,4 @@ }, "terms": [], "name": "Unclassified Road" -} \ No newline at end of file +} diff --git a/data/presets/schema/field.json b/data/presets/schema/field.json index c51c0cddd..b3733eaa2 100644 --- a/data/presets/schema/field.json +++ b/data/presets/schema/field.json @@ -52,6 +52,7 @@ "address", "check", "combo", + "cycleway", "defaultcheck", "text", "maxspeed", diff --git a/dist/img/line-presets.png b/dist/img/line-presets.png index f27d52017..bc20ef448 100644 Binary files a/dist/img/line-presets.png and b/dist/img/line-presets.png differ diff --git a/dist/img/relation-presets.png b/dist/img/relation-presets.png index 47f1d6e30..ef444fb49 100644 Binary files a/dist/img/relation-presets.png and b/dist/img/relation-presets.png differ diff --git a/dist/locales/en.json b/dist/locales/en.json index d21a16cfb..570d599a9 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -786,6 +786,45 @@ "cuisine": { "label": "Cuisine" }, + "cycleway": { + "label": "Bike Lanes", + "placeholder": "lane, shared lane", + "types": { + "cycleway": "Both sides", + "cycleway:left": "Left side", + "cycleway:right": "Right side" + }, + "options": { + "no": { + "title": "None", + "description": "No bike lane" + }, + "lane": { + "title": "Standard bike lane", + "description": "A bike lane separated from auto traffic by a painted line" + }, + "shared_lane": { + "title": "Shared bike lane", + "description": "A bike lane with no separation from auto traffic" + }, + "track": { + "title": "Bike track", + "description": "A bike lane separated from traffic by a physical barrier" + }, + "share_busway": { + "title": "Bike lane shared with bus", + "description": "A bike lane shared with a bus lane" + }, + "opposite_lane": { + "title": "Opposite bike lane", + "description": "A bike lane that travels in the opposite direction of traffic" + }, + "opposite": { + "title": "Contraflow bike lane", + "description": "A bike lane that travels in both directions on a one-way street" + } + } + }, "delivery": { "label": "Delivery" }, diff --git a/index.html b/index.html index ff5f84d8f..edf3987d9 100644 --- a/index.html +++ b/index.html @@ -127,6 +127,7 @@ + diff --git a/js/id/ui/preset/cycleway.js b/js/id/ui/preset/cycleway.js new file mode 100644 index 000000000..5a5d3f454 --- /dev/null +++ b/js/id/ui/preset/cycleway.js @@ -0,0 +1,86 @@ +iD.ui.preset.cycleway = function(field) { + var event = d3.dispatch('change'), + items; + + function cycleway(selection) { + var wrap = selection.selectAll('.preset-input-wrap') + .data([0]); + + wrap.enter().append('div') + .attr('class', 'cf preset-input-wrap') + .append('ul'); + + items = wrap.select('ul').selectAll('li') + .data(field.keys); + + // Enter + + var enter = items.enter().append('li') + .attr('class', function(d) { return 'cf preset-cycleway-' + d; }); + + enter.append('span') + .attr('class', 'col6 label preset-label-cycleway') + .attr('for', function(d) { return 'preset-input-cycleway-' + d; }) + .text(function(d) { return field.t('types.' + d); }); + + enter.append('div') + .attr('class', 'col6 preset-input-cycleway-wrap') + .append('input') + .attr('type', 'text') + .attr('class', 'preset-input-cycleway') + .attr('id', function(d) { return 'preset-input-cycleway-' + d; }) + .each(function(d) { + d3.select(this) + .call(d3.combobox() + .data(cycleway.options(d))); + }); + + // Update + + wrap.selectAll('.preset-input-cycleway') + .on('change', change) + .on('blur', change); + } + + function change(d) { + var tag = {}; + tag[d] = d3.select(this).value() || undefined; + event.change(tag); + } + + cycleway.options = function() { + var options = ['no', 'lane', 'shared_lane', 'track', 'share_busway', 'opposite_lane', 'opposite']; + + return options.map(function(option) { + return { + title: field.t('options.' + option + '.description'), + value: option + }; + }); + }; + + cycleway.tags = function(tags) { + items.selectAll('.preset-input-cycleway') + .value(function(d) { return tags[d] || ''; }) + .attr('placeholder', function() { + return tags.cycleway ? tags.cycleway : field.placeholder(); + }); + + items.selectAll('#preset-input-cycleway-cycleway') + .attr('placeholder', 'no'); + + // Remove "no" values + _.forEach(tags, function (value, key) { + if (key.indexOf('cycleway') === 0 && value === 'no') { + delete tags[key]; + } + }); + }; + + cycleway.focus = function() { + items.selectAll('.preset-input-cycleway') + .node().focus(); + }; + + return d3.rebind(cycleway, event, 'on'); +};