Avoid reordering stops and platforms in PTv2 routes

(closes #4864)
This commit is contained in:
Bryan Housel
2018-03-10 00:12:46 -05:00
parent 88dea28cf7
commit aa1565baf8
2 changed files with 44 additions and 10 deletions
+29 -5
View File
@@ -10,10 +10,20 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
return function action(graph) {
var relation = graph.entity(relationId);
if ((isNaN(memberIndex) || insertPair) && member.type === 'way') {
// There are some special rules for Public Transport v2 routes.
var isPTv2 = (member.role === 'stop' || member.role === 'platform');
if ((isNaN(memberIndex) || insertPair) && member.type === 'way' && !isPTv2) {
// Try to perform sensible inserts based on how the ways join together
graph = addWayMember(relation, graph);
} else {
// see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes
// Stops and Platforms for PTv2 should be ordered first.
// hack: We do not currently have the ability to place them in the exactly correct order.
if (isPTv2 && isNaN(memberIndex)) {
memberIndex = 0;
}
graph = graph.replace(relation.addMember(member, memberIndex));
}
@@ -26,6 +36,20 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
function addWayMember(relation, graph) {
var groups, tempWay, item, i, j, k;
// remove PTv2 stops and platforms before doing anything.
var PTv2members = [];
var members = [];
for (i = 0; i < relation.members.length; i++) {
var m = relation.members[i];
if (m.role === 'stop' || m.role === 'platform') {
PTv2members.push(m);
} else {
members.push(m);
}
}
relation = relation.update({ members: members });
if (insertPair) {
// We're adding a member that must stay paired with an existing member.
// (This feature is used by `actionSplit`)
@@ -50,7 +74,7 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
groups.way.push(member);
}
var members = withIndex(groups.way);
members = withIndex(groups.way);
var joined = osmJoinWays(members, graph);
// `joined` might not contain all of the way members,
@@ -116,10 +140,10 @@ export function actionAddMember(relationId, member, memberIndex, insertPair) {
}
}
// Write members in the order: nodes, ways, relations
// This is reccomended for Public Transport routes:
// Put stops and platforms first, then nodes, ways, relations
// This is recommended for Public Transport v2 routes:
// see https://wiki.openstreetmap.org/wiki/Public_transport#Service_routes
var newMembers = (groups.node || []).concat(wayMembers, (groups.relation || []));
var newMembers = PTv2members.concat( (groups.node || []), wayMembers, (groups.relation || []) );
return graph.replace(relation.update({members: newMembers}));
+15 -5
View File
@@ -177,7 +177,7 @@ describe('iD.actionAddMember', function() {
expect(members(graph)).to.eql(['-', '=', '~', '~', '=', '-']);
});
it('reorders members as node, way, relation (for Public Transport routing)', function() {
it('keeps stops and platforms ordered before node, way, relation (for PTv2 routes)', function() {
var graph = iD.coreGraph([
iD.osmNode({id: 'a', loc: [0, 0]}),
iD.osmNode({id: 'b', loc: [0, 0]}),
@@ -185,17 +185,27 @@ describe('iD.actionAddMember', function() {
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '=', nodes: ['b', 'c']}),
iD.osmRelation({id: 'r', members: [
{ id: 'n1', type: 'node', role: 'forward' },
{ id: 'n1', type: 'node', role: 'stop' },
{ id: 'w1', type: 'way', role: 'platform' },
{ id: 'n2', type: 'node', role: 'stop' },
{ id: 'w2', type: 'way', role: 'platform' },
{ id: 'n3', type: 'node', role: 'forward' },
{ id: 'n4', type: 'node', role: 'forward' },
{ id: '-', type: 'way', role: 'forward' },
{ id: 'r1', type: 'relation', role: 'forward' },
{ id: 'n2', type: 'node', role: 'forward' }
{ id: 'n5', type: 'node', role: 'forward' }
]})
]);
graph = iD.actionAddMember('r', { id: '=', type: 'way', role: 'forward' })(graph);
expect(graph.entity('r').members).to.eql([
{ id: 'n1', type: 'node', role: 'forward' },
{ id: 'n2', type: 'node', role: 'forward' },
{ id: 'n1', type: 'node', role: 'stop' },
{ id: 'w1', type: 'way', role: 'platform' },
{ id: 'n2', type: 'node', role: 'stop' },
{ id: 'w2', type: 'way', role: 'platform' },
{ id: 'n3', type: 'node', role: 'forward' },
{ id: 'n4', type: 'node', role: 'forward' },
{ id: 'n5', type: 'node', role: 'forward' },
{ id: '-', type: 'way', role: 'forward' },
{ id: '=', type: 'way', role: 'forward' },
{ id: 'r1', type: 'relation', role: 'forward' }