Cesium has this very nice Cartesian3.fromDegreesArray
function which will take a packed array of longitude and latitude values and create an array of Cartesian3
objects. I’m looking for the inverse that will take an array of Cartesian3
and create a packed array of longitude and latitude values. Does that exist or do I just have to roll my own conversion loop?
There is not a toDegressArray
helper function but it was pretty easy to roll my own:
const longLat = [];
for (const p of positions) {
const carto = Cartographic.fromCartesian(p);
longLat.push(CesiumMath.toDegrees(carto.longitude));
longLat.push(CesiumMath.toDegrees(carto.latitude));
}
Not really tested, but maybe a stub if someone wants to add something like this later:
/**
* Returns an array of longitude and latitude values, in degrees, computed from the given Cartesian3 positions array.
*
* If any of the given cartesian objects is too close to the center of the ellipsoid
* and the resulting cartographic cannot be computed, then the values in the result
* array will remain unaffected.
*
* @param {Cartesian3[]} cartesians A list of {@link Cartesian3} objects.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the target coordinates lie.
* @param {Number[]} [result] An array of numbers to store the result.
* @returns {Number[]} The array of longitude and latitide positions. If this is a typed array, it must have
* (cartesians.length * 2) components, else a {@link DeveloperError} will be thrown. If it is a regular array,
* it will be resized to have (cartesians.length * 2) elements.
*/
const toDegreesArray = function (cartesians, ellipsoid, result) {
//>>includeStart('debug', pragmas.debug);
Check.defined("cartesians", cartesians);
//>>includeEnd('debug');
const length = cartesians.length;
const resultLength = length * 2;
if (!defined(result)) {
result = new Array(resultLength);
} else if (!Array.isArray(result) && result.length !== resultLength) {
throw new DeveloperError(
"If result is a typed array, it must have exactly array.length * 2 elements"
);
} else if (result.length !== resultLength) {
result.length = resultLength;
}
const cartographicScratch = new Cartographic();
for (var i = 0; i < length; i++) {
const cartesian = cartesians[i];
const cartographic = Cartographic.fromCartesian(cartesian, ellipsoid, cartographicScratch);
if (defined(cartographic)) {
result[i * 2 + 0] = CesiumMath.toDegrees(cartographic.longitude);
result[i * 2 + 1] = CesiumMath.toDegrees(cartographic.latitude);
}
}
return result;
};
A sensible handling of the cartesians that are at the ellipsoid center may be tricky, though. And more generally, I think it could make sense to break this down further, so that the body of this function only consists of toRadiansArray(...).map(r => CesiumMath.toDegrees(r));
. But if there should be a toDegreesArrayHeights
function as well, this would require more thought.