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)
This commit is contained in:
Bryan Housel
2018-02-16 11:42:44 -05:00
parent 5e9db0d409
commit aff9258dee
2 changed files with 28 additions and 26 deletions

View File

@@ -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;

View File

@@ -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');