mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-27 14:16:42 +02:00
26e38d7f8f
No code needs the tags, and it eliminates one level of function calls in the d3 stream pipeline.
474 lines
21 KiB
JavaScript
474 lines
21 KiB
JavaScript
describe('iD.Relation', function () {
|
|
if (iD.debug) {
|
|
it("freezes nodes", function () {
|
|
expect(Object.isFrozen(iD.Relation().members)).to.be.true;
|
|
});
|
|
}
|
|
|
|
it("returns a relation", function () {
|
|
expect(iD.Relation()).to.be.an.instanceOf(iD.Relation);
|
|
expect(iD.Relation().type).to.equal("relation");
|
|
});
|
|
|
|
it("defaults members to an empty array", function () {
|
|
expect(iD.Relation().members).to.eql([]);
|
|
});
|
|
|
|
it("sets members as specified", function () {
|
|
expect(iD.Relation({members: ["n-1"]}).members).to.eql(["n-1"]);
|
|
});
|
|
|
|
it("defaults tags to an empty object", function () {
|
|
expect(iD.Relation().tags).to.eql({});
|
|
});
|
|
|
|
it("sets tags as specified", function () {
|
|
expect(iD.Relation({tags: {foo: 'bar'}}).tags).to.eql({foo: 'bar'});
|
|
});
|
|
|
|
describe("#extent", function () {
|
|
it("returns the minimal extent containing the extents of all members", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [5, 10]}),
|
|
r = iD.Relation({members: [{id: a.id}, {id: b.id}]}),
|
|
graph = iD.Graph([a, b, r]);
|
|
|
|
expect(r.extent(graph)).to.eql([[0, 0], [5, 10]])
|
|
});
|
|
|
|
it("returns the known extent of incomplete relations", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [5, 10]}),
|
|
r = iD.Relation({members: [{id: a.id}, {id: b.id}]}),
|
|
graph = iD.Graph([a, r]);
|
|
|
|
expect(r.extent(graph)).to.eql([[0, 0], [0, 0]])
|
|
});
|
|
});
|
|
|
|
describe("#geometry", function () {
|
|
it("returns 'area' for multipolygons", function () {
|
|
expect(iD.Relation({tags: {type: 'multipolygon'}}).geometry(iD.Graph())).to.equal('area');
|
|
});
|
|
|
|
it("returns 'relation' for other relations", function () {
|
|
expect(iD.Relation().geometry(iD.Graph())).to.equal('relation');
|
|
});
|
|
});
|
|
|
|
describe("#isDegenerate", function () {
|
|
it("returns true for a relation without members", function () {
|
|
expect(iD.Relation().isDegenerate()).to.equal(true);
|
|
});
|
|
|
|
it("returns false for a relation with members", function () {
|
|
expect(iD.Relation({members: [{id: 'a', role: 'inner'}]}).isDegenerate()).to.equal(false);
|
|
});
|
|
});
|
|
|
|
describe("#memberByRole", function () {
|
|
it("returns the first member with the given role", function () {
|
|
var r = iD.Relation({members: [
|
|
{id: 'a', role: 'inner'},
|
|
{id: 'b', role: 'outer'},
|
|
{id: 'c', role: 'outer'}]});
|
|
expect(r.memberByRole('outer')).to.eql({id: 'b', role: 'outer', index: 1});
|
|
});
|
|
|
|
it("returns undefined if no members have the given role", function () {
|
|
expect(iD.Relation().memberByRole('outer')).to.be.undefined;
|
|
});
|
|
});
|
|
|
|
describe("#memberById", function () {
|
|
it("returns the first member with the given id", function () {
|
|
var r = iD.Relation({members: [
|
|
{id: 'a', role: 'outer'},
|
|
{id: 'b', role: 'outer'},
|
|
{id: 'b', role: 'inner'}]});
|
|
expect(r.memberById('b')).to.eql({id: 'b', role: 'outer', index: 1});
|
|
});
|
|
|
|
it("returns undefined if no members have the given role", function () {
|
|
expect(iD.Relation().memberById('b')).to.be.undefined;
|
|
});
|
|
});
|
|
|
|
describe("#isRestriction", function () {
|
|
it("returns true for 'restriction' type", function () {
|
|
expect(iD.Relation({tags: {type: 'restriction'}}).isRestriction()).to.be.true;
|
|
});
|
|
|
|
it("returns true for 'restriction:type' types", function () {
|
|
expect(iD.Relation({tags: {type: 'restriction:bus'}}).isRestriction()).to.be.true;
|
|
});
|
|
|
|
it("returns false otherwise", function () {
|
|
expect(iD.Relation().isRestriction()).to.be.false;
|
|
expect(iD.Relation({tags: {type: 'multipolygon'}}).isRestriction()).to.be.false;
|
|
});
|
|
});
|
|
|
|
describe("#indexedMembers", function () {
|
|
it("returns an array of members extended with indexes", function () {
|
|
var r = iD.Relation({members: [{id: '1'}, {id: '3'}]});
|
|
expect(r.indexedMembers()).to.eql([{id: '1', index: 0}, {id: '3', index: 1}]);
|
|
});
|
|
});
|
|
|
|
describe("#addMember", function () {
|
|
it("adds a member at the end of the relation", function () {
|
|
var r = iD.Relation();
|
|
expect(r.addMember({id: '1'}).members).to.eql([{id: '1'}]);
|
|
});
|
|
|
|
it("adds a member at index 0", function () {
|
|
var r = iD.Relation({members: [{id: '1'}]});
|
|
expect(r.addMember({id: '2'}, 0).members).to.eql([{id: '2'}, {id: '1'}]);
|
|
});
|
|
|
|
it("adds a member at a positive index", function () {
|
|
var r = iD.Relation({members: [{id: '1'}, {id: '3'}]});
|
|
expect(r.addMember({id: '2'}, 1).members).to.eql([{id: '1'}, {id: '2'}, {id: '3'}]);
|
|
});
|
|
|
|
it("adds a member at a negative index", function () {
|
|
var r = iD.Relation({members: [{id: '1'}, {id: '3'}]});
|
|
expect(r.addMember({id: '2'}, -1).members).to.eql([{id: '1'}, {id: '2'}, {id: '3'}]);
|
|
});
|
|
});
|
|
|
|
describe("#updateMember", function () {
|
|
it("updates the properties of the relation member at the specified index", function () {
|
|
var r = iD.Relation({members: [{role: 'forward'}]});
|
|
expect(r.updateMember({role: 'backward'}, 0).members).to.eql([{role: 'backward'}]);
|
|
});
|
|
});
|
|
|
|
describe("#removeMember", function () {
|
|
it("removes the member at the specified index", function () {
|
|
var r = iD.Relation({members: [{id: 'a'}, {id: 'b'}, {id: 'c'}]});
|
|
expect(r.removeMember(1).members).to.eql([{id: 'a'}, {id: 'c'}]);
|
|
});
|
|
});
|
|
|
|
describe("#removeMembersWithID", function () {
|
|
it("removes members with the given ID", function () {
|
|
var r = iD.Relation({members: [{id: 'a'}, {id: 'b'}, {id: 'a'}]});
|
|
expect(r.removeMembersWithID('a').members).to.eql([{id: 'b'}]);
|
|
});
|
|
});
|
|
|
|
describe("#replaceMember", function () {
|
|
it("returns self if self does not contain needle", function () {
|
|
var r = iD.Relation({members: []});
|
|
expect(r.replaceMember({id: 'a'}, {id: 'b'})).to.equal(r);
|
|
});
|
|
|
|
it("replaces a member which doesn't already exist", function () {
|
|
var r = iD.Relation({members: [{id: 'a', role: 'a'}]});
|
|
expect(r.replaceMember({id: 'a'}, {id: 'b', type: 'node'}).members).to.eql([{id: 'b', role: 'a', type: 'node'}]);
|
|
});
|
|
|
|
it("preserves the existing role", function () {
|
|
var r = iD.Relation({members: [{id: 'a', role: 'a', type: 'node'}]});
|
|
expect(r.replaceMember({id: 'a'}, {id: 'b', type: 'node'}).members).to.eql([{id: 'b', role: 'a', type: 'node'}]);
|
|
});
|
|
|
|
it("uses the replacement type", function () {
|
|
var r = iD.Relation({members: [{id: 'a', role: 'a', type: 'node'}]});
|
|
expect(r.replaceMember({id: 'a'}, {id: 'b', type: 'way'}).members).to.eql([{id: 'b', role: 'a', type: 'way'}]);
|
|
});
|
|
|
|
it("removes members if replacing them would produce duplicates", function () {
|
|
var r = iD.Relation({members: [
|
|
{id: 'a', role: 'b', type: 'node'},
|
|
{id: 'b', role: 'b', type: 'node'}]});
|
|
expect(r.replaceMember({id: 'a'}, {id: 'b', type: 'node'}).members).to.eql([{id: 'b', role: 'b', type: 'node'}]);
|
|
});
|
|
});
|
|
|
|
describe("#asJXON", function () {
|
|
it('converts a relation to jxon', function() {
|
|
var relation = iD.Relation({id: 'r-1', members: [{id: 'w1', role: 'forward', type: 'way'}], tags: {type: 'route'}});
|
|
expect(relation.asJXON()).to.eql({relation: {
|
|
'@id': '-1',
|
|
'@version': 0,
|
|
member: [{keyAttributes: {ref: '1', role: 'forward', type: 'way'}}],
|
|
tag: [{keyAttributes: {k: 'type', v: 'route'}}]}});
|
|
});
|
|
|
|
it('includes changeset if provided', function() {
|
|
expect(iD.Relation().asJXON('1234').relation['@changeset']).to.equal('1234');
|
|
});
|
|
});
|
|
|
|
describe("#asGeoJSON", function (){
|
|
it('converts a multipolygon to a GeoJSON MultiPolygon geometry', function() {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
r = iD.Relation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w, r]),
|
|
json = r.asGeoJSON(g);
|
|
|
|
expect(json.type).to.equal('MultiPolygon');
|
|
expect(json.coordinates).to.eql([[[a.loc, b.loc, c.loc, a.loc]]]);
|
|
});
|
|
|
|
it('forces clockwise winding order for outer multipolygon ways', function() {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
w = iD.Way({nodes: [a.id, c.id, b.id, a.id]}),
|
|
r = iD.Relation({tags: {type: 'multipolygon'}, members: [{id: w.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w, r]),
|
|
json = r.asGeoJSON(g);
|
|
|
|
expect(json.coordinates[0][0]).to.eql([a.loc, b.loc, c.loc, a.loc]);
|
|
});
|
|
|
|
it('forces counterclockwise winding order for inner multipolygon ways', function() {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
d = iD.Node({loc: [0.1, 0.1]}),
|
|
e = iD.Node({loc: [0.1, 0.2]}),
|
|
f = iD.Node({loc: [0.2, 0.1]}),
|
|
outer = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
inner = iD.Way({nodes: [d.id, e.id, f.id, d.id]}),
|
|
r = iD.Relation({members: [{id: outer.id, type: 'way'}, {id: inner.id, role: 'inner', type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, e, f, outer, inner, r]);
|
|
|
|
expect(r.multipolygon(g)[0][1]).to.eql([d.loc, f.loc, e.loc, d.loc]);
|
|
});
|
|
|
|
it('converts a relation to a GeoJSON FeatureCollection', function() {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
r = iD.Relation({tags: {type: 'type'}, members: [{id: a.id, role: 'role'}]}),
|
|
g = iD.Graph([a, r]),
|
|
json = r.asGeoJSON(g);
|
|
|
|
expect(json.type).to.equal('FeatureCollection');
|
|
expect(json.properties).to.eql({type: 'type'});
|
|
expect(json.features).to.eql([_.extend({role: 'role'}, a.asGeoJSON(g))]);
|
|
});
|
|
});
|
|
|
|
describe("#multipolygon", function () {
|
|
specify("single polygon consisting of a single way", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
r = iD.Relation({members: [{id: w.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("single polygon consisting of multiple ways", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id]}),
|
|
w2 = iD.Way({nodes: [b.id, c.id, a.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("single polygon consisting of multiple ways, one needing reversal", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id]}),
|
|
w2 = iD.Way({nodes: [a.id, c.id, b.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("multiple polygons consisting of single ways", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
d = iD.Node({loc: [4, 4]}),
|
|
e = iD.Node({loc: [6, 6]}),
|
|
f = iD.Node({loc: [5, 5]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
w2 = iD.Way({nodes: [d.id, e.id, f.id, d.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, e, f, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc]], [[d.loc, e.loc, f.loc, d.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unclosed ring consisting of a single way", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w = iD.Way({nodes: [a.id, b.id, c.id]}),
|
|
r = iD.Relation({members: [{id: w.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unclosed ring consisting of multiple ways", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [3, 3]}),
|
|
c = iD.Node({loc: [2, 2]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id]}),
|
|
w2 = iD.Way({nodes: [b.id, c.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unclosed ring consisting of multiple ways, alternate order", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [2, 2]}),
|
|
c = iD.Node({loc: [3, 3]}),
|
|
d = iD.Node({loc: [4, 4]}),
|
|
w1 = iD.Way({nodes: [c.id, d.id]}),
|
|
w2 = iD.Way({nodes: [a.id, b.id, c.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[d.loc, c.loc, b.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unclosed ring consisting of multiple ways, one needing reversal", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [2, 2]}),
|
|
c = iD.Node({loc: [3, 3]}),
|
|
d = iD.Node({loc: [4, 4]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id, c.id]}),
|
|
w2 = iD.Way({nodes: [d.id, c.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[d.loc, c.loc, b.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unclosed ring consisting of multiple ways, one needing reversal, alternate order", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [2, 2]}),
|
|
c = iD.Node({loc: [3, 3]}),
|
|
d = iD.Node({loc: [4, 4]}),
|
|
w1 = iD.Way({nodes: [c.id, d.id]}),
|
|
w2 = iD.Way({nodes: [c.id, b.id, a.id]}),
|
|
r = iD.Relation({members: [{id: w1.id, type: 'way'}, {id: w2.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, w1, w2, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[d.loc, c.loc, b.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("single polygon with single single-way inner", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
d = iD.Node({loc: [0.1, 0.1]}),
|
|
e = iD.Node({loc: [0.2, 0.1]}),
|
|
f = iD.Node({loc: [0.1, 0.2]}),
|
|
outer = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
inner = iD.Way({nodes: [d.id, e.id, f.id, d.id]}),
|
|
r = iD.Relation({members: [{id: outer.id, type: 'way'}, {id: inner.id, role: 'inner', type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, d, e, f, outer, inner, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc], [d.loc, e.loc, f.loc, d.loc]]]);
|
|
});
|
|
|
|
specify("single polygon with single multi-way inner", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
d = iD.Node({loc: [0.1, 0.1]}),
|
|
e = iD.Node({loc: [0.2, 0.1]}),
|
|
f = iD.Node({loc: [0.2, 0.1]}),
|
|
outer = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
inner1 = iD.Way({nodes: [d.id, e.id]}),
|
|
inner2 = iD.Way({nodes: [e.id, f.id, d.id]}),
|
|
r = iD.Relation({members: [
|
|
{id: outer.id, type: 'way'},
|
|
{id: inner1.id, role: 'inner', type: 'way'},
|
|
{id: inner2.id, role: 'inner', type: 'way'}]}),
|
|
graph = iD.Graph([a, b, c, d, e, f, outer, inner1, inner2, r]);
|
|
|
|
expect(r.multipolygon(graph)).to.eql([[[a.loc, b.loc, c.loc, a.loc], [d.loc, e.loc, f.loc, d.loc]]]);
|
|
});
|
|
|
|
specify("single polygon with multiple single-way inners", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
d = iD.Node({loc: [0.1, 0.1]}),
|
|
e = iD.Node({loc: [0.2, 0.1]}),
|
|
f = iD.Node({loc: [0.1, 0.2]}),
|
|
g = iD.Node({loc: [0.2, 0.2]}),
|
|
h = iD.Node({loc: [0.3, 0.2]}),
|
|
i = iD.Node({loc: [0.2, 0.3]}),
|
|
outer = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
inner1 = iD.Way({nodes: [d.id, e.id, f.id, d.id]}),
|
|
inner2 = iD.Way({nodes: [g.id, h.id, i.id, g.id]}),
|
|
r = iD.Relation({members: [
|
|
{id: outer.id, type: 'way'},
|
|
{id: inner1.id, role: 'inner', type: 'way'},
|
|
{id: inner2.id, role: 'inner', type: 'way'}]}),
|
|
graph = iD.Graph([a, b, c, d, e, f, g, h, i, outer, inner1, inner2, r]);
|
|
|
|
expect(r.multipolygon(graph)).to.eql([[[a.loc, b.loc, c.loc, a.loc], [d.loc, e.loc, f.loc, d.loc], [g.loc, h.loc, i.loc, g.loc]]]);
|
|
});
|
|
|
|
specify("multiple polygons with single single-way inner", function () {
|
|
var a = iD.Node({loc: [0, 0]}),
|
|
b = iD.Node({loc: [0, 1]}),
|
|
c = iD.Node({loc: [1, 0]}),
|
|
d = iD.Node({loc: [0.1, 0.1]}),
|
|
e = iD.Node({loc: [0.2, 0.1]}),
|
|
f = iD.Node({loc: [0.1, 0.2]}),
|
|
g = iD.Node({loc: [0, 0]}),
|
|
h = iD.Node({loc: [0, -1]}),
|
|
i = iD.Node({loc: [-1, 0]}),
|
|
outer1 = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
outer2 = iD.Way({nodes: [g.id, h.id, i.id, g.id]}),
|
|
inner = iD.Way({nodes: [d.id, e.id, f.id, d.id]}),
|
|
r = iD.Relation({members: [
|
|
{id: outer1.id, type: 'way'},
|
|
{id: outer2.id, type: 'way'},
|
|
{id: inner.id, role: 'inner', type: 'way'}]}),
|
|
graph = iD.Graph([a, b, c, d, e, f, g, h, i, outer1, outer2, inner, r]);
|
|
|
|
expect(r.multipolygon(graph)).to.eql([[[a.loc, b.loc, c.loc, a.loc], [d.loc, e.loc, f.loc, d.loc]], [[g.loc, h.loc, i.loc, g.loc]]]);
|
|
});
|
|
|
|
specify("invalid geometry: unmatched inner", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [2, 2]}),
|
|
c = iD.Node({loc: [3, 3]}),
|
|
w = iD.Way({nodes: [a.id, b.id, c.id, a.id]}),
|
|
r = iD.Relation({members: [{id: w.id, role: 'inner', type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc, a.loc]]]);
|
|
});
|
|
|
|
specify("incomplete relation", function () {
|
|
var a = iD.Node({loc: [1, 1]}),
|
|
b = iD.Node({loc: [2, 2]}),
|
|
c = iD.Node({loc: [3, 3]}),
|
|
w1 = iD.Way({nodes: [a.id, b.id, c.id]}),
|
|
w2 = iD.Way(),
|
|
r = iD.Relation({members: [{id: w2.id, type: 'way'}, {id: w1.id, type: 'way'}]}),
|
|
g = iD.Graph([a, b, c, w1, r]);
|
|
|
|
expect(r.multipolygon(g)).to.eql([[[a.loc, b.loc, c.loc]]]);
|
|
});
|
|
});
|
|
});
|