mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-14 05:12:13 +02:00
Handle incomplete relations in simpleMultipolygonOuterMember
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
@@ -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
@@ -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') {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user