mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-16 13:59:27 +02:00
order to-be-created relations by dependencies in a changeset
This commit is contained in:
+47
-1
@@ -314,6 +314,52 @@ export default {
|
||||
});
|
||||
return ordered;
|
||||
}
|
||||
// sort relations in a changeset by dependencies
|
||||
function sort(changes) {
|
||||
// find a referenced relation in the current changeset
|
||||
function resolve(item){
|
||||
return _.find(relations, function(relation) {
|
||||
return item.keyAttributes.ref === relation['@id'];
|
||||
});
|
||||
}
|
||||
// a new item is an item that has not been already processed
|
||||
function isNew(item) {
|
||||
return !sorted[ item['@id'] ] && !_.find(processing, function(proc){
|
||||
return proc['@id'] === item['@id'];
|
||||
});
|
||||
}
|
||||
var processing = [],
|
||||
sorted = {},
|
||||
relations = changes.relation;
|
||||
|
||||
if (!relations) return changes;
|
||||
|
||||
for (var i = 0; i < relations.length; i++) {
|
||||
|
||||
var relation = relations[i];
|
||||
|
||||
// skip relation if already sorted
|
||||
if ( !sorted[relation['@id']] ) {
|
||||
processing.push( relation );
|
||||
}
|
||||
|
||||
while ( processing.length > 0 ){
|
||||
var next = processing[0],
|
||||
deps = _.filter( _.compact(next.member.map(resolve)), isNew);
|
||||
|
||||
if ( deps.length === 0 ){
|
||||
sorted[ next['@id'] ] = next;
|
||||
processing.shift();
|
||||
} else {
|
||||
processing = deps.concat( processing );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
changes.relation = _.values(sorted);
|
||||
return changes;
|
||||
}
|
||||
|
||||
function rep(entity) {
|
||||
return entity.asJXON(changeset_id);
|
||||
@@ -323,7 +369,7 @@ export default {
|
||||
osmChange: {
|
||||
'@version': 0.6,
|
||||
'@generator': 'iD',
|
||||
'create': nest(changes.created.map(rep), ['node', 'way', 'relation']),
|
||||
'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])),
|
||||
'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']),
|
||||
'delete': _.extend(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), {'@if-unused': true})
|
||||
}
|
||||
|
||||
@@ -362,6 +362,35 @@ describe('iD.serviceOsm', function () {
|
||||
]);
|
||||
});
|
||||
|
||||
it('includes creations ordered by dependencies', function() {
|
||||
var n = iD.Node({loc: [0, 0]}),
|
||||
w = iD.Way({nodes: [n.id]}),
|
||||
r1 = iD.Relation({members: [{id: w.id}]}),
|
||||
r2 = iD.Relation({members: [{id: r1.id}]}),
|
||||
changes = {created: [r2, r1, w, n], modified: [], deleted: []},
|
||||
jxon = connection.osmChangeJXON('1234', changes);
|
||||
|
||||
expect(d3.entries(jxon.osmChange.create)).to.eql([
|
||||
{key: 'node', value: [n.asJXON('1234').node]},
|
||||
{key: 'way', value: [w.asJXON('1234').way]},
|
||||
{key: 'relation', value: [r1.asJXON('1234').relation, r2.asJXON('1234').relation]},
|
||||
]);
|
||||
});
|
||||
|
||||
it('includes creations ignoring circular dependencies', function() {
|
||||
var r1 = iD.Relation(),
|
||||
r2 = iD.Relation(),
|
||||
changes, jxon;
|
||||
r1.addMember({id: r2.id});
|
||||
r2.addMember({id: r1.id});
|
||||
changes = {created: [r1,r2], modified: [], deleted: []};
|
||||
jxon = connection.osmChangeJXON('1234', changes);
|
||||
|
||||
expect(d3.entries(jxon.osmChange.create)).to.eql([
|
||||
{key: 'relation', value: [r1.asJXON('1234').relation, r2.asJXON('1234').relation]},
|
||||
]);
|
||||
});
|
||||
|
||||
it('includes modifications', function() {
|
||||
var n = iD.Node({loc: [0, 0]}),
|
||||
w = iD.Way(),
|
||||
|
||||
Reference in New Issue
Block a user