From f7e6eae065fd81a98d1150937825624c3873a022 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 15 Feb 2018 17:27:45 -0500 Subject: [PATCH] Support Only Via paths, render indirect turn restriction with opacity --- modules/osm/intersection.js | 60 +++++++++++++++++++------------ modules/svg/turns.js | 5 ++- modules/ui/fields/restrictions.js | 10 +++--- 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index c728e500f..0e17947c3 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -433,31 +433,42 @@ export function osmIntersection(graph, startVertexId, maxDistance) { isLocalVia = _every(v, function(via) { return keyWayIds.indexOf(via.id) !== -1; }); } - // Does this path match the turn restriction? - var isMatch = false; - if ( // match via node, to way - v.length === 1 && - v[0].type === 'node' && - v[0].id === entity.id && - t.id === way.id - ) { - isMatch = true; - } else if ( // match via ways, to way - _every(v, function(via) { return currPath.indexOf(via.id) !== -1; }) && - t.id === way.id - ) { - isMatch = true; + // Does the current path match this turn restriction? + var isDirectMatch = false; + var isAlongOnlyPath = false; + + if (t.id === way.id) { // match TO + if (v.length === 1 && v[0].type === 'node' && v[0].id === entity.id) { + isDirectMatch = true; // match VIA node + } else if (_every(v, function(via) { return currPath.indexOf(via.id) !== -1; })) { + isDirectMatch = true; // match all VIA ways + } + + } else if (isOnly) { + for (k = 0; k < v.length; k++) { + // way doesn't match TO, but is one of the via ways along the path of an "only" + if (v[k].type === 'way' && v[k].id === way.id) { + isAlongOnlyPath = true; + break; + } + } } - if (isMatch && isOnly) { - restrict = { id: restriction.id, only: true }; + if (isDirectMatch) { + if (isOnly) { + restrict = { id: restriction.id, direct: true, only: true }; + } else { + restrict = { id: restriction.id, direct: true, no: true }; + } break; - } else if (isMatch && !isOnly) { - restrict = { id: restriction.id, direct: true }; - break; - } else if (!isMatch && isOnly && isLocalVia) { - restrict = { id: restriction.id, indirect: true }; - // no break - keep looking for a "better" direct or only + + } else { // indirect match, caused by presence of an "only" + if (isAlongOnlyPath) { + restrict = { id: restriction.id, indirect: true, only: true }; + } else if (isOnly && isLocalVia) { + restrict = { id: restriction.id, indirect: true, no: true }; + } + // no break - keep looking for a "better" direct match } } @@ -475,6 +486,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) { if (turn) { if (matchedRestriction) { turn.restrictionID = matchedRestriction.id; + turn.no = matchedRestriction.no; turn.only = matchedRestriction.only; turn.direct = matchedRestriction.direct; turn.indirect = matchedRestriction.indirect; @@ -485,7 +497,9 @@ export function osmIntersection(graph, startVertexId, maxDistance) { if (currPath[0] === currPath[2]) return; // we made a u-turn - stop here } - if (matchedRestriction) return; // don't advance any further + if (matchedRestriction && + (matchedRestriction.direct || matchedRestriction.no) + ) return; // don't advance any further // which nodes can we step into? var n1 = vgraph.entity(entity.first()), diff --git a/modules/svg/turns.js b/modules/svg/turns.js index baae52635..0022ef4a6 100644 --- a/modules/svg/turns.js +++ b/modules/svg/turns.js @@ -7,7 +7,7 @@ export function svgTurns(projection) { function icon(turn) { var u = turn.u ? '-u' : ''; - if (turn.direct || turn.indirect) return '#turn-no' + u; + if (turn.no) return '#turn-no' + u; if (turn.only) return '#turn-only' + u; return '#turn-yes' + u; } @@ -62,6 +62,9 @@ export function svgTurns(projection) { .merge(enter); groups + .attr('opacity', function (turn) { + return turn.indirect ? '0.7' : null; + }) .attr('transform', function (turn) { var pxRadius = 50; var toWay = graph.entity(turn.to.way); diff --git a/modules/ui/fields/restrictions.js b/modules/ui/fields/restrictions.js index bebbff44b..3589cc6ae 100644 --- a/modules/ui/fields/restrictions.js +++ b/modules/ui/fields/restrictions.js @@ -349,7 +349,9 @@ export function uiFieldRestrictions(field, context) { var actions; datum.restriction = osmInferRestriction(vgraph, datum.from, datum.to, projection); - if (datum.restrictionID && !datum.only) { // cycle thru the `only_` state + if (datum.restrictionID && datum.indirect) { + return; + } else if (datum.restrictionID && !datum.only) { // cycle thru the `only_` state var datumOnly = _cloneDeep(datum); datumOnly.only = true; datumOnly.restriction = datumOnly.restriction.replace(/^no\_/, 'only_'); @@ -411,12 +413,12 @@ export function uiFieldRestrictions(field, context) { var restrictType = ''; var klass = 'allow'; if (datum.restrictionID) { - if (datum.direct) { restrictType = 'NO'; klass = 'restrict'; } - if (datum.indirect) { restrictType = 'NO'; klass = 'restrict'; } - if (datum.only) { restrictType = 'ONLY'; klass = 'only'; } + if (datum.no) { restrictType = 'NO'; klass = 'restrict'; } + if (datum.only) { restrictType = 'ONLY'; klass = 'only'; } } var s = (klass === 'allow' ? turnType + ' Allowed' : restrictType + ' ' + turnType); + if (datum.indirect) { s += ' (indirect)'; } div = help.append('div'); div.append('span')