Skip to content

Commit

Permalink
Merge pull request #3975 from Aviture/feature/more-tolerant-kml-proce…
Browse files Browse the repository at this point in the history
…ssing

Allow for more tolerant processing of KML
  • Loading branch information
Tom Fili authored Jun 14, 2016
2 parents 71a084f + 2048441 commit 1aa922f
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Change Log

* Add a `rotatable2D` option to to `Scene`, `CesiumWidget` and `Viewer` to enable a rotatable map in 2D. [#3897](https://github.com/AnalyticalGraphicsInc/cesium/issues/3897)
* `Camera.setView` and `Camera.flyTo` will now use the `orientation.heading` parameter in 2D if the map is rotatable.
* Made changes to KML processing that allows for some incorrect KML (specifically KML that reuses IDs) to still be parsed correctly
* Added `packArray` and `unpackArray` functions to `Cartesian2`, `Cartesian3`, and `Cartesian4`.
* Fix some large polygon triangulations. [#2788](https://github.com/AnalyticalGraphicsInc/cesium/issues/2788)
* Improved performance and accuracy of polygon triangulation by using the [earcut](https://github.com/mapbox/earcut) library. Loading a GeoJSON with polygons for each country was 2x faster.
Expand Down
17 changes: 12 additions & 5 deletions Source/DataSources/KmlDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,14 @@ define([
return url;
}

function getOrCreateEntity(node, entityCollection) {
// an optional context is passed to allow for some malformed kmls (those with multiple geometries with same ids) to still parse
// correctly, as they do in Google Earth.
function getOrCreateEntity(node, entityCollection, context) {
var id = queryStringAttribute(node, 'id');
id = defined(id) ? id : createGuid();
id = defined(id) && id.length !== 0 ? id : createGuid();
if(defined(context)){
id = context + id;
}
var entity = entityCollection.getOrCreateEntity(id);
if (!defined(entity.kml)) {
entity.addProperty('kml');
Expand Down Expand Up @@ -1286,14 +1291,14 @@ define([
return true;
}

function processMultiGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity) {
function processMultiGeometry(dataSource, entityCollection, geometryNode, entity, styleEntity, context) {
var childNodes = geometryNode.childNodes;
var hasGeometry = false;
for (var i = 0, len = childNodes.length; i < len; i++) {
var childNode = childNodes.item(i);
var geometryProcessor = geometryTypes[childNode.localName];
if (defined(geometryProcessor)) {
var childEntity = getOrCreateEntity(childNode, entityCollection);
var childEntity = getOrCreateEntity(childNode, entityCollection, context);
childEntity.parent = entity;
childEntity.name = entity.name;
childEntity.availability = entity.availability;
Expand Down Expand Up @@ -1552,7 +1557,9 @@ define([
var childNode = childNodes.item(i);
var geometryProcessor = geometryTypes[childNode.localName];
if (defined(geometryProcessor)) {
geometryProcessor(dataSource, entityCollection, childNode, entity, styleEntity);
// pass the placemark entity id as a context for case of defining multiple child entities together to handle case
// where some malformed kmls reuse the same id across placemarks, which works in GE, but is not technically to spec.
geometryProcessor(dataSource, entityCollection, childNode, entity, styleEntity, entity.id);
hasGeometry = true;
}
}
Expand Down
4 changes: 2 additions & 2 deletions Specs/DataSources/KmlDataSourceSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2938,15 +2938,15 @@ defineSuite([
var multi = entities.getById('testID');
expect(multi).toBeDefined();

var point1 = entities.getById('point1');
var point1 = entities.getById('testIDpoint1');
expect(point1).toBeDefined();
expect(point1.parent).toBe(multi);
expect(point1.name).toBe(multi.name);
expect(point1.description).toBe(multi.description);
expect(point1.kml).toBe(multi.kml);
expect(point1.position.getValue(Iso8601.MINIMUM_VALUE)).toEqualEpsilon(Cartesian3.fromDegrees(1, 2), CesiumMath.EPSILON13);

var point2 = entities.getById('point2');
var point2 = entities.getById('testIDpoint2');
expect(point2).toBeDefined();
expect(point2.parent).toBe(multi);
expect(point2.name).toBe(multi.name);
Expand Down

0 comments on commit 1aa922f

Please sign in to comment.