Render oneway=alternating, oneway=reversible with dual arrows

(closes #4291)
This commit is contained in:
Bryan Housel
2018-01-04 13:40:13 -05:00
parent 77ec49d959
commit c908807f64
5 changed files with 57 additions and 19 deletions

View File

@@ -13,9 +13,9 @@ export function geoVecSubtract(a, b) {
return [ a[0] - b[0], a[1] - b[1] ];
}
// vector multiplication
export function geoVecScale(a, b) {
return [ a[0] * b, a[1] * b ];
// vector scaling
export function geoVecScale(a, mag) {
return [ a[0] * mag, a[1] * mag ];
}
// vector rounding (was: geoRoundCoordinates)

View File

@@ -108,8 +108,18 @@ _extend(osmWay.prototype, {
isOneWay: function() {
// explicit oneway tag..
if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
var values = {
'yes': true,
'1': true,
'-1': true,
'reversible': true,
'alternating': true,
'no': false,
'0': false
};
if (values[this.tags.oneway] !== undefined) {
return values[this.tags.oneway];
}
// implied oneway tag..
for (var key in this.tags) {

View File

@@ -31,7 +31,7 @@ export function svgDefs(context) {
.append('marker')
.attr('id', 'oneway-marker')
.attr('viewBox', '0 0 10 5')
.attr('refX', 5)
.attr('refX', 2.5)
.attr('refY', 2.5)
.attr('markerWidth', 2)
.attr('markerHeight', 2)

View File

@@ -6,7 +6,11 @@ import {
geoStream as d3_geoStream
} from 'd3-geo';
import { geoVecLength } from '../geo';
import {
geoVecAdd,
geoVecAngle,
geoVecLength
} from '../geo';
// Touch targets control which other vertices we can drag a vertex onto.
@@ -72,6 +76,8 @@ export function svgOneWaySegments(projection, graph, dt) {
coordinates.reverse();
}
var isReversible = (entity.tags.oneway === 'reversible' || entity.tags.oneway === 'alternating');
d3_geoStream({
type: 'LineString',
coordinates: coordinates
@@ -85,27 +91,41 @@ export function svgOneWaySegments(projection, graph, dt) {
var span = geoVecLength(a, b) - offset;
if (span >= 0) {
var angle = Math.atan2(b[1] - a[1], b[0] - a[0]);
var dx = dt * Math.cos(angle);
var dy = dt * Math.sin(angle);
var heading = geoVecAngle(a, b);
var dx = dt * Math.cos(heading);
var dy = dt * Math.sin(heading);
var p = [
a[0] + offset * Math.cos(angle),
a[1] + offset * Math.sin(angle)
a[0] + offset * Math.cos(heading),
a[1] + offset * Math.sin(heading)
];
var segment = 'M' + a[0] + ',' + a[1] + 'L' + p[0] + ',' + p[1];
// gather coordinates
var coord = [a, p];
for (span -= dt; span >= 0; span -= dt) {
p[0] += dx;
p[1] += dy;
segment += 'L' + p[0] + ',' + p[1];
p = geoVecAdd(p, [dx, dy]);
coord.push(p);
}
coord.push(b);
segment += 'L' + b[0] + ',' + b[1];
segments.push({id: entity.id, index: i, d: segment});
// generate svg paths
var segment = '';
var j;
for (j = 0; j < coord.length; j++) {
segment += (j === 0 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
}
segments.push({ id: entity.id, index: i++, d: segment });
if (isReversible) {
segment = '';
for (j = coord.length - 1; j >= 0; j--) {
segment += (j === coord.length - 1 ? 'M' : 'L') + coord[j][0] + ',' + coord[j][1];
}
segments.push({ id: entity.id, index: i++, d: segment });
}
}
offset = -span;
i++;
}
a = b;

View File

@@ -293,6 +293,14 @@ describe('iD.osmWay', function() {
expect(iD.Way({tags: { oneway: '-1' }}).isOneWay(), 'oneway -1').to.be.true;
});
it('returns true when the way has tag oneway=reversible', function() {
expect(iD.Way({tags: { oneway: 'reversible' }}).isOneWay(), 'oneway reversible').to.be.true;
});
it('returns true when the way has tag oneway=alternating', function() {
expect(iD.Way({tags: { oneway: 'alternating' }}).isOneWay(), 'oneway alternating').to.be.true;
});
it('returns true when the way has implied oneway tag (waterway=river, waterway=stream, etc)', function() {
expect(iD.Way({tags: { waterway: 'river' }}).isOneWay(), 'river').to.be.true;
expect(iD.Way({tags: { waterway: 'stream' }}).isOneWay(), 'stream').to.be.true;