From aff9258deeea371b02220b72ebe507e3be144fe9 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Fri, 16 Feb 2018 11:42:44 -0500 Subject: [PATCH] Indirect restrictions now include only the partial path This lets us properly infer the actual turn taken through the indirect restriction using osmInferRestriction (an improvement over 5e9db0d) --- modules/osm/intersection.js | 34 ++++++++++++++++++++----------- modules/ui/fields/restrictions.js | 20 ++++++------------ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/modules/osm/intersection.js b/modules/osm/intersection.js index c4785a599..1673bbb45 100644 --- a/modules/osm/intersection.js +++ b/modules/osm/intersection.js @@ -401,13 +401,14 @@ export function osmIntersection(graph, startVertexId, maxDistance) { if (currPath.length >= maxPathLength) return; currPath.push(entity.id); currRestrictions = _clone(currRestrictions || []); + var i, j; if (entity.type === 'node') { var parents = vgraph.parentWays(entity); var nextWays = []; // which ways can we step into? - for (var i = 0; i < parents.length; i++) { + for (i = 0; i < parents.length; i++) { var way = parents[i]; // if next way is a oneway incoming to this vertex, skip @@ -418,7 +419,7 @@ export function osmIntersection(graph, startVertexId, maxDistance) { // Check all "current" restrictions (where we've already walked the `from`) var restrict = undefined; - for (var j = 0; j < currRestrictions.length; j++) { + for (j = 0; j < currRestrictions.length; j++) { var restriction = currRestrictions[j]; var f = restriction.memberByRole('from'); var v = restriction.membersByRole('via'); @@ -458,15 +459,15 @@ export function osmIntersection(graph, startVertexId, maxDistance) { if (matchesViaTo) { if (isOnly) { - restrict = { id: restriction.id, direct: matchesFrom, only: true, end: true }; + restrict = { id: restriction.id, direct: matchesFrom, from: f.id, only: true, end: true }; } else { - restrict = { id: restriction.id, direct: matchesFrom, no: true, end: true }; + restrict = { id: restriction.id, direct: matchesFrom, from: f.id, no: true, end: true }; } } else { // indirect - caused by a different nearby restriction if (isAlongOnlyPath) { - restrict = { id: restriction.id, direct: false, only: true, end: false }; + restrict = { id: restriction.id, direct: false, from: f.id, only: true, end: false }; } else if (isOnly && isLocalVia) { - restrict = { id: restriction.id, direct: false, no: true, end: true }; + restrict = { id: restriction.id, direct: false, from: f.id, no: true, end: true }; } } @@ -485,7 +486,19 @@ export function osmIntersection(graph, startVertexId, maxDistance) { } else { // entity.type === 'way' if (currPath.length >= 3) { // this is a "complete" path.. - var turn = pathToTurn(currPath); + var turnPath = _clone(currPath); + + // an indirect restriction - only include the partial path (starting at FROM) + if (matchedRestriction && matchedRestriction.direct === false) { + for (i = 0; i < turnPath.length; i++) { + if (i > 0 && turnPath[i] === matchedRestriction.from) { + turnPath = turnPath.slice(i); + break; + } + } + } + + var turn = pathToTurn(turnPath); if (turn) { if (matchedRestriction) { turn.restrictionID = matchedRestriction.id; @@ -583,7 +596,6 @@ export function osmIntersection(graph, startVertexId, maxDistance) { var nodes = vgraph.entity(wayId).nodes; return affixId === nodes[0] ? nodes[1] : nodes[nodes.length - 2]; } - } }; @@ -602,10 +614,8 @@ export function osmInferRestriction(graph, from, to, projection) { var fromOneWay = (fromWay.tags.oneway === 'yes'); var toOneWay = (toWay.tags.oneway === 'yes'); - var angle = geoAngle(fromVertex, fromNode, projection) - - geoAngle(toVertex, toNode, projection); - - angle = angle * 180 / Math.PI; + var angle = (geoAngle(fromVertex, fromNode, projection) - + geoAngle(toVertex, toNode, projection)) * 180 / Math.PI; while (angle < 0) angle += 360; diff --git a/modules/ui/fields/restrictions.js b/modules/ui/fields/restrictions.js index c4be98774..0550cff63 100644 --- a/modules/ui/fields/restrictions.js +++ b/modules/ui/fields/restrictions.js @@ -254,7 +254,7 @@ export function uiFieldRestrictions(field, context) { // If this is a large intersection, adjust zoom to fit extent if (_intersection.vertices.length > 1) { - var padding = 160; // in z22 pixels + var padding = 180; // in z22 pixels var tl = projection([extent[0][0], extent[1][1]]); var br = projection([extent[1][0], extent[0][1]]); var hFactor = (br[0] - tl[0]) / (d[0] - padding); @@ -265,7 +265,7 @@ export function uiFieldRestrictions(field, context) { projection.scale(geoZoomToScale(z)); } - var padTop = 30; // reserve top space for hint text + var padTop = 35; // reserve top space for hint text var extentCenter = projection(extent.center()); extentCenter[1] = extentCenter[1] - padTop; @@ -351,10 +351,10 @@ export function uiFieldRestrictions(field, context) { if (datum.restrictionID && !datum.direct) { return; - } else if (datum.restrictionID && !datum.only) { // cycle thru the `only_` state + } 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_'); + datumOnly.restriction = datumOnly.restriction.replace(/^no/, 'only'); actions = _intersection.actions.concat([ actionUnrestrictTurn(datum, projection), actionRestrictTurn(datumOnly, projection), @@ -438,20 +438,12 @@ export function uiFieldRestrictions(field, context) { var toWayID = datum.to.way; var restrictionType = osmInferRestriction(vgraph, datum.from, datum.to, projection); - if (datum.restrictionID && datum.only && datum.direct === false) { - var r = vgraph.entity(datum.restrictionID); - fromWayID = r.memberByRole('from').id; - viaWayIDs = r.membersByRole('via').map(function (m) { return m.id; }); - toWayID = r.memberByRole('to').id; - restrictionType = r.tags.restriction.replace(/^only/, 'no'); - } - var turnType = { 'no_left_turn': 'Left Turn', 'no_right_turn': 'Right Turn', 'no_u_turn': 'U-Turn', 'no_straight_on': 'Straight On' - }[restrictionType]; + }[restrictionType.replace(/^only/, 'no')]; var restrictType = ''; var klass = 'allow'; @@ -475,7 +467,7 @@ export function uiFieldRestrictions(field, context) { div.append('span').attr('class', 'qualifier').text('TO'); div.append('span').text(d.name || d.type); - if (viaWayIDs) { + if (viaWayIDs && viaWayIDs.length) { div = help.append('div'); div.append('span').attr('class', 'qualifier').text('VIA');