diff --git a/modules/core/way.js b/modules/core/way.js index a5ce5f6d6..b4f488403 100644 --- a/modules/core/way.js +++ b/modules/core/way.js @@ -125,9 +125,9 @@ _.extend(Way.prototype, { tagged.oneway = this.isOneWay(); tagged.lanes = {}; - if (this.tags.lanes) tagged.lanes.count = this.tags.lanes; - if (this.tags['lanes:forward']) tagged.lanes.forward = this.tags['lanes:forward']; - if (this.tags['lanes:backward']) tagged.lanes.backward = this.tags['lanes:backward']; + if (this.tags.lanes) tagged.lanes.count = parseInt(this.tags.lanes); + if (this.tags['lanes:forward']) tagged.lanes.forward = parseInt(this.tags['lanes:forward']); + if (this.tags['lanes:backward']) tagged.lanes.backward = parseInt(this.tags['lanes:backward']); return { defaults: { diff --git a/modules/ui/fields/lanes.js b/modules/ui/fields/lanes.js index 57a4bbdf3..eafaa6d42 100644 --- a/modules/ui/fields/lanes.js +++ b/modules/ui/fields/lanes.js @@ -1,32 +1,128 @@ export function lanes(field, context) { var dispatch = d3.dispatch('change'), + LANE_WIDTH = 40, + LANE_HEIGHT = 200, wayID, laneData; + function processData(raw) { + var laneCount = raw.tagged.lanes.count || raw.defaults.lanes.count; + var lanesArray = []; + + for (var i = 0; i < laneCount; i++) { + lanesArray.push({ key: i }); + } + + if (raw.tagged.oneway) { + lanesArray.forEach(function(l) { + l.forward = true; + l.backward = false; + }); + } else { + var countForward = raw.tagged.lanes.forward || 0; + var countBackward = raw.tagged.lanes.backward || 0; + + if (countForward + countBackward === 0) { + countForward = laneCount/2; + countBackward = laneCount/2; + } + + for (i = 0; i < countForward; i++) { + lanesArray[i].forward = true; + lanesArray[i].backward = false; + } + for (i = 0; i < countBackward; i++) { + lanesArray[countForward + i].forward = false; + lanesArray[countForward + i].backward = true; + } + } + + return lanesArray; + } function lanes(selection) { + laneData = processData(context.entity(wayID).lanes()); + + var laneCount = laneData.length; + // if form field is hidden or has detached from dom, clean up. if (!d3.select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) { selection.call(lanes.off); return; } - laneData = context.entity(wayID).lanes(); - var wrap = selection.selectAll('.preset-input-wrap') .data([0]); - var enter = wrap.enter() + wrap.enter() .append('div') .attr('class', 'preset-input-wrap'); + var surface = wrap.selectAll('.surface') + .data([0]); + + var d = wrap.dimensions(); + var freeSpace = d[0] - laneCount*LANE_WIDTH*1.5 + LANE_WIDTH*0.5; + + surface.enter() + .append('svg') + .attr('width', d[0]) + .attr('height', 300) + .attr('class', 'surface'); + + var lanesSelection = surface.selectAll('.lanes') + .data([0]); + + lanesSelection.enter() + .append('g') + .attr('class', 'lanes'); + + lanesSelection + .attr('transform', function () { + return 'translate(' + (freeSpace/2)+ ', 0)'; + }); + + var lane = lanesSelection.selectAll('.lane') + .data(laneData); + + var enter = lane.enter() + .append('g') + .attr('class', 'lane'); + enter - .append('div') - .attr('class', 'lane-count') - .append('span'); + .append('g') + .append('rect') + .attr('y', 50) + .attr('width', LANE_WIDTH) + .attr('height', LANE_HEIGHT); - selection.selectAll('.lane-count') - .text(laneData.tagged.lanes.count || laneData.defaults.lanes.count); + enter + .append('g') + .attr('class', 'forward') + .append('text') + .attr('y', 40) + .attr('x', 14) + .text('▲'); + enter + .append('g') + .attr('class', 'backward') + .append('text') + .attr('y', 40) + .attr('x', 14) + .text('▼'); + + lane.exit().remove(); + + lane + .attr('transform', function(d) { + return 'translate(' + (LANE_WIDTH*d.key*1.5)+ ', 0)'; + }); + + lane.select('.forward') + .style('visibility', function(d) { return d.forward ? 'visible' : 'hidden'; }); + + lane.select('.backward') + .style('visibility', function(d) { return d.backward ? 'visible' : 'hidden'; }); }