PolygonGeometryLibrary-59126025.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. define(['exports', './ArcType-2d9abbbc', './arrayRemoveDuplicates-d2061e85', './Matrix2-e1298525', './Matrix3-41c58dde', './ComponentDatatype-cf1fa08e', './defaultValue-fe22d8c0', './EllipsoidRhumbLine-ef872433', './GeometryAttribute-a466e9c7', './GeometryAttributes-ad136444', './GeometryPipeline-dcf79306', './IndexDatatype-2643aa47', './Math-0a2ac845', './PolygonPipeline-1fe328c0', './Transforms-bc45e707'], (function (exports, ArcType, arrayRemoveDuplicates, Matrix2, Matrix3, ComponentDatatype, defaultValue, EllipsoidRhumbLine, GeometryAttribute, GeometryAttributes, GeometryPipeline, IndexDatatype, Math$1, PolygonPipeline, Transforms) { 'use strict';
  2. /**
  3. * A queue that can enqueue items at the end, and dequeue items from the front.
  4. *
  5. * @alias Queue
  6. * @constructor
  7. */
  8. function Queue() {
  9. this._array = [];
  10. this._offset = 0;
  11. this._length = 0;
  12. }
  13. Object.defineProperties(Queue.prototype, {
  14. /**
  15. * The length of the queue.
  16. *
  17. * @memberof Queue.prototype
  18. *
  19. * @type {number}
  20. * @readonly
  21. */
  22. length: {
  23. get: function () {
  24. return this._length;
  25. },
  26. },
  27. });
  28. /**
  29. * Enqueues the specified item.
  30. *
  31. * @param {*} item The item to enqueue.
  32. */
  33. Queue.prototype.enqueue = function (item) {
  34. this._array.push(item);
  35. this._length++;
  36. };
  37. /**
  38. * Dequeues an item. Returns undefined if the queue is empty.
  39. *
  40. * @returns {*} The the dequeued item.
  41. */
  42. Queue.prototype.dequeue = function () {
  43. if (this._length === 0) {
  44. return undefined;
  45. }
  46. const array = this._array;
  47. let offset = this._offset;
  48. const item = array[offset];
  49. array[offset] = undefined;
  50. offset++;
  51. if (offset > 10 && offset * 2 > array.length) {
  52. //compact array
  53. this._array = array.slice(offset);
  54. offset = 0;
  55. }
  56. this._offset = offset;
  57. this._length--;
  58. return item;
  59. };
  60. /**
  61. * Returns the item at the front of the queue. Returns undefined if the queue is empty.
  62. *
  63. * @returns {*} The item at the front of the queue.
  64. */
  65. Queue.prototype.peek = function () {
  66. if (this._length === 0) {
  67. return undefined;
  68. }
  69. return this._array[this._offset];
  70. };
  71. /**
  72. * Check whether this queue contains the specified item.
  73. *
  74. * @param {*} item The item to search for.
  75. */
  76. Queue.prototype.contains = function (item) {
  77. return this._array.indexOf(item) !== -1;
  78. };
  79. /**
  80. * Remove all items from the queue.
  81. */
  82. Queue.prototype.clear = function () {
  83. this._array.length = this._offset = this._length = 0;
  84. };
  85. /**
  86. * Sort the items in the queue in-place.
  87. *
  88. * @param {Queue.Comparator} compareFunction A function that defines the sort order.
  89. */
  90. Queue.prototype.sort = function (compareFunction) {
  91. if (this._offset > 0) {
  92. //compact array
  93. this._array = this._array.slice(this._offset);
  94. this._offset = 0;
  95. }
  96. this._array.sort(compareFunction);
  97. };
  98. /**
  99. * @private
  100. */
  101. const PolygonGeometryLibrary = {};
  102. PolygonGeometryLibrary.computeHierarchyPackedLength = function (
  103. polygonHierarchy,
  104. CartesianX
  105. ) {
  106. let numComponents = 0;
  107. const stack = [polygonHierarchy];
  108. while (stack.length > 0) {
  109. const hierarchy = stack.pop();
  110. if (!defaultValue.defined(hierarchy)) {
  111. continue;
  112. }
  113. numComponents += 2;
  114. const positions = hierarchy.positions;
  115. const holes = hierarchy.holes;
  116. if (defaultValue.defined(positions) && positions.length > 0) {
  117. numComponents += positions.length * CartesianX.packedLength;
  118. }
  119. if (defaultValue.defined(holes)) {
  120. const length = holes.length;
  121. for (let i = 0; i < length; ++i) {
  122. stack.push(holes[i]);
  123. }
  124. }
  125. }
  126. return numComponents;
  127. };
  128. PolygonGeometryLibrary.packPolygonHierarchy = function (
  129. polygonHierarchy,
  130. array,
  131. startingIndex,
  132. CartesianX
  133. ) {
  134. const stack = [polygonHierarchy];
  135. while (stack.length > 0) {
  136. const hierarchy = stack.pop();
  137. if (!defaultValue.defined(hierarchy)) {
  138. continue;
  139. }
  140. const positions = hierarchy.positions;
  141. const holes = hierarchy.holes;
  142. array[startingIndex++] = defaultValue.defined(positions) ? positions.length : 0;
  143. array[startingIndex++] = defaultValue.defined(holes) ? holes.length : 0;
  144. if (defaultValue.defined(positions)) {
  145. const positionsLength = positions.length;
  146. for (
  147. let i = 0;
  148. i < positionsLength;
  149. ++i, startingIndex += CartesianX.packedLength
  150. ) {
  151. CartesianX.pack(positions[i], array, startingIndex);
  152. }
  153. }
  154. if (defaultValue.defined(holes)) {
  155. const holesLength = holes.length;
  156. for (let j = 0; j < holesLength; ++j) {
  157. stack.push(holes[j]);
  158. }
  159. }
  160. }
  161. return startingIndex;
  162. };
  163. PolygonGeometryLibrary.unpackPolygonHierarchy = function (
  164. array,
  165. startingIndex,
  166. CartesianX
  167. ) {
  168. const positionsLength = array[startingIndex++];
  169. const holesLength = array[startingIndex++];
  170. const positions = new Array(positionsLength);
  171. const holes = holesLength > 0 ? new Array(holesLength) : undefined;
  172. for (
  173. let i = 0;
  174. i < positionsLength;
  175. ++i, startingIndex += CartesianX.packedLength
  176. ) {
  177. positions[i] = CartesianX.unpack(array, startingIndex);
  178. }
  179. for (let j = 0; j < holesLength; ++j) {
  180. holes[j] = PolygonGeometryLibrary.unpackPolygonHierarchy(
  181. array,
  182. startingIndex,
  183. CartesianX
  184. );
  185. startingIndex = holes[j].startingIndex;
  186. delete holes[j].startingIndex;
  187. }
  188. return {
  189. positions: positions,
  190. holes: holes,
  191. startingIndex: startingIndex,
  192. };
  193. };
  194. const distance2DScratch = new Matrix2.Cartesian2();
  195. function getPointAtDistance2D(p0, p1, distance, length) {
  196. Matrix2.Cartesian2.subtract(p1, p0, distance2DScratch);
  197. Matrix2.Cartesian2.multiplyByScalar(
  198. distance2DScratch,
  199. distance / length,
  200. distance2DScratch
  201. );
  202. Matrix2.Cartesian2.add(p0, distance2DScratch, distance2DScratch);
  203. return [distance2DScratch.x, distance2DScratch.y];
  204. }
  205. const distanceScratch = new Matrix3.Cartesian3();
  206. function getPointAtDistance(p0, p1, distance, length) {
  207. Matrix3.Cartesian3.subtract(p1, p0, distanceScratch);
  208. Matrix3.Cartesian3.multiplyByScalar(
  209. distanceScratch,
  210. distance / length,
  211. distanceScratch
  212. );
  213. Matrix3.Cartesian3.add(p0, distanceScratch, distanceScratch);
  214. return [distanceScratch.x, distanceScratch.y, distanceScratch.z];
  215. }
  216. PolygonGeometryLibrary.subdivideLineCount = function (p0, p1, minDistance) {
  217. const distance = Matrix3.Cartesian3.distance(p0, p1);
  218. const n = distance / minDistance;
  219. const countDivide = Math.max(0, Math.ceil(Math$1.CesiumMath.log2(n)));
  220. return Math.pow(2, countDivide);
  221. };
  222. const scratchCartographic0 = new Matrix3.Cartographic();
  223. const scratchCartographic1 = new Matrix3.Cartographic();
  224. const scratchCartographic2 = new Matrix3.Cartographic();
  225. const scratchCartesian0 = new Matrix3.Cartesian3();
  226. const scratchRhumbLine = new EllipsoidRhumbLine.EllipsoidRhumbLine();
  227. PolygonGeometryLibrary.subdivideRhumbLineCount = function (
  228. ellipsoid,
  229. p0,
  230. p1,
  231. minDistance
  232. ) {
  233. const c0 = ellipsoid.cartesianToCartographic(p0, scratchCartographic0);
  234. const c1 = ellipsoid.cartesianToCartographic(p1, scratchCartographic1);
  235. const rhumb = new EllipsoidRhumbLine.EllipsoidRhumbLine(c0, c1, ellipsoid);
  236. const n = rhumb.surfaceDistance / minDistance;
  237. const countDivide = Math.max(0, Math.ceil(Math$1.CesiumMath.log2(n)));
  238. return Math.pow(2, countDivide);
  239. };
  240. /**
  241. * Subdivides texture coordinates based on the subdivision of the associated world positions.
  242. *
  243. * @param {Cartesian2} t0 First texture coordinate.
  244. * @param {Cartesian2} t1 Second texture coordinate.
  245. * @param {Cartesian3} p0 First world position.
  246. * @param {Cartesian3} p1 Second world position.
  247. * @param {number} minDistance Minimum distance for a segment.
  248. * @param {Cartesian2[]} result The subdivided texture coordinates.
  249. *
  250. * @private
  251. */
  252. PolygonGeometryLibrary.subdivideTexcoordLine = function (
  253. t0,
  254. t1,
  255. p0,
  256. p1,
  257. minDistance,
  258. result
  259. ) {
  260. // Compute the number of subdivisions.
  261. const subdivisions = PolygonGeometryLibrary.subdivideLineCount(
  262. p0,
  263. p1,
  264. minDistance
  265. );
  266. // Compute the distance between each subdivided point.
  267. const length2D = Matrix2.Cartesian2.distance(t0, t1);
  268. const distanceBetweenCoords = length2D / subdivisions;
  269. // Resize the result array.
  270. const texcoords = result;
  271. texcoords.length = subdivisions * 2;
  272. // Compute texture coordinates using linear interpolation.
  273. let index = 0;
  274. for (let i = 0; i < subdivisions; i++) {
  275. const t = getPointAtDistance2D(t0, t1, i * distanceBetweenCoords, length2D);
  276. texcoords[index++] = t[0];
  277. texcoords[index++] = t[1];
  278. }
  279. return texcoords;
  280. };
  281. PolygonGeometryLibrary.subdivideLine = function (p0, p1, minDistance, result) {
  282. const numVertices = PolygonGeometryLibrary.subdivideLineCount(
  283. p0,
  284. p1,
  285. minDistance
  286. );
  287. const length = Matrix3.Cartesian3.distance(p0, p1);
  288. const distanceBetweenVertices = length / numVertices;
  289. if (!defaultValue.defined(result)) {
  290. result = [];
  291. }
  292. const positions = result;
  293. positions.length = numVertices * 3;
  294. let index = 0;
  295. for (let i = 0; i < numVertices; i++) {
  296. const p = getPointAtDistance(p0, p1, i * distanceBetweenVertices, length);
  297. positions[index++] = p[0];
  298. positions[index++] = p[1];
  299. positions[index++] = p[2];
  300. }
  301. return positions;
  302. };
  303. /**
  304. * Subdivides texture coordinates based on the subdivision of the associated world positions using a rhumb line.
  305. *
  306. * @param {Cartesian2} t0 First texture coordinate.
  307. * @param {Cartesian2} t1 Second texture coordinate.
  308. * @param {Ellipsoid} ellipsoid The ellipsoid.
  309. * @param {Cartesian3} p0 First world position.
  310. * @param {Cartesian3} p1 Second world position.
  311. * @param {number} minDistance Minimum distance for a segment.
  312. * @param {Cartesian2[]} result The subdivided texture coordinates.
  313. *
  314. * @private
  315. */
  316. PolygonGeometryLibrary.subdivideTexcoordRhumbLine = function (
  317. t0,
  318. t1,
  319. ellipsoid,
  320. p0,
  321. p1,
  322. minDistance,
  323. result
  324. ) {
  325. // Compute the surface distance.
  326. const c0 = ellipsoid.cartesianToCartographic(p0, scratchCartographic0);
  327. const c1 = ellipsoid.cartesianToCartographic(p1, scratchCartographic1);
  328. scratchRhumbLine.setEndPoints(c0, c1);
  329. const n = scratchRhumbLine.surfaceDistance / minDistance;
  330. // Compute the number of subdivisions.
  331. const countDivide = Math.max(0, Math.ceil(Math$1.CesiumMath.log2(n)));
  332. const subdivisions = Math.pow(2, countDivide);
  333. // Compute the distance between each subdivided point.
  334. const length2D = Matrix2.Cartesian2.distance(t0, t1);
  335. const distanceBetweenCoords = length2D / subdivisions;
  336. // Resize the result array.
  337. const texcoords = result;
  338. texcoords.length = subdivisions * 2;
  339. // Compute texture coordinates using linear interpolation.
  340. let index = 0;
  341. for (let i = 0; i < subdivisions; i++) {
  342. const t = getPointAtDistance2D(t0, t1, i * distanceBetweenCoords, length2D);
  343. texcoords[index++] = t[0];
  344. texcoords[index++] = t[1];
  345. }
  346. return texcoords;
  347. };
  348. PolygonGeometryLibrary.subdivideRhumbLine = function (
  349. ellipsoid,
  350. p0,
  351. p1,
  352. minDistance,
  353. result
  354. ) {
  355. const c0 = ellipsoid.cartesianToCartographic(p0, scratchCartographic0);
  356. const c1 = ellipsoid.cartesianToCartographic(p1, scratchCartographic1);
  357. const rhumb = new EllipsoidRhumbLine.EllipsoidRhumbLine(c0, c1, ellipsoid);
  358. const n = rhumb.surfaceDistance / minDistance;
  359. const countDivide = Math.max(0, Math.ceil(Math$1.CesiumMath.log2(n)));
  360. const numVertices = Math.pow(2, countDivide);
  361. const distanceBetweenVertices = rhumb.surfaceDistance / numVertices;
  362. if (!defaultValue.defined(result)) {
  363. result = [];
  364. }
  365. const positions = result;
  366. positions.length = numVertices * 3;
  367. let index = 0;
  368. for (let i = 0; i < numVertices; i++) {
  369. const c = rhumb.interpolateUsingSurfaceDistance(
  370. i * distanceBetweenVertices,
  371. scratchCartographic2
  372. );
  373. const p = ellipsoid.cartographicToCartesian(c, scratchCartesian0);
  374. positions[index++] = p.x;
  375. positions[index++] = p.y;
  376. positions[index++] = p.z;
  377. }
  378. return positions;
  379. };
  380. const scaleToGeodeticHeightN1 = new Matrix3.Cartesian3();
  381. const scaleToGeodeticHeightN2 = new Matrix3.Cartesian3();
  382. const scaleToGeodeticHeightP1 = new Matrix3.Cartesian3();
  383. const scaleToGeodeticHeightP2 = new Matrix3.Cartesian3();
  384. PolygonGeometryLibrary.scaleToGeodeticHeightExtruded = function (
  385. geometry,
  386. maxHeight,
  387. minHeight,
  388. ellipsoid,
  389. perPositionHeight
  390. ) {
  391. ellipsoid = defaultValue.defaultValue(ellipsoid, Matrix3.Ellipsoid.WGS84);
  392. const n1 = scaleToGeodeticHeightN1;
  393. let n2 = scaleToGeodeticHeightN2;
  394. const p = scaleToGeodeticHeightP1;
  395. let p2 = scaleToGeodeticHeightP2;
  396. if (
  397. defaultValue.defined(geometry) &&
  398. defaultValue.defined(geometry.attributes) &&
  399. defaultValue.defined(geometry.attributes.position)
  400. ) {
  401. const positions = geometry.attributes.position.values;
  402. const length = positions.length / 2;
  403. for (let i = 0; i < length; i += 3) {
  404. Matrix3.Cartesian3.fromArray(positions, i, p);
  405. ellipsoid.geodeticSurfaceNormal(p, n1);
  406. p2 = ellipsoid.scaleToGeodeticSurface(p, p2);
  407. n2 = Matrix3.Cartesian3.multiplyByScalar(n1, minHeight, n2);
  408. n2 = Matrix3.Cartesian3.add(p2, n2, n2);
  409. positions[i + length] = n2.x;
  410. positions[i + 1 + length] = n2.y;
  411. positions[i + 2 + length] = n2.z;
  412. if (perPositionHeight) {
  413. p2 = Matrix3.Cartesian3.clone(p, p2);
  414. }
  415. n2 = Matrix3.Cartesian3.multiplyByScalar(n1, maxHeight, n2);
  416. n2 = Matrix3.Cartesian3.add(p2, n2, n2);
  417. positions[i] = n2.x;
  418. positions[i + 1] = n2.y;
  419. positions[i + 2] = n2.z;
  420. }
  421. }
  422. return geometry;
  423. };
  424. PolygonGeometryLibrary.polygonOutlinesFromHierarchy = function (
  425. polygonHierarchy,
  426. scaleToEllipsoidSurface,
  427. ellipsoid
  428. ) {
  429. // create from a polygon hierarchy
  430. // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
  431. const polygons = [];
  432. const queue = new Queue();
  433. queue.enqueue(polygonHierarchy);
  434. let i;
  435. let j;
  436. let length;
  437. while (queue.length !== 0) {
  438. const outerNode = queue.dequeue();
  439. let outerRing = outerNode.positions;
  440. if (scaleToEllipsoidSurface) {
  441. length = outerRing.length;
  442. for (i = 0; i < length; i++) {
  443. ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]);
  444. }
  445. }
  446. outerRing = arrayRemoveDuplicates.arrayRemoveDuplicates(
  447. outerRing,
  448. Matrix3.Cartesian3.equalsEpsilon,
  449. true
  450. );
  451. if (outerRing.length < 3) {
  452. continue;
  453. }
  454. const numChildren = outerNode.holes ? outerNode.holes.length : 0;
  455. // The outer polygon contains inner polygons
  456. for (i = 0; i < numChildren; i++) {
  457. const hole = outerNode.holes[i];
  458. let holePositions = hole.positions;
  459. if (scaleToEllipsoidSurface) {
  460. length = holePositions.length;
  461. for (j = 0; j < length; ++j) {
  462. ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]);
  463. }
  464. }
  465. holePositions = arrayRemoveDuplicates.arrayRemoveDuplicates(
  466. holePositions,
  467. Matrix3.Cartesian3.equalsEpsilon,
  468. true
  469. );
  470. if (holePositions.length < 3) {
  471. continue;
  472. }
  473. polygons.push(holePositions);
  474. let numGrandchildren = 0;
  475. if (defaultValue.defined(hole.holes)) {
  476. numGrandchildren = hole.holes.length;
  477. }
  478. for (j = 0; j < numGrandchildren; j++) {
  479. queue.enqueue(hole.holes[j]);
  480. }
  481. }
  482. polygons.push(outerRing);
  483. }
  484. return polygons;
  485. };
  486. PolygonGeometryLibrary.polygonsFromHierarchy = function (
  487. polygonHierarchy,
  488. keepDuplicates,
  489. projectPointsTo2D,
  490. scaleToEllipsoidSurface,
  491. ellipsoid
  492. ) {
  493. // create from a polygon hierarchy
  494. // Algorithm adapted from http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
  495. const hierarchy = [];
  496. const polygons = [];
  497. const queue = new Queue();
  498. queue.enqueue(polygonHierarchy);
  499. while (queue.length !== 0) {
  500. const outerNode = queue.dequeue();
  501. let outerRing = outerNode.positions;
  502. const holes = outerNode.holes;
  503. let i;
  504. let length;
  505. if (scaleToEllipsoidSurface) {
  506. length = outerRing.length;
  507. for (i = 0; i < length; i++) {
  508. ellipsoid.scaleToGeodeticSurface(outerRing[i], outerRing[i]);
  509. }
  510. }
  511. if (!keepDuplicates) {
  512. outerRing = arrayRemoveDuplicates.arrayRemoveDuplicates(
  513. outerRing,
  514. Matrix3.Cartesian3.equalsEpsilon,
  515. true
  516. );
  517. }
  518. if (outerRing.length < 3) {
  519. continue;
  520. }
  521. let positions2D = projectPointsTo2D(outerRing);
  522. if (!defaultValue.defined(positions2D)) {
  523. continue;
  524. }
  525. const holeIndices = [];
  526. let originalWindingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(
  527. positions2D
  528. );
  529. if (originalWindingOrder === PolygonPipeline.WindingOrder.CLOCKWISE) {
  530. positions2D.reverse();
  531. outerRing = outerRing.slice().reverse();
  532. }
  533. let positions = outerRing.slice();
  534. const numChildren = defaultValue.defined(holes) ? holes.length : 0;
  535. const polygonHoles = [];
  536. let j;
  537. for (i = 0; i < numChildren; i++) {
  538. const hole = holes[i];
  539. let holePositions = hole.positions;
  540. if (scaleToEllipsoidSurface) {
  541. length = holePositions.length;
  542. for (j = 0; j < length; ++j) {
  543. ellipsoid.scaleToGeodeticSurface(holePositions[j], holePositions[j]);
  544. }
  545. }
  546. if (!keepDuplicates) {
  547. holePositions = arrayRemoveDuplicates.arrayRemoveDuplicates(
  548. holePositions,
  549. Matrix3.Cartesian3.equalsEpsilon,
  550. true
  551. );
  552. }
  553. if (holePositions.length < 3) {
  554. continue;
  555. }
  556. const holePositions2D = projectPointsTo2D(holePositions);
  557. if (!defaultValue.defined(holePositions2D)) {
  558. continue;
  559. }
  560. originalWindingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(
  561. holePositions2D
  562. );
  563. if (originalWindingOrder === PolygonPipeline.WindingOrder.CLOCKWISE) {
  564. holePositions2D.reverse();
  565. holePositions = holePositions.slice().reverse();
  566. }
  567. polygonHoles.push(holePositions);
  568. holeIndices.push(positions.length);
  569. positions = positions.concat(holePositions);
  570. positions2D = positions2D.concat(holePositions2D);
  571. let numGrandchildren = 0;
  572. if (defaultValue.defined(hole.holes)) {
  573. numGrandchildren = hole.holes.length;
  574. }
  575. for (j = 0; j < numGrandchildren; j++) {
  576. queue.enqueue(hole.holes[j]);
  577. }
  578. }
  579. hierarchy.push({
  580. outerRing: outerRing,
  581. holes: polygonHoles,
  582. });
  583. polygons.push({
  584. positions: positions,
  585. positions2D: positions2D,
  586. holes: holeIndices,
  587. });
  588. }
  589. return {
  590. hierarchy: hierarchy,
  591. polygons: polygons,
  592. };
  593. };
  594. const computeBoundingRectangleCartesian2 = new Matrix2.Cartesian2();
  595. const computeBoundingRectangleCartesian3 = new Matrix3.Cartesian3();
  596. const computeBoundingRectangleQuaternion = new Transforms.Quaternion();
  597. const computeBoundingRectangleMatrix3 = new Matrix3.Matrix3();
  598. PolygonGeometryLibrary.computeBoundingRectangle = function (
  599. planeNormal,
  600. projectPointTo2D,
  601. positions,
  602. angle,
  603. result
  604. ) {
  605. const rotation = Transforms.Quaternion.fromAxisAngle(
  606. planeNormal,
  607. angle,
  608. computeBoundingRectangleQuaternion
  609. );
  610. const textureMatrix = Matrix3.Matrix3.fromQuaternion(
  611. rotation,
  612. computeBoundingRectangleMatrix3
  613. );
  614. let minX = Number.POSITIVE_INFINITY;
  615. let maxX = Number.NEGATIVE_INFINITY;
  616. let minY = Number.POSITIVE_INFINITY;
  617. let maxY = Number.NEGATIVE_INFINITY;
  618. const length = positions.length;
  619. for (let i = 0; i < length; ++i) {
  620. const p = Matrix3.Cartesian3.clone(
  621. positions[i],
  622. computeBoundingRectangleCartesian3
  623. );
  624. Matrix3.Matrix3.multiplyByVector(textureMatrix, p, p);
  625. const st = projectPointTo2D(p, computeBoundingRectangleCartesian2);
  626. if (defaultValue.defined(st)) {
  627. minX = Math.min(minX, st.x);
  628. maxX = Math.max(maxX, st.x);
  629. minY = Math.min(minY, st.y);
  630. maxY = Math.max(maxY, st.y);
  631. }
  632. }
  633. result.x = minX;
  634. result.y = minY;
  635. result.width = maxX - minX;
  636. result.height = maxY - minY;
  637. return result;
  638. };
  639. PolygonGeometryLibrary.createGeometryFromPositions = function (
  640. ellipsoid,
  641. polygon,
  642. textureCoordinates,
  643. granularity,
  644. perPositionHeight,
  645. vertexFormat,
  646. arcType
  647. ) {
  648. let indices = PolygonPipeline.PolygonPipeline.triangulate(polygon.positions2D, polygon.holes);
  649. /* If polygon is completely unrenderable, just use the first three vertices */
  650. if (indices.length < 3) {
  651. indices = [0, 1, 2];
  652. }
  653. const positions = polygon.positions;
  654. const hasTexcoords = defaultValue.defined(textureCoordinates);
  655. const texcoords = hasTexcoords ? textureCoordinates.positions : undefined;
  656. if (perPositionHeight) {
  657. const length = positions.length;
  658. const flattenedPositions = new Array(length * 3);
  659. let index = 0;
  660. for (let i = 0; i < length; i++) {
  661. const p = positions[i];
  662. flattenedPositions[index++] = p.x;
  663. flattenedPositions[index++] = p.y;
  664. flattenedPositions[index++] = p.z;
  665. }
  666. const geometryOptions = {
  667. attributes: {
  668. position: new GeometryAttribute.GeometryAttribute({
  669. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  670. componentsPerAttribute: 3,
  671. values: flattenedPositions,
  672. }),
  673. },
  674. indices: indices,
  675. primitiveType: GeometryAttribute.PrimitiveType.TRIANGLES,
  676. };
  677. if (hasTexcoords) {
  678. geometryOptions.attributes.st = new GeometryAttribute.GeometryAttribute({
  679. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  680. componentsPerAttribute: 2,
  681. values: Matrix2.Cartesian2.packArray(texcoords),
  682. });
  683. }
  684. const geometry = new GeometryAttribute.Geometry(geometryOptions);
  685. if (vertexFormat.normal) {
  686. return GeometryPipeline.GeometryPipeline.computeNormal(geometry);
  687. }
  688. return geometry;
  689. }
  690. if (arcType === ArcType.ArcType.GEODESIC) {
  691. return PolygonPipeline.PolygonPipeline.computeSubdivision(
  692. ellipsoid,
  693. positions,
  694. indices,
  695. texcoords,
  696. granularity
  697. );
  698. } else if (arcType === ArcType.ArcType.RHUMB) {
  699. return PolygonPipeline.PolygonPipeline.computeRhumbLineSubdivision(
  700. ellipsoid,
  701. positions,
  702. indices,
  703. texcoords,
  704. granularity
  705. );
  706. }
  707. };
  708. const computeWallTexcoordsSubdivided = [];
  709. const computeWallIndicesSubdivided = [];
  710. const p1Scratch = new Matrix3.Cartesian3();
  711. const p2Scratch = new Matrix3.Cartesian3();
  712. PolygonGeometryLibrary.computeWallGeometry = function (
  713. positions,
  714. textureCoordinates,
  715. ellipsoid,
  716. granularity,
  717. perPositionHeight,
  718. arcType
  719. ) {
  720. let edgePositions;
  721. let topEdgeLength;
  722. let i;
  723. let p1;
  724. let p2;
  725. let t1;
  726. let t2;
  727. let edgeTexcoords;
  728. let topEdgeTexcoordLength;
  729. let length = positions.length;
  730. let index = 0;
  731. let textureIndex = 0;
  732. const hasTexcoords = defaultValue.defined(textureCoordinates);
  733. const texcoords = hasTexcoords ? textureCoordinates.positions : undefined;
  734. if (!perPositionHeight) {
  735. const minDistance = Math$1.CesiumMath.chordLength(
  736. granularity,
  737. ellipsoid.maximumRadius
  738. );
  739. let numVertices = 0;
  740. if (arcType === ArcType.ArcType.GEODESIC) {
  741. for (i = 0; i < length; i++) {
  742. numVertices += PolygonGeometryLibrary.subdivideLineCount(
  743. positions[i],
  744. positions[(i + 1) % length],
  745. minDistance
  746. );
  747. }
  748. } else if (arcType === ArcType.ArcType.RHUMB) {
  749. for (i = 0; i < length; i++) {
  750. numVertices += PolygonGeometryLibrary.subdivideRhumbLineCount(
  751. ellipsoid,
  752. positions[i],
  753. positions[(i + 1) % length],
  754. minDistance
  755. );
  756. }
  757. }
  758. topEdgeLength = (numVertices + length) * 3;
  759. edgePositions = new Array(topEdgeLength * 2);
  760. if (hasTexcoords) {
  761. topEdgeTexcoordLength = (numVertices + length) * 2;
  762. edgeTexcoords = new Array(topEdgeTexcoordLength * 2);
  763. }
  764. for (i = 0; i < length; i++) {
  765. p1 = positions[i];
  766. p2 = positions[(i + 1) % length];
  767. let tempPositions;
  768. let tempTexcoords;
  769. if (hasTexcoords) {
  770. t1 = texcoords[i];
  771. t2 = texcoords[(i + 1) % length];
  772. }
  773. if (arcType === ArcType.ArcType.GEODESIC) {
  774. tempPositions = PolygonGeometryLibrary.subdivideLine(
  775. p1,
  776. p2,
  777. minDistance,
  778. computeWallIndicesSubdivided
  779. );
  780. if (hasTexcoords) {
  781. tempTexcoords = PolygonGeometryLibrary.subdivideTexcoordLine(
  782. t1,
  783. t2,
  784. p1,
  785. p2,
  786. minDistance,
  787. computeWallTexcoordsSubdivided
  788. );
  789. }
  790. } else if (arcType === ArcType.ArcType.RHUMB) {
  791. tempPositions = PolygonGeometryLibrary.subdivideRhumbLine(
  792. ellipsoid,
  793. p1,
  794. p2,
  795. minDistance,
  796. computeWallIndicesSubdivided
  797. );
  798. if (hasTexcoords) {
  799. tempTexcoords = PolygonGeometryLibrary.subdivideTexcoordRhumbLine(
  800. t1,
  801. t2,
  802. ellipsoid,
  803. p1,
  804. p2,
  805. minDistance,
  806. computeWallTexcoordsSubdivided
  807. );
  808. }
  809. }
  810. const tempPositionsLength = tempPositions.length;
  811. for (let j = 0; j < tempPositionsLength; ++j, ++index) {
  812. edgePositions[index] = tempPositions[j];
  813. edgePositions[index + topEdgeLength] = tempPositions[j];
  814. }
  815. edgePositions[index] = p2.x;
  816. edgePositions[index + topEdgeLength] = p2.x;
  817. ++index;
  818. edgePositions[index] = p2.y;
  819. edgePositions[index + topEdgeLength] = p2.y;
  820. ++index;
  821. edgePositions[index] = p2.z;
  822. edgePositions[index + topEdgeLength] = p2.z;
  823. ++index;
  824. if (hasTexcoords) {
  825. const tempTexcoordsLength = tempTexcoords.length;
  826. for (let k = 0; k < tempTexcoordsLength; ++k, ++textureIndex) {
  827. edgeTexcoords[textureIndex] = tempTexcoords[k];
  828. edgeTexcoords[textureIndex + topEdgeTexcoordLength] =
  829. tempTexcoords[k];
  830. }
  831. edgeTexcoords[textureIndex] = t2.x;
  832. edgeTexcoords[textureIndex + topEdgeTexcoordLength] = t2.x;
  833. ++textureIndex;
  834. edgeTexcoords[textureIndex] = t2.y;
  835. edgeTexcoords[textureIndex + topEdgeTexcoordLength] = t2.y;
  836. ++textureIndex;
  837. }
  838. }
  839. } else {
  840. topEdgeLength = length * 3 * 2;
  841. edgePositions = new Array(topEdgeLength * 2);
  842. if (hasTexcoords) {
  843. topEdgeTexcoordLength = length * 2 * 2;
  844. edgeTexcoords = new Array(topEdgeTexcoordLength * 2);
  845. }
  846. for (i = 0; i < length; i++) {
  847. p1 = positions[i];
  848. p2 = positions[(i + 1) % length];
  849. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.x;
  850. ++index;
  851. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.y;
  852. ++index;
  853. edgePositions[index] = edgePositions[index + topEdgeLength] = p1.z;
  854. ++index;
  855. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.x;
  856. ++index;
  857. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.y;
  858. ++index;
  859. edgePositions[index] = edgePositions[index + topEdgeLength] = p2.z;
  860. ++index;
  861. if (hasTexcoords) {
  862. t1 = texcoords[i];
  863. t2 = texcoords[(i + 1) % length];
  864. edgeTexcoords[textureIndex] = edgeTexcoords[
  865. textureIndex + topEdgeTexcoordLength
  866. ] = t1.x;
  867. ++textureIndex;
  868. edgeTexcoords[textureIndex] = edgeTexcoords[
  869. textureIndex + topEdgeTexcoordLength
  870. ] = t1.y;
  871. ++textureIndex;
  872. edgeTexcoords[textureIndex] = edgeTexcoords[
  873. textureIndex + topEdgeTexcoordLength
  874. ] = t2.x;
  875. ++textureIndex;
  876. edgeTexcoords[textureIndex] = edgeTexcoords[
  877. textureIndex + topEdgeTexcoordLength
  878. ] = t2.y;
  879. ++textureIndex;
  880. }
  881. }
  882. }
  883. length = edgePositions.length;
  884. const indices = IndexDatatype.IndexDatatype.createTypedArray(
  885. length / 3,
  886. length - positions.length * 6
  887. );
  888. let edgeIndex = 0;
  889. length /= 6;
  890. for (i = 0; i < length; i++) {
  891. const UL = i;
  892. const UR = UL + 1;
  893. const LL = UL + length;
  894. const LR = LL + 1;
  895. p1 = Matrix3.Cartesian3.fromArray(edgePositions, UL * 3, p1Scratch);
  896. p2 = Matrix3.Cartesian3.fromArray(edgePositions, UR * 3, p2Scratch);
  897. if (
  898. Matrix3.Cartesian3.equalsEpsilon(
  899. p1,
  900. p2,
  901. Math$1.CesiumMath.EPSILON10,
  902. Math$1.CesiumMath.EPSILON10
  903. )
  904. ) {
  905. //skip corner
  906. continue;
  907. }
  908. indices[edgeIndex++] = UL;
  909. indices[edgeIndex++] = LL;
  910. indices[edgeIndex++] = UR;
  911. indices[edgeIndex++] = UR;
  912. indices[edgeIndex++] = LL;
  913. indices[edgeIndex++] = LR;
  914. }
  915. const geometryOptions = {
  916. attributes: new GeometryAttributes.GeometryAttributes({
  917. position: new GeometryAttribute.GeometryAttribute({
  918. componentDatatype: ComponentDatatype.ComponentDatatype.DOUBLE,
  919. componentsPerAttribute: 3,
  920. values: edgePositions,
  921. }),
  922. }),
  923. indices: indices,
  924. primitiveType: GeometryAttribute.PrimitiveType.TRIANGLES,
  925. };
  926. if (hasTexcoords) {
  927. geometryOptions.attributes.st = new GeometryAttribute.GeometryAttribute({
  928. componentDatatype: ComponentDatatype.ComponentDatatype.FLOAT,
  929. componentsPerAttribute: 2,
  930. values: edgeTexcoords,
  931. });
  932. }
  933. const geometry = new GeometryAttribute.Geometry(geometryOptions);
  934. return geometry;
  935. };
  936. var PolygonGeometryLibrary$1 = PolygonGeometryLibrary;
  937. exports.PolygonGeometryLibrary = PolygonGeometryLibrary$1;
  938. }));