diff --git a/modules/osm/index.js b/modules/osm/index.js
index aa9effc79..38bc88520 100644
--- a/modules/osm/index.js
+++ b/modules/osm/index.js
@@ -7,13 +7,17 @@ export {
osmIntersection,
osmTurn,
osmInferRestriction
-} from './intersection.js';
+} from './intersection';
+
+export {
+ osmLanes
+} from './lanes';
export {
osmIsSimpleMultipolygonOuterMember,
osmSimpleMultipolygonOuterMember,
osmJoinWays
-} from './multipolygon.js';
+} from './multipolygon';
export {
osmOneWayTags,
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
new file mode 100644
index 000000000..f8c136d8d
--- /dev/null
+++ b/modules/osm/lanes.js
@@ -0,0 +1,246 @@
+import _ from 'lodash';
+
+
+export function osmLanes(entity) {
+ if (entity.type !== 'way') return null;
+ if (!entity.tags.highway) return null;
+
+ var tags = entity.tags;
+ var isOneWay = entity.isOneWay();
+ var laneCount = getLaneCount(tags, isOneWay);
+ var maxspeed = parseMaxspeed(tags);
+
+ var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
+ var forward = laneDirections.forward;
+ var backward = laneDirections.backward;
+ var bothways = laneDirections.bothways;
+
+ // parse the piped string 'x|y|z' format
+ var turnLanes = {};
+ turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
+ turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
+ turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
+
+ var maxspeedLanes = {};
+ maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
+ maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
+ maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
+
+ var psvLanes = {};
+ psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
+ psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
+ psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
+
+ var busLanes = {};
+ busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
+ busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
+ busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
+
+ var taxiLanes = {};
+ taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
+ taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
+ taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
+
+ var hovLanes = {};
+ hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
+ hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
+ hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
+
+ var hgvLanes = {};
+ hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
+ hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
+ hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
+
+ var bicyclewayLanes = {};
+ bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
+ bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
+ bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
+
+ var lanesObj = {
+ forward: [],
+ backward: [],
+ unspecified: []
+ };
+
+ // map forward/backward/unspecified of each lane type to lanesObj
+ mapToLanesObj(lanesObj, turnLanes, 'turnLane');
+ mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
+ mapToLanesObj(lanesObj, psvLanes, 'psv');
+ mapToLanesObj(lanesObj, busLanes, 'bus');
+ mapToLanesObj(lanesObj, taxiLanes, 'taxi');
+ mapToLanesObj(lanesObj, hovLanes, 'hov');
+ mapToLanesObj(lanesObj, hgvLanes, 'hgv');
+ mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
+
+ return {
+ metadata: {
+ count: laneCount,
+ oneway: isOneWay,
+ forward: forward,
+ backward: backward,
+ bothways: bothways,
+ turnLanes: turnLanes,
+ maxspeed: maxspeed,
+ maxspeedLanes: maxspeedLanes,
+ psvLanes: psvLanes,
+ busLanes: busLanes,
+ taxiLanes: taxiLanes,
+ hovLanes: hovLanes,
+ hgvLanes: hgvLanes,
+ bicyclewayLanes: bicyclewayLanes
+ },
+ lanes: lanesObj
+ };
+}
+
+
+function getLaneCount(tags, isOneWay) {
+ var count;
+ if (tags.lanes) {
+ count = parseInt(tags.lanes, 10);
+ if (count > 0) {
+ return count;
+ }
+ }
+
+
+ switch (tags.highway) {
+ case 'trunk':
+ case 'motorway':
+ count = isOneWay ? 2 : 4;
+ break;
+ default:
+ count = isOneWay ? 1 : 2;
+ break;
+ }
+
+ return count;
+}
+
+
+function parseMaxspeed(tags) {
+ 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, 10);
+ }
+}
+
+
+function parseLaneDirections(tags, isOneWay, laneCount) {
+ var forward = parseInt(tags['lanes:forward'], 10);
+ var backward = parseInt(tags['lanes:backward'], 10);
+ var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
+
+ if (parseInt(tags.oneway, 10) === -1) {
+ forward = 0;
+ bothways = 0;
+ backward = laneCount;
+ }
+ else if (isOneWay) {
+ forward = laneCount;
+ bothways = 0;
+ backward = 0;
+ }
+ else if (_.isNaN(forward) && _.isNaN(backward)) {
+ backward = Math.floor((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
+ };
+}
+
+
+function parseTurnLanes(tag){
+ if (!tag) return;
+
+ var validValues = [
+ 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
+ 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
+ ];
+
+ return tag.split('|')
+ .map(function (s) {
+ if (s === '') s = 'none';
+ return s.split(';')
+ .map(function (d) {
+ return validValues.indexOf(d) === -1 ? 'unknown': d;
+ });
+ });
+}
+
+
+function parseMaxspeedLanes(tag, maxspeed) {
+ if (!tag) return;
+
+ return tag.split('|')
+ .map(function (s) {
+ if (s === 'none') return s;
+ var m = parseInt(s, 10);
+ if (s === '' || m === maxspeed) return null;
+ return _.isNaN(m) ? 'unknown': m;
+ });
+}
+
+
+function parseMiscLanes(tag) {
+ if (!tag) return;
+
+ var validValues = [
+ 'yes', 'no', 'designated'
+ ];
+
+ return tag.split('|')
+ .map(function (s) {
+ if (s === '') s = 'no';
+ return validValues.indexOf(s) === -1 ? 'unknown': s;
+ });
+}
+
+
+function parseBicycleWay(tag) {
+ if (!tag) return;
+
+ var validValues = [
+ 'yes', 'no', 'designated', 'lane'
+ ];
+
+ return tag.split('|')
+ .map(function (s) {
+ if (s === '') s = 'no';
+ return validValues.indexOf(s) === -1 ? 'unknown': s;
+ });
+}
+
+
+function mapToLanesObj(lanesObj, data, key) {
+ if (data.forward) data.forward.forEach(function(l, i) {
+ if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
+ lanesObj.forward[i][key] = l;
+ });
+ if (data.backward) data.backward.forEach(function(l, i) {
+ if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
+ lanesObj.backward[i][key] = l;
+ });
+ if (data.unspecified) data.unspecified.forEach(function(l, i) {
+ if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
+ lanesObj.unspecified[i][key] = l;
+ });
+}
diff --git a/modules/osm/way.js b/modules/osm/way.js
index aa6ef190c..7f328894c 100644
--- a/modules/osm/way.js
+++ b/modules/osm/way.js
@@ -2,6 +2,7 @@ import * as d3 from 'd3';
import _ from 'lodash';
import { geoExtent, geoCross } from '../geo/index';
import { osmEntity } from './entity';
+import { osmLanes } from './lanes';
import { osmOneWayTags } from './tags';
import { areaKeys } from '../core/context';
@@ -116,233 +117,7 @@ _.extend(osmWay.prototype, {
lanes: function() {
- 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, 10);
- return count;
- }
-
- 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, 10);
- }
- }
-
- function parseLaneDirections() {
- var forward = parseInt(tags['lanes:forward'], 10);
- var backward = parseInt(tags['lanes:backward'], 10);
- var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
-
- if (parseInt(tags.oneway, 10) === -1) {
- forward = 0;
- bothways = 0;
- backward = laneCount;
- }
- else if (oneway) {
- forward = laneCount;
- bothways = 0;
- backward = 0;
- }
- else if (_.isNaN(forward) && _.isNaN(backward)) {
- backward = Math.floor((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
- };
- }
-
- 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) {
- if (s === 'none') return s;
- var m = parseInt(s, 10);
- if (s === '' || m === maxspeed) return null;
- return _.isNaN(m) ? 'unknown': m;
- });
- return parsedArray;
- }
-
- 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;
- }
-
- 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 mapToLanesObj(data, key) {
- if (data.forward) data.forward.forEach(function(l, i) {
- if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
- lanesObj.forward[i][key] = l;
- });
- if (data.backward) data.backward.forEach(function(l, i) {
- if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
- lanesObj.backward[i][key] = l;
- });
- if (data.unspecified) data.unspecified.forEach(function(l, i) {
- if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
- lanesObj.unspecified[i][key] = l;
- });
- }
-
- if (!this.tags.highway) return null;
-
- var tags = this.tags;
- var oneway = this.isOneWay();
- var laneCount = getLaneCount();
- var maxspeed = parseMaxspeed();
-
- var laneDirections = parseLaneDirections();
- var forward = laneDirections.forward;
- var backward = laneDirections.backward;
- var bothways = laneDirections.bothways;
-
- // parse the piped string 'x|y|z' format
- var turnLanes = {};
- turnLanes.unspecified = parseTurnLanes('turn:lanes');
- turnLanes.forward = parseTurnLanes('turn:lanes:forward');
- turnLanes.backward = parseTurnLanes('turn:lanes:backward');
-
- var maxspeedLanes = {};
- maxspeedLanes.unspecified = parseMaxspeedLanes('maxspeed:lanes');
- maxspeedLanes.forward = parseMaxspeedLanes('maxspeed:lanes:forward');
- maxspeedLanes.backward = parseMaxspeedLanes('maxspeed:lanes: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');
-
- var lanesObj = {
- forward: [],
- backward: [],
- unspecified: []
- };
-
- // 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: {
- count: laneCount,
- oneway: oneway,
- forward: forward,
- backward: backward,
- bothways: bothways,
- turnLanes: turnLanes,
- maxspeed: maxspeed,
- maxspeedLanes: maxspeedLanes,
- psvLanes: psvLanes,
- busLanes: busLanes,
- taxiLanes: taxiLanes,
- hovLanes: hovLanes,
- hgvLanes: hgvLanes,
- bicyclewayLanes: bicyclewayLanes
- },
- lanes: lanesObj
- };
+ return osmLanes(this);
},
diff --git a/test/index.html b/test/index.html
index 23dfd3eab..24c233ab4 100644
--- a/test/index.html
+++ b/test/index.html
@@ -84,6 +84,7 @@
+
diff --git a/test/spec/osm/lanes.js b/test/spec/osm/lanes.js
new file mode 100644
index 000000000..4a072a28c
--- /dev/null
+++ b/test/spec/osm/lanes.js
@@ -0,0 +1,1218 @@
+describe('iD.Lanes', function() {
+
+ describe('default lane tags', function() {
+
+ describe('motorway', function() {
+
+ it('returns 2 lanes for highway=motorway', function() {
+ expect(iD.Way({tags: { highway: 'motorway' }}).lanes().metadata.count, 'motorway lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'motorway', oneway: 'yes' }}).lanes().metadata.count, 'motorway lanes')
+ .to.eql(2);
+ });
+
+ it('returns 4 lanes for highway=motorway and oneway=no', function() {
+ expect(iD.Way({tags: { highway: 'motorway', oneway: 'no' }}).lanes().metadata.count, 'motorway lanes')
+ .to.eql(4);
+ });
+
+ it('returns 1 lane for highway=motorway_link', function() {
+ expect(iD.Way({tags: { highway: 'motorway_link' }}).lanes().metadata.count, 'motorway_link lanes')
+ .to.eql(1);
+ expect(iD.Way({tags: { highway: 'motorway_link', oneway: 'yes' }}).lanes().metadata.count, 'motorway_link lanes')
+ .to.eql(1);
+ });
+
+ it('returns 2 lanes for highway=motorway_link and oneway=no', function() {
+ expect(iD.Way({tags: { highway: 'motorway_link', oneway: 'no' }}).lanes().metadata.count, 'motorway_link lanes')
+ .to.eql(2);
+ });
+
+ });
+
+ describe('trunk', function() {
+
+ it('returns 4 lanes for highway=trunk', function() {
+ expect(iD.Way({tags: { highway: 'trunk' }}).lanes().metadata.count, 'trunk lanes')
+ .to.eql(4);
+ expect(iD.Way({tags: { highway: 'trunk', oneway: 'no' }}).lanes().metadata.count, 'trunk lanes')
+ .to.eql(4);
+ });
+
+ it('returns 2 lanes for highway=trunk and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'trunk', oneway: 'yes' }}).lanes().metadata.count, 'trunk lanes')
+ .to.eql(2);
+ });
+
+ it('returns 2 lanes for highway=trunk_link', function() {
+ expect(iD.Way({tags: { highway: 'trunk_link' }}).lanes().metadata.count, 'trunk_link lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'trunk_link', oneway: 'no' }}).lanes().metadata.count, 'trunk_link lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=trunk_link and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'trunk_link', oneway: 'yes' }}).lanes().metadata.count, 'trunk_link lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('primary', function() {
+
+ it('returns 2 lanes for highway=primary', function() {
+ expect(iD.Way({tags: { highway: 'primary' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'primary', oneway: 'no' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=primary and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'primary', oneway: 'yes' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(1);
+ });
+
+ it('returns 2 lanes for highway=primary_link', function() {
+ expect(iD.Way({tags: { highway: 'primary_link' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'primary_link', oneway: 'no' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=primary_link and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'primary_link', oneway: 'yes' }}).lanes().metadata.count, 'primary lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('seconday', function() {
+
+ it('returns 2 lanes for highway=secondary', function() {
+ expect(iD.Way({tags: { highway: 'secondary' }}).lanes().metadata.count, 'secondary lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'secondary', oneway: 'no' }}).lanes().metadata.count, 'secondary lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=secondary and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'secondary', oneway: 'yes' }}).lanes().metadata.count, 'secondary lanes')
+ .to.eql(1);
+ });
+
+ it('returns 2 lane for highway=secondary_link', function() {
+ expect(iD.Way({tags: { highway: 'secondary_link' }}).lanes().metadata.count, 'secondary_link lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'secondary_link', oneway: 'no' }}).lanes().metadata.count, 'secondary_link lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=secondary_link and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'secondary_link', oneway: 'yes' }}).lanes().metadata.count, 'secondary_link lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('tertiary', function() {
+
+ it('returns 2 lanes for highway=tertiary', function() {
+ expect(iD.Way({tags: { highway: 'tertiary' }}).lanes().metadata.count, 'tertiary lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'tertiary', oneway: 'no' }}).lanes().metadata.count, 'tertiary lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=tertiary and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'tertiary', oneway: 'yes' }}).lanes().metadata.count, 'tertiary lanes')
+ .to.eql(1);
+ });
+
+ it('returns 2 lane for highway=tertiary_link', function() {
+ expect(iD.Way({tags: { highway: 'tertiary_link' }}).lanes().metadata.count, 'tertiary_link lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'tertiary_link', oneway: 'no' }}).lanes().metadata.count, 'tertiary_link lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=tertiary_link and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'tertiary_link', oneway: 'yes' }}).lanes().metadata.count, 'tertiary_link lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('residential', function() {
+
+ it('returns 2 lanes for highway=residential', function() {
+ expect(iD.Way({tags: { highway: 'residential' }}).lanes().metadata.count, 'residential lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'residential', oneway: 'no' }}).lanes().metadata.count, 'residential lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=residential and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'residential', oneway: 'yes' }}).lanes().metadata.count, 'residential lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('service', function() {
+
+ it('returns 2 lanes for highway=service', function() {
+ expect(iD.Way({tags: { highway: 'service' }}).lanes().metadata.count, 'service lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'service', oneway: 'no' }}).lanes().metadata.count, 'service lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=service and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'service', oneway: 'yes' }}).lanes().metadata.count, 'service lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('track', function() {
+
+ it('returns 2 lanes for highway=track', function() {
+ expect(iD.Way({tags: { highway: 'track' }}).lanes().metadata.count, 'track lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'track', oneway: 'no' }}).lanes().metadata.count, 'track lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=track and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'track', oneway: 'yes' }}).lanes().metadata.count, 'track lanes')
+ .to.eql(1);
+ });
+ });
+
+ describe('path', function() {
+
+ it('returns 2 lanes for highway=path', function() {
+ expect(iD.Way({tags: { highway: 'path' }}).lanes().metadata.count, 'path lanes')
+ .to.eql(2);
+ expect(iD.Way({tags: { highway: 'path', oneway: 'no' }}).lanes().metadata.count, 'path lanes')
+ .to.eql(2);
+ });
+
+ it('returns 1 lane for highway=path and oneway=yes', function() {
+ expect(iD.Way({tags: { highway: 'path', oneway: 'yes' }}).lanes().metadata.count, 'path lanes')
+ .to.eql(1);
+ });
+ });
+ });
+
+ describe('oneway tags', 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')
+ .to.be.false;
+ });
+ });
+
+ describe('lane direction', 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,
+ oneway: false,
+ forward: 1,
+ backward: 1,
+ bothways: 0
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:forward': 3, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 4,
+ oneway: false,
+ forward: 3,
+ backward: 1,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 2,
+ backward: 0,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: true,
+ forward: 2,
+ backward: 0,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: true,
+ backward: 4,
+ forward: 0,
+ 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({
+ count: 2,
+ oneway: true,
+ forward: 2,
+ backward: 0,
+ 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({
+ count: 2,
+ oneway: true,
+ forward: 2,
+ backward: 0,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 2,
+ backward: 1,
+ bothways: 0
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:backward': 3, }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 4,
+ oneway: false,
+ forward: 1,
+ backward: 3,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 1,
+ backward: 2,
+ bothways: 0
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 2,
+ oneway: false,
+ forward: 1,
+ backward: 1,
+ bothways: 0
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 1,
+ backward: 1,
+ bothways: 1
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 5,
+ oneway: false,
+ forward: 1,
+ backward: 3,
+ bothways: 1
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 1,
+ backward: 1,
+ bothways: 1
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 5,
+ oneway: false,
+ forward: 3,
+ backward: 1,
+ bothways: 1
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 1,
+ backward: 0,
+ bothways: 1
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 2,
+ backward: 2,
+ bothways: 1
+ });
+ });
+
+ 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,
+ oneway: false,
+ forward: 2,
+ backward: 3,
+ bothways: 0
+ });
+ expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 'none' }}).lanes().metadata, 'residential lanes')
+ .to.include({
+ count: 2,
+ oneway: false,
+ forward: 1,
+ backward: 1,
+ bothways: 0
+ });
+ });
+
+ });
+
+ 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) {
+ 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);
+ });
+ });
+
+ describe('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.unspecified)
+ .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.unspecified)
+ .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.turnLanes.forward)
+ .to.deep.equal([
+ ['slight_left']
+ ]);
+ expect(metadata.turnLanes.backward)
+ .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.unspecified)
+ .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.turnLanes.forward)
+ .to.deep.equal([
+ ['slight_left', 'reverse', 'left'],
+ ['slight_left', 'left', 'through'],
+ ['through']
+ ]);
+ expect(lanesData.metadata.turnLanes.backward)
+ .to.deep.equal([
+ ['none'],
+ ['through', 'left']
+ ]);
+ });
+
+ 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.unspecified)
+ .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.turnLanes.forward)
+ .to.deep.equal([
+ ['unknown']
+ ]);
+ expect(metadata.turnLanes.backward)
+ .to.deep.equal([
+ ['none'], ['through'], ['unknown', 'slight_right']
+ ]);
+ });
+
+ it.skip('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|',
+ }
+ }).lanes().metadata;
+
+ expect(metadata.turnLanes.unspecified)
+ .to.deep.equal([
+ ['slight_left'], ['none']
+ ]);
+ });
+
+ it.skip('fills with [\'unknown\'] 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.turnLanes.forward)
+ .to.deep.equal([
+ ['slight_left'], ['unknown'], ['unknown']
+ ]);
+ expect(metadata.turnLanes.backward)
+ .to.deep.equal([
+ ['through'], ['unknown']
+ ]);
+ });
+
+ it.skip('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.unspecified)
+ .to.equal(undefined);
+ expect(metadata.turnLanes.forward)
+ .to.equal(undefined);
+ expect(metadata.turnLanes.backward)
+ .to.equal(undefined);
+ });
+
+ it('turnLanes.forward and turnLanes.backward 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.unspecified)
+ .to.deep.equal([['through'], ['through', 'slight_right']]);
+ expect(metadata.turnLanes.forward)
+ .to.equal(undefined);
+ expect(metadata.turnLanes.backward)
+ .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();
+ 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() {
+ 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();
+ 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() {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'tertiary',
+ lanes: 3,
+ oneway: 'yes',
+ 'turn:lanes': '||through;slight_right',
+ }
+ }).lanes().metadata;
+
+ expect(metadata.turnLanes.unspecified)
+ .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.unspecified)
+ .to.deep.equal([['none'], ['through'], ['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.turnLanes.forward)
+ .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]);
+ expect(metadata.turnLanes.backward)
+ .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.turnLanes.forward)
+ .to.deep.equal([['slight_left'], ['none'], ['none']]);
+ expect(metadata.turnLanes.backward)
+ .to.deep.equal([['none'], ['none']]);
+ });
+
+ 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',
+ lanes: 5,
+ 'lanes:forward': 3,
+ 'lanes:backward': 2,
+ 'turn:lanes:backward': 'none|slight_right',
+ 'turn:lanes:forward': 'slight_left||',
+ }
+ }).lanes().lanes;
+ 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']
+ ]);
+ });
+ });
+
+ 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);
+ 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',
+ lanes: 5,
+ 'maxspeed:lanes': '30|40|40|40|40'
+ }
+ }).lanes().metadata.maxspeedLanes.unspecified;
+ 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.maxspeedLanes.forward).to.deep.equal([
+ null, 40, 40, 40
+ ]);
+ expect(metadata.maxspeedLanes.backward).to.deep.equal([
+ null
+ ]);
+ });
+
+ 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.unspecified).to.deep.equal([
+ 30, null, null, null
+ ]);
+ });
+
+ it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function() {
+ var lanes = 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',
+ maxspeed: '60kmh',
+ 'maxspeed:lanes': '30|||'
+ }
+ }).lanes();
+ expect(lanes.metadata.maxspeedLanes.unspecified).to.deep.equal([
+ 30, null, null, null
+ ]);
+ });
+
+ 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.unspecified).to.deep.equal([
+ 30, null, null, null, null
+ ]);
+ maxspeedLanes = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ maxspeed: '50kmh',
+ 'maxspeed:lanes': '30|40|40|40|40'
+ }
+ }).lanes().metadata.maxspeedLanes;
+ expect(maxspeedLanes.unspecified).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.unspecified).to.deep.equal([
+ null, 40, 40, 40, 40
+ ]);
+ });
+
+ it('should return \'unknown\' for every invalid 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.unspecified).to.deep.equal([
+ null, 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.unspecified).to.deep.equal([
+ 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: {
+ highway: 'residential',
+ lanes: 5,
+ maxspeed: '30kmh',
+ 'maxspeed:lanes': '30|40|fourty|40|40'
+ }
+ }).lanes().lanes;
+ var maxspeedLanes = lanes.unspecified.map(function (l) {
+ return l.maxspeed;
+ });
+ expect(maxspeedLanes).to.deep.equal([
+ null, 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('should parse bicycle:lanes:forward/backward correctly', function() {
+ var lanes = iD.Way({
+ tags: {
+ 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();
+ 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'
+ ]);
+ });
+ });
+});
diff --git a/test/spec/osm/way.js b/test/spec/osm/way.js
index 4635daaf6..78141ff94 100644
--- a/test/spec/osm/way.js
+++ b/test/spec/osm/way.js
@@ -560,1222 +560,4 @@ describe('iD.osmWay', function() {
});
});
- describe('iD.Lanes', function() {
-
- describe('default lane tags', function() {
-
- describe('motorway', function() {
-
- it('returns 2 lanes for highway=motorway', function() {
- expect(iD.Way({tags: { highway: 'motorway' }}).lanes().metadata.count, 'motorway lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'motorway', oneway: 'yes' }}).lanes().metadata.count, 'motorway lanes')
- .to.eql(2);
- });
-
- it('returns 4 lanes for highway=motorway and oneway=no', function() {
- expect(iD.Way({tags: { highway: 'motorway', oneway: 'no' }}).lanes().metadata.count, 'motorway lanes')
- .to.eql(4);
- });
-
- it('returns 1 lane for highway=motorway_link', function() {
- expect(iD.Way({tags: { highway: 'motorway_link' }}).lanes().metadata.count, 'motorway_link lanes')
- .to.eql(1);
- expect(iD.Way({tags: { highway: 'motorway_link', oneway: 'yes' }}).lanes().metadata.count, 'motorway_link lanes')
- .to.eql(1);
- });
-
- it('returns 2 lanes for highway=motorway_link and oneway=no', function() {
- expect(iD.Way({tags: { highway: 'motorway_link', oneway: 'no' }}).lanes().metadata.count, 'motorway_link lanes')
- .to.eql(2);
- });
-
- });
-
- describe('trunk', function() {
-
- it('returns 4 lanes for highway=trunk', function() {
- expect(iD.Way({tags: { highway: 'trunk' }}).lanes().metadata.count, 'trunk lanes')
- .to.eql(4);
- expect(iD.Way({tags: { highway: 'trunk', oneway: 'no' }}).lanes().metadata.count, 'trunk lanes')
- .to.eql(4);
- });
-
- it('returns 2 lanes for highway=trunk and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'trunk', oneway: 'yes' }}).lanes().metadata.count, 'trunk lanes')
- .to.eql(2);
- });
-
- it('returns 2 lanes for highway=trunk_link', function() {
- expect(iD.Way({tags: { highway: 'trunk_link' }}).lanes().metadata.count, 'trunk_link lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'trunk_link', oneway: 'no' }}).lanes().metadata.count, 'trunk_link lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=trunk_link and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'trunk_link', oneway: 'yes' }}).lanes().metadata.count, 'trunk_link lanes')
- .to.eql(1);
- });
- });
-
- describe('primary', function() {
-
- it('returns 2 lanes for highway=primary', function() {
- expect(iD.Way({tags: { highway: 'primary' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'primary', oneway: 'no' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=primary and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'primary', oneway: 'yes' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(1);
- });
-
- it('returns 2 lanes for highway=primary_link', function() {
- expect(iD.Way({tags: { highway: 'primary_link' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'primary_link', oneway: 'no' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=primary_link and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'primary_link', oneway: 'yes' }}).lanes().metadata.count, 'primary lanes')
- .to.eql(1);
- });
- });
-
- describe('seconday', function() {
-
- it('returns 2 lanes for highway=secondary', function() {
- expect(iD.Way({tags: { highway: 'secondary' }}).lanes().metadata.count, 'secondary lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'secondary', oneway: 'no' }}).lanes().metadata.count, 'secondary lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=secondary and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'secondary', oneway: 'yes' }}).lanes().metadata.count, 'secondary lanes')
- .to.eql(1);
- });
-
- it('returns 2 lane for highway=secondary_link', function() {
- expect(iD.Way({tags: { highway: 'secondary_link' }}).lanes().metadata.count, 'secondary_link lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'secondary_link', oneway: 'no' }}).lanes().metadata.count, 'secondary_link lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=secondary_link and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'secondary_link', oneway: 'yes' }}).lanes().metadata.count, 'secondary_link lanes')
- .to.eql(1);
- });
- });
-
- describe('tertiary', function() {
-
- it('returns 2 lanes for highway=tertiary', function() {
- expect(iD.Way({tags: { highway: 'tertiary' }}).lanes().metadata.count, 'tertiary lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'tertiary', oneway: 'no' }}).lanes().metadata.count, 'tertiary lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=tertiary and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'tertiary', oneway: 'yes' }}).lanes().metadata.count, 'tertiary lanes')
- .to.eql(1);
- });
-
- it('returns 2 lane for highway=tertiary_link', function() {
- expect(iD.Way({tags: { highway: 'tertiary_link' }}).lanes().metadata.count, 'tertiary_link lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'tertiary_link', oneway: 'no' }}).lanes().metadata.count, 'tertiary_link lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=tertiary_link and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'tertiary_link', oneway: 'yes' }}).lanes().metadata.count, 'tertiary_link lanes')
- .to.eql(1);
- });
- });
-
- describe('residential', function() {
-
- it('returns 2 lanes for highway=residential', function() {
- expect(iD.Way({tags: { highway: 'residential' }}).lanes().metadata.count, 'residential lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'residential', oneway: 'no' }}).lanes().metadata.count, 'residential lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=residential and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'residential', oneway: 'yes' }}).lanes().metadata.count, 'residential lanes')
- .to.eql(1);
- });
- });
-
- describe('service', function() {
-
- it('returns 2 lanes for highway=service', function() {
- expect(iD.Way({tags: { highway: 'service' }}).lanes().metadata.count, 'service lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'service', oneway: 'no' }}).lanes().metadata.count, 'service lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=service and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'service', oneway: 'yes' }}).lanes().metadata.count, 'service lanes')
- .to.eql(1);
- });
- });
-
- describe('track', function() {
-
- it('returns 2 lanes for highway=track', function() {
- expect(iD.Way({tags: { highway: 'track' }}).lanes().metadata.count, 'track lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'track', oneway: 'no' }}).lanes().metadata.count, 'track lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=track and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'track', oneway: 'yes' }}).lanes().metadata.count, 'track lanes')
- .to.eql(1);
- });
- });
-
- describe('path', function() {
-
- it('returns 2 lanes for highway=path', function() {
- expect(iD.Way({tags: { highway: 'path' }}).lanes().metadata.count, 'path lanes')
- .to.eql(2);
- expect(iD.Way({tags: { highway: 'path', oneway: 'no' }}).lanes().metadata.count, 'path lanes')
- .to.eql(2);
- });
-
- it('returns 1 lane for highway=path and oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'path', oneway: 'yes' }}).lanes().metadata.count, 'path lanes')
- .to.eql(1);
- });
- });
- });
-
- describe('oneway tags', 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')
- .to.be.false;
- });
- });
-
- describe('lane direction', 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,
- oneway: false,
- forward: 1,
- backward: 1,
- bothways: 0
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:forward': 3, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 4,
- oneway: false,
- forward: 3,
- backward: 1,
- bothways: 0
- });
- });
-
- 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,
- oneway: false,
- forward: 2,
- backward: 0,
- bothways: 0
- });
- });
-
- 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,
- oneway: true,
- forward: 2,
- backward: 0,
- bothways: 0
- });
- });
-
- 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,
- oneway: true,
- backward: 4,
- forward: 0,
- 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({
- count: 2,
- oneway: true,
- forward: 2,
- backward: 0,
- 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({
- count: 2,
- oneway: true,
- forward: 2,
- backward: 0,
- bothways: 0
- });
- });
-
- 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,
- oneway: false,
- forward: 2,
- backward: 1,
- bothways: 0
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:backward': 3, }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 4,
- oneway: false,
- forward: 1,
- backward: 3,
- bothways: 0
- });
- });
-
- 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,
- oneway: false,
- forward: 1,
- backward: 2,
- bothways: 0
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 2,
- oneway: false,
- forward: 1,
- backward: 1,
- bothways: 0
- });
- });
-
- 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,
- oneway: false,
- forward: 1,
- backward: 1,
- bothways: 1
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 5,
- oneway: false,
- forward: 1,
- backward: 3,
- bothways: 1
- });
- });
-
- 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,
- oneway: false,
- forward: 1,
- backward: 1,
- bothways: 1
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 5,
- oneway: false,
- forward: 3,
- backward: 1,
- bothways: 1
- });
- });
-
- 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,
- oneway: false,
- forward: 1,
- backward: 0,
- bothways: 1
- });
- });
-
- 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,
- oneway: false,
- forward: 2,
- backward: 2,
- bothways: 1
- });
- });
-
- 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,
- oneway: false,
- forward: 2,
- backward: 3,
- bothways: 0
- });
- expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 'none' }}).lanes().metadata, 'residential lanes')
- .to.include({
- count: 2,
- oneway: false,
- forward: 1,
- backward: 1,
- bothways: 0
- });
- });
-
- });
-
- 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) {
- 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);
- });
- });
-
- describe('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.unspecified)
- .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.unspecified)
- .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.turnLanes.forward)
- .to.deep.equal([
- ['slight_left']
- ]);
- expect(metadata.turnLanes.backward)
- .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.unspecified)
- .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.turnLanes.forward)
- .to.deep.equal([
- ['slight_left', 'reverse', 'left'],
- ['slight_left', 'left', 'through'],
- ['through']
- ]);
- expect(lanesData.metadata.turnLanes.backward)
- .to.deep.equal([
- ['none'],
- ['through', 'left']
- ]);
- });
-
- 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.unspecified)
- .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.turnLanes.forward)
- .to.deep.equal([
- ['unknown']
- ]);
- expect(metadata.turnLanes.backward)
- .to.deep.equal([
- ['none'], ['through'], ['unknown', 'slight_right']
- ]);
- });
-
- it.skip('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|',
- }
- }).lanes().metadata;
-
- expect(metadata.turnLanes.unspecified)
- .to.deep.equal([
- ['slight_left'], ['none']
- ]);
- });
-
- it.skip('fills with [\'unknown\'] 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.turnLanes.forward)
- .to.deep.equal([
- ['slight_left'], ['unknown'], ['unknown']
- ]);
- expect(metadata.turnLanes.backward)
- .to.deep.equal([
- ['through'], ['unknown']
- ]);
- });
-
- it.skip('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.unspecified)
- .to.equal(undefined);
- expect(metadata.turnLanes.forward)
- .to.equal(undefined);
- expect(metadata.turnLanes.backward)
- .to.equal(undefined);
- });
-
- it('turnLanes.forward and turnLanes.backward 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.unspecified)
- .to.deep.equal([['through'], ['through', 'slight_right']]);
- expect(metadata.turnLanes.forward)
- .to.equal(undefined);
- expect(metadata.turnLanes.backward)
- .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();
- 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() {
- 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();
- 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() {
- var metadata = iD.Way({
- tags: {
- highway: 'tertiary',
- lanes: 3,
- oneway: 'yes',
- 'turn:lanes': '||through;slight_right',
- }
- }).lanes().metadata;
-
- expect(metadata.turnLanes.unspecified)
- .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.unspecified)
- .to.deep.equal([['none'], ['through'], ['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.turnLanes.forward)
- .to.deep.equal([['none'], ['none'], ['through', 'slight_right']]);
- expect(metadata.turnLanes.backward)
- .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.turnLanes.forward)
- .to.deep.equal([['slight_left'], ['none'], ['none']]);
- expect(metadata.turnLanes.backward)
- .to.deep.equal([['none'], ['none']]);
- });
-
- 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',
- lanes: 5,
- 'lanes:forward': 3,
- 'lanes:backward': 2,
- 'turn:lanes:backward': 'none|slight_right',
- 'turn:lanes:forward': 'slight_left||',
- }
- }).lanes().lanes;
- 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']
- ]);
- });
- });
-
- 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);
- 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',
- lanes: 5,
- 'maxspeed:lanes': '30|40|40|40|40'
- }
- }).lanes().metadata.maxspeedLanes.unspecified;
- 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.maxspeedLanes.forward).to.deep.equal([
- null, 40, 40, 40
- ]);
- expect(metadata.maxspeedLanes.backward).to.deep.equal([
- null
- ]);
- });
-
- 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.unspecified).to.deep.equal([
- 30, null, null, null
- ]);
- });
-
- it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function() {
- var lanes = 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',
- maxspeed: '60kmh',
- 'maxspeed:lanes': '30|||'
- }
- }).lanes();
- expect(lanes.metadata.maxspeedLanes.unspecified).to.deep.equal([
- 30, null, null, null
- ]);
- });
-
- 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.unspecified).to.deep.equal([
- 30, null, null, null, null
- ]);
- maxspeedLanes = iD.Way({
- tags: {
- highway: 'residential',
- lanes: 5,
- maxspeed: '50kmh',
- 'maxspeed:lanes': '30|40|40|40|40'
- }
- }).lanes().metadata.maxspeedLanes;
- expect(maxspeedLanes.unspecified).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.unspecified).to.deep.equal([
- null, 40, 40, 40, 40
- ]);
- });
-
- it('should return \'unknown\' for every invalid 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.unspecified).to.deep.equal([
- null, 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.unspecified).to.deep.equal([
- 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: {
- highway: 'residential',
- lanes: 5,
- maxspeed: '30kmh',
- 'maxspeed:lanes': '30|40|fourty|40|40'
- }
- }).lanes().lanes;
- var maxspeedLanes = lanes.unspecified.map(function (l) {
- return l.maxspeed;
- });
- expect(maxspeedLanes).to.deep.equal([
- null, 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('should parse bicycle:lanes:forward/backward correctly', function() {
- var lanes = iD.Way({
- tags: {
- 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();
- 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'
- ]);
- });
- });
- });
});