Skip to content

Commit

Permalink
Merge pull request Esri#340 from patrickarlt/topologies
Browse files Browse the repository at this point in the history
Fix ArcGIS > GeoJSON parsing edge case
  • Loading branch information
patrickarlt committed Sep 1, 2014
2 parents b3fe5b3 + 320563d commit 90551ea
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 14 deletions.
27 changes: 23 additions & 4 deletions spec/UtilSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -653,15 +653,16 @@ describe('L.esri.Util', function () {
};

var output = L.esri.Util.arcgisToGeojson(input);

expect(output.coordinates).to.deep.equal([
var expected = [
[
[ [-122.63,45.52],[-122.57,45.53],[-122.52,45.5],[-122.49,45.48],[-122.64,45.49],[-122.63,45.52],[-122.63,45.52] ]
],
[
[ [-83,35],[-83,41],[-74,41],[-74,35],[-83,35] ]
]
]);
];

expect(output.coordinates).to.deep.equal(expected);
expect(output.type).to.deep.equal('MultiPolygon');
});

Expand Down Expand Up @@ -708,7 +709,7 @@ describe('L.esri.Util', function () {
expect(output.type).to.deep.equal('MultiPolygon');
});

it('should parse an ArcGIS MultiPolygon with holes in web mercator to a GeoJSON MultiPolygon', function(){
it('should parse an ArcGIS MultiPolygon with holes to a GeoJSON MultiPolygon', function(){
var input = {
'type':'polygon',
'rings':[
Expand Down Expand Up @@ -736,6 +737,24 @@ describe('L.esri.Util', function () {
expect(output.type).to.deep.equal('MultiPolygon');
});

it('should still parse holes outside the outer rings', function(){
var input = {
"rings": [
[ [-122.45,45.63], [-122.45,45.68], [-122.39,45.68], [-122.39,45.63], [-122.45,45.63] ],
[ [-122.46,45.64], [-122.4,45.64], [-122.4,45.66], [-122.46,45.66], [-122.46,45.64] ]
]
}

var output = L.esri.Util.arcgisToGeojson(input);

var expected = [
[ [-122.45,45.63], [-122.45,45.68], [-122.39,45.68], [-122.39,45.63], [-122.45,45.63] ],
[ [-122.46,45.64], [-122.4,45.64], [-122.4,45.66], [-122.46,45.66], [-122.46,45.64] ]
];

expect(output.coordinates).to.deep.equal(expected);
});

it('should parse an ArcGIS Feature into a GeoJSON Feature', function(){
var input = {
'geometry': {
Expand Down
44 changes: 34 additions & 10 deletions src/Util.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@
function convertRingsToGeoJSON(rings){
var outerRings = [];
var holes = [];
var x; // iterator
var outerRing; // current outer ring being evaluated
var hole; // current hole being evaluated

// for each ring
for (var r = 0; r < rings.length; r++) {
Expand All @@ -123,30 +126,51 @@
}
}

var uncontainedHoles = [];

// while there are holes left...
while(holes.length){
// pop a hole off out stack
var hole = holes.pop();
var matched = false;
hole = holes.pop();

// loop over all outer rings and see if they contain our hole.
for (var x = outerRings.length - 1; x >= 0; x--) {
var outerRing = outerRings[x][0];
var contained = false;
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if(coordinatesContainCoordinates(outerRing, hole)){
// the hole is contained push it into our polygon
outerRings[x].push(hole);
contained = true;
break;
}
}

// ring is not contained in any outer ring
// sometimes this happens https://github.com/Esri/esri-leaflet/issues/320
if(!contained){
uncontainedHoles.push(hole);
}
}

// we matched the hole
matched = true;
// if we couldn't match any holes using contains we can try intersects...
while(uncontainedHoles.length){
// pop a hole off out stack
hole = uncontainedHoles.pop();

// stop checking to see if other outer rings contian this hole
// loop over all outer rings and see if any intersect our hole.
var intersects = false;
for (x = outerRings.length - 1; x >= 0; x--) {
outerRing = outerRings[x][0];
if(arrayIntersectsArray(outerRing, hole)){
// the hole is contained push it into our polygon
outerRings[x].push(hole);
intersects = true;
break;
}
}

// no outer rings contain this hole turn it into and outer ring (reverse it)
if(!matched){
outerRings.push([ hole.reverse() ]);
if(!intersects) {
outerRings.push([hole.reverse()]);
}
}

Expand Down

0 comments on commit 90551ea

Please sign in to comment.