Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Handle incomplete relations in simpleMultipolygonOuterMember

  • Loading branch information...
commit d2479623244393b6b83a2ac43780b2ede59f823a 1 parent 786c2ab
@jfirebaugh jfirebaugh authored
View
1  index.html
@@ -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>
View
50 js/id/geo/multipolygon.js
@@ -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);
+};
View
28 js/id/svg/areas.js
@@ -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)))
View
29 js/id/svg/lines.js
@@ -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') {
View
2  test/index.html
@@ -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>
View
1  test/index_packaged.html
@@ -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>
View
41 test/spec/geo/multipolygon.js
@@ -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;
+ });
+});
Please sign in to comment.
Something went wrong with that request. Please try again.