mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-15 05:30:35 +02:00
Most iD.actions.MergeRemoteChanges features complete
(todo: merging ways where nodelist has not been reordered)
This commit is contained in:
@@ -1,29 +1,57 @@
|
||||
iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph) {
|
||||
var base = localGraph.base().entities[id],
|
||||
local = localGraph.entities[id],
|
||||
remote = remoteGraph.entities[id],
|
||||
option = 'safe', // 'safe', 'force_local', 'force_remote'
|
||||
target;
|
||||
local = localGraph.entity(id),
|
||||
remote = remoteGraph.entity(id),
|
||||
option = 'safe'; // 'safe', 'force_local', 'force_remote'
|
||||
|
||||
function sameLocation() {
|
||||
var epsilon = 1e-6;
|
||||
return (Math.abs(remote.loc[0] - local.loc[0]) < epsilon) &&
|
||||
(Math.abs(remote.loc[1] - local.loc[1]) < epsilon);
|
||||
|
||||
function mergeLocation(target) {
|
||||
function pointEqual(a, b) {
|
||||
var epsilon = 1e-6;
|
||||
return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
|
||||
}
|
||||
|
||||
if (!pointEqual(remote.loc, local.loc)) {
|
||||
return (option === 'force_remote') ? target.update({loc: remote.loc}) : undefined;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
function mergeChildren() {
|
||||
function mergeRemoteChildren(target) {
|
||||
if (option === 'force_remote') {
|
||||
return target.update({nodes: remote.nodes});
|
||||
}
|
||||
|
||||
// todo, support non-destructive merging
|
||||
return _.isEqual(local.nodes, remote.nodes);
|
||||
// for now fail on any change..
|
||||
if (!_.isEqual(local.nodes, remote.nodes)) {
|
||||
return;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
function mergeMembers() {
|
||||
function mergeRemoteMembers(target) {
|
||||
if (option === 'force_remote') {
|
||||
return target.update({members: remote.members});
|
||||
}
|
||||
|
||||
// todo, support non-destructive merging
|
||||
return _.isEqual(local.members, remote.members);
|
||||
// for now fail on any change..
|
||||
if (!_.isEqual(local.members, remote.members)) {
|
||||
return;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
function mergeTags() {
|
||||
function mergeRemoteTags(target) {
|
||||
if (!target) { return; }
|
||||
if (option === 'force_remote') {
|
||||
return target.update({tags: remote.tags});
|
||||
}
|
||||
|
||||
var keys = _.reject(_.union(_.keys(base.tags), _.keys(remote.tags)), ignoreKey),
|
||||
tags = _.cloneDeep(target.tags);
|
||||
tags = _.cloneDeep(target.tags),
|
||||
changed = false;
|
||||
|
||||
function ignoreKey(k) {
|
||||
return k.indexOf('tiger:') === 0 || _.contains(iD.data.discarded, k);
|
||||
@@ -33,34 +61,35 @@ iD.actions.MergeRemoteChanges = function(id, localGraph, remoteGraph) {
|
||||
var k = keys[i];
|
||||
if (remote.tags[k] !== base.tags[k]) { // tag modified remotely..
|
||||
if (local.tags[k] && local.tags[k] !== remote.tags[k]) {
|
||||
return false;
|
||||
return;
|
||||
} else {
|
||||
tags[k] = remote.tags[k];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
target = target.update({tags: tags});
|
||||
return true;
|
||||
return changed ? target.update({tags: tags}) : target;
|
||||
}
|
||||
|
||||
var action = function(graph) {
|
||||
var target = iD.Entity(local, {version: remote.version});
|
||||
|
||||
target = iD.Entity(local, {version: remote.version});
|
||||
if (option === 'force_remote') { return graph.replace(remote); }
|
||||
if (option === 'force_local') { return graph.replace(target); }
|
||||
|
||||
// otherwise, safe mode: only permit non-destructive merges..
|
||||
var doMerge;
|
||||
if (target.type === 'node') {
|
||||
doMerge = (sameLocation() && mergeTags());
|
||||
} else if (target.type === 'way') {
|
||||
doMerge = (mergeChildren() && mergeTags());
|
||||
} else if (target.type === 'relation') {
|
||||
doMerge = (mergeMembers() && mergeTags());
|
||||
if (option === 'force_local') {
|
||||
return graph.replace(target);
|
||||
}
|
||||
|
||||
return doMerge ? graph.replace(target) : graph;
|
||||
if (target.type === 'node') {
|
||||
target = mergeLocation(target);
|
||||
} else if (target.type === 'way') {
|
||||
graph.rebase(remoteGraph.childNodes(remote), [graph], false);
|
||||
target = mergeRemoteChildren(target);
|
||||
} else if (target.type === 'relation') {
|
||||
target = mergeRemoteMembers(target);
|
||||
}
|
||||
|
||||
target = mergeRemoteTags(target);
|
||||
return target ? graph.replace(target) : graph;
|
||||
};
|
||||
|
||||
action.withOption = function(opt) {
|
||||
|
||||
@@ -1,210 +1,338 @@
|
||||
describe("iD.actions.MergeRemoteChanges", function () {
|
||||
var base = iD.Graph([
|
||||
iD.Node({id: 'a', loc: [1, 1], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'a', loc: [1, 1], version: '1', tags: {foo: 'foo'}}),
|
||||
|
||||
iD.Node({id: 'p1', loc: [ 10, 10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p2', loc: [ 10, -10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p3', loc: [-10, -10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p4', loc: [-10, 10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Way({
|
||||
id: 'w1',
|
||||
nodes: ['p1', 'p2', 'p3', 'p4', 'p1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo', area: 'yes'}
|
||||
}),
|
||||
iD.Node({id: 'p1', loc: [ 10, 10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p2', loc: [ 10, -10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p3', loc: [-10, -10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'p4', loc: [-10, 10], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Way({
|
||||
id: 'w1',
|
||||
nodes: ['p1', 'p2', 'p3', 'p4', 'p1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo', area: 'yes'}
|
||||
}),
|
||||
|
||||
iD.Node({id: 'q1', loc: [ 5, 5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q2', loc: [ 5, -5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q3', loc: [-5, -5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q4', loc: [-5, 5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Way({
|
||||
id: 'w2',
|
||||
nodes: ['q1', 'q2', 'q3', 'q4', 'q1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo', area: 'yes'}
|
||||
}),
|
||||
iD.Node({id: 'q1', loc: [ 5, 5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q2', loc: [ 5, -5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q3', loc: [-5, -5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Node({id: 'q4', loc: [-5, 5], version: '1', tags: {foo: 'foo'}}),
|
||||
iD.Way({
|
||||
id: 'w2',
|
||||
nodes: ['q1', 'q2', 'q3', 'q4', 'q1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo', area: 'yes'}
|
||||
}),
|
||||
|
||||
iD.Relation({
|
||||
id: 'r',
|
||||
members: [{id: 'w1', role: 'outer'}, {id: 'w2', role: 'inner'}],
|
||||
version: '1',
|
||||
tags: {type: 'multipolygon', foo: 'foo'}
|
||||
}),
|
||||
iD.Relation({
|
||||
id: 'r',
|
||||
members: [{id: 'w1', role: 'outer'}, {id: 'w2', role: 'inner'}],
|
||||
version: '1',
|
||||
tags: {type: 'multipolygon', foo: 'foo'}
|
||||
})
|
||||
]),
|
||||
|
||||
]);
|
||||
// some new objects not in the graph yet..
|
||||
r1 = iD.Node({id: 'r1', loc: [ 12, 12], version: '1', tags: {foo: 'foo_new'}}),
|
||||
r2 = iD.Node({id: 'r2', loc: [ 12, -12], version: '1', tags: {foo: 'foo_new'}}),
|
||||
r3 = iD.Node({id: 'r3', loc: [-12, -12], version: '1', tags: {foo: 'foo_new'}}),
|
||||
r4 = iD.Node({id: 'r4', loc: [-12, 12], version: '1', tags: {foo: 'foo_new'}}),
|
||||
w3 = iD.Way({
|
||||
id: 'w3',
|
||||
nodes: ['r1', 'r2', 'r3', 'r4', 'r1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo_new', area: 'yes'}
|
||||
}),
|
||||
|
||||
s1 = iD.Node({id: 's1', loc: [ 6, 6], version: '1', tags: {foo: 'foo_new'}}),
|
||||
s2 = iD.Node({id: 's2', loc: [ 6, -6], version: '1', tags: {foo: 'foo_new'}}),
|
||||
s3 = iD.Node({id: 's3', loc: [-6, -6], version: '1', tags: {foo: 'foo_new'}}),
|
||||
s4 = iD.Node({id: 's4', loc: [-6, 6], version: '1', tags: {foo: 'foo_new'}}),
|
||||
w4 = iD.Way({
|
||||
id: 'w4',
|
||||
nodes: ['s1', 's2', 's3', 's4', 's1'],
|
||||
version: '1',
|
||||
tags: {foo: 'foo_new', area: 'yes'}
|
||||
});
|
||||
|
||||
function makeGraph(entities) {
|
||||
return _.reduce(entities, function(graph, entity) {
|
||||
return graph.replace(entity);
|
||||
}, iD.Graph(base));
|
||||
}
|
||||
|
||||
|
||||
describe("non-destuctive merging", function () {
|
||||
it("doesn't merge nodes if location is different", function () {
|
||||
var local = iD.Node({id: 'a', loc: [1, 1], version: '1', v: 2, tags: {foo: 'foo_local'}}),
|
||||
remote = iD.Node({id: 'a', loc: [3, 3], version: '2', tags: {foo: 'foo', bar: 'bar_remote'}}),
|
||||
graph = iD.Graph(base).replace(local),
|
||||
altGraph = iD.Graph(base).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
describe("nodes", function () {
|
||||
it("doesn't merge nodes if location is different", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo', bar: 'bar_remote'}, // didn't change tag foo, added tag bar
|
||||
localLoc = [1, 1], // didn't move node
|
||||
remoteLoc = [3, 3], // moved node
|
||||
local = iD.Node({id: 'a', loc: localLoc, version: '1', v: 2, tags: localTags }),
|
||||
remote = iD.Node({id: 'a', loc: remoteLoc, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a')).to.eql(local);
|
||||
expect(graph.entity('a')).to.eql(local);
|
||||
});
|
||||
|
||||
it("doesn't merge nodes if changed tags conflict", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', bar: 'bar_remote'}, // changed tag foo, added tag bar
|
||||
localLoc = [1, 1], // didn't move node
|
||||
remoteLoc = [1, 1], // didn't move node
|
||||
local = iD.Node({id: 'a', loc: localLoc, version: '1', v: 2, tags: localTags }),
|
||||
remote = iD.Node({id: 'a', loc: remoteLoc, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a')).to.eql(local);
|
||||
});
|
||||
|
||||
it("merges nodes if location is same and changed tags don't conflict", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo', bar: 'bar_remote'}, // didn't change tag foo, added tag bar
|
||||
localLoc = [1, 1], // didn't move node
|
||||
remoteLoc = [1, 1], // didn't move node
|
||||
local = iD.Node({id: 'a', loc: localLoc, version: '1', v: 2, tags: localTags }),
|
||||
remote = iD.Node({id: 'a', loc: remoteLoc, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').tags).to.eql({foo: 'foo_local', bar: 'bar_remote'});
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't merge nodes if changed tags conflict", function () {
|
||||
var local = iD.Node({id: 'a', loc: [1, 1], version: '1', v: 2, tags: {foo: 'foo_local'}}),
|
||||
remote = iD.Node({id: 'a', loc: [1, 1], version: '2', tags: {foo: 'foo_remote', bar: 'bar_remote'}}),
|
||||
graph = iD.Graph(base).replace(local),
|
||||
altGraph = iD.Graph(base).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
describe("ways", function () {
|
||||
it("doesn't merge ways if changed tags conflict", function () {
|
||||
var localNodes = ['p1', 'p2', 'p3', 'p4', 'p1'], // didn't change nodes
|
||||
remoteNodes = ['p1', 'p2', 'p3', 'p4', 'p1'], // didn't change nodes
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', bar: 'bar_remote', area: 'yes'}, // changed tag foo, added tag bar
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1')).to.eql(local);
|
||||
});
|
||||
|
||||
it("merges ways if nodelist is same and tags don't conflict", function () {
|
||||
var localNodes = ['p1', 'p2', 'p3', 'p4', 'p1'], // didn't change nodes
|
||||
remoteNodes = ['p1', 'p2', 'p3', 'p4', 'p1'], // didn't change nodes
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo', bar: 'bar_remote', area: 'yes'}, // didn't change tag foo, added tag bar
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1').version).to.eql('2');
|
||||
expect(graph.entity('w1').tags).to.eql({foo: 'foo_local', bar: 'bar_remote', area: 'yes'});
|
||||
});
|
||||
|
||||
it("doesn't merge ways if nodelist reordered", function () {
|
||||
var localNodes = ['p1', 'p2', 'p3', 'p4', 'p1'], // didn't change nodes
|
||||
remoteNodes = ['p1', 'p3', 'p4', 'p2', 'p1'], // reordered nodes
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo', bar: 'bar_remote', area: 'yes'}, // didn't change tag foo, added tag bar
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1')).to.eql(local);
|
||||
});
|
||||
|
||||
it("merges ways if nodelist order preserved");
|
||||
|
||||
expect(graph.entity('a')).to.eql(local);
|
||||
});
|
||||
|
||||
it("does merge nodes if location is same and changed tags don't conflict", function () {
|
||||
var local = iD.Node({id: 'a', loc: [1, 1], version: '1', v: 2, tags: {foo: 'foo_local'}}),
|
||||
remote = iD.Node({id: 'a', loc: [1, 1], version: '2', tags: {foo: 'foo', bar: 'bar_remote'}}),
|
||||
graph = iD.Graph(base).replace(local),
|
||||
altGraph = iD.Graph(base).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph);
|
||||
describe("relations", function () {
|
||||
it("doesn't merge relations if members have changed", function () {
|
||||
var localMembers = [{id: 'w1', role: 'outer'}, {id: 'w2', role: 'inner'}], // didn't change members
|
||||
remoteMembers = [{id: 'w1', role: 'outer'}, {id: 'w4', role: 'inner'}], // changed inner to w4
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo', bar: 'bar_remote'}, // didn't change tag foo, added tag bar
|
||||
local = iD.Relation({id: 'r', members: localMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: remoteMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([s1, s2, s3, s4, w4]);
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').tags).to.eql({foo: 'foo_local', bar: 'bar_remote'});
|
||||
expect(graph.entity('r')).to.eql(local);
|
||||
});
|
||||
|
||||
it("doesn't merge relations if changed tags conflict", function () {
|
||||
var relMembers = [{id: 'w1', role: 'outer'}, {id: 'w2', role: 'inner'}], // didn't change members
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo_remote', bar: 'bar_remote'}, // changed tag foo, added tag bar
|
||||
local = iD.Relation({id: 'r', members: relMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: relMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]);
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('r')).to.eql(local);
|
||||
});
|
||||
|
||||
it("merges relations if members are same and changed tags don't conflict", function () {
|
||||
var relMembers = [{id: 'w1', role: 'outer'}, {id: 'w2', role: 'inner'}], // didn't change members
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo', bar: 'bar_remote'}, // didn't change tag foo, added tag bar
|
||||
local = iD.Relation({id: 'r', members: relMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: relMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]);
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph);
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('r').version).to.eql('2');
|
||||
expect(graph.entity('r').tags).to.eql({type: 'multipolygon', foo: 'foo_local', bar: 'bar_remote'});
|
||||
});
|
||||
});
|
||||
|
||||
// test merging ways
|
||||
|
||||
// test merging relations
|
||||
|
||||
});
|
||||
|
||||
describe("destuctive merging", function () {
|
||||
it("merges nodes with 'force_local' option", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Node({id: 'a', loc: [2, 2], version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Node({id: 'a', loc: [3, 3], version: '2', tags: remoteTags}),
|
||||
graph = iD.Graph(base).replace(local),
|
||||
altGraph = iD.Graph(base).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph).withOption('force_local');
|
||||
describe("nodes", function () {
|
||||
it("merges nodes with 'force_local' option", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
localLoc = [2, 2], // moved node
|
||||
remoteLoc = [3, 3], // moved node
|
||||
local = iD.Node({id: 'a', loc: localLoc, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Node({id: 'a', loc: remoteLoc, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph).withOption('force_local');
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').loc).to.eql([2, 2]);
|
||||
expect(graph.entity('a').tags).to.eql(localTags);
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').loc).to.eql(localLoc);
|
||||
expect(graph.entity('a').tags).to.eql(localTags);
|
||||
});
|
||||
|
||||
it("merges nodes with 'force_remote' option", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
localLoc = [2, 2], // moved node
|
||||
remoteLoc = [3, 3], // moved node
|
||||
local = iD.Node({id: 'a', loc: localLoc, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Node({id: 'a', loc: remoteLoc, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local]),
|
||||
altGraph = makeGraph([remote]),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph).withOption('force_remote');
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').loc).to.eql(remoteLoc);
|
||||
expect(graph.entity('a').tags).to.eql(remoteTags);
|
||||
});
|
||||
});
|
||||
|
||||
it("merges nodes with 'force_remote' option", function () {
|
||||
var localTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Node({id: 'a', loc: [2, 2], version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Node({id: 'a', loc: [3, 3], version: '2', tags: remoteTags}),
|
||||
graph = iD.Graph(base).replace(local),
|
||||
altGraph = iD.Graph(base).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('a', graph, altGraph).withOption('force_remote');
|
||||
describe("ways", function () {
|
||||
it("merges ways with 'force_local' option", function () {
|
||||
var localNodes = ['p1', 'r1', 'p2', 'p3', 'p4', 'p1'], // inserted node r1
|
||||
remoteNodes = ['p1', 'p2', 'p3', 's3', 'p4', 'p1'], // inserted node s3
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', area: 'yes'}, // changed tag foo
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local, r1]),
|
||||
altGraph = makeGraph([remote, s3]),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph).withOption('force_local');
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('a').version).to.eql('2');
|
||||
expect(graph.entity('a').loc).to.eql([3, 3]);
|
||||
expect(graph.entity('a').tags).to.eql(remoteTags);
|
||||
expect(graph.entity('w1').version).to.eql('2');
|
||||
expect(graph.hasEntity('s3')).to.be.undefined;
|
||||
expect(graph.entity('w1').nodes).to.eql(localNodes);
|
||||
expect(graph.entity('w1').tags).to.eql(localTags);
|
||||
});
|
||||
|
||||
it("merges ways with 'force_remote' option", function () {
|
||||
var localNodes = ['p1', 'r1', 'p2', 'p3', 'p4', 'p1'], // inserted node r1
|
||||
remoteNodes = ['p1', 'p2', 'p3', 's3', 'p4', 'p1'], // inserted node s3
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', area: 'yes'}, // changed tag foo
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = makeGraph([local, r1]),
|
||||
altGraph = makeGraph([remote, s3]),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph).withOption('force_remote');
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1').version).to.eql('2');
|
||||
expect(graph.hasEntity('s3')).to.eql(s3);
|
||||
expect(graph.entity('w1').nodes).to.eql(remoteNodes);
|
||||
expect(graph.entity('w1').tags).to.eql(remoteTags);
|
||||
});
|
||||
});
|
||||
|
||||
it("merges ways with 'force_local' option", function () {
|
||||
var x = iD.Node({id: 'x', loc: [5, 0], tags: {foo: 'foo_local'}}),
|
||||
y = iD.Node({id: 'y', loc: [-5, 0], version: '2', tags: {foo: 'foo_remote'}}),
|
||||
localNodes = ['p1', 'x', 'p2', 'p3', 'p4', 'p1'], // inserted node x
|
||||
remoteNodes = ['p1', 'p2', 'p3', 'y', 'p4', 'p1'], // inserted node y
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', area: 'yes'}, // changed tag foo
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = iD.Graph(base).replace(x).replace(local),
|
||||
altGraph = iD.Graph(base).replace(y).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph).withOption('force_local');
|
||||
describe("relations", function () {
|
||||
it("merges relations with 'force_local' option", function () {
|
||||
var localMembers = [{id: 'w3', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to w3
|
||||
remoteMembers = [{id: 'w4', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to w4
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Relation({id: 'r', members: localMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: remoteMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = makeGraph([local, r1, r2, r3, r4, w3]),
|
||||
altGraph = makeGraph([remote, s1, s2, s3, s4, w4]),
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph).withOption('force_local');
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1').version).to.eql('2');
|
||||
// expect(graph.hasEntity('x')).to.be.true;
|
||||
// expect(graph.hasEntity('y')).to.be.false;
|
||||
expect(graph.entity('w1').nodes).to.eql(localNodes);
|
||||
expect(graph.entity('w1').tags).to.eql(localTags);
|
||||
});
|
||||
expect(graph.entity('r').version).to.eql('2');
|
||||
expect(graph.entity('r').members).to.eql(localMembers);
|
||||
expect(graph.entity('r').tags).to.eql(localRelTags);
|
||||
});
|
||||
|
||||
it("merges ways with 'force_remote' option", function () {
|
||||
var x = iD.Node({id: 'x', loc: [5, 0], tags: {foo: 'foo_local'}}),
|
||||
y = iD.Node({id: 'y', loc: [-5, 0], version: '2', tags: {foo: 'foo_remote'}}),
|
||||
localNodes = ['p1', 'x', 'p2', 'p3', 'p4', 'p1'], // inserted node x
|
||||
remoteNodes = ['p1', 'p2', 'p3', 'y', 'p4', 'p1'], // inserted node y
|
||||
localTags = {foo: 'foo_local', area: 'yes'}, // changed tag foo
|
||||
remoteTags = {foo: 'foo_remote', area: 'yes'}, // changed tag foo
|
||||
local = iD.Way({id: 'w1', nodes: localNodes, version: '1', v: 2, tags: localTags}),
|
||||
remote = iD.Way({id: 'w1', nodes: remoteNodes, version: '2', tags: remoteTags}),
|
||||
graph = iD.Graph(base).replace(x).replace(local),
|
||||
altGraph = iD.Graph(base).replace(y).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('w1', graph, altGraph).withOption('force_remote');
|
||||
it("merges relations with 'force_remote' option", function () {
|
||||
var localMembers = [{id: 'w3', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to w3
|
||||
remoteMembers = [{id: 'w4', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to w4
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Relation({id: 'r', members: localMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: remoteMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = makeGraph([local, r1, r2, r3, r4, w3]),
|
||||
altGraph = makeGraph([remote, s1, s2, s3, s4, w4]),
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph).withOption('force_remote');
|
||||
|
||||
graph = action(graph);
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('w1').version).to.eql('2');
|
||||
// expect(graph.hasEntity('x')).to.be.true;
|
||||
// expect(graph.hasEntity('y')).to.be.true;
|
||||
expect(graph.entity('w1').nodes).to.eql(remoteNodes);
|
||||
expect(graph.entity('w1').tags).to.eql(remoteTags);
|
||||
});
|
||||
|
||||
it("merges relations with 'force_local' option", function () {
|
||||
var localNodes = ['p2', 'p3', 'p4', 'p1', 'p2'], // changed order
|
||||
remoteNodes = ['p1', 'p4', 'p3', 'p2', 'p1'], // reversed order
|
||||
localWayTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteWayTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
x = iD.Way({id: 'x', nodes: localNodes, tags: localWayTags}),
|
||||
y = iD.Way({id: 'y', nodes: remoteNodes, version: '2', tags: remoteWayTags}),
|
||||
localMembers = [{id: 'x', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to x
|
||||
remoteMembers = [{id: 'y', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to y
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Relation({id: 'r', members: localMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: remoteMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = iD.Graph(base).replace(x).replace(local),
|
||||
altGraph = iD.Graph(base).replace(y).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph).withOption('force_local');
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('r').version).to.eql('2');
|
||||
// expect(graph.hasEntity('x')).to.be.true;
|
||||
// expect(graph.hasEntity('y')).to.be.false;
|
||||
expect(graph.entity('r').members).to.eql(localMembers);
|
||||
expect(graph.entity('r').tags).to.eql(localRelTags);
|
||||
});
|
||||
|
||||
it("merges relations with 'force_remote' option", function () {
|
||||
var localNodes = ['p2', 'p3', 'p4', 'p1', 'p2'], // changed order
|
||||
remoteNodes = ['p1', 'p4', 'p3', 'p2', 'p1'], // reversed
|
||||
localWayTags = {foo: 'foo_local'}, // changed tag foo
|
||||
remoteWayTags = {foo: 'foo_remote'}, // changed tag foo
|
||||
x = iD.Way({id: 'x', nodes: localNodes, tags: localWayTags}),
|
||||
y = iD.Way({id: 'y', nodes: remoteNodes, version: '2', tags: remoteWayTags}),
|
||||
localMembers = [{id: 'x', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to x
|
||||
remoteMembers = [{id: 'y', role: 'outer'}, {id: 'w2', role: 'inner'}], // changed outer to y
|
||||
localRelTags = {type: 'multipolygon', foo: 'foo_local'}, // changed tag foo
|
||||
remoteRelTags = {type: 'multipolygon', foo: 'foo_remote'}, // changed tag foo
|
||||
local = iD.Relation({id: 'r', members: localMembers, version: '1', v: 2, tags: localRelTags}),
|
||||
remote = iD.Relation({id: 'r', members: remoteMembers, version: '2', tags: remoteRelTags}),
|
||||
graph = iD.Graph(base).replace(x).replace(local),
|
||||
altGraph = iD.Graph(base).replace(y).replace(remote),
|
||||
action = iD.actions.MergeRemoteChanges('r', graph, altGraph).withOption('force_remote');
|
||||
|
||||
graph = action(graph);
|
||||
|
||||
expect(graph.entity('r').version).to.eql('2');
|
||||
// expect(graph.hasEntity('x')).to.be.true;
|
||||
// expect(graph.hasEntity('y')).to.be.true;
|
||||
expect(graph.entity('r').members).to.eql(remoteMembers);
|
||||
expect(graph.entity('r').tags).to.eql(remoteRelTags);
|
||||
expect(graph.entity('r').version).to.eql('2');
|
||||
expect(graph.entity('r').members).to.eql(remoteMembers);
|
||||
expect(graph.entity('r').tags).to.eql(remoteRelTags);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user