From 72888060124a8529be71a2c2f1fbbc9cc5288577 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 28 Jul 2015 17:18:16 -0400 Subject: [PATCH] Add styling for ephemeral tags (closes #2740) includes various forms of: 'proposed', 'construction', 'disused', 'abandoned', 'dismantled', 'razed', 'demolished', 'obliterated' --- css/map.css | 18 +++++------ js/id/svg/tag_classes.js | 60 ++++++++++++++++++++++++++++++------ test/spec/svg/tag_classes.js | 39 +++++++++++++++++++++-- 3 files changed, 97 insertions(+), 20 deletions(-) diff --git a/css/map.css b/css/map.css index 7cf427f3a..06e90ef9b 100644 --- a/css/map.css +++ b/css/map.css @@ -347,10 +347,10 @@ path.fill.tag-landuse-landfill { .pattern-color-construction { fill: rgba(196, 189, 25, 0.2); } -path.stroke.tag-landuse-construction { +path.stroke.tag-landuse.tag-ephemeral { stroke: rgb(196, 189, 25); } -.preset-icon-fill-area.tag-landuse-construction { +.preset-icon-fill-area.tag-landuse.tag-ephemeral { border-color: rgb(196, 189, 25); background-color: rgba(196, 189, 25, 0.2); } @@ -939,18 +939,18 @@ path.shadow.tag-cutting { } -/* construction */ +/* Ephemeral */ -path.stroke.tag-highway-construction, -path.casing.tag-highway-construction { +path.stroke.tag-ephemeral, +path.casing.tag-ephemeral { stroke-linecap: butt; - stroke-dasharray: 7, 7; + stroke-dasharray: 7, 3; } -.low-zoom path.stroke.tag-highway-construction, -.low-zoom path.casing.tag-highway-construction { +.low-zoom path.stroke.tag-ephemeral, +.low-zoom path.casing.tag-ephemeral { stroke-linecap: butt; - stroke-dasharray: 5, 5; + stroke-dasharray: 5, 2; } text { diff --git a/js/id/svg/tag_classes.js b/js/id/svg/tag_classes.js index f20928f75..e9c3fcafc 100644 --- a/js/id/svg/tag_classes.js +++ b/js/id/svg/tag_classes.js @@ -1,18 +1,24 @@ iD.svg.TagClasses = function() { - var primary = [ + var primaries = [ 'building', 'highway', 'railway', 'waterway', 'aeroway', 'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse', 'leisure', 'place' ], - secondary = [ - 'oneway', 'bridge', 'tunnel', 'construction', 'embankment', 'cutting', 'barrier' + statuses = [ + 'proposed', 'construction', 'disused', 'abandoned', 'dismantled', + 'razed', 'demolished', 'obliterated' + ], + secondaries = [ + 'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier' ], tagClassRe = /^tag-/, tags = function(entity) { return entity.tags; }; + var tagClasses = function(selection) { selection.each(function tagClassesEach(entity) { - var classes, value = this.className; + var value = this.className, + classes, primary, status; if (value.baseVal !== undefined) value = value.baseVal; @@ -22,16 +28,52 @@ iD.svg.TagClasses = function() { var t = tags(entity), i, k, v; - for (i = 0; i < primary.length; i++) { - k = primary[i]; + // pick at most one primary classification tag.. + for (i = 0; i < primaries.length; i++) { + k = primaries[i]; v = t[k]; if (!v || v === 'no') continue; - classes += ' tag-' + k + ' tag-' + k + '-' + v; + + primary = k; + if (statuses.indexOf(v) !== -1) { // e.g. `railway=abandoned` + status = v; + classes += ' tag-' + k; + } else { + classes += ' tag-' + k + ' tag-' + k + '-' + v; + } + break; } - for (i = 0; i < secondary.length; i++) { - k = secondary[i]; + // add at most one ephemeral status tag, only if relates to primary tag.. + if (!status) { + for (i = 0; i < statuses.length; i++) { + k = statuses[i]; + v = t[k]; + if (!v || v === 'no') continue; + + if (v === 'yes') { // e.g. `railway=rail + abandoned=yes` + status = k; + } + else if (primary && primary === v) { // e.g. `railway=rail + abandoned=railway` + status = k; + } else if (!primary && primaries.indexOf(v) !== -1) { // e.g. `abandoned=railway` + status = k; + primary = v; + classes += ' tag-' + v; + } // else ignore e.g. `highway=path + abandoned=railway` + + if (status) break; + } + } + + if (status) { + classes += ' tag-ephemeral'; + } + + // add any secondary (structure) tags + for (i = 0; i < secondaries.length; i++) { + k = secondaries[i]; v = t[k]; if (!v || v === 'no') continue; classes += ' tag-' + k + ' tag-' + k + '-' + v; diff --git a/test/spec/svg/tag_classes.js b/test/spec/svg/tag_classes.js index eaf8d3885..752a4b094 100644 --- a/test/spec/svg/tag_classes.js +++ b/test/spec/svg/tag_classes.js @@ -21,18 +21,53 @@ describe("iD.svg.TagClasses", function () { it('adds only one primary tag', function() { selection - .datum(iD.Entity({tags: {highway: 'primary', railway: 'abandoned'}})) + .datum(iD.Entity({tags: {highway: 'primary', railway: 'rail'}})) .call(iD.svg.TagClasses()); expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary'); }); it('orders primary tags', function() { selection - .datum(iD.Entity({tags: {railway: 'abandoned', highway: 'primary'}})) + .datum(iD.Entity({tags: {railway: 'rail', highway: 'primary'}})) .call(iD.svg.TagClasses()); expect(selection.attr('class')).to.equal('tag-highway tag-highway-primary'); }); + it('adds ephemeral status tag when status in primary value (`railway=abandoned`)', function() { + selection + .datum(iD.Entity({tags: {railway: 'abandoned'}})) + .call(iD.svg.TagClasses()); + expect(selection.attr('class')).to.equal('tag-railway tag-ephemeral'); + }); + + it('adds ephemeral status tag when status in key and value matches "yes" (railway=rail + abandoned=yes)', function() { + selection + .datum(iD.Entity({tags: {railway: 'rail', abandoned: 'yes'}})) + .call(iD.svg.TagClasses()); + expect(selection.attr('class')).to.equal('tag-railway tag-railway-rail tag-ephemeral'); + }); + + it('adds ephemeral status tag when status in key and value matches primary (railway=rail + abandoned=railway)', function() { + selection + .datum(iD.Entity({tags: {railway: 'rail', abandoned: 'railway'}})) + .call(iD.svg.TagClasses()); + expect(selection.attr('class')).to.equal('tag-railway tag-railway-rail tag-ephemeral'); + }); + + it('adds primary and ephemeral status tag when status in key and no primary (abandoned=railway)', function() { + selection + .datum(iD.Entity({tags: {abandoned: 'railway'}})) + .call(iD.svg.TagClasses()); + expect(selection.attr('class')).to.equal('tag-railway tag-ephemeral'); + }); + + it('does not add ephemeral status tag for different primary tag (highway=path + abandoned=railway)', function() { + selection + .datum(iD.Entity({tags: {highway: 'path', abandoned: 'railway'}})) + .call(iD.svg.TagClasses()); + expect(selection.attr('class')).to.equal('tag-highway tag-highway-path'); + }); + it('adds secondary tags', function() { selection .datum(iD.Entity({tags: {highway: 'primary', bridge: 'yes'}}))