diff --git a/CHANGES.md b/CHANGES.md index 1791f071487b..1440c669cd48 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ Change Log * Fixed a bug where glTF models with animations of different lengths would cause an error. [#5694](https://github.com/AnalyticalGraphicsInc/cesium/issues/5694) * Added a `clampAnimations` parameter to `Model` and `Entity.model`. Setting this to `false` allows different length animations to loop asynchronously over the duration of the longest animation. * Fixed `Invalid asm.js: Invalid member of stdlib` console error by recompiling crunch.js with latest emscripten toolchain. [#5847](https://github.com/AnalyticalGraphicsInc/cesium/issues/5847) +* Added function that removes duplicate namespace declarations while loading a KML or a KMZ. [#5972](https://github.com/AnalyticalGraphicsInc/cesium/pull/5972) * Added `file:` scheme compatibility to `joinUrls`. [#5989](https://github.com/AnalyticalGraphicsInc/cesium/pull/5989) * Added a Reverse Geocoder [Sandcastle example](https://cesiumjs.org/Cesium/Apps/Sandcastle/?src=Reverse%20Geocoder.html&label=Showcases). [#5976](https://github.com/AnalyticalGraphicsInc/cesium/pull/5976) * Added ability to support touch event in Imagery Layers Split Sandcastle example. [#5948](https://github.com/AnalyticalGraphicsInc/cesium/pull/5948) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index d4421bfc910e..ce3a82155124 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -99,6 +99,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to Cesiu * [Joshua Bernstein](https://github.com/jbernstein/) * [Natanael Rivera](https://github.com/nrivera-Novetta/) * [Justin Burr](https://github.com/jburr-nc/) + * [Jeremy Marzano](https://github.com/JeremyMarzano-ISPA/) ## [Individual CLA](Documentation/Contributors/CLAs/individual-cla-agi-v1.0.txt) * [Victor Berchet](https://github.com/vicb) diff --git a/Source/DataSources/KmlDataSource.js b/Source/DataSources/KmlDataSource.js index b8170fdf9881..2c22d6cbe479 100644 --- a/Source/DataSources/KmlDataSource.js +++ b/Source/DataSources/KmlDataSource.js @@ -282,9 +282,31 @@ define([ return text; } + function removeDuplicateNamespaces(text) { + var index = text.indexOf('xmlns:'); + var endDeclaration = text.indexOf('>', index); + var namespace, startIndex, endIndex; + + while ((index !== -1) && (index < endDeclaration)) { + namespace = text.slice(index, text.indexOf('\"', index)); + startIndex = index; + index = text.indexOf(namespace, index + 1); + if (index !== -1) { + endIndex = text.indexOf('\"', (text.indexOf('\"', index) + 1)); + text = text.slice(0, index -1) + text.slice(endIndex + 1, text.length); + index = text.indexOf('xmlns:', startIndex - 1); + } else { + index = text.indexOf('xmlns:', startIndex + 1); + } + } + + return text; + } + function loadXmlFromZip(reader, entry, uriResolver, deferred) { entry.getData(new zip.TextWriter(), function(text) { text = insertNamespaces(text); + text = removeDuplicateNamespaces(text); uriResolver.kml = parser.parseFromString(text, 'application/xml'); deferred.resolve(); }); @@ -2369,6 +2391,9 @@ define([ //Insert missing namespaces text = insertNamespaces(text); + //Remove Duplicate Namespaces + text = removeDuplicateNamespaces(text); + //IE raises an exception var kml; var error; diff --git a/Specs/Data/KML/duplicateNamespace.kml b/Specs/Data/KML/duplicateNamespace.kml new file mode 100644 index 000000000000..88fa1f21e850 --- /dev/null +++ b/Specs/Data/KML/duplicateNamespace.kml @@ -0,0 +1,18 @@ + + + + + + image.png]]> + + 1,2,3 + + + + diff --git a/Specs/Data/KML/duplicateNamespace.kmz b/Specs/Data/KML/duplicateNamespace.kmz new file mode 100644 index 000000000000..0e653a838acb Binary files /dev/null and b/Specs/Data/KML/duplicateNamespace.kmz differ diff --git a/Specs/DataSources/KmlDataSourceSpec.js b/Specs/DataSources/KmlDataSourceSpec.js index 2181216fbcd8..d3c8ea9d8972 100644 --- a/Specs/DataSources/KmlDataSourceSpec.js +++ b/Specs/DataSources/KmlDataSourceSpec.js @@ -260,6 +260,22 @@ defineSuite([ }); }); + it('load deletes duplicate namespace declaration in kml', function() { + var datasource = new KmlDataSource(options); + return datasource.load('Data/KML/duplicateNamespace.kml').then(function(source) { + expect(source).toBe(datasource); + expect(source.entities.values.length).toEqual(1); + }); + }); + + it('load deletes duplicate namespace declaration in kmz', function() { + var dataSource = new KmlDataSource(options); + return dataSource.load('Data/KML/duplicateNamespace.kmz').then(function(source) { + expect(source).toBe(dataSource); + expect(source.entities.values.length).toEqual(1); + }); + }); + it('load rejects nonexistent URL', function() { return KmlDataSource.load('test.invalid', options).otherwise(function(e) { expect(e).toBeInstanceOf(RequestErrorEvent);