From e77a0453afff58470040e51179decaa21a1031a5 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Wed, 18 Jan 2017 20:56:15 +0530
Subject: [PATCH 01/25] interim
---
.vscode/launch.json | 19 ++
css/app.css | 45 ++++
data/presets/fields.json | 2 +-
data/presets/fields/lanes.json | 2 +-
modules/osm/lanes.js | 67 +++++-
modules/ui/field.js | 52 +++++
modules/ui/fields/lanes.js | 381 ++++++++++++++++++++++++++-------
test/spec/osm/lanes.js | 17 +-
8 files changed, 490 insertions(+), 95 deletions(-)
create mode 100644 .vscode/launch.json
create mode 100644 modules/ui/field.js
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000000..064c90f7b3c
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,19 @@
+{
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch Chrome against localhost",
+ "type": "chrome",
+ "request": "launch",
+ "url": "http://localhost:8080/#background=Bing&id=w26283961&map=18.71/12.98164/77.63874",
+ "webRoot": "${workspaceRoot}"
+ },
+ {
+ "name": "Attach to Chrome",
+ "type": "chrome",
+ "request": "attach",
+ "port": 9222,
+ "webRoot": "${workspaceRoot}"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/css/app.css b/css/app.css
index 74874394e32..6e200c65e86 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1221,6 +1221,51 @@ button.save.has-count .count::before {
border-bottom-right-radius: 4px;
}
+/* lanes */
+
+.form-field-lanes {
+
+}
+
+.form-field-lanes > .lanes-info {
+ margin-bottom: 10px;
+}
+
+
+
+.lane-tags > label {
+ position: relative;
+ padding: 5px 10px;
+ display: block;
+ height: 30px;
+ background-color: white;
+ color: #7092FF;
+ cursor: pointer;
+}
+
+.lane-tags > label:hover {
+ background-color: #ececec;
+}
+
+.lane-tags > label:not(:last-child) {
+ border-bottom: 1px solid #ccc;
+}
+
+.lane-tags > label:last-child {
+ border-radius: 0 0 3px 3px;
+}
+
+.lane-tags label > span {
+ display: block;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+}
+
+.lane-tags > label.active {
+ background: #E8EBFF;
+}
+
/* preset form multicombo */
.form-field-multicombo {
diff --git a/data/presets/fields.json b/data/presets/fields.json
index 68ec1dbf4cc..3ad05e74ade 100644
--- a/data/presets/fields.json
+++ b/data/presets/fields.json
@@ -827,7 +827,7 @@
},
"lanes": {
"key": "lanes",
- "type": "number",
+ "type": "lanes",
"label": "Lanes",
"placeholder": "1, 2, 3..."
},
diff --git a/data/presets/fields/lanes.json b/data/presets/fields/lanes.json
index 8b4a10628e2..833f91f4043 100644
--- a/data/presets/fields/lanes.json
+++ b/data/presets/fields/lanes.json
@@ -1,6 +1,6 @@
{
"key": "lanes",
- "type": "number",
+ "type": "lanes",
"label": "Lanes",
"placeholder":"1, 2, 3..."
}
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index f8c136d8d44..5eac22c7c5f 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -72,6 +72,8 @@ export function osmLanes(entity) {
mapToLanesObj(lanesObj, hgvLanes, 'hgv');
mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
+ // TODO: need to make sure forward lanes is consistent across all tags,
+ // eg if psv:lanes:forward is 3 and lanes:forward is 2, changes lanes:forward =3,
return {
metadata: {
count: laneCount,
@@ -89,7 +91,24 @@ export function osmLanes(entity) {
hgvLanes: hgvLanes,
bicyclewayLanes: bicyclewayLanes
},
- lanes: lanesObj
+ lanes: lanesObj,
+ lanesArray: flattenLanesArray(lanesArray(
+ {
+ 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
+ }))
};
}
@@ -169,7 +188,7 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
function parseTurnLanes(tag){
- if (!tag) return;
+ if (!tag) return [];
var validValues = [
'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
@@ -188,7 +207,7 @@ function parseTurnLanes(tag){
function parseMaxspeedLanes(tag, maxspeed) {
- if (!tag) return;
+ if (!tag) return [];
return tag.split('|')
.map(function (s) {
@@ -201,7 +220,7 @@ function parseMaxspeedLanes(tag, maxspeed) {
function parseMiscLanes(tag) {
- if (!tag) return;
+ if (!tag) return [];
var validValues = [
'yes', 'no', 'designated'
@@ -214,9 +233,9 @@ function parseMiscLanes(tag) {
});
}
-
+// TODO: need to append lanes? and make it return an array?
function parseBicycleWay(tag) {
- if (!tag) return;
+ if (!tag) return [];
var validValues = [
'yes', 'no', 'designated', 'lane'
@@ -244,3 +263,39 @@ function mapToLanesObj(lanesObj, data, key) {
lanesObj.unspecified[i][key] = l;
});
}
+
+function flattenLanesArray(lanes) {
+ var order = ['backward', 'forward'];
+ var ret = [].concat(lanes[order[0]], lanes[order[1]]);
+ for (var i = 0; i < ret.length; i++) {
+ ret[i] = _.assign(ret[i] || {}, lanes.unspecified[i]);
+ }
+ return ret;
+}
+
+function lanesArray(lanesData) {
+ var metadata = _.cloneDeep(lanesData);
+ // var arr = new Array(metadata.count);
+ var consideredLaneTags = [ 'busLanes', 'hgvLanes', 'hovLanes', 'maxspeedLanes', 'psvLanes', 'taxiLanes', 'turnLanes' ];
+ var obj = {};
+
+ obj.forward = new Array(metadata.forward);
+ obj.backward = new Array(metadata.backward);
+ // obj.bothways = new Array(metadata.bothways); // jo
+ obj.unspecified = new Array(metadata.count); //_.fill(Array(metadata.count), { });
+
+ consideredLaneTags.forEach(function (laneTag) {
+ var lane = metadata[laneTag];
+ Object.keys(lane).forEach(function (direction) {
+ lane[direction]
+ .forEach(function (tag, i) {
+ if (!obj[direction][i]) obj[direction][i] = {};
+ if (i < obj[direction].length) {
+ obj[direction][i][laneTag] = tag;
+ }
+ });
+ });
+ });
+
+ return obj;
+}
\ No newline at end of file
diff --git a/modules/ui/field.js b/modules/ui/field.js
new file mode 100644
index 00000000000..af817558d47
--- /dev/null
+++ b/modules/ui/field.js
@@ -0,0 +1,52 @@
+import { uiFields } from './fields/index';
+
+function UIField(field, entity, show, context) {
+ field = _.clone(field);
+
+ field.input = uiFields[field.type](field, context)
+ .on('change', function(t, onInput) {
+ dispatch.call('change', field, t, onInput);
+ });
+
+ if (field.input.entity) field.input.entity(entity);
+
+ field.keys = field.keys || [field.key];
+
+ field.show = show;
+
+ field.shown = function() {
+ return field.id === 'name' || field.show || _.some(field.keys, function(key) { return !!tags[key]; });
+ };
+
+ field.modified = function() {
+ var original = context.graph().base().entities[entity.id];
+ return _.some(field.keys, function(key) {
+ return original ? tags[key] !== original.tags[key] : tags[key];
+ });
+ };
+
+ field.revert = function() {
+ var original = context.graph().base().entities[entity.id],
+ t = {};
+ field.keys.forEach(function(key) {
+ t[key] = original ? original.tags[key] : undefined;
+ });
+ return t;
+ };
+
+ field.present = function() {
+ return _.some(field.keys, function(key) {
+ return tags[key];
+ });
+ };
+
+ field.remove = function() {
+ var t = {};
+ field.keys.forEach(function(key) {
+ t[key] = undefined;
+ });
+ return t;
+ };
+
+ return field;
+ }
\ No newline at end of file
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index c2c57b25bc8..63bfcfff914 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -1,126 +1,224 @@
import * as d3 from 'd3';
import { utilRebind } from '../../util/rebind';
import { utilGetDimensions } from '../../util/dimensions';
+import { uiFieldCheck } from './check';
+import _ from 'lodash';
+import { d3combobox } from '../../lib/d3.combobox.js';
+import { utilGetSetValue } from '../../util/get_set_value';
+function validLanes() {
+ return [
+ 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
+ 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
+ ];
+}
+
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
LANE_WIDTH = 40,
LANE_HEIGHT = 200,
wayID,
lanesData;
-
- function lanes(selection) {
- lanesData = context.entity(wayID).lanes();
-
- if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
- selection.call(lanes.off);
- return;
- }
-
+
+ function lanesInfoUI(selection) {
var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
+ var keysConsidered = ['count', 'forward', 'backward', 'maxspeed'];
+ var metadata = lanesData.metadata;
wrap = wrap.enter()
.append('div')
- .attr('class', 'preset-input-wrap')
+ .attr('class', 'cf preset-input-wrap')
+ .append('ul')
.merge(wrap);
- var surface = wrap.selectAll('.surface')
+ var list = wrap.selectAll('ul')
.data([0]);
- var d = utilGetDimensions(wrap);
- var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
+ list = list.enter()
+ .append('ul')
+ .merge(list);
- surface = surface.enter()
- .append('svg')
- .attr('width', d[0])
- .attr('height', 300)
- .attr('class', 'surface')
- .merge(surface);
+ var items = list.selectAll('li')
+ .data(keysConsidered);
- var lanesSelection = surface.selectAll('.lanes')
- .data([0]);
+ // Enter
+ var enter = items.enter()
+ .append('li')
+ .attr('class', function(d) { return 'cf preset-access-' + d; });
+
+ enter
+ .append('span')
+ .attr('class', 'col6 label preset-label-access')
+ .attr('for', function(d) { return 'preset-input-access-' + d; })
+ .text(function(d) { return d; });
- lanesSelection = lanesSelection.enter()
- .append('g')
- .attr('class', 'lanes')
- .merge(lanesSelection);
+ enter
+ .append('div')
+ .attr('class', 'col6 preset-input-access-wrap')
+ .append('input')
+ .attr('type', 'text')
+ .attr('class', 'preset-input-access')
+ .attr('id', function(d) { return 'preset-input-access-' + d; })
+ .each(function(d) {
+ this.value = metadata[d];
+
+ });
- lanesSelection
- .attr('transform', function () {
- return 'translate(' + (freeSpace / 2) + ', 0)';
+ // Update
+ items = items.merge(enter);
+ items.selectAll('input')
+ .property('value', function (d) {
+ return metadata[d];
});
+ items.selectAll('input')
+ .on('change', change)
+ .on('blur', change);
+ }
- var lane = lanesSelection.selectAll('.lane')
- .data(lanesData.lanes);
+ function turnLanesUI(selection) {
+
+
+ var laneTags = selection.selectAll('.lane-tags').data([0]);
- lane.exit()
- .remove();
+
+ laneTags
+ .enter()
+ .append('label')
+ .attr('class','form-label')
+ .text('Turn Lanes');
- var enter = lane.enter()
- .append('g')
- .attr('class', 'lane');
+ var laneTagsEnter = laneTags
+ .enter()
+ .append('div')
+ .attr('class', 'lane-tags cf preset-input-wrap')
+ .classed('checkselect', 'true');
- enter
- .append('g')
- .append('rect')
- .attr('y', 50)
- .attr('width', LANE_WIDTH)
- .attr('height', LANE_HEIGHT);
+ var inputNumber = laneTagsEnter.append('input')
+ .attr('type', 'field.type')
+ .attr('id', 'fieldId')
+ .attr('placeholder', 'inspector.unknown')
+ .attr('type', 'text');
- enter
- .append('g')
- .attr('class', 'forward')
- .append('text')
- .attr('y', 40)
- .attr('x', 14)
- .text('▲');
+ var spinControl = laneTagsEnter.selectAll('.spin-control')
+ .data([0]);
- enter
- .append('g')
- .attr('class', 'bothways')
- .append('text')
- .attr('y', 40)
- .attr('x', 14)
- .text('▲▼');
+ var spinControlEnter = spinControl.enter()
+ .append('div')
+ .attr('class', 'spin-control');
- enter
- .append('g')
- .attr('class', 'backward')
- .append('text')
- .attr('y', 40)
- .attr('x', 14)
- .text('▼');
+ spinControlEnter
+ .append('button')
+ .datum(1)
+ .attr('class', 'increment')
+ .attr('tabindex', -1);
+ spinControlEnter
+ .append('button')
+ .datum(-1)
+ .attr('class', 'decrement')
+ .attr('tabindex', -1);
- lane = lane
- .merge(enter);
+ spinControl = spinControl
+ .merge(spinControlEnter);
- lane
- .attr('transform', function(d) {
- return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
+ spinControl.selectAll('button')
+ .on('click', function(d) {
+ d3.event.preventDefault();
+ var num = parseInt(inputNumber.node().value || 0, 10);
+ if (!isNaN(num) && num + d > 0 && num + d <= lanesData.metadata.count) inputNumber.node().value = num + d;
});
- lane.select('.forward')
- .style('visibility', function(d) {
- return d.direction === 'forward' ? 'visible' : 'hidden';
- });
- lane.select('.bothways')
- .style('visibility', function(d) {
- return d.direction === 'bothways' ? 'visible' : 'hidden';
- });
- lane.select('.backward')
- .style('visibility', function(d) {
- return d.direction === 'backward' ? 'visible' : 'hidden';
- });
+ var label = laneTagsEnter.selectAll('.label')
+ .data(validLanes());
+
+ var labelEnter = label.enter()
+ .append('label');
+
+ labelEnter
+ .append('input')
+ .property('indeterminate', field.type === 'check')
+ .attr('type', 'checkbox')
+ .attr('id', 'preset-input-' + field.id);
+
+ labelEnter
+ .append('span')
+ .text(function (d) { return d;})
+ .attr('class', 'value');
+
+ label = label.merge(labelEnter);
}
+ function lanes(selection) {
+
+ lanesData = context.entity(wayID).lanes();
+ var lanesArray = lanesData.lanesArray;
+
+ if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
+ selection.call(lanes.off);
+ return;
+ }
+
+ var lanesInfo = selection.selectAll('.lanes-info').data([0]);
+ lanesInfo = lanesInfo.enter()
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(lanesInfo);
+ console.log('called', lanesData.metadata);
+ lanesInfoUI(lanesInfo);
+
+ var turnLanes = selection.selectAll('.turn-lanes').data([0]);
+ turnLanes = turnLanes.enter()
+ .append('div')
+ .attr('class', 'turn-lanes')
+ .merge(turnLanes);
+ turnLanesUI(turnLanes);
+
+ var wrap = selection.selectAll('.lane-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'lane-input-wrap')
+ .merge(wrap);
+
+
+ var surface = wrap.selectAll('.surface')
+ .data([0]);
+
+
+ var d = utilGetDimensions(wrap);
+ var freeSpace = d[0] - lanesData.metadata.count * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
+
+
+ }
+
+ function change(d) {
+ var tag = {};
+ if (d === 'count') {
+ tag.lanes = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'forward') {
+ tag['lanes:forward'] = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'backward') {
+ tag['lanes:backward'] = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'maxspeed') {
+ tag['maxspeed:lanes'] = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'oneway') {
+ tag.oneway = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ dispatch.call('change', this, tag);
+ }
+
lanes.entity = function(_) {
if (!wayID || wayID !== _.id) {
wayID = _.id;
@@ -131,5 +229,130 @@ export function uiFieldLanes(field, context) {
lanes.focus = function() {};
lanes.off = function() {};
+ function laneSvg() {
+ // surface = surface.enter()
+ // .append('svg')
+ // .attr('width', d[0])
+ // .attr('height', 300)
+ // .attr('class', 'surface')
+ // .merge(surface);
+
+
+ // var lanesSelection = surface.selectAll('.lanes')
+ // .data([0]);
+
+ // lanesSelection = lanesSelection.enter()
+ // .append('g')
+ // .attr('class', 'lanes')
+ // .merge(lanesSelection);
+
+ // lanesSelection
+ // .attr('transform', function () {
+ // return 'translate(' + (freeSpace / 2) + ', 0)';
+ // });
+
+
+ // // var lanesArray =
+ // var lane = lanesSelection.selectAll('.lane')
+ // .data(new Array(lanesData.metadata.count));
+
+ // lane.exit()
+ // .remove();
+
+ // var enter = lane.enter()
+ // .append('g')
+ // .attr('class', 'lane');
+
+ // enter
+ // .append('g')
+ // .append('rect')
+ // .attr('y', 50)
+ // .attr('width', LANE_WIDTH)
+ // .attr('height', LANE_HEIGHT)
+ // .attr('transform', function (d, i) {
+ // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
+ // });
+
+ // enter
+ // .append('g')
+ // .attr('class', 'forward')
+ // .append('text')
+ // .attr('y', 40)
+ // .attr('x', 14)
+ // .text('▲')
+ // .attr('transform', function (d, i) {
+ // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
+ // });
+
+ // enter
+ // .append('g')
+ // .attr('class', 'bothways')
+ // .append('text')
+ // .attr('y', 40)
+ // .attr('x', 14)
+ // .text('▲▼')
+ // .attr('transform', function (d, i) {
+ // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
+ // });
+
+ // enter
+ // .append('g')
+ // .attr('class', 'backward')
+ // .append('text')
+ // .attr('y', 40)
+ // .attr('x', 14)
+ // .text('▼')
+ // .attr('transform', function (d, i) {
+ // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
+ // });
+
+
+ // lane = lane
+ // .merge(enter);
+
+ // lane
+ // .attr('transform', function(d, i) {
+ // return 'translate(' + (LANE_WIDTH * i * 1.5) + ', 0)';
+ // });
+
+
+ // var te = wrap.selectAll('.lane-text').data([0]);
+
+ // te
+ // .enter()
+ // .append('div')
+ // .attr('class', 'lane-text')
+ // .text('check 123');
+
+ // var sel = wrap.selectAll('.lane-text');
+
+ // sel.on('click', function() {
+ // var t = {};
+ // t['kushan'] = 'joshi' + Math.random();
+ // dispatch.call('change', this, t);
+ // d3.event.stopPropagation();
+
+ // });
+
+
+
+
+ // te.exit().remove();
+
+ // lane.select('.forward')
+ // .style('visibility', function(d) {
+ // return d.direction === 'forward' ? 'visible' : 'hidden';
+ // });
+
+ // lane.select('.bothways')
+ // .style('visibility', function(d) {
+ // return d.direction === 'bothways' ? 'visible' : 'hidden';
+ // });
+
+ // lane.select('.backward')
+ // .style('visibility', function(d) {
+ // return d.direction === 'backward' ? 'visible' : 'hidden';
+ // });
+ }
return utilRebind(lanes, dispatch, 'on');
}
diff --git a/test/spec/osm/lanes.js b/test/spec/osm/lanes.js
index 4a072a28c9e..c704af8bace 100644
--- a/test/spec/osm/lanes.js
+++ b/test/spec/osm/lanes.js
@@ -1,4 +1,4 @@
-describe('iD.Lanes', function() {
+describe.only('iD.Lanes', function() {
describe('default lane tags', function() {
@@ -271,6 +271,7 @@ describe('iD.Lanes', function() {
backward: 0,
bothways: 0
});
+
});
it('skips provided lanes:backward value when oneway=yes', function() {
@@ -624,7 +625,7 @@ describe('iD.Lanes', function() {
]);
});
- it('turnLanes is undefined when not present', function() {
+ it('turnLanes is [] when not present', function() {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -634,14 +635,14 @@ describe('iD.Lanes', function() {
}).lanes().metadata;
expect(metadata.turnLanes.unspecified)
- .to.equal(undefined);
+ .to.deep.equal([]);
expect(metadata.turnLanes.forward)
- .to.equal(undefined);
+ .to.deep.equal([]);
expect(metadata.turnLanes.backward)
- .to.equal(undefined);
+ .to.deep.equal([]);
});
- it('turnLanes.forward and turnLanes.backward are both undefined when both are not provided', function() {
+ it('turnLanes.forward and turnLanes.backward are both [] when both are not provided', function() {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -654,9 +655,9 @@ describe('iD.Lanes', function() {
expect(metadata.turnLanes.unspecified)
.to.deep.equal([['through'], ['through', 'slight_right']]);
expect(metadata.turnLanes.forward)
- .to.equal(undefined);
+ .to.deep.equal([]);
expect(metadata.turnLanes.backward)
- .to.equal(undefined);
+ .to.deep.equal([]);
});
it('parses turnLane correctly when lanes:both_ways=1', function() {
From 8b6ac28624f8a8e49a972c91fdb0292431d7c333 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 19 Jan 2017 09:46:26 +0530
Subject: [PATCH 02/25] interim 2
---
css/app.css | 20 +++++++-
modules/ui/fields/lanes.js | 95 +++++++++++++++-----------------------
2 files changed, 55 insertions(+), 60 deletions(-)
diff --git a/css/app.css b/css/app.css
index 6e200c65e86..7a6f1966f14 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1227,11 +1227,29 @@ button.save.has-count .count::before {
}
-.form-field-lanes > .lanes-info {
+.form-field-lanes .lanes-info {
margin-bottom: 10px;
}
+.form-field-lanes .preset-input-wrap input {
+ border-radius: 0;
+ border-width: 0;
+ border-bottom-width: 1px;
+}
+
+.form-field-lanes .preset-input-lanes-wrap input {
+ border-radius: 0;
+ border-width: 0;
+ border-left-width: 1px;
+}
+.form-field-lanes .preset-input-wrap li {
+ border-bottom: 1px solid #CCC;
+}
+
+.form-field-lanes .preset-input-wrap li:last-child {
+ border-bottom: 0;
+}
.lane-tags > label {
position: relative;
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 63bfcfff914..ded355ed97d 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -7,17 +7,17 @@ import { d3combobox } from '../../lib/d3.combobox.js';
import { utilGetSetValue } from '../../util/get_set_value';
-function validLanes() {
- return [
+var validLanes = [
'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
];
-}
+
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
LANE_WIDTH = 40,
LANE_HEIGHT = 200,
+ currentLane = 0,
wayID,
lanesData;
@@ -29,7 +29,7 @@ export function uiFieldLanes(field, context) {
wrap = wrap.enter()
.append('div')
- .attr('class', 'cf preset-input-wrap')
+ .attr('class', 'preset-input-wrap')
.append('ul')
.merge(wrap);
@@ -51,17 +51,17 @@ export function uiFieldLanes(field, context) {
enter
.append('span')
- .attr('class', 'col6 label preset-label-access')
- .attr('for', function(d) { return 'preset-input-access-' + d; })
+ .attr('class', 'col6 label preset-label-')
+ .attr('for', function(d) { return 'preset-input-' + d; })
.text(function(d) { return d; });
enter
.append('div')
- .attr('class', 'col6 preset-input-access-wrap')
+ .attr('class', 'col6 preset-input-lanes-wrap')
.append('input')
.attr('type', 'text')
- .attr('class', 'preset-input-access')
- .attr('id', function(d) { return 'preset-input-access-' + d; })
+ .attr('class', 'preset-input-lanes')
+ .attr('id', function(d) { return 'preset-input-lanes-' + d; })
.each(function(d) {
this.value = metadata[d];
@@ -71,6 +71,7 @@ export function uiFieldLanes(field, context) {
items = items.merge(enter);
items.selectAll('input')
.property('value', function (d) {
+ console.log('there');
return metadata[d];
});
@@ -80,62 +81,27 @@ export function uiFieldLanes(field, context) {
}
function turnLanesUI(selection) {
-
-
- var laneTags = selection.selectAll('.lane-tags').data([0]);
-
-
- laneTags
+ selection.selectAll('.form-label')
+ .data([0])
.enter()
.append('label')
.attr('class','form-label')
.text('Turn Lanes');
- var laneTagsEnter = laneTags
- .enter()
- .append('div')
- .attr('class', 'lane-tags cf preset-input-wrap')
- .classed('checkselect', 'true');
-
- var inputNumber = laneTagsEnter.append('input')
- .attr('type', 'field.type')
- .attr('id', 'fieldId')
- .attr('placeholder', 'inspector.unknown')
- .attr('type', 'text');
-
- var spinControl = laneTagsEnter.selectAll('.spin-control')
+ var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
-
- var spinControlEnter = spinControl.enter()
+ var metadata = lanesData.metadata;
+
+ wrap = wrap.enter()
.append('div')
- .attr('class', 'spin-control');
-
- spinControlEnter
- .append('button')
- .datum(1)
- .attr('class', 'increment')
- .attr('tabindex', -1);
-
- spinControlEnter
- .append('button')
- .datum(-1)
- .attr('class', 'decrement')
- .attr('tabindex', -1);
-
- spinControl = spinControl
- .merge(spinControlEnter);
-
- spinControl.selectAll('button')
- .on('click', function(d) {
- d3.event.preventDefault();
- var num = parseInt(inputNumber.node().value || 0, 10);
- if (!isNaN(num) && num + d > 0 && num + d <= lanesData.metadata.count) inputNumber.node().value = num + d;
- });
-
+ .attr('class', 'preset-input-wrap checkselect')
+ // .append('ul');
+ // // .merge(wrap);
+
- var label = laneTagsEnter.selectAll('.label')
- .data(validLanes());
+ var label = wrap.selectAll('.label')
+ .data(validLanes);
var labelEnter = label.enter()
.append('label');
@@ -151,7 +117,11 @@ export function uiFieldLanes(field, context) {
.text(function (d) { return d;})
.attr('class', 'value');
- label = label.merge(labelEnter);
+ // label = label.merge(labelEnter);
+
+ selection.selectAll('input').property('checked', function () {
+ return Math.random() > 0.4;
+ });
}
@@ -176,8 +146,12 @@ export function uiFieldLanes(field, context) {
var turnLanes = selection.selectAll('.turn-lanes').data([0]);
turnLanes = turnLanes.enter()
.append('div')
- .attr('class', 'turn-lanes')
+ .attr('class', 'turn-lanes localized-wrap')
+ // .append('div')
+ // .attr('class', 'entry')
+ // .attr('style', 'margin-top: 10px;opacity: 1;overflow: visible;')
.merge(turnLanes);
+
turnLanesUI(turnLanes);
var wrap = selection.selectAll('.lane-input-wrap')
@@ -200,6 +174,7 @@ export function uiFieldLanes(field, context) {
}
function change(d) {
+ console.log('hola')
var tag = {};
if (d === 'count') {
tag.lanes = utilGetSetValue(d3.select(this)) || undefined;
@@ -225,7 +200,9 @@ export function uiFieldLanes(field, context) {
}
};
- lanes.tags = function() {};
+ lanes.tags = function(tags) {
+ console.log(tags, field.key, 'lolololoxsxs');
+ };
lanes.focus = function() {};
lanes.off = function() {};
From 40fa12f0d9aeae33c63d8b78ef5e0b135ad85259 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 19 Jan 2017 12:32:32 +0530
Subject: [PATCH 03/25] select lane part 1
---
css/app.css | 6 +++
modules/ui/fields/lanes.js | 79 ++++++++++++++++++++++++++++++--------
2 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/css/app.css b/css/app.css
index 7a6f1966f14..b3e7792ee2d 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1251,6 +1251,12 @@ button.save.has-count .count::before {
border-bottom: 0;
}
+.form-field-lanes .entry {
+ margin-top: 10px;
+ opacity: 1;
+ overflow: visible;
+}
+
.lane-tags > label {
position: relative;
padding: 5px 10px;
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index ded355ed97d..1508405a8a7 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -64,14 +64,12 @@ export function uiFieldLanes(field, context) {
.attr('id', function(d) { return 'preset-input-lanes-' + d; })
.each(function(d) {
this.value = metadata[d];
-
});
// Update
items = items.merge(enter);
items.selectAll('input')
.property('value', function (d) {
- console.log('there');
return metadata[d];
});
@@ -85,19 +83,15 @@ export function uiFieldLanes(field, context) {
.data([0])
.enter()
.append('label')
- .attr('class','form-label')
+ .attr('class','form-label entry')
.text('Turn Lanes');
var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
- var metadata = lanesData.metadata;
wrap = wrap.enter()
.append('div')
- .attr('class', 'preset-input-wrap checkselect')
- // .append('ul');
- // // .merge(wrap);
-
+ .attr('class', 'lane-tags preset-input-wrap checkselect')
var label = wrap.selectAll('.label')
@@ -117,11 +111,55 @@ export function uiFieldLanes(field, context) {
.text(function (d) { return d;})
.attr('class', 'value');
- // label = label.merge(labelEnter);
-
- selection.selectAll('input').property('checked', function () {
+ var input = selection.selectAll('input');
+ input.property('checked', function () {
return Math.random() > 0.4;
});
+
+ input.on('click', function() {
+ var key = utilGetSetValue(d3.select(this)) || undefined;
+ console.log(key);
+ d3.event.stopPropagation();
+ });
+ }
+
+ function laneSelectorUI(selection) {
+ var items;
+ selection.selectAll('.form-label')
+ .data([0])
+ .enter()
+ .append('label')
+ .attr('class','form-label entry')
+ .text('Select Lane');
+
+ var wrap = selection.selectAll('.preset-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'lane-tags preset-input-wrap checkselect')
+ .merge(wrap);
+
+ var list = wrap.selectAll('ul')
+ .data([0]);
+
+ list = list.enter()
+ .append('ul')
+ .merge(list);
+
+ items = list.selectAll('li')
+ .data(_.fill(Array(lanesData.metadata.count), 0).map(function (n, i) {
+ return i;
+ }));
+
+ items.enter()
+ .append('li')
+ .append('span').text(function (d) {
+ return d;
+ });
+
+ items.exit().remove();
+
}
@@ -140,19 +178,26 @@ export function uiFieldLanes(field, context) {
.append('div')
.attr('class', 'lanes-info')
.merge(lanesInfo);
- console.log('called', lanesData.metadata);
- lanesInfoUI(lanesInfo);
+ lanesInfo.call(lanesInfoUI);
+
+ var laneSelector = selection.selectAll('.lanes-selector').data([0]);
+
+ laneSelector = laneSelector.enter()
+ .append('div')
+ .attr('class', 'lanes-selector localized-wrap')
+ .merge(laneSelector);
+
+ laneSelector.call(laneSelectorUI);
+
var turnLanes = selection.selectAll('.turn-lanes').data([0]);
turnLanes = turnLanes.enter()
.append('div')
.attr('class', 'turn-lanes localized-wrap')
- // .append('div')
- // .attr('class', 'entry')
- // .attr('style', 'margin-top: 10px;opacity: 1;overflow: visible;')
.merge(turnLanes);
+ turnLanes.call(turnLanesUI);
+
- turnLanesUI(turnLanes);
var wrap = selection.selectAll('.lane-input-wrap')
.data([0]);
From 8b8522f6d2e2f43e2ea16f2337d9ab9299b45472 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 19 Jan 2017 17:56:36 +0530
Subject: [PATCH 04/25] interim 3
---
.eslintrc | 2 +-
css/app.css | 36 ++++
modules/osm/lanes.js | 8 +-
modules/ui/field.js | 52 -----
modules/ui/fields/lanes.js | 427 ++++++++++++++++++++-----------------
5 files changed, 270 insertions(+), 255 deletions(-)
delete mode 100644 modules/ui/field.js
diff --git a/.eslintrc b/.eslintrc
index 0e0fbd05145..5a358c79ab8 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -17,7 +17,7 @@
"rules": {
"dot-notation": "error",
"eqeqeq": ["error", "smart"],
- "indent": ["off", 4],
+ "indent": ["error", 4],
"keyword-spacing": "error",
"linebreak-style": ["error", "unix"],
"no-caller": "error",
diff --git a/css/app.css b/css/app.css
index b3e7792ee2d..f38d52727b4 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1257,6 +1257,42 @@ button.save.has-count .count::before {
overflow: visible;
}
+.lane-selector ul {
+ display: flex;
+ flex-direction: row;
+
+}
+
+.lane-selector .lane-item {
+ cursor: pointer;
+ display: flex;
+ flex-grow: 1;
+ border-right: 1px solid #ccc;
+ border-bottom: 0;
+ flex-direction: column;
+ align-items: center;
+ background-color: white;
+}
+
+.lane-selector .lane-item.active {
+ background-color: #E8EBFF;
+}
+.lane-selector .lane-item.active:hover {
+ background-color: #E8EBFF;
+}
+.lane-selector .lane-item:hover {
+ background-color: #ececec;
+}
+
+.lane-selector .lane-item:last-child {
+ border-right: 0;
+}
+
+.lane-selector .lane-item span {
+ height: 30px;
+ padding: 5px 10px 5px 10px;
+}
+
.lane-tags > label {
position: relative;
padding: 5px 10px;
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 5eac22c7c5f..78219dccea4 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -89,7 +89,9 @@ export function osmLanes(entity) {
taxiLanes: taxiLanes,
hovLanes: hovLanes,
hgvLanes: hgvLanes,
- bicyclewayLanes: bicyclewayLanes
+ bicyclewayLanes: bicyclewayLanes,
+ leftHandDrive: false,
+ reverse: parseInt(tags.oneway, 10) === -1
},
lanes: lanesObj,
lanesArray: flattenLanesArray(lanesArray(
@@ -107,7 +109,9 @@ export function osmLanes(entity) {
taxiLanes: taxiLanes,
hovLanes: hovLanes,
hgvLanes: hgvLanes,
- bicyclewayLanes: bicyclewayLanes
+ bicyclewayLanes: bicyclewayLanes,
+ leftHandDrive: false,
+ reverse: parseInt(tags.oneway, 10) === -1
}))
};
}
diff --git a/modules/ui/field.js b/modules/ui/field.js
deleted file mode 100644
index af817558d47..00000000000
--- a/modules/ui/field.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import { uiFields } from './fields/index';
-
-function UIField(field, entity, show, context) {
- field = _.clone(field);
-
- field.input = uiFields[field.type](field, context)
- .on('change', function(t, onInput) {
- dispatch.call('change', field, t, onInput);
- });
-
- if (field.input.entity) field.input.entity(entity);
-
- field.keys = field.keys || [field.key];
-
- field.show = show;
-
- field.shown = function() {
- return field.id === 'name' || field.show || _.some(field.keys, function(key) { return !!tags[key]; });
- };
-
- field.modified = function() {
- var original = context.graph().base().entities[entity.id];
- return _.some(field.keys, function(key) {
- return original ? tags[key] !== original.tags[key] : tags[key];
- });
- };
-
- field.revert = function() {
- var original = context.graph().base().entities[entity.id],
- t = {};
- field.keys.forEach(function(key) {
- t[key] = original ? original.tags[key] : undefined;
- });
- return t;
- };
-
- field.present = function() {
- return _.some(field.keys, function(key) {
- return tags[key];
- });
- };
-
- field.remove = function() {
- var t = {};
- field.keys.forEach(function(key) {
- t[key] = undefined;
- });
- return t;
- };
-
- return field;
- }
\ No newline at end of file
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 1508405a8a7..a8dd0584eae 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -20,224 +20,251 @@ export function uiFieldLanes(field, context) {
currentLane = 0,
wayID,
lanesData;
-
- function lanesInfoUI(selection) {
- var wrap = selection.selectAll('.preset-input-wrap')
- .data([0]);
- var keysConsidered = ['count', 'forward', 'backward', 'maxspeed'];
- var metadata = lanesData.metadata;
-
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'preset-input-wrap')
- .append('ul')
- .merge(wrap);
-
- var list = wrap.selectAll('ul')
- .data([0]);
-
- list = list.enter()
- .append('ul')
- .merge(list);
-
-
- var items = list.selectAll('li')
- .data(keysConsidered);
-
- // Enter
- var enter = items.enter()
- .append('li')
- .attr('class', function(d) { return 'cf preset-access-' + d; });
-
- enter
- .append('span')
- .attr('class', 'col6 label preset-label-')
- .attr('for', function(d) { return 'preset-input-' + d; })
- .text(function(d) { return d; });
-
- enter
- .append('div')
- .attr('class', 'col6 preset-input-lanes-wrap')
- .append('input')
- .attr('type', 'text')
- .attr('class', 'preset-input-lanes')
- .attr('id', function(d) { return 'preset-input-lanes-' + d; })
- .each(function(d) {
- this.value = metadata[d];
- });
- // Update
- items = items.merge(enter);
- items.selectAll('input')
- .property('value', function (d) {
- return metadata[d];
- });
+ function lanes(selection) {
+ lanesData = context.entity(wayID).lanes();
+ var lanesArray = lanesData.lanesArray;
+ window.lanesData = lanesData;
+ if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
+ selection.call(lanes.off);
+ return;
+ }
+
+ var lanesInfo = selection.selectAll('.lanes-info').data([0]);
+ lanesInfo = lanesInfo.enter()
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(lanesInfo);
+ lanesInfo.call(lanesInfoUI);
+
+ var laneSelector = selection.selectAll('.lane-selector').data([0]);
+
+ laneSelector = laneSelector.enter()
+ .append('div')
+ .attr('class', 'lane-selector localized-wrap')
+ .merge(laneSelector);
+
+ laneSelector.call(laneSelectorUI);
+
+ var turnLanes = selection.selectAll('.turn-lanes').data([0]);
+ turnLanes = turnLanes.enter()
+ .append('div')
+ .attr('class', 'turn-lanes localized-wrap')
+ .merge(turnLanes);
+ turnLanes.call(turnLanesUI);
+
+ var wrap = selection.selectAll('.lane-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'lane-input-wrap')
+ .merge(wrap);
+
+ var surface = wrap.selectAll('.surface')
+ .data([0]);
- items.selectAll('input')
- .on('change', change)
- .on('blur', change);
- }
+ var d = utilGetDimensions(wrap);
+ var freeSpace = d[0] - lanesData.metadata.count * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
- function turnLanesUI(selection) {
- selection.selectAll('.form-label')
- .data([0])
- .enter()
- .append('label')
- .attr('class','form-label entry')
- .text('Turn Lanes');
+ function render() {
+ if (context.hasEntity(wayID)) {
+ lanes(selection);
+ }
+ }
- var wrap = selection.selectAll('.preset-input-wrap')
- .data([0]);
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'lane-tags preset-input-wrap checkselect')
-
-
- var label = wrap.selectAll('.label')
- .data(validLanes);
-
- var labelEnter = label.enter()
- .append('label');
-
- labelEnter
- .append('input')
- .property('indeterminate', field.type === 'check')
- .attr('type', 'checkbox')
- .attr('id', 'preset-input-' + field.id);
-
- labelEnter
- .append('span')
- .text(function (d) { return d;})
- .attr('class', 'value');
-
- var input = selection.selectAll('input');
- input.property('checked', function () {
- return Math.random() > 0.4;
- });
-
- input.on('click', function() {
- var key = utilGetSetValue(d3.select(this)) || undefined;
- console.log(key);
- d3.event.stopPropagation();
- });
- }
-
- function laneSelectorUI(selection) {
- var items;
- selection.selectAll('.form-label')
- .data([0])
- .enter()
- .append('label')
- .attr('class','form-label entry')
- .text('Select Lane');
-
- var wrap = selection.selectAll('.preset-input-wrap')
- .data([0]);
+ function lanesInfoUI(selection) {
+ var wrap = selection.selectAll('.preset-input-wrap')
+ .data([0]);
+ var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'lane-tags preset-input-wrap checkselect')
- .merge(wrap);
-
- var list = wrap.selectAll('ul')
- .data([0]);
+ var metadata = lanesData.metadata;
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'preset-input-wrap')
+ .append('ul')
+ .merge(wrap);
+
+ var list = wrap.selectAll('ul')
+ .data([0]);
+
+ list = list.enter()
+ .append('ul')
+ .merge(list);
+
+
+ var items = list.selectAll('li')
+ .data(keysConsidered);
+
+ // Enter
+ var enter = items.enter()
+ .append('li')
+ .attr('class', function(d) { return 'cf preset-access-' + d; });
+
+ enter
+ .append('span')
+ .attr('class', 'col6 label preset-label-')
+ .attr('for', function(d) { return 'preset-input-' + d; })
+ .text(function(d) { return d; });
+
+ enter
+ .append('div')
+ .attr('class', 'col6 preset-input-lanes-wrap')
+ .append('input')
+ .attr('type', 'text')
+ .attr('class', 'preset-input-lanes')
+ .attr('id', function(d) { return 'preset-input-lanes-' + d; })
+ .each(function(d) {
+ this.value = metadata[d];
+ });
+
+ // Update
+ items = items.merge(enter);
+ items.selectAll('input')
+ .property('value', function (d) {
+ return metadata[d];
+ });
- list = list.enter()
- .append('ul')
- .merge(list);
+ items.selectAll('input')
+ .on('change', _.debounce(change, 700))
+ .on('blur', _.debounce(change, 700));
+
+ function change(d) {
+ console.log('hola');
+ var tag = {};
+ if (d === 'count') {
+ tag.lanes = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'forward') {
+ tag['lanes:forward'] = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'backward') {
+ tag['lanes:backward'] = utilGetSetValue(d3.select(this)) || undefined;
+ }
+ if (d === 'reverse') {
+ if (utilGetSetValue(d3.select(this)) === 'true') {
+ tag.oneway = '-1';
+ } else {
+ tag.oneway = undefined;
+ }
+ }
+ console.log(tag);
+ dispatch.call('change', this, tag);
+ }
+ }
- items = list.selectAll('li')
- .data(_.fill(Array(lanesData.metadata.count), 0).map(function (n, i) {
- return i;
- }));
-
- items.enter()
- .append('li')
- .append('span').text(function (d) {
- return d;
+ function turnLanesUI(selection) {
+ var lanesArray = lanesData.lanesArray;
+ selection.selectAll('.form-label')
+ .data([0])
+ .enter()
+ .append('label')
+ .attr('class','form-label entry')
+ .text('Turn Lanes');
+
+ var wrap = selection.selectAll('.preset-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'lane-tags preset-input-wrap checkselect');
+
+
+ var label = wrap.selectAll('.label')
+ .data(validLanes);
+
+ var labelEnter = label.enter()
+ .append('label');
+
+ labelEnter
+ .append('input')
+ .property('indeterminate', field.type === 'check')
+ .attr('type', 'checkbox')
+ .attr('id', 'preset-input-' + field.id);
+
+ labelEnter
+ .append('span')
+ .text(function (d) { return d;})
+ .attr('class', 'value');
+ console.log(lanesArray[currentLane]);
+ var input = selection.selectAll('input');
+ input.property('checked', function (d) {
+ if (_.isArray(lanesArray[currentLane].turnLanes)) {
+ return lanesArray[currentLane].turnLanes.filter(function (el) {
+ return el === d;
+ }).length === 1;
+ }
+ return false;
+ // return Math.random() > 0.4;
});
- items.exit().remove();
-
- }
-
-
- function lanes(selection) {
-
- lanesData = context.entity(wayID).lanes();
- var lanesArray = lanesData.lanesArray;
-
- if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
- selection.call(lanes.off);
- return;
+ input.on('click', function() {
+ var key = utilGetSetValue(d3.select(this)) || undefined;
+ console.log(key);
+ d3.event.stopPropagation();
+ });
}
- var lanesInfo = selection.selectAll('.lanes-info').data([0]);
- lanesInfo = lanesInfo.enter()
- .append('div')
- .attr('class', 'lanes-info')
- .merge(lanesInfo);
- lanesInfo.call(lanesInfoUI);
-
- var laneSelector = selection.selectAll('.lanes-selector').data([0]);
-
- laneSelector = laneSelector.enter()
- .append('div')
- .attr('class', 'lanes-selector localized-wrap')
- .merge(laneSelector);
-
- laneSelector.call(laneSelectorUI);
-
-
- var turnLanes = selection.selectAll('.turn-lanes').data([0]);
- turnLanes = turnLanes.enter()
- .append('div')
- .attr('class', 'turn-lanes localized-wrap')
- .merge(turnLanes);
- turnLanes.call(turnLanesUI);
-
-
-
- var wrap = selection.selectAll('.lane-input-wrap')
- .data([0]);
-
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'lane-input-wrap')
- .merge(wrap);
+ function laneSelectorUI(selection) {
+ var items;
+ selection.selectAll('.form-label')
+ .data([0])
+ .enter()
+ .append('label')
+ .attr('class','form-label entry')
+ .text('Select Lane');
+
+ var wrap = selection.selectAll('.preset-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'lane-tags preset-input-wrap checkselect')
+ .merge(wrap);
-
- var surface = wrap.selectAll('.surface')
- .data([0]);
+ var list = wrap.selectAll('ul')
+ .data([0]);
+ list = list.enter()
+ .append('ul')
+ .merge(list);
- var d = utilGetDimensions(wrap);
- var freeSpace = d[0] - lanesData.metadata.count * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
+ items = list.selectAll('.lane-item')
+ .data(_.fill(Array(lanesData.metadata.count), 0).map(function (n, i) {
+ return i;
+ }));
+
+ items.enter()
+ .append('div')
+ .attr('class', 'lane-item')
+ .attr('id', function (d) {
+ return 'lane-' + d;
+ })
+ .classed('active', function (d) {
+ return d === currentLane;
+ })
+ .append('span')
+ .text(function (d) {
+ return d + 1;
+ });
+
+ var input = selection.selectAll('.lane-item');
+
+ input.on('click', function () {
+ var lane = parseInt(d3.select(this).selectAll('span').text(), 10) - 1;
+ selection.select('#lane-' + currentLane).classed('active', false);
+ currentLane = lane;
+ d3.select(this).classed('active', true);
+ render();
+ });
+ items.exit().remove();
+ }
-
}
- function change(d) {
- console.log('hola')
- var tag = {};
- if (d === 'count') {
- tag.lanes = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'forward') {
- tag['lanes:forward'] = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'backward') {
- tag['lanes:backward'] = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'maxspeed') {
- tag['maxspeed:lanes'] = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'oneway') {
- tag.oneway = utilGetSetValue(d3.select(this)) || undefined;
- }
- dispatch.call('change', this, tag);
- }
+
lanes.entity = function(_) {
if (!wayID || wayID !== _.id) {
From bf0e8b42e5b510254fa5ec81447cd3c3a4b4c7ea Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sat, 21 Jan 2017 10:19:02 +0530
Subject: [PATCH 05/25] add turn selector UI?
---
.eslintrc | 2 +-
development_server.js | 14 +-
modules/osm/lanes.js | 32 +---
modules/ui/entity_editor.js | 1 -
modules/ui/fields/lanes.js | 291 ++++++++++++++++++++++++++----------
5 files changed, 223 insertions(+), 117 deletions(-)
diff --git a/.eslintrc b/.eslintrc
index 5a358c79ab8..0e0fbd05145 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -17,7 +17,7 @@
"rules": {
"dot-notation": "error",
"eqeqeq": ["error", "smart"],
- "indent": ["error", 4],
+ "indent": ["off", 4],
"keyword-spacing": "error",
"linebreak-style": ["error", "unix"],
"no-caller": "error",
diff --git a/development_server.js b/development_server.js
index c8b40bc538a..4060527c5b3 100644
--- a/development_server.js
+++ b/development_server.js
@@ -10,8 +10,8 @@ var gaze = require('gaze');
var ecstatic = require('ecstatic');
var building = false;
-
-
+var cache;
+var cacheCount = 0;
if (process.argv[2] === 'develop') {
build();
@@ -56,7 +56,8 @@ function build() {
}),
commonjs(),
json()
- ]
+ ],
+ cache: cache
}).then(function (bundle) {
bundle.write({
@@ -67,7 +68,12 @@ function build() {
});
building = false;
console.timeEnd('Rebuilt');
-
+ cache = bundle;
+ if (cacheCount === 5) {
+ cache = undefined;
+ cacheCount = 0;
+ }
+ cacheCount++;
}, function(err) {
building = false;
console.error(err);
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 78219dccea4..8f2c72644b4 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -93,27 +93,8 @@ export function osmLanes(entity) {
leftHandDrive: false,
reverse: parseInt(tags.oneway, 10) === -1
},
- lanes: lanesObj,
- lanesArray: flattenLanesArray(lanesArray(
- {
- 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,
- leftHandDrive: false,
- reverse: parseInt(tags.oneway, 10) === -1
- }))
- };
+ lanes: lanesObj
+ };
}
@@ -268,15 +249,6 @@ function mapToLanesObj(lanesObj, data, key) {
});
}
-function flattenLanesArray(lanes) {
- var order = ['backward', 'forward'];
- var ret = [].concat(lanes[order[0]], lanes[order[1]]);
- for (var i = 0; i < ret.length; i++) {
- ret[i] = _.assign(ret[i] || {}, lanes.unspecified[i]);
- }
- return ret;
-}
-
function lanesArray(lanesData) {
var metadata = _.cloneDeep(lanesData);
// var arr = new Array(metadata.count);
diff --git a/modules/ui/entity_editor.js b/modules/ui/entity_editor.js
index e5fc7bb9070..ffe2b871650 100644
--- a/modules/ui/entity_editor.js
+++ b/modules/ui/entity_editor.js
@@ -180,7 +180,6 @@ export function uiEntityEditor(context) {
var blacklist = ['description', 'note', 'fixme'];
if (_.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
-
var cleaned = v.split(';')
.map(function(s) { return s.trim(); })
.join(keepSpaces(k) ? '; ' : ';');
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index a8dd0584eae..e84e7c7606a 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -8,66 +8,72 @@ import { utilGetSetValue } from '../../util/get_set_value';
var validLanes = [
- 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
- 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
- ];
+ 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
+ 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
+];
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
LANE_WIDTH = 40,
LANE_HEIGHT = 200,
+ // TODO: currentLane if big like 6 goes crazy if other wayID has less than 6 lanes
currentLane = 0,
+ curDirection = 'unspecified',
wayID,
lanesData;
function lanes(selection) {
- lanesData = context.entity(wayID).lanes();
- var lanesArray = lanesData.lanesArray;
- window.lanesData = lanesData;
- if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
- selection.call(lanes.off);
- return;
- }
+ console.log('hollaa mee', currentLane, curDirection)
+ lanesData = context.entity(wayID).lanes();
+ var lanesArray = lanesData.lanesArray;
+ window.lanesData = lanesData;
+ window.currentLane = currentLane;
+ window.curDirection = curDirection;
+
+ if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
+ selection.call(lanes.off);
+ return;
+ }
- var lanesInfo = selection.selectAll('.lanes-info').data([0]);
- lanesInfo = lanesInfo.enter()
+ var lanesInfo = selection.selectAll('.lanes-info').data([0]);
+ lanesInfo = lanesInfo.enter()
.append('div')
.attr('class', 'lanes-info')
.merge(lanesInfo);
- lanesInfo.call(lanesInfoUI);
+ lanesInfo.call(lanesInfoUI);
- var laneSelector = selection.selectAll('.lane-selector').data([0]);
+ var laneSelector = selection.selectAll('.lane-selector').data([0]);
- laneSelector = laneSelector.enter()
+ laneSelector = laneSelector.enter()
.append('div')
.attr('class', 'lane-selector localized-wrap')
.merge(laneSelector);
- laneSelector.call(laneSelectorUI);
+ laneSelector.call(laneSelectorUI);
- var turnLanes = selection.selectAll('.turn-lanes').data([0]);
- turnLanes = turnLanes.enter()
+ var turnLanes = selection.selectAll('.turn-lanes').data([0]);
+ turnLanes = turnLanes.enter()
.append('div')
.attr('class', 'turn-lanes localized-wrap')
.merge(turnLanes);
- turnLanes.call(turnLanesUI);
+ turnLanes.call(turnLanesUI);
- var wrap = selection.selectAll('.lane-input-wrap')
+ var wrap = selection.selectAll('.lane-input-wrap')
.data([0]);
- wrap = wrap.enter()
+ wrap = wrap.enter()
.append('div')
.attr('class', 'lane-input-wrap')
.merge(wrap);
- var surface = wrap.selectAll('.surface')
+ var surface = wrap.selectAll('.surface')
.data([0]);
var d = utilGetDimensions(wrap);
var freeSpace = d[0] - lanesData.metadata.count * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
- function render() {
+ function render() {
if (context.hasEntity(wayID)) {
lanes(selection);
}
@@ -75,6 +81,8 @@ export function uiFieldLanes(field, context) {
function lanesInfoUI(selection) {
+ // TODO: make this thing dynamic and show keysConsidered
+ // wrt to oneway.
var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
@@ -117,8 +125,8 @@ export function uiFieldLanes(field, context) {
.attr('class', 'preset-input-lanes')
.attr('id', function(d) { return 'preset-input-lanes-' + d; })
.each(function(d) {
- this.value = metadata[d];
- });
+ this.value = metadata[d];
+ });
// Update
items = items.merge(enter);
@@ -127,36 +135,50 @@ export function uiFieldLanes(field, context) {
return metadata[d];
});
- items.selectAll('input')
- .on('change', _.debounce(change, 700))
- .on('blur', _.debounce(change, 700));
-
- function change(d) {
- console.log('hola');
- var tag = {};
- if (d === 'count') {
- tag.lanes = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'forward') {
- tag['lanes:forward'] = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'backward') {
- tag['lanes:backward'] = utilGetSetValue(d3.select(this)) || undefined;
- }
- if (d === 'reverse') {
- if (utilGetSetValue(d3.select(this)) === 'true') {
- tag.oneway = '-1';
+
+ // selection.selectAll('.preset-access-count')
+ // .attr('hidden', function () {
+ // return metadata.oneway;
+ // });
+
+ var input = items.selectAll('input');
+
+ input
+ .on('change',change)
+ .on('blur', change);
+
+ function change(d) {
+ if (metadata.oneway) {
+ if (d === 'count') {
+ var count = utilGetSetValue(d3.select(this));
+ count = parseInt(count, 10);
+ if (!_.isNaN(count)) metadata.count = count;
+ }
+ if (d === 'reverse') {
+ if (utilGetSetValue(d3.select(this)) === 'true') {
+ metadata.reverse = true;
+ } else {
+ metadata.reverse = false;
+ }
+ }
} else {
- tag.oneway = undefined;
+ if (d === 'forward') {
+ var forward = utilGetSetValue(d3.select(this));
+ forward = parseInt(forward, 10);
+ if (!_.isNaN(forward)) metadata.forward = forward;
+ }
+ if (d === 'backward') {
+ var backward = utilGetSetValue(d3.select(this));
+ backward = parseInt(backward, 10);
+ if (!_.isNaN(forward)) metadata.backward = backward;
+ }
}
- }
- console.log(tag);
- dispatch.call('change', this, tag);
+ megaChange();
}
}
function turnLanesUI(selection) {
- var lanesArray = lanesData.lanesArray;
+ var turnLanes = lanesData.metadata.turnLanes;
selection.selectAll('.form-label')
.data([0])
.enter()
@@ -188,27 +210,54 @@ export function uiFieldLanes(field, context) {
.append('span')
.text(function (d) { return d;})
.attr('class', 'value');
- console.log(lanesArray[currentLane]);
var input = selection.selectAll('input');
input.property('checked', function (d) {
- if (_.isArray(lanesArray[currentLane].turnLanes)) {
- return lanesArray[currentLane].turnLanes.filter(function (el) {
+ if (turnLanes[curDirection] && _.isArray(turnLanes[curDirection][currentLane])) {
+ return turnLanes[curDirection][currentLane].filter(function (el) {
return el === d;
}).length === 1;
- }
+ }
return false;
- // return Math.random() > 0.4;
- });
+ })
+ .property('direction', function (d) {return d;});
+
- input.on('click', function() {
- var key = utilGetSetValue(d3.select(this)) || undefined;
- console.log(key);
+ input.on('click', change);
+
+ function change() {
d3.event.stopPropagation();
- });
+ var direction = d3.select(this).property('direction');
+
+ var newDirs = [];
+ input.each(function (d, i) {
+ var value = d3.select(this).property('checked');
+ if (value) {
+ newDirs.push(d);
+ }
+ });
+
+ if (direction === 'none' || newDirs.length === 0) {
+ newDirs = ['none'];
+ } else {
+ _.pull(newDirs, 'none');
+ }
+
+ turnLanes[curDirection][currentLane] = newDirs;
+
+ megaChange();
+
+ }
}
function laneSelectorUI(selection) {
var items;
+ var metadata = lanesData.metadata;
+ var oneway = metadata.oneway;
+ var len;
+
+ if (oneway) len = metadata.count;
+ else len = metadata.forward + metadata.backward;
+
selection.selectAll('.form-label')
.data([0])
.enter()
@@ -232,7 +281,7 @@ export function uiFieldLanes(field, context) {
.merge(list);
items = list.selectAll('.lane-item')
- .data(_.fill(Array(lanesData.metadata.count), 0).map(function (n, i) {
+ .data(_.fill(Array(len), 0).map(function (n, i) {
return i;
}));
@@ -242,38 +291,118 @@ export function uiFieldLanes(field, context) {
.attr('id', function (d) {
return 'lane-' + d;
})
- .classed('active', function (d) {
- return d === currentLane;
- })
- .append('span')
- .text(function (d) {
- return d + 1;
- });
-
- var input = selection.selectAll('.lane-item');
-
- input.on('click', function () {
- var lane = parseInt(d3.select(this).selectAll('span').text(), 10) - 1;
- selection.select('#lane-' + currentLane).classed('active', false);
- currentLane = lane;
- d3.select(this).classed('active', true);
- render();
- });
- items.exit().remove();
+ .append('span');
+
+ var input = selection.selectAll('.lane-item');
+
+ input.selectAll('span')
+ .text(function (d) {
+ if (metadata.oneway) return d + 1;
+ if (d < metadata.forward) {
+ return (d + 1) + '▲';
+ }
+ return (d - metadata.forward + 1) + '▼';
+ });
+
+ input.classed('active', function (d) {
+ if (metadata.oneway) return d === currentLane;
+ if (curDirection === 'forward') {
+ return d === currentLane;
+ }
+ return currentLane + metadata.forward === d;
+ });
+ input.on('click', function (d) {
+ if (metadata.oneway) {
+ currentLane = d;
+ curDirection = 'unspecified';
+ } else {
+ if (d < metadata.forward) {
+ currentLane = d;
+ curDirection = 'forward';
+ } else {
+ currentLane = d - metadata.forward;
+ curDirection = 'backward';
+ }
+ }
+
+
+ render();
+ });
+ items.exit().remove();
}
+ function megaChange() {
+ var tag = {};
+ var metadata = lanesData.metadata;
+
+
+ tag.lanes = Number(metadata.count).toString();
+
+ // Explanation: Removing tags on the basis of oneway tagging,
+ // assuming if it is a oneway, the forward and backward tags
+ // would be pruned, vice versa for oneway=no.
+ if (metadata.oneway) {
+
+ if (metadata.reverse) tag.oneway = '-1';
+ else tag.oneway = 'yes';
+
+ tag['lanes:forward'] = undefined;
+ tag['lanes:backward'] = undefined;
+
+ tag['turn:lanes'] = formPipes(metadata.turnLanes.unspecified, metadata.count, 'none');
+ tag['turn:lanes:forward'] = undefined;
+ tag['turn:lanes:backward'] = undefined;
+ } else {
+ tag.lanes = (metadata.forward + metadata.backward) + '';
+
+ tag['lanes:forward'] = metadata.forward + '';
+ tag['lanes:backward'] = metadata.backward + '';
+
+ tag['turn:lanes'] = undefined;
+ tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
+ tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
+ }
+
+ console.log('final tag', tag);
+ console.log('turn:lane ===',tag['turn:lanes']);
+ console.log('turn:lane;forward ==',tag['turn:lanes:forward']);
+ console.log('turn:lane;backward ==',tag['turn:lanes:backward']);
+ dispatch.call('change', this, tag);
+ }
+
+ function formPipes(data, len, nullKey) {
+ var str = data.map(function (lane) {
+ return lane.join(';');
+ });
+ while (str.length < len) {
+ str.push(nullKey);
+ }
+ str = str.join('|');
+ return str === '' ? undefined: str;
+ }
+
+ function pruneStr(str, s) {
+
+ }
}
lanes.entity = function(_) {
- if (!wayID || wayID !== _.id) {
- wayID = _.id;
+ if (!wayID) {
+ if (wayID !== _.id) {
+ currentLane = 0;
+ wayID = _.id;
+ }
+ if (_.isOneWay()) {
+ curDirection = 'unspecified';
+ } else {
+ curDirection = 'forward';
+ }
}
};
lanes.tags = function(tags) {
- console.log(tags, field.key, 'lolololoxsxs');
};
lanes.focus = function() {};
lanes.off = function() {};
From a539956d6e567ac2e564e8932962b6c1791211fb Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Tue, 31 Jan 2017 14:22:41 +0530
Subject: [PATCH 06/25] add some turn lane icons
---
.vscode/settings.json | 3 +
css/app.css | 8 ++
modules/geo/geo.js | 22 +++++
modules/geo/index.js | 1 +
modules/modes/select.js | 22 ++++-
modules/osm/lanes.js | 2 +-
modules/svg/lanes.js | 81 +++++++++++++++++++
modules/ui/fields/lanes.js | 3 -
modules/ui/index.js | 2 +
modules/ui/lane_visualizer.js | 146 ++++++++++++++++++++++++++++++++++
modules/ui/map_in_map.js | 31 +++++---
modules/ui/radial_menu.js | 3 +-
svg/iD-sprite.src.svg | 79 ++++++++++++++++++
13 files changed, 385 insertions(+), 18 deletions(-)
create mode 100644 .vscode/settings.json
create mode 100644 modules/svg/lanes.js
create mode 100644 modules/ui/lane_visualizer.js
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000000..0c4a6693fab
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "vsicons.presets.angular": false
+}
\ No newline at end of file
diff --git a/css/app.css b/css/app.css
index f38d52727b4..2f9456b59e0 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1326,6 +1326,14 @@ button.save.has-count .count::before {
background: #E8EBFF;
}
+/*lane-visualizer*/
+
+.lane-visualizer-background {
+ fill: #000;
+ fill-opacity: 0.5;
+}
+
+
/* preset form multicombo */
.form-field-multicombo {
diff --git a/modules/geo/geo.js b/modules/geo/geo.js
index 096c0a18e0d..7ccf0b6f5cd 100644
--- a/modules/geo/geo.js
+++ b/modules/geo/geo.js
@@ -103,6 +103,10 @@ export function geoAngle(a, b, projection) {
return Math.atan2(b[1] - a[1], b[0] - a[0]);
}
+function geoAngle2(a, b) {
+ return (Math.atan2(b[1] - a[1], b[0] - a[0]) * 180)/Math.PI;
+}
+
// Rotate all points counterclockwise around a pivot point by given angle
export function geoRotate(points, angle, around) {
@@ -274,3 +278,21 @@ export function geoPathLength(path) {
}
return length;
}
+
+export function geoPointOnLine(point, nodes, projection) {
+ var dist = geoEuclideanDistance,
+ points = nodes.map(function(n) { return projection(n.loc); }),
+ min = Infinity,
+ idx, loc;
+
+ for (var i = 0; i < points.length - 1; i++) {
+ console.log(point, points[i+1], points[i]);
+ var cross = geoAngle2(point, points[i], projection) - geoAngle2(point, points[i+1], projection);
+ var segmentLen = dist(points[i], points[i+1]);
+ var splitLen = dist(points[i], point) + dist(points[i+1], point);
+ console.log(cross);
+ if (cross.toFixed(5) === 0 && segmentLen.toFixed(5) === splitLen.toFixed(5)) {
+ return nodes[i];
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/geo/index.js b/modules/geo/index.js
index 5e37b16fe04..82fe277a773 100644
--- a/modules/geo/index.js
+++ b/modules/geo/index.js
@@ -21,3 +21,4 @@ export { geoPointInPolygon } from './geo.js';
export { geoPolygonContainsPolygon } from './geo.js';
export { geoPolygonIntersectsPolygon } from './geo.js';
export { geoSphericalDistance } from './geo.js';
+export { geoPointOnLine } from './geo.js';
\ No newline at end of file
diff --git a/modules/modes/select.js b/modules/modes/select.js
index 27032262e84..29427f731f9 100644
--- a/modules/modes/select.js
+++ b/modules/modes/select.js
@@ -28,7 +28,7 @@ import {
import { modeBrowse } from './browse';
import { modeDragNode } from './drag_node';
import * as Operations from '../operations/index';
-import { uiRadialMenu, uiSelectionList } from '../ui/index';
+import { uiRadialMenu, uiLaneVisualizer, uiSelectionList } from '../ui/index';
import { uiCmd } from '../ui/cmd';
import { utilEntityOrMemberSelector, utilEntitySelector } from '../util/index';
@@ -54,6 +54,7 @@ export function modeSelect(context, selectedIDs) {
modeDragNode(context).selectedIDs(selectedIDs).behavior
],
inspector,
+ laneVisualizer,
radialMenu,
newFeature = false,
suppressMenu = false,
@@ -142,13 +143,22 @@ export function modeSelect(context, selectedIDs) {
if (radialMenu) {
context.surface().call(radialMenu.close);
}
+ if (laneVisualizer) {
+ context.surface().call(laneVisualizer.close);
+ }
}
function positionMenu() {
+ var entity = singular();
+
+ if (entity && laneVisualizer && entity.type === 'way') {
+ laneVisualizer.center(context.mouse());
+ laneVisualizer.wayID(entity.id);
+ }
+
if (suppressMenu || !radialMenu) { return; }
- var entity = singular();
if (entity && context.geometry(entity.id) === 'relation') {
suppressMenu = true;
} else if (entity && entity.type === 'node') {
@@ -158,10 +168,12 @@ export function modeSelect(context, selectedIDs) {
viewport = geoExtent(context.projection.clipExtent()).polygon();
if (geoPointInPolygon(point, viewport)) {
radialMenu.center(point);
+
} else {
suppressMenu = true;
}
}
+ console.log(entity);
}
@@ -170,6 +182,9 @@ export function modeSelect(context, selectedIDs) {
if (!suppressMenu && radialMenu) {
context.surface().call(radialMenu);
}
+ if (laneVisualizer) {
+ context.surface().call(laneVisualizer);
+ }
}
@@ -427,6 +442,8 @@ export function modeSelect(context, selectedIDs) {
radialMenu = uiRadialMenu(context, operations);
+ laneVisualizer = uiLaneVisualizer(context);
+
context.ui().sidebar
.select(singular() ? singular().id : null, newFeature);
@@ -486,6 +503,7 @@ export function modeSelect(context, selectedIDs) {
keybinding.off();
closeMenu();
radialMenu = undefined;
+ laneVisualizer = undefined;
context.history()
.on('undone.select', null)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 8f2c72644b4..0378286e81b 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -174,7 +174,7 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
function parseTurnLanes(tag){
if (!tag) return [];
-
+ // TODO: need to add reverse_left and reverse_right
var validValues = [
'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
new file mode 100644
index 00000000000..94d8ddb30b8
--- /dev/null
+++ b/modules/svg/lanes.js
@@ -0,0 +1,81 @@
+import { geoAngle } from '../geo/index';
+
+
+export function svgTurns(projection) {
+
+ return function drawTurns(selection, graph, turns) {
+
+ function key(turn) {
+ return [turn.from.node + turn.via.node + turn.to.node].join('-');
+ }
+
+ function icon(turn) {
+ var u = turn.u ? '-u' : '';
+ if (!turn.restriction)
+ return '#turn-yes' + u;
+ var restriction = graph.entity(turn.restriction).tags.restriction;
+ return '#turn-' +
+ (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
+ }
+
+ var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
+ .data(turns, key);
+
+ groups.exit()
+ .remove();
+
+
+ var enter = groups.enter()
+ .append('g')
+ .attr('class', 'turn');
+
+ var nEnter = enter
+ .filter(function (turn) { return !turn.u; });
+
+ nEnter.append('rect')
+ .attr('transform', 'translate(-22, -12)')
+ .attr('width', '44')
+ .attr('height', '24');
+
+ nEnter.append('use')
+ .attr('transform', 'translate(-22, -12)')
+ .attr('width', '44')
+ .attr('height', '24');
+
+
+ var uEnter = enter
+ .filter(function (turn) { return turn.u; });
+
+ uEnter.append('circle')
+ .attr('r', '16');
+
+ uEnter.append('use')
+ .attr('transform', 'translate(-16, -16)')
+ .attr('width', '32')
+ .attr('height', '32');
+
+
+ groups = groups
+ .merge(enter);
+
+ groups
+ .attr('transform', function (turn) {
+ var v = graph.entity(turn.via.node),
+ t = graph.entity(turn.to.node),
+ a = geoAngle(v, t, projection),
+ p = projection(v.loc),
+ r = turn.u ? 0 : 60;
+
+ return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
+ 'rotate(' + a * 180 / Math.PI + ')';
+ });
+
+ groups.select('use')
+ .attr('xlink:href', icon);
+
+ groups.select('rect');
+ groups.select('circle');
+
+ return this;
+ };
+}
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index e84e7c7606a..3ed70f88b43 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -16,7 +16,6 @@ var validLanes = [
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
LANE_WIDTH = 40,
- LANE_HEIGHT = 200,
// TODO: currentLane if big like 6 goes crazy if other wayID has less than 6 lanes
currentLane = 0,
curDirection = 'unspecified',
@@ -24,9 +23,7 @@ export function uiFieldLanes(field, context) {
lanesData;
function lanes(selection) {
- console.log('hollaa mee', currentLane, curDirection)
lanesData = context.entity(wayID).lanes();
- var lanesArray = lanesData.lanesArray;
window.lanesData = lanesData;
window.currentLane = currentLane;
window.curDirection = curDirection;
diff --git a/modules/ui/index.js b/modules/ui/index.js
index 37bfc22cc9b..050dcd0e5a5 100644
--- a/modules/ui/index.js
+++ b/modules/ui/index.js
@@ -47,3 +47,5 @@ export { uiTooltipHtml } from './tooltipHtml';
export { uiUndoRedo } from './undo_redo';
export { uiViewOnOSM } from './view_on_osm';
export { uiZoom } from './zoom';
+
+export { uiLaneVisualizer } from './lane_visualizer';
\ No newline at end of file
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
new file mode 100644
index 00000000000..2e02dc6cd2c
--- /dev/null
+++ b/modules/ui/lane_visualizer.js
@@ -0,0 +1,146 @@
+import * as d3 from 'd3';
+import _ from 'lodash';
+import { geoAngle, geoChooseEdge, geoPointOnLine } from '../geo/index';
+
+function createSVGLink(directions) {
+ var dir = directions.sort(function(a, b) {
+ return a.charCodeAt(0) - b.charCodeAt(0);
+ });
+ dir = dir.join('-');
+ if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+ return dir;
+}
+export function uiLaneVisualizer(context) {
+ var menu,
+ wrapper,
+ wayId,
+ center = [0, 0],
+ tooltip,
+ metadata;
+
+ var laneVisualizer = function (selection) {
+ if (!wayId) return;
+ metadata = context.entity(wayId).lanes().metadata;
+ if (!metadata) return;
+
+ const iconWidth = 40;
+ const count = metadata.count;
+
+ function render() {
+ if (context.hasEntity(wayId)) {
+ laneVisualizer.close();
+ laneVisualizer(selection);
+ }
+ }
+
+ var projection = context.projection;
+ var graph = context.graph();
+ var way = graph.entity(wayId);
+
+ var nodes = _.uniq(graph.childNodes(way));
+ var choice = geoChooseEdge(nodes, context.mouse(), context.projection);
+ var prev = nodes[choice.index - 1];
+ var next = nodes[choice.index];
+ var angle = (geoAngle(prev, next, projection) * 180 / Math.PI) + 180;
+
+ context.history()
+ .on('change.lanes', render);
+
+ selection.node().parentNode.focus();
+
+ function click() {
+ d3.event.stopPropagation();
+ laneVisualizer.close();
+ }
+
+
+ wrapper = selection
+ .append('g')
+ .attr('class', 'lane-visualizer')
+ .attr('transform', 'translate('+ center+ ') rotate('+ angle + ')')
+ .attr('opacity', 0);
+
+ wrapper
+ .transition()
+ .attr('opacity', 1);
+
+ var menu = wrapper
+ .append('g')
+ .attr('transform', 'translate(0, ' +(-1*count*iconWidth)/2 + ')');
+
+
+
+ var rect = menu
+ .append('rect')
+ .attr('class', 'lane-visualizer-background')
+ .attr('width', iconWidth)
+ .attr('height', count*iconWidth);
+
+ var button = menu.selectAll()
+ .data(_.fill(Array(metadata.count), 0).map(function (n, i) {
+ return i;
+ }))
+ .enter()
+ .append('g')
+ .attr('class', 'radial-menu-item radial-menu-item-move')
+ .attr('transform', function(d, i) {
+ return 'translate(' + [ iconWidth/2, (iconWidth/2 + i*iconWidth) ]+ ') rotate(-90)';
+ });
+
+ button
+ .append('circle')
+ .attr('r', 15);
+
+ button
+ .append('use')
+ .attr('transform', 'translate(-15,-12)')
+ .attr('width', '20')
+ .attr('height', '20')
+ .attr('xlink:href', function (d, i) {
+ return '#lane-' + createSVGLink(metadata.turnLanes.unspecified[i]);
+ });
+
+ // menu
+ // .append('rect')
+ // .attr('width', 20)
+ // .attr('height', 30)
+ // .attr('stroke-width', 50)
+ // .attr('stroke-linecap', 'round');
+
+ };
+
+ laneVisualizer.center = function (_) {
+ if (!arguments.length) return center;
+ center = _;
+ console.log(center);
+ return laneVisualizer;
+ };
+
+
+ laneVisualizer.wayID = function (_) {
+ if (!arguments.length) return _;
+ wayId = _;
+ return laneVisualizer;
+ };
+
+ laneVisualizer.close = function() {
+ console.log('closing')
+ if (wrapper) {
+
+ wrapper
+ .style('pointer-events', 'none')
+ .transition()
+ .attr('opacity', 0)
+ .remove();
+
+ context.history()
+ .on('change.lanes', null);
+ }
+
+
+ if (tooltip) {
+ tooltip.remove();
+ }
+ };
+ return laneVisualizer;
+}
diff --git a/modules/ui/map_in_map.js b/modules/ui/map_in_map.js
index f4e903e48bf..5b19007da6d 100644
--- a/modules/ui/map_in_map.js
+++ b/modules/ui/map_in_map.js
@@ -237,27 +237,36 @@ export function uiMapInMap(context) {
// redraw viewport bounding box
if (gesture !== 'pan') {
- var getPath = d3.geoPath(projection),
- bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
+ // var getPath = d3.geoPath(projection),
+ var bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
viewport = wrap.selectAll('.map-in-map-viewport')
.data([0]);
viewport = viewport.enter()
- .append('svg')
- .attr('class', 'map-in-map-viewport')
+ .append('canvas')
+ // .attr('class', 'map-in-map-viewport')
+ .attr('height', 300)
+ .attr('width', 300)
.merge(viewport);
- var path = viewport.selectAll('.map-in-map-bbox')
+ var path2 = viewport.selectAll('.map-in-map-bbox')
.data([bbox]);
- path.enter()
- .append('path')
- .attr('class', 'map-in-map-bbox')
- .merge(path)
- .attr('d', getPath)
- .classed('thick', function(d) { return getPath.area(d) < 30; });
+ var ctx = d3.select('canvas').node().getContext('2d');
+ var path = d3.geoPath()
+ .projection(projection)
+ .context(ctx);
+ ctx.beginPath();
+ path(bbox);
+ ctx.stroke();
+ // path.enter()
+ // .append('path')
+ // .attr('class', 'map-in-map-bbox')
+ // .merge(path)
+ // .attr('d', getPath)
+ // .classed('thick', function(d) { return getPath.area(d) < 30; });
}
}
diff --git a/modules/ui/radial_menu.js b/modules/ui/radial_menu.js
index 8c62abb5b25..0f545f7a2db 100644
--- a/modules/ui/radial_menu.js
+++ b/modules/ui/radial_menu.js
@@ -8,8 +8,8 @@ export function uiRadialMenu(context, operations) {
center = [0, 0],
tooltip;
-
var radialMenu = function(selection) {
+ if (operations) return;
if (!operations.length) return;
selection.node().parentNode.focus();
@@ -47,6 +47,7 @@ export function uiRadialMenu(context, operations) {
.attr('stroke-width', 50)
.attr('stroke-linecap', 'round');
+ console.log(operations);
var button = menu.selectAll()
.data(operations)
.enter()
diff --git a/svg/iD-sprite.src.svg b/svg/iD-sprite.src.svg
index dbed29ff0ee..859baae60fc 100644
--- a/svg/iD-sprite.src.svg
+++ b/svg/iD-sprite.src.svg
@@ -187,6 +187,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From c3e1fae24fa6ea67ada36f5ccfecf0c19c97a28c Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Tue, 31 Jan 2017 19:53:53 +0530
Subject: [PATCH 07/25] add colors
---
modules/osm/lanes.js | 59 +++++++++++++++--
modules/svg/midpoints.js | 2 +-
modules/ui/fields/lanes.js | 6 +-
modules/ui/lane_visualizer.js | 118 +++++++++++++++++++---------------
4 files changed, 121 insertions(+), 64 deletions(-)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 0378286e81b..7435174e5d1 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -14,7 +14,14 @@ export function osmLanes(entity) {
var forward = laneDirections.forward;
var backward = laneDirections.backward;
var bothways = laneDirections.bothways;
+
+ // sometimes just forward and backward are available
+ laneCount = laneDirections.laneCount;
+ // TODO: if you change the forward backward and click on trash at top,
+ // laneCount and forward/backward goes out of sync
+ // TODO: sometimes people just do turn:lanes:backward=|||| and dont mention
+ // any kind of count. need to handle it
// parse the piped string 'x|y|z' format
var turnLanes = {};
turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
@@ -74,8 +81,7 @@ export function osmLanes(entity) {
// TODO: need to make sure forward lanes is consistent across all tags,
// eg if psv:lanes:forward is 3 and lanes:forward is 2, changes lanes:forward =3,
- return {
- metadata: {
+ var metadata = {
count: laneCount,
oneway: isOneWay,
forward: forward,
@@ -92,9 +98,12 @@ export function osmLanes(entity) {
bicyclewayLanes: bicyclewayLanes,
leftHandDrive: false,
reverse: parseInt(tags.oneway, 10) === -1
- },
+ };
+ return {
+ metadata: metadata,
+ accessSeq: makeAccessSeq(metadata, true),
lanes: lanesObj
- };
+ };
}
@@ -137,7 +146,7 @@ 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;
-
+ var count = laneCount;
if (parseInt(tags.oneway, 10) === -1) {
forward = 0;
bothways = 0;
@@ -164,10 +173,12 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
}
backward = laneCount - bothways - forward;
}
+
return {
forward: forward,
backward: backward,
- bothways: bothways
+ bothways: bothways,
+ laneCount: forward + backward+ bothways
};
}
@@ -274,4 +285,38 @@ function lanesArray(lanesData) {
});
return obj;
-}
\ No newline at end of file
+}
+
+function makeAccessSeq(metadata, leftHand) {
+ if (metadata.oneway) {
+ return _.fill(Array(metadata.count), 0).map(function (n, i) {
+ return {
+ dir: 'unspecified',
+ index: i
+ };
+ });
+ }
+
+ var forward = metadata.forward;
+ var backward = metadata.backward;
+
+ var forSeq = _.fill(Array(forward), 0).map(function (n, i) {
+ return {
+ dir: 'forward',
+ index: i
+ };
+ });
+ var backSeq = _.fill(Array(backward), 0).map(function (n, i) {
+ return {
+ dir: 'backward',
+ index: backward - i - 1
+ };
+ });
+
+ if (leftHand) {
+ return [].concat(forSeq, backSeq);
+ }
+ return [].concat(backSeq, forSeq);
+}
+
+window.makeAccessSeq = makeAccessSeq;
\ No newline at end of file
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index a64b922254a..31e00bcd4fc 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -27,7 +27,7 @@ export function svgMidpoints(projection, context) {
continue;
if (context.selectedIDs().indexOf(entity.id) < 0)
continue;
-
+ console.log(context.selectedIDs().indexOf(entity.id));
var nodes = graph.childNodes(entity);
for (var j = 0; j < nodes.length - 1; j++) {
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 3ed70f88b43..3ef35c75451 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -85,7 +85,7 @@ export function uiFieldLanes(field, context) {
var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
var metadata = lanesData.metadata;
-
+ window.metadata = metadata;
wrap = wrap.enter()
.append('div')
.attr('class', 'preset-input-wrap')
@@ -250,8 +250,8 @@ export function uiFieldLanes(field, context) {
var items;
var metadata = lanesData.metadata;
var oneway = metadata.oneway;
- var len;
-
+ var len = metadata.count;
+ // TODO: clean up this mess of vvvvv
if (oneway) len = metadata.count;
else len = metadata.forward + metadata.backward;
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
index 2e02dc6cd2c..a8683fdcf0a 100644
--- a/modules/ui/lane_visualizer.js
+++ b/modules/ui/lane_visualizer.js
@@ -2,14 +2,6 @@ import * as d3 from 'd3';
import _ from 'lodash';
import { geoAngle, geoChooseEdge, geoPointOnLine } from '../geo/index';
-function createSVGLink(directions) {
- var dir = directions.sort(function(a, b) {
- return a.charCodeAt(0) - b.charCodeAt(0);
- });
- dir = dir.join('-');
- if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
- return dir;
-}
export function uiLaneVisualizer(context) {
var menu,
wrapper,
@@ -17,22 +9,19 @@ export function uiLaneVisualizer(context) {
center = [0, 0],
tooltip,
metadata;
-
+
var laneVisualizer = function (selection) {
+ var leftHand = false;
+
if (!wayId) return;
- metadata = context.entity(wayId).lanes().metadata;
+ metadata = context.entity(wayId).lanes().metadata;
if (!metadata) return;
-
+
+ var seq = context.entity(wayId).lanes().accessSeq;
+
const iconWidth = 40;
const count = metadata.count;
- function render() {
- if (context.hasEntity(wayId)) {
- laneVisualizer.close();
- laneVisualizer(selection);
- }
- }
-
var projection = context.projection;
var graph = context.graph();
var way = graph.entity(wayId);
@@ -41,8 +30,8 @@ export function uiLaneVisualizer(context) {
var choice = geoChooseEdge(nodes, context.mouse(), context.projection);
var prev = nodes[choice.index - 1];
var next = nodes[choice.index];
- var angle = (geoAngle(prev, next, projection) * 180 / Math.PI) + 180;
-
+ var angle = (geoAngle(prev, next, projection) * 180 / Math.PI);
+
context.history()
.on('change.lanes', render);
@@ -53,11 +42,11 @@ export function uiLaneVisualizer(context) {
laneVisualizer.close();
}
-
wrapper = selection
.append('g')
.attr('class', 'lane-visualizer')
- .attr('transform', 'translate('+ center+ ') rotate('+ angle + ')')
+ // .attr('transform', 'translate('+ center + ')')
+ .attr('transform', 'translate(' + center + ') rotate(' + (angle+ 90) + ')')
.attr('opacity', 0);
wrapper
@@ -66,29 +55,39 @@ export function uiLaneVisualizer(context) {
var menu = wrapper
.append('g')
- .attr('transform', 'translate(0, ' +(-1*count*iconWidth)/2 + ')');
+ .attr('transform', 'translate(' + count*iconWidth/(-2) + ', 0)');
-
-
- var rect = menu
+ menu
.append('rect')
.attr('class', 'lane-visualizer-background')
- .attr('width', iconWidth)
- .attr('height', count*iconWidth);
+ .attr('width', count* iconWidth)
+ .attr('height', iconWidth);
var button = menu.selectAll()
- .data(_.fill(Array(metadata.count), 0).map(function (n, i) {
- return i;
- }))
- .enter()
- .append('g')
- .attr('class', 'radial-menu-item radial-menu-item-move')
- .attr('transform', function(d, i) {
- return 'translate(' + [ iconWidth/2, (iconWidth/2 + i*iconWidth) ]+ ') rotate(-90)';
- });
+ .data(seq)
+ .enter()
+ .append('g')
+ .attr('class', 'radial-menu-item radial-menu-item-move')
+ .attr('transform', function (d, i) {
+ var reverse = 0;
+ if (d.dir === 'backward') {
+ reverse = 180;
+ }
+ return 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ') rotate(' + reverse + ')';
+ });
button
.append('circle')
+ .style('fill', function(d) {
+ switch (d.dir) {
+ case 'forward':
+ return '#dfffdf';
+ case 'backward':
+ return '#ffd8d8';
+ default:
+ return '';
+ }
+ })
.attr('r', 15);
button
@@ -96,23 +95,37 @@ export function uiLaneVisualizer(context) {
.attr('transform', 'translate(-15,-12)')
.attr('width', '20')
.attr('height', '20')
- .attr('xlink:href', function (d, i) {
- return '#lane-' + createSVGLink(metadata.turnLanes.unspecified[i]);
+ .attr('xlink:href', function (d) {
+ return '#lane-' + createSVGLink(d);
});
-
- // menu
- // .append('rect')
- // .attr('width', 20)
- // .attr('height', 30)
- // .attr('stroke-width', 50)
- // .attr('stroke-linecap', 'round');
+
- };
+ function render() {
+ if (context.hasEntity(wayId)) {
+ laneVisualizer.close();
+ laneVisualizer(selection);
+ }
+ }
+ };
+ function createSVGLink(d) {
+ var directions;
+ console.log(d.dir);
+ directions = metadata.turnLanes[d.dir][d.index];
+
+ // TODO: fix this vv
+ if (!directions) return '';
+ var dir = directions.sort(function (a, b) {
+ return a.charCodeAt(0) - b.charCodeAt(0);
+ });
+ dir = dir.join('-');
+ if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+
+ return dir;
+ }
laneVisualizer.center = function (_) {
if (!arguments.length) return center;
center = _;
- console.log(center);
return laneVisualizer;
};
@@ -123,10 +136,9 @@ export function uiLaneVisualizer(context) {
return laneVisualizer;
};
- laneVisualizer.close = function() {
- console.log('closing')
+ laneVisualizer.close = function () {
if (wrapper) {
-
+
wrapper
.style('pointer-events', 'none')
.transition()
@@ -134,9 +146,9 @@ export function uiLaneVisualizer(context) {
.remove();
context.history()
- .on('change.lanes', null);
+ .on('change.lanes', null);
}
-
+
if (tooltip) {
tooltip.remove();
From cd0308bdbdda34b3c27987bc55e3da863b194310 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Wed, 1 Feb 2017 13:51:11 +0530
Subject: [PATCH 08/25] Add left hand drive check
---
modules/osm/lanes.js | 6 ++----
modules/ui/fields/lanes.js | 9 +++++----
modules/ui/lane_visualizer.js | 21 +++++++++++++++------
3 files changed, 22 insertions(+), 14 deletions(-)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 7435174e5d1..cca156d5aa4 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -96,12 +96,10 @@ export function osmLanes(entity) {
hovLanes: hovLanes,
hgvLanes: hgvLanes,
bicyclewayLanes: bicyclewayLanes,
- leftHandDrive: false,
reverse: parseInt(tags.oneway, 10) === -1
};
return {
metadata: metadata,
- accessSeq: makeAccessSeq(metadata, true),
lanes: lanesObj
};
}
@@ -287,7 +285,7 @@ function lanesArray(lanesData) {
return obj;
}
-function makeAccessSeq(metadata, leftHand) {
+export function getLayoutSeq(metadata, leftHand) {
if (metadata.oneway) {
return _.fill(Array(metadata.count), 0).map(function (n, i) {
return {
@@ -319,4 +317,4 @@ function makeAccessSeq(metadata, leftHand) {
return [].concat(backSeq, forSeq);
}
-window.makeAccessSeq = makeAccessSeq;
\ No newline at end of file
+window.getLayoutSeq = getLayoutSeq;
\ No newline at end of file
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 3ef35c75451..1a763054118 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -3,10 +3,8 @@ import { utilRebind } from '../../util/rebind';
import { utilGetDimensions } from '../../util/dimensions';
import { uiFieldCheck } from './check';
import _ from 'lodash';
-import { d3combobox } from '../../lib/d3.combobox.js';
import { utilGetSetValue } from '../../util/get_set_value';
-
var validLanes = [
'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
@@ -20,19 +18,22 @@ export function uiFieldLanes(field, context) {
currentLane = 0,
curDirection = 'unspecified',
wayID,
- lanesData;
+ lanesData,
+ driveLeft;
+
function lanes(selection) {
lanesData = context.entity(wayID).lanes();
window.lanesData = lanesData;
window.currentLane = currentLane;
window.curDirection = curDirection;
-
+
if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
selection.call(lanes.off);
return;
}
+
var lanesInfo = selection.selectAll('.lanes-info').data([0]);
lanesInfo = lanesInfo.enter()
.append('div')
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
index a8683fdcf0a..b86c7ac0279 100644
--- a/modules/ui/lane_visualizer.js
+++ b/modules/ui/lane_visualizer.js
@@ -1,6 +1,9 @@
import * as d3 from 'd3';
import _ from 'lodash';
import { geoAngle, geoChooseEdge, geoPointOnLine } from '../geo/index';
+import { getLayoutSeq } from '../osm/lanes';
+import { dataDriveLeft } from '../../data';
+import { geoPointInPolygon } from '../geo';
export function uiLaneVisualizer(context) {
var menu,
@@ -8,17 +11,14 @@ export function uiLaneVisualizer(context) {
wayId,
center = [0, 0],
tooltip,
- metadata;
+ metadata,
+ driveLeft;
var laneVisualizer = function (selection) {
- var leftHand = false;
-
if (!wayId) return;
metadata = context.entity(wayId).lanes().metadata;
if (!metadata) return;
- var seq = context.entity(wayId).lanes().accessSeq;
-
const iconWidth = 40;
const count = metadata.count;
@@ -26,6 +26,15 @@ export function uiLaneVisualizer(context) {
var graph = context.graph();
var way = graph.entity(wayId);
+ var loc = way.extent(context.graph()).center();
+ driveLeft = _.some(dataDriveLeft.features, function(f) {
+ return _.some(f.geometry.coordinates, function(d) {
+ return geoPointInPolygon(loc, d);
+ });
+ });
+
+ var layout = getLayoutSeq(metadata, driveLeft);
+
var nodes = _.uniq(graph.childNodes(way));
var choice = geoChooseEdge(nodes, context.mouse(), context.projection);
var prev = nodes[choice.index - 1];
@@ -64,7 +73,7 @@ export function uiLaneVisualizer(context) {
.attr('height', iconWidth);
var button = menu.selectAll()
- .data(seq)
+ .data(layout)
.enter()
.append('g')
.attr('class', 'radial-menu-item radial-menu-item-move')
From 14c583bb1c8eb7fc2504b3c87d44625d026746fe Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Wed, 1 Feb 2017 23:05:24 +0530
Subject: [PATCH 09/25] basic svg Lanes
---
modules/geo/geo.js | 28 +-----
modules/geo/index.js | 2 +-
modules/osm/lanes.js | 6 +-
modules/renderer/map.js | 6 +-
modules/svg/index.js | 1 +
modules/svg/lanes.js | 181 ++++++++++++++++++++++------------
modules/svg/midpoints.js | 4 +-
modules/ui/lane_visualizer.js | 3 +-
8 files changed, 138 insertions(+), 93 deletions(-)
diff --git a/modules/geo/geo.js b/modules/geo/geo.js
index 7ccf0b6f5cd..f0c78dda0ec 100644
--- a/modules/geo/geo.js
+++ b/modules/geo/geo.js
@@ -11,6 +11,11 @@ export function geoInterp(p1, p2, t) {
p1[1] + (p2[1] - p1[1]) * t];
}
+// returns a point which divides the line joining p1, p2
+// in the ratio m:n
+export function geoDivideSegment(p1, p2, m, n) {
+ return [(p2[0]*n + p2[0]*m)/(m+n), (p2[1]*n + p2[1]*m)/(m+n)];
+}
// 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
// Returns a positive value, if OAB makes a counter-clockwise turn,
@@ -103,11 +108,6 @@ export function geoAngle(a, b, projection) {
return Math.atan2(b[1] - a[1], b[0] - a[0]);
}
-function geoAngle2(a, b) {
- return (Math.atan2(b[1] - a[1], b[0] - a[0]) * 180)/Math.PI;
-}
-
-
// Rotate all points counterclockwise around a pivot point by given angle
export function geoRotate(points, angle, around) {
return points.map(function(point) {
@@ -278,21 +278,3 @@ export function geoPathLength(path) {
}
return length;
}
-
-export function geoPointOnLine(point, nodes, projection) {
- var dist = geoEuclideanDistance,
- points = nodes.map(function(n) { return projection(n.loc); }),
- min = Infinity,
- idx, loc;
-
- for (var i = 0; i < points.length - 1; i++) {
- console.log(point, points[i+1], points[i]);
- var cross = geoAngle2(point, points[i], projection) - geoAngle2(point, points[i+1], projection);
- var segmentLen = dist(points[i], points[i+1]);
- var splitLen = dist(points[i], point) + dist(points[i+1], point);
- console.log(cross);
- if (cross.toFixed(5) === 0 && segmentLen.toFixed(5) === splitLen.toFixed(5)) {
- return nodes[i];
- }
- }
-}
\ No newline at end of file
diff --git a/modules/geo/index.js b/modules/geo/index.js
index 82fe277a773..8e060f7f787 100644
--- a/modules/geo/index.js
+++ b/modules/geo/index.js
@@ -21,4 +21,4 @@ export { geoPointInPolygon } from './geo.js';
export { geoPolygonContainsPolygon } from './geo.js';
export { geoPolygonIntersectsPolygon } from './geo.js';
export { geoSphericalDistance } from './geo.js';
-export { geoPointOnLine } from './geo.js';
\ No newline at end of file
+export { geoDivideSegment } from './geo.js';
\ No newline at end of file
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index cca156d5aa4..c6e92a21f9e 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -285,11 +285,13 @@ function lanesArray(lanesData) {
return obj;
}
-export function getLayoutSeq(metadata, leftHand) {
+export function getLayoutSeq(metadata, leftHand, kind) {
+ if (!metadata) return [];
if (metadata.oneway) {
return _.fill(Array(metadata.count), 0).map(function (n, i) {
return {
dir: 'unspecified',
+ lanes: metadata[kind].unspecified,
index: i
};
});
@@ -301,12 +303,14 @@ export function getLayoutSeq(metadata, leftHand) {
var forSeq = _.fill(Array(forward), 0).map(function (n, i) {
return {
dir: 'forward',
+ lanes: metadata[kind].forward,
index: i
};
});
var backSeq = _.fill(Array(backward), 0).map(function (n, i) {
return {
dir: 'backward',
+ lanes: metadata[kind].backward,
index: backward - i - 1
};
});
diff --git a/modules/renderer/map.js b/modules/renderer/map.js
index ec10c9201a0..baf0fed15fe 100644
--- a/modules/renderer/map.js
+++ b/modules/renderer/map.js
@@ -10,6 +10,7 @@ import {
svgAreas,
svgLabels,
svgLayers,
+ svgLanes,
svgLines,
svgMidpoints,
svgPoints,
@@ -44,6 +45,7 @@ export function rendererMap(context) {
drawLines = svgLines(projection),
drawAreas = svgAreas(projection, context),
drawMidpoints = svgMidpoints(projection, context),
+ drawLanes = svgLanes(projection, context),
drawLabels = svgLabels(projection, context),
supersurface = d3.select(null),
wrapper = d3.select(null),
@@ -159,7 +161,8 @@ export function rendererMap(context) {
all = context.features().filter(all, graph);
surface.selectAll('.data-layer-osm')
.call(drawVertices, graph, all, filter, map.extent(), map.zoom())
- .call(drawMidpoints, graph, all, filter, map.trimmedExtent());
+ .call(drawMidpoints, graph, all, filter, map.trimmedExtent())
+ .call(drawLanes, graph, all, filter, map.trimmedExtent(), map.center());
dispatch.call('drawn', this, {full: false});
}
});
@@ -252,6 +255,7 @@ export function rendererMap(context) {
.call(drawLines, graph, data, filter)
.call(drawAreas, graph, data, filter)
.call(drawMidpoints, graph, data, filter, map.trimmedExtent())
+ .call(drawLanes, graph, data, filter, map.trimmedExtent(), map.center())
.call(drawLabels, graph, data, filter, dimensions, !difference && !extent)
.call(drawPoints, graph, data, filter);
diff --git a/modules/svg/index.js b/modules/svg/index.js
index 9b48ba93d39..0120b5c1461 100644
--- a/modules/svg/index.js
+++ b/modules/svg/index.js
@@ -5,6 +5,7 @@ export { svgGpx } from './gpx.js';
export { svgIcon } from './icon.js';
export { svgLabels } from './labels.js';
export { svgLayers } from './layers.js';
+export { svgLanes } from './lanes.js';
export { svgLines } from './lines.js';
export { svgMapillaryImages } from './mapillary_images.js';
export { svgMapillarySigns } from './mapillary_signs.js';
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 94d8ddb30b8..e64410b9ab5 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -1,81 +1,134 @@
-import { geoAngle } from '../geo/index';
-
-
-export function svgTurns(projection) {
-
- return function drawTurns(selection, graph, turns) {
-
- function key(turn) {
- return [turn.from.node + turn.via.node + turn.to.node].join('-');
+import _ from 'lodash';
+import {
+ svgPointTransform,
+ svgTagClasses
+} from './index';
+
+import {
+ geoAngle,
+ geoEuclideanDistance,
+ geoInterp,
+ geoLineIntersection
+} from '../geo/index';
+import { getLayoutSeq } from '../osm/lanes';
+import { dataDriveLeft } from '../../data';
+import { geoPointInPolygon } from '../geo';
+
+
+export function svgLanes(projection, context) {
+
+ return function drawMidpoints(selection, graph, entities, filter, extent, mapCenter) {
+ // return ;
+ var entity = getEntity();
+ var showLanes = [];
+ var metadata;
+ var iconPosition;
+ var driveLeft;
+ var layoutSeq;
+
+ if (entity) {
+ metadata = entity.lanes().metadata;
+ iconPosition = findPosition();
+ driveLeft = isDriveLeft();
+ layoutSeq = getLayoutSeq(metadata, driveLeft, 'turnLanes');
+ layer = selection.selectAll('.layer-hit');
+ showLanes = [0];
}
+ var layer = selection.selectAll('.layer-hit');
- function icon(turn) {
- var u = turn.u ? '-u' : '';
- if (!turn.restriction)
- return '#turn-yes' + u;
- var restriction = graph.entity(turn.restriction).tags.restriction;
- return '#turn-' +
- (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
- }
-
- var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
- .data(turns, key);
+ var groups = layer
+ .selectAll('g.midpoint')
+ .data(showLanes);
groups.exit()
.remove();
-
var enter = groups.enter()
- .append('g')
- .attr('class', 'turn');
-
- var nEnter = enter
- .filter(function (turn) { return !turn.u; });
-
- nEnter.append('rect')
- .attr('transform', 'translate(-22, -12)')
- .attr('width', '44')
- .attr('height', '24');
+ .insert('g', ':first-child')
+ .attr('class', 'midpoint');
- nEnter.append('use')
- .attr('transform', 'translate(-22, -12)')
- .attr('width', '44')
- .attr('height', '24');
-
-
- var uEnter = enter
- .filter(function (turn) { return turn.u; });
-
- uEnter.append('circle')
- .attr('r', '16');
-
- uEnter.append('use')
- .attr('transform', 'translate(-16, -16)')
- .attr('width', '32')
- .attr('height', '32');
+ enter.append('polygon')
+ .attr('points', '-6,8 10,0 -6,-8')
+ .attr('class', 'shadow');
+ enter.append('polygon')
+ .attr('points', '-3,4 5,0 -3,-4')
+ .attr('class', 'fill');
groups = groups
- .merge(enter);
-
- groups
- .attr('transform', function (turn) {
- var v = graph.entity(turn.via.node),
- t = graph.entity(turn.to.node),
- a = geoAngle(v, t, projection),
- p = projection(v.loc),
- r = turn.u ? 0 : 60;
-
- return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
- 'rotate(' + a * 180 / Math.PI + ')';
+ .merge(enter)
+ .attr('transform', function (d) {
+ var translate = svgPointTransform(projection),
+ a = graph.entity(iconPosition.edge[0]),
+ b = graph.entity(iconPosition.edge[1]);
+ var angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
+ return translate(iconPosition)+ ' rotate(' + angleVal + ')';
+ })
+ .call(svgTagClasses().tags(
+ // TODO: what if entity is null
+ function () { return entity && entity.tags; }
+ ));
+
+ // Propagate data bindings.
+ groups.select('polygon.shadow');
+ groups.select('polygon.fill');
+
+ function isDriveLeft() {
+ return _.some(dataDriveLeft.features, function (f) {
+ return _.some(f.geometry.coordinates, function (d) {
+ return geoPointInPolygon(mapCenter, d);
+ });
});
+ }
- groups.select('use')
- .attr('xlink:href', icon);
+ function getEntity() {
+ if (context.selectedIDs().length !== 1) return null;
+ var entity = graph.entity(context.selectedIDs()[0]);
- groups.select('rect');
- groups.select('circle');
+ if (entity.type !== 'way') return null;
+ if (!filter(entity)) return null;
+ if (!entity.tags.highway) return null;
+ return entity;
+ }
- return this;
+ function findPosition() {
+ var loc;
+ if (!entity) {
+ return {
+ loc: undefined,
+ edge: []
+ };
+ }
+ var nodes = graph.childNodes(entity);
+ var poly = extent.polygon();
+
+ for (var j = nodes.length - 1; j > 0; j--) {
+ var a = nodes[j - 1];
+ var b = nodes[j];
+ if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
+ var point = geoInterp(a.loc, b.loc, 0.75);
+ if (extent.intersects(point)) {
+ loc = point;
+ } else {
+ for (var k = 0; k < 4; k++) {
+ point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
+ if (point &&
+ geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
+ geoEuclideanDistance(projection(b.loc), projection(point)) > 20) {
+ loc = point;
+ break;
+ }
+ }
+ }
+ if (loc) {
+ return {
+ loc: loc,
+ edge: [a.id, b.id],
+ };
+ }
+ }
+ }
+ }
};
+
}
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index 31e00bcd4fc..b75c672c2e6 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -17,7 +17,7 @@ export function svgMidpoints(projection, context) {
return function drawMidpoints(selection, graph, entities, filter, extent) {
var poly = extent.polygon(),
midpoints = {};
-
+ return;
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
@@ -92,7 +92,7 @@ export function svgMidpoints(projection, context) {
.selectAll('g.midpoint')
.filter(midpointFilter)
.data(_.values(midpoints), function(d) { return d.id; });
-
+ console.log(_.values(midpoints), function(d) { return d.id;});
groups.exit()
.remove();
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
index b86c7ac0279..b55a3449b82 100644
--- a/modules/ui/lane_visualizer.js
+++ b/modules/ui/lane_visualizer.js
@@ -1,6 +1,6 @@
import * as d3 from 'd3';
import _ from 'lodash';
-import { geoAngle, geoChooseEdge, geoPointOnLine } from '../geo/index';
+import { geoAngle, geoChooseEdge } from '../geo/index';
import { getLayoutSeq } from '../osm/lanes';
import { dataDriveLeft } from '../../data';
import { geoPointInPolygon } from '../geo';
@@ -16,6 +16,7 @@ export function uiLaneVisualizer(context) {
var laneVisualizer = function (selection) {
if (!wayId) return;
+ return;
metadata = context.entity(wayId).lanes().metadata;
if (!metadata) return;
From d354c80f90d604801d84d6f83d3c1a26bd568372 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 2 Feb 2017 00:42:40 +0530
Subject: [PATCH 10/25] add svg rect
---
modules/svg/lanes.js | 38 +++++++++++++++++++++++++++++---------
1 file changed, 29 insertions(+), 9 deletions(-)
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index e64410b9ab5..35cec4279ae 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -18,26 +18,29 @@ import { geoPointInPolygon } from '../geo';
export function svgLanes(projection, context) {
return function drawMidpoints(selection, graph, entities, filter, extent, mapCenter) {
- // return ;
+ // return;
var entity = getEntity();
var showLanes = [];
var metadata;
var iconPosition;
var driveLeft;
var layoutSeq;
-
+ const iconWidth = 40;
+
if (entity) {
metadata = entity.lanes().metadata;
iconPosition = findPosition();
driveLeft = isDriveLeft();
layoutSeq = getLayoutSeq(metadata, driveLeft, 'turnLanes');
layer = selection.selectAll('.layer-hit');
- showLanes = [0];
+ if (iconPosition) {
+ showLanes = [0];
+ }
}
var layer = selection.selectAll('.layer-hit');
var groups = layer
- .selectAll('g.midpoint')
+ .selectAll('g.lanes-visual')
.data(showLanes);
groups.exit()
@@ -45,11 +48,28 @@ export function svgLanes(projection, context) {
var enter = groups.enter()
.insert('g', ':first-child')
- .attr('class', 'midpoint');
+ .attr('class', 'lanes-visual');
+
+ enter
+ .append('g')
+ .attr('class', 'lanes-visual-wrapper')
+ .append('rect')
+ .attr('class', 'lane-visual-background');
+
+ layer
+ .selectAll('.lanes-visual-wrapper')
+ .attr('transform', function() {
+ return 'translate(' + metadata.count*iconWidth/(-2) + ', 0)';
+ });
+
- enter.append('polygon')
- .attr('points', '-6,8 10,0 -6,-8')
- .attr('class', 'shadow');
+ selection.selectAll('rect')
+ .attr('width', function() {
+ return metadata.count* iconWidth;
+ })
+ .attr('height', function() {
+ return iconWidth;
+ });
enter.append('polygon')
.attr('points', '-3,4 5,0 -3,-4')
@@ -61,7 +81,7 @@ export function svgLanes(projection, context) {
var translate = svgPointTransform(projection),
a = graph.entity(iconPosition.edge[0]),
b = graph.entity(iconPosition.edge[1]);
- var angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
+ var angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI)) + 90;
return translate(iconPosition)+ ' rotate(' + angleVal + ')';
})
.call(svgTagClasses().tags(
From 482658e38a4a10bcede40b6f45cb1b1d90934a1b Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 2 Feb 2017 01:46:36 +0530
Subject: [PATCH 11/25] d3 update
---
modules/osm/lanes.js | 4 ++
modules/svg/lanes.js | 87 ++++++++++++++++++++++++++++++++++++--------
2 files changed, 75 insertions(+), 16 deletions(-)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index c6e92a21f9e..2a77477eff4 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -23,6 +23,10 @@ export function osmLanes(entity) {
// TODO: sometimes people just do turn:lanes:backward=|||| and dont mention
// any kind of count. need to handle it
// parse the piped string 'x|y|z' format
+
+ // TODO: if you add 8 forward turn lanes and thrn put forward count as 4
+ // goes out of sync. Reducing the number of forward turn lanes doesnt reduce turn lanes
+ // forward
var turnLanes = {};
turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 35cec4279ae..1069651c629 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -24,9 +24,9 @@ export function svgLanes(projection, context) {
var metadata;
var iconPosition;
var driveLeft;
- var layoutSeq;
+ var layoutSeq = [];
const iconWidth = 40;
-
+ // TODO: on removing map features svgLanes stays there
if (entity) {
metadata = entity.lanes().metadata;
iconPosition = findPosition();
@@ -50,26 +50,66 @@ export function svgLanes(projection, context) {
.insert('g', ':first-child')
.attr('class', 'lanes-visual');
- enter
+ var wrapper = enter
.append('g')
- .attr('class', 'lanes-visual-wrapper')
- .append('rect')
+ .attr('class', 'lanes-visual-wrapper');
+
+ wrapper.append('rect')
.attr('class', 'lane-visual-background');
+ wrapper.append('g')
+ .attr('class', 'lane-visual-items');
+
layer
.selectAll('.lanes-visual-wrapper')
- .attr('transform', function() {
- return 'translate(' + metadata.count*iconWidth/(-2) + ', 0)';
+ .attr('transform', function () {
+ return 'translate(' + metadata.count * iconWidth / (-2) + ', 0)';
});
-
selection.selectAll('rect')
- .attr('width', function() {
- return metadata.count* iconWidth;
- })
- .attr('height', function() {
- return iconWidth;
- });
+ .attr('width', function () {
+ return metadata.count * iconWidth;
+ })
+ .attr('height', function () {
+ return iconWidth;
+ });
+
+ var button = groups.selectAll('lane-visual-items')
+ .data(layoutSeq)
+ .enter()
+ .append('g')
+ .attr('class', 'lane-visual-items radial-menu-item radial-menu-item-move')
+ .attr('transform', function (d, i) {
+ var reverse = 0;
+ if (d.dir === 'backward') {
+ reverse = 180;
+ }
+ return 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ') rotate(' + reverse + ')';
+ });
+
+ button
+ .append('circle')
+ .style('fill', function (d) {
+ switch (d.dir) {
+ case 'forward':
+ return '#dfffdf';
+ case 'backward':
+ return '#ffd8d8';
+ default:
+ return '';
+ }
+ })
+ .attr('r', 15);
+
+ button
+ .append('use')
+ .attr('transform', 'translate(-15,-12)')
+ .attr('width', '20')
+ .attr('height', '20')
+ .attr('xlink:href', function (d) {
+ console.log(d);
+ return '#lane-' + createSVGLink(d);
+ });
enter.append('polygon')
.attr('points', '-3,4 5,0 -3,-4')
@@ -82,7 +122,7 @@ export function svgLanes(projection, context) {
a = graph.entity(iconPosition.edge[0]),
b = graph.entity(iconPosition.edge[1]);
var angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI)) + 90;
- return translate(iconPosition)+ ' rotate(' + angleVal + ')';
+ return translate(iconPosition) + ' rotate(' + angleVal + ')';
})
.call(svgTagClasses().tags(
// TODO: what if entity is null
@@ -121,7 +161,7 @@ export function svgLanes(projection, context) {
}
var nodes = graph.childNodes(entity);
var poly = extent.polygon();
-
+
for (var j = nodes.length - 1; j > 0; j--) {
var a = nodes[j - 1];
var b = nodes[j];
@@ -149,6 +189,21 @@ export function svgLanes(projection, context) {
}
}
}
+ function createSVGLink(d) {
+ var directions;
+ console.log(d.dir);
+ directions = metadata.turnLanes[d.dir][d.index];
+
+ // TODO: fix this vv
+ if (!directions) return '';
+ var dir = directions.sort(function (a, b) {
+ return a.charCodeAt(0) - b.charCodeAt(0);
+ });
+ dir = dir.join('-');
+ if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+
+ return dir;
+ }
};
}
From 99c50676909328be06a800784638a0b2c935b930 Mon Sep 17 00:00:00 2001
From: Bryan Housel
Date: Wed, 1 Feb 2017 18:03:09 -0500
Subject: [PATCH 12/25] Cleanup, simplify, and add some d3 commentary
---
modules/svg/lanes.js | 212 +++++++++++++++++++++++--------------------
1 file changed, 113 insertions(+), 99 deletions(-)
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 1069651c629..d29da9b09bf 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -17,78 +17,123 @@ import { geoPointInPolygon } from '../geo';
export function svgLanes(projection, context) {
- return function drawMidpoints(selection, graph, entities, filter, extent, mapCenter) {
- // return;
+ return function drawLanes(selection, graph, entities, filter, extent, mapCenter) {
var entity = getEntity();
- var showLanes = [];
var metadata;
- var iconPosition;
var driveLeft;
var layoutSeq = [];
- const iconWidth = 40;
+ var iconWidth = 40;
+
// TODO: on removing map features svgLanes stays there
if (entity) {
metadata = entity.lanes().metadata;
- iconPosition = findPosition();
driveLeft = isDriveLeft();
layoutSeq = getLayoutSeq(metadata, driveLeft, 'turnLanes');
- layer = selection.selectAll('.layer-hit');
- if (iconPosition) {
- showLanes = [0];
- }
}
- var layer = selection.selectAll('.layer-hit');
-
- var groups = layer
- .selectAll('g.lanes-visual')
- .data(showLanes);
- groups.exit()
+ var wrapperData = findPosition();
+
+ // wrapper DATA BIND
+ // `wrapperData` is an array set up how we want the DOM to look.
+ // Always think about data first when working with D3!
+ // The `data` bind matches DOM nodes to wrapperData array elements
+ // Each DOM node bound to data will have a special __data__ property
+ // you can see it in Chrome developer tools
+ var wrapper = selection.selectAll('.layer-hit')
+ .selectAll('.lanes-wrapper')
+ .data(wrapperData ? [wrapperData] : []);
+
+ // wrapper EXIT
+ // exit selection includes existing DOM nodes with no match in wrapperData
+ // if you don't remove them, they just stay around forever.
+ wrapper.exit()
.remove();
- var enter = groups.enter()
+ // wrapper ENTER
+ // enter selection includes wrapperData with no match to DOM nodes
+ // the normal thing to do here is create the missing DOM nodes
+ var enter = wrapper.enter()
.insert('g', ':first-child')
- .attr('class', 'lanes-visual');
+ .attr('class', 'lanes-wrapper');
- var wrapper = enter
- .append('g')
- .attr('class', 'lanes-visual-wrapper');
+ enter
+ .append('rect')
+ .attr('class', 'lanes-background');
- wrapper.append('rect')
- .attr('class', 'lane-visual-background');
+ // enter.append('polygon')
+ // .attr('points', '-3,4 5,0 -3,-4')
+ // .attr('class', 'fill');
- wrapper.append('g')
- .attr('class', 'lane-visual-items');
- layer
- .selectAll('.lanes-visual-wrapper')
- .attr('transform', function () {
- return 'translate(' + metadata.count * iconWidth / (-2) + ', 0)';
- });
+ // wrapper UPDATE
+ // update selection runs every time for all the matched DOM elements.
+ // `merge` brings in the nodes that were just entered
+ // Assignment is important here because selections are immutable,
+ // so we need to replace wrapper with the new wrapper before using it.
+ wrapper = wrapper
+ .merge(enter);
- selection.selectAll('rect')
- .attr('width', function () {
- return metadata.count * iconWidth;
- })
- .attr('height', function () {
- return iconWidth;
+ wrapper
+ .attr('transform', function (d) {
+ var p = projection(d.loc),
+ a = graph.entity(d.edge[0]),
+ b = graph.entity(d.edge[1]),
+ ang = Math.round(geoAngle(a, b, projection) * (180 / Math.PI)) + 90;
+
+ p[0] -= metadata.count * iconWidth / 2;
+ return 'translate(' + p[0] + ',' + p[1] + ') rotate(' + ang + ')';
});
- var button = groups.selectAll('lane-visual-items')
- .data(layoutSeq)
- .enter()
+ wrapper.selectAll('.lanes-background')
+ .attr('width', function () { return metadata.count * iconWidth; })
+ .attr('height', function () { return iconWidth; });
+
+
+
+ // lanes DATA BIND
+ var lanes = wrapper.selectAll('.lanes-lane')
+ .data(layoutSeq);
+
+ // lanes EXIT
+ lanes.exit()
+ .remove();
+
+ // lanes ENTER
+ enter = lanes.enter()
.append('g')
- .attr('class', 'lane-visual-items radial-menu-item radial-menu-item-move')
+ .attr('class', 'lanes-lane');
+
+ enter
+ .append('circle')
+ .attr('class', 'lanes-circle')
+ .attr('r', 15);
+
+ enter
+ .append('use')
+ .attr('transform', 'translate(-10,-13)')
+ .attr('width', '20')
+ .attr('height', '20')
+ .attr('xlink:href', function (d) {
+ // return '#lane-' + createSVGLink(d);
+ return '#icon-up';
+ });
+
+ // lanes UPDATE
+ lanes = lanes
+ .merge(enter);
+
+ lanes
.attr('transform', function (d, i) {
- var reverse = 0;
- if (d.dir === 'backward') {
- reverse = 180;
- }
- return 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ') rotate(' + reverse + ')';
+ var transform = 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ')';
+ if (d.dir === 'backward') { transform += ' rotate(180)'; }
+ return transform;
});
- button
- .append('circle')
+ // Watch out! `select` here not only selects the first .lanes-circle node,
+ // but it also propagates __data__ from lanes down to that circle. In this
+ // situation, it's the behavior we want, so we can style the circle based on `d.dir`.
+ // `select` propagates __data__ to children, `selectAll` does not.
+ lanes.select('.lanes-circle')
.style('fill', function (d) {
switch (d.dir) {
case 'forward':
@@ -96,42 +141,11 @@ export function svgLanes(projection, context) {
case 'backward':
return '#ffd8d8';
default:
- return '';
+ return '#d8d8d8';
}
- })
- .attr('r', 15);
-
- button
- .append('use')
- .attr('transform', 'translate(-15,-12)')
- .attr('width', '20')
- .attr('height', '20')
- .attr('xlink:href', function (d) {
- console.log(d);
- return '#lane-' + createSVGLink(d);
});
- enter.append('polygon')
- .attr('points', '-3,4 5,0 -3,-4')
- .attr('class', 'fill');
- groups = groups
- .merge(enter)
- .attr('transform', function (d) {
- var translate = svgPointTransform(projection),
- a = graph.entity(iconPosition.edge[0]),
- b = graph.entity(iconPosition.edge[1]);
- var angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI)) + 90;
- return translate(iconPosition) + ' rotate(' + angleVal + ')';
- })
- .call(svgTagClasses().tags(
- // TODO: what if entity is null
- function () { return entity && entity.tags; }
- ));
-
- // Propagate data bindings.
- groups.select('polygon.shadow');
- groups.select('polygon.fill');
function isDriveLeft() {
return _.some(dataDriveLeft.features, function (f) {
@@ -141,6 +155,7 @@ export function svgLanes(projection, context) {
});
}
+
function getEntity() {
if (context.selectedIDs().length !== 1) return null;
var entity = graph.entity(context.selectedIDs()[0]);
@@ -151,14 +166,11 @@ export function svgLanes(projection, context) {
return entity;
}
+
function findPosition() {
var loc;
- if (!entity) {
- return {
- loc: undefined,
- edge: []
- };
- }
+ if (!entity) return;
+
var nodes = graph.childNodes(entity);
var poly = extent.polygon();
@@ -189,21 +201,23 @@ export function svgLanes(projection, context) {
}
}
}
- function createSVGLink(d) {
- var directions;
- console.log(d.dir);
- directions = metadata.turnLanes[d.dir][d.index];
-
- // TODO: fix this vv
- if (!directions) return '';
- var dir = directions.sort(function (a, b) {
- return a.charCodeAt(0) - b.charCodeAt(0);
- });
- dir = dir.join('-');
- if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
- return dir;
- }
+
+ // function createSVGLink(d) {
+ // var directions;
+ // console.log(d.dir);
+ // directions = metadata.turnLanes[d.dir][d.index];
+
+ // // TODO: fix this vv
+ // if (!directions) return '';
+ // var dir = directions.sort(function (a, b) {
+ // return a.charCodeAt(0) - b.charCodeAt(0);
+ // });
+ // dir = dir.join('-');
+ // if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+
+ // return dir;
+ // }
};
}
From 883316dfc5275af47152bc0906c170374bb39da2 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 2 Feb 2017 11:55:33 +0530
Subject: [PATCH 13/25] svgLanes update fix
---
modules/modes/select.js | 18 +-----------------
modules/osm/lanes.js | 22 +++++++++++++++++++---
modules/svg/lanes.js | 34 +++++++++-------------------------
modules/svg/midpoints.js | 2 +-
modules/ui/fields/lanes.js | 1 -
modules/ui/lane_visualizer.js | 1 -
modules/ui/radial_menu.js | 2 --
7 files changed, 30 insertions(+), 50 deletions(-)
diff --git a/modules/modes/select.js b/modules/modes/select.js
index 29427f731f9..d87c76c984c 100644
--- a/modules/modes/select.js
+++ b/modules/modes/select.js
@@ -28,7 +28,7 @@ import {
import { modeBrowse } from './browse';
import { modeDragNode } from './drag_node';
import * as Operations from '../operations/index';
-import { uiRadialMenu, uiLaneVisualizer, uiSelectionList } from '../ui/index';
+import { uiRadialMenu, uiSelectionList } from '../ui/index';
import { uiCmd } from '../ui/cmd';
import { utilEntityOrMemberSelector, utilEntitySelector } from '../util/index';
@@ -54,7 +54,6 @@ export function modeSelect(context, selectedIDs) {
modeDragNode(context).selectedIDs(selectedIDs).behavior
],
inspector,
- laneVisualizer,
radialMenu,
newFeature = false,
suppressMenu = false,
@@ -143,20 +142,11 @@ export function modeSelect(context, selectedIDs) {
if (radialMenu) {
context.surface().call(radialMenu.close);
}
- if (laneVisualizer) {
- context.surface().call(laneVisualizer.close);
- }
}
function positionMenu() {
var entity = singular();
-
- if (entity && laneVisualizer && entity.type === 'way') {
- laneVisualizer.center(context.mouse());
- laneVisualizer.wayID(entity.id);
- }
-
if (suppressMenu || !radialMenu) { return; }
if (entity && context.geometry(entity.id) === 'relation') {
@@ -182,9 +172,6 @@ export function modeSelect(context, selectedIDs) {
if (!suppressMenu && radialMenu) {
context.surface().call(radialMenu);
}
- if (laneVisualizer) {
- context.surface().call(laneVisualizer);
- }
}
@@ -442,8 +429,6 @@ export function modeSelect(context, selectedIDs) {
radialMenu = uiRadialMenu(context, operations);
- laneVisualizer = uiLaneVisualizer(context);
-
context.ui().sidebar
.select(singular() ? singular().id : null, newFeature);
@@ -503,7 +488,6 @@ export function modeSelect(context, selectedIDs) {
keybinding.off();
closeMenu();
radialMenu = undefined;
- laneVisualizer = undefined;
context.history()
.on('undone.select', null)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 2a77477eff4..b5883d8ff49 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -295,7 +295,7 @@ export function getLayoutSeq(metadata, leftHand, kind) {
return _.fill(Array(metadata.count), 0).map(function (n, i) {
return {
dir: 'unspecified',
- lanes: metadata[kind].unspecified,
+ turnLanes: createSVGLink(metadata.turnLanes.unspecified[i]),
index: i
};
});
@@ -307,14 +307,14 @@ export function getLayoutSeq(metadata, leftHand, kind) {
var forSeq = _.fill(Array(forward), 0).map(function (n, i) {
return {
dir: 'forward',
- lanes: metadata[kind].forward,
+ turnLanes: createSVGLink(metadata.turnLanes.forward[i]),
index: i
};
});
var backSeq = _.fill(Array(backward), 0).map(function (n, i) {
return {
dir: 'backward',
- lanes: metadata[kind].backward,
+ turnLanes: createSVGLink(metadata.turnLanes.backward[backward - i - 1]),
index: backward - i - 1
};
});
@@ -325,4 +325,20 @@ export function getLayoutSeq(metadata, leftHand, kind) {
return [].concat(backSeq, forSeq);
}
+function createSVGLink(dirArray) {
+ var directions =_.cloneDeep(dirArray);
+ // console.log(d.dir);
+ // directions = metadata.turnLanes[d.dir][d.index];
+
+ // TODO: fix this vv
+ if (!directions) return '';
+ var dir = directions.sort(function (a, b) {
+ return a.charCodeAt(0) - b.charCodeAt(0);
+ });
+ dir = dir.join('-');
+ if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+
+ return dir;
+ }
+
window.getLayoutSeq = getLayoutSeq;
\ No newline at end of file
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index d29da9b09bf..af4851f307f 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -79,12 +79,13 @@ export function svgLanes(projection, context) {
a = graph.entity(d.edge[0]),
b = graph.entity(d.edge[1]),
ang = Math.round(geoAngle(a, b, projection) * (180 / Math.PI)) + 90;
-
- p[0] -= metadata.count * iconWidth / 2;
return 'translate(' + p[0] + ',' + p[1] + ') rotate(' + ang + ')';
});
wrapper.selectAll('.lanes-background')
+ .attr('transform', function () {
+ return 'translate(' + metadata.count * iconWidth / (-2) + ', 0)';
+ })
.attr('width', function () { return metadata.count * iconWidth; })
.attr('height', function () { return iconWidth; });
@@ -112,11 +113,7 @@ export function svgLanes(projection, context) {
.append('use')
.attr('transform', 'translate(-10,-13)')
.attr('width', '20')
- .attr('height', '20')
- .attr('xlink:href', function (d) {
- // return '#lane-' + createSVGLink(d);
- return '#icon-up';
- });
+ .attr('height', '20');
// lanes UPDATE
lanes = lanes
@@ -124,9 +121,13 @@ export function svgLanes(projection, context) {
lanes
.attr('transform', function (d, i) {
- var transform = 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ')';
+ var transform = 'translate(' + [iconWidth / 2 + i * iconWidth - metadata.count * iconWidth / (2) , (iconWidth / 2)] + ')';
if (d.dir === 'backward') { transform += ' rotate(180)'; }
return transform;
+ })
+ .select('use')
+ .attr('xlink:href', function (d) {
+ return '#lane-' + d.turnLanes;
});
// Watch out! `select` here not only selects the first .lanes-circle node,
@@ -201,23 +202,6 @@ export function svgLanes(projection, context) {
}
}
}
-
-
- // function createSVGLink(d) {
- // var directions;
- // console.log(d.dir);
- // directions = metadata.turnLanes[d.dir][d.index];
-
- // // TODO: fix this vv
- // if (!directions) return '';
- // var dir = directions.sort(function (a, b) {
- // return a.charCodeAt(0) - b.charCodeAt(0);
- // });
- // dir = dir.join('-');
- // if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
-
- // return dir;
- // }
};
}
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index b75c672c2e6..78a4360feb9 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -17,7 +17,7 @@ export function svgMidpoints(projection, context) {
return function drawMidpoints(selection, graph, entities, filter, extent) {
var poly = extent.polygon(),
midpoints = {};
- return;
+
for (var i = 0; i < entities.length; i++) {
var entity = entities[i];
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 1a763054118..842299ecc48 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -1,7 +1,6 @@
import * as d3 from 'd3';
import { utilRebind } from '../../util/rebind';
import { utilGetDimensions } from '../../util/dimensions';
-import { uiFieldCheck } from './check';
import _ from 'lodash';
import { utilGetSetValue } from '../../util/get_set_value';
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
index b55a3449b82..37ffa5c765e 100644
--- a/modules/ui/lane_visualizer.js
+++ b/modules/ui/lane_visualizer.js
@@ -16,7 +16,6 @@ export function uiLaneVisualizer(context) {
var laneVisualizer = function (selection) {
if (!wayId) return;
- return;
metadata = context.entity(wayId).lanes().metadata;
if (!metadata) return;
diff --git a/modules/ui/radial_menu.js b/modules/ui/radial_menu.js
index 0f545f7a2db..1abc0ebff20 100644
--- a/modules/ui/radial_menu.js
+++ b/modules/ui/radial_menu.js
@@ -9,7 +9,6 @@ export function uiRadialMenu(context, operations) {
tooltip;
var radialMenu = function(selection) {
- if (operations) return;
if (!operations.length) return;
selection.node().parentNode.focus();
@@ -47,7 +46,6 @@ export function uiRadialMenu(context, operations) {
.attr('stroke-width', 50)
.attr('stroke-linecap', 'round');
- console.log(operations);
var button = menu.selectAll()
.data(operations)
.enter()
From 2f813e1659b0a89fe19b49b11963743c1972104c Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 2 Feb 2017 13:10:11 +0530
Subject: [PATCH 14/25] add right flipping of turnLanes
---
modules/osm/lanes.js | 10 +-
modules/renderer/map.js | 4 +-
modules/svg/lanes.js | 8 +-
modules/ui/fields/lanes.js | 25 +----
modules/ui/index.js | 2 -
modules/ui/lane_visualizer.js | 167 ----------------------------------
svg/iD-sprite.src.svg | 6 +-
7 files changed, 20 insertions(+), 202 deletions(-)
delete mode 100644 modules/ui/lane_visualizer.js
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index b5883d8ff49..d34e5c61cd0 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -1,5 +1,9 @@
import _ from 'lodash';
+export var validTurnLanes = [
+ 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
+ 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
+];
export function osmLanes(entity) {
if (entity.type !== 'way') return null;
@@ -188,17 +192,13 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
function parseTurnLanes(tag){
if (!tag) return [];
// TODO: need to add reverse_left and reverse_right
- 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;
+ return validTurnLanes.indexOf(d) === -1 ? 'unknown': d;
});
});
}
diff --git a/modules/renderer/map.js b/modules/renderer/map.js
index baf0fed15fe..9b8794fc016 100644
--- a/modules/renderer/map.js
+++ b/modules/renderer/map.js
@@ -162,7 +162,7 @@ export function rendererMap(context) {
surface.selectAll('.data-layer-osm')
.call(drawVertices, graph, all, filter, map.extent(), map.zoom())
.call(drawMidpoints, graph, all, filter, map.trimmedExtent())
- .call(drawLanes, graph, all, filter, map.trimmedExtent(), map.center());
+ .call(drawLanes, graph, all, filter, map.trimmedExtent(), map.zoom(), map.center());
dispatch.call('drawn', this, {full: false});
}
});
@@ -255,7 +255,7 @@ export function rendererMap(context) {
.call(drawLines, graph, data, filter)
.call(drawAreas, graph, data, filter)
.call(drawMidpoints, graph, data, filter, map.trimmedExtent())
- .call(drawLanes, graph, data, filter, map.trimmedExtent(), map.center())
+ .call(drawLanes, graph, data, filter, map.trimmedExtent(), map.zoom(), map.center())
.call(drawLabels, graph, data, filter, dimensions, !difference && !extent)
.call(drawPoints, graph, data, filter);
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index af4851f307f..3f44a109f48 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -17,12 +17,13 @@ import { geoPointInPolygon } from '../geo';
export function svgLanes(projection, context) {
- return function drawLanes(selection, graph, entities, filter, extent, mapCenter) {
+ return function drawLanes(selection, graph, entities, filter, extent, zoom, mapCenter) {
var entity = getEntity();
var metadata;
var driveLeft;
var layoutSeq = [];
var iconWidth = 40;
+ var zoomLimit = zoom >= 18;
// TODO: on removing map features svgLanes stays there
if (entity) {
@@ -41,7 +42,7 @@ export function svgLanes(projection, context) {
// you can see it in Chrome developer tools
var wrapper = selection.selectAll('.layer-hit')
.selectAll('.lanes-wrapper')
- .data(wrapperData ? [wrapperData] : []);
+ .data(wrapperData && zoomLimit ? [wrapperData] : []);
// wrapper EXIT
// exit selection includes existing DOM nodes with no match in wrapperData
@@ -122,12 +123,13 @@ export function svgLanes(projection, context) {
lanes
.attr('transform', function (d, i) {
var transform = 'translate(' + [iconWidth / 2 + i * iconWidth - metadata.count * iconWidth / (2) , (iconWidth / 2)] + ')';
+ transform += d.turnLanes.indexOf('right') > -1 ? ' scale(-1, 1)' : '';
if (d.dir === 'backward') { transform += ' rotate(180)'; }
return transform;
})
.select('use')
.attr('xlink:href', function (d) {
- return '#lane-' + d.turnLanes;
+ return '#lane-' + d.turnLanes.split('right').join('left');
});
// Watch out! `select` here not only selects the first .lanes-circle node,
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 842299ecc48..486a33034e2 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -3,12 +3,7 @@ import { utilRebind } from '../../util/rebind';
import { utilGetDimensions } from '../../util/dimensions';
import _ from 'lodash';
import { utilGetSetValue } from '../../util/get_set_value';
-
-var validLanes = [
- 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
- 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
-];
-
+import { validTurnLanes } from '../../osm/lanes';
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
@@ -17,22 +12,18 @@ export function uiFieldLanes(field, context) {
currentLane = 0,
curDirection = 'unspecified',
wayID,
- lanesData,
- driveLeft;
+ lanesData;
function lanes(selection) {
lanesData = context.entity(wayID).lanes();
window.lanesData = lanesData;
- window.currentLane = currentLane;
- window.curDirection = curDirection;
-
+
if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
selection.call(lanes.off);
return;
}
-
var lanesInfo = selection.selectAll('.lanes-info').data([0]);
lanesInfo = lanesInfo.enter()
.append('div')
@@ -59,17 +50,11 @@ export function uiFieldLanes(field, context) {
var wrap = selection.selectAll('.lane-input-wrap')
.data([0]);
- wrap = wrap.enter()
+ wrap.enter()
.append('div')
.attr('class', 'lane-input-wrap')
.merge(wrap);
- var surface = wrap.selectAll('.surface')
- .data([0]);
-
- var d = utilGetDimensions(wrap);
- var freeSpace = d[0] - lanesData.metadata.count * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
-
function render() {
if (context.hasEntity(wayID)) {
lanes(selection);
@@ -192,7 +177,7 @@ export function uiFieldLanes(field, context) {
var label = wrap.selectAll('.label')
- .data(validLanes);
+ .data(validTurnLanes);
var labelEnter = label.enter()
.append('label');
diff --git a/modules/ui/index.js b/modules/ui/index.js
index 050dcd0e5a5..37bfc22cc9b 100644
--- a/modules/ui/index.js
+++ b/modules/ui/index.js
@@ -47,5 +47,3 @@ export { uiTooltipHtml } from './tooltipHtml';
export { uiUndoRedo } from './undo_redo';
export { uiViewOnOSM } from './view_on_osm';
export { uiZoom } from './zoom';
-
-export { uiLaneVisualizer } from './lane_visualizer';
\ No newline at end of file
diff --git a/modules/ui/lane_visualizer.js b/modules/ui/lane_visualizer.js
deleted file mode 100644
index 37ffa5c765e..00000000000
--- a/modules/ui/lane_visualizer.js
+++ /dev/null
@@ -1,167 +0,0 @@
-import * as d3 from 'd3';
-import _ from 'lodash';
-import { geoAngle, geoChooseEdge } from '../geo/index';
-import { getLayoutSeq } from '../osm/lanes';
-import { dataDriveLeft } from '../../data';
-import { geoPointInPolygon } from '../geo';
-
-export function uiLaneVisualizer(context) {
- var menu,
- wrapper,
- wayId,
- center = [0, 0],
- tooltip,
- metadata,
- driveLeft;
-
- var laneVisualizer = function (selection) {
- if (!wayId) return;
- metadata = context.entity(wayId).lanes().metadata;
- if (!metadata) return;
-
- const iconWidth = 40;
- const count = metadata.count;
-
- var projection = context.projection;
- var graph = context.graph();
- var way = graph.entity(wayId);
-
- var loc = way.extent(context.graph()).center();
- driveLeft = _.some(dataDriveLeft.features, function(f) {
- return _.some(f.geometry.coordinates, function(d) {
- return geoPointInPolygon(loc, d);
- });
- });
-
- var layout = getLayoutSeq(metadata, driveLeft);
-
- var nodes = _.uniq(graph.childNodes(way));
- var choice = geoChooseEdge(nodes, context.mouse(), context.projection);
- var prev = nodes[choice.index - 1];
- var next = nodes[choice.index];
- var angle = (geoAngle(prev, next, projection) * 180 / Math.PI);
-
- context.history()
- .on('change.lanes', render);
-
- selection.node().parentNode.focus();
-
- function click() {
- d3.event.stopPropagation();
- laneVisualizer.close();
- }
-
- wrapper = selection
- .append('g')
- .attr('class', 'lane-visualizer')
- // .attr('transform', 'translate('+ center + ')')
- .attr('transform', 'translate(' + center + ') rotate(' + (angle+ 90) + ')')
- .attr('opacity', 0);
-
- wrapper
- .transition()
- .attr('opacity', 1);
-
- var menu = wrapper
- .append('g')
- .attr('transform', 'translate(' + count*iconWidth/(-2) + ', 0)');
-
- menu
- .append('rect')
- .attr('class', 'lane-visualizer-background')
- .attr('width', count* iconWidth)
- .attr('height', iconWidth);
-
- var button = menu.selectAll()
- .data(layout)
- .enter()
- .append('g')
- .attr('class', 'radial-menu-item radial-menu-item-move')
- .attr('transform', function (d, i) {
- var reverse = 0;
- if (d.dir === 'backward') {
- reverse = 180;
- }
- return 'translate(' + [iconWidth / 2 + i * iconWidth, (iconWidth / 2)] + ') rotate(' + reverse + ')';
- });
-
- button
- .append('circle')
- .style('fill', function(d) {
- switch (d.dir) {
- case 'forward':
- return '#dfffdf';
- case 'backward':
- return '#ffd8d8';
- default:
- return '';
- }
- })
- .attr('r', 15);
-
- button
- .append('use')
- .attr('transform', 'translate(-15,-12)')
- .attr('width', '20')
- .attr('height', '20')
- .attr('xlink:href', function (d) {
- return '#lane-' + createSVGLink(d);
- });
-
-
- function render() {
- if (context.hasEntity(wayId)) {
- laneVisualizer.close();
- laneVisualizer(selection);
- }
- }
-
- };
- function createSVGLink(d) {
- var directions;
- console.log(d.dir);
- directions = metadata.turnLanes[d.dir][d.index];
-
- // TODO: fix this vv
- if (!directions) return '';
- var dir = directions.sort(function (a, b) {
- return a.charCodeAt(0) - b.charCodeAt(0);
- });
- dir = dir.join('-');
- if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
-
- return dir;
- }
- laneVisualizer.center = function (_) {
- if (!arguments.length) return center;
- center = _;
- return laneVisualizer;
- };
-
-
- laneVisualizer.wayID = function (_) {
- if (!arguments.length) return _;
- wayId = _;
- return laneVisualizer;
- };
-
- laneVisualizer.close = function () {
- if (wrapper) {
-
- wrapper
- .style('pointer-events', 'none')
- .transition()
- .attr('opacity', 0)
- .remove();
-
- context.history()
- .on('change.lanes', null);
- }
-
-
- if (tooltip) {
- tooltip.remove();
- }
- };
- return laneVisualizer;
-}
diff --git a/svg/iD-sprite.src.svg b/svg/iD-sprite.src.svg
index 859baae60fc..97808e72a32 100644
--- a/svg/iD-sprite.src.svg
+++ b/svg/iD-sprite.src.svg
@@ -210,12 +210,12 @@
-
+
-
+
@@ -225,7 +225,7 @@
-
+
From 9104b018b6ee9b2e6c23485e5fedc9a8e527d8ef Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Thu, 2 Feb 2017 19:27:05 +0530
Subject: [PATCH 15/25] add lane count check
---
modules/osm/lanes.js | 271 +++++++--------
modules/ui/fields/lanes.js | 6 +-
test/spec/osm/lanes.js | 652 ++++++++++++++++++++++---------------
3 files changed, 513 insertions(+), 416 deletions(-)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index d34e5c61cd0..03c9569c9b1 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -14,13 +14,6 @@ export function osmLanes(entity) {
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;
-
- // sometimes just forward and backward are available
- laneCount = laneDirections.laneCount;
// TODO: if you change the forward backward and click on trash at top,
// laneCount and forward/backward goes out of sync
@@ -71,47 +64,59 @@ export function osmLanes(entity) {
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');
-
// TODO: need to make sure forward lanes is consistent across all tags,
// eg if psv:lanes:forward is 3 and lanes:forward is 2, changes lanes:forward =3,
var 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,
- reverse: parseInt(tags.oneway, 10) === -1
+ count: laneCount,
+ oneway: isOneWay,
+ turnLanes: turnLanes,
+ maxspeedLanes: maxspeedLanes,
+ psvLanes: psvLanes,
+ busLanes: busLanes,
+ taxiLanes: taxiLanes,
+ hovLanes: hovLanes,
+ hgvLanes: hgvLanes,
+ bicyclewayLanes: bicyclewayLanes,
+ reverse: parseInt(tags.oneway, 10) === -1
};
+
+ tallyLaneCount(metadata);
+ parseLaneDirections(tags, isOneWay, metadata);
+
return {
metadata: metadata,
- lanes: lanesObj
+ getLayoutSeq: getLayoutSeq
};
}
+// Overides the lanes, lanes:forward, lanes:backward
+// if the other lane tags dont tally.
+function tallyLaneCount(metadata) {
+ var consideredLaneTags = ['busLanes', 'hgvLanes', 'hovLanes', 'psvLanes', 'taxiLanes', 'turnLanes'];
+ var maxUnspecified = 0;
+ var maxForward = 0;
+ var maxBackward = 0;
+
+ consideredLaneTags.forEach(function (tag) {
+ if (metadata[tag].unspecified.length > maxUnspecified)
+ maxUnspecified = metadata[tag].unspecified.length;
+
+ if (metadata[tag].forward.length > maxForward)
+ maxForward = metadata[tag].forward.length;
+
+ if (metadata[tag].backward.length > maxBackward)
+ maxBackward = metadata[tag].backward.length;
+ });
+
+ if (metadata.oneway) {
+ metadata.count = maxUnspecified > metadata.count ? maxUnspecified : metadata.count;
+ } else {
+ metadata.forward = maxForward > 0 ? maxForward : undefined;
+ metadata.backward = maxBackward > 0 ? maxBackward : undefined;
+ }
+ // TODO: how to update if they decrease metadata.forward and the array would be bigger
+ // this function would override it.
+}
function getLaneCount(tags, isOneWay) {
var count;
@@ -122,7 +127,6 @@ function getLaneCount(tags, isOneWay) {
}
}
-
switch (tags.highway) {
case 'trunk':
case 'motorway':
@@ -136,7 +140,7 @@ function getLaneCount(tags, isOneWay) {
return count;
}
-
+// TODO: needs fix, difference between maxspeed and lane:maxspeed
function parseMaxspeed(tags) {
var maxspeed = tags.maxspeed;
if (_.isNumber(maxspeed)) return maxspeed;
@@ -147,23 +151,22 @@ function parseMaxspeed(tags) {
}
}
-
-function parseLaneDirections(tags, isOneWay, laneCount) {
- var forward = parseInt(tags['lanes:forward'], 10);
- var backward = parseInt(tags['lanes:backward'], 10);
+// gives priority to '*:lanes:direction' over 'lanes:direction'
+function parseLaneDirections(tags, isOneWay, metadata) {
+ var laneCount = metadata.count;
+ var forward = metadata.forward || parseInt(tags['lanes:forward'], 10);
+ var backward = metadata.backward || parseInt(tags['lanes:backward'], 10);
var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
- var count = laneCount;
- if (parseInt(tags.oneway, 10) === -1) {
- forward = 0;
- bothways = 0;
- backward = laneCount;
- }
- else if (isOneWay) {
- forward = laneCount;
- bothways = 0;
- backward = 0;
+
+ // should just rely on lane count
+ if (isOneWay) {
+ metadata.forward = 0;
+ metadata.bothways = 0;
+ metadata.backward = 0;
+ return;
}
- else if (_.isNaN(forward) && _.isNaN(backward)) {
+
+ if (_.isNaN(forward) && _.isNaN(backward)) {
backward = Math.floor((laneCount - bothways) / 2);
forward = laneCount - bothways - backward;
}
@@ -179,17 +182,15 @@ function parseLaneDirections(tags, isOneWay, laneCount) {
}
backward = laneCount - bothways - forward;
}
+ metadata.forward = forward;
+ metadata.bothways = bothways;
+ metadata.backward = backward;
+ metadata.count = forward + backward + bothways;
- return {
- forward: forward,
- backward: backward,
- bothways: bothways,
- laneCount: forward + backward+ bothways
- };
+ return;
}
-
-function parseTurnLanes(tag){
+function parseTurnLanes(tag) {
if (!tag) return [];
// TODO: need to add reverse_left and reverse_right
@@ -198,7 +199,7 @@ function parseTurnLanes(tag){
if (s === '') s = 'none';
return s.split(';')
.map(function (d) {
- return validTurnLanes.indexOf(d) === -1 ? 'unknown': d;
+ return validTurnLanes.indexOf(d) === -1 ? 'unknown' : d;
});
});
}
@@ -212,7 +213,7 @@ function parseMaxspeedLanes(tag, maxspeed) {
if (s === 'none') return s;
var m = parseInt(s, 10);
if (s === '' || m === maxspeed) return null;
- return _.isNaN(m) ? 'unknown': m;
+ return _.isNaN(m) ? 'unknown' : m;
});
}
@@ -227,7 +228,7 @@ function parseMiscLanes(tag) {
return tag.split('|')
.map(function (s) {
if (s === '') s = 'no';
- return validValues.indexOf(s) === -1 ? 'unknown': s;
+ return validValues.indexOf(s) === -1 ? 'unknown' : s;
});
}
@@ -242,103 +243,71 @@ function parseBicycleWay(tag) {
return tag.split('|')
.map(function (s) {
if (s === '') s = 'no';
- return validValues.indexOf(s) === -1 ? 'unknown': s;
+ return validValues.indexOf(s) === -1 ? 'unknown' : s;
});
}
+// TODO: exporting it directly since parameter leftHand is needed
+export function getLayoutSeq(metadata, leftHand) {
-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;
- });
-}
-
-function lanesArray(lanesData) {
- var metadata = _.cloneDeep(lanesData);
- // var arr = new Array(metadata.count);
- var consideredLaneTags = [ 'busLanes', 'hgvLanes', 'hovLanes', 'maxspeedLanes', 'psvLanes', 'taxiLanes', 'turnLanes' ];
- var obj = {};
-
- obj.forward = new Array(metadata.forward);
- obj.backward = new Array(metadata.backward);
- // obj.bothways = new Array(metadata.bothways); // jo
- obj.unspecified = new Array(metadata.count); //_.fill(Array(metadata.count), { });
-
- consideredLaneTags.forEach(function (laneTag) {
- var lane = metadata[laneTag];
- Object.keys(lane).forEach(function (direction) {
- lane[direction]
- .forEach(function (tag, i) {
- if (!obj[direction][i]) obj[direction][i] = {};
- if (i < obj[direction].length) {
- obj[direction][i][laneTag] = tag;
- }
- });
- });
- });
-
- return obj;
-}
+ function turnLanesSeq(obj) {
+ var dir = obj.dir;
+ var index = obj.index;
+ // will be '' if array goes out of bound
+ obj.turnLanes = createSVGLink(metadata.turnLanes[dir][index]);
+ return obj;
+ }
-export function getLayoutSeq(metadata, leftHand, kind) {
if (!metadata) return [];
+
+ var seq = [];
+
if (metadata.oneway) {
- return _.fill(Array(metadata.count), 0).map(function (n, i) {
+ seq = _.fill(Array(metadata.count), 0)
+ .map(function (n, i) {
+ return {
+ dir: 'unspecified',
+ index: i
+ };
+ });
+ } else {
+ var forward = metadata.forward;
+ var backward = metadata.backward;
+
+ var forSeq = _.fill(Array(forward), 0).map(function (n, i) {
return {
- dir: 'unspecified',
- turnLanes: createSVGLink(metadata.turnLanes.unspecified[i]),
+ dir: 'forward',
index: i
};
});
+ // backward seq is always reversed in any hand drive.
+ // eg: turn:lanes:backward=0|1|2|3, turn:lanes:forward=0|1|2
+ // LHD = 0,1,23,2,1,0; RHD= 3,2,1,00,1,2
+ var backSeq = _.fill(Array(backward), 0).map(function (n, i) {
+ return {
+ dir: 'backward',
+ index: backward - i - 1
+ };
+ });
+
+ seq = leftHand ? [].concat(forSeq, backSeq)
+ : [].concat(backSeq, forSeq);
}
-
- var forward = metadata.forward;
- var backward = metadata.backward;
-
- var forSeq = _.fill(Array(forward), 0).map(function (n, i) {
- return {
- dir: 'forward',
- turnLanes: createSVGLink(metadata.turnLanes.forward[i]),
- index: i
- };
- });
- var backSeq = _.fill(Array(backward), 0).map(function (n, i) {
- return {
- dir: 'backward',
- turnLanes: createSVGLink(metadata.turnLanes.backward[backward - i - 1]),
- index: backward - i - 1
- };
- });
-
- if (leftHand) {
- return [].concat(forSeq, backSeq);
- }
- return [].concat(backSeq, forSeq);
-}
-function createSVGLink(dirArray) {
- var directions =_.cloneDeep(dirArray);
- // console.log(d.dir);
- // directions = metadata.turnLanes[d.dir][d.index];
+ seq = seq
+ .map(turnLanesSeq);
- // TODO: fix this vv
- if (!directions) return '';
- var dir = directions.sort(function (a, b) {
- return a.charCodeAt(0) - b.charCodeAt(0);
- });
- dir = dir.join('-');
- if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
+ return seq;
+}
- return dir;
- }
+function createSVGLink(directions) {
+ if (!directions || !_.isArray(directions)) return '';
+ var dir = _.cloneDeep(directions).sort(function (a, b) {
+ // lane icons are sorted in lexical order
+ return a.charCodeAt(0) - b.charCodeAt(0);
+ });
+ dir = dir.join('-');
+ if (dir.indexOf('unknown') > -1 || dir.length === 0) return 'unknown';
-window.getLayoutSeq = getLayoutSeq;
\ No newline at end of file
+ return dir;
+}
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 486a33034e2..de5ef4fb608 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -335,11 +335,11 @@ export function uiFieldLanes(field, context) {
tag['turn:lanes:forward'] = undefined;
tag['turn:lanes:backward'] = undefined;
} else {
- tag.lanes = (metadata.forward + metadata.backward) + '';
+ tag.lanes = (metadata.forward + metadata.backward) + ''; //TODO: add bothways
tag['lanes:forward'] = metadata.forward + '';
tag['lanes:backward'] = metadata.backward + '';
-
+
tag['turn:lanes'] = undefined;
tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
@@ -349,6 +349,8 @@ export function uiFieldLanes(field, context) {
console.log('turn:lane ===',tag['turn:lanes']);
console.log('turn:lane;forward ==',tag['turn:lanes:forward']);
console.log('turn:lane;backward ==',tag['turn:lanes:backward']);
+
+ // TODO: need to prune unwanted things, and lane:forward,backward would be zero if oneway
dispatch.call('change', this, tag);
}
diff --git a/test/spec/osm/lanes.js b/test/spec/osm/lanes.js
index c704af8bace..99a22b21bbe 100644
--- a/test/spec/osm/lanes.js
+++ b/test/spec/osm/lanes.js
@@ -1,217 +1,217 @@
-describe.only('iD.Lanes', function() {
+describe.only('iD.Lanes', function () {
- describe('default lane tags', function() {
+ describe('default lane tags', function () {
- describe('motorway', function() {
+ describe('motorway', function () {
- it('returns 2 lanes for highway=motorway', function() {
- expect(iD.Way({tags: { highway: 'motorway' }}).lanes().metadata.count, 'motorway lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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() {
+ describe('trunk', function () {
- it('returns 4 lanes for highway=trunk', function() {
- expect(iD.Way({tags: { highway: 'trunk' }}).lanes().metadata.count, 'trunk lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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() {
+ describe('primary', function () {
- it('returns 2 lanes for highway=primary', function() {
- expect(iD.Way({tags: { highway: 'primary' }}).lanes().metadata.count, 'primary lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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() {
+ describe('seconday', function () {
- it('returns 2 lanes for highway=secondary', function() {
- expect(iD.Way({tags: { highway: 'secondary' }}).lanes().metadata.count, 'secondary lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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() {
+ describe('tertiary', function () {
- it('returns 2 lanes for highway=tertiary', function() {
- expect(iD.Way({tags: { highway: 'tertiary' }}).lanes().metadata.count, 'tertiary lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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() {
+ describe('residential', function () {
- it('returns 2 lanes for highway=residential', function() {
- expect(iD.Way({tags: { highway: 'residential' }}).lanes().metadata.count, 'residential lanes')
+ 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')
+ 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')
+ 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() {
+ describe('service', function () {
- it('returns 2 lanes for highway=service', function() {
- expect(iD.Way({tags: { highway: 'service' }}).lanes().metadata.count, 'service lanes')
+ 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')
+ 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')
+ 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() {
+ describe('track', function () {
- it('returns 2 lanes for highway=track', function() {
- expect(iD.Way({tags: { highway: 'track' }}).lanes().metadata.count, 'track lanes')
+ 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')
+ 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')
+ 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() {
+ describe('path', function () {
- it('returns 2 lanes for highway=path', function() {
- expect(iD.Way({tags: { highway: 'path' }}).lanes().metadata.count, 'path lanes')
+ 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')
+ 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')
+ 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')
+ 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')
+ expect(iD.Way({ tags: { highway: 'residential', oneway: 'no' } }).lanes().metadata.oneway, 'residential lanes')
.to.be.false;
});
});
- describe('lane direction', function() {
+ 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')
+ 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,
@@ -219,7 +219,7 @@ describe.only('iD.Lanes', function() {
backward: 1,
bothways: 0
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:forward': 3, 'lanes:backward': 1 }}).lanes().metadata, 'residential lanes')
+ expect(iD.Way({ tags: { highway: 'residential', lanes: 4, 'lanes:forward': 3, 'lanes:backward': 1 } }).lanes().metadata, 'residential lanes')
.to.include({
count: 4,
oneway: false,
@@ -229,8 +229,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -240,53 +240,54 @@ describe.only('iD.Lanes', function() {
});
});
- it('returns correctly forward count when oneway=yes', function() {
- expect(iD.Way({tags: { highway: 'trunk', lanes: 2, oneway: 'yes' }}).lanes().metadata, 'trunk lanes')
+ 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,
+ forward: 0,
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')
+ 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,
+ backward: 0,
forward: 0,
- bothways: 0
+ bothways: 0,
+ reverse: true
});
});
- 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')
+ 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,
+ forward: 0,
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')
+ 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,
+ forward: 0,
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')
+ 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,
@@ -294,7 +295,7 @@ describe.only('iD.Lanes', function() {
backward: 1,
bothways: 0
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 4, 'lanes:backward': 3, }}).lanes().metadata, 'residential lanes')
+ expect(iD.Way({ tags: { highway: 'residential', lanes: 4, 'lanes:backward': 3, } }).lanes().metadata, 'residential lanes')
.to.include({
count: 4,
oneway: false,
@@ -304,8 +305,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -313,7 +314,7 @@ describe.only('iD.Lanes', function() {
backward: 2,
bothways: 0
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, }}).lanes().metadata, 'residential lanes')
+ expect(iD.Way({ tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, } }).lanes().metadata, 'residential lanes')
.to.include({
count: 2,
oneway: false,
@@ -323,8 +324,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -332,7 +333,7 @@ describe.only('iD.Lanes', function() {
backward: 1,
bothways: 1
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:forward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
+ 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,
@@ -342,8 +343,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -351,7 +352,7 @@ describe.only('iD.Lanes', function() {
backward: 1,
bothways: 1
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 5, 'lanes:backward': 1, 'lanes:both_ways': 1 }}).lanes().metadata, 'residential lanes')
+ 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,
@@ -361,8 +362,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -372,8 +373,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -383,8 +384,8 @@ describe.only('iD.Lanes', 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')
+ 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,
@@ -392,7 +393,7 @@ describe.only('iD.Lanes', function() {
backward: 3,
bothways: 0
});
- expect(iD.Way({tags: { highway: 'residential', lanes: 2, 'lanes:forward': 1, 'lanes:both_ways': 'none' }}).lanes().metadata, 'residential lanes')
+ 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,
@@ -404,42 +405,42 @@ describe.only('iD.Lanes', 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) {
- 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);
+ 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';
+ 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);
});
- 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() {
+ describe('turn lanes', function () {
+ it('returns correctly when oneway=yes', function () {
var metadata = iD.Way({
tags: {
highway: 'trunk',
@@ -453,7 +454,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns correctly when oneway=yes and lanes=2', function() {
+ it('returns correctly when oneway=yes and lanes=2', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -469,7 +470,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns correctly when lanes=5 and both_ways=1', function() {
+ it('returns correctly when lanes=5 and both_ways=1', function () {
var metadata = iD.Way({
tags: {
highway: 'residential',
@@ -490,7 +491,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns correctly when multiple values are present in a lane and oneway=yes', function() {
+ it('returns correctly when multiple values are present in a lane and oneway=yes', function () {
var lanesData = iD.Way({
tags: {
highway: 'tertiary',
@@ -510,7 +511,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns correctly when multiple values are present in a lane and oneway=no', function() {
+ it('returns correctly when multiple values are present in a lane and oneway=no', function () {
var lanesData = iD.Way({
tags: {
highway: 'tertiary',
@@ -535,7 +536,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns unknown for every invalid value in turn:lanes', function() {
+ it('returns unknown for every invalid value in turn:lanes', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -550,7 +551,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('returns unknown for every invalid value in turn:lanes:forward & turn:lanes:backward', function() {
+ it('returns unknown for every invalid value in turn:lanes:forward & turn:lanes:backward', function () {
var metadata = iD.Way({
tags: {
highway: 'residential',
@@ -571,7 +572,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it.skip('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',
@@ -587,7 +588,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it.skip('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',
@@ -609,7 +610,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it.skip('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',
@@ -625,7 +626,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('turnLanes is [] when not present', function() {
+ it('turnLanes is [] when not present', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -642,7 +643,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([]);
});
- it('turnLanes.forward and turnLanes.backward are both [] when both are not provided', function() {
+ it('turnLanes.forward and turnLanes.backward are both [] when both are not provided', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -660,7 +661,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([]);
});
- it('parses turnLane correctly when lanes:both_ways=1', function() {
+ it('parses turnLane correctly when lanes:both_ways=1', function () {
var lanes = iD.Way({
tags: {
highway: 'tertiary',
@@ -679,7 +680,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['slight_left'], ['none'], ['none']]);
});
- it('parses turnLane correctly when lanes:both_ways=1 & lanes:forward < lanes:backward', function() {
+ it('parses turnLane correctly when lanes:both_ways=1 & lanes:forward < lanes:backward', function () {
var lanes = iD.Way({
tags: {
highway: 'tertiary',
@@ -698,7 +699,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['slight_left'], ['none'], ['none']]);
});
- it('parses correctly when turn:lanes= ||x', function() {
+ it('parses correctly when turn:lanes= ||x', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -712,7 +713,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['none'], ['none'], ['through', 'slight_right']]);
});
- it('parses correctly when turn:lanes= |x|', function() {
+ it('parses correctly when turn:lanes= |x|', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -725,7 +726,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['none'], ['through'], ['none']]);
});
- it('parses correctly when turn:lanes:forward= ||x', function() {
+ it('parses correctly when turn:lanes:forward= ||x', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -744,7 +745,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['none']]);
});
- it('parses correctly when turn:lanes:backward= |', function() {
+ it('parses correctly when turn:lanes:backward= |', function () {
var metadata = iD.Way({
tags: {
highway: 'tertiary',
@@ -763,7 +764,7 @@ describe.only('iD.Lanes', function() {
.to.deep.equal([['none'], ['none']]);
});
- it('fills lanes.unspecified with key \'turnLane\' correctly', function() {
+ it.skip('fills lanes.unspecified with key \'turnLane\' correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'tertiary',
@@ -772,7 +773,7 @@ describe.only('iD.Lanes', function() {
'turn:lanes': 'slight_left||through|through;slight_right|slight_right'
}
}).lanes().lanes;
- var turnLanesUnspecified = lanes.unspecified.map(function(l) { return l.turnLane; });
+ var turnLanesUnspecified = lanes.unspecified.map(function (l) { return l.turnLane; });
expect(turnLanesUnspecified).to.deep.equal([
['slight_left'], ['none'], ['through'], ['through', 'slight_right'], ['slight_right']
]);
@@ -780,7 +781,7 @@ describe.only('iD.Lanes', function() {
expect(lanes.backward).to.deep.equal([]);
});
- it('fills lanes.forward & lanes.backward with key \'turnLane\' correctly', function() {
+ it.skip('fills lanes.forward & lanes.backward with key \'turnLane\' correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'tertiary',
@@ -792,8 +793,8 @@ describe.only('iD.Lanes', function() {
}
}).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; });
+ 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']
]);
@@ -803,8 +804,8 @@ describe.only('iD.Lanes', function() {
});
});
- describe('maxspeed', function() {
- it('should parse maxspeed without any units correctly', function() {
+ describe.skip('maxspeed', function () {
+ it('should parse maxspeed without any units correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -823,7 +824,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(70);
});
- it('should parse maxspeed with km/h correctly', function() {
+ it('should parse maxspeed with km/h correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -834,7 +835,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(70);
});
- it('should parse maxspeed with kmh correctly', function() {
+ it('should parse maxspeed with kmh correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -845,7 +846,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(70);
});
- it('should parse maxspeed with kph correctly', function() {
+ it('should parse maxspeed with kph correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -856,7 +857,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(70);
});
- it('should parse maxspeed with mph correctly', function() {
+ it('should parse maxspeed with mph correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -867,7 +868,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(70);
});
- it('should parse maxspeed with knots correctly', function() {
+ it('should parse maxspeed with knots correctly', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -878,7 +879,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(50);
});
- it('should return undefined when incorrect maxspeed unit provided ', function() {
+ it('should return undefined when incorrect maxspeed unit provided ', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -889,7 +890,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(undefined);
});
- it('should return undefined when incorrect maxspeed value provided ', function() {
+ it('should return undefined when incorrect maxspeed value provided ', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -900,7 +901,7 @@ describe.only('iD.Lanes', function() {
expect(maxspeed).to.equal(undefined);
});
- it('should return undefined when maxspeed not provided ', function() {
+ it('should return undefined when maxspeed not provided ', function () {
var maxspeed = iD.Way({
tags: {
highway: 'residential',
@@ -911,9 +912,9 @@ describe.only('iD.Lanes', function() {
});
});
- describe('maxspeed:lanes', function() {
+ describe('maxspeed:lanes', function () {
- it('should parse correctly', function() {
+ it('should parse correctly', function () {
var maxspeedLanes = iD.Way({
tags: {
highway: 'residential',
@@ -926,7 +927,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should parse maxspeed:lanes:forward/backward correctly', function() {
+ it('should parse maxspeed:lanes:forward/backward correctly', function () {
var metadata = iD.Way({
tags: {
highway: 'residential',
@@ -938,6 +939,7 @@ describe.only('iD.Lanes', function() {
'maxspeed:lanes:backward': '30'
}
}).lanes().metadata;
+ // TODO: should we remove maxspeed from lanes?
expect(metadata.maxspeedLanes.forward).to.deep.equal([
null, 40, 40, 40
]);
@@ -946,7 +948,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should parse correctly when some values maxspeed:lanes are implied by x||y notation', function() {
+ it('should parse correctly when some values maxspeed:lanes are implied by x||y notation', function () {
var maxspeedLanes = iD.Way({
tags: {
highway: 'residential',
@@ -960,7 +962,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function() {
+ it('should parse correctly when some values maxspeed:lanes are implied by x||| notation', function () {
var lanes = iD.Way({
tags: {
highway: 'residential',
@@ -978,7 +980,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should return none for each maxspeed:lanes which equals maxspeed', function() {
+ it('should return none for each maxspeed:lanes which equals maxspeed', function () {
var maxspeedLanes = iD.Way({
tags: {
highway: 'residential',
@@ -1014,7 +1016,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should return \'unknown\' for every invalid maxspeed:lane value', function() {
+ it('should return \'unknown\' for every invalid maxspeed:lane value', function () {
var maxspeedLanes = iD.Way({
tags: {
highway: 'residential',
@@ -1040,7 +1042,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('should parse maxspeed when none', function() {
+ it('should parse maxspeed when none', function () {
var maxspeedLanes = iD.Way({
tags: {
highway: 'residential',
@@ -1053,7 +1055,7 @@ describe.only('iD.Lanes', function() {
]);
});
- it('fills lanes.unspecified with key \'maxspeed\' correctly', function() {
+ it.skip('fills lanes.unspecified with key \'maxspeed\' correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'residential',
@@ -1071,8 +1073,8 @@ describe.only('iD.Lanes', function() {
});
});
- describe('bicycle lanes', function() {
- it('should parse bicycle:lanes correctly', function() {
+ describe('bicycle lanes', function () {
+ it('should parse bicycle:lanes correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'residential',
@@ -1084,17 +1086,17 @@ describe.only('iD.Lanes', function() {
}
}).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'
+ '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() {
+ it('should parse bicycle:lanes:forward/backward correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'residential',
@@ -1106,26 +1108,26 @@ describe.only('iD.Lanes', function() {
}
}).lanes();
expect(lanes.metadata.bicyclewayLanes.forward).to.deep.equal([
- 'lane','no','no', 'no', 'no'
+ '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'
+ 'lane', 'no', 'no', 'no'
]);
- });
-
- it('should replace any invalid value with unknown', function() {
+ // 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',
@@ -1136,19 +1138,19 @@ describe.only('iD.Lanes', function() {
}
}).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'
+ '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() {
+ describe('miscellaneous lanes', function () {
+ it('should parse psv:lanes correctly', function () {
var lanes = iD.Way({
tags: {
highway: 'residential',
@@ -1158,16 +1160,16 @@ describe.only('iD.Lanes', function() {
}
}).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'
+ 'yes', 'no', 'no', 'no', 'no'
]);
- });
- it('should parse psv:lanes:forward/backward correctly', function() {
+ // 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',
@@ -1178,25 +1180,25 @@ describe.only('iD.Lanes', function() {
}
}).lanes();
expect(lanes.metadata.psvLanes.forward).to.deep.equal([
- 'no','no','no'
+ '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 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',
@@ -1206,14 +1208,138 @@ describe.only('iD.Lanes', function() {
}
}).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'
+ 'yes', 'no', 'unknown'
]);
+ // var psvLanesForward = lanes.lanes.unspecified.map(function(l) {
+ // return l.psv;
+ // });
+ // expect(psvLanesForward).to.deep.equal([
+ // 'yes','no', 'unknown'
+ // ]);
+ });
+ });
+
+ describe('lane count with disparity', function () {
+ it('should choose turn:lanes\'s length', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'trunk',
+ oneway: 'yes',
+ 'lanes': '2',
+ 'turn:lanes': 'none|slight_right|none'
+ }
+ }).lanes().metadata;
+ expect(metadata.count)
+ .to.equal(3);
+
+ });
+ it('should return forward backward count 0 if oneway', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'trunk',
+ oneway: 'yes',
+ 'lanes': '3',
+ 'turn:lanes': 'none|slight_right|none',
+ }
+ }).lanes().metadata;
+ expect(metadata.count)
+ .to.equal(3);
+ expect(metadata.backward)
+ .to.equal(0);
+ expect(metadata.forward)
+ .to.equal(0);
+ expect(metadata.backward)
+ .to.equal(0);
+ });
+ it('should choose the turn lanes count if lanes:forward', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ 'lanes:forward': 2,
+ 'lanes:both_ways': 1,
+ 'turn:lanes:forward': 'slight_left|through|reverse',
+ 'turn:lanes:backward': 'none|through;slight_right',
+ }
+ }).lanes().metadata;
+ expect(metadata.forward)
+ .to.equal(3);
+ expect(metadata.backward)
+ .to.equal(2);
+ });
+ it('should overide lanes:backward if in dispute with turn:lanes:backward ', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ 'lanes:backward': 4,
+ 'lanes:forward': 2,
+ 'turn:lanes:forward': 'slight_left|through|reverse',
+ 'turn:lanes:backward': 'none|through;slight_right',
+ }
+ }).lanes().metadata;
+ expect(metadata.count)
+ .to.equal(5);
+ expect(metadata.forward)
+ .to.equal(3);
+ expect(metadata.backward)
+ .to.equal(2);
+ });
+
+ it('should choose ignore a \'*:lanes\' notation if oneway=no', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ 'lanes:backward': 4,
+ 'lanes:forward': 2,
+ 'turn:lanes:forward': 'slight_left|through|reverse',
+ 'turn:lanes:backward': 'none|through;slight_right',
+ 'psv:lanes': 'yes|no||no|no'
+ }
+ }).lanes().metadata;
+ // console.log(JSON.stringify(metadata,null, 2));
+ expect(metadata.count)
+ .to.equal(5);
+ expect(metadata.forward)
+ .to.equal(3);
+ expect(metadata.backward)
+ .to.equal(2);
+ });
+
+ it('should fill lanes:backward correctly', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ 'turn:lanes:backward': 'none|through;slight_right',
+ }
+ }).lanes().metadata;
+ // console.log(JSON.stringify(metadata,null, 2));
+ expect(metadata.count)
+ .to.equal(5);
+ expect(metadata.forward)
+ .to.equal(3);
+ expect(metadata.backward)
+ .to.equal(2);
+ });
+
+ it('should fill lanes:backward correctly', function () {
+ var metadata = iD.Way({
+ tags: {
+ highway: 'residential',
+ lanes: 5,
+ 'turn:lanes:backward': 'none|through;slight_right',
+ 'psv:lanes:backward': 'yes|||',
+ }
+ }).lanes().metadata;
+ expect(metadata.count)
+ .to.equal(5);
+ expect(metadata.forward)
+ .to.equal(1);
+ expect(metadata.backward )
+ .to.equal(4);
});
});
});
+
From bcc6a0fc9b38597dd21e1ec0706d6b77e4d603b2 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Fri, 3 Feb 2017 17:30:34 +0530
Subject: [PATCH 16/25] Working
---
modules/osm/lanes.js | 1 +
modules/svg/lanes.js | 2 +-
modules/svg/midpoints.js | 2 -
modules/ui/fields/lanes.js | 445 ++++++++++++++-----------------------
modules/ui/preset.js | 2 +-
5 files changed, 171 insertions(+), 281 deletions(-)
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 03c9569c9b1..8989181ce07 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -95,6 +95,7 @@ function tallyLaneCount(metadata) {
var consideredLaneTags = ['busLanes', 'hgvLanes', 'hovLanes', 'psvLanes', 'taxiLanes', 'turnLanes'];
var maxUnspecified = 0;
var maxForward = 0;
+
var maxBackward = 0;
consideredLaneTags.forEach(function (tag) {
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 3f44a109f48..285f0c4b5b9 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -33,7 +33,6 @@ export function svgLanes(projection, context) {
}
var wrapperData = findPosition();
-
// wrapper DATA BIND
// `wrapperData` is an array set up how we want the DOM to look.
// Always think about data first when working with D3!
@@ -160,6 +159,7 @@ export function svgLanes(projection, context) {
function getEntity() {
+ // TODO: fails if I trash the current way selected
if (context.selectedIDs().length !== 1) return null;
var entity = graph.entity(context.selectedIDs()[0]);
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index 78a4360feb9..b99110839a8 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -27,7 +27,6 @@ export function svgMidpoints(projection, context) {
continue;
if (context.selectedIDs().indexOf(entity.id) < 0)
continue;
- console.log(context.selectedIDs().indexOf(entity.id));
var nodes = graph.childNodes(entity);
for (var j = 0; j < nodes.length - 1; j++) {
@@ -92,7 +91,6 @@ export function svgMidpoints(projection, context) {
.selectAll('g.midpoint')
.filter(midpointFilter)
.data(_.values(midpoints), function(d) { return d.id; });
- console.log(_.values(midpoints), function(d) { return d.id;});
groups.exit()
.remove();
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index de5ef4fb608..04939e38ef1 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -1,19 +1,17 @@
import * as d3 from 'd3';
import { utilRebind } from '../../util/rebind';
-import { utilGetDimensions } from '../../util/dimensions';
import _ from 'lodash';
import { utilGetSetValue } from '../../util/get_set_value';
import { validTurnLanes } from '../../osm/lanes';
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
- LANE_WIDTH = 40,
// TODO: currentLane if big like 6 goes crazy if other wayID has less than 6 lanes
- currentLane = 0,
+ curLane = 0,
curDirection = 'unspecified',
wayID,
lanesData;
-
+
function lanes(selection) {
lanesData = context.entity(wayID).lanes();
@@ -26,49 +24,51 @@ export function uiFieldLanes(field, context) {
var lanesInfo = selection.selectAll('.lanes-info').data([0]);
lanesInfo = lanesInfo.enter()
- .append('div')
- .attr('class', 'lanes-info')
- .merge(lanesInfo);
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(lanesInfo);
lanesInfo.call(lanesInfoUI);
var laneSelector = selection.selectAll('.lane-selector').data([0]);
laneSelector = laneSelector.enter()
- .append('div')
- .attr('class', 'lane-selector localized-wrap')
- .merge(laneSelector);
-
+ .append('div')
+ .attr('class', 'lane-selector localized-wrap')
+ .merge(laneSelector);
+
laneSelector.call(laneSelectorUI);
- var turnLanes = selection.selectAll('.turn-lanes').data([0]);
- turnLanes = turnLanes.enter()
- .append('div')
- .attr('class', 'turn-lanes localized-wrap')
- .merge(turnLanes);
- turnLanes.call(turnLanesUI);
+ // var turnLanes = selection.selectAll('.turn-lanes').data([0]);
+
+ // turnLanes = turnLanes.enter()
+ // .append('div')
+ // .attr('class', 'turn-lanes localized-wrap')
+ // .merge(turnLanes);
+ // turnLanes.call(turnLanesUI);
+ selection.call(turnLanesUI);
var wrap = selection.selectAll('.lane-input-wrap')
- .data([0]);
+ .data([0]);
wrap.enter()
- .append('div')
- .attr('class', 'lane-input-wrap')
- .merge(wrap);
-
+ .append('div')
+ .attr('class', 'lane-input-wrap')
+ .merge(wrap);
+
function render() {
if (context.hasEntity(wayID)) {
lanes(selection);
}
}
-
+
function lanesInfoUI(selection) {
// TODO: make this thing dynamic and show keysConsidered
// wrt to oneway.
var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
-
+
var metadata = lanesData.metadata;
window.metadata = metadata;
wrap = wrap.enter()
@@ -91,13 +91,13 @@ export function uiFieldLanes(field, context) {
// Enter
var enter = items.enter()
.append('li')
- .attr('class', function(d) { return 'cf preset-access-' + d; });
+ .attr('class', function (d) { return 'cf preset-access-' + d; });
enter
.append('span')
.attr('class', 'col6 label preset-label-')
- .attr('for', function(d) { return 'preset-input-' + d; })
- .text(function(d) { return d; });
+ .attr('for', function (d) { return 'preset-input-' + d; })
+ .text(function (d) { return d; });
enter
.append('div')
@@ -105,8 +105,8 @@ export function uiFieldLanes(field, context) {
.append('input')
.attr('type', 'text')
.attr('class', 'preset-input-lanes')
- .attr('id', function(d) { return 'preset-input-lanes-' + d; })
- .each(function(d) {
+ .attr('id', function (d) { return 'preset-input-lanes-' + d; })
+ .each(function (d) {
this.value = metadata[d];
});
@@ -117,7 +117,7 @@ export function uiFieldLanes(field, context) {
return metadata[d];
});
-
+
// selection.selectAll('.preset-access-count')
// .attr('hidden', function () {
// return metadata.oneway;
@@ -125,9 +125,9 @@ export function uiFieldLanes(field, context) {
var input = items.selectAll('input');
- input
- .on('change',change)
- .on('blur', change);
+ input
+ .on('change', change)
+ .on('blur', change);
function change(d) {
if (metadata.oneway) {
@@ -147,7 +147,7 @@ export function uiFieldLanes(field, context) {
if (d === 'forward') {
var forward = utilGetSetValue(d3.select(this));
forward = parseInt(forward, 10);
- if (!_.isNaN(forward)) metadata.forward = forward;
+ if (!_.isNaN(forward)) metadata.forward = forward;
}
if (d === 'backward') {
var backward = utilGetSetValue(d3.select(this));
@@ -161,73 +161,92 @@ export function uiFieldLanes(field, context) {
function turnLanesUI(selection) {
var turnLanes = lanesData.metadata.turnLanes;
- selection.selectAll('.form-label')
- .data([0])
- .enter()
- .append('label')
- .attr('class','form-label entry')
- .text('Turn Lanes');
-
- var wrap = selection.selectAll('.preset-input-wrap')
+
+ var data = validTurnLanes.map(function (t) {
+ var dir = turnLanes[curDirection][curLane];
+ if (!dir) return false;
+ return dir.indexOf(t) > -1;
+ });
+
+
+ var wrapper = selection
+ .selectAll('.turn-lanes')
.data([0]);
-
- wrap = wrap.enter()
+
+ wrapper.exit().remove();
+
+
+ var enter = wrapper.enter()
+ .append('div')
+ .attr('class', 'turn-lanes localized-wrap');
+
+ enter
+ .append('label')
+ .attr('class', 'form-label entry')
+ .text('Turn Lanes');
+
+ enter
.append('div')
.attr('class', 'lane-tags preset-input-wrap checkselect');
+ wrapper = wrapper
+ .merge(enter);
+
+ var label = wrapper
+ .selectAll('.lane-tags')
+ .selectAll('label')
+ .data(data);
- var label = wrap.selectAll('.label')
- .data(validTurnLanes);
+ label.exit()
+ .remove();
var labelEnter = label.enter()
.append('label');
labelEnter
.append('input')
+ .property('direction', function (d, i) { return validTurnLanes[i]; })
.property('indeterminate', field.type === 'check')
.attr('type', 'checkbox')
.attr('id', 'preset-input-' + field.id);
-
+
+
labelEnter
.append('span')
- .text(function (d) { return d;})
+ .text(function (d, i) { return validTurnLanes[i]; })
.attr('class', 'value');
- var input = selection.selectAll('input');
- input.property('checked', function (d) {
- if (turnLanes[curDirection] && _.isArray(turnLanes[curDirection][currentLane])) {
- return turnLanes[curDirection][currentLane].filter(function (el) {
- return el === d;
- }).length === 1;
- }
- return false;
- })
- .property('direction', function (d) {return d;});
-
-
- input.on('click', change);
+ label = label
+ .merge(labelEnter)
+ .select('input')
+ .property('checked', function (d) {
+ return d;
+ })
+ .on('click', change);
+
function change() {
d3.event.stopPropagation();
- var direction = d3.select(this).property('direction');
+ var input = selection.selectAll('input');
+ var direction = d3.select(this).property('direction');
var newDirs = [];
+
input.each(function (d, i) {
- var value = d3.select(this).property('checked');
+ var value = d3.select(this).property('checked');
+ var direction = d3.select(this).property('direction');
if (value) {
- newDirs.push(d);
+ newDirs.push(direction);
}
});
if (direction === 'none' || newDirs.length === 0) {
- newDirs = ['none'];
+ newDirs = ['none'];
} else {
- _.pull(newDirs, 'none');
+ _.pull(newDirs, 'none');
}
-
- turnLanes[curDirection][currentLane] = newDirs;
-
+ turnLanes[curDirection][curLane] = newDirs;
megaChange();
-
+
}
}
@@ -241,20 +260,20 @@ export function uiFieldLanes(field, context) {
else len = metadata.forward + metadata.backward;
selection.selectAll('.form-label')
- .data([0])
- .enter()
- .append('label')
- .attr('class','form-label entry')
- .text('Select Lane');
+ .data([0])
+ .enter()
+ .append('label')
+ .attr('class', 'form-label entry')
+ .text('Select Lane');
var wrap = selection.selectAll('.preset-input-wrap')
.data([0]);
-
+
wrap = wrap.enter()
.append('div')
.attr('class', 'lane-tags preset-input-wrap checkselect')
.merge(wrap);
-
+
var list = wrap.selectAll('ul')
.data([0]);
@@ -266,116 +285,65 @@ export function uiFieldLanes(field, context) {
.data(_.fill(Array(len), 0).map(function (n, i) {
return i;
}));
-
+
items.enter()
- .append('div')
- .attr('class', 'lane-item')
- .attr('id', function (d) {
- return 'lane-' + d;
- })
- .append('span');
+ .append('div')
+ .attr('class', 'lane-item')
+ .attr('id', function (d) {
+ return 'lane-' + d;
+ })
+ .append('span');
var input = selection.selectAll('.lane-item');
input.selectAll('span')
.text(function (d) {
- if (metadata.oneway) return d + 1;
- if (d < metadata.forward) {
- return (d + 1) + '▲';
- }
- return (d - metadata.forward + 1) + '▼';
- });
+ if (metadata.oneway) return d + 1;
+ if (d < metadata.forward) {
+ return (d + 1) + '▲';
+ }
+ return (d - metadata.forward + 1) + '▼';
+ });
input.classed('active', function (d) {
- if (metadata.oneway) return d === currentLane;
+ if (metadata.oneway) return d === curLane;
if (curDirection === 'forward') {
- return d === currentLane;
+ return d === curLane;
}
- return currentLane + metadata.forward === d;
+ return curLane + metadata.forward === d;
});
input.on('click', function (d) {
if (metadata.oneway) {
- currentLane = d;
+ curLane = d;
curDirection = 'unspecified';
} else {
if (d < metadata.forward) {
- currentLane = d;
+ curLane = d;
curDirection = 'forward';
} else {
- currentLane = d - metadata.forward;
+ curLane = d - metadata.forward;
curDirection = 'backward';
}
}
-
-
+
+
render();
});
items.exit().remove();
}
function megaChange() {
- var tag = {};
- var metadata = lanesData.metadata;
-
-
- tag.lanes = Number(metadata.count).toString();
-
- // Explanation: Removing tags on the basis of oneway tagging,
- // assuming if it is a oneway, the forward and backward tags
- // would be pruned, vice versa for oneway=no.
- if (metadata.oneway) {
-
- if (metadata.reverse) tag.oneway = '-1';
- else tag.oneway = 'yes';
-
- tag['lanes:forward'] = undefined;
- tag['lanes:backward'] = undefined;
-
- tag['turn:lanes'] = formPipes(metadata.turnLanes.unspecified, metadata.count, 'none');
- tag['turn:lanes:forward'] = undefined;
- tag['turn:lanes:backward'] = undefined;
- } else {
- tag.lanes = (metadata.forward + metadata.backward) + ''; //TODO: add bothways
-
- tag['lanes:forward'] = metadata.forward + '';
- tag['lanes:backward'] = metadata.backward + '';
-
- tag['turn:lanes'] = undefined;
- tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
- tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
- }
-
- console.log('final tag', tag);
- console.log('turn:lane ===',tag['turn:lanes']);
- console.log('turn:lane;forward ==',tag['turn:lanes:forward']);
- console.log('turn:lane;backward ==',tag['turn:lanes:backward']);
-
- // TODO: need to prune unwanted things, and lane:forward,backward would be zero if oneway
+ var tag = metadataToOSM(lanesData.metadata);
dispatch.call('change', this, tag);
}
-
- function formPipes(data, len, nullKey) {
- var str = data.map(function (lane) {
- return lane.join(';');
- });
- while (str.length < len) {
- str.push(nullKey);
- }
- str = str.join('|');
- return str === '' ? undefined: str;
- }
-
- function pruneStr(str, s) {
-
- }
}
-
- lanes.entity = function(_) {
+
+ lanes.entity = function (_) {
if (!wayID) {
if (wayID !== _.id) {
- currentLane = 0;
+ curLane = 0;
wayID = _.id;
}
if (_.isOneWay()) {
@@ -386,135 +354,58 @@ export function uiFieldLanes(field, context) {
}
};
- lanes.tags = function(tags) {
+ lanes.tags = function () {
};
- lanes.focus = function() {};
- lanes.off = function() {};
-
- function laneSvg() {
- // surface = surface.enter()
- // .append('svg')
- // .attr('width', d[0])
- // .attr('height', 300)
- // .attr('class', 'surface')
- // .merge(surface);
-
-
- // var lanesSelection = surface.selectAll('.lanes')
- // .data([0]);
-
- // lanesSelection = lanesSelection.enter()
- // .append('g')
- // .attr('class', 'lanes')
- // .merge(lanesSelection);
-
- // lanesSelection
- // .attr('transform', function () {
- // return 'translate(' + (freeSpace / 2) + ', 0)';
- // });
-
-
- // // var lanesArray =
- // var lane = lanesSelection.selectAll('.lane')
- // .data(new Array(lanesData.metadata.count));
-
- // lane.exit()
- // .remove();
-
- // var enter = lane.enter()
- // .append('g')
- // .attr('class', 'lane');
-
- // enter
- // .append('g')
- // .append('rect')
- // .attr('y', 50)
- // .attr('width', LANE_WIDTH)
- // .attr('height', LANE_HEIGHT)
- // .attr('transform', function (d, i) {
- // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
- // });
-
- // enter
- // .append('g')
- // .attr('class', 'forward')
- // .append('text')
- // .attr('y', 40)
- // .attr('x', 14)
- // .text('▲')
- // .attr('transform', function (d, i) {
- // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
- // });
-
- // enter
- // .append('g')
- // .attr('class', 'bothways')
- // .append('text')
- // .attr('y', 40)
- // .attr('x', 14)
- // .text('▲▼')
- // .attr('transform', function (d, i) {
- // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
- // });
-
- // enter
- // .append('g')
- // .attr('class', 'backward')
- // .append('text')
- // .attr('y', 40)
- // .attr('x', 14)
- // .text('▼')
- // .attr('transform', function (d, i) {
- // return 'translate(' + LANE_WIDTH * i * 1.5+ ')';
- // });
-
-
- // lane = lane
- // .merge(enter);
-
- // lane
- // .attr('transform', function(d, i) {
- // return 'translate(' + (LANE_WIDTH * i * 1.5) + ', 0)';
- // });
-
-
- // var te = wrap.selectAll('.lane-text').data([0]);
-
- // te
- // .enter()
- // .append('div')
- // .attr('class', 'lane-text')
- // .text('check 123');
+ lanes.focus = function () { };
+ lanes.off = function () { };
- // var sel = wrap.selectAll('.lane-text');
+ return utilRebind(lanes, dispatch, 'on');
+}
- // sel.on('click', function() {
- // var t = {};
- // t['kushan'] = 'joshi' + Math.random();
- // dispatch.call('change', this, t);
- // d3.event.stopPropagation();
+export function metadataToOSM(metadata) {
+ var tag = {};
- // });
-
-
+ if (metadata.oneway) {
+ tag.lanes = Number(metadata.count).toString();
+ tag['lanes:forward'] = undefined;
+ tag['lanes:backward'] = undefined;
- // te.exit().remove();
-
- // lane.select('.forward')
- // .style('visibility', function(d) {
- // return d.direction === 'forward' ? 'visible' : 'hidden';
- // });
-
- // lane.select('.bothways')
- // .style('visibility', function(d) {
- // return d.direction === 'bothways' ? 'visible' : 'hidden';
- // });
-
- // lane.select('.backward')
- // .style('visibility', function(d) {
- // return d.direction === 'backward' ? 'visible' : 'hidden';
- // });
+ tag['turn:lanes'] = formPipes(metadata.turnLanes.unspecified, metadata.count, 'none');
+ tag['turn:lanes:forward'] = undefined;
+ tag['turn:lanes:backward'] = undefined;
+ } else {
+ tag.lanes = metadata.forward + metadata.backward + metadata.bothways + '';
+ tag['lanes:forward'] = metadata.forward + '';
+ tag['lanes:backward'] = metadata.backward + '';
+
+ tag['turn:lanes'] = undefined;
+ tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
+ tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
}
- return utilRebind(lanes, dispatch, 'on');
+ return tag;
}
+
+
+function formPipes(data, len, nullKey) {
+ var piped = data.slice(0, len);
+
+ // Makes sure it fills any undefined as nullKey
+ for (var i = 0; i < len; i++) {
+ if (!piped[i]) {
+ piped[i] = [nullKey];
+ }
+ }
+
+ var isEmpty = _.every(piped, function (i) {
+ if (!_.isArray(i)) throw new exception('I is not array');
+ return i.indexOf(nullKey) > -1;
+ });
+
+ var str = piped.map(function (lane) {
+ return lane.join(';');
+ });
+
+ str = str.join('|');
+ return isEmpty ? undefined : str;
+}
\ No newline at end of file
diff --git a/modules/ui/preset.js b/modules/ui/preset.js
index 77c586626dd..2670ece223c 100644
--- a/modules/ui/preset.js
+++ b/modules/ui/preset.js
@@ -23,7 +23,7 @@ export function uiPreset(context) {
// Field Constructor
function UIField(field, entity, show) {
field = _.clone(field);
-
+ console.log(field);
field.input = uiFields[field.type](field, context)
.on('change', function(t, onInput) {
dispatch.call('change', field, t, onInput);
From d5f82cde2c0d4371d4d0e42154323f325b37b931 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sat, 4 Feb 2017 15:23:57 +0530
Subject: [PATCH 17/25] Refactor fields/lanes
---
modules/ui/fields/lanes.js | 296 +++++-----------------------
modules/ui/fields/lanes/laneInfo.js | 113 +++++++++++
modules/ui/fields/lanes/turn.js | 98 +++++++++
modules/ui/preset.js | 1 -
4 files changed, 261 insertions(+), 247 deletions(-)
create mode 100644 modules/ui/fields/lanes/laneInfo.js
create mode 100644 modules/ui/fields/lanes/turn.js
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 04939e38ef1..93a15daf517 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -2,32 +2,35 @@ import * as d3 from 'd3';
import { utilRebind } from '../../util/rebind';
import _ from 'lodash';
import { utilGetSetValue } from '../../util/get_set_value';
-import { validTurnLanes } from '../../osm/lanes';
+import { uiTurnLanes } from './lanes/turn';
+import { uiLaneInfo } from './lanes/laneInfo';
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
// TODO: currentLane if big like 6 goes crazy if other wayID has less than 6 lanes
curLane = 0,
- curDirection = 'unspecified',
+ curDir = 'unspecified',
wayID,
- lanesData;
+ lanesData,
+ metadata;
+ var turnLanes = uiTurnLanes(field, context)
+ .on('change', change);
+
+ var lanesInfo = uiLaneInfo(field, context)
+ .on('change', change);
+ // var lanes
function lanes(selection) {
lanesData = context.entity(wayID).lanes();
- window.lanesData = lanesData;
-
+ metadata = lanesData.metadata;
+
if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
selection.call(lanes.off);
return;
}
- var lanesInfo = selection.selectAll('.lanes-info').data([0]);
- lanesInfo = lanesInfo.enter()
- .append('div')
- .attr('class', 'lanes-info')
- .merge(lanesInfo);
- lanesInfo.call(lanesInfoUI);
+ selection.call(lanesInfo, metadata, curDir, curLane);
var laneSelector = selection.selectAll('.lane-selector').data([0]);
@@ -35,17 +38,10 @@ export function uiFieldLanes(field, context) {
.append('div')
.attr('class', 'lane-selector localized-wrap')
.merge(laneSelector);
-
+
laneSelector.call(laneSelectorUI);
- // var turnLanes = selection.selectAll('.turn-lanes').data([0]);
-
- // turnLanes = turnLanes.enter()
- // .append('div')
- // .attr('class', 'turn-lanes localized-wrap')
- // .merge(turnLanes);
- // turnLanes.call(turnLanesUI);
- selection.call(turnLanesUI);
+ selection.call(turnLanes, metadata, curDir, curLane);
var wrap = selection.selectAll('.lane-input-wrap')
.data([0]);
@@ -61,195 +57,6 @@ export function uiFieldLanes(field, context) {
}
}
-
- function lanesInfoUI(selection) {
- // TODO: make this thing dynamic and show keysConsidered
- // wrt to oneway.
- var wrap = selection.selectAll('.preset-input-wrap')
- .data([0]);
- var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
-
- var metadata = lanesData.metadata;
- window.metadata = metadata;
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'preset-input-wrap')
- .append('ul')
- .merge(wrap);
-
- var list = wrap.selectAll('ul')
- .data([0]);
-
- list = list.enter()
- .append('ul')
- .merge(list);
-
-
- var items = list.selectAll('li')
- .data(keysConsidered);
-
- // Enter
- var enter = items.enter()
- .append('li')
- .attr('class', function (d) { return 'cf preset-access-' + d; });
-
- enter
- .append('span')
- .attr('class', 'col6 label preset-label-')
- .attr('for', function (d) { return 'preset-input-' + d; })
- .text(function (d) { return d; });
-
- enter
- .append('div')
- .attr('class', 'col6 preset-input-lanes-wrap')
- .append('input')
- .attr('type', 'text')
- .attr('class', 'preset-input-lanes')
- .attr('id', function (d) { return 'preset-input-lanes-' + d; })
- .each(function (d) {
- this.value = metadata[d];
- });
-
- // Update
- items = items.merge(enter);
- items.selectAll('input')
- .property('value', function (d) {
- return metadata[d];
- });
-
-
- // selection.selectAll('.preset-access-count')
- // .attr('hidden', function () {
- // return metadata.oneway;
- // });
-
- var input = items.selectAll('input');
-
- input
- .on('change', change)
- .on('blur', change);
-
- function change(d) {
- if (metadata.oneway) {
- if (d === 'count') {
- var count = utilGetSetValue(d3.select(this));
- count = parseInt(count, 10);
- if (!_.isNaN(count)) metadata.count = count;
- }
- if (d === 'reverse') {
- if (utilGetSetValue(d3.select(this)) === 'true') {
- metadata.reverse = true;
- } else {
- metadata.reverse = false;
- }
- }
- } else {
- if (d === 'forward') {
- var forward = utilGetSetValue(d3.select(this));
- forward = parseInt(forward, 10);
- if (!_.isNaN(forward)) metadata.forward = forward;
- }
- if (d === 'backward') {
- var backward = utilGetSetValue(d3.select(this));
- backward = parseInt(backward, 10);
- if (!_.isNaN(forward)) metadata.backward = backward;
- }
- }
- megaChange();
- }
- }
-
- function turnLanesUI(selection) {
- var turnLanes = lanesData.metadata.turnLanes;
-
- var data = validTurnLanes.map(function (t) {
- var dir = turnLanes[curDirection][curLane];
- if (!dir) return false;
- return dir.indexOf(t) > -1;
- });
-
-
- var wrapper = selection
- .selectAll('.turn-lanes')
- .data([0]);
-
- wrapper.exit().remove();
-
-
- var enter = wrapper.enter()
- .append('div')
- .attr('class', 'turn-lanes localized-wrap');
-
- enter
- .append('label')
- .attr('class', 'form-label entry')
- .text('Turn Lanes');
-
- enter
- .append('div')
- .attr('class', 'lane-tags preset-input-wrap checkselect');
-
- wrapper = wrapper
- .merge(enter);
-
- var label = wrapper
- .selectAll('.lane-tags')
- .selectAll('label')
- .data(data);
-
- label.exit()
- .remove();
-
- var labelEnter = label.enter()
- .append('label');
-
- labelEnter
- .append('input')
- .property('direction', function (d, i) { return validTurnLanes[i]; })
- .property('indeterminate', field.type === 'check')
- .attr('type', 'checkbox')
- .attr('id', 'preset-input-' + field.id);
-
-
- labelEnter
- .append('span')
- .text(function (d, i) { return validTurnLanes[i]; })
- .attr('class', 'value');
-
- label = label
- .merge(labelEnter)
- .select('input')
- .property('checked', function (d) {
- return d;
- })
- .on('click', change);
-
- function change() {
- d3.event.stopPropagation();
- var input = selection.selectAll('input');
- var direction = d3.select(this).property('direction');
-
- var newDirs = [];
-
- input.each(function (d, i) {
- var value = d3.select(this).property('checked');
- var direction = d3.select(this).property('direction');
- if (value) {
- newDirs.push(direction);
- }
- });
-
- if (direction === 'none' || newDirs.length === 0) {
- newDirs = ['none'];
- } else {
- _.pull(newDirs, 'none');
- }
- turnLanes[curDirection][curLane] = newDirs;
- megaChange();
-
- }
- }
-
function laneSelectorUI(selection) {
var items;
var metadata = lanesData.metadata;
@@ -307,7 +114,7 @@ export function uiFieldLanes(field, context) {
input.classed('active', function (d) {
if (metadata.oneway) return d === curLane;
- if (curDirection === 'forward') {
+ if (curDir === 'forward') {
return d === curLane;
}
return curLane + metadata.forward === d;
@@ -315,14 +122,14 @@ export function uiFieldLanes(field, context) {
input.on('click', function (d) {
if (metadata.oneway) {
curLane = d;
- curDirection = 'unspecified';
+ curDir = 'unspecified';
} else {
if (d < metadata.forward) {
curLane = d;
- curDirection = 'forward';
+ curDir = 'forward';
} else {
curLane = d - metadata.forward;
- curDirection = 'backward';
+ curDir = 'backward';
}
}
@@ -331,14 +138,36 @@ export function uiFieldLanes(field, context) {
});
items.exit().remove();
}
-
- function megaChange() {
- var tag = metadataToOSM(lanesData.metadata);
- dispatch.call('change', this, tag);
- }
}
+ function change(t, onInput) {
+ var tag = {};
+ if (metadata.oneway) {
+ curDir = 'unspecified';
+ curLane = curLane >= metadata.count ? 0 : curLane;
+
+ tag.lanes = Number(metadata.count).toString();
+
+ tag['lanes:forward'] = undefined;
+ tag['lanes:backward'] = undefined;
+
+ tag['turn:lanes'] = formPipes(metadata.turnLanes.unspecified, metadata.count, 'none');
+ tag['turn:lanes:forward'] = undefined;
+ tag['turn:lanes:backward'] = undefined;
+ } else {
+ curLane = curLane >= metadata[curDir] ? 0 : curLane;
+
+ tag.lanes = metadata.forward + metadata.backward + metadata.bothways + '';
+ tag['lanes:forward'] = metadata.forward + '';
+ tag['lanes:backward'] = metadata.backward + '';
+
+ tag['turn:lanes'] = undefined;
+ tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
+ tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
+ }
+ dispatch.call('change', this, tag, onInput);
+ }
lanes.entity = function (_) {
if (!wayID) {
@@ -347,9 +176,9 @@ export function uiFieldLanes(field, context) {
wayID = _.id;
}
if (_.isOneWay()) {
- curDirection = 'unspecified';
+ curDir = 'unspecified';
} else {
- curDirection = 'forward';
+ curDir = 'forward';
}
}
};
@@ -362,32 +191,7 @@ export function uiFieldLanes(field, context) {
return utilRebind(lanes, dispatch, 'on');
}
-export function metadataToOSM(metadata) {
- var tag = {};
-
- if (metadata.oneway) {
- tag.lanes = Number(metadata.count).toString();
-
- tag['lanes:forward'] = undefined;
- tag['lanes:backward'] = undefined;
-
- tag['turn:lanes'] = formPipes(metadata.turnLanes.unspecified, metadata.count, 'none');
- tag['turn:lanes:forward'] = undefined;
- tag['turn:lanes:backward'] = undefined;
- } else {
- tag.lanes = metadata.forward + metadata.backward + metadata.bothways + '';
- tag['lanes:forward'] = metadata.forward + '';
- tag['lanes:backward'] = metadata.backward + '';
-
- tag['turn:lanes'] = undefined;
- tag['turn:lanes:forward'] = formPipes(metadata.turnLanes.forward, metadata.forward, 'none');
- tag['turn:lanes:backward'] = formPipes(metadata.turnLanes.backward, metadata.backward, 'none');
- }
- return tag;
-}
-
-
-function formPipes(data, len, nullKey) {
+export function formPipes(data, len, nullKey) {
var piped = data.slice(0, len);
// Makes sure it fills any undefined as nullKey
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
new file mode 100644
index 00000000000..e5f4fcc23b1
--- /dev/null
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -0,0 +1,113 @@
+import * as d3 from 'd3';
+import { validTurnLanes } from '../../../osm/lanes';
+import { utilRebind } from '../../../util/rebind';
+import { formPipes } from '../lanes';
+import { utilGetSetValue } from '../../../util/get_set_value';
+
+import _ from 'lodash';
+
+export function uiLaneInfo() {
+ var dispatch = d3.dispatch('change');
+ function laneInfo(selection, metadata, curDirection, curLane) {
+ // TODO: make this thing dynamic and show keysConsidered
+ // wrt to oneway.
+ var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
+ var s = selection.selectAll('.lanes-info').data([0]);
+ s = s.enter()
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(s);
+
+ var wrap = s.selectAll('.preset-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'preset-input-wrap')
+ .append('ul')
+ .merge(wrap);
+
+ var list = wrap.selectAll('ul')
+ .data([0]);
+
+ list = list.enter()
+ .append('ul')
+ .merge(list);
+
+
+ var items = list.selectAll('li')
+ .data(keysConsidered);
+
+ // Enter
+ var enter = items.enter()
+ .append('li')
+ .attr('class', function (d) { return 'cf preset-access-' + d; });
+
+ enter
+ .append('span')
+ .attr('class', 'col6 label preset-label-')
+ .attr('for', function (d) { return 'preset-input-' + d; })
+ .text(function (d) { return d; });
+
+ enter
+ .append('div')
+ .attr('class', 'col6 preset-input-lanes-wrap')
+ .append('input')
+ .attr('type', 'text')
+ .attr('class', 'preset-input-lanes')
+ .attr('id', function (d) { return 'preset-input-lanes-' + d; })
+ .each(function (d) {
+ this.value = metadata[d];
+ });
+
+ // Update
+ items = items.merge(enter);
+ items.selectAll('input')
+ .property('value', function (d) {
+ return metadata[d];
+ });
+
+ var input = items.selectAll('input');
+
+ input
+ .on('change', change)
+ .on('blur', change);
+
+ function change(d) {
+ var tag = {};
+ if (metadata.oneway) {
+ if (d === 'count') {
+ var count = utilGetSetValue(d3.select(this));
+ count = parseInt(count, 10);
+ if (!_.isNaN(count)) metadata.count = count;
+ }
+ if (d === 'reverse') {
+ if (utilGetSetValue(d3.select(this)) === 'true') {
+ metadata.reverse = true;
+ } else {
+ metadata.reverse = false;
+ }
+ }
+
+ tag.lanes = Number(metadata.count).toString();
+ tag['lanes:forward'] = undefined;
+ tag['lanes:backward'] = undefined;
+
+ } else {
+ if (d === 'forward') {
+ var forward = utilGetSetValue(d3.select(this));
+ forward = parseInt(forward, 10);
+ if (!_.isNaN(forward)) metadata.forward = forward;
+ }
+ if (d === 'backward') {
+ var backward = utilGetSetValue(d3.select(this));
+ backward = parseInt(backward, 10);
+ if (!_.isNaN(backward)) metadata.backward = backward;
+ }
+ }
+
+ dispatch.call('change', this);
+ }
+ }
+ return utilRebind(laneInfo, dispatch, 'on');
+}
\ No newline at end of file
diff --git a/modules/ui/fields/lanes/turn.js b/modules/ui/fields/lanes/turn.js
new file mode 100644
index 00000000000..66542a37fe3
--- /dev/null
+++ b/modules/ui/fields/lanes/turn.js
@@ -0,0 +1,98 @@
+import * as d3 from 'd3';
+import { validTurnLanes } from '../../../osm/lanes';
+import { utilRebind } from '../../../util/rebind';
+import { formPipes } from '../lanes';
+import _ from 'lodash';
+
+export function uiTurnLanes(field) {
+ var dispatch = d3.dispatch('change');
+
+ function turnLanes(selection, metadata, curDirection, curLane) {
+ var turnLanesData = metadata.turnLanes;
+ var valid = validTurnLanes.map(function (t) {
+ var dir = turnLanesData[curDirection][curLane];
+ if (!dir) return false;
+ return dir.indexOf(t) > -1;
+ });
+
+ var wrapper = selection
+ .selectAll('.turn-lanes')
+ .data([0]);
+
+ wrapper.exit().remove();
+
+ var enter = wrapper.enter()
+ .append('div')
+ .attr('class', 'turn-lanes localized-wrap');
+
+ enter
+ .append('label')
+ .attr('class', 'form-label entry')
+ .text('Turn Lanes');
+
+ enter
+ .append('div')
+ .attr('class', 'lane-tags preset-input-wrap checkselect');
+
+ wrapper = wrapper
+ .merge(enter);
+
+ var label = wrapper
+ .selectAll('.lane-tags')
+ .selectAll('label')
+ .data(valid);
+
+ label.exit()
+ .remove();
+
+ var labelEnter = label.enter()
+ .append('label');
+
+ labelEnter
+ .append('input')
+ .property('direction', function (d, i) { return validTurnLanes[i]; })
+ .property('indeterminate', field.type === 'check')
+ .attr('type', 'checkbox')
+ .attr('id', 'preset-input-' + field.id);
+
+
+ labelEnter
+ .append('span')
+ .text(function (d, i) { return validTurnLanes[i]; })
+ .attr('class', 'value');
+
+ label = label
+ .merge(labelEnter)
+ .select('input')
+ .property('checked', function (d) {
+ return d;
+ })
+ .on('click', change);
+
+ function change() {
+ d3.event.stopPropagation();
+ var input = selection.selectAll('input');
+ var direction = d3.select(this).property('direction');
+ var newDirs = [];
+
+ input.each(function (d, i) {
+ var value = d3.select(this).property('checked');
+ var direction = d3.select(this).property('direction');
+ if (value) {
+ newDirs.push(direction);
+ }
+ });
+
+ if (direction === 'none' || newDirs.length === 0) {
+ newDirs = ['none'];
+ } else {
+ _.pull(newDirs, 'none');
+ }
+
+ turnLanesData[curDirection][curLane] = newDirs;
+
+ dispatch.call('change', this);
+ }
+ }
+ return utilRebind(turnLanes, dispatch, 'on');
+}
\ No newline at end of file
diff --git a/modules/ui/preset.js b/modules/ui/preset.js
index 2670ece223c..12b9a26af1a 100644
--- a/modules/ui/preset.js
+++ b/modules/ui/preset.js
@@ -23,7 +23,6 @@ export function uiPreset(context) {
// Field Constructor
function UIField(field, entity, show) {
field = _.clone(field);
- console.log(field);
field.input = uiFields[field.type](field, context)
.on('change', function(t, onInput) {
dispatch.call('change', field, t, onInput);
From b8c837de540998c7bfd86ce1af05848e610a0a9c Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sat, 4 Feb 2017 22:05:14 +0530
Subject: [PATCH 18/25] lanes info styling
---
css/app.css | 26 +++++-
modules/ui/fields/lanes/laneInfo.js | 128 +++++++++++++++++-----------
2 files changed, 100 insertions(+), 54 deletions(-)
diff --git a/css/app.css b/css/app.css
index 2f9456b59e0..397132c74eb 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1227,22 +1227,40 @@ button.save.has-count .count::before {
}
-.form-field-lanes .lanes-info {
- margin-bottom: 10px;
+.form-field-lanes .lanes-info input {
+ min-height: 30px;
}
+ /*.form-field-lanes input {
+ border: 1px solid #ccc;
+ min-height: 30px;
+ border-top: 0;
+ border-radius: 0 0 4px 4px;
+ overflow: hidden;
+ }*/
-.form-field-lanes .preset-input-wrap input {
+
+.form-field-lanes .lane-field {
border-radius: 0;
border-width: 0;
border-bottom-width: 1px;
+ padding: 5px 10px;
+ width: 100%;
+ border: 1px solid #CCC;
+ border-top: 0
}
+
+.form-field-lanes .preset-input-lanes-wrap input {
+ border-top: 0
+}
+
+/*
.form-field-lanes .preset-input-lanes-wrap input {
border-radius: 0;
border-width: 0;
border-left-width: 1px;
}
-
+*/
.form-field-lanes .preset-input-wrap li {
border-bottom: 1px solid #CCC;
}
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index e5f4fcc23b1..8cc10fd0266 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -12,66 +12,94 @@ export function uiLaneInfo() {
// TODO: make this thing dynamic and show keysConsidered
// wrt to oneway.
var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
- var s = selection.selectAll('.lanes-info').data([0]);
- s = s.enter()
- .append('div')
- .attr('class', 'lanes-info')
- .merge(s);
-
- var wrap = s.selectAll('.preset-input-wrap')
+ var wrapper = selection
+ .selectAll('.lanes-info')
.data([0]);
- wrap = wrap.enter()
+ var enter = wrapper.enter()
.append('div')
- .attr('class', 'preset-input-wrap')
- .append('ul')
- .merge(wrap);
-
- var list = wrap.selectAll('ul')
- .data([0]);
+ .attr('class', 'lanes-info lanes-wrap preset-input-wrap');
- list = list.enter()
- .append('ul')
- .merge(list);
-
-
- var items = list.selectAll('li')
- .data(keysConsidered);
-
- // Enter
- var enter = items.enter()
- .append('li')
- .attr('class', function (d) { return 'cf preset-access-' + d; });
+ var input = enter
+ .append('input')
+ .attr('class', 'lanes-info')
+ .attr('type', 'lane-count')
+ .attr('id', '23231')
+ .attr('placeholder', 'Lane count');
- enter
- .append('span')
- .attr('class', 'col6 label preset-label-')
- .attr('for', function (d) { return 'preset-input-' + d; })
- .text(function (d) { return d; });
+ input
+ .on('input', change(true))
+ .on('blur', change())
+ .on('change', change());
- enter
+ var spinControl = enter
.append('div')
- .attr('class', 'col6 preset-input-lanes-wrap')
- .append('input')
- .attr('type', 'text')
- .attr('class', 'preset-input-lanes')
- .attr('id', function (d) { return 'preset-input-lanes-' + d; })
- .each(function (d) {
- this.value = metadata[d];
+ .attr('class', 'spin-control');
+
+ // var enter = spinControl.enter()
+ // .append('div')
+ // .attr('class', 'spin-control');
+
+ spinControl
+ .append('button')
+ .datum(1)
+ .attr('class', 'increment')
+ .attr('tabindex', -1);
+
+ spinControl
+ .append('button')
+ .datum(-1)
+ .attr('class', 'decrement')
+ .attr('tabindex', -1);
+
+ // spinControl = spinControl
+ // .merge(enter);
+
+ spinControl.selectAll('button')
+ .on('click', function (d) {
+ d3.event.preventDefault();
+ var num = parseInt(input.node().value || 0, 10);
+ if (!isNaN(num)) input.node().value = num + d;
+ change()();
});
- // Update
- items = items.merge(enter);
- items.selectAll('input')
- .property('value', function (d) {
- return metadata[d];
- });
-
- var input = items.selectAll('input');
+ // var items = list.selectAll('li')
+ // .data(keysConsidered);
- input
- .on('change', change)
- .on('blur', change);
+ // Enter
+ // var enter = items.enter()
+ // .append('li')
+ // .attr('class', function (d) { return 'cf preset-access-' + d; });
+
+ // enter
+ // .append('span')
+ // .attr('class', 'col6 label preset-label-')
+ // .attr('for', function (d) { return 'preset-input-' + d; })
+ // .text(function (d) { return d; });
+
+ // enter
+ // .append('div')
+ // .attr('class', 'col6 preset-input-lanes-wrap')
+ // .append('input')
+ // .attr('type', 'text')
+ // .attr('class', 'preset-input-lanes')
+ // .attr('id', function (d) { return 'preset-input-lanes-' + d; })
+ // .each(function (d) {
+ // this.value = metadata[d];
+ // });
+
+ // // Update
+ // items = items.merge(enter);
+ // items.selectAll('input')
+ // .property('value', function (d) {
+ // return metadata[d];
+ // });
+
+ // var input = items.selectAll('input');
+
+ // input
+ // .on('change', change)
+ // .on('blur', change);
function change(d) {
var tag = {};
From 711f9f1bac9fa842d74857bb56bbc2eebe9ba13a Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 11:49:31 +0530
Subject: [PATCH 19/25] styling lanesInfo
---
css/app.css | 3 ++
modules/ui/fields/lanes/laneInfo.js | 51 ++++++++++++++++++++---------
2 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/css/app.css b/css/app.css
index 397132c74eb..423157bc32f 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1229,6 +1229,9 @@ button.save.has-count .count::before {
.form-field-lanes .lanes-info input {
min-height: 30px;
+ padding: 5px 10px;
+ width: 100%;
+ border: 0;
}
/*.form-field-lanes input {
border: 1px solid #ccc;
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index 8cc10fd0266..9b54321fdff 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -11,7 +11,6 @@ export function uiLaneInfo() {
function laneInfo(selection, metadata, curDirection, curLane) {
// TODO: make this thing dynamic and show keysConsidered
// wrt to oneway.
- var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
var wrapper = selection
.selectAll('.lanes-info')
.data([0]);
@@ -20,47 +19,67 @@ export function uiLaneInfo() {
.append('div')
.attr('class', 'lanes-info lanes-wrap preset-input-wrap');
- var input = enter
+ wrapper = wrapper
+ .merge(enter);
+
+ var input = wrapper.selectAll('.lanes-info')
+ .data([0]);
+
+ input.exit()
+ .remove();
+
+ input = input.enter()
.append('input')
.attr('class', 'lanes-info')
.attr('type', 'lane-count')
- .attr('id', '23231')
- .attr('placeholder', 'Lane count');
-
+ .attr('placeholder', 'Lane count')
+ .merge(input);
+
input
- .on('input', change(true))
- .on('blur', change())
- .on('change', change());
+ .on('input', change)
+ .on('blur', change)
+ .on('change', change);
+ // .each(() => this.value = metadata.count);
+
+ input.node().value = metadata.count;
- var spinControl = enter
+ var spinControl = wrapper.selectAll('.spin-control')
+ .data([0]);
+
+
+ var senter = spinControl.enter()
.append('div')
.attr('class', 'spin-control');
-
+
+ // console.log(wrapper.selectAll('input').node().value(metadata.count));
+ // utilGetSetValue(wrapper.selectAll('input'), metadata.count || '');
// var enter = spinControl.enter()
// .append('div')
// .attr('class', 'spin-control');
- spinControl
+ senter
.append('button')
.datum(1)
.attr('class', 'increment')
.attr('tabindex', -1);
- spinControl
+ senter
.append('button')
.datum(-1)
.attr('class', 'decrement')
.attr('tabindex', -1);
- // spinControl = spinControl
- // .merge(enter);
+ spinControl = spinControl
+ .merge(senter);
spinControl.selectAll('button')
.on('click', function (d) {
d3.event.preventDefault();
+ console.log(input.node().value);
var num = parseInt(input.node().value || 0, 10);
if (!isNaN(num)) input.node().value = num + d;
- change()();
+
+ change();
});
// var items = list.selectAll('li')
@@ -103,6 +122,8 @@ export function uiLaneInfo() {
function change(d) {
var tag = {};
+ metadata.count = utilGetSetValue(selection.selectAll('input'));
+
if (metadata.oneway) {
if (d === 'count') {
var count = utilGetSetValue(d3.select(this));
From 5189ea0f16161e68642b5ea41a8e1c2e8cb7318e Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 13:14:59 +0530
Subject: [PATCH 20/25] lanes info styling part 2
---
css/app.css | 8 -----
modules/ui/fields/lanes/laneInfo.js | 48 +++++++++++++++++++----------
2 files changed, 32 insertions(+), 24 deletions(-)
diff --git a/css/app.css b/css/app.css
index 423157bc32f..04b68e87977 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1233,14 +1233,6 @@ button.save.has-count .count::before {
width: 100%;
border: 0;
}
- /*.form-field-lanes input {
- border: 1px solid #ccc;
- min-height: 30px;
- border-top: 0;
- border-radius: 0 0 4px 4px;
- overflow: hidden;
- }*/
-
.form-field-lanes .lane-field {
border-radius: 0;
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index 9b54321fdff..cf667a67ee5 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -11,6 +11,8 @@ export function uiLaneInfo() {
function laneInfo(selection, metadata, curDirection, curLane) {
// TODO: make this thing dynamic and show keysConsidered
// wrt to oneway.
+ var oneway = metadata.oneway;
+
var wrapper = selection
.selectAll('.lanes-info')
.data([0]);
@@ -21,9 +23,19 @@ export function uiLaneInfo() {
wrapper = wrapper
.merge(enter);
-
+
var input = wrapper.selectAll('.lanes-info')
- .data([0]);
+ .data(oneway ? [{
+ text: 'Lanes',
+ dir: 'oneway'
+ }] : [{
+ text: 'Forward Lanes',
+ dir: 'forward'
+ },
+ {
+ text: 'Backward Lanes',
+ dir: 'backward'
+ }]);
input.exit()
.remove();
@@ -32,45 +44,49 @@ export function uiLaneInfo() {
.append('input')
.attr('class', 'lanes-info')
.attr('type', 'lane-count')
- .attr('placeholder', 'Lane count')
.merge(input);
input
+ .attr('placeholder', function (d) {
+ return d.text;
+ })
+ .attr('direction', function (d) {
+ return d.dir;
+ })
.on('input', change)
.on('blur', change)
- .on('change', change);
- // .each(() => this.value = metadata.count);
+ .on('change', change)
+ .each(function (d) {
+ if (d.dir === 'oneway') {
+ this.value = metadata.count;
+ return;
+ }
+ this.value = metadata[d.dir];
+ });
- input.node().value = metadata.count;
var spinControl = wrapper.selectAll('.spin-control')
.data([0]);
- var senter = spinControl.enter()
+ var spinEnter = spinControl.enter()
.append('div')
.attr('class', 'spin-control');
- // console.log(wrapper.selectAll('input').node().value(metadata.count));
- // utilGetSetValue(wrapper.selectAll('input'), metadata.count || '');
- // var enter = spinControl.enter()
- // .append('div')
- // .attr('class', 'spin-control');
-
- senter
+ spinEnter
.append('button')
.datum(1)
.attr('class', 'increment')
.attr('tabindex', -1);
- senter
+ spinEnter
.append('button')
.datum(-1)
.attr('class', 'decrement')
.attr('tabindex', -1);
spinControl = spinControl
- .merge(senter);
+ .merge(spinEnter);
spinControl.selectAll('button')
.on('click', function (d) {
From 399633fc41ceba3e3f24eb5c9eb85b892042c710 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 15:07:21 +0530
Subject: [PATCH 21/25] lane selector UI
---
css/app.css | 20 +-
modules/ui/fields/lanes/laneInfo.js | 314 ++++++++++++++++++----------
temp.js | 113 ++++++++++
3 files changed, 330 insertions(+), 117 deletions(-)
create mode 100644 temp.js
diff --git a/css/app.css b/css/app.css
index 04b68e87977..2a87cf72e5f 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1231,9 +1231,14 @@ button.save.has-count .count::before {
min-height: 30px;
padding: 5px 10px;
width: 100%;
- border: 0;
+ border-radius: 0;
+ border-width: 0;
+ border-left-width: 1px;
+}
+.form-field-lanes .spin-control button{
+ height: 30px;
+ right: 0;
}
-
.form-field-lanes .lane-field {
border-radius: 0;
border-width: 0;
@@ -1244,10 +1249,11 @@ button.save.has-count .count::before {
border-top: 0
}
-
+/*
.form-field-lanes .preset-input-lanes-wrap input {
- border-top: 0
-}
+ border-top: 0;
+ border-left-width: 1px;
+}*/
/*
.form-field-lanes .preset-input-lanes-wrap input {
@@ -1281,7 +1287,6 @@ button.save.has-count .count::before {
display: flex;
flex-grow: 1;
border-right: 1px solid #ccc;
- border-bottom: 0;
flex-direction: column;
align-items: center;
background-color: white;
@@ -1303,7 +1308,7 @@ button.save.has-count .count::before {
.lane-selector .lane-item span {
height: 30px;
- padding: 5px 10px 5px 10px;
+ line-height: 30px;
}
.lane-tags > label {
@@ -3353,7 +3358,6 @@ img.tile-removing {
/* Scrollbars
----------------------------------------------------- */
-
::-webkit-scrollbar {
height: 20px;
overflow: visible;
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index cf667a67ee5..6a37fc33a74 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -9,67 +9,49 @@ import _ from 'lodash';
export function uiLaneInfo() {
var dispatch = d3.dispatch('change');
function laneInfo(selection, metadata, curDirection, curLane) {
- // TODO: make this thing dynamic and show keysConsidered
- // wrt to oneway.
- var oneway = metadata.oneway;
+ var s = selection.selectAll('.lanes-info').data([0]);
+ s = s.enter()
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(s);
- var wrapper = selection
- .selectAll('.lanes-info')
+ var wrap = s.selectAll('.preset-input-wrap')
.data([0]);
- var enter = wrapper.enter()
+ wrap = wrap.enter()
.append('div')
- .attr('class', 'lanes-info lanes-wrap preset-input-wrap');
-
- wrapper = wrapper
- .merge(enter);
-
- var input = wrapper.selectAll('.lanes-info')
- .data(oneway ? [{
- text: 'Lanes',
- dir: 'oneway'
- }] : [{
- text: 'Forward Lanes',
- dir: 'forward'
- },
- {
- text: 'Backward Lanes',
- dir: 'backward'
- }]);
-
- input.exit()
- .remove();
-
- input = input.enter()
- .append('input')
- .attr('class', 'lanes-info')
- .attr('type', 'lane-count')
- .merge(input);
-
- input
- .attr('placeholder', function (d) {
- return d.text;
- })
- .attr('direction', function (d) {
- return d.dir;
- })
- .on('input', change)
- .on('blur', change)
- .on('change', change)
- .each(function (d) {
- if (d.dir === 'oneway') {
- this.value = metadata.count;
- return;
- }
- this.value = metadata[d.dir];
- });
-
+ .attr('class', 'preset-input-wrap')
+ .merge(wrap);
- var spinControl = wrapper.selectAll('.spin-control')
+ var list = wrap.selectAll('ul')
.data([0]);
+ list = list.enter()
+ .append('ul')
+ .merge(list);
- var spinEnter = spinControl.enter()
+
+ var items = list.selectAll('li')
+ .data(metadata.oneway ? ['count'] : ['forward', 'backward']);
+
+ items.exit().remove();
+ // Enter
+ var enter = items.enter()
+ .append('li')
+ .attr('class', 'cf preset-lanes-info');
+
+ enter
+ .append('span')
+ .attr('class', 'col6 label preset-label-')
+ .text(function (d) { return d; });
+
+ enter
+ .append('div')
+ .attr('class', 'col6 preset-input-lanes-wrap')
+ .append('input')
+ .attr('type', 'text');
+
+ var spinEnter = enter
.append('div')
.attr('class', 'spin-control');
@@ -85,74 +67,43 @@ export function uiLaneInfo() {
.attr('class', 'decrement')
.attr('tabindex', -1);
- spinControl = spinControl
- .merge(spinEnter);
- spinControl.selectAll('button')
+
+ // Update
+ items = items.merge(enter);
+
+ items.select('span')
+ .text(function (d) { return d; });
+
+ items.select('input')
+ .each(function (d) {
+ this.value = metadata[d];
+ })
+ .attr('name', function (d) {
+ return d;
+ })
+ .on('change', change)
+ .on('blur', change);
+
+ items.selectAll('button')
.on('click', function (d) {
d3.event.preventDefault();
- console.log(input.node().value);
- var num = parseInt(input.node().value || 0, 10);
- if (!isNaN(num)) input.node().value = num + d;
-
- change();
+ var el = d3.select(this.parentNode.parentNode);
+ el = el.selectAll('input');
+ var num = parseInt(el.node().value || 0, 10);
+ if (!isNaN(num) && num + d > 0 && num + d < 11)
+ el.node().value = num + d;
+ change.call(el.node(), el.attr('name'));
});
- // var items = list.selectAll('li')
- // .data(keysConsidered);
-
- // Enter
- // var enter = items.enter()
- // .append('li')
- // .attr('class', function (d) { return 'cf preset-access-' + d; });
-
- // enter
- // .append('span')
- // .attr('class', 'col6 label preset-label-')
- // .attr('for', function (d) { return 'preset-input-' + d; })
- // .text(function (d) { return d; });
-
- // enter
- // .append('div')
- // .attr('class', 'col6 preset-input-lanes-wrap')
- // .append('input')
- // .attr('type', 'text')
- // .attr('class', 'preset-input-lanes')
- // .attr('id', function (d) { return 'preset-input-lanes-' + d; })
- // .each(function (d) {
- // this.value = metadata[d];
- // });
-
- // // Update
- // items = items.merge(enter);
- // items.selectAll('input')
- // .property('value', function (d) {
- // return metadata[d];
- // });
-
- // var input = items.selectAll('input');
-
- // input
- // .on('change', change)
- // .on('blur', change);
-
function change(d) {
var tag = {};
- metadata.count = utilGetSetValue(selection.selectAll('input'));
-
if (metadata.oneway) {
if (d === 'count') {
var count = utilGetSetValue(d3.select(this));
count = parseInt(count, 10);
if (!_.isNaN(count)) metadata.count = count;
}
- if (d === 'reverse') {
- if (utilGetSetValue(d3.select(this)) === 'true') {
- metadata.reverse = true;
- } else {
- metadata.reverse = false;
- }
- }
tag.lanes = Number(metadata.count).toString();
tag['lanes:forward'] = undefined;
@@ -175,4 +126,149 @@ export function uiLaneInfo() {
}
}
return utilRebind(laneInfo, dispatch, 'on');
-}
\ No newline at end of file
+}
+// import * as d3 from 'd3';
+// import { validTurnLanes } from '../../../osm/lanes';
+// import { utilRebind } from '../../../util/rebind';
+// import { formPipes } from '../lanes';
+// import { utilGetSetValue } from '../../../util/get_set_value';
+
+// import _ from 'lodash';
+
+// export function uiLaneInfo() {
+// var dispatch = d3.dispatch('change');
+// function laneInfo(selection, metadata, curDirection, curLane) {
+// // TODO: make this thing dynamic and show keysConsidered
+// // wrt to oneway.
+// var oneway = metadata.oneway;
+
+// var wrapper = selection
+// .selectAll('.lanes-info')
+// .data([0]);
+
+// var enter = wrapper.enter()
+// .append('div')
+// .attr('class', 'lanes-info lanes-wrap preset-input-wrap');
+
+// wrapper = wrapper
+// .merge(enter);
+
+// var input = wrapper.selectAll('.lanes-info')
+// .data(oneway ? [{
+// text: 'Lanes',
+// dir: 'oneway'
+// }] : [{
+// text: 'Forward Lanes',
+// dir: 'forward'
+// },
+// {
+// text: 'Backward Lanes',
+// dir: 'backward'
+// }]);
+
+// input.exit()
+// .remove();
+
+// input = input.enter()
+// .append('input')
+// .attr('class', 'lanes-info')
+// .attr('type', 'lane-count')
+// .merge(input);
+
+// input
+// .attr('placeholder', function (d) {
+// return d.text;
+// })
+// .attr('direction', function (d) {
+// return d.dir;
+// })
+// .on('input', change)
+// .on('blur', change)
+// .on('change', change)
+// .each(function (d) {
+// if (d.dir === 'oneway') {
+// this.value = metadata.count;
+// return;
+// }
+// this.value = metadata[d.dir];
+// });
+
+
+// // var items = list.selectAll('li')
+// // .data(keysConsidered);
+
+// // Enter
+// // var enter = items.enter()
+// // .append('li')
+// // .attr('class', function (d) { return 'cf preset-access-' + d; });
+
+// // enter
+// // .append('span')
+// // .attr('class', 'col6 label preset-label-')
+// // .attr('for', function (d) { return 'preset-input-' + d; })
+// // .text(function (d) { return d; });
+
+// // enter
+// // .append('div')
+// // .attr('class', 'col6 preset-input-lanes-wrap')
+// // .append('input')
+// // .attr('type', 'text')
+// // .attr('class', 'preset-input-lanes')
+// // .attr('id', function (d) { return 'preset-input-lanes-' + d; })
+// // .each(function (d) {
+// // this.value = metadata[d];
+// // });
+
+// // // Update
+// // items = items.merge(enter);
+// // items.selectAll('input')
+// // .property('value', function (d) {
+// // return metadata[d];
+// // });
+
+// // var input = items.selectAll('input');
+
+// // input
+// // .on('change', change)
+// // .on('blur', change);
+
+// function change(d) {
+// var tag = {};
+// metadata.count = utilGetSetValue(selection.selectAll('input'));
+
+// if (metadata.oneway) {
+// if (d === 'count') {
+// var count = utilGetSetValue(d3.select(this));
+// count = parseInt(count, 10);
+// if (!_.isNaN(count)) metadata.count = count;
+// }
+// if (d === 'reverse') {
+// if (utilGetSetValue(d3.select(this)) === 'true') {
+// metadata.reverse = true;
+// } else {
+// metadata.reverse = false;
+// }
+// }
+
+// tag.lanes = Number(metadata.count).toString();
+// tag['lanes:forward'] = undefined;
+// tag['lanes:backward'] = undefined;
+
+// } else {
+// if (d === 'forward') {
+// var forward = utilGetSetValue(d3.select(this));
+// forward = parseInt(forward, 10);
+// if (!_.isNaN(forward)) metadata.forward = forward;
+// }
+// if (d === 'backward') {
+// var backward = utilGetSetValue(d3.select(this));
+// backward = parseInt(backward, 10);
+// if (!_.isNaN(backward)) metadata.backward = backward;
+// }
+// }
+
+// dispatch.call('change', this);
+// }
+// }
+// return utilRebind(laneInfo, dispatch, 'on');
+// }
\ No newline at end of file
diff --git a/temp.js b/temp.js
new file mode 100644
index 00000000000..e5f4fcc23b1
--- /dev/null
+++ b/temp.js
@@ -0,0 +1,113 @@
+import * as d3 from 'd3';
+import { validTurnLanes } from '../../../osm/lanes';
+import { utilRebind } from '../../../util/rebind';
+import { formPipes } from '../lanes';
+import { utilGetSetValue } from '../../../util/get_set_value';
+
+import _ from 'lodash';
+
+export function uiLaneInfo() {
+ var dispatch = d3.dispatch('change');
+ function laneInfo(selection, metadata, curDirection, curLane) {
+ // TODO: make this thing dynamic and show keysConsidered
+ // wrt to oneway.
+ var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
+ var s = selection.selectAll('.lanes-info').data([0]);
+ s = s.enter()
+ .append('div')
+ .attr('class', 'lanes-info')
+ .merge(s);
+
+ var wrap = s.selectAll('.preset-input-wrap')
+ .data([0]);
+
+ wrap = wrap.enter()
+ .append('div')
+ .attr('class', 'preset-input-wrap')
+ .append('ul')
+ .merge(wrap);
+
+ var list = wrap.selectAll('ul')
+ .data([0]);
+
+ list = list.enter()
+ .append('ul')
+ .merge(list);
+
+
+ var items = list.selectAll('li')
+ .data(keysConsidered);
+
+ // Enter
+ var enter = items.enter()
+ .append('li')
+ .attr('class', function (d) { return 'cf preset-access-' + d; });
+
+ enter
+ .append('span')
+ .attr('class', 'col6 label preset-label-')
+ .attr('for', function (d) { return 'preset-input-' + d; })
+ .text(function (d) { return d; });
+
+ enter
+ .append('div')
+ .attr('class', 'col6 preset-input-lanes-wrap')
+ .append('input')
+ .attr('type', 'text')
+ .attr('class', 'preset-input-lanes')
+ .attr('id', function (d) { return 'preset-input-lanes-' + d; })
+ .each(function (d) {
+ this.value = metadata[d];
+ });
+
+ // Update
+ items = items.merge(enter);
+ items.selectAll('input')
+ .property('value', function (d) {
+ return metadata[d];
+ });
+
+ var input = items.selectAll('input');
+
+ input
+ .on('change', change)
+ .on('blur', change);
+
+ function change(d) {
+ var tag = {};
+ if (metadata.oneway) {
+ if (d === 'count') {
+ var count = utilGetSetValue(d3.select(this));
+ count = parseInt(count, 10);
+ if (!_.isNaN(count)) metadata.count = count;
+ }
+ if (d === 'reverse') {
+ if (utilGetSetValue(d3.select(this)) === 'true') {
+ metadata.reverse = true;
+ } else {
+ metadata.reverse = false;
+ }
+ }
+
+ tag.lanes = Number(metadata.count).toString();
+ tag['lanes:forward'] = undefined;
+ tag['lanes:backward'] = undefined;
+
+ } else {
+ if (d === 'forward') {
+ var forward = utilGetSetValue(d3.select(this));
+ forward = parseInt(forward, 10);
+ if (!_.isNaN(forward)) metadata.forward = forward;
+ }
+ if (d === 'backward') {
+ var backward = utilGetSetValue(d3.select(this));
+ backward = parseInt(backward, 10);
+ if (!_.isNaN(backward)) metadata.backward = backward;
+ }
+ }
+
+ dispatch.call('change', this);
+ }
+ }
+ return utilRebind(laneInfo, dispatch, 'on');
+}
\ No newline at end of file
From eb759ee8ff68ec406a842f633d7221970c4b46f1 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 21:49:27 +0530
Subject: [PATCH 22/25] UI cleanup
---
css/app.css | 46 +++++++--
modules/osm/lanes.js | 4 +-
modules/ui/fields/lanes.js | 49 ++++++----
modules/ui/fields/lanes/laneInfo.js | 145 ----------------------------
modules/ui/fields/lanes/turn.js | 115 ++++++++++++----------
5 files changed, 131 insertions(+), 228 deletions(-)
diff --git a/css/app.css b/css/app.css
index 2a87cf72e5f..36119c7d363 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1282,7 +1282,7 @@ button.save.has-count .count::before {
}
-.lane-selector .lane-item {
+.lane-selector .lane-index {
cursor: pointer;
display: flex;
flex-grow: 1;
@@ -1292,35 +1292,63 @@ button.save.has-count .count::before {
background-color: white;
}
-.lane-selector .lane-item.active {
+.lane-selector .lane-index.active {
background-color: #E8EBFF;
}
-.lane-selector .lane-item.active:hover {
+.lane-selector .lane-index.active:hover {
background-color: #E8EBFF;
}
-.lane-selector .lane-item:hover {
+.lane-selector .lane-index:hover {
background-color: #ececec;
}
-.lane-selector .lane-item:last-child {
+.lane-selector .lane-index.has-data {
+ color: #7092ff;
+}
+
+.lane-selector .lane-index:last-child {
border-right: 0;
}
-.lane-selector .lane-item span {
+.lane-selector .lane-index span {
height: 30px;
line-height: 30px;
}
-.lane-tags > label {
+.turn-lane-tags .turn-lanes-direction {
position: relative;
padding: 5px 10px;
- display: block;
height: 30px;
background-color: white;
color: #7092FF;
cursor: pointer;
}
+.turn-lane-tags .turn-lanes-direction.active {
+ background-color: #E8EBFF;
+}
+.turn-lane-tags .turn-lanes-direction.active:hover {
+ background-color: #E8EBFF;
+}
+.turn-lane-tags .turn-lanes-direction.left-border {
+ border-left: 1px solid #ccc
+}
+.turn-lane-tags .turn-lanes-direction:hover {
+ background-color: #ececec;
+}
+.turn-lanes-directions .direction {
+ width: 50px;
+}
+.turn-lane-tags .turn-lanes-direction:nth-last-child(2) {
+ border-bottom: 0;
+ border-bottom-left-radius: 4px;
+}
+.turn-lane-tags .turn-lanes-direction:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 4px;
+}
+
+/*
.lane-tags > label:hover {
background-color: #ececec;
}
@@ -1342,7 +1370,7 @@ button.save.has-count .count::before {
.lane-tags > label.active {
background: #E8EBFF;
-}
+}*/
/*lane-visualizer*/
diff --git a/modules/osm/lanes.js b/modules/osm/lanes.js
index 8989181ce07..b60195fc758 100644
--- a/modules/osm/lanes.js
+++ b/modules/osm/lanes.js
@@ -1,8 +1,8 @@
import _ from 'lodash';
export var validTurnLanes = [
- 'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
- 'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
+ 'left', 'right', 'slight_left', 'slight_right', 'sharp_left',
+ 'sharp_right', 'merge_to_left', 'merge_to_right','reverse', 'through', 'none'
];
export function osmLanes(entity) {
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 93a15daf517..30cce898b63 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -19,12 +19,11 @@ export function uiFieldLanes(field, context) {
var lanesInfo = uiLaneInfo(field, context)
.on('change', change);
- // var lanes
function lanes(selection) {
lanesData = context.entity(wayID).lanes();
metadata = lanesData.metadata;
-
+
if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
selection.call(lanes.off);
return;
@@ -38,7 +37,7 @@ export function uiFieldLanes(field, context) {
.append('div')
.attr('class', 'lane-selector localized-wrap')
.merge(laneSelector);
-
+
laneSelector.call(laneSelectorUI);
selection.call(turnLanes, metadata, curDir, curLane);
@@ -60,11 +59,7 @@ export function uiFieldLanes(field, context) {
function laneSelectorUI(selection) {
var items;
var metadata = lanesData.metadata;
- var oneway = metadata.oneway;
var len = metadata.count;
- // TODO: clean up this mess of vvvvv
- if (oneway) len = metadata.count;
- else len = metadata.forward + metadata.backward;
selection.selectAll('.form-label')
.data([0])
@@ -88,20 +83,20 @@ export function uiFieldLanes(field, context) {
.append('ul')
.merge(list);
- items = list.selectAll('.lane-item')
+ items = list.selectAll('.lane-index')
.data(_.fill(Array(len), 0).map(function (n, i) {
return i;
}));
items.enter()
.append('div')
- .attr('class', 'lane-item')
+ .attr('class', 'lane-index')
.attr('id', function (d) {
return 'lane-' + d;
})
.append('span');
- var input = selection.selectAll('.lane-item');
+ var input = selection.selectAll('.lane-index');
input.selectAll('span')
.text(function (d) {
@@ -112,13 +107,24 @@ export function uiFieldLanes(field, context) {
return (d - metadata.forward + 1) + '▼';
});
- input.classed('active', function (d) {
- if (metadata.oneway) return d === curLane;
- if (curDir === 'forward') {
- return d === curLane;
- }
- return curLane + metadata.forward === d;
- });
+ input
+ .classed('active', function (d) {
+ if (metadata.oneway) return d === curLane;
+ if (curDir === 'forward') {
+ return d === curLane;
+ }
+ return curLane + metadata.forward === d;
+ })
+ .classed('has-data', function (d) {
+ if (metadata.oneway) {
+ return hasData('unspecified', d);
+ }
+ if (d < metadata.forward) {
+ return hasData('forward', d);
+ }
+ return hasData('backward', d - metadata.forward);
+ });
+
input.on('click', function (d) {
if (metadata.oneway) {
curLane = d;
@@ -140,6 +146,12 @@ export function uiFieldLanes(field, context) {
}
}
+ function hasData(direction, lane) {
+ var data = metadata.turnLanes[direction][lane];
+ if (data) {
+ return data.indexOf('none') === -1;
+ }
+ }
function change(t, onInput) {
var tag = {};
@@ -157,7 +169,7 @@ export function uiFieldLanes(field, context) {
tag['turn:lanes:backward'] = undefined;
} else {
curLane = curLane >= metadata[curDir] ? 0 : curLane;
-
+
tag.lanes = metadata.forward + metadata.backward + metadata.bothways + '';
tag['lanes:forward'] = metadata.forward + '';
tag['lanes:backward'] = metadata.backward + '';
@@ -202,7 +214,6 @@ export function formPipes(data, len, nullKey) {
}
var isEmpty = _.every(piped, function (i) {
- if (!_.isArray(i)) throw new exception('I is not array');
return i.indexOf(nullKey) > -1;
});
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index 6a37fc33a74..4ef1cdd95bd 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -127,148 +127,3 @@ export function uiLaneInfo() {
}
return utilRebind(laneInfo, dispatch, 'on');
}
-// import * as d3 from 'd3';
-// import { validTurnLanes } from '../../../osm/lanes';
-// import { utilRebind } from '../../../util/rebind';
-// import { formPipes } from '../lanes';
-// import { utilGetSetValue } from '../../../util/get_set_value';
-
-// import _ from 'lodash';
-
-// export function uiLaneInfo() {
-// var dispatch = d3.dispatch('change');
-// function laneInfo(selection, metadata, curDirection, curLane) {
-// // TODO: make this thing dynamic and show keysConsidered
-// // wrt to oneway.
-// var oneway = metadata.oneway;
-
-// var wrapper = selection
-// .selectAll('.lanes-info')
-// .data([0]);
-
-// var enter = wrapper.enter()
-// .append('div')
-// .attr('class', 'lanes-info lanes-wrap preset-input-wrap');
-
-// wrapper = wrapper
-// .merge(enter);
-
-// var input = wrapper.selectAll('.lanes-info')
-// .data(oneway ? [{
-// text: 'Lanes',
-// dir: 'oneway'
-// }] : [{
-// text: 'Forward Lanes',
-// dir: 'forward'
-// },
-// {
-// text: 'Backward Lanes',
-// dir: 'backward'
-// }]);
-
-// input.exit()
-// .remove();
-
-// input = input.enter()
-// .append('input')
-// .attr('class', 'lanes-info')
-// .attr('type', 'lane-count')
-// .merge(input);
-
-// input
-// .attr('placeholder', function (d) {
-// return d.text;
-// })
-// .attr('direction', function (d) {
-// return d.dir;
-// })
-// .on('input', change)
-// .on('blur', change)
-// .on('change', change)
-// .each(function (d) {
-// if (d.dir === 'oneway') {
-// this.value = metadata.count;
-// return;
-// }
-// this.value = metadata[d.dir];
-// });
-
-
-// // var items = list.selectAll('li')
-// // .data(keysConsidered);
-
-// // Enter
-// // var enter = items.enter()
-// // .append('li')
-// // .attr('class', function (d) { return 'cf preset-access-' + d; });
-
-// // enter
-// // .append('span')
-// // .attr('class', 'col6 label preset-label-')
-// // .attr('for', function (d) { return 'preset-input-' + d; })
-// // .text(function (d) { return d; });
-
-// // enter
-// // .append('div')
-// // .attr('class', 'col6 preset-input-lanes-wrap')
-// // .append('input')
-// // .attr('type', 'text')
-// // .attr('class', 'preset-input-lanes')
-// // .attr('id', function (d) { return 'preset-input-lanes-' + d; })
-// // .each(function (d) {
-// // this.value = metadata[d];
-// // });
-
-// // // Update
-// // items = items.merge(enter);
-// // items.selectAll('input')
-// // .property('value', function (d) {
-// // return metadata[d];
-// // });
-
-// // var input = items.selectAll('input');
-
-// // input
-// // .on('change', change)
-// // .on('blur', change);
-
-// function change(d) {
-// var tag = {};
-// metadata.count = utilGetSetValue(selection.selectAll('input'));
-
-// if (metadata.oneway) {
-// if (d === 'count') {
-// var count = utilGetSetValue(d3.select(this));
-// count = parseInt(count, 10);
-// if (!_.isNaN(count)) metadata.count = count;
-// }
-// if (d === 'reverse') {
-// if (utilGetSetValue(d3.select(this)) === 'true') {
-// metadata.reverse = true;
-// } else {
-// metadata.reverse = false;
-// }
-// }
-
-// tag.lanes = Number(metadata.count).toString();
-// tag['lanes:forward'] = undefined;
-// tag['lanes:backward'] = undefined;
-
-// } else {
-// if (d === 'forward') {
-// var forward = utilGetSetValue(d3.select(this));
-// forward = parseInt(forward, 10);
-// if (!_.isNaN(forward)) metadata.forward = forward;
-// }
-// if (d === 'backward') {
-// var backward = utilGetSetValue(d3.select(this));
-// backward = parseInt(backward, 10);
-// if (!_.isNaN(backward)) metadata.backward = backward;
-// }
-// }
-
-// dispatch.call('change', this);
-// }
-// }
-// return utilRebind(laneInfo, dispatch, 'on');
-// }
\ No newline at end of file
diff --git a/modules/ui/fields/lanes/turn.js b/modules/ui/fields/lanes/turn.js
index 66542a37fe3..7a026da25dc 100644
--- a/modules/ui/fields/lanes/turn.js
+++ b/modules/ui/fields/lanes/turn.js
@@ -1,23 +1,28 @@
import * as d3 from 'd3';
-import { validTurnLanes } from '../../../osm/lanes';
import { utilRebind } from '../../../util/rebind';
-import { formPipes } from '../lanes';
import _ from 'lodash';
+import { svgIcon } from '../../../svg/index';
-export function uiTurnLanes(field) {
+var validTurnLanes = [
+ 'left', 'right', 'slight_left', 'slight_right', 'sharp_left',
+ 'sharp_right', 'merge_to_left', 'merge_to_right', 'reverse', 'through'
+];
+
+export function uiTurnLanes() {
var dispatch = d3.dispatch('change');
function turnLanes(selection, metadata, curDirection, curLane) {
var turnLanesData = metadata.turnLanes;
- var valid = validTurnLanes.map(function (t) {
- var dir = turnLanesData[curDirection][curLane];
- if (!dir) return false;
- return dir.indexOf(t) > -1;
- });
-
+ var valid = validTurnLanes.map(function (d) {
+ var directions = turnLanesData[curDirection][curLane];
+ return {
+ dir: d,
+ active: directions && directions.indexOf(d) > -1
+ };
+ });
var wrapper = selection
.selectAll('.turn-lanes')
- .data([0]);
+ .data([curLane]);
wrapper.exit().remove();
@@ -25,72 +30,76 @@ export function uiTurnLanes(field) {
.append('div')
.attr('class', 'turn-lanes localized-wrap');
- enter
+ var label = enter
.append('label')
.attr('class', 'form-label entry')
.text('Turn Lanes');
- enter
+ var buttonWrap = label
.append('div')
- .attr('class', 'lane-tags preset-input-wrap checkselect');
+ .attr('class', 'form-label-button-wrap');
+
+ buttonWrap.append('button')
+ .attr('class', 'remove-icon')
+ .attr('tabindex', -1)
+ .call(svgIcon('#operation-delete'));
+
+ enter
+ .append('ul')
+ .attr('class', 'turn-lane-tags preset-input-wrap checkselect');
wrapper = wrapper
.merge(enter);
- var label = wrapper
- .selectAll('.lane-tags')
- .selectAll('label')
- .data(valid);
- label.exit()
- .remove();
+ // Updatoe
+ // wrapper
+ // .selectAll('.form-label')
+ // .text(function (d) {
+ // return 'Turn Lane #' + (curLane + 1);
+ // });
+
+ wrapper.selectAll('.remove-icon')
+ .on('click', remove);
- var labelEnter = label.enter()
- .append('label');
+ var dirWrapper = wrapper.selectAll('ul')
+ .selectAll('.turn-lanes-direction')
+ .data(valid);
- labelEnter
- .append('input')
- .property('direction', function (d, i) { return validTurnLanes[i]; })
- .property('indeterminate', field.type === 'check')
- .attr('type', 'checkbox')
- .attr('id', 'preset-input-' + field.id);
+ dirWrapper.exit().remove();
+ var row = dirWrapper
+ .enter()
+ .append('li')
+ .attr('class', 'label col6 turn-lanes-direction')
+ .text(function (d, i) { return d.dir; });
- labelEnter
- .append('span')
- .text(function (d, i) { return validTurnLanes[i]; })
- .attr('class', 'value');
+ dirWrapper = dirWrapper
+ .merge(row);
- label = label
- .merge(labelEnter)
- .select('input')
- .property('checked', function (d) {
- return d;
+ // Update
+ dirWrapper
+ .classed('active', function (d) { return d.active; })
+ .classed('left-border', function(d, i) {
+ return i%2 === 1;
})
.on('click', change);
- function change() {
+ function remove() {
+ d3.event.stopPropagation();
+ turnLanesData[curDirection][curLane] = ['none'];
+ dispatch.call('change', this);
+ }
+ function change(d) {
d3.event.stopPropagation();
- var input = selection.selectAll('input');
- var direction = d3.select(this).property('direction');
var newDirs = [];
-
- input.each(function (d, i) {
- var value = d3.select(this).property('checked');
- var direction = d3.select(this).property('direction');
- if (value) {
- newDirs.push(direction);
- }
+ d.active = !d.active;
+ valid.forEach(function (v) {
+ if (v.active) newDirs.push(v.dir);
});
- if (direction === 'none' || newDirs.length === 0) {
- newDirs = ['none'];
- } else {
- _.pull(newDirs, 'none');
- }
-
+ if (newDirs.length === 0) newDirs = ['none'];
turnLanesData[curDirection][curLane] = newDirs;
-
dispatch.call('change', this);
}
}
From 512468a57f508bf3c38d8a2a82f61c57ae39bb4e Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 22:16:18 +0530
Subject: [PATCH 23/25] svg lanes ui cleanup
---
css/app.css | 39 ++++++++-------------------------------
modules/svg/lanes.js | 41 ++++++++++++++++++++---------------------
2 files changed, 28 insertions(+), 52 deletions(-)
diff --git a/css/app.css b/css/app.css
index 36119c7d363..30925ce7d79 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1303,7 +1303,7 @@ button.save.has-count .count::before {
}
.lane-selector .lane-index.has-data {
- color: #7092ff;
+ font-weight: bold;
}
.lane-selector .lane-index:last-child {
@@ -1347,39 +1347,16 @@ button.save.has-count .count::before {
border-bottom-right-radius: 4px;
}
-
-/*
-.lane-tags > label:hover {
- background-color: #ececec;
-}
-
-.lane-tags > label:not(:last-child) {
- border-bottom: 1px solid #ccc;
-}
-
-.lane-tags > label:last-child {
- border-radius: 0 0 3px 3px;
-}
-
-.lane-tags label > span {
- display: block;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
+.lanes-svg-wrapper .lanes-circle {
+ stroke-width: 2;
+ stroke: #000;
+ fill-opacity: 0.75;
+ fill: #fff;
}
-.lane-tags > label.active {
- background: #E8EBFF;
-}*/
-
-/*lane-visualizer*/
-
-.lane-visualizer-background {
- fill: #000;
- fill-opacity: 0.5;
+.lanes-svg-wrapper .lanes-circle.backward {
+ stroke-dasharray: 3 5;
}
-
-
/* preset form multicombo */
.form-field-multicombo {
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 285f0c4b5b9..3d82cbe9ff2 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -23,7 +23,7 @@ export function svgLanes(projection, context) {
var driveLeft;
var layoutSeq = [];
var iconWidth = 40;
- var zoomLimit = zoom >= 18;
+ var zoomLimit = zoom >= 19.5;
// TODO: on removing map features svgLanes stays there
if (entity) {
@@ -40,7 +40,7 @@ export function svgLanes(projection, context) {
// Each DOM node bound to data will have a special __data__ property
// you can see it in Chrome developer tools
var wrapper = selection.selectAll('.layer-hit')
- .selectAll('.lanes-wrapper')
+ .selectAll('.lanes-svg-wrapper')
.data(wrapperData && zoomLimit ? [wrapperData] : []);
// wrapper EXIT
@@ -54,11 +54,9 @@ export function svgLanes(projection, context) {
// the normal thing to do here is create the missing DOM nodes
var enter = wrapper.enter()
.insert('g', ':first-child')
- .attr('class', 'lanes-wrapper');
+ .attr('class', 'lanes-svg-wrapper');
+
- enter
- .append('rect')
- .attr('class', 'lanes-background');
// enter.append('polygon')
// .attr('points', '-3,4 5,0 -3,-4')
@@ -82,12 +80,12 @@ export function svgLanes(projection, context) {
return 'translate(' + p[0] + ',' + p[1] + ') rotate(' + ang + ')';
});
- wrapper.selectAll('.lanes-background')
- .attr('transform', function () {
- return 'translate(' + metadata.count * iconWidth / (-2) + ', 0)';
- })
- .attr('width', function () { return metadata.count * iconWidth; })
- .attr('height', function () { return iconWidth; });
+ // wrapper.selectAll('.lanes-background')
+ // .attr('transform', function () {
+ // return 'translate(' + metadata.count * iconWidth / (-2) + ', 0)';
+ // })
+ // .attr('width', function () { return metadata.count * iconWidth; })
+ // .attr('height', function () { return iconWidth; });
@@ -136,15 +134,16 @@ export function svgLanes(projection, context) {
// situation, it's the behavior we want, so we can style the circle based on `d.dir`.
// `select` propagates __data__ to children, `selectAll` does not.
lanes.select('.lanes-circle')
- .style('fill', function (d) {
- switch (d.dir) {
- case 'forward':
- return '#dfffdf';
- case 'backward':
- return '#ffd8d8';
- default:
- return '#d8d8d8';
- }
+ .classed('backward', function (d) {
+ return d.dir === 'backward';
+ // switch (d.dir) {
+ // case 'forward':
+ // return '#dfffdf';
+ // case 'backward':
+ // return '#ffd8d8';
+ // default:
+ // return '#d8d8d8';
+ // }
});
From b84323f2b5897adec80202b5cf2f5eb44b52f692 Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 22:26:33 +0530
Subject: [PATCH 24/25] lanesInfo cleanup
---
modules/ui/fields/lanes.js | 4 +---
modules/ui/fields/lanes/laneInfo.js | 7 ++-----
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js
index 30cce898b63..1a1a1557122 100644
--- a/modules/ui/fields/lanes.js
+++ b/modules/ui/fields/lanes.js
@@ -1,13 +1,11 @@
import * as d3 from 'd3';
-import { utilRebind } from '../../util/rebind';
import _ from 'lodash';
-import { utilGetSetValue } from '../../util/get_set_value';
+import { utilRebind } from '../../util/rebind';
import { uiTurnLanes } from './lanes/turn';
import { uiLaneInfo } from './lanes/laneInfo';
export function uiFieldLanes(field, context) {
var dispatch = d3.dispatch('change'),
- // TODO: currentLane if big like 6 goes crazy if other wayID has less than 6 lanes
curLane = 0,
curDir = 'unspecified',
wayID,
diff --git a/modules/ui/fields/lanes/laneInfo.js b/modules/ui/fields/lanes/laneInfo.js
index 4ef1cdd95bd..9d886b0bc53 100644
--- a/modules/ui/fields/lanes/laneInfo.js
+++ b/modules/ui/fields/lanes/laneInfo.js
@@ -1,14 +1,12 @@
import * as d3 from 'd3';
-import { validTurnLanes } from '../../../osm/lanes';
import { utilRebind } from '../../../util/rebind';
-import { formPipes } from '../lanes';
import { utilGetSetValue } from '../../../util/get_set_value';
import _ from 'lodash';
export function uiLaneInfo() {
var dispatch = d3.dispatch('change');
- function laneInfo(selection, metadata, curDirection, curLane) {
+ function laneInfo(selection, metadata) {
var s = selection.selectAll('.lanes-info').data([0]);
s = s.enter()
.append('div')
@@ -35,6 +33,7 @@ export function uiLaneInfo() {
.data(metadata.oneway ? ['count'] : ['forward', 'backward']);
items.exit().remove();
+
// Enter
var enter = items.enter()
.append('li')
@@ -67,8 +66,6 @@ export function uiLaneInfo() {
.attr('class', 'decrement')
.attr('tabindex', -1);
-
-
// Update
items = items.merge(enter);
From 8014de2efb581f5890dd51559cfecd13e6fd80ef Mon Sep 17 00:00:00 2001
From: Kushan Joshi <0o3ko0@gmail.com>
Date: Sun, 5 Feb 2017 22:44:57 +0530
Subject: [PATCH 25/25] css cleanup
---
.gitignore | 1 +
.vscode/launch.json | 19 ------
.vscode/settings.json | 3 -
css/app.css | 22 +------
data/core.yaml | 12 ++++
dist/locales/en.json | 14 ++++
modules/geo/geo.js | 6 +-
modules/geo/index.js | 1 -
modules/modes/select.js | 4 +-
modules/renderer/map.js | 5 +-
modules/svg/lanes.js | 27 ++++----
modules/svg/midpoints.js | 2 +
modules/ui/entity_editor.js | 1 +
modules/ui/fields/lanes/turn.js | 13 +---
modules/ui/map_in_map.js | 49 ++++++--------
modules/ui/preset.js | 1 +
modules/ui/radial_menu.js | 1 +
temp.js | 113 --------------------------------
test/spec/osm/lanes.js | 2 +-
19 files changed, 74 insertions(+), 222 deletions(-)
delete mode 100644 .vscode/launch.json
delete mode 100644 .vscode/settings.json
delete mode 100644 temp.js
diff --git a/.gitignore b/.gitignore
index c2925d6a7de..4335eac6196 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ dist/mapillary-js/
node_modules/
npm-debug.log
transifex.auth
+.vscode
# autogenerated symlinks
land.html
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 064c90f7b3c..00000000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "version": "0.2.0",
- "configurations": [
- {
- "name": "Launch Chrome against localhost",
- "type": "chrome",
- "request": "launch",
- "url": "http://localhost:8080/#background=Bing&id=w26283961&map=18.71/12.98164/77.63874",
- "webRoot": "${workspaceRoot}"
- },
- {
- "name": "Attach to Chrome",
- "type": "chrome",
- "request": "attach",
- "port": 9222,
- "webRoot": "${workspaceRoot}"
- }
- ]
-}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index 0c4a6693fab..00000000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "vsicons.presets.angular": false
-}
\ No newline at end of file
diff --git a/css/app.css b/css/app.css
index 30925ce7d79..8d3aa4855e3 100644
--- a/css/app.css
+++ b/css/app.css
@@ -1223,14 +1223,10 @@ button.save.has-count .count::before {
/* lanes */
-.form-field-lanes {
-
-}
-
.form-field-lanes .lanes-info input {
min-height: 30px;
- padding: 5px 10px;
- width: 100%;
+ /*padding: 5px 10px;
+ width: 100%;*/
border-radius: 0;
border-width: 0;
border-left-width: 1px;
@@ -1249,19 +1245,6 @@ button.save.has-count .count::before {
border-top: 0
}
-/*
-.form-field-lanes .preset-input-lanes-wrap input {
- border-top: 0;
- border-left-width: 1px;
-}*/
-
-/*
-.form-field-lanes .preset-input-lanes-wrap input {
- border-radius: 0;
- border-width: 0;
- border-left-width: 1px;
-}
-*/
.form-field-lanes .preset-input-wrap li {
border-bottom: 1px solid #CCC;
}
@@ -1279,7 +1262,6 @@ button.save.has-count .count::before {
.lane-selector ul {
display: flex;
flex-direction: row;
-
}
.lane-selector .lane-index {
diff --git a/data/core.yaml b/data/core.yaml
index 3aa09cd67e0..6f4e51e421c 100644
--- a/data/core.yaml
+++ b/data/core.yaml
@@ -838,3 +838,15 @@ en:
help: "You can replay this walkthrough or view more documentation by clicking the {button} Help button."
save: "Don't forget to regularly save your changes!"
start: "Start mapping!"
+ lanes:
+ turn:
+ left: "Left"
+ right: "Right"
+ slight_left: "Slight left"
+ slight_right: "Slight right"
+ sharp_left: "Sharp left"
+ sharp_right: "Sharp right"
+ merge_to_left: "Merge left"
+ merge_to_right: "Merge right"
+ reverse: "Reverse"
+ through: "Through"
\ No newline at end of file
diff --git a/dist/locales/en.json b/dist/locales/en.json
index 04eac3a490b..afb7eea9e25 100644
--- a/dist/locales/en.json
+++ b/dist/locales/en.json
@@ -697,6 +697,20 @@
"start": "Start mapping!"
}
},
+ "lanes": {
+ "turn": {
+ "left": "Left",
+ "right": "Right",
+ "slight_left": "Slight left",
+ "slight_right": "Slight right",
+ "sharp_left": "Sharp left",
+ "sharp_right": "Sharp right",
+ "merge_to_left": "Merge left",
+ "merge_to_right": "Merge right",
+ "reverse": "Reverse",
+ "through": "Through"
+ }
+ },
"presets": {
"categories": {
"category-barrier": {
diff --git a/modules/geo/geo.js b/modules/geo/geo.js
index f0c78dda0ec..096c0a18e0d 100644
--- a/modules/geo/geo.js
+++ b/modules/geo/geo.js
@@ -11,11 +11,6 @@ export function geoInterp(p1, p2, t) {
p1[1] + (p2[1] - p1[1]) * t];
}
-// returns a point which divides the line joining p1, p2
-// in the ratio m:n
-export function geoDivideSegment(p1, p2, m, n) {
- return [(p2[0]*n + p2[0]*m)/(m+n), (p2[1]*n + p2[1]*m)/(m+n)];
-}
// 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
// Returns a positive value, if OAB makes a counter-clockwise turn,
@@ -108,6 +103,7 @@ export function geoAngle(a, b, projection) {
return Math.atan2(b[1] - a[1], b[0] - a[0]);
}
+
// Rotate all points counterclockwise around a pivot point by given angle
export function geoRotate(points, angle, around) {
return points.map(function(point) {
diff --git a/modules/geo/index.js b/modules/geo/index.js
index 8e060f7f787..5e37b16fe04 100644
--- a/modules/geo/index.js
+++ b/modules/geo/index.js
@@ -21,4 +21,3 @@ export { geoPointInPolygon } from './geo.js';
export { geoPolygonContainsPolygon } from './geo.js';
export { geoPolygonIntersectsPolygon } from './geo.js';
export { geoSphericalDistance } from './geo.js';
-export { geoDivideSegment } from './geo.js';
\ No newline at end of file
diff --git a/modules/modes/select.js b/modules/modes/select.js
index d87c76c984c..27032262e84 100644
--- a/modules/modes/select.js
+++ b/modules/modes/select.js
@@ -146,9 +146,9 @@ export function modeSelect(context, selectedIDs) {
function positionMenu() {
- var entity = singular();
if (suppressMenu || !radialMenu) { return; }
+ var entity = singular();
if (entity && context.geometry(entity.id) === 'relation') {
suppressMenu = true;
} else if (entity && entity.type === 'node') {
@@ -158,12 +158,10 @@ export function modeSelect(context, selectedIDs) {
viewport = geoExtent(context.projection.clipExtent()).polygon();
if (geoPointInPolygon(point, viewport)) {
radialMenu.center(point);
-
} else {
suppressMenu = true;
}
}
- console.log(entity);
}
diff --git a/modules/renderer/map.js b/modules/renderer/map.js
index 9b8794fc016..91a146d71c6 100644
--- a/modules/renderer/map.js
+++ b/modules/renderer/map.js
@@ -63,7 +63,6 @@ export function rendererMap(context) {
function map(selection) {
-
_selection = selection;
context
@@ -162,7 +161,7 @@ export function rendererMap(context) {
surface.selectAll('.data-layer-osm')
.call(drawVertices, graph, all, filter, map.extent(), map.zoom())
.call(drawMidpoints, graph, all, filter, map.trimmedExtent())
- .call(drawLanes, graph, all, filter, map.trimmedExtent(), map.zoom(), map.center());
+ .call(drawLanes, graph, all, filter, dimensions, map.zoom(), map.center());
dispatch.call('drawn', this, {full: false});
}
});
@@ -255,7 +254,7 @@ export function rendererMap(context) {
.call(drawLines, graph, data, filter)
.call(drawAreas, graph, data, filter)
.call(drawMidpoints, graph, data, filter, map.trimmedExtent())
- .call(drawLanes, graph, data, filter, map.trimmedExtent(), map.zoom(), map.center())
+ .call(drawLanes, graph, data, filter, dimensions, map.zoom(), map.center())
.call(drawLabels, graph, data, filter, dimensions, !difference && !extent)
.call(drawPoints, graph, data, filter);
diff --git a/modules/svg/lanes.js b/modules/svg/lanes.js
index 3d82cbe9ff2..42366795077 100644
--- a/modules/svg/lanes.js
+++ b/modules/svg/lanes.js
@@ -1,8 +1,5 @@
import _ from 'lodash';
-import {
- svgPointTransform,
- svgTagClasses
-} from './index';
+
import {
geoAngle,
@@ -12,12 +9,11 @@ import {
} from '../geo/index';
import { getLayoutSeq } from '../osm/lanes';
import { dataDriveLeft } from '../../data';
-import { geoPointInPolygon } from '../geo';
+import { geoPointInPolygon, geoExtent } from '../geo';
export function svgLanes(projection, context) {
-
- return function drawLanes(selection, graph, entities, filter, extent, zoom, mapCenter) {
+ return function drawLanes(selection, graph, entities, filter, dimensions, zoom, mapCenter) {
var entity = getEntity();
var metadata;
var driveLeft;
@@ -57,12 +53,6 @@ export function svgLanes(projection, context) {
.attr('class', 'lanes-svg-wrapper');
-
- // enter.append('polygon')
- // .attr('points', '-3,4 5,0 -3,-4')
- // .attr('class', 'fill');
-
-
// wrapper UPDATE
// update selection runs every time for all the matched DOM elements.
// `merge` brings in the nodes that were just entered
@@ -119,7 +109,7 @@ export function svgLanes(projection, context) {
lanes
.attr('transform', function (d, i) {
- var transform = 'translate(' + [iconWidth / 2 + i * iconWidth - metadata.count * iconWidth / (2) , (iconWidth / 2)] + ')';
+ var transform = 'translate(' + [iconWidth / 2 + i * iconWidth - metadata.count * iconWidth / (2), (iconWidth / 2)] + ')';
transform += d.turnLanes.indexOf('right') > -1 ? ' scale(-1, 1)' : '';
if (d.dir === 'backward') { transform += ' rotate(180)'; }
return transform;
@@ -168,8 +158,14 @@ export function svgLanes(projection, context) {
return entity;
}
+ function trimmedExtent() {
+ var headerY = 60, footerY = 30, pad = 90;
+ return new geoExtent(projection.invert([pad, dimensions[1] - footerY - pad]),
+ projection.invert([dimensions[0] - pad, headerY + pad]));
+ }
function findPosition() {
+ var extent = trimmedExtent();
var loc;
if (!entity) return;
@@ -180,7 +176,7 @@ export function svgLanes(projection, context) {
var a = nodes[j - 1];
var b = nodes[j];
if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
- var point = geoInterp(a.loc, b.loc, 0.75);
+ var point = geoInterp(a.loc, b.loc, 0.77);
if (extent.intersects(point)) {
loc = point;
} else {
@@ -206,3 +202,4 @@ export function svgLanes(projection, context) {
};
}
+
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index b99110839a8..a64b922254a 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -27,6 +27,7 @@ export function svgMidpoints(projection, context) {
continue;
if (context.selectedIDs().indexOf(entity.id) < 0)
continue;
+
var nodes = graph.childNodes(entity);
for (var j = 0; j < nodes.length - 1; j++) {
@@ -91,6 +92,7 @@ export function svgMidpoints(projection, context) {
.selectAll('g.midpoint')
.filter(midpointFilter)
.data(_.values(midpoints), function(d) { return d.id; });
+
groups.exit()
.remove();
diff --git a/modules/ui/entity_editor.js b/modules/ui/entity_editor.js
index ffe2b871650..e5fc7bb9070 100644
--- a/modules/ui/entity_editor.js
+++ b/modules/ui/entity_editor.js
@@ -180,6 +180,7 @@ export function uiEntityEditor(context) {
var blacklist = ['description', 'note', 'fixme'];
if (_.some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
+
var cleaned = v.split(';')
.map(function(s) { return s.trim(); })
.join(keepSpaces(k) ? '; ' : ';');
diff --git a/modules/ui/fields/lanes/turn.js b/modules/ui/fields/lanes/turn.js
index 7a026da25dc..4da9cf22ebf 100644
--- a/modules/ui/fields/lanes/turn.js
+++ b/modules/ui/fields/lanes/turn.js
@@ -1,7 +1,7 @@
import * as d3 from 'd3';
import { utilRebind } from '../../../util/rebind';
-import _ from 'lodash';
import { svgIcon } from '../../../svg/index';
+import { t } from '../../../util/locale';
var validTurnLanes = [
'left', 'right', 'slight_left', 'slight_right', 'sharp_left',
@@ -48,17 +48,10 @@ export function uiTurnLanes() {
.append('ul')
.attr('class', 'turn-lane-tags preset-input-wrap checkselect');
+ // Update
wrapper = wrapper
.merge(enter);
-
- // Updatoe
- // wrapper
- // .selectAll('.form-label')
- // .text(function (d) {
- // return 'Turn Lane #' + (curLane + 1);
- // });
-
wrapper.selectAll('.remove-icon')
.on('click', remove);
@@ -72,7 +65,7 @@ export function uiTurnLanes() {
.enter()
.append('li')
.attr('class', 'label col6 turn-lanes-direction')
- .text(function (d, i) { return d.dir; });
+ .text(function (d) { return t('lanes.turn.' + d.dir); });
dirWrapper = dirWrapper
.merge(row);
diff --git a/modules/ui/map_in_map.js b/modules/ui/map_in_map.js
index 5b19007da6d..1b383914511 100644
--- a/modules/ui/map_in_map.js
+++ b/modules/ui/map_in_map.js
@@ -10,8 +10,8 @@ import { utilGetDimensions } from '../util/dimensions';
var TAU = 2 * Math.PI;
function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
-function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
-function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
+function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
+function vecScale(a, b) { return [a[0] * b, a[1] * b]; }
export function uiMapInMap(context) {
@@ -209,7 +209,7 @@ export function uiMapInMap(context) {
var overlays = overlay
.selectAll('div')
- .data(activeOverlayLayers, function(d) { return d.source().name(); });
+ .data(activeOverlayLayers, function (d) { return d.source().name(); });
overlays.exit()
.remove();
@@ -217,7 +217,7 @@ export function uiMapInMap(context) {
overlays = overlays.enter()
.append('div')
.merge(overlays)
- .each(function(layer) { d3.select(this).call(layer); });
+ .each(function (layer) { d3.select(this).call(layer); });
var dataLayers = tiles
@@ -237,43 +237,34 @@ export function uiMapInMap(context) {
// redraw viewport bounding box
if (gesture !== 'pan') {
- // var getPath = d3.geoPath(projection),
- var bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
+ var getPath = d3.geoPath(projection),
+ bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
viewport = wrap.selectAll('.map-in-map-viewport')
.data([0]);
viewport = viewport.enter()
- .append('canvas')
- // .attr('class', 'map-in-map-viewport')
- .attr('height', 300)
- .attr('width', 300)
+ .append('svg')
+ .attr('class', 'map-in-map-viewport')
.merge(viewport);
- var path2 = viewport.selectAll('.map-in-map-bbox')
+ var path = viewport.selectAll('.map-in-map-bbox')
.data([bbox]);
- var ctx = d3.select('canvas').node().getContext('2d');
- var path = d3.geoPath()
- .projection(projection)
- .context(ctx);
- ctx.beginPath();
- path(bbox);
- ctx.stroke();
- // path.enter()
- // .append('path')
- // .attr('class', 'map-in-map-bbox')
- // .merge(path)
- // .attr('d', getPath)
- // .classed('thick', function(d) { return getPath.area(d) < 30; });
+ path.enter()
+ .append('path')
+ .attr('class', 'map-in-map-bbox')
+ .merge(path)
+ .attr('d', getPath)
+ .classed('thick', function (d) { return getPath.area(d) < 30; });
}
}
function queueRedraw() {
clearTimeout(timeoutId);
- timeoutId = setTimeout(function() { redraw(); }, 750);
+ timeoutId = setTimeout(function () { redraw(); }, 750);
}
@@ -293,7 +284,7 @@ export function uiMapInMap(context) {
.transition()
.duration(200)
.style('opacity', '0')
- .on('end', function() {
+ .on('end', function () {
selection.selectAll('.map-in-map')
.style('display', 'none');
});
@@ -304,7 +295,7 @@ export function uiMapInMap(context) {
.transition()
.duration(200)
.style('opacity', '1')
- .on('end', function() {
+ .on('end', function () {
redraw();
});
}
@@ -325,7 +316,7 @@ export function uiMapInMap(context) {
.merge(wrap);
context.map()
- .on('drawn.map-in-map', function(drawn) {
+ .on('drawn.map-in-map', function (drawn) {
if (drawn.full === true) {
redraw();
}
@@ -341,4 +332,4 @@ export function uiMapInMap(context) {
}
return map_in_map;
-}
+}
\ No newline at end of file
diff --git a/modules/ui/preset.js b/modules/ui/preset.js
index 12b9a26af1a..77c586626dd 100644
--- a/modules/ui/preset.js
+++ b/modules/ui/preset.js
@@ -23,6 +23,7 @@ export function uiPreset(context) {
// Field Constructor
function UIField(field, entity, show) {
field = _.clone(field);
+
field.input = uiFields[field.type](field, context)
.on('change', function(t, onInput) {
dispatch.call('change', field, t, onInput);
diff --git a/modules/ui/radial_menu.js b/modules/ui/radial_menu.js
index 1abc0ebff20..8c62abb5b25 100644
--- a/modules/ui/radial_menu.js
+++ b/modules/ui/radial_menu.js
@@ -8,6 +8,7 @@ export function uiRadialMenu(context, operations) {
center = [0, 0],
tooltip;
+
var radialMenu = function(selection) {
if (!operations.length) return;
diff --git a/temp.js b/temp.js
deleted file mode 100644
index e5f4fcc23b1..00000000000
--- a/temp.js
+++ /dev/null
@@ -1,113 +0,0 @@
-import * as d3 from 'd3';
-import { validTurnLanes } from '../../../osm/lanes';
-import { utilRebind } from '../../../util/rebind';
-import { formPipes } from '../lanes';
-import { utilGetSetValue } from '../../../util/get_set_value';
-
-import _ from 'lodash';
-
-export function uiLaneInfo() {
- var dispatch = d3.dispatch('change');
- function laneInfo(selection, metadata, curDirection, curLane) {
- // TODO: make this thing dynamic and show keysConsidered
- // wrt to oneway.
- var keysConsidered = ['count', 'forward', 'backward', 'reverse'];
- var s = selection.selectAll('.lanes-info').data([0]);
- s = s.enter()
- .append('div')
- .attr('class', 'lanes-info')
- .merge(s);
-
- var wrap = s.selectAll('.preset-input-wrap')
- .data([0]);
-
- wrap = wrap.enter()
- .append('div')
- .attr('class', 'preset-input-wrap')
- .append('ul')
- .merge(wrap);
-
- var list = wrap.selectAll('ul')
- .data([0]);
-
- list = list.enter()
- .append('ul')
- .merge(list);
-
-
- var items = list.selectAll('li')
- .data(keysConsidered);
-
- // Enter
- var enter = items.enter()
- .append('li')
- .attr('class', function (d) { return 'cf preset-access-' + d; });
-
- enter
- .append('span')
- .attr('class', 'col6 label preset-label-')
- .attr('for', function (d) { return 'preset-input-' + d; })
- .text(function (d) { return d; });
-
- enter
- .append('div')
- .attr('class', 'col6 preset-input-lanes-wrap')
- .append('input')
- .attr('type', 'text')
- .attr('class', 'preset-input-lanes')
- .attr('id', function (d) { return 'preset-input-lanes-' + d; })
- .each(function (d) {
- this.value = metadata[d];
- });
-
- // Update
- items = items.merge(enter);
- items.selectAll('input')
- .property('value', function (d) {
- return metadata[d];
- });
-
- var input = items.selectAll('input');
-
- input
- .on('change', change)
- .on('blur', change);
-
- function change(d) {
- var tag = {};
- if (metadata.oneway) {
- if (d === 'count') {
- var count = utilGetSetValue(d3.select(this));
- count = parseInt(count, 10);
- if (!_.isNaN(count)) metadata.count = count;
- }
- if (d === 'reverse') {
- if (utilGetSetValue(d3.select(this)) === 'true') {
- metadata.reverse = true;
- } else {
- metadata.reverse = false;
- }
- }
-
- tag.lanes = Number(metadata.count).toString();
- tag['lanes:forward'] = undefined;
- tag['lanes:backward'] = undefined;
-
- } else {
- if (d === 'forward') {
- var forward = utilGetSetValue(d3.select(this));
- forward = parseInt(forward, 10);
- if (!_.isNaN(forward)) metadata.forward = forward;
- }
- if (d === 'backward') {
- var backward = utilGetSetValue(d3.select(this));
- backward = parseInt(backward, 10);
- if (!_.isNaN(backward)) metadata.backward = backward;
- }
- }
-
- dispatch.call('change', this);
- }
- }
- return utilRebind(laneInfo, dispatch, 'on');
-}
\ No newline at end of file
diff --git a/test/spec/osm/lanes.js b/test/spec/osm/lanes.js
index 99a22b21bbe..289c3afd064 100644
--- a/test/spec/osm/lanes.js
+++ b/test/spec/osm/lanes.js
@@ -1,4 +1,4 @@
-describe.only('iD.Lanes', function () {
+describe('iD.Lanes', function () {
describe('default lane tags', function () {