| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 | 
							- import Cartesian3 from './Cartesian3.js';
 - import Cartographic from './Cartographic.js';
 - import defaultValue from './defaultValue.js';
 - import defined from './defined.js';
 - import DeveloperError from './DeveloperError.js';
 - import Ellipsoid from './Ellipsoid.js';
 - import EllipsoidGeodesic from './EllipsoidGeodesic.js';
 - import EllipsoidRhumbLine from './EllipsoidRhumbLine.js';
 - import IntersectionTests from './IntersectionTests.js';
 - import isArray from './isArray.js';
 - import CesiumMath from './Math.js';
 - import Matrix4 from './Matrix4.js';
 - import Plane from './Plane.js';
 - 
 -     /**
 -      * @private
 -      */
 -     var PolylinePipeline = {};
 - 
 -     PolylinePipeline.numberOfPoints = function(p0, p1, minDistance) {
 -         var distance = Cartesian3.distance(p0, p1);
 -         return Math.ceil(distance / minDistance);
 -     };
 - 
 -     PolylinePipeline.numberOfPointsRhumbLine = function(p0, p1, granularity) {
 -         var radiansDistanceSquared = Math.pow((p0.longitude - p1.longitude), 2) + Math.pow((p0.latitude - p1.latitude), 2);
 -         return Math.ceil(Math.sqrt(radiansDistanceSquared / (granularity * granularity)));
 -     };
 - 
 -     var cartoScratch = new Cartographic();
 -     PolylinePipeline.extractHeights = function(positions, ellipsoid) {
 -         var length = positions.length;
 -         var heights = new Array(length);
 -         for (var i = 0; i < length; i++) {
 -             var p = positions[i];
 -             heights[i] = ellipsoid.cartesianToCartographic(p, cartoScratch).height;
 -         }
 -         return heights;
 -     };
 - 
 -     var wrapLongitudeInversMatrix = new Matrix4();
 -     var wrapLongitudeOrigin = new Cartesian3();
 -     var wrapLongitudeXZNormal = new Cartesian3();
 -     var wrapLongitudeXZPlane = new Plane(Cartesian3.UNIT_X, 0.0);
 -     var wrapLongitudeYZNormal = new Cartesian3();
 -     var wrapLongitudeYZPlane = new Plane(Cartesian3.UNIT_X, 0.0);
 -     var wrapLongitudeIntersection = new Cartesian3();
 -     var wrapLongitudeOffset = new Cartesian3();
 - 
 -     var subdivideHeightsScratchArray = [];
 - 
 -     function subdivideHeights(numPoints, h0, h1) {
 -         var heights = subdivideHeightsScratchArray;
 -         heights.length = numPoints;
 - 
 -         var i;
 -         if (h0 === h1) {
 -             for (i = 0; i < numPoints; i++) {
 -                 heights[i] = h0;
 -             }
 -             return heights;
 -         }
 - 
 -         var dHeight = h1 - h0;
 -         var heightPerVertex = dHeight / numPoints;
 - 
 -         for (i = 0; i < numPoints; i++) {
 -             var h = h0 + i*heightPerVertex;
 -             heights[i] = h;
 -         }
 - 
 -         return heights;
 -     }
 - 
 -     var carto1 = new Cartographic();
 -     var carto2 = new Cartographic();
 -     var cartesian = new Cartesian3();
 -     var scaleFirst = new Cartesian3();
 -     var scaleLast = new Cartesian3();
 -     var ellipsoidGeodesic = new EllipsoidGeodesic();
 -     var ellipsoidRhumb = new EllipsoidRhumbLine();
 - 
 -     //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2.
 -     //Result includes p1, but not include p2.  This function is called for a sequence of line segments,
 -     //and this prevents duplication of end point.
 -     function generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, array, offset) {
 -         var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst);
 -         var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast);
 -         var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance);
 -         var start = ellipsoid.cartesianToCartographic(first, carto1);
 -         var end = ellipsoid.cartesianToCartographic(last, carto2);
 -         var heights = subdivideHeights(numPoints, h0, h1);
 - 
 -         ellipsoidGeodesic.setEndPoints(start, end);
 -         var surfaceDistanceBetweenPoints = ellipsoidGeodesic.surfaceDistance / numPoints;
 - 
 -         var index = offset;
 -         start.height = h0;
 -         var cart = ellipsoid.cartographicToCartesian(start, cartesian);
 -         Cartesian3.pack(cart, array, index);
 -         index += 3;
 - 
 -         for (var i = 1; i < numPoints; i++) {
 -             var carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2);
 -             carto.height = heights[i];
 -             cart = ellipsoid.cartographicToCartesian(carto, cartesian);
 -             Cartesian3.pack(cart, array, index);
 -             index += 3;
 -         }
 - 
 -         return index;
 -     }
 - 
 -     //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2.
 -     //Result includes p1, but not include p2.  This function is called for a sequence of line segments,
 -     //and this prevents duplication of end point.
 -     function generateCartesianRhumbArc(p0, p1, granularity, ellipsoid, h0, h1, array, offset) {
 -         var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst);
 -         var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast);
 -         var start = ellipsoid.cartesianToCartographic(first, carto1);
 -         var end = ellipsoid.cartesianToCartographic(last, carto2);
 - 
 -         var numPoints = PolylinePipeline.numberOfPointsRhumbLine(start, end, granularity);
 -         var heights = subdivideHeights(numPoints, h0, h1);
 - 
 -         if (!ellipsoidRhumb.ellipsoid.equals(ellipsoid)) {
 -             ellipsoidRhumb = new EllipsoidRhumbLine(undefined, undefined, ellipsoid);
 -         }
 -         ellipsoidRhumb.setEndPoints(start, end);
 -         var surfaceDistanceBetweenPoints = ellipsoidRhumb.surfaceDistance / numPoints;
 - 
 -         var index = offset;
 -         start.height = h0;
 -         var cart = ellipsoid.cartographicToCartesian(start, cartesian);
 -         Cartesian3.pack(cart, array, index);
 -         index += 3;
 - 
 -         for (var i = 1; i < numPoints; i++) {
 -             var carto = ellipsoidRhumb.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2);
 -             carto.height = heights[i];
 -             cart = ellipsoid.cartographicToCartesian(carto, cartesian);
 -             Cartesian3.pack(cart, array, index);
 -             index += 3;
 -         }
 - 
 -         return index;
 -     }
 - 
 -     /**
 -      * Breaks a {@link Polyline} into segments such that it does not cross the ±180 degree meridian of an ellipsoid.
 -      *
 -      * @param {Cartesian3[]} positions The polyline's Cartesian positions.
 -      * @param {Matrix4} [modelMatrix=Matrix4.IDENTITY] The polyline's model matrix. Assumed to be an affine
 -      * transformation matrix, where the upper left 3x3 elements are a rotation matrix, and
 -      * the upper three elements in the fourth column are the translation.  The bottom row is assumed to be [0, 0, 0, 1].
 -      * The matrix is not verified to be in the proper form.
 -      * @returns {Object} An object with a <code>positions</code> property that is an array of positions and a
 -      * <code>segments</code> property.
 -      *
 -      *
 -      * @example
 -      * var polylines = new Cesium.PolylineCollection();
 -      * var polyline = polylines.add(...);
 -      * var positions = polyline.positions;
 -      * var modelMatrix = polylines.modelMatrix;
 -      * var segments = Cesium.PolylinePipeline.wrapLongitude(positions, modelMatrix);
 -      *
 -      * @see PolygonPipeline.wrapLongitude
 -      * @see Polyline
 -      * @see PolylineCollection
 -      */
 -     PolylinePipeline.wrapLongitude = function(positions, modelMatrix) {
 -         var cartesians = [];
 -         var segments = [];
 - 
 -         if (defined(positions) && positions.length > 0) {
 -             modelMatrix = defaultValue(modelMatrix, Matrix4.IDENTITY);
 -             var inverseModelMatrix = Matrix4.inverseTransformation(modelMatrix, wrapLongitudeInversMatrix);
 - 
 -             var origin = Matrix4.multiplyByPoint(inverseModelMatrix, Cartesian3.ZERO, wrapLongitudeOrigin);
 -             var xzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_Y, wrapLongitudeXZNormal), wrapLongitudeXZNormal);
 -             var xzPlane = Plane.fromPointNormal(origin, xzNormal, wrapLongitudeXZPlane);
 -             var yzNormal = Cartesian3.normalize(Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian3.UNIT_X, wrapLongitudeYZNormal), wrapLongitudeYZNormal);
 -             var yzPlane = Plane.fromPointNormal(origin, yzNormal, wrapLongitudeYZPlane);
 - 
 -             var count = 1;
 -             cartesians.push(Cartesian3.clone(positions[0]));
 -             var prev = cartesians[0];
 - 
 -             var length = positions.length;
 -             for (var i = 1; i < length; ++i) {
 -                 var cur = positions[i];
 - 
 -                 // intersects the IDL if either endpoint is on the negative side of the yz-plane
 -                 if (Plane.getPointDistance(yzPlane, prev) < 0.0 || Plane.getPointDistance(yzPlane, cur) < 0.0) {
 -                     // and intersects the xz-plane
 -                     var intersection = IntersectionTests.lineSegmentPlane(prev, cur, xzPlane, wrapLongitudeIntersection);
 -                     if (defined(intersection)) {
 -                         // move point on the xz-plane slightly away from the plane
 -                         var offset = Cartesian3.multiplyByScalar(xzNormal, 5.0e-9, wrapLongitudeOffset);
 -                         if (Plane.getPointDistance(xzPlane, prev) < 0.0) {
 -                             Cartesian3.negate(offset, offset);
 -                         }
 - 
 -                         cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3()));
 -                         segments.push(count + 1);
 - 
 -                         Cartesian3.negate(offset, offset);
 -                         cartesians.push(Cartesian3.add(intersection, offset, new Cartesian3()));
 -                         count = 1;
 -                     }
 -                 }
 - 
 -                 cartesians.push(Cartesian3.clone(positions[i]));
 -                 count++;
 - 
 -                 prev = cur;
 -             }
 - 
 -             segments.push(count);
 -         }
 - 
 -         return {
 -             positions : cartesians,
 -             lengths : segments
 -         };
 -     };
 - 
 -     /**
 -      * Subdivides polyline and raises all points to the specified height.  Returns an array of numbers to represent the positions.
 -      * @param {Object} options Object with the following properties:
 -      * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
 -      * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
 -      * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
 -      * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
 -      * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid.
 -      *
 -      * @example
 -      * var positions = Cesium.Cartesian3.fromDegreesArray([
 -      *   -105.0, 40.0,
 -      *   -100.0, 38.0,
 -      *   -105.0, 35.0,
 -      *   -100.0, 32.0
 -      * ]);
 -      * var surfacePositions = Cesium.PolylinePipeline.generateArc({
 -      *   positons: positions
 -      * });
 -      */
 -     PolylinePipeline.generateArc = function(options) {
 -         if (!defined(options)) {
 -             options = {};
 -         }
 -         var positions = options.positions;
 -         //>>includeStart('debug', pragmas.debug);
 -         if (!defined(positions)) {
 -             throw new DeveloperError('options.positions is required.');
 -         }
 -         //>>includeEnd('debug');
 - 
 -         var length = positions.length;
 -         var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
 -         var height = defaultValue(options.height, 0);
 -         var hasHeightArray = isArray(height);
 - 
 -         if (length < 1) {
 -             return [];
 -         } else if (length === 1) {
 -             var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
 -             height = hasHeightArray ? height[0] : height;
 -             if (height !== 0) {
 -                 var n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
 -                 Cartesian3.multiplyByScalar(n, height, n);
 -                 Cartesian3.add(p, n, p);
 -             }
 - 
 -             return [p.x, p.y, p.z];
 -         }
 - 
 -         var minDistance = options.minDistance;
 -         if (!defined(minDistance)) {
 -             var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE);
 -             minDistance = CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
 -         }
 - 
 -         var numPoints = 0;
 -         var i;
 - 
 -         for (i = 0; i < length -1; i++) {
 -             numPoints += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance);
 -         }
 - 
 -         var arrayLength = (numPoints + 1) * 3;
 -         var newPositions = new Array(arrayLength);
 -         var offset = 0;
 - 
 -         for (i = 0; i < length - 1; i++) {
 -             var p0 = positions[i];
 -             var p1 = positions[i + 1];
 - 
 -             var h0 = hasHeightArray ? height[i] : height;
 -             var h1 = hasHeightArray ? height[i + 1] : height;
 - 
 -             offset = generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, newPositions, offset);
 -         }
 - 
 -         subdivideHeightsScratchArray.length = 0;
 - 
 -         var lastPoint = positions[length - 1];
 -         var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
 -         carto.height = hasHeightArray ? height[length - 1] : height;
 -         var cart = ellipsoid.cartographicToCartesian(carto, cartesian);
 -         Cartesian3.pack(cart, newPositions, arrayLength - 3);
 - 
 -         return newPositions;
 -     };
 - 
 -     var scratchCartographic0 = new Cartographic();
 -     var scratchCartographic1 = new Cartographic();
 - 
 -     /**
 -      * Subdivides polyline and raises all points to the specified height using Rhumb lines.  Returns an array of numbers to represent the positions.
 -      * @param {Object} options Object with the following properties:
 -      * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
 -      * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
 -      * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
 -      * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
 -      * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid.
 -      *
 -      * @example
 -      * var positions = Cesium.Cartesian3.fromDegreesArray([
 -      *   -105.0, 40.0,
 -      *   -100.0, 38.0,
 -      *   -105.0, 35.0,
 -      *   -100.0, 32.0
 -      * ]);
 -      * var surfacePositions = Cesium.PolylinePipeline.generateRhumbArc({
 -      *   positons: positions
 -      * });
 -      */
 -     PolylinePipeline.generateRhumbArc = function(options) {
 -         if (!defined(options)) {
 -             options = {};
 -         }
 -         var positions = options.positions;
 -         //>>includeStart('debug', pragmas.debug);
 -         if (!defined(positions)) {
 -             throw new DeveloperError('options.positions is required.');
 -         }
 -         //>>includeEnd('debug');
 - 
 -         var length = positions.length;
 -         var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
 -         var height = defaultValue(options.height, 0);
 -         var hasHeightArray = isArray(height);
 - 
 -         if (length < 1) {
 -             return [];
 -         } else if (length === 1) {
 -             var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
 -             height = hasHeightArray ? height[0] : height;
 -             if (height !== 0) {
 -                 var n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
 -                 Cartesian3.multiplyByScalar(n, height, n);
 -                 Cartesian3.add(p, n, p);
 -             }
 - 
 -             return [p.x, p.y, p.z];
 -         }
 - 
 -         var granularity = defaultValue(options.granularity, CesiumMath.RADIANS_PER_DEGREE);
 - 
 -         var numPoints = 0;
 -         var i;
 - 
 -         var c0 = ellipsoid.cartesianToCartographic(positions[0], scratchCartographic0);
 -         var c1;
 -         for (i = 0; i < length - 1; i++) {
 -             c1 = ellipsoid.cartesianToCartographic(positions[i + 1], scratchCartographic1);
 -             numPoints += PolylinePipeline.numberOfPointsRhumbLine(c0, c1, granularity);
 -             c0 = Cartographic.clone(c1, scratchCartographic0);
 -         }
 - 
 -         var arrayLength = (numPoints + 1) * 3;
 -         var newPositions = new Array(arrayLength);
 -         var offset = 0;
 - 
 -         for (i = 0; i < length - 1; i++) {
 -             var p0 = positions[i];
 -             var p1 = positions[i + 1];
 - 
 -             var h0 = hasHeightArray ? height[i] : height;
 -             var h1 = hasHeightArray ? height[i + 1] : height;
 - 
 -             offset = generateCartesianRhumbArc(p0, p1, granularity, ellipsoid, h0, h1, newPositions, offset);
 -         }
 - 
 -         subdivideHeightsScratchArray.length = 0;
 - 
 -         var lastPoint = positions[length - 1];
 -         var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
 -         carto.height = hasHeightArray ? height[length - 1] : height;
 -         var cart = ellipsoid.cartographicToCartesian(carto, cartesian);
 -         Cartesian3.pack(cart, newPositions, arrayLength - 3);
 - 
 -         return newPositions;
 -     };
 - 
 -     /**
 -      * Subdivides polyline and raises all points to the specified height. Returns an array of new {Cartesian3} positions.
 -      * @param {Object} options Object with the following properties:
 -      * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
 -      * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
 -      * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
 -      * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
 -      * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid.
 -      *
 -      * @example
 -      * var positions = Cesium.Cartesian3.fromDegreesArray([
 -      *   -105.0, 40.0,
 -      *   -100.0, 38.0,
 -      *   -105.0, 35.0,
 -      *   -100.0, 32.0
 -      * ]);
 -      * var surfacePositions = Cesium.PolylinePipeline.generateCartesianArc({
 -      *   positons: positions
 -      * });
 -      */
 -     PolylinePipeline.generateCartesianArc = function(options) {
 -         var numberArray = PolylinePipeline.generateArc(options);
 -         var size = numberArray.length/3;
 -         var newPositions = new Array(size);
 -         for (var i = 0; i < size; i++) {
 -             newPositions[i] = Cartesian3.unpack(numberArray, i*3);
 -         }
 -         return newPositions;
 -     };
 - 
 -     /**
 -      * Subdivides polyline and raises all points to the specified height using Rhumb Lines. Returns an array of new {Cartesian3} positions.
 -      * @param {Object} options Object with the following properties:
 -      * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
 -      * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
 -      * @param {Number} [options.granularity = CesiumMath.RADIANS_PER_DEGREE] The distance, in radians, between each latitude and longitude. Determines the number of positions in the buffer.
 -      * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
 -      * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid.
 -      *
 -      * @example
 -      * var positions = Cesium.Cartesian3.fromDegreesArray([
 -      *   -105.0, 40.0,
 -      *   -100.0, 38.0,
 -      *   -105.0, 35.0,
 -      *   -100.0, 32.0
 -      * ]);
 -      * var surfacePositions = Cesium.PolylinePipeline.generateCartesianRhumbArc({
 -      *   positons: positions
 -      * });
 -      */
 -     PolylinePipeline.generateCartesianRhumbArc = function(options) {
 -         var numberArray = PolylinePipeline.generateRhumbArc(options);
 -         var size = numberArray.length/3;
 -         var newPositions = new Array(size);
 -         for (var i = 0; i < size; i++) {
 -             newPositions[i] = Cartesian3.unpack(numberArray, i*3);
 -         }
 -         return newPositions;
 -     };
 - export default PolylinePipeline;
 
 
  |