123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598 |
- /**
- * @license
- * Cesium - https://github.com/CesiumGS/cesium
- * Version 1.95
- *
- * Copyright 2011-2022 Cesium Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * Columbus View (Pat. Pend.)
- *
- * Portions licensed separately.
- * See https://github.com/CesiumGS/cesium/blob/main/LICENSE.md for full licensing details.
- */
- define(['exports', './Matrix2-9e1c22e2', './defaultValue-97284df2', './RuntimeError-4f8ec8a2', './EllipsoidGeodesic-72f01b70', './EllipsoidRhumbLine-7bc7dfce', './IntersectionTests-ea138127', './ComponentDatatype-4eeb6d9b', './Plane-76b84425'], (function (exports, Matrix2, defaultValue, RuntimeError, EllipsoidGeodesic, EllipsoidRhumbLine, IntersectionTests, ComponentDatatype, Plane) { 'use strict';
- /**
- * @private
- */
- const PolylinePipeline = {};
- PolylinePipeline.numberOfPoints = function (p0, p1, minDistance) {
- const distance = Matrix2.Cartesian3.distance(p0, p1);
- return Math.ceil(distance / minDistance);
- };
- PolylinePipeline.numberOfPointsRhumbLine = function (p0, p1, granularity) {
- const radiansDistanceSquared =
- Math.pow(p0.longitude - p1.longitude, 2) +
- Math.pow(p0.latitude - p1.latitude, 2);
- return Math.max(
- 1,
- Math.ceil(Math.sqrt(radiansDistanceSquared / (granularity * granularity)))
- );
- };
- const cartoScratch = new Matrix2.Cartographic();
- PolylinePipeline.extractHeights = function (positions, ellipsoid) {
- const length = positions.length;
- const heights = new Array(length);
- for (let i = 0; i < length; i++) {
- const p = positions[i];
- heights[i] = ellipsoid.cartesianToCartographic(p, cartoScratch).height;
- }
- return heights;
- };
- const wrapLongitudeInversMatrix = new Matrix2.Matrix4();
- const wrapLongitudeOrigin = new Matrix2.Cartesian3();
- const wrapLongitudeXZNormal = new Matrix2.Cartesian3();
- const wrapLongitudeXZPlane = new Plane.Plane(Matrix2.Cartesian3.UNIT_X, 0.0);
- const wrapLongitudeYZNormal = new Matrix2.Cartesian3();
- const wrapLongitudeYZPlane = new Plane.Plane(Matrix2.Cartesian3.UNIT_X, 0.0);
- const wrapLongitudeIntersection = new Matrix2.Cartesian3();
- const wrapLongitudeOffset = new Matrix2.Cartesian3();
- const subdivideHeightsScratchArray = [];
- function subdivideHeights(numPoints, h0, h1) {
- const heights = subdivideHeightsScratchArray;
- heights.length = numPoints;
- let i;
- if (h0 === h1) {
- for (i = 0; i < numPoints; i++) {
- heights[i] = h0;
- }
- return heights;
- }
- const dHeight = h1 - h0;
- const heightPerVertex = dHeight / numPoints;
- for (i = 0; i < numPoints; i++) {
- const h = h0 + i * heightPerVertex;
- heights[i] = h;
- }
- return heights;
- }
- const carto1 = new Matrix2.Cartographic();
- const carto2 = new Matrix2.Cartographic();
- const cartesian = new Matrix2.Cartesian3();
- const scaleFirst = new Matrix2.Cartesian3();
- const scaleLast = new Matrix2.Cartesian3();
- const ellipsoidGeodesic = new EllipsoidGeodesic.EllipsoidGeodesic();
- let ellipsoidRhumb = new EllipsoidRhumbLine.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
- ) {
- const first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst);
- const last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast);
- const numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance);
- const start = ellipsoid.cartesianToCartographic(first, carto1);
- const end = ellipsoid.cartesianToCartographic(last, carto2);
- const heights = subdivideHeights(numPoints, h0, h1);
- ellipsoidGeodesic.setEndPoints(start, end);
- const surfaceDistanceBetweenPoints =
- ellipsoidGeodesic.surfaceDistance / numPoints;
- let index = offset;
- start.height = h0;
- let cart = ellipsoid.cartographicToCartesian(start, cartesian);
- Matrix2.Cartesian3.pack(cart, array, index);
- index += 3;
- for (let i = 1; i < numPoints; i++) {
- const carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(
- i * surfaceDistanceBetweenPoints,
- carto2
- );
- carto.height = heights[i];
- cart = ellipsoid.cartographicToCartesian(carto, cartesian);
- Matrix2.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
- ) {
- const start = ellipsoid.cartesianToCartographic(p0, carto1);
- const end = ellipsoid.cartesianToCartographic(p1, carto2);
- const numPoints = PolylinePipeline.numberOfPointsRhumbLine(
- start,
- end,
- granularity
- );
- start.height = 0.0;
- end.height = 0.0;
- const heights = subdivideHeights(numPoints, h0, h1);
- if (!ellipsoidRhumb.ellipsoid.equals(ellipsoid)) {
- ellipsoidRhumb = new EllipsoidRhumbLine.EllipsoidRhumbLine(undefined, undefined, ellipsoid);
- }
- ellipsoidRhumb.setEndPoints(start, end);
- const surfaceDistanceBetweenPoints =
- ellipsoidRhumb.surfaceDistance / numPoints;
- let index = offset;
- start.height = h0;
- let cart = ellipsoid.cartographicToCartesian(start, cartesian);
- Matrix2.Cartesian3.pack(cart, array, index);
- index += 3;
- for (let i = 1; i < numPoints; i++) {
- const carto = ellipsoidRhumb.interpolateUsingSurfaceDistance(
- i * surfaceDistanceBetweenPoints,
- carto2
- );
- carto.height = heights[i];
- cart = ellipsoid.cartographicToCartesian(carto, cartesian);
- Matrix2.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
- * const polylines = new Cesium.PolylineCollection();
- * const polyline = polylines.add(...);
- * const positions = polyline.positions;
- * const modelMatrix = polylines.modelMatrix;
- * const segments = Cesium.PolylinePipeline.wrapLongitude(positions, modelMatrix);
- *
- * @see PolygonPipeline.wrapLongitude
- * @see Polyline
- * @see PolylineCollection
- */
- PolylinePipeline.wrapLongitude = function (positions, modelMatrix) {
- const cartesians = [];
- const segments = [];
- if (defaultValue.defined(positions) && positions.length > 0) {
- modelMatrix = defaultValue.defaultValue(modelMatrix, Matrix2.Matrix4.IDENTITY);
- const inverseModelMatrix = Matrix2.Matrix4.inverseTransformation(
- modelMatrix,
- wrapLongitudeInversMatrix
- );
- const origin = Matrix2.Matrix4.multiplyByPoint(
- inverseModelMatrix,
- Matrix2.Cartesian3.ZERO,
- wrapLongitudeOrigin
- );
- const xzNormal = Matrix2.Cartesian3.normalize(
- Matrix2.Matrix4.multiplyByPointAsVector(
- inverseModelMatrix,
- Matrix2.Cartesian3.UNIT_Y,
- wrapLongitudeXZNormal
- ),
- wrapLongitudeXZNormal
- );
- const xzPlane = Plane.Plane.fromPointNormal(
- origin,
- xzNormal,
- wrapLongitudeXZPlane
- );
- const yzNormal = Matrix2.Cartesian3.normalize(
- Matrix2.Matrix4.multiplyByPointAsVector(
- inverseModelMatrix,
- Matrix2.Cartesian3.UNIT_X,
- wrapLongitudeYZNormal
- ),
- wrapLongitudeYZNormal
- );
- const yzPlane = Plane.Plane.fromPointNormal(
- origin,
- yzNormal,
- wrapLongitudeYZPlane
- );
- let count = 1;
- cartesians.push(Matrix2.Cartesian3.clone(positions[0]));
- let prev = cartesians[0];
- const length = positions.length;
- for (let i = 1; i < length; ++i) {
- const cur = positions[i];
- // intersects the IDL if either endpoint is on the negative side of the yz-plane
- if (
- Plane.Plane.getPointDistance(yzPlane, prev) < 0.0 ||
- Plane.Plane.getPointDistance(yzPlane, cur) < 0.0
- ) {
- // and intersects the xz-plane
- const intersection = IntersectionTests.IntersectionTests.lineSegmentPlane(
- prev,
- cur,
- xzPlane,
- wrapLongitudeIntersection
- );
- if (defaultValue.defined(intersection)) {
- // move point on the xz-plane slightly away from the plane
- const offset = Matrix2.Cartesian3.multiplyByScalar(
- xzNormal,
- 5.0e-9,
- wrapLongitudeOffset
- );
- if (Plane.Plane.getPointDistance(xzPlane, prev) < 0.0) {
- Matrix2.Cartesian3.negate(offset, offset);
- }
- cartesians.push(
- Matrix2.Cartesian3.add(intersection, offset, new Matrix2.Cartesian3())
- );
- segments.push(count + 1);
- Matrix2.Cartesian3.negate(offset, offset);
- cartesians.push(
- Matrix2.Cartesian3.add(intersection, offset, new Matrix2.Cartesian3())
- );
- count = 1;
- }
- }
- cartesians.push(Matrix2.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
- * const positions = Cesium.Cartesian3.fromDegreesArray([
- * -105.0, 40.0,
- * -100.0, 38.0,
- * -105.0, 35.0,
- * -100.0, 32.0
- * ]);
- * const surfacePositions = Cesium.PolylinePipeline.generateArc({
- * positons: positions
- * });
- */
- PolylinePipeline.generateArc = function (options) {
- if (!defaultValue.defined(options)) {
- options = {};
- }
- const positions = options.positions;
- //>>includeStart('debug', pragmas.debug);
- if (!defaultValue.defined(positions)) {
- throw new RuntimeError.DeveloperError("options.positions is required.");
- }
- //>>includeEnd('debug');
- const length = positions.length;
- const ellipsoid = defaultValue.defaultValue(options.ellipsoid, Matrix2.Ellipsoid.WGS84);
- let height = defaultValue.defaultValue(options.height, 0);
- const hasHeightArray = Array.isArray(height);
- if (length < 1) {
- return [];
- } else if (length === 1) {
- const p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
- height = hasHeightArray ? height[0] : height;
- if (height !== 0) {
- const n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
- Matrix2.Cartesian3.multiplyByScalar(n, height, n);
- Matrix2.Cartesian3.add(p, n, p);
- }
- return [p.x, p.y, p.z];
- }
- let minDistance = options.minDistance;
- if (!defaultValue.defined(minDistance)) {
- const granularity = defaultValue.defaultValue(
- options.granularity,
- ComponentDatatype.CesiumMath.RADIANS_PER_DEGREE
- );
- minDistance = ComponentDatatype.CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
- }
- let numPoints = 0;
- let i;
- for (i = 0; i < length - 1; i++) {
- numPoints += PolylinePipeline.numberOfPoints(
- positions[i],
- positions[i + 1],
- minDistance
- );
- }
- const arrayLength = (numPoints + 1) * 3;
- const newPositions = new Array(arrayLength);
- let offset = 0;
- for (i = 0; i < length - 1; i++) {
- const p0 = positions[i];
- const p1 = positions[i + 1];
- const h0 = hasHeightArray ? height[i] : height;
- const h1 = hasHeightArray ? height[i + 1] : height;
- offset = generateCartesianArc(
- p0,
- p1,
- minDistance,
- ellipsoid,
- h0,
- h1,
- newPositions,
- offset
- );
- }
- subdivideHeightsScratchArray.length = 0;
- const lastPoint = positions[length - 1];
- const carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
- carto.height = hasHeightArray ? height[length - 1] : height;
- const cart = ellipsoid.cartographicToCartesian(carto, cartesian);
- Matrix2.Cartesian3.pack(cart, newPositions, arrayLength - 3);
- return newPositions;
- };
- const scratchCartographic0 = new Matrix2.Cartographic();
- const scratchCartographic1 = new Matrix2.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
- * const positions = Cesium.Cartesian3.fromDegreesArray([
- * -105.0, 40.0,
- * -100.0, 38.0,
- * -105.0, 35.0,
- * -100.0, 32.0
- * ]);
- * const surfacePositions = Cesium.PolylinePipeline.generateRhumbArc({
- * positons: positions
- * });
- */
- PolylinePipeline.generateRhumbArc = function (options) {
- if (!defaultValue.defined(options)) {
- options = {};
- }
- const positions = options.positions;
- //>>includeStart('debug', pragmas.debug);
- if (!defaultValue.defined(positions)) {
- throw new RuntimeError.DeveloperError("options.positions is required.");
- }
- //>>includeEnd('debug');
- const length = positions.length;
- const ellipsoid = defaultValue.defaultValue(options.ellipsoid, Matrix2.Ellipsoid.WGS84);
- let height = defaultValue.defaultValue(options.height, 0);
- const hasHeightArray = Array.isArray(height);
- if (length < 1) {
- return [];
- } else if (length === 1) {
- const p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
- height = hasHeightArray ? height[0] : height;
- if (height !== 0) {
- const n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
- Matrix2.Cartesian3.multiplyByScalar(n, height, n);
- Matrix2.Cartesian3.add(p, n, p);
- }
- return [p.x, p.y, p.z];
- }
- const granularity = defaultValue.defaultValue(
- options.granularity,
- ComponentDatatype.CesiumMath.RADIANS_PER_DEGREE
- );
- let numPoints = 0;
- let i;
- let c0 = ellipsoid.cartesianToCartographic(
- positions[0],
- scratchCartographic0
- );
- let c1;
- for (i = 0; i < length - 1; i++) {
- c1 = ellipsoid.cartesianToCartographic(
- positions[i + 1],
- scratchCartographic1
- );
- numPoints += PolylinePipeline.numberOfPointsRhumbLine(c0, c1, granularity);
- c0 = Matrix2.Cartographic.clone(c1, scratchCartographic0);
- }
- const arrayLength = (numPoints + 1) * 3;
- const newPositions = new Array(arrayLength);
- let offset = 0;
- for (i = 0; i < length - 1; i++) {
- const p0 = positions[i];
- const p1 = positions[i + 1];
- const h0 = hasHeightArray ? height[i] : height;
- const h1 = hasHeightArray ? height[i + 1] : height;
- offset = generateCartesianRhumbArc(
- p0,
- p1,
- granularity,
- ellipsoid,
- h0,
- h1,
- newPositions,
- offset
- );
- }
- subdivideHeightsScratchArray.length = 0;
- const lastPoint = positions[length - 1];
- const carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
- carto.height = hasHeightArray ? height[length - 1] : height;
- const cart = ellipsoid.cartographicToCartesian(carto, cartesian);
- Matrix2.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
- * const positions = Cesium.Cartesian3.fromDegreesArray([
- * -105.0, 40.0,
- * -100.0, 38.0,
- * -105.0, 35.0,
- * -100.0, 32.0
- * ]);
- * const surfacePositions = Cesium.PolylinePipeline.generateCartesianArc({
- * positons: positions
- * });
- */
- PolylinePipeline.generateCartesianArc = function (options) {
- const numberArray = PolylinePipeline.generateArc(options);
- const size = numberArray.length / 3;
- const newPositions = new Array(size);
- for (let i = 0; i < size; i++) {
- newPositions[i] = Matrix2.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
- * const positions = Cesium.Cartesian3.fromDegreesArray([
- * -105.0, 40.0,
- * -100.0, 38.0,
- * -105.0, 35.0,
- * -100.0, 32.0
- * ]);
- * const surfacePositions = Cesium.PolylinePipeline.generateCartesianRhumbArc({
- * positons: positions
- * });
- */
- PolylinePipeline.generateCartesianRhumbArc = function (options) {
- const numberArray = PolylinePipeline.generateRhumbArc(options);
- const size = numberArray.length / 3;
- const newPositions = new Array(size);
- for (let i = 0; i < size; i++) {
- newPositions[i] = Matrix2.Cartesian3.unpack(numberArray, i * 3);
- }
- return newPositions;
- };
- exports.PolylinePipeline = PolylinePipeline;
- }));
- //# sourceMappingURL=PolylinePipeline-e67c0760.js.map
|