PolygonGeometryLibrary-0f4bb1aa.js 32 KB

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