Skip to content

Commit

Permalink
Merge pull request #4024 from AnalyticalGraphicsInc/timeVaryingWallHe…
Browse files Browse the repository at this point in the history
…ight

Allow time-varying wall min/max height via CZML
  • Loading branch information
mramato authored Jun 16, 2016
2 parents fd35ce7 + 99035a9 commit c9443d1
Show file tree
Hide file tree
Showing 4 changed files with 226 additions and 115 deletions.
111 changes: 71 additions & 40 deletions Source/Core/Cartesian3.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ define([
};

/**
* Flattens an array of Cartesian3s into and array of components.
* Flattens an array of Cartesian3s into an array of components.
*
* @param {Cartesian3[]} array The array of cartesians to pack.
* @param {Number[]} result The array onto which to store the result.
Expand All @@ -214,7 +214,7 @@ define([
};

/**
* Unpacks an array of cartesian components into and array of Cartesian3s.
* Unpacks an array of cartesian components into an array of Cartesian3s.
*
* @param {Number[]} array The array of components to unpack.
* @param {Cartesian3[]} result The array onto which to store the result.
Expand All @@ -225,6 +225,12 @@ define([
if (!defined(array)) {
throw new DeveloperError('array is required');
}
if (array.length < 3) {
throw new DeveloperError('array length cannot be less than 3.');
}
if (array.length % 3 !== 0) {
throw new DeveloperError('array length must be a multiple of 3.');
}
//>>includeEnd('debug');

var length = array.length;
Expand Down Expand Up @@ -849,9 +855,9 @@ define([
}
//>>includeEnd('debug');

var lon = CesiumMath.toRadians(longitude);
var lat = CesiumMath.toRadians(latitude);
return Cartesian3.fromRadians(lon, lat, height, ellipsoid, result);
longitude = CesiumMath.toRadians(longitude);
latitude = CesiumMath.toRadians(latitude);
return Cartesian3.fromRadians(longitude, latitude, height, ellipsoid, result);
};

var scratchN = new Cartesian3();
Expand Down Expand Up @@ -915,16 +921,31 @@ define([
Cartesian3.fromDegreesArray = function(coordinates, ellipsoid, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(coordinates)) {
throw new DeveloperError('positions is required.');
throw new DeveloperError('coordinates is required.');
}
if (coordinates.length < 2) {
throw new DeveloperError('coordinates length cannot be less than 2.');
}
if (coordinates.length % 2 !== 0) {
throw new DeveloperError('coordinates length must be a multiple of 2.');
}
//>>includeEnd('debug');

var pos = new Array(coordinates.length);
for (var i = 0; i < coordinates.length; i++) {
pos[i] = CesiumMath.toRadians(coordinates[i]);
var length = coordinates.length;
if (!defined(result)) {
result = new Array(length / 2);
} else {
result.length = length / 2;
}

for (var i = 0; i < length; i += 2) {
var longitude = coordinates[i];
var latitude = coordinates[i + 1];
var index = i / 2;
result[index] = Cartesian3.fromDegrees(longitude, latitude, 0, ellipsoid, result[index]);
}

return Cartesian3.fromRadiansArray(pos, ellipsoid, result);
return result;
};

/**
Expand All @@ -941,27 +962,28 @@ define([
Cartesian3.fromRadiansArray = function(coordinates, ellipsoid, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(coordinates)) {
throw new DeveloperError('positions is required.');
throw new DeveloperError('coordinates is required.');
}
if (coordinates.length < 2) {
throw new DeveloperError('positions length cannot be less than 2.');
throw new DeveloperError('coordinates length cannot be less than 2.');
}
if (coordinates.length % 2 !== 0) {
throw new DeveloperError('positions length must be a multiple of 2.');
throw new DeveloperError('coordinates length must be a multiple of 2.');
}
//>>includeEnd('debug');

var length = coordinates.length;
if (!defined(result)) {
result = new Array(length/2);
result = new Array(length / 2);
} else {
result.length = length/2;
result.length = length / 2;
}

for ( var i = 0; i < length; i+=2) {
var lon = coordinates[i];
var lat = coordinates[i+1];
result[i/2] = Cartesian3.fromRadians(lon, lat, 0, ellipsoid, result[i/2]);
for (var i = 0; i < length; i += 2) {
var longitude = coordinates[i];
var latitude = coordinates[i + 1];
var index = i / 2;
result[index] = Cartesian3.fromRadians(longitude, latitude, 0, ellipsoid, result[index]);
}

return result;
Expand All @@ -970,7 +992,7 @@ define([
/**
* Returns an array of Cartesian3 positions given an array of longitude, latitude and height values where longitude and latitude are given in degrees.
*
* @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height,, longitude, latitude, height...].
* @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...].
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies.
* @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result.
* @returns {Cartesian3[]} The array of positions.
Expand All @@ -981,30 +1003,38 @@ define([
Cartesian3.fromDegreesArrayHeights = function(coordinates, ellipsoid, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(coordinates)) {
throw new DeveloperError('positions is required.');
throw new DeveloperError('coordinates is required.');
}
if (coordinates.length < 3) {
throw new DeveloperError('positions length cannot be less than 3.');
throw new DeveloperError('coordinates length cannot be less than 3.');
}
if (coordinates.length % 3 !== 0) {
throw new DeveloperError('positions length must be a multiple of 3.');
throw new DeveloperError('coordinates length must be a multiple of 3.');
}
//>>includeEnd('debug');

var pos = new Array(coordinates.length);
for (var i = 0; i < coordinates.length; i+=3) {
pos[i] = CesiumMath.toRadians(coordinates[i]);
pos[i+1] = CesiumMath.toRadians(coordinates[i+1]);
pos[i+2] = coordinates[i+2];
var length = coordinates.length;
if (!defined(result)) {
result = new Array(length / 3);
} else {
result.length = length / 3;
}

for (var i = 0; i < length; i += 3) {
var longitude = coordinates[i];
var latitude = coordinates[i + 1];
var height = coordinates[i + 2];
var index = i / 3;
result[index] = Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result[index]);
}

return Cartesian3.fromRadiansArrayHeights(pos, ellipsoid, result);
return result;
};

/**
* Returns an array of Cartesian3 positions given an array of longitude, latitude and height values where longitude and latitude are given in radians.
*
* @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height,, longitude, latitude, height...].
* @param {Number[]} coordinates A list of longitude, latitude and height values. Values alternate [longitude, latitude, height, longitude, latitude, height...].
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the position lies.
* @param {Cartesian3[]} [result] An array of Cartesian3 objects to store the result.
* @returns {Cartesian3[]} The array of positions.
Expand All @@ -1015,28 +1045,29 @@ define([
Cartesian3.fromRadiansArrayHeights = function(coordinates, ellipsoid, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(coordinates)) {
throw new DeveloperError('positions is required.');
throw new DeveloperError('coordinates is required.');
}
if (coordinates.length < 3) {
throw new DeveloperError('positions length cannot be less than 3.');
throw new DeveloperError('coordinates length cannot be less than 3.');
}
if (coordinates.length % 3 !== 0) {
throw new DeveloperError('positions length must be a multiple of 3.');
throw new DeveloperError('coordinates length must be a multiple of 3.');
}
//>>includeEnd('debug');

var length = coordinates.length;
if (!defined(result)) {
result = new Array(length/3);
result = new Array(length / 3);
} else {
result.length = length/3;
result.length = length / 3;
}

for ( var i = 0; i < length; i+=3) {
var lon = coordinates[i];
var lat = coordinates[i+1];
var alt = coordinates[i+2];
result[i/3] = Cartesian3.fromRadians(lon, lat, alt, ellipsoid, result[i/3]);
for (var i = 0; i < length; i += 3) {
var longitude = coordinates[i];
var latitude = coordinates[i + 1];
var height = coordinates[i + 2];
var index = i / 3;
result[index] = Cartesian3.fromRadians(longitude, latitude, height, ellipsoid, result[index]);
}

return result;
Expand Down
94 changes: 55 additions & 39 deletions Source/DataSources/CzmlDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ define([
'./PolylineGraphics',
'./PolylineOutlineMaterialProperty',
'./PositionPropertyArray',
'./PropertyArray',
'./PropertyBag',
'./RectangleGraphics',
'./ReferenceProperty',
Expand Down Expand Up @@ -142,6 +143,7 @@ define([
PolylineGraphics,
PolylineOutlineMaterialProperty,
PositionPropertyArray,
PropertyArray,
PropertyBag,
RectangleGraphics,
ReferenceProperty,
Expand Down Expand Up @@ -901,15 +903,49 @@ define([
}
}

function processVertexData(object, propertyName, positionsData, entityCollection) {
var i;
var len;
var references = positionsData.references;
function processArrayPacketData(object, propertyName, packetData, entityCollection) {
var references = packetData.references;
if (defined(references)) {
var properties = [];
for (i = 0, len = references.length; i < len; i++) {
properties.push(makeReference(entityCollection, references[i]));
var properties = references.map(function(reference) {
return makeReference(entityCollection, reference);
});

var iso8601Interval = packetData.interval;
if (defined(iso8601Interval)) {
iso8601Interval = TimeInterval.fromIso8601(iso8601Interval);
if (!(object[propertyName] instanceof CompositePositionProperty)) {
iso8601Interval.data = new PropertyArray(properties);
var property = new CompositeProperty();
property.intervals.addInterval(iso8601Interval);
object[propertyName] = property;
}
} else {
object[propertyName] = new PropertyArray(properties);
}
} else {
processPacketData(Array, object, propertyName, packetData, undefined, undefined, entityCollection);
}
}

function processArray(object, propertyName, packetData, entityCollection) {
if (!defined(packetData)) {
return;
}

if (isArray(packetData)) {
for (var i = 0, length = packetData.length; i < length; ++i) {
processArrayPacketData(object, propertyName, packetData[i], entityCollection);
}
} else {
processArrayPacketData(object, propertyName, packetData, entityCollection);
}
}

function processPositionsPacketData(object, propertyName, positionsData, entityCollection) {
if (defined(positionsData.references)) {
var properties = positionsData.references.map(function(reference) {
return makeReference(entityCollection, reference);
});

var iso8601Interval = positionsData.interval;
if (defined(iso8601Interval)) {
Expand All @@ -924,33 +960,14 @@ define([
object[propertyName] = new PositionPropertyArray(properties);
}
} else {
var values = [];
var tmp = positionsData.cartesian;
if (defined(tmp)) {
for (i = 0, len = tmp.length; i < len; i += 3) {
values.push(new Cartesian3(tmp[i], tmp[i + 1], tmp[i + 2]));
}
positionsData.array = values;
} else {
tmp = positionsData.cartographicRadians;
if (defined(tmp)) {
for (i = 0, len = tmp.length; i < len; i += 3) {
scratchCartographic.longitude = tmp[i];
scratchCartographic.latitude = tmp[i + 1];
scratchCartographic.height = tmp[i + 2];
values.push(Ellipsoid.WGS84.cartographicToCartesian(scratchCartographic));
}
positionsData.array = values;
} else {
tmp = positionsData.cartographicDegrees;
if (defined(tmp)) {
for (i = 0, len = tmp.length; i < len; i += 3) {
values.push(Cartesian3.fromDegrees(tmp[i], tmp[i + 1], tmp[i + 2]));
}
positionsData.array = values;
}
}
if (defined(positionsData.cartesian)) {
positionsData.array = Cartesian3.unpackArray(positionsData.cartesian);
} else if (defined(positionsData.cartographicRadians)) {
positionsData.array = Cartesian3.fromRadiansArrayHeights(positionsData.cartographicRadians);
} else if (defined(positionsData.cartographicDegrees)) {
positionsData.array = Cartesian3.fromDegreesArrayHeights(positionsData.cartographicDegrees);
}

if (defined(positionsData.array)) {
processPacketData(Array, object, propertyName, positionsData, undefined, undefined, entityCollection);
}
Expand All @@ -963,12 +980,11 @@ define([
}

if (isArray(positionsData)) {
var length = positionsData.length;
for (var i = 0; i < length; i++) {
processVertexData(object, propertyName, positionsData[i], entityCollection);
for (var i = 0, length = positionsData.length; i < length; i++) {
processPositionsPacketData(object, propertyName, positionsData[i], entityCollection);
}
} else {
processVertexData(object, propertyName, positionsData, entityCollection);
processPositionsPacketData(object, propertyName, positionsData, entityCollection);
}
}

Expand Down Expand Up @@ -1514,8 +1530,8 @@ define([

processPacketData(Boolean, wall, 'show', wallData.show, interval, sourceUri, entityCollection);
processPositions(wall, 'positions', wallData.positions, entityCollection);
processPacketData(Array, wall, 'minimumHeights', wallData.minimumHeights, interval, sourceUri, entityCollection);
processPacketData(Array, wall, 'maximumHeights', wallData.maximumHeights, interval, sourceUri, entityCollection);
processArray(wall, 'minimumHeights', wallData.minimumHeights, entityCollection);
processArray(wall, 'maximumHeights', wallData.maximumHeights, entityCollection);
processPacketData(Number, wall, 'granularity', wallData.granularity, interval, sourceUri, entityCollection);
processPacketData(Boolean, wall, 'fill', wallData.fill, interval, sourceUri, entityCollection);
processMaterialPacketData(wall, 'material', wallData.material, interval, sourceUri, entityCollection);
Expand Down
29 changes: 29 additions & 0 deletions Specs/Core/Cartesian3Spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,35 @@ defineSuite([
}).toThrowDeveloperError();
});

it('unpackArray works', function() {
var array = Cartesian3.unpackArray([0.0, 1.0, 2.0, 3.0, 0.0, 4.0]);
expect(array).toEqual([new Cartesian3(0.0, 1.0, 2.0), new Cartesian3(3.0, 0.0, 4.0)]);
});

it('unpackArray works with a result parameter', function() {
var array = [];
var result = Cartesian3.unpackArray([1.0, 2.0, 3.0], array);
expect(result).toBe(array);
expect(result).toEqual([new Cartesian3(1.0, 2.0, 3.0)]);

array = [new Cartesian3(), new Cartesian3(), new Cartesian3()];
result = Cartesian3.unpackArray([1.0, 2.0, 3.0], array);
expect(result).toBe(array);
expect(result).toEqual([new Cartesian3(1.0, 2.0, 3.0)]);
});

it('unpackArray throws with array less than 3 length', function() {
expect(function() {
Cartesian3.unpackArray([1.0]);
}).toThrowDeveloperError();
});

it('unpackArray throws with array not multiple of 3', function() {
expect(function() {
Cartesian3.unpackArray([1.0, 2.0, 3.0, 4.0]);
}).toThrowDeveloperError();
});

it('clone with a result parameter', function() {
var cartesian = new Cartesian3(1.0, 2.0, 3.0);
var result = new Cartesian3();
Expand Down
Loading

0 comments on commit c9443d1

Please sign in to comment.