From 24592f8b0ae8c0df26d68493c237012c5a5e1a56 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sat, 6 Aug 2016 16:21:14 +0530 Subject: [PATCH 01/11] add test cases for lanes array --- test/spec/core/way.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/test/spec/core/way.js b/test/spec/core/way.js index e39795743..ba53091a8 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -926,7 +926,7 @@ describe('iD.Way', function() { bothways: 1 }); }); - it('correctly returns the lane:both_ways as 0 or NaN', function() { + it('correctly returns when lane:both_ways is 0 or Not a Number', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().metadata, 'residential lanes') .to.eql({ count: 5, @@ -945,5 +945,39 @@ describe('iD.Way', function() { }); }); }); + + describe.only('lanes array', function() { + it('should have correct number of direction elements', function() { + var lanes = iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().lanes; + var forward = lanes.filter(function(l) { + return l.direction === 'forward'; + }); + var backward = lanes.filter(function(l) { + return l.direction === 'backward'; + }); + var bothways = lanes.filter(function(l) { + return l.direction === 'bothways'; + }); + expect(forward.length).to.eql(2); + expect(backward.length).to.eql(3); + expect(bothways.length).to.eql(0); + + }); + it('should have corrent number of direction elements', function() { + var lanes = iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().lanes; + var forward = lanes.filter(function(l) { + return l.direction === 'forward'; + }); + var backward = lanes.filter(function(l) { + return l.direction === 'backward'; + }); + var bothways = lanes.filter(function(l) { + return l.direction === 'bothways'; + }); + expect(forward.length).to.eql(3); + expect(backward.length).to.eql(1); + expect(bothways.length).to.eql(1); + }); + }); }); }); From 94b40cdfd01c4108223455b0c9188715a184cca8 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Tue, 9 Aug 2016 00:53:33 +0530 Subject: [PATCH 02/11] add turn lanes --- modules/core/way.js | 62 ++++++- test/spec/core/way.js | 403 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 427 insertions(+), 38 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 562acc5ee..880b6a7ca 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -110,7 +110,6 @@ _.extend(Way.prototype, { direction: direction }; } - var lanesArray = []; for (var i = 0; i < metadata.forward; i++) { lanesArray.push(createLaneItem(i, 'forward')); } @@ -123,6 +122,21 @@ _.extend(Way.prototype, { return lanesArray; } + function getTurns(str, count) { + var array = str.split('|') + .filter(function(s, i) { + return i < count; + }) + .map(function(s) { + if (s === '') s = 'none'; + return s.split(';'); + }); + while (array.length < count) { + array.push(['none']); + } + return array; + } + function safeValue(n) { if (n < 0) return 0; if (n > metadata.count - metadata.bothways) @@ -133,6 +147,7 @@ _.extend(Way.prototype, { if (!this.tags.highway) return null; var metadata = {}; + var lanesArray = []; // fill metadata.count with default count switch (this.tags.highway) { @@ -147,8 +162,13 @@ _.extend(Way.prototype, { if (this.tags.lanes) metadata.count = parseInt(this.tags.lanes); + for (var i = 0; i < metadata.count; i++) { + lanesArray.push({ index: i}); + } + metadata.oneway = this.isOneWay(); + // fill metadata with safe forward, backward, bothways values. if (parseInt(this.tags.oneway) === -1) { metadata.forward = 0; metadata.bothways = 0; @@ -158,19 +178,20 @@ _.extend(Way.prototype, { metadata.forward = metadata.count; metadata.bothways = 0; metadata.backward = 0; - } else { + } + else { + // bothways is forced to always be either 1 or 0. metadata.bothways = parseInt(this.tags['lanes:both_ways']) > 0 ? 1 : 0; metadata.forward = parseInt(this.tags['lanes:forward']); metadata.backward = parseInt(this.tags['lanes:backward']); if (_.isNaN(metadata.forward) && _.isNaN(metadata.backward)) { - metadata.forward = parseInt((metadata.count - metadata.bothways) / 2); - metadata.backward = metadata.count - metadata.bothways - metadata.forward; + metadata.backward = parseInt((metadata.count - metadata.bothways) / 2); + metadata.forward = metadata.count - metadata.bothways - metadata.backward; } else if (_.isNaN(metadata.forward)) { metadata.backward = safeValue(metadata.backward); metadata.forward = metadata.count - metadata.bothways - metadata.backward; - } else if (_.isNaN(metadata.backward)) { metadata.forward = safeValue(metadata.forward); @@ -178,9 +199,38 @@ _.extend(Way.prototype, { } } + for (i = 0; i < metadata.count; i++) { + if (i < metadata.forward) + lanesArray[i].direction = 'forward'; + else if (i < metadata.forward + metadata.bothways) + lanesArray[i].direction = 'bothways'; + else + lanesArray[i].direction = 'backward'; + } + + // parse turn:lanes:forward/backward first + if (!metadata.oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { + metadata.turnLanesForward = getTurns(this.tags['turn:lanes:forward'], metadata.forward); + metadata.turnLanesBackward = getTurns(this.tags['turn:lanes:backward'], metadata.backward); + + // set turnLane for each lanesArray item, except for bothways. + metadata.turnLanesForward.forEach(function(l, i) { + lanesArray[i].turnLane = l; + }); + metadata.turnLanesBackward.forEach(function(l, i) { + lanesArray[i + metadata.forward + metadata.bothways].turnLane = l; + }); + } + else if (this.tags['turn:lanes']) { + metadata.turnLanes = getTurns(this.tags['turn:lanes'], metadata.count); + metadata.turnLanes.forEach(function(l, i) { + lanesArray[i].turnLane = l; + }); + } + return { metadata: metadata, - lanes: makeLanesArray(metadata) + lanes: lanesArray }; }, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index ba53091a8..73edbf607 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -756,7 +756,7 @@ describe('iD.Way', function() { }); describe('oneway tags', function() { - it('correctly returns oneway when tagged as oneway', function() { + it('returns correctlys oneway when tagged as oneway', function() { expect(iD.Way({tags: { highway: 'residential', oneway: 'yes' }}).lanes().metadata.oneway, 'residential lanes') .to.be.true; expect(iD.Way({tags: { highway: 'residential', oneway: 'no' }}).lanes().metadata.oneway, 'residential lanes') @@ -765,9 +765,9 @@ describe('iD.Way', function() { }); describe('lane direction', function() { - it('correctly returns the lane:forward and lane:backward count', function() { + it('returns correctlys the lane:forward and lane:backward count', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 2, oneway: false, forward: 1, @@ -775,7 +775,7 @@ describe('iD.Way', function() { bothways: 0 }); expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:forward': 3, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 4, oneway: false, forward: 3, @@ -783,9 +783,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns count under total count if erroneous values are supplied', function() { + it('returns correctlys count under total count if erroneous values are supplied', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, 'lanes:forward': 3 }}).lanes().metadata, 'trunk lanes') - .to.eql({ + .to.include({ count: 2, oneway: false, forward: 2, @@ -793,9 +793,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns forward count when oneway=yes', function() { + it('returns correctlys forward count when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes' }}).lanes().metadata, 'trunk lanes') - .to.eql({ + .to.include({ count: 2, oneway: true, forward: 2, @@ -803,9 +803,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns backward count the when oneway=-1', function() { + it('returns correctlys backward count the when oneway=-1', function() { expect(iD.Way({tags: { highway: 'primary', lanes: 4, oneway: '-1' }}).lanes().metadata, 'primary lanes') - .to.eql({ + .to.include({ count: 4, oneway: true, backward: 4, @@ -815,7 +815,7 @@ describe('iD.Way', function() { }); it('skips provided lanes:forward value when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes', 'lanes:forward': 1 }}).lanes().metadata, 'trunk lanes') - .to.eql({ + .to.include({ count: 2, oneway: true, forward: 2, @@ -825,7 +825,7 @@ describe('iD.Way', function() { }); it('skips provided lanes:backward value when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes', 'lanes:backward': 1 }}).lanes().metadata, 'trunk lanes') - .to.eql({ + .to.include({ count: 2, oneway: true, forward: 2, @@ -833,9 +833,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns forward count if only backward is supplied', function() { + it('returns correctlys forward count if only backward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 3, oneway: false, forward: 2, @@ -843,7 +843,7 @@ describe('iD.Way', function() { bothways: 0 }); expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:backward': 3, }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 4, oneway: false, forward: 1, @@ -851,9 +851,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns backward count if only forward is supplied', function() { + it('returns correctlys backward count if only forward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 3, oneway: false, forward: 1, @@ -861,7 +861,7 @@ describe('iD.Way', function() { bothways: 0 }); expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 2, oneway: false, forward: 1, @@ -869,9 +869,9 @@ describe('iD.Way', function() { bothways: 0 }); }); - it('correctly returns backward count if forward and both_ways are supplied', function() { + it('returns correctlys backward count if forward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 3, oneway: false, forward: 1, @@ -879,7 +879,7 @@ describe('iD.Way', function() { bothways: 1 }); expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 5, oneway: false, forward: 1, @@ -887,9 +887,9 @@ describe('iD.Way', function() { bothways: 1 }); }); - it('correctly returns forward count if backward and both_ways are supplied', function() { + it('returns correctlys forward count if backward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 3, oneway: false, forward: 1, @@ -897,7 +897,7 @@ describe('iD.Way', function() { bothways: 1 }); expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 5, oneway: false, forward: 3, @@ -906,9 +906,9 @@ describe('iD.Way', function() { }); }); - it('correctly returns the lane:both_ways count as 1', function() { + it('returns correctlys the lane:both_ways count as 1', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 2, oneway: false, forward: 1, @@ -916,9 +916,9 @@ describe('iD.Way', function() { bothways: 1 }); }); - it('correctly returns when lane:both_ways>1', function() { + it('returns correctlys when lane:both_ways>1', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 2, 'lanes:backward': 2 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 5, oneway: false, forward: 2, @@ -926,9 +926,9 @@ describe('iD.Way', function() { bothways: 1 }); }); - it('correctly returns when lane:both_ways is 0 or Not a Number', function() { + it('returns correctlys when lane:both_ways is 0 or Not a Number', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 5, oneway: false, forward: 2, @@ -936,7 +936,7 @@ describe('iD.Way', function() { bothways: 0 }); expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 'none' }}).lanes().metadata, 'residential lanes') - .to.eql({ + .to.include({ count: 2, oneway: false, forward: 1, @@ -946,7 +946,7 @@ describe('iD.Way', function() { }); }); - describe.only('lanes array', function() { + describe('lanes array', function() { it('should have correct number of direction elements', function() { var lanes = iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().lanes; var forward = lanes.filter(function(l) { @@ -979,5 +979,344 @@ describe('iD.Way', function() { expect(bothways.length).to.eql(1); }); }); + + describe.only('turn lanes', function() { + it('returns correctly when oneway=yes', function() { + var metadata = iD.Way({ + tags: { + highway: 'trunk', + oneway: 'yes', + 'turn:lanes': 'none|slight_right' + } + }).lanes().metadata; + expect(metadata.turnLanes) + .to.deep.equal([ + ['none'], ['slight_right'] + ]); + }); + + it('returns correctly when oneway=yes and lanes=2', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + oneway: 'yes', + lanes: '2', + 'turn:lanes': 'none|slight_right' + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([ + ['none'], ['slight_right'] + ]); + }); + + it('returns correctly when lanes=5 and both_ways=1', function() { + var metadata = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'lanes:forward': 1, + 'lanes:both_ways': 1, + 'turn:lanes:forward': 'slight_left', + 'turn:lanes:backward': 'none|through|through;slight_right', + } + }).lanes().metadata; + expect(metadata.turnLanesForward) + .to.deep.equal([ + ['slight_left'] + ]); + expect(metadata.turnLanesBackward) + .to.deep.equal([ + ['none'], ['through'], ['through', 'slight_right'] + ]); + }); + + it('returns correctly when multiple values are present in a lane and oneway=yes', function() { + var lanesData = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'yes', + 'turn:lanes': 'slight_left;reverse;left|slight_left;left;through|through|none|through;right', + } + }).lanes(); + + expect(lanesData.metadata.turnLanes) + .to.deep.equal([ + ['slight_left', 'reverse', 'left'], + ['slight_left', 'left', 'through'], + ['through'], + ['none'], + ['through', 'right'] + ]); + + expect(lanesData.lanes.map(function(l) { return l.turnLane; })) + .to.deep.equal([ + ['slight_left', 'reverse', 'left'], + ['slight_left', 'left', 'through'], + ['through'], + ['none'], + ['through', 'right'] + ]); + }); + + it('returns correctly when multiple values are present in a lane and oneway=no', function() { + var lanesData = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 3, + 'lanes:backward': 2, + 'turn:lanes:forward': 'slight_left;reverse;left|slight_left;left;through|through', + 'turn:lanes:backward': 'none|through;left' + } + }).lanes(); + expect(lanesData.metadata.turnLanesForward) + .to.deep.equal([ + ['slight_left', 'reverse', 'left'], + ['slight_left', 'left', 'through'], + ['through'] + ]); + expect(lanesData.metadata.turnLanesBackward) + .to.deep.equal([ + ['none'], + ['through', 'left'] + ]); + expect(lanesData.lanes.map(function(l) { return l.turnLane; })) + .to.deep.equal([ + ['slight_left', 'reverse', 'left'], + ['slight_left', 'left', 'through'], + ['through'], + ['none'], + ['through', 'left'] + ]); + }); + + it('fills with [\'none\'] when given turn:lanes are less than lanes count', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'yes', + 'turn:lanes': 'slight_left', + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([ + ['slight_left'], ['none'], ['none'], ['none'], ['none'] + ]); + }); + + it('fills with [\'none\'] when given turn:lanes:forward are less than lanes forward count', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 3, + 'turn:lanes:forward': 'slight_left', + 'turn:lanes:backward': 'through', + } + }).lanes().metadata; + + expect(metadata.turnLanesForward) + .to.deep.equal([ + ['slight_left'], ['none'], ['none'] + ]); + expect(metadata.turnLanesBackward) + .to.deep.equal([ + ['through'], ['none'] + ]); + }); + + it('clips when turn lane information is more than lane count', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 2, + oneway: 'yes', + 'turn:lanes': 'through|through;slight_right|slight_right', + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([ + ['through'], ['through', 'slight_right'] + ]); + }); + + it('turnLanes is undefined when not present', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 2, + oneway: 'yes' + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.equal(undefined); + expect(metadata.turnLanesForward) + .to.equal(undefined); + expect(metadata.turnLanesBackward) + .to.equal(undefined); + }); + + it('turnLanesForward and turnLanesBackward are both undefined when both are not provided', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 2, + oneway: 'yes', + 'turn:lanes': 'through|through;slight_right', + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([['through'], ['through', 'slight_right']]); + expect(metadata.turnLanesForward) + .to.equal(undefined); + expect(metadata.turnLanesBackward) + .to.equal(undefined); + }); + + it('turnLanesForward and turnLanesBackward are both undefined when either is provided', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 2, + 'turn:lanes:backward': 'none', + } + }).lanes().metadata; + + expect(metadata.turnLanesForward) + .to.equal(undefined); + expect(metadata.turnLanesBackward) + .to.equal(undefined); + }); + + it('turnLanesForward and turnLanesBackward are both undefined when oneway="yes"', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 2, + oneway: 'yes', + 'turn:lanes:forward': 'through', + 'turn:lanes:backward': 'none' + } + }).lanes().metadata; + + expect(metadata.turnLanesForward) + .to.equal(undefined); + expect(metadata.turnLanesBackward) + .to.equal(undefined); + }); + + it('parses correctly when turn:lanes= ||x', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 3, + oneway: 'yes', + 'turn:lanes': '||through;slight_right', + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]); + }); + + it('parses correctly when turn:lanes= |x|', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + 'turn:lanes': '|through|', + } + }).lanes().metadata; + + expect(metadata.turnLanes) + .to.deep.equal([['none'], ['through'], ['none'], ['none'], ['none']]); + }); + + it('parses correctly when turn:lanes:forward= ||x', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 4, + oneway: 'no', + 'lanes:forward': 3, + 'lanes:backward': 1, + 'turn:lanes:forward': '||through;slight_right', + 'turn:lanes:backward': 'none', + } + }).lanes().metadata; + + expect(metadata.turnLanesForward) + .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]); + expect(metadata.turnLanesBackward) + .to.deep.equal([['none']]); + }); + + it('parses correctly when turn:lanes:backward= |', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 3, + 'lanes:backward': 2, + 'turn:lanes:backward': '|', + 'turn:lanes:forward': 'slight_left||', + } + }).lanes().metadata; + + expect(metadata.turnLanesForward) + .to.deep.equal([['slight_left'], ['none'], ['none']]); + expect(metadata.turnLanesBackward) + .to.deep.equal([['none'], ['none']]); + }); + + it('fills turnLane correctly in lanes', function() { + var lanes = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + 'lanes:forward': 3, + 'lanes:backward': 2, + 'turn:lanes:backward': 'none|slight_right', + 'turn:lanes:forward': 'slight_left||', + } + }).lanes().lanes; + + var turnLanes = lanes.map(function(l) { return l.turnLane; }); + expect(turnLanes).to.deep.equal([ + ['slight_left'], ['none'], ['none'], ['none'], ['slight_right'] + ]); + }); + + it('fills turnLane correctly in lanes when lanes:both_ways=1', function() { + var lanes = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 3, + 'lanes:both_ways': 1, + 'lanes:backward': 1, + 'turn:lanes:backward': 'slight_right', + 'turn:lanes:forward': 'slight_left||', + } + }).lanes().lanes; + + var turnLanes = lanes.map(function(l) { return l.turnLane; }); + expect(turnLanes).to.deep.equal([ + ['slight_left'], ['none'], ['none'], undefined, ['slight_right'] + ]); + }); + }); }); }); From 9a1c68f2b5bf3681286c0403253f096d1b57137c Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Tue, 16 Aug 2016 19:01:54 +0530 Subject: [PATCH 03/11] interim --- modules/core/way.js | 140 ++++++++++++++++++++++++------------------ test/spec/core/way.js | 64 +++++++++++++------ 2 files changed, 125 insertions(+), 79 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 880b6a7ca..68ad5abd4 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -110,122 +110,144 @@ _.extend(Way.prototype, { direction: direction }; } - for (var i = 0; i < metadata.forward; i++) { + for (var i = 0; i < forward; i++) { lanesArray.push(createLaneItem(i, 'forward')); } - for (i = 0; i < metadata.bothways; i++) { - lanesArray.push(createLaneItem(metadata.forward + i, 'bothways')); + for (i = 0; i < bothways; i++) { + lanesArray.push(createLaneItem(forward + i, 'bothways')); } - for (i = 0; i < metadata.backward; i++) { - lanesArray.push(createLaneItem(metadata.forward + metadata.bothways + i, 'backward')); + for (i = 0; i < backward; i++) { + lanesArray.push(createLaneItem(forward + bothways + i, 'backward')); } return lanesArray; } - function getTurns(str, count) { + function parseString(str, n) { var array = str.split('|') .filter(function(s, i) { - return i < count; + return i < n; }) .map(function(s) { if (s === '') s = 'none'; return s.split(';'); }); - while (array.length < count) { + while (array.length < n) { array.push(['none']); } return array; } + // smartly fills the undefined array.key elements with values + function smartFill(array, key, values) { + if (!array) return; + // keeps track of elements filled with 'value' + var counter = 0; + array.forEach(function(o) { + if (!o || counter === values.length) return; + + if (o[key] === undefined) { + o[key] = values[counter]; + counter++; + } + }); + } + function safeValue(n) { if (n < 0) return 0; - if (n > metadata.count - metadata.bothways) - return metadata.count - metadata.bothways; + if (n > count - bothways) + return count - bothways; return n; } if (!this.tags.highway) return null; - var metadata = {}; + var laneCount, forward, bothways, backward; var lanesArray = []; + var oneway = this.isOneWay(); - // fill metadata.count with default count + // fill laneCount with defaults switch (this.tags.highway) { case 'trunk': case 'motorway': - metadata.count = this.isOneWay() ? 2 : 4; + laneCount = oneway ? 2 : 4; break; default: - metadata.count = this.isOneWay() ? 1 : 2; + laneCount = oneway ? 1 : 2; break; } - if (this.tags.lanes) metadata.count = parseInt(this.tags.lanes); + if (this.tags.lanes) laneCount = parseInt(this.tags.lanes); - for (var i = 0; i < metadata.count; i++) { + for (var i = 0; i < laneCount; i++) { lanesArray.push({ index: i}); } - metadata.oneway = this.isOneWay(); - // fill metadata with safe forward, backward, bothways values. if (parseInt(this.tags.oneway) === -1) { - metadata.forward = 0; - metadata.bothways = 0; - metadata.backward = metadata.count; + forward = 0; + bothways = 0; + backward = laneCount; } - else if (metadata.oneway) { - metadata.forward = metadata.count; - metadata.bothways = 0; - metadata.backward = 0; + else if (oneway) { + forward = laneCount; + bothways = 0; + backward = 0; } else { // bothways is forced to always be either 1 or 0. - metadata.bothways = parseInt(this.tags['lanes:both_ways']) > 0 ? 1 : 0; - metadata.forward = parseInt(this.tags['lanes:forward']); - metadata.backward = parseInt(this.tags['lanes:backward']); + bothways = parseInt(this.tags['lanes:both_ways']) > 0 ? 1 : 0; + forward = parseInt(this.tags['lanes:forward']); + backward = parseInt(this.tags['lanes:backward']); - if (_.isNaN(metadata.forward) && _.isNaN(metadata.backward)) { - metadata.backward = parseInt((metadata.count - metadata.bothways) / 2); - metadata.forward = metadata.count - metadata.bothways - metadata.backward; + if (_.isNaN(forward) && _.isNaN(backward)) { + backward = parseInt((laneCount - bothways) / 2); + forward = laneCount - bothways - backward; } - else if (_.isNaN(metadata.forward)) { - metadata.backward = safeValue(metadata.backward); - metadata.forward = metadata.count - metadata.bothways - metadata.backward; + else if (_.isNaN(forward)) { + backward = safeValue(backward); + forward = laneCount - bothways - backward; } - else if (_.isNaN(metadata.backward)) { - metadata.forward = safeValue(metadata.forward); - metadata.backward = metadata.count - metadata.bothways - metadata.forward; + else if (_.isNaN(backward)) { + forward = safeValue(forward); + backward = laneCount - bothways - forward; } } - for (i = 0; i < metadata.count; i++) { - if (i < metadata.forward) - lanesArray[i].direction = 'forward'; - else if (i < metadata.forward + metadata.bothways) - lanesArray[i].direction = 'bothways'; - else - lanesArray[i].direction = 'backward'; - } + // fill each undefined lanesArray's direction element with 'forward/bothwats/backward'. + smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); + smartFill(lanesArray, 'direction', _.fill(Array(bothways), 'bothways')); + smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); // parse turn:lanes:forward/backward first - if (!metadata.oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { - metadata.turnLanesForward = getTurns(this.tags['turn:lanes:forward'], metadata.forward); - metadata.turnLanesBackward = getTurns(this.tags['turn:lanes:backward'], metadata.backward); + var turnLanes, turnLanesForward, turnLanesBackward; - // set turnLane for each lanesArray item, except for bothways. - metadata.turnLanesForward.forEach(function(l, i) { - lanesArray[i].turnLane = l; - }); - metadata.turnLanesBackward.forEach(function(l, i) { - lanesArray[i + metadata.forward + metadata.bothways].turnLane = l; - }); + if (!oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { + turnLanesForward = parseString(this.tags['turn:lanes:forward'], forward); + turnLanesBackward = parseString(this.tags['turn:lanes:backward'], backward); + + smartFill(lanesArray, 'turnLane', turnLanesForward); + // if both_ways fill it with null + smartFill(lanesArray, 'turnLane', _.fill(Array(bothways), null)); + smartFill(lanesArray, 'turnLane', turnLanesBackward); } else if (this.tags['turn:lanes']) { - metadata.turnLanes = getTurns(this.tags['turn:lanes'], metadata.count); - metadata.turnLanes.forEach(function(l, i) { - lanesArray[i].turnLane = l; - }); + turnLanes = parseString(this.tags['turn:lanes'], laneCount); + smartFill(lanesArray, 'turnLane', turnLanes); + } + + // parse max speed + var maxspeed, maxspeedForward, maxspeedBackward; + if (!oneway && this.tags['maxspeed:lanes:forward'] && this.tags['maxspeed:lanes:backward']) { + maxspeedForward = parseString(this.tags['maxspeed:lanes:forward'], forward); + maxspeedBackward = parseString(this.tags['maxspeed:lanes:backward'], backward); + + smartFill(lanesArray, 'maxspeed', maxspeedForward); + smartFill(lanesArray, 'maxspeed', _.fill(Array(bothways), null)); + smartFill(lanesArray, 'maxspeed', maxspeedBackward); + } + else if (this.tags['maxspeed:lanes']) { + maxspeed = parseString(this.tags['maxspeed:lanes'], forward); + smartFill(lanesArray, 'maxspeed', maxspeed); } return { diff --git a/test/spec/core/way.js b/test/spec/core/way.js index 73edbf607..800101428 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -980,7 +980,7 @@ describe('iD.Way', function() { }); }); - describe.only('turn lanes', function() { + describe('turn lanes', function() { it('returns correctly when oneway=yes', function() { var metadata = iD.Way({ tags: { @@ -1215,6 +1215,49 @@ describe('iD.Way', function() { .to.equal(undefined); }); + it('parses turnLane correctly when lanes:both_ways=1', function() { + var lanes = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 3, + 'lanes:both_ways': 1, + 'lanes:backward': 1, + 'turn:lanes:backward': 'slight_right', + 'turn:lanes:forward': 'slight_left||', + } + }).lanes().lanes; + var turnLanes = lanes.map(function(l) { return l.turnLane; }); + expect(turnLanes).to.deep.equal([ + ['slight_left'], ['none'], ['none'], null, ['slight_right'] + ]); + + }); + + it('parses turnLane correctly when lanes:both_ways=1 & lanes:forward < lanes:backward', function() { + var lanes = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'no', + 'lanes:forward': 1, + 'lanes:both_ways': 1, + 'lanes:backward': 3, + 'turn:lanes:forward': 'through', + 'turn:lanes:backward': 'slight_left||', + } + }).lanes().lanes; + + var turnLanes = lanes.map(function(l) { return l.turnLane; }); + expect(turnLanes).to.deep.equal([ + ['through'], null, ['slight_left'], ['none'], ['none'] + ]); + + }); + + + it('parses correctly when turn:lanes= ||x', function() { var metadata = iD.Way({ tags: { @@ -1298,25 +1341,6 @@ describe('iD.Way', function() { ]); }); - it('fills turnLane correctly in lanes when lanes:both_ways=1', function() { - var lanes = iD.Way({ - tags: { - highway: 'tertiary', - lanes: 5, - oneway: 'no', - 'lanes:forward': 3, - 'lanes:both_ways': 1, - 'lanes:backward': 1, - 'turn:lanes:backward': 'slight_right', - 'turn:lanes:forward': 'slight_left||', - } - }).lanes().lanes; - - var turnLanes = lanes.map(function(l) { return l.turnLane; }); - expect(turnLanes).to.deep.equal([ - ['slight_left'], ['none'], ['none'], undefined, ['slight_right'] - ]); - }); }); }); }); From 51c0670a5782ed5b55e047e203760acc2e9c078d Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Fri, 19 Aug 2016 03:22:34 +0530 Subject: [PATCH 04/11] add maxspeed --- modules/core/way.js | 199 +++++++++++++++++++++++++----------------- test/spec/core/way.js | 49 ++++------- 2 files changed, 134 insertions(+), 114 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 68ad5abd4..d9d1400fa 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -103,26 +103,11 @@ _.extend(Way.prototype, { lanes: function() { - function makeLanesArray(metadata) { - function createLaneItem(index, direction) { - return { - index: index, - direction: direction - }; - } - for (var i = 0; i < forward; i++) { - lanesArray.push(createLaneItem(i, 'forward')); - } - for (i = 0; i < bothways; i++) { - lanesArray.push(createLaneItem(forward + i, 'bothways')); - } - for (i = 0; i < backward; i++) { - lanesArray.push(createLaneItem(forward + bothways + i, 'backward')); - } - return lanesArray; - } + function parsePipeString(key, n) { + var str = tags[key]; + + if (!str) return; - function parseString(str, n) { var array = str.split('|') .filter(function(s, i) { return i < n; @@ -137,6 +122,73 @@ _.extend(Way.prototype, { return array; } + function parseTurnLanes(key, n){ + var validValues = [ + 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', + 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none' + ]; + var parsedArray = parsePipeString(key, n); + if (!parsedArray) return; + + return parsedArray.map(function(l) { + return l.map(function(i) { + return validValues.indexOf(i) === -1 ? 'unknown': i; + }); + }); + } + + function parseMaxspeed(key, n) { + var str = tags[key]; + if (!str) return; + return str.split('|') + .filter(function(s, i) { + return i < n; + }) + .map(function(s) { + if (s === '') return 'none'; + var m = parseInt(s); + return _.isNaN(m) ? 'unknown': m; + }); + } + + function parseLaneDirections() { + var forward = parseInt(tags['lanes:forward']); + var backward = parseInt(tags['lanes:backward']); + var bothways = parseInt(tags['lanes:both_ways']) > 0 ? 1 : 0; + + if (parseInt(tags.oneway) === -1) { + forward = 0; + bothways = 0; + backward = laneCount; + } + else if (oneway) { + forward = laneCount; + bothways = 0; + backward = 0; + } + else if (_.isNaN(forward) && _.isNaN(backward)) { + backward = parseInt((laneCount - bothways) / 2); + forward = laneCount - bothways - backward; + } + else if (_.isNaN(forward)) { + if (backward > laneCount - bothways) { + backward = laneCount - bothways; + } + forward = laneCount - bothways - backward; + } + else if (_.isNaN(backward)) { + if (forward > laneCount - bothways) { + forward = laneCount - bothways; + } + backward = laneCount - bothways - forward; + } + return { + forward: forward, + backward: backward, + bothways: bothways + }; + } + // smartly fills the undefined array.key elements with values function smartFill(array, key, values) { if (!array) return; @@ -152,66 +204,47 @@ _.extend(Way.prototype, { }); } - function safeValue(n) { - if (n < 0) return 0; - if (n > count - bothways) - return count - bothways; - return n; + function getLaneCount() { + var count; + // fill laneCount with defaults + switch (tags.highway) { + case 'trunk': + case 'motorway': + count = oneway ? 2 : 4; + break; + default: + count = oneway ? 1 : 2; + break; + } + + if (tags.lanes) count = parseInt(tags.lanes); + return count; } if (!this.tags.highway) return null; - var laneCount, forward, bothways, backward; - var lanesArray = []; + var tags = this.tags; var oneway = this.isOneWay(); + var laneCount = getLaneCount(); - // fill laneCount with defaults - switch (this.tags.highway) { - case 'trunk': - case 'motorway': - laneCount = oneway ? 2 : 4; - break; - default: - laneCount = oneway ? 1 : 2; - break; - } - - if (this.tags.lanes) laneCount = parseInt(this.tags.lanes); - + var lanesArray = []; for (var i = 0; i < laneCount; i++) { lanesArray.push({ index: i}); } - // fill metadata with safe forward, backward, bothways values. - if (parseInt(this.tags.oneway) === -1) { - forward = 0; - bothways = 0; - backward = laneCount; - } - else if (oneway) { - forward = laneCount; - bothways = 0; - backward = 0; - } - else { - // bothways is forced to always be either 1 or 0. - bothways = parseInt(this.tags['lanes:both_ways']) > 0 ? 1 : 0; - forward = parseInt(this.tags['lanes:forward']); - backward = parseInt(this.tags['lanes:backward']); + var laneDirections = parseLaneDirections(); + var forward = laneDirections.forward; + var backward = laneDirections.backward; + var bothways = laneDirections.bothways; - if (_.isNaN(forward) && _.isNaN(backward)) { - backward = parseInt((laneCount - bothways) / 2); - forward = laneCount - bothways - backward; - } - else if (_.isNaN(forward)) { - backward = safeValue(backward); - forward = laneCount - bothways - backward; - } - else if (_.isNaN(backward)) { - forward = safeValue(forward); - backward = laneCount - bothways - forward; - } - } + // parse the piped string 'x|y|z' format + var turnLanes = parseTurnLanes('turn:lanes', laneCount); + var turnLanesForward = parseTurnLanes('turn:lanes:forward', forward); + var turnLanesBackward = parseTurnLanes('turn:lanes:backward', backward); + + var maxspeedLanes = parseMaxspeed('maxspeed:lanes', laneCount); + var maxspeedLanesForward = parseMaxspeed('maxspeed:lanes:forward', forward); + var maxspeedLanesBackward = parseMaxspeed('maxspeed:lanes:backward', backward); // fill each undefined lanesArray's direction element with 'forward/bothwats/backward'. smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); @@ -219,39 +252,41 @@ _.extend(Way.prototype, { smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); // parse turn:lanes:forward/backward first - var turnLanes, turnLanesForward, turnLanesBackward; if (!oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { - turnLanesForward = parseString(this.tags['turn:lanes:forward'], forward); - turnLanesBackward = parseString(this.tags['turn:lanes:backward'], backward); - smartFill(lanesArray, 'turnLane', turnLanesForward); // if both_ways fill it with null smartFill(lanesArray, 'turnLane', _.fill(Array(bothways), null)); smartFill(lanesArray, 'turnLane', turnLanesBackward); } else if (this.tags['turn:lanes']) { - turnLanes = parseString(this.tags['turn:lanes'], laneCount); smartFill(lanesArray, 'turnLane', turnLanes); } // parse max speed - var maxspeed, maxspeedForward, maxspeedBackward; if (!oneway && this.tags['maxspeed:lanes:forward'] && this.tags['maxspeed:lanes:backward']) { - maxspeedForward = parseString(this.tags['maxspeed:lanes:forward'], forward); - maxspeedBackward = parseString(this.tags['maxspeed:lanes:backward'], backward); - - smartFill(lanesArray, 'maxspeed', maxspeedForward); + smartFill(lanesArray, 'maxspeed', maxspeedLanesForward); smartFill(lanesArray, 'maxspeed', _.fill(Array(bothways), null)); - smartFill(lanesArray, 'maxspeed', maxspeedBackward); + smartFill(lanesArray, 'maxspeed', maxspeedLanesBackward); } else if (this.tags['maxspeed:lanes']) { - maxspeed = parseString(this.tags['maxspeed:lanes'], forward); - smartFill(lanesArray, 'maxspeed', maxspeed); + smartFill(lanesArray, 'maxspeed', maxspeedLanes); } return { - metadata: metadata, + metadata: { + count: laneCount, + oneway: oneway, + forward: forward, + backward: backward, + bothways: bothways, + turnLanes: turnLanes, + turnLanesForward: turnLanesForward, + turnLanesBackward: turnLanesBackward, + maxspeedLanes: maxspeedLanes, + maxspeedLanesForward: maxspeedLanesForward, + maxspeedLanesBackward: maxspeedLanesBackward, + }, lanes: lanesArray }; }, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index 800101428..536ad9568 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -1183,38 +1183,6 @@ describe('iD.Way', function() { .to.equal(undefined); }); - it('turnLanesForward and turnLanesBackward are both undefined when either is provided', function() { - var metadata = iD.Way({ - tags: { - highway: 'tertiary', - lanes: 2, - 'turn:lanes:backward': 'none', - } - }).lanes().metadata; - - expect(metadata.turnLanesForward) - .to.equal(undefined); - expect(metadata.turnLanesBackward) - .to.equal(undefined); - }); - - it('turnLanesForward and turnLanesBackward are both undefined when oneway="yes"', function() { - var metadata = iD.Way({ - tags: { - highway: 'tertiary', - lanes: 2, - oneway: 'yes', - 'turn:lanes:forward': 'through', - 'turn:lanes:backward': 'none' - } - }).lanes().metadata; - - expect(metadata.turnLanesForward) - .to.equal(undefined); - expect(metadata.turnLanesBackward) - .to.equal(undefined); - }); - it('parses turnLane correctly when lanes:both_ways=1', function() { var lanes = iD.Way({ tags: { @@ -1342,5 +1310,22 @@ describe('iD.Way', function() { }); }); + + describe.only('maxspeed', function() { + it('should parse maxspeed correctly', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed:lanes': '30|40|40|40|40' + } + }).lanes().metadata.maxspeedLanes; + + expect(maxspeedLanes).to.deep.equal([ + 30, 40, 40, 40, 40 + ]); + + }); + }); }); }); From 80d2000291b8a46d547cc1dc4d9c22d65ebca36d Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sat, 20 Aug 2016 18:32:35 +0530 Subject: [PATCH 05/11] add test cases for maxspeed & maxpseed:lanes --- modules/core/way.js | 64 +++++++---- test/spec/core/way.js | 241 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 275 insertions(+), 30 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index d9d1400fa..4574a66cf 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -127,28 +127,47 @@ _.extend(Way.prototype, { 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none' ]; - var parsedArray = parsePipeString(key, n); - if (!parsedArray) return; - - return parsedArray.map(function(l) { - return l.map(function(i) { - return validValues.indexOf(i) === -1 ? 'unknown': i; - }); - }); - } - - function parseMaxspeed(key, n) { var str = tags[key]; if (!str) return; - return str.split('|') - .filter(function(s, i) { - return i < n; - }) - .map(function(s) { - if (s === '') return 'none'; + var parsedArray = str.split('|') + .slice(0, n) + .map(function (s) { + if (s === '') s = 'none'; + return s.split(';') + .map(function (d) { + return validValues.indexOf(d) === -1 ? 'unknown': d; + }); + }); + while (parsedArray.length < n) { + parsedArray.push(['unknown']); + } + return parsedArray; + } + + function parseMaxspeed() { + var maxspeed = tags.maxspeed; + if (_.isNumber(maxspeed)) return maxspeed; + if (_.isString(maxspeed)) { + maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g); + if (!maxspeed) return; + return parseInt(maxspeed); + } + } + + function parseMaxspeedLanes(key, n) { + var str = tags[key]; + if (!str) return; + var parsedArray = str.split('|') + .slice(0, n) + .map(function (s) { var m = parseInt(s); + if (s === '' || m === maxspeed) return 'none'; return _.isNaN(m) ? 'unknown': m; }); + while (parsedArray.length < n) { + parsedArray.push('unknown'); + } + return parsedArray; } function parseLaneDirections() { @@ -242,11 +261,13 @@ _.extend(Way.prototype, { var turnLanesForward = parseTurnLanes('turn:lanes:forward', forward); var turnLanesBackward = parseTurnLanes('turn:lanes:backward', backward); - var maxspeedLanes = parseMaxspeed('maxspeed:lanes', laneCount); - var maxspeedLanesForward = parseMaxspeed('maxspeed:lanes:forward', forward); - var maxspeedLanesBackward = parseMaxspeed('maxspeed:lanes:backward', backward); + var maxspeed = parseMaxspeed(); + var maxspeedLanes = parseMaxspeedLanes('maxspeed:lanes', laneCount); + var maxspeedLanesForward = parseMaxspeedLanes('maxspeed:lanes:forward', forward); + var maxspeedLanesBackward = parseMaxspeedLanes('maxspeed:lanes:backward', backward); - // fill each undefined lanesArray's direction element with 'forward/bothwats/backward'. + + // fill each undefined lanesArray's direction element with 'forward/bothways/backward'. smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); smartFill(lanesArray, 'direction', _.fill(Array(bothways), 'bothways')); smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); @@ -283,6 +304,7 @@ _.extend(Way.prototype, { turnLanes: turnLanes, turnLanesForward: turnLanesForward, turnLanesBackward: turnLanesBackward, + maxspeed: maxspeed, maxspeedLanes: maxspeedLanes, maxspeedLanesForward: maxspeedLanesForward, maxspeedLanesBackward: maxspeedLanesBackward, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index 536ad9568..b688e8049 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -1106,7 +1106,7 @@ describe('iD.Way', function() { expect(metadata.turnLanes) .to.deep.equal([ - ['slight_left'], ['none'], ['none'], ['none'], ['none'] + ['slight_left'], ['unknown'], ['unknown'], ['unknown'], ['unknown'] ]); }); @@ -1124,11 +1124,11 @@ describe('iD.Way', function() { expect(metadata.turnLanesForward) .to.deep.equal([ - ['slight_left'], ['none'], ['none'] + ['slight_left'], ['unknown'], ['unknown'] ]); expect(metadata.turnLanesBackward) .to.deep.equal([ - ['through'], ['none'] + ['through'], ['unknown'] ]); }); @@ -1224,8 +1224,6 @@ describe('iD.Way', function() { }); - - it('parses correctly when turn:lanes= ||x', function() { var metadata = iD.Way({ tags: { @@ -1250,7 +1248,7 @@ describe('iD.Way', function() { }).lanes().metadata; expect(metadata.turnLanes) - .to.deep.equal([['none'], ['through'], ['none'], ['none'], ['none']]); + .to.deep.equal([['none'], ['through'], ['none'], ['unknown'], ['unknown']]); }); it('parses correctly when turn:lanes:forward= ||x', function() { @@ -1311,8 +1309,99 @@ describe('iD.Way', function() { }); - describe.only('maxspeed', function() { - it('should parse maxspeed correctly', function() { + describe('maxspeed', function() { + it('should parse maxspeed without any units correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); + }); + it('should parse maxspeed with km/h correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70 km/h' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); + }); + it('should parse maxspeed with kmh correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70kmh' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); + }); + it('should parse maxspeed with kph correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70 kph' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); + }); + it('should parse maxspeed with mph correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70mph' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); + }); + it('should parse maxspeed with knots correctly', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '50knots' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(50); + }); + it('should return undefined when incorrect maxspeed unit provided ', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': '70km' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(undefined); + }); + it('should return undefined when incorrect maxspeed value provided ', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': 'a70knots' + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(undefined); + }); + it('should return undefined when maxspeed not provided ', function() { + var maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(undefined); + }); + }); + describe('maxspeed:lanes', function() { + it('should parse correctly', function() { var maxspeedLanes = iD.Way({ tags: { highway: 'residential', @@ -1320,11 +1409,145 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|40|40|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ 30, 40, 40, 40, 40 ]); + }); + it('should parse maxspeed:lanes:forward/backward correctly', function() { + var metadata = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: 30, + 'lanes:forward': 4, + 'lanes:backward': 1, + 'maxspeed:lanes:forward': '30|40|40|40', + 'maxspeed:lanes:backward': '30' + } + }).lanes().metadata; + expect(metadata.maxspeedLanesForward).to.deep.equal([ + 'none', 40, 40, 40 + ]); + expect(metadata.maxspeedLanesBackward).to.deep.equal([ + 'none' + ]); + }); + + it('should parse correctly when some values maxspeed:lanes are implied by x||y notation', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 4, + maxspeed: '40kmh', + 'maxspeed:lanes': '30|||40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 30, 'none', 'none', 'none' + ]); + }); + + it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 4, + maxspeed: '60kmh', + 'maxspeed:lanes': '30|||' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 30, 'none', 'none', 'none' + ]); + }); + + it('should return none for each maxspeed:lanes which equals maxspeed', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '40kmh', + 'maxspeed:lanes': '30|40|40|40|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 30, 'none', 'none', 'none', 'none' + ]); + maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '50kmh', + 'maxspeed:lanes': '30|40|40|40|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 30, 40, 40, 40, 40 + ]); + maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '30knots', + 'maxspeed:lanes': '30|40|40|40|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 'none', 40, 40, 40, 40 + ]); + }); + it('should return \'unknown\' for every bogus maxspeed:lane value', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '30kmh', + 'maxspeed:lanes': '30|40|fourty|40|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 'none', 40, 'unknown', 40, 40 + ]); + maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '30kmh', + 'maxspeed:lanes': '30|40|fourty|40|random' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 'none', 40, 'unknown', 40, 'unknown' + ]); + }); + + it('should return \'unknown\' when maxspeed:lanes length is less than lane count', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'primary', + lanes: 4, + maxspeed: '40mph', + 'maxspeed:lanes': '40|60|60' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 'none', 60, 60, 'unknown' + ]); + }); + + it('should clip if maxspeed:lanes length is more than lane count', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'primary', + lanes: 4, + maxspeed: '40mph', + 'maxspeed:lanes': '40|60|60|60|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes).to.deep.equal([ + 'none', 60, 60, 60 + ]); }); }); }); From 856f6618d90d611b7b9e46929a243e9f5c5e03b9 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sat, 20 Aug 2016 18:34:50 +0530 Subject: [PATCH 06/11] format test cases --- test/spec/core/way.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/spec/core/way.js b/test/spec/core/way.js index b688e8049..c8b7df650 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -765,6 +765,7 @@ describe('iD.Way', function() { }); describe('lane direction', function() { + it('returns correctlys the lane:forward and lane:backward count', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes') .to.include({ @@ -783,6 +784,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys count under total count if erroneous values are supplied', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, 'lanes:forward': 3 }}).lanes().metadata, 'trunk lanes') .to.include({ @@ -793,6 +795,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys forward count when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes' }}).lanes().metadata, 'trunk lanes') .to.include({ @@ -803,6 +806,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys backward count the when oneway=-1', function() { expect(iD.Way({tags: { highway: 'primary', lanes: 4, oneway: '-1' }}).lanes().metadata, 'primary lanes') .to.include({ @@ -813,6 +817,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('skips provided lanes:forward value when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes', 'lanes:forward': 1 }}).lanes().metadata, 'trunk lanes') .to.include({ @@ -823,6 +828,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('skips provided lanes:backward value when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes', 'lanes:backward': 1 }}).lanes().metadata, 'trunk lanes') .to.include({ @@ -833,6 +839,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys forward count if only backward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, }}).lanes().metadata, 'residential lanes') .to.include({ @@ -851,6 +858,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys backward count if only forward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes') .to.include({ @@ -869,6 +877,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + it('returns correctlys backward count if forward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') .to.include({ @@ -887,6 +896,7 @@ describe('iD.Way', function() { bothways: 1 }); }); + it('returns correctlys forward count if backward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') .to.include({ @@ -916,6 +926,7 @@ describe('iD.Way', function() { bothways: 1 }); }); + it('returns correctlys when lane:both_ways>1', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 2, 'lanes:backward': 2 }}).lanes().metadata, 'residential lanes') .to.include({ @@ -926,6 +937,7 @@ describe('iD.Way', function() { bothways: 1 }); }); + it('returns correctlys when lane:both_ways is 0 or Not a Number', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().metadata, 'residential lanes') .to.include({ @@ -944,6 +956,7 @@ describe('iD.Way', function() { bothways: 0 }); }); + }); describe('lanes array', function() { @@ -1320,6 +1333,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); }); + it('should parse maxspeed with km/h correctly', function() { var maxspeed = iD.Way({ tags: { @@ -1330,6 +1344,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); }); + it('should parse maxspeed with kmh correctly', function() { var maxspeed = iD.Way({ tags: { @@ -1340,6 +1355,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); }); + it('should parse maxspeed with kph correctly', function() { var maxspeed = iD.Way({ tags: { @@ -1350,6 +1366,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); }); + it('should parse maxspeed with mph correctly', function() { var maxspeed = iD.Way({ tags: { @@ -1360,6 +1377,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); }); + it('should parse maxspeed with knots correctly', function() { var maxspeed = iD.Way({ tags: { @@ -1370,6 +1388,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(50); }); + it('should return undefined when incorrect maxspeed unit provided ', function() { var maxspeed = iD.Way({ tags: { @@ -1380,6 +1399,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(undefined); }); + it('should return undefined when incorrect maxspeed value provided ', function() { var maxspeed = iD.Way({ tags: { @@ -1390,6 +1410,7 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(undefined); }); + it('should return undefined when maxspeed not provided ', function() { var maxspeed = iD.Way({ tags: { @@ -1400,7 +1421,9 @@ describe('iD.Way', function() { expect(maxspeed).to.equal(undefined); }); }); + describe('maxspeed:lanes', function() { + it('should parse correctly', function() { var maxspeedLanes = iD.Way({ tags: { @@ -1497,6 +1520,7 @@ describe('iD.Way', function() { 'none', 40, 40, 40, 40 ]); }); + it('should return \'unknown\' for every bogus maxspeed:lane value', function() { var maxspeedLanes = iD.Way({ tags: { From 9f7626715273613671b9446d62ae31c25fceaae7 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sun, 21 Aug 2016 02:34:47 +0530 Subject: [PATCH 07/11] add psv, hov, hgv , bicycle lanes --- modules/core/way.js | 115 ++++++++++++++++++++++++++---------------- test/spec/core/way.js | 48 +++++++++++++++--- 2 files changed, 114 insertions(+), 49 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 4574a66cf..3d7cb19de 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -103,25 +103,6 @@ _.extend(Way.prototype, { lanes: function() { - function parsePipeString(key, n) { - var str = tags[key]; - - if (!str) return; - - var array = str.split('|') - .filter(function(s, i) { - return i < n; - }) - .map(function(s) { - if (s === '') s = 'none'; - return s.split(';'); - }); - while (array.length < n) { - array.push(['none']); - } - return array; - } - function parseTurnLanes(key, n){ var validValues = [ 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', @@ -170,6 +151,12 @@ _.extend(Way.prototype, { return parsedArray; } + function parseVehicleLanes(key, n) { + var str = tags[key]; + if (!str) return; + var parsedArray + } + function parseLaneDirections() { var forward = parseInt(tags['lanes:forward']); var backward = parseInt(tags['lanes:backward']); @@ -208,19 +195,32 @@ _.extend(Way.prototype, { }; } - // smartly fills the undefined array.key elements with values - function smartFill(array, key, values) { - if (!array) return; - // keeps track of elements filled with 'value' - var counter = 0; - array.forEach(function(o) { - if (!o || counter === values.length) return; + function parseMiscLanes(key) { + var validValues = [ + 'yes', 'no', 'designated' + ]; + var str = tags[key]; + if (!str) return; + var parsedArray = str.split('|') + .map(function (s) { + if (s === '') s = 'no'; + return validValues.indexOf(s) === -1 ? 'unknown': s; + }); + return parsedArray; + } - if (o[key] === undefined) { - o[key] = values[counter]; - counter++; - } - }); + function parsebicycleWay(key) { + var validValues = [ + 'yes', 'no', 'designated', 'lane' + ]; + var str = tags[key]; + if (!str) return; + var parsedArray = str.split('|') + .map(function (s) { + if (s === '') s = 'no'; + return validValues.indexOf(s) === -1 ? 'unknown': s; + }); + return parsedArray; } function getLaneCount() { @@ -245,11 +245,7 @@ _.extend(Way.prototype, { var tags = this.tags; var oneway = this.isOneWay(); var laneCount = getLaneCount(); - - var lanesArray = []; - for (var i = 0; i < laneCount; i++) { - lanesArray.push({ index: i}); - } + var maxspeed = parseMaxspeed(); var laneDirections = parseLaneDirections(); var forward = laneDirections.forward; @@ -257,15 +253,45 @@ _.extend(Way.prototype, { var bothways = laneDirections.bothways; // parse the piped string 'x|y|z' format - var turnLanes = parseTurnLanes('turn:lanes', laneCount); - var turnLanesForward = parseTurnLanes('turn:lanes:forward', forward); - var turnLanesBackward = parseTurnLanes('turn:lanes:backward', backward); + var turnLanes = {}; + turnLanes.unspecified = parseTurnLanes('turn:lanes', laneCount); + turnLanes.forward = parseTurnLanes('turn:lanes:forward', forward); + turnLanes.backward = parseTurnLanes('turn:lanes:backward', backward); - var maxspeed = parseMaxspeed(); - var maxspeedLanes = parseMaxspeedLanes('maxspeed:lanes', laneCount); - var maxspeedLanesForward = parseMaxspeedLanes('maxspeed:lanes:forward', forward); - var maxspeedLanesBackward = parseMaxspeedLanes('maxspeed:lanes:backward', backward); + var maxspeedLanes = {}; + maxspeedLanes.unspecified = parseMaxspeedLanes('maxspeed:lanes', laneCount); + maxspeedLanes.forward = parseMaxspeedLanes('maxspeed:lanes:forward', forward); + maxspeedLanes.backward = parseMaxspeedLanes('maxspeed:lanes:backward', backward); + var psvLanes = {}; + psvLanes.unspecified = parseMiscLanes('psv:lanes'); + psvLanes.forward = parseMiscLanes('psv:lanes:forward'); + psvLanes.backward = parseMiscLanes('psv:lanes:backward'); + + var busLanes = {}; + busLanes.unspecified = parseMiscLanes('bus:lanes'); + busLanes.forward = parseMiscLanes('bus:lanes:forward'); + busLanes.backward = parseMiscLanes('bus:lanes:backward'); + + var taxiLanes = {}; + taxiLanes.unspecified = parseMiscLanes('taxi:lanes'); + taxiLanes.forward = parseMiscLanes('taxi:lanes:forward'); + taxiLanes.backward = parseMiscLanes('taxi:lanes:backward'); + + var hovLanes = {}; + hovLanes.unspecified = parseMiscLanes('hov:lanes'); + hovLanes.forward = parseMiscLanes('hov:lanes:forward'); + hovLanes.backward = parseMiscLanes('hov:lanes:backward'); + + var hgvLanes = {}; + hgvLanes.unspecified = parseMiscLanes('hgv:lanes'); + hgvLanes.forward = parseMiscLanes('hgv:lanes:forward'); + hgvLanes.backward = parseMiscLanes('hgv:lanes:backward'); + + var bicyclewayLanes = {}; + bicyclewayLanes.unspecified = parsebicycleWay('bicycleway:lanes'); + bicyclewayLanes.forward = parsebicycleWay('bicycleway:lanes:forward'); + bicyclewayLanes.backward = parsebicycleWay('bicycleway:lanes:backward'); // fill each undefined lanesArray's direction element with 'forward/bothways/backward'. smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); @@ -308,6 +334,9 @@ _.extend(Way.prototype, { maxspeedLanes: maxspeedLanes, maxspeedLanesForward: maxspeedLanesForward, maxspeedLanesBackward: maxspeedLanesBackward, + vehicleLanes: vehicleLanes, + vehicleLanesForward: vehicleLanesForward, + vehicleLanesBackward: vehicleLanesBackward }, lanes: lanesArray }; diff --git a/test/spec/core/way.js b/test/spec/core/way.js index c8b7df650..7f03cc802 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -554,7 +554,7 @@ describe('iD.Way', function() { }); }); - describe('iD.Lanes', function() { + describe.only('iD.Lanes', function() { describe('default lane tags', function() { @@ -956,7 +956,7 @@ describe('iD.Way', function() { bothways: 0 }); }); - + }); describe('lanes array', function() { @@ -1107,23 +1107,59 @@ describe('iD.Way', function() { ]); }); - it('fills with [\'none\'] when given turn:lanes are less than lanes count', function() { + it('returns unknown for every invalid value in turn:lanes', function() { + var metadata = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 3, + oneway: 'yes', + 'turn:lanes': '||straight;NO_LEFT', + } + }).lanes().metadata; + expect(metadata.turnLanes) + .to.deep.equal([ + ['none'], ['none'], ['unknown', 'unknown'] + ]); + }); + + it('returns unknown for every invalid value in turn:lanes:forward & turn:lanes:backward', function() { + var metadata = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'lanes:forward': 1, + 'lanes:both_ways': 1, + 'turn:lanes:forward': 'sligh_left', + 'turn:lanes:backward': 'none|through|though;slight_right', + } + }).lanes().metadata; + expect(metadata.turnLanesForward) + .to.deep.equal([ + ['unknown'] + ]); + expect(metadata.turnLanesBackward) + .to.deep.equal([ + ['none'], ['through'], ['unknown', 'slight_right'] + ]); + }); + + it('fills with [\'unknown\'] when given turn:lanes are less than lanes count', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', lanes: 5, oneway: 'yes', - 'turn:lanes': 'slight_left', + 'turn:lanes': 'slight_left|', } }).lanes().metadata; expect(metadata.turnLanes) .to.deep.equal([ - ['slight_left'], ['unknown'], ['unknown'], ['unknown'], ['unknown'] + ['slight_left'], ['none'], ['unknown'], ['unknown'], ['unknown'] ]); }); - it('fills with [\'none\'] when given turn:lanes:forward are less than lanes forward count', function() { + it('fills with [\'unknown\'] when given turn:lanes:forward are less than lanes forward count', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', From ce948f75632ca60f4310da4cc9b84ad5228f3293 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sun, 21 Aug 2016 03:35:52 +0530 Subject: [PATCH 08/11] modify test cases to adjust lanes != total lane count --- modules/core/way.js | 189 +++++++++++++++++++----------------------- test/spec/core/way.js | 159 +++++++++++++++-------------------- 2 files changed, 155 insertions(+), 193 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 3d7cb19de..fd47c06ec 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -102,27 +102,21 @@ _.extend(Way.prototype, { }, lanes: function() { - - function parseTurnLanes(key, n){ - var validValues = [ - 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', - 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none' - ]; - var str = tags[key]; - if (!str) return; - var parsedArray = str.split('|') - .slice(0, n) - .map(function (s) { - if (s === '') s = 'none'; - return s.split(';') - .map(function (d) { - return validValues.indexOf(d) === -1 ? 'unknown': d; - }); - }); - while (parsedArray.length < n) { - parsedArray.push(['unknown']); + function getLaneCount() { + var count; + // fill laneCount with defaults + switch (tags.highway) { + case 'trunk': + case 'motorway': + count = oneway ? 2 : 4; + break; + default: + count = oneway ? 1 : 2; + break; } - return parsedArray; + + if (tags.lanes) count = parseInt(tags.lanes); + return count; } function parseMaxspeed() { @@ -135,28 +129,6 @@ _.extend(Way.prototype, { } } - function parseMaxspeedLanes(key, n) { - var str = tags[key]; - if (!str) return; - var parsedArray = str.split('|') - .slice(0, n) - .map(function (s) { - var m = parseInt(s); - if (s === '' || m === maxspeed) return 'none'; - return _.isNaN(m) ? 'unknown': m; - }); - while (parsedArray.length < n) { - parsedArray.push('unknown'); - } - return parsedArray; - } - - function parseVehicleLanes(key, n) { - var str = tags[key]; - if (!str) return; - var parsedArray - } - function parseLaneDirections() { var forward = parseInt(tags['lanes:forward']); var backward = parseInt(tags['lanes:backward']); @@ -195,6 +167,36 @@ _.extend(Way.prototype, { }; } + function parseTurnLanes(key){ + var validValues = [ + 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right', + 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none' + ]; + var str = tags[key]; + if (!str) return; + var parsedArray = str.split('|') + .map(function (s) { + if (s === '') s = 'none'; + return s.split(';') + .map(function (d) { + return validValues.indexOf(d) === -1 ? 'unknown': d; + }); + }); + return parsedArray; + } + + function parseMaxspeedLanes(key) { + var str = tags[key]; + if (!str) return; + var parsedArray = str.split('|') + .map(function (s) { + var m = parseInt(s); + if (s === '' || m === maxspeed) return 'none'; + return _.isNaN(m) ? 'unknown': m; + }); + return parsedArray; + } + function parseMiscLanes(key) { var validValues = [ 'yes', 'no', 'designated' @@ -209,7 +211,7 @@ _.extend(Way.prototype, { return parsedArray; } - function parsebicycleWay(key) { + function parseBicycleWay(key) { var validValues = [ 'yes', 'no', 'designated', 'lane' ]; @@ -223,23 +225,6 @@ _.extend(Way.prototype, { return parsedArray; } - function getLaneCount() { - var count; - // fill laneCount with defaults - switch (tags.highway) { - case 'trunk': - case 'motorway': - count = oneway ? 2 : 4; - break; - default: - count = oneway ? 1 : 2; - break; - } - - if (tags.lanes) count = parseInt(tags.lanes); - return count; - } - if (!this.tags.highway) return null; var tags = this.tags; @@ -254,14 +239,14 @@ _.extend(Way.prototype, { // parse the piped string 'x|y|z' format var turnLanes = {}; - turnLanes.unspecified = parseTurnLanes('turn:lanes', laneCount); - turnLanes.forward = parseTurnLanes('turn:lanes:forward', forward); - turnLanes.backward = parseTurnLanes('turn:lanes:backward', backward); + turnLanes.unspecified = parseTurnLanes('turn:lanes'); + turnLanes.forward = parseTurnLanes('turn:lanes:forward'); + turnLanes.backward = parseTurnLanes('turn:lanes:backward'); var maxspeedLanes = {}; - maxspeedLanes.unspecified = parseMaxspeedLanes('maxspeed:lanes', laneCount); - maxspeedLanes.forward = parseMaxspeedLanes('maxspeed:lanes:forward', forward); - maxspeedLanes.backward = parseMaxspeedLanes('maxspeed:lanes:backward', backward); + maxspeedLanes.unspecified = parseMaxspeedLanes('maxspeed:lanes'); + maxspeedLanes.forward = parseMaxspeedLanes('maxspeed:lanes:forward'); + maxspeedLanes.backward = parseMaxspeedLanes('maxspeed:lanes:backward'); var psvLanes = {}; psvLanes.unspecified = parseMiscLanes('psv:lanes'); @@ -289,36 +274,36 @@ _.extend(Way.prototype, { hgvLanes.backward = parseMiscLanes('hgv:lanes:backward'); var bicyclewayLanes = {}; - bicyclewayLanes.unspecified = parsebicycleWay('bicycleway:lanes'); - bicyclewayLanes.forward = parsebicycleWay('bicycleway:lanes:forward'); - bicyclewayLanes.backward = parsebicycleWay('bicycleway:lanes:backward'); + bicyclewayLanes.unspecified = parseBicycleWay('bicycleway:lanes'); + bicyclewayLanes.forward = parseBicycleWay('bicycleway:lanes:forward'); + bicyclewayLanes.backward = parseBicycleWay('bicycleway:lanes:backward'); // fill each undefined lanesArray's direction element with 'forward/bothways/backward'. - smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); - smartFill(lanesArray, 'direction', _.fill(Array(bothways), 'bothways')); - smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); - - // parse turn:lanes:forward/backward first - - if (!oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { - smartFill(lanesArray, 'turnLane', turnLanesForward); - // if both_ways fill it with null - smartFill(lanesArray, 'turnLane', _.fill(Array(bothways), null)); - smartFill(lanesArray, 'turnLane', turnLanesBackward); - } - else if (this.tags['turn:lanes']) { - smartFill(lanesArray, 'turnLane', turnLanes); - } - - // parse max speed - if (!oneway && this.tags['maxspeed:lanes:forward'] && this.tags['maxspeed:lanes:backward']) { - smartFill(lanesArray, 'maxspeed', maxspeedLanesForward); - smartFill(lanesArray, 'maxspeed', _.fill(Array(bothways), null)); - smartFill(lanesArray, 'maxspeed', maxspeedLanesBackward); - } - else if (this.tags['maxspeed:lanes']) { - smartFill(lanesArray, 'maxspeed', maxspeedLanes); - } + // smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); + // smartFill(lanesArray, 'direction', _.fill(Array(bothways), 'bothways')); + // smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); + // + // // parse turn:lanes:forward/backward first + // + // if (!oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { + // smartFill(lanesArray, 'turnLane', turnLanesForward); + // // if both_ways fill it with null + // smartFill(lanesArray, 'turnLane', _.fill(Array(bothways), null)); + // smartFill(lanesArray, 'turnLane', turnLanesBackward); + // } + // else if (this.tags['turn:lanes']) { + // smartFill(lanesArray, 'turnLane', turnLanes); + // } + // + // // parse max speed + // if (!oneway && this.tags['maxspeed:lanes:forward'] && this.tags['maxspeed:lanes:backward']) { + // smartFill(lanesArray, 'maxspeed', maxspeedLanesForward); + // smartFill(lanesArray, 'maxspeed', _.fill(Array(bothways), null)); + // smartFill(lanesArray, 'maxspeed', maxspeedLanesBackward); + // } + // else if (this.tags['maxspeed:lanes']) { + // smartFill(lanesArray, 'maxspeed', maxspeedLanes); + // } return { metadata: { @@ -328,17 +313,15 @@ _.extend(Way.prototype, { backward: backward, bothways: bothways, turnLanes: turnLanes, - turnLanesForward: turnLanesForward, - turnLanesBackward: turnLanesBackward, maxspeed: maxspeed, maxspeedLanes: maxspeedLanes, - maxspeedLanesForward: maxspeedLanesForward, - maxspeedLanesBackward: maxspeedLanesBackward, - vehicleLanes: vehicleLanes, - vehicleLanesForward: vehicleLanesForward, - vehicleLanesBackward: vehicleLanesBackward - }, - lanes: lanesArray + psvLanes: psvLanes, + busLanes: busLanes, + taxiLanes: taxiLanes, + hovLanes: hovLanes, + hgvLanes: hgvLanes, + bicyclewayLanes: bicyclewayLanes + } }; }, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index 7f03cc802..036d72b9e 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -756,7 +756,7 @@ describe('iD.Way', function() { }); describe('oneway tags', function() { - it('returns correctlys oneway when tagged as oneway', function() { + it('returns correctly oneway when tagged as oneway', function() { expect(iD.Way({tags: { highway: 'residential', oneway: 'yes' }}).lanes().metadata.oneway, 'residential lanes') .to.be.true; expect(iD.Way({tags: { highway: 'residential', oneway: 'no' }}).lanes().metadata.oneway, 'residential lanes') @@ -766,7 +766,7 @@ describe('iD.Way', function() { describe('lane direction', function() { - it('returns correctlys the lane:forward and lane:backward count', function() { + it('returns correctly the lane:forward and lane:backward count', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes') .to.include({ count: 2, @@ -785,7 +785,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys count under total count if erroneous values are supplied', function() { + it('returns correctly the count if erroneous values are supplied', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, 'lanes:forward': 3 }}).lanes().metadata, 'trunk lanes') .to.include({ count: 2, @@ -796,7 +796,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys forward count when oneway=yes', function() { + it('returns correctly forward count when oneway=yes', function() { expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes' }}).lanes().metadata, 'trunk lanes') .to.include({ count: 2, @@ -807,7 +807,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys backward count the when oneway=-1', function() { + it('returns correctly backward count the when oneway=-1', function() { expect(iD.Way({tags: { highway: 'primary', lanes: 4, oneway: '-1' }}).lanes().metadata, 'primary lanes') .to.include({ count: 4, @@ -840,7 +840,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys forward count if only backward is supplied', function() { + it('returns correctly forward count if only backward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, }}).lanes().metadata, 'residential lanes') .to.include({ count: 3, @@ -859,7 +859,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys backward count if only forward is supplied', function() { + it('returns correctly backward count if only forward is supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes') .to.include({ count: 3, @@ -878,7 +878,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys backward count if forward and both_ways are supplied', function() { + it('returns correctly backward count if forward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') .to.include({ count: 3, @@ -897,7 +897,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys forward count if backward and both_ways are supplied', function() { + it('returns correctly forward count if backward and both_ways are supplied', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 3, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') .to.include({ count: 3, @@ -916,7 +916,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys the lane:both_ways count as 1', function() { + it('returns correctly the lane:both_ways count as 1', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes') .to.include({ count: 2, @@ -927,7 +927,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys when lane:both_ways>1', function() { + it('returns correctly when lane:both_ways>1', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 2, 'lanes:backward': 2 }}).lanes().metadata, 'residential lanes') .to.include({ count: 5, @@ -938,7 +938,7 @@ describe('iD.Way', function() { }); }); - it('returns correctlys when lane:both_ways is 0 or Not a Number', function() { + it('returns correctly when lane:both_ways is 0 or Not a Number', function() { expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().metadata, 'residential lanes') .to.include({ count: 5, @@ -959,7 +959,7 @@ describe('iD.Way', function() { }); - describe('lanes array', function() { + describe.skip('lanes array', function() { it('should have correct number of direction elements', function() { var lanes = iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 2, 'lanes:both_ways': 0, 'lanes:backward': 3 }}).lanes().lanes; var forward = lanes.filter(function(l) { @@ -1002,7 +1002,7 @@ describe('iD.Way', function() { 'turn:lanes': 'none|slight_right' } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([ ['none'], ['slight_right'] ]); @@ -1018,7 +1018,7 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([ ['none'], ['slight_right'] ]); @@ -1035,11 +1035,11 @@ describe('iD.Way', function() { 'turn:lanes:backward': 'none|through|through;slight_right', } }).lanes().metadata; - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.deep.equal([ ['slight_left'] ]); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.deep.equal([ ['none'], ['through'], ['through', 'slight_right'] ]); @@ -1055,16 +1055,7 @@ describe('iD.Way', function() { } }).lanes(); - expect(lanesData.metadata.turnLanes) - .to.deep.equal([ - ['slight_left', 'reverse', 'left'], - ['slight_left', 'left', 'through'], - ['through'], - ['none'], - ['through', 'right'] - ]); - - expect(lanesData.lanes.map(function(l) { return l.turnLane; })) + expect(lanesData.metadata.turnLanes.unspecified) .to.deep.equal([ ['slight_left', 'reverse', 'left'], ['slight_left', 'left', 'through'], @@ -1086,25 +1077,17 @@ describe('iD.Way', function() { 'turn:lanes:backward': 'none|through;left' } }).lanes(); - expect(lanesData.metadata.turnLanesForward) + expect(lanesData.metadata.turnLanes.forward) .to.deep.equal([ ['slight_left', 'reverse', 'left'], ['slight_left', 'left', 'through'], ['through'] ]); - expect(lanesData.metadata.turnLanesBackward) + expect(lanesData.metadata.turnLanes.backward) .to.deep.equal([ ['none'], ['through', 'left'] ]); - expect(lanesData.lanes.map(function(l) { return l.turnLane; })) - .to.deep.equal([ - ['slight_left', 'reverse', 'left'], - ['slight_left', 'left', 'through'], - ['through'], - ['none'], - ['through', 'left'] - ]); }); it('returns unknown for every invalid value in turn:lanes', function() { @@ -1116,7 +1099,7 @@ describe('iD.Way', function() { 'turn:lanes': '||straight;NO_LEFT', } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([ ['none'], ['none'], ['unknown', 'unknown'] ]); @@ -1133,17 +1116,17 @@ describe('iD.Way', function() { 'turn:lanes:backward': 'none|through|though;slight_right', } }).lanes().metadata; - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.deep.equal([ ['unknown'] ]); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.deep.equal([ ['none'], ['through'], ['unknown', 'slight_right'] ]); }); - it('fills with [\'unknown\'] when given turn:lanes are less than lanes count', function() { + it.skip('fills with [\'unknown\'] when given turn:lanes are less than lanes count', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', @@ -1153,13 +1136,13 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([ - ['slight_left'], ['none'], ['unknown'], ['unknown'], ['unknown'] + ['slight_left'], ['none'] ]); }); - it('fills with [\'unknown\'] when given turn:lanes:forward are less than lanes forward count', function() { + it.skip('fills with [\'unknown\'] when given turn:lanes:forward are less than lanes forward count', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', @@ -1171,17 +1154,17 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.deep.equal([ ['slight_left'], ['unknown'], ['unknown'] ]); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.deep.equal([ ['through'], ['unknown'] ]); }); - it('clips when turn lane information is more than lane count', function() { + it.skip('clips when turn lane information is more than lane count', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', @@ -1206,15 +1189,15 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.equal(undefined); - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.equal(undefined); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.equal(undefined); }); - it('turnLanesForward and turnLanesBackward are both undefined when both are not provided', function() { + it('turnLanes.forward and turnLanes.backward are both undefined when both are not provided', function() { var metadata = iD.Way({ tags: { highway: 'tertiary', @@ -1224,11 +1207,11 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([['through'], ['through', 'slight_right']]); - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.equal(undefined); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.equal(undefined); }); @@ -1244,12 +1227,11 @@ describe('iD.Way', function() { 'turn:lanes:backward': 'slight_right', 'turn:lanes:forward': 'slight_left||', } - }).lanes().lanes; - var turnLanes = lanes.map(function(l) { return l.turnLane; }); - expect(turnLanes).to.deep.equal([ - ['slight_left'], ['none'], ['none'], null, ['slight_right'] - ]); - + }).lanes(); + expect(lanes.metadata.turnLanes.backward) + .to.deep.equal([['slight_right']]); + expect(lanes.metadata.turnLanes.forward) + .to.deep.equal([['slight_left'], ['none'], ['none']]); }); it('parses turnLane correctly when lanes:both_ways=1 & lanes:forward < lanes:backward', function() { @@ -1264,13 +1246,11 @@ describe('iD.Way', function() { 'turn:lanes:forward': 'through', 'turn:lanes:backward': 'slight_left||', } - }).lanes().lanes; - - var turnLanes = lanes.map(function(l) { return l.turnLane; }); - expect(turnLanes).to.deep.equal([ - ['through'], null, ['slight_left'], ['none'], ['none'] - ]); - + }).lanes(); + expect(lanes.metadata.turnLanes.forward) + .to.deep.equal([['through']]); + expect(lanes.metadata.turnLanes.backward) + .to.deep.equal([['slight_left'], ['none'], ['none']]); }); it('parses correctly when turn:lanes= ||x', function() { @@ -1283,7 +1263,7 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) + expect(metadata.turnLanes.unspecified) .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]); }); @@ -1296,8 +1276,8 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanes) - .to.deep.equal([['none'], ['through'], ['none'], ['unknown'], ['unknown']]); + expect(metadata.turnLanes.unspecified) + .to.deep.equal([['none'], ['through'], ['none']]); }); it('parses correctly when turn:lanes:forward= ||x', function() { @@ -1313,9 +1293,9 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.deep.equal([['none']]); }); @@ -1332,13 +1312,13 @@ describe('iD.Way', function() { } }).lanes().metadata; - expect(metadata.turnLanesForward) + expect(metadata.turnLanes.forward) .to.deep.equal([['slight_left'], ['none'], ['none']]); - expect(metadata.turnLanesBackward) + expect(metadata.turnLanes.backward) .to.deep.equal([['none'], ['none']]); }); - it('fills turnLane correctly in lanes', function() { + it.skip('fills turnLane correctly in lanes', function() { var lanes = iD.Way({ tags: { highway: 'tertiary', @@ -1355,7 +1335,6 @@ describe('iD.Way', function() { ['slight_left'], ['none'], ['none'], ['none'], ['slight_right'] ]); }); - }); describe('maxspeed', function() { @@ -1467,7 +1446,7 @@ describe('iD.Way', function() { lanes: 5, 'maxspeed:lanes': '30|40|40|40|40' } - }).lanes().metadata.maxspeedLanes; + }).lanes().metadata.maxspeedLanes.unspecified; expect(maxspeedLanes).to.deep.equal([ 30, 40, 40, 40, 40 ]); @@ -1485,10 +1464,10 @@ describe('iD.Way', function() { 'maxspeed:lanes:backward': '30' } }).lanes().metadata; - expect(metadata.maxspeedLanesForward).to.deep.equal([ + expect(metadata.maxspeedLanes.forward).to.deep.equal([ 'none', 40, 40, 40 ]); - expect(metadata.maxspeedLanesBackward).to.deep.equal([ + expect(metadata.maxspeedLanes.backward).to.deep.equal([ 'none' ]); }); @@ -1502,7 +1481,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|||40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 30, 'none', 'none', 'none' ]); }); @@ -1516,7 +1495,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|||' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 30, 'none', 'none', 'none' ]); }); @@ -1530,7 +1509,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|40|40|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 30, 'none', 'none', 'none', 'none' ]); maxspeedLanes = iD.Way({ @@ -1541,7 +1520,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|40|40|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 30, 40, 40, 40, 40 ]); maxspeedLanes = iD.Way({ @@ -1552,7 +1531,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|40|40|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 40, 40, 40, 40 ]); }); @@ -1566,7 +1545,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|fourty|40|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 40, 'unknown', 40, 40 ]); maxspeedLanes = iD.Way({ @@ -1577,12 +1556,12 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|fourty|40|random' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 40, 'unknown', 40, 'unknown' ]); }); - it('should return \'unknown\' when maxspeed:lanes length is less than lane count', function() { + it.skip('should return \'unknown\' when maxspeed:lanes length is less than lane count', function() { var maxspeedLanes = iD.Way({ tags: { highway: 'primary', @@ -1591,12 +1570,12 @@ describe('iD.Way', function() { 'maxspeed:lanes': '40|60|60' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 60, 60, 'unknown' ]); }); - it('should clip if maxspeed:lanes length is more than lane count', function() { + it.skip('should clip if maxspeed:lanes length is more than lane count', function() { var maxspeedLanes = iD.Way({ tags: { highway: 'primary', @@ -1605,7 +1584,7 @@ describe('iD.Way', function() { 'maxspeed:lanes': '40|60|60|60|40' } }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes).to.deep.equal([ + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 60, 60, 60 ]); }); From c95df1c830eaff72f96355f6e40d659deffb36ae Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Sun, 21 Aug 2016 04:04:42 +0530 Subject: [PATCH 09/11] restructure lanesArray --- modules/core/way.js | 58 +++++++++++++++++++++++-------------------- test/spec/core/way.js | 13 +++++++--- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index fd47c06ec..2b43f7c9f 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -225,6 +225,21 @@ _.extend(Way.prototype, { return parsedArray; } + function addToLanesArray(data, key) { + if (data.forward) data.forward.forEach(function(l, i) { + if (!lanesArray.forward[i]) lanesArray.forward[i] = {}; + lanesArray.forward[i][key] = l; + }); + if (data.backward) data.backward.forEach(function(l, i) { + if (!lanesArray.backward[i]) lanesArray.backward[i] = {}; + lanesArray.backward[i][key] = l; + }); + if (data.unspecified) data.unspecified.forEach(function(l, i) { + if (!lanesArray.unspecified[i]) lanesArray.unspecified[i] = {}; + lanesArray.unspecified[i][key] = l; + }); + + } if (!this.tags.highway) return null; var tags = this.tags; @@ -278,32 +293,20 @@ _.extend(Way.prototype, { bicyclewayLanes.forward = parseBicycleWay('bicycleway:lanes:forward'); bicyclewayLanes.backward = parseBicycleWay('bicycleway:lanes:backward'); - // fill each undefined lanesArray's direction element with 'forward/bothways/backward'. - // smartFill(lanesArray, 'direction', _.fill(Array(forward), 'forward')); - // smartFill(lanesArray, 'direction', _.fill(Array(bothways), 'bothways')); - // smartFill(lanesArray, 'direction', _.fill(Array(backward), 'backward')); - // - // // parse turn:lanes:forward/backward first - // - // if (!oneway && this.tags['turn:lanes:forward'] && this.tags['turn:lanes:backward']) { - // smartFill(lanesArray, 'turnLane', turnLanesForward); - // // if both_ways fill it with null - // smartFill(lanesArray, 'turnLane', _.fill(Array(bothways), null)); - // smartFill(lanesArray, 'turnLane', turnLanesBackward); - // } - // else if (this.tags['turn:lanes']) { - // smartFill(lanesArray, 'turnLane', turnLanes); - // } - // - // // parse max speed - // if (!oneway && this.tags['maxspeed:lanes:forward'] && this.tags['maxspeed:lanes:backward']) { - // smartFill(lanesArray, 'maxspeed', maxspeedLanesForward); - // smartFill(lanesArray, 'maxspeed', _.fill(Array(bothways), null)); - // smartFill(lanesArray, 'maxspeed', maxspeedLanesBackward); - // } - // else if (this.tags['maxspeed:lanes']) { - // smartFill(lanesArray, 'maxspeed', maxspeedLanes); - // } + var lanesArray = { + forward: [], + backward: [], + unspecified: [] + }; + + addToLanesArray(turnLanes, 'turnLane'); + addToLanesArray(maxspeedLanes, 'maxspeed'); + addToLanesArray(psvLanes, 'psv'); + addToLanesArray(busLanes, 'bus'); + addToLanesArray(taxiLanes, 'taxi'); + addToLanesArray(hovLanes, 'hov'); + addToLanesArray(hgvLanes, 'hgv'); + addToLanesArray(bicyclewayLanes, 'bicycle'); return { metadata: { @@ -321,7 +324,8 @@ _.extend(Way.prototype, { hovLanes: hovLanes, hgvLanes: hgvLanes, bicyclewayLanes: bicyclewayLanes - } + }, + lanes: lanesArray }; }, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index 036d72b9e..bccef6f01 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -1487,15 +1487,20 @@ describe('iD.Way', function() { }); it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function() { - var maxspeedLanes = iD.Way({ + var lanes = iD.Way({ tags: { highway: 'residential', - lanes: 4, + lanes: 5, + 'lanes:forward': 1, + 'lanes:both_ways': 1, + 'turn:lanes:forward': 'slight_left', + 'turn:lanes:backward': 'none|through|through;slight_right', maxspeed: '60kmh', 'maxspeed:lanes': '30|||' } - }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes.unspecified).to.deep.equal([ + }).lanes(); + console.log(JSON.stringify(lanes.lanes, null, '\t')); + expect(lanes.metadata.maxspeedLanes.unspecified).to.deep.equal([ 30, 'none', 'none', 'none' ]); }); From cb670ccdc43f9c5f33ec755ca1d895a1e2fc6bf6 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Mon, 22 Aug 2016 18:12:22 +0530 Subject: [PATCH 10/11] add test cases for bicycleway --- modules/core/way.js | 37 +++---- test/spec/core/way.js | 217 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 209 insertions(+), 45 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 2b43f7c9f..06424b4e7 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -225,21 +225,21 @@ _.extend(Way.prototype, { return parsedArray; } - function addToLanesArray(data, key) { + function mapToLanesObj(data, key) { if (data.forward) data.forward.forEach(function(l, i) { - if (!lanesArray.forward[i]) lanesArray.forward[i] = {}; - lanesArray.forward[i][key] = l; + if (!lanesObj.forward[i]) lanesObj.forward[i] = {}; + lanesObj.forward[i][key] = l; }); if (data.backward) data.backward.forEach(function(l, i) { - if (!lanesArray.backward[i]) lanesArray.backward[i] = {}; - lanesArray.backward[i][key] = l; + if (!lanesObj.backward[i]) lanesObj.backward[i] = {}; + lanesObj.backward[i][key] = l; }); if (data.unspecified) data.unspecified.forEach(function(l, i) { - if (!lanesArray.unspecified[i]) lanesArray.unspecified[i] = {}; - lanesArray.unspecified[i][key] = l; + if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {}; + lanesObj.unspecified[i][key] = l; }); - } + if (!this.tags.highway) return null; var tags = this.tags; @@ -293,20 +293,21 @@ _.extend(Way.prototype, { bicyclewayLanes.forward = parseBicycleWay('bicycleway:lanes:forward'); bicyclewayLanes.backward = parseBicycleWay('bicycleway:lanes:backward'); - var lanesArray = { + var lanesObj = { forward: [], backward: [], unspecified: [] }; - addToLanesArray(turnLanes, 'turnLane'); - addToLanesArray(maxspeedLanes, 'maxspeed'); - addToLanesArray(psvLanes, 'psv'); - addToLanesArray(busLanes, 'bus'); - addToLanesArray(taxiLanes, 'taxi'); - addToLanesArray(hovLanes, 'hov'); - addToLanesArray(hgvLanes, 'hgv'); - addToLanesArray(bicyclewayLanes, 'bicycle'); + // map forward/backward/unspecified of each lane type to lanesObj + mapToLanesObj(turnLanes, 'turnLane'); + mapToLanesObj(maxspeedLanes, 'maxspeed'); + mapToLanesObj(psvLanes, 'psv'); + mapToLanesObj(busLanes, 'bus'); + mapToLanesObj(taxiLanes, 'taxi'); + mapToLanesObj(hovLanes, 'hov'); + mapToLanesObj(hgvLanes, 'hgv'); + mapToLanesObj(bicyclewayLanes, 'bicycleway'); return { metadata: { @@ -325,7 +326,7 @@ _.extend(Way.prototype, { hgvLanes: hgvLanes, bicyclewayLanes: bicyclewayLanes }, - lanes: lanesArray + lanes: lanesObj }; }, diff --git a/test/spec/core/way.js b/test/spec/core/way.js index bccef6f01..a052f7a87 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -554,7 +554,7 @@ describe('iD.Way', function() { }); }); - describe.only('iD.Lanes', function() { + describe('iD.Lanes', function() { describe('default lane tags', function() { @@ -1318,7 +1318,24 @@ describe('iD.Way', function() { .to.deep.equal([['none'], ['none']]); }); - it.skip('fills turnLane correctly in lanes', function() { + it('fills lanes.unspecified with key \'turnLane\' correctly', function() { + var lanes = iD.Way({ + tags: { + highway: 'tertiary', + lanes: 5, + oneway: 'yes', + 'turn:lanes': 'slight_left||through|through;slight_right|slight_right' + } + }).lanes().lanes; + var turnLanesUnspecified = lanes.unspecified.map(function(l) { return l.turnLane; }); + expect(turnLanesUnspecified).to.deep.equal([ + ['slight_left'], ['none'], ['through'], ['through', 'slight_right'], ['slight_right'] + ]); + expect(lanes.forward).to.deep.equal([]); + expect(lanes.backward).to.deep.equal([]); + }); + + it('fills lanes.forward & lanes.backward with key \'turnLane\' correctly', function() { var lanes = iD.Way({ tags: { highway: 'tertiary', @@ -1329,10 +1346,14 @@ describe('iD.Way', function() { 'turn:lanes:forward': 'slight_left||', } }).lanes().lanes; - - var turnLanes = lanes.map(function(l) { return l.turnLane; }); - expect(turnLanes).to.deep.equal([ - ['slight_left'], ['none'], ['none'], ['none'], ['slight_right'] + expect(lanes.unspecified).to.deep.equal([]); + var turnLanesForward = lanes.forward.map(function(l) { return l.turnLane; }); + var turnLanesBackward = lanes.backward.map(function(l) { return l.turnLane; }); + expect(turnLanesForward).to.deep.equal([ + ['slight_left'], ['none'], ['none'] + ]); + expect(turnLanesBackward).to.deep.equal([ + ['none'], ['slight_right'] ]); }); }); @@ -1347,6 +1368,14 @@ describe('iD.Way', function() { } }).lanes().metadata.maxspeed; expect(maxspeed).to.equal(70); + maxspeed = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed': 70 + } + }).lanes().metadata.maxspeed; + expect(maxspeed).to.equal(70); }); it('should parse maxspeed with km/h correctly', function() { @@ -1499,7 +1528,6 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|||' } }).lanes(); - console.log(JSON.stringify(lanes.lanes, null, '\t')); expect(lanes.metadata.maxspeedLanes.unspecified).to.deep.equal([ 30, 'none', 'none', 'none' ]); @@ -1541,7 +1569,7 @@ describe('iD.Way', function() { ]); }); - it('should return \'unknown\' for every bogus maxspeed:lane value', function() { + it('should return \'unknown\' for every invalid maxspeed:lane value', function() { var maxspeedLanes = iD.Way({ tags: { highway: 'residential', @@ -1561,36 +1589,171 @@ describe('iD.Way', function() { 'maxspeed:lanes': '30|40|fourty|40|random' } }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes.unspecified).to.deep.equal([ 'none', 40, 'unknown', 40, 'unknown' ]); }); - - it.skip('should return \'unknown\' when maxspeed:lanes length is less than lane count', function() { - var maxspeedLanes = iD.Way({ + it('fills lanes.unspecified with key \'maxspeed\' correctly', function() { + var lanes = iD.Way({ tags: { - highway: 'primary', - lanes: 4, - maxspeed: '40mph', - 'maxspeed:lanes': '40|60|60' + highway: 'residential', + lanes: 5, + maxspeed: '30kmh', + 'maxspeed:lanes': '30|40|fourty|40|40' } - }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes.unspecified).to.deep.equal([ - 'none', 60, 60, 'unknown' + }).lanes().lanes; + var maxspeedLanes = lanes.unspecified.map(function (l) { + return l.maxspeed; + }); + expect(maxspeedLanes).to.deep.equal([ + 'none', 40, 'unknown', 40, 40 + ]); + }); + }); + + describe('bicycle lanes', function() { + it('should parse bicycle:lanes correctly', function() { + var lanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 3, + 'lanes:bicycleway': 2, + 'bicycleway:lanes': 'no|yes|no|designated|no', + maxspeed: '30kmh', + 'turn:lanes': 'left|||through|right' + } + }).lanes(); + expect(lanes.metadata.bicyclewayLanes.unspecified).to.deep.equal([ + 'no','yes','no', 'designated', 'no' + ]); + var bicyclewayLanes = lanes.lanes.unspecified.map(function(l) { + return l.bicycleway; + }); + expect(bicyclewayLanes).to.deep.equal([ + 'no','yes','no', 'designated', 'no' ]); }); - it.skip('should clip if maxspeed:lanes length is more than lane count', function() { - var maxspeedLanes = iD.Way({ + it('should parse bicycle:lanes:forward/backward correctly', function() { + var lanes = iD.Way({ tags: { - highway: 'primary', - lanes: 4, - maxspeed: '40mph', - 'maxspeed:lanes': '40|60|60|60|40' + highway: 'residential', + 'lanes:forward': 4, + 'lanes:backward': 3, + 'turn:lanes:forward': 'left;through|left;through|through|right;through|right', + 'bicycleway:lanes:forward': 'lane|no|no|no|no', + 'bicycleway:lanes:backward': 'lane|no|no|no' } - }).lanes().metadata.maxspeedLanes; - expect(maxspeedLanes.unspecified).to.deep.equal([ - 'none', 60, 60, 60 + }).lanes(); + expect(lanes.metadata.bicyclewayLanes.forward).to.deep.equal([ + 'lane','no','no', 'no', 'no' + ]); + expect(lanes.metadata.bicyclewayLanes.backward).to.deep.equal([ + 'lane','no','no', 'no' + ]); + var bicyclewayLanesForward = lanes.lanes.forward.map(function(l) { + return l.bicycleway; + }); + expect(bicyclewayLanesForward).to.deep.equal([ + 'lane','no','no', 'no', 'no' + ]); + var bicyclewayLanesBackward = lanes.lanes.backward.map(function(l) { + return l.bicycleway; + }); + expect(bicyclewayLanesBackward).to.deep.equal([ + 'lane','no','no', 'no' + ]); + }); + + it('should replace any invalid value with unknown', function() { + var lanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 3, + maxspeed: '30kmh', + 'bicycleway:lanes': 'no|share|no|designated|no', + 'turn:lanes': 'left|||through|right' + } + }).lanes(); + expect(lanes.metadata.bicyclewayLanes.unspecified).to.deep.equal([ + 'no','unknown','no', 'designated', 'no' + ]); + var psvLanesForward = lanes.lanes.unspecified.map(function(l) { + return l.bicycleway; + }); + expect(psvLanesForward).to.deep.equal([ + 'no','unknown','no', 'designated', 'no' + ]); + }); + }); + + describe('miscellaneous lanes', function() { + it('should parse psv:lanes correctly', function() { + var lanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '30kmh', + 'psv:lanes': 'yes|no||no|no' + } + }).lanes(); + expect(lanes.metadata.psvLanes.unspecified).to.deep.equal([ + 'yes','no','no', 'no', 'no' + ]); + var psvLanesForward = lanes.lanes.unspecified.map(function(l) { + return l.psv; + }); + expect(psvLanesForward).to.deep.equal([ + 'yes','no','no', 'no', 'no' + ]); + }); + it('should parse psv:lanes:forward/backward correctly', function() { + var lanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + maxspeed: '30kmh', + 'psv:lanes:forward': 'no|no|', + 'psv:lanes:backward': 'yes|designated', + } + }).lanes(); + expect(lanes.metadata.psvLanes.forward).to.deep.equal([ + 'no','no','no' + ]); + expect(lanes.metadata.psvLanes.backward).to.deep.equal([ + 'yes', 'designated' + ]); + var psvLanesForward = lanes.lanes.forward.map(function(l) { + return l.psv; + }); + var psvLanesBackward = lanes.lanes.backward.map(function(l) { + return l.psv; + }); + expect(psvLanesForward).to.deep.equal([ + 'no','no','no' + ]); + expect(psvLanesBackward).to.deep.equal([ + 'yes', 'designated' + ]); + }); + it('should replace any invalid value with unknown', function() { + var lanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 3, + maxspeed: '30kmh', + 'psv:lanes': 'yes|no|garbage' + } + }).lanes(); + expect(lanes.metadata.psvLanes.unspecified).to.deep.equal([ + 'yes','no', 'unknown' + ]); + var psvLanesForward = lanes.lanes.unspecified.map(function(l) { + return l.psv; + }); + expect(psvLanesForward).to.deep.equal([ + 'yes','no', 'unknown' ]); }); }); From 4c996b9b422432a5095a83ac0f7569ac75f1ca24 Mon Sep 17 00:00:00 2001 From: Kushan Joshi <0o3ko0@gmail.com> Date: Tue, 13 Sep 2016 19:53:02 +0530 Subject: [PATCH 11/11] refactor none to null --- modules/core/way.js | 3 ++- test/spec/core/way.js | 34 ++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/modules/core/way.js b/modules/core/way.js index 06424b4e7..1b66e660c 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -190,8 +190,9 @@ _.extend(Way.prototype, { if (!str) return; var parsedArray = str.split('|') .map(function (s) { + if (s === 'none') return s; var m = parseInt(s); - if (s === '' || m === maxspeed) return 'none'; + if (s === '' || m === maxspeed) return null; return _.isNaN(m) ? 'unknown': m; }); return parsedArray; diff --git a/test/spec/core/way.js b/test/spec/core/way.js index a052f7a87..14e4a86a0 100644 --- a/test/spec/core/way.js +++ b/test/spec/core/way.js @@ -1466,7 +1466,7 @@ describe('iD.Way', function() { }); }); - describe('maxspeed:lanes', function() { + describe.only('maxspeed:lanes', function() { it('should parse correctly', function() { var maxspeedLanes = iD.Way({ @@ -1494,10 +1494,10 @@ describe('iD.Way', function() { } }).lanes().metadata; expect(metadata.maxspeedLanes.forward).to.deep.equal([ - 'none', 40, 40, 40 + null, 40, 40, 40 ]); expect(metadata.maxspeedLanes.backward).to.deep.equal([ - 'none' + null ]); }); @@ -1511,7 +1511,7 @@ describe('iD.Way', function() { } }).lanes().metadata.maxspeedLanes; expect(maxspeedLanes.unspecified).to.deep.equal([ - 30, 'none', 'none', 'none' + 30, null, null, null ]); }); @@ -1529,7 +1529,7 @@ describe('iD.Way', function() { } }).lanes(); expect(lanes.metadata.maxspeedLanes.unspecified).to.deep.equal([ - 30, 'none', 'none', 'none' + 30, null, null, null ]); }); @@ -1543,7 +1543,7 @@ describe('iD.Way', function() { } }).lanes().metadata.maxspeedLanes; expect(maxspeedLanes.unspecified).to.deep.equal([ - 30, 'none', 'none', 'none', 'none' + 30, null, null, null, null ]); maxspeedLanes = iD.Way({ tags: { @@ -1565,7 +1565,7 @@ describe('iD.Way', function() { } }).lanes().metadata.maxspeedLanes; expect(maxspeedLanes.unspecified).to.deep.equal([ - 'none', 40, 40, 40, 40 + null, 40, 40, 40, 40 ]); }); @@ -1579,7 +1579,7 @@ describe('iD.Way', function() { } }).lanes().metadata.maxspeedLanes; expect(maxspeedLanes.unspecified).to.deep.equal([ - 'none', 40, 'unknown', 40, 40 + null, 40, 'unknown', 40, 40 ]); maxspeedLanes = iD.Way({ tags: { @@ -1591,9 +1591,23 @@ describe('iD.Way', function() { }).lanes().metadata.maxspeedLanes; expect(maxspeedLanes.unspecified).to.deep.equal([ - 'none', 40, 'unknown', 40, 'unknown' + null, 40, 'unknown', 40, 'unknown' ]); }); + + it('should parse maxspeed when none', function() { + var maxspeedLanes = iD.Way({ + tags: { + highway: 'residential', + lanes: 5, + 'maxspeed:lanes': '30|40|none|40|40' + } + }).lanes().metadata.maxspeedLanes; + expect(maxspeedLanes.unspecified).to.deep.equal([ + 30, 40, 'none', 40, 40 + ]); + }); + it('fills lanes.unspecified with key \'maxspeed\' correctly', function() { var lanes = iD.Way({ tags: { @@ -1607,7 +1621,7 @@ describe('iD.Way', function() { return l.maxspeed; }); expect(maxspeedLanes).to.deep.equal([ - 'none', 40, 'unknown', 40, 40 + null, 40, 'unknown', 40, 40 ]); }); });