PolylinePipeline-b4161aaf.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. /* This file is automatically rebuilt by the Cesium build process. */
  2. define(['exports', './defined-26bd4a03', './Check-da037458', './defaultValue-f2e68450', './Math-fa6e45cb', './Cartesian2-2a723276', './Transforms-65aba0a4', './IntersectionTests-c2360ffa', './Plane-a1a3fd52', './EllipsoidRhumbLine-c6cdbfd3', './EllipsoidGeodesic-53e988a6'], function (exports, defined, Check, defaultValue, _Math, Cartesian2, Transforms, IntersectionTests, Plane, EllipsoidRhumbLine, EllipsoidGeodesic) { 'use strict';
  3. /**
  4. * @private
  5. */
  6. var PolylinePipeline = {};
  7. PolylinePipeline.numberOfPoints = function(p0, p1, minDistance) {
  8. var distance = Cartesian2.Cartesian3.distance(p0, p1);
  9. return Math.ceil(distance / minDistance);
  10. };
  11. PolylinePipeline.numberOfPointsRhumbLine = function(p0, p1, granularity) {
  12. var radiansDistanceSquared = Math.pow((p0.longitude - p1.longitude), 2) + Math.pow((p0.latitude - p1.latitude), 2);
  13. return Math.ceil(Math.sqrt(radiansDistanceSquared / (granularity * granularity)));
  14. };
  15. var cartoScratch = new Cartesian2.Cartographic();
  16. PolylinePipeline.extractHeights = function(positions, ellipsoid) {
  17. var length = positions.length;
  18. var heights = new Array(length);
  19. for (var i = 0; i < length; i++) {
  20. var p = positions[i];
  21. heights[i] = ellipsoid.cartesianToCartographic(p, cartoScratch).height;
  22. }
  23. return heights;
  24. };
  25. var wrapLongitudeInversMatrix = new Transforms.Matrix4();
  26. var wrapLongitudeOrigin = new Cartesian2.Cartesian3();
  27. var wrapLongitudeXZNormal = new Cartesian2.Cartesian3();
  28. var wrapLongitudeXZPlane = new Plane.Plane(Cartesian2.Cartesian3.UNIT_X, 0.0);
  29. var wrapLongitudeYZNormal = new Cartesian2.Cartesian3();
  30. var wrapLongitudeYZPlane = new Plane.Plane(Cartesian2.Cartesian3.UNIT_X, 0.0);
  31. var wrapLongitudeIntersection = new Cartesian2.Cartesian3();
  32. var wrapLongitudeOffset = new Cartesian2.Cartesian3();
  33. var subdivideHeightsScratchArray = [];
  34. function subdivideHeights(numPoints, h0, h1) {
  35. var heights = subdivideHeightsScratchArray;
  36. heights.length = numPoints;
  37. var i;
  38. if (h0 === h1) {
  39. for (i = 0; i < numPoints; i++) {
  40. heights[i] = h0;
  41. }
  42. return heights;
  43. }
  44. var dHeight = h1 - h0;
  45. var heightPerVertex = dHeight / numPoints;
  46. for (i = 0; i < numPoints; i++) {
  47. var h = h0 + i*heightPerVertex;
  48. heights[i] = h;
  49. }
  50. return heights;
  51. }
  52. var carto1 = new Cartesian2.Cartographic();
  53. var carto2 = new Cartesian2.Cartographic();
  54. var cartesian = new Cartesian2.Cartesian3();
  55. var scaleFirst = new Cartesian2.Cartesian3();
  56. var scaleLast = new Cartesian2.Cartesian3();
  57. var ellipsoidGeodesic = new EllipsoidGeodesic.EllipsoidGeodesic();
  58. var ellipsoidRhumb = new EllipsoidRhumbLine.EllipsoidRhumbLine();
  59. //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2.
  60. //Result includes p1, but not include p2. This function is called for a sequence of line segments,
  61. //and this prevents duplication of end point.
  62. function generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, array, offset) {
  63. var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst);
  64. var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast);
  65. var numPoints = PolylinePipeline.numberOfPoints(p0, p1, minDistance);
  66. var start = ellipsoid.cartesianToCartographic(first, carto1);
  67. var end = ellipsoid.cartesianToCartographic(last, carto2);
  68. var heights = subdivideHeights(numPoints, h0, h1);
  69. ellipsoidGeodesic.setEndPoints(start, end);
  70. var surfaceDistanceBetweenPoints = ellipsoidGeodesic.surfaceDistance / numPoints;
  71. var index = offset;
  72. start.height = h0;
  73. var cart = ellipsoid.cartographicToCartesian(start, cartesian);
  74. Cartesian2.Cartesian3.pack(cart, array, index);
  75. index += 3;
  76. for (var i = 1; i < numPoints; i++) {
  77. var carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2);
  78. carto.height = heights[i];
  79. cart = ellipsoid.cartographicToCartesian(carto, cartesian);
  80. Cartesian2.Cartesian3.pack(cart, array, index);
  81. index += 3;
  82. }
  83. return index;
  84. }
  85. //Returns subdivided line scaled to ellipsoid surface starting at p1 and ending at p2.
  86. //Result includes p1, but not include p2. This function is called for a sequence of line segments,
  87. //and this prevents duplication of end point.
  88. function generateCartesianRhumbArc(p0, p1, granularity, ellipsoid, h0, h1, array, offset) {
  89. var first = ellipsoid.scaleToGeodeticSurface(p0, scaleFirst);
  90. var last = ellipsoid.scaleToGeodeticSurface(p1, scaleLast);
  91. var start = ellipsoid.cartesianToCartographic(first, carto1);
  92. var end = ellipsoid.cartesianToCartographic(last, carto2);
  93. var numPoints = PolylinePipeline.numberOfPointsRhumbLine(start, end, granularity);
  94. var heights = subdivideHeights(numPoints, h0, h1);
  95. if (!ellipsoidRhumb.ellipsoid.equals(ellipsoid)) {
  96. ellipsoidRhumb = new EllipsoidRhumbLine.EllipsoidRhumbLine(undefined, undefined, ellipsoid);
  97. }
  98. ellipsoidRhumb.setEndPoints(start, end);
  99. var surfaceDistanceBetweenPoints = ellipsoidRhumb.surfaceDistance / numPoints;
  100. var index = offset;
  101. start.height = h0;
  102. var cart = ellipsoid.cartographicToCartesian(start, cartesian);
  103. Cartesian2.Cartesian3.pack(cart, array, index);
  104. index += 3;
  105. for (var i = 1; i < numPoints; i++) {
  106. var carto = ellipsoidRhumb.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2);
  107. carto.height = heights[i];
  108. cart = ellipsoid.cartographicToCartesian(carto, cartesian);
  109. Cartesian2.Cartesian3.pack(cart, array, index);
  110. index += 3;
  111. }
  112. return index;
  113. }
  114. /**
  115. * Breaks a {@link Polyline} into segments such that it does not cross the &plusmn;180 degree meridian of an ellipsoid.
  116. *
  117. * @param {Cartesian3[]} positions The polyline's Cartesian positions.
  118. * @param {Matrix4} [modelMatrix=Matrix4.IDENTITY] The polyline's model matrix. Assumed to be an affine
  119. * transformation matrix, where the upper left 3x3 elements are a rotation matrix, and
  120. * the upper three elements in the fourth column are the translation. The bottom row is assumed to be [0, 0, 0, 1].
  121. * The matrix is not verified to be in the proper form.
  122. * @returns {Object} An object with a <code>positions</code> property that is an array of positions and a
  123. * <code>segments</code> property.
  124. *
  125. *
  126. * @example
  127. * var polylines = new Cesium.PolylineCollection();
  128. * var polyline = polylines.add(...);
  129. * var positions = polyline.positions;
  130. * var modelMatrix = polylines.modelMatrix;
  131. * var segments = Cesium.PolylinePipeline.wrapLongitude(positions, modelMatrix);
  132. *
  133. * @see PolygonPipeline.wrapLongitude
  134. * @see Polyline
  135. * @see PolylineCollection
  136. */
  137. PolylinePipeline.wrapLongitude = function(positions, modelMatrix) {
  138. var cartesians = [];
  139. var segments = [];
  140. if (defined.defined(positions) && positions.length > 0) {
  141. modelMatrix = defaultValue.defaultValue(modelMatrix, Transforms.Matrix4.IDENTITY);
  142. var inverseModelMatrix = Transforms.Matrix4.inverseTransformation(modelMatrix, wrapLongitudeInversMatrix);
  143. var origin = Transforms.Matrix4.multiplyByPoint(inverseModelMatrix, Cartesian2.Cartesian3.ZERO, wrapLongitudeOrigin);
  144. var xzNormal = Cartesian2.Cartesian3.normalize(Transforms.Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian2.Cartesian3.UNIT_Y, wrapLongitudeXZNormal), wrapLongitudeXZNormal);
  145. var xzPlane = Plane.Plane.fromPointNormal(origin, xzNormal, wrapLongitudeXZPlane);
  146. var yzNormal = Cartesian2.Cartesian3.normalize(Transforms.Matrix4.multiplyByPointAsVector(inverseModelMatrix, Cartesian2.Cartesian3.UNIT_X, wrapLongitudeYZNormal), wrapLongitudeYZNormal);
  147. var yzPlane = Plane.Plane.fromPointNormal(origin, yzNormal, wrapLongitudeYZPlane);
  148. var count = 1;
  149. cartesians.push(Cartesian2.Cartesian3.clone(positions[0]));
  150. var prev = cartesians[0];
  151. var length = positions.length;
  152. for (var i = 1; i < length; ++i) {
  153. var cur = positions[i];
  154. // intersects the IDL if either endpoint is on the negative side of the yz-plane
  155. if (Plane.Plane.getPointDistance(yzPlane, prev) < 0.0 || Plane.Plane.getPointDistance(yzPlane, cur) < 0.0) {
  156. // and intersects the xz-plane
  157. var intersection = IntersectionTests.IntersectionTests.lineSegmentPlane(prev, cur, xzPlane, wrapLongitudeIntersection);
  158. if (defined.defined(intersection)) {
  159. // move point on the xz-plane slightly away from the plane
  160. var offset = Cartesian2.Cartesian3.multiplyByScalar(xzNormal, 5.0e-9, wrapLongitudeOffset);
  161. if (Plane.Plane.getPointDistance(xzPlane, prev) < 0.0) {
  162. Cartesian2.Cartesian3.negate(offset, offset);
  163. }
  164. cartesians.push(Cartesian2.Cartesian3.add(intersection, offset, new Cartesian2.Cartesian3()));
  165. segments.push(count + 1);
  166. Cartesian2.Cartesian3.negate(offset, offset);
  167. cartesians.push(Cartesian2.Cartesian3.add(intersection, offset, new Cartesian2.Cartesian3()));
  168. count = 1;
  169. }
  170. }
  171. cartesians.push(Cartesian2.Cartesian3.clone(positions[i]));
  172. count++;
  173. prev = cur;
  174. }
  175. segments.push(count);
  176. }
  177. return {
  178. positions : cartesians,
  179. lengths : segments
  180. };
  181. };
  182. /**
  183. * Subdivides polyline and raises all points to the specified height. Returns an array of numbers to represent the positions.
  184. * @param {Object} options Object with the following properties:
  185. * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
  186. * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
  187. * @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.
  188. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
  189. * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid.
  190. *
  191. * @example
  192. * var positions = Cesium.Cartesian3.fromDegreesArray([
  193. * -105.0, 40.0,
  194. * -100.0, 38.0,
  195. * -105.0, 35.0,
  196. * -100.0, 32.0
  197. * ]);
  198. * var surfacePositions = Cesium.PolylinePipeline.generateArc({
  199. * positons: positions
  200. * });
  201. */
  202. PolylinePipeline.generateArc = function(options) {
  203. if (!defined.defined(options)) {
  204. options = {};
  205. }
  206. var positions = options.positions;
  207. //>>includeStart('debug', pragmas.debug);
  208. if (!defined.defined(positions)) {
  209. throw new Check.DeveloperError('options.positions is required.');
  210. }
  211. //>>includeEnd('debug');
  212. var length = positions.length;
  213. var ellipsoid = defaultValue.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  214. var height = defaultValue.defaultValue(options.height, 0);
  215. var hasHeightArray = Transforms.isArray(height);
  216. if (length < 1) {
  217. return [];
  218. } else if (length === 1) {
  219. var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
  220. height = hasHeightArray ? height[0] : height;
  221. if (height !== 0) {
  222. var n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
  223. Cartesian2.Cartesian3.multiplyByScalar(n, height, n);
  224. Cartesian2.Cartesian3.add(p, n, p);
  225. }
  226. return [p.x, p.y, p.z];
  227. }
  228. var minDistance = options.minDistance;
  229. if (!defined.defined(minDistance)) {
  230. var granularity = defaultValue.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  231. minDistance = _Math.CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
  232. }
  233. var numPoints = 0;
  234. var i;
  235. for (i = 0; i < length -1; i++) {
  236. numPoints += PolylinePipeline.numberOfPoints(positions[i], positions[i+1], minDistance);
  237. }
  238. var arrayLength = (numPoints + 1) * 3;
  239. var newPositions = new Array(arrayLength);
  240. var offset = 0;
  241. for (i = 0; i < length - 1; i++) {
  242. var p0 = positions[i];
  243. var p1 = positions[i + 1];
  244. var h0 = hasHeightArray ? height[i] : height;
  245. var h1 = hasHeightArray ? height[i + 1] : height;
  246. offset = generateCartesianArc(p0, p1, minDistance, ellipsoid, h0, h1, newPositions, offset);
  247. }
  248. subdivideHeightsScratchArray.length = 0;
  249. var lastPoint = positions[length - 1];
  250. var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
  251. carto.height = hasHeightArray ? height[length - 1] : height;
  252. var cart = ellipsoid.cartographicToCartesian(carto, cartesian);
  253. Cartesian2.Cartesian3.pack(cart, newPositions, arrayLength - 3);
  254. return newPositions;
  255. };
  256. var scratchCartographic0 = new Cartesian2.Cartographic();
  257. var scratchCartographic1 = new Cartesian2.Cartographic();
  258. /**
  259. * Subdivides polyline and raises all points to the specified height using Rhumb lines. Returns an array of numbers to represent the positions.
  260. * @param {Object} options Object with the following properties:
  261. * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
  262. * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
  263. * @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.
  264. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
  265. * @returns {Number[]} A new array of positions of type {Number} that have been subdivided and raised to the surface of the ellipsoid.
  266. *
  267. * @example
  268. * var positions = Cesium.Cartesian3.fromDegreesArray([
  269. * -105.0, 40.0,
  270. * -100.0, 38.0,
  271. * -105.0, 35.0,
  272. * -100.0, 32.0
  273. * ]);
  274. * var surfacePositions = Cesium.PolylinePipeline.generateRhumbArc({
  275. * positons: positions
  276. * });
  277. */
  278. PolylinePipeline.generateRhumbArc = function(options) {
  279. if (!defined.defined(options)) {
  280. options = {};
  281. }
  282. var positions = options.positions;
  283. //>>includeStart('debug', pragmas.debug);
  284. if (!defined.defined(positions)) {
  285. throw new Check.DeveloperError('options.positions is required.');
  286. }
  287. //>>includeEnd('debug');
  288. var length = positions.length;
  289. var ellipsoid = defaultValue.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  290. var height = defaultValue.defaultValue(options.height, 0);
  291. var hasHeightArray = Transforms.isArray(height);
  292. if (length < 1) {
  293. return [];
  294. } else if (length === 1) {
  295. var p = ellipsoid.scaleToGeodeticSurface(positions[0], scaleFirst);
  296. height = hasHeightArray ? height[0] : height;
  297. if (height !== 0) {
  298. var n = ellipsoid.geodeticSurfaceNormal(p, cartesian);
  299. Cartesian2.Cartesian3.multiplyByScalar(n, height, n);
  300. Cartesian2.Cartesian3.add(p, n, p);
  301. }
  302. return [p.x, p.y, p.z];
  303. }
  304. var granularity = defaultValue.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  305. var numPoints = 0;
  306. var i;
  307. var c0 = ellipsoid.cartesianToCartographic(positions[0], scratchCartographic0);
  308. var c1;
  309. for (i = 0; i < length - 1; i++) {
  310. c1 = ellipsoid.cartesianToCartographic(positions[i + 1], scratchCartographic1);
  311. numPoints += PolylinePipeline.numberOfPointsRhumbLine(c0, c1, granularity);
  312. c0 = Cartesian2.Cartographic.clone(c1, scratchCartographic0);
  313. }
  314. var arrayLength = (numPoints + 1) * 3;
  315. var newPositions = new Array(arrayLength);
  316. var offset = 0;
  317. for (i = 0; i < length - 1; i++) {
  318. var p0 = positions[i];
  319. var p1 = positions[i + 1];
  320. var h0 = hasHeightArray ? height[i] : height;
  321. var h1 = hasHeightArray ? height[i + 1] : height;
  322. offset = generateCartesianRhumbArc(p0, p1, granularity, ellipsoid, h0, h1, newPositions, offset);
  323. }
  324. subdivideHeightsScratchArray.length = 0;
  325. var lastPoint = positions[length - 1];
  326. var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);
  327. carto.height = hasHeightArray ? height[length - 1] : height;
  328. var cart = ellipsoid.cartographicToCartesian(carto, cartesian);
  329. Cartesian2.Cartesian3.pack(cart, newPositions, arrayLength - 3);
  330. return newPositions;
  331. };
  332. /**
  333. * Subdivides polyline and raises all points to the specified height. Returns an array of new {Cartesian3} positions.
  334. * @param {Object} options Object with the following properties:
  335. * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
  336. * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
  337. * @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.
  338. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
  339. * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid.
  340. *
  341. * @example
  342. * var positions = Cesium.Cartesian3.fromDegreesArray([
  343. * -105.0, 40.0,
  344. * -100.0, 38.0,
  345. * -105.0, 35.0,
  346. * -100.0, 32.0
  347. * ]);
  348. * var surfacePositions = Cesium.PolylinePipeline.generateCartesianArc({
  349. * positons: positions
  350. * });
  351. */
  352. PolylinePipeline.generateCartesianArc = function(options) {
  353. var numberArray = PolylinePipeline.generateArc(options);
  354. var size = numberArray.length/3;
  355. var newPositions = new Array(size);
  356. for (var i = 0; i < size; i++) {
  357. newPositions[i] = Cartesian2.Cartesian3.unpack(numberArray, i*3);
  358. }
  359. return newPositions;
  360. };
  361. /**
  362. * Subdivides polyline and raises all points to the specified height using Rhumb Lines. Returns an array of new {Cartesian3} positions.
  363. * @param {Object} options Object with the following properties:
  364. * @param {Cartesian3[]} options.positions The array of type {Cartesian3} representing positions.
  365. * @param {Number|Number[]} [options.height=0.0] A number or array of numbers representing the heights of each position.
  366. * @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.
  367. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid on which the positions lie.
  368. * @returns {Cartesian3[]} A new array of cartesian3 positions that have been subdivided and raised to the surface of the ellipsoid.
  369. *
  370. * @example
  371. * var positions = Cesium.Cartesian3.fromDegreesArray([
  372. * -105.0, 40.0,
  373. * -100.0, 38.0,
  374. * -105.0, 35.0,
  375. * -100.0, 32.0
  376. * ]);
  377. * var surfacePositions = Cesium.PolylinePipeline.generateCartesianRhumbArc({
  378. * positons: positions
  379. * });
  380. */
  381. PolylinePipeline.generateCartesianRhumbArc = function(options) {
  382. var numberArray = PolylinePipeline.generateRhumbArc(options);
  383. var size = numberArray.length/3;
  384. var newPositions = new Array(size);
  385. for (var i = 0; i < size; i++) {
  386. newPositions[i] = Cartesian2.Cartesian3.unpack(numberArray, i*3);
  387. }
  388. return newPositions;
  389. };
  390. exports.PolylinePipeline = PolylinePipeline;
  391. });