Handle incomplete relations in simpleMultipolygonOuterMember

This commit is contained in:
John Firebaugh
2013-05-01 10:28:40 -07:00
parent 786c2ab540
commit d247962324
7 changed files with 97 additions and 55 deletions
+1
View File
@@ -41,6 +41,7 @@
<script src="js/id/geo.js"></script>
<script src="js/id/geo/extent.js"></script>
<script src="js/id/geo/multipolygon.js"></script>
<script src='js/id/renderer/background.js'></script>
<script src='js/id/renderer/background_source.js'></script>
+50
View File
@@ -0,0 +1,50 @@
// For fixing up rendering of multipolygons with tags on the outer member.
// https://github.com/systemed/iD/issues/613
iD.geo.isSimpleMultipolygonOuterMember = function(entity, graph) {
if (entity.type !== 'way')
return false;
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
return false;
var members = parent.members, member;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (member.id === entity.id && member.role && member.role !== 'outer')
return false; // Not outer member
if (member.id !== entity.id && (!member.role || member.role === 'outer'))
return false; // Not a simple multipolygon
}
return parent;
};
iD.geo.simpleMultipolygonOuterMember = function(entity, graph) {
if (entity.type !== 'way')
return false;
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
return false;
var members = parent.members, member, outerMember;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (!member.role || member.role === 'outer') {
if (outerMember)
return false; // Not a simple multipolygon
outerMember = member;
}
}
return outerMember && graph.hasEntity(outerMember.id);
};
+1 -27
View File
@@ -1,30 +1,4 @@
iD.svg.Areas = function(projection) {
// For fixing up rendering of multipolygons with tags on the outer member.
// https://github.com/systemed/iD/issues/613
function isSimpleMultipolygonOuterMember(entity, graph) {
if (entity.type !== 'way')
return false;
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
return false;
var members = parent.members, member;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (member.id === entity.id && member.role && member.role !== 'outer')
return false; // Not outer member
if (member.id !== entity.id && (!member.role || member.role === 'outer'))
return false; // Not a simple multipolygon
}
return parent;
}
// Patterns only work in Firefox when set directly on element
var patterns = {
wetland: 'wetland',
@@ -62,7 +36,7 @@ iD.svg.Areas = function(projection) {
var entity = entities[i];
if (entity.geometry(graph) !== 'area') continue;
if (multipolygon = isSimpleMultipolygonOuterMember(entity, graph)) {
if (multipolygon = iD.geo.isSimpleMultipolygonOuterMember(entity, graph)) {
areas[multipolygon.id] = {
entity: multipolygon.mergeTags(entity.tags),
area: Math.abs(path.area(entity.asGeoJSON(graph, true)))
+1 -28
View File
@@ -32,33 +32,6 @@ iD.svg.Lines = function(projection) {
return as - bs;
}
// For fixing up rendering of multipolygons with tags on the outer member.
// https://github.com/systemed/iD/issues/613
function simpleMultipolygonOuterMember(entity, graph) {
if (entity.type !== 'way')
return false;
var parents = graph.parentRelations(entity);
if (parents.length !== 1)
return false;
var parent = parents[0];
if (!parent.isMultipolygon() || Object.keys(parent.tags).length > 1)
return false;
var members = parent.members, member, outer;
for (var i = 0; i < members.length; i++) {
member = members[i];
if (!member.role || member.role === 'outer') {
if (outer)
return false; // Not a simple multipolygon
outer = graph.entity(member.id);
}
}
return outer;
}
return function drawLines(surface, graph, entities, filter) {
function drawPaths(group, lines, filter, klass, lineString) {
lines = lines.filter(function(line) {
@@ -95,7 +68,7 @@ iD.svg.Lines = function(projection) {
for (var i = 0; i < entities.length; i++) {
var entity = entities[i],
outer = simpleMultipolygonOuterMember(entity, graph);
outer = iD.geo.simpleMultipolygonOuterMember(entity, graph);
if (outer) {
lines.push(entity.mergeTags(outer.tags));
} else if (entity.geometry(graph) === 'line') {
+2
View File
@@ -42,6 +42,7 @@
<script src="../js/id/geo.js"></script>
<script src="../js/id/geo/extent.js"></script>
<script src="../js/id/geo/multipolygon.js"></script>
<script src='../js/id/renderer/background.js'></script>
<script src='../js/id/renderer/background_source.js'></script>
@@ -200,6 +201,7 @@
<script src="spec/actions/split.js"></script>
<script src="spec/geo/extent.js"></script>
<script src="spec/geo/multipolygon.js"></script>
<script src="spec/core/connection.js"></script>
<script src="spec/core/graph.js"></script>
+1
View File
@@ -44,6 +44,7 @@
<script src="spec/actions/split.js"></script>
<script src="spec/geo/extent.js"></script>
<script src="spec/geo/multipolygon.js"></script>
<script src="spec/core/connection.js"></script>
<script src="spec/core/graph.js"></script>
+41
View File
@@ -0,0 +1,41 @@
describe("iD.geo.simpleMultipolygonOuterMember", function() {
it("returns the outer member of a simple multipolygon", function() {
var inner = iD.Way(),
outer = iD.Way(),
relation = iD.Relation({tags: {type: 'multipolygon'}, members: [
{id: outer.id, role: 'outer'},
{id: inner.id, role: 'inner'}]
}),
graph = iD.Graph([inner, outer, relation]);
expect(iD.geo.simpleMultipolygonOuterMember(inner, graph)).to.equal(outer);
expect(iD.geo.simpleMultipolygonOuterMember(outer, graph)).to.equal(outer);
});
it("returns falsy for a complex multipolygon", function() {
var inner = iD.Way(),
outer1 = iD.Way(),
outer2 = iD.Way(),
relation = iD.Relation({tags: {type: 'multipolygon'}, members: [
{id: outer1.id, role: 'outer'},
{id: outer2.id, role: 'outer'},
{id: inner.id, role: 'inner'}]
}),
graph = iD.Graph([inner, outer1, outer2, relation]);
expect(iD.geo.simpleMultipolygonOuterMember(inner, graph)).not.to.be.ok;
expect(iD.geo.simpleMultipolygonOuterMember(outer1, graph)).not.to.be.ok;
expect(iD.geo.simpleMultipolygonOuterMember(outer2, graph)).not.to.be.ok;
});
it("handles incomplete relations", function() {
var way = iD.Way({id: 'w'}),
relation = iD.Relation({id: 'r', tags: {type: 'multipolygon'}, members: [
{id: 'o', role: 'outer'},
{id: 'w', role: 'inner'}]
}),
graph = iD.Graph([way, relation]);
expect(iD.geo.simpleMultipolygonOuterMember(way, graph)).to.be.undefined;
});
});