PolygonOutlineGeometry.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. import ArcType from "./ArcType.js";
  2. import arrayFill from "./arrayFill.js";
  3. import BoundingSphere from "./BoundingSphere.js";
  4. import Check from "./Check.js";
  5. import ComponentDatatype from "./ComponentDatatype.js";
  6. import defaultValue from "./defaultValue.js";
  7. import defined from "./defined.js";
  8. import DeveloperError from "./DeveloperError.js";
  9. import Ellipsoid from "./Ellipsoid.js";
  10. import EllipsoidTangentPlane from "./EllipsoidTangentPlane.js";
  11. import Geometry from "./Geometry.js";
  12. import GeometryAttribute from "./GeometryAttribute.js";
  13. import GeometryAttributes from "./GeometryAttributes.js";
  14. import GeometryInstance from "./GeometryInstance.js";
  15. import GeometryOffsetAttribute from "./GeometryOffsetAttribute.js";
  16. import GeometryPipeline from "./GeometryPipeline.js";
  17. import IndexDatatype from "./IndexDatatype.js";
  18. import CesiumMath from "./Math.js";
  19. import PolygonGeometryLibrary from "./PolygonGeometryLibrary.js";
  20. import PolygonPipeline from "./PolygonPipeline.js";
  21. import PrimitiveType from "./PrimitiveType.js";
  22. import WindingOrder from "./WindingOrder.js";
  23. var createGeometryFromPositionsPositions = [];
  24. var createGeometryFromPositionsSubdivided = [];
  25. function createGeometryFromPositions(
  26. ellipsoid,
  27. positions,
  28. minDistance,
  29. perPositionHeight,
  30. arcType
  31. ) {
  32. var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
  33. var positions2D = tangentPlane.projectPointsOntoPlane(
  34. positions,
  35. createGeometryFromPositionsPositions
  36. );
  37. var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
  38. if (originalWindingOrder === WindingOrder.CLOCKWISE) {
  39. positions2D.reverse();
  40. positions = positions.slice().reverse();
  41. }
  42. var subdividedPositions;
  43. var i;
  44. var length = positions.length;
  45. var index = 0;
  46. if (!perPositionHeight) {
  47. var numVertices = 0;
  48. if (arcType === ArcType.GEODESIC) {
  49. for (i = 0; i < length; i++) {
  50. numVertices += PolygonGeometryLibrary.subdivideLineCount(
  51. positions[i],
  52. positions[(i + 1) % length],
  53. minDistance
  54. );
  55. }
  56. } else if (arcType === ArcType.RHUMB) {
  57. for (i = 0; i < length; i++) {
  58. numVertices += PolygonGeometryLibrary.subdivideRhumbLineCount(
  59. ellipsoid,
  60. positions[i],
  61. positions[(i + 1) % length],
  62. minDistance
  63. );
  64. }
  65. }
  66. subdividedPositions = new Float64Array(numVertices * 3);
  67. for (i = 0; i < length; i++) {
  68. var tempPositions;
  69. if (arcType === ArcType.GEODESIC) {
  70. tempPositions = PolygonGeometryLibrary.subdivideLine(
  71. positions[i],
  72. positions[(i + 1) % length],
  73. minDistance,
  74. createGeometryFromPositionsSubdivided
  75. );
  76. } else if (arcType === ArcType.RHUMB) {
  77. tempPositions = PolygonGeometryLibrary.subdivideRhumbLine(
  78. ellipsoid,
  79. positions[i],
  80. positions[(i + 1) % length],
  81. minDistance,
  82. createGeometryFromPositionsSubdivided
  83. );
  84. }
  85. var tempPositionsLength = tempPositions.length;
  86. for (var j = 0; j < tempPositionsLength; ++j) {
  87. subdividedPositions[index++] = tempPositions[j];
  88. }
  89. }
  90. } else {
  91. subdividedPositions = new Float64Array(length * 2 * 3);
  92. for (i = 0; i < length; i++) {
  93. var p0 = positions[i];
  94. var p1 = positions[(i + 1) % length];
  95. subdividedPositions[index++] = p0.x;
  96. subdividedPositions[index++] = p0.y;
  97. subdividedPositions[index++] = p0.z;
  98. subdividedPositions[index++] = p1.x;
  99. subdividedPositions[index++] = p1.y;
  100. subdividedPositions[index++] = p1.z;
  101. }
  102. }
  103. length = subdividedPositions.length / 3;
  104. var indicesSize = length * 2;
  105. var indices = IndexDatatype.createTypedArray(length, indicesSize);
  106. index = 0;
  107. for (i = 0; i < length - 1; i++) {
  108. indices[index++] = i;
  109. indices[index++] = i + 1;
  110. }
  111. indices[index++] = length - 1;
  112. indices[index++] = 0;
  113. return new GeometryInstance({
  114. geometry: new Geometry({
  115. attributes: new GeometryAttributes({
  116. position: new GeometryAttribute({
  117. componentDatatype: ComponentDatatype.DOUBLE,
  118. componentsPerAttribute: 3,
  119. values: subdividedPositions,
  120. }),
  121. }),
  122. indices: indices,
  123. primitiveType: PrimitiveType.LINES,
  124. }),
  125. });
  126. }
  127. function createGeometryFromPositionsExtruded(
  128. ellipsoid,
  129. positions,
  130. minDistance,
  131. perPositionHeight,
  132. arcType
  133. ) {
  134. var tangentPlane = EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
  135. var positions2D = tangentPlane.projectPointsOntoPlane(
  136. positions,
  137. createGeometryFromPositionsPositions
  138. );
  139. var originalWindingOrder = PolygonPipeline.computeWindingOrder2D(positions2D);
  140. if (originalWindingOrder === WindingOrder.CLOCKWISE) {
  141. positions2D.reverse();
  142. positions = positions.slice().reverse();
  143. }
  144. var subdividedPositions;
  145. var i;
  146. var length = positions.length;
  147. var corners = new Array(length);
  148. var index = 0;
  149. if (!perPositionHeight) {
  150. var numVertices = 0;
  151. if (arcType === ArcType.GEODESIC) {
  152. for (i = 0; i < length; i++) {
  153. numVertices += PolygonGeometryLibrary.subdivideLineCount(
  154. positions[i],
  155. positions[(i + 1) % length],
  156. minDistance
  157. );
  158. }
  159. } else if (arcType === ArcType.RHUMB) {
  160. for (i = 0; i < length; i++) {
  161. numVertices += PolygonGeometryLibrary.subdivideRhumbLineCount(
  162. ellipsoid,
  163. positions[i],
  164. positions[(i + 1) % length],
  165. minDistance
  166. );
  167. }
  168. }
  169. subdividedPositions = new Float64Array(numVertices * 3 * 2);
  170. for (i = 0; i < length; ++i) {
  171. corners[i] = index / 3;
  172. var tempPositions;
  173. if (arcType === ArcType.GEODESIC) {
  174. tempPositions = PolygonGeometryLibrary.subdivideLine(
  175. positions[i],
  176. positions[(i + 1) % length],
  177. minDistance,
  178. createGeometryFromPositionsSubdivided
  179. );
  180. } else if (arcType === ArcType.RHUMB) {
  181. tempPositions = PolygonGeometryLibrary.subdivideRhumbLine(
  182. ellipsoid,
  183. positions[i],
  184. positions[(i + 1) % length],
  185. minDistance,
  186. createGeometryFromPositionsSubdivided
  187. );
  188. }
  189. var tempPositionsLength = tempPositions.length;
  190. for (var j = 0; j < tempPositionsLength; ++j) {
  191. subdividedPositions[index++] = tempPositions[j];
  192. }
  193. }
  194. } else {
  195. subdividedPositions = new Float64Array(length * 2 * 3 * 2);
  196. for (i = 0; i < length; ++i) {
  197. corners[i] = index / 3;
  198. var p0 = positions[i];
  199. var p1 = positions[(i + 1) % length];
  200. subdividedPositions[index++] = p0.x;
  201. subdividedPositions[index++] = p0.y;
  202. subdividedPositions[index++] = p0.z;
  203. subdividedPositions[index++] = p1.x;
  204. subdividedPositions[index++] = p1.y;
  205. subdividedPositions[index++] = p1.z;
  206. }
  207. }
  208. length = subdividedPositions.length / (3 * 2);
  209. var cornersLength = corners.length;
  210. var indicesSize = (length * 2 + cornersLength) * 2;
  211. var indices = IndexDatatype.createTypedArray(
  212. length + cornersLength,
  213. indicesSize
  214. );
  215. index = 0;
  216. for (i = 0; i < length; ++i) {
  217. indices[index++] = i;
  218. indices[index++] = (i + 1) % length;
  219. indices[index++] = i + length;
  220. indices[index++] = ((i + 1) % length) + length;
  221. }
  222. for (i = 0; i < cornersLength; i++) {
  223. var corner = corners[i];
  224. indices[index++] = corner;
  225. indices[index++] = corner + length;
  226. }
  227. return new GeometryInstance({
  228. geometry: new Geometry({
  229. attributes: new GeometryAttributes({
  230. position: new GeometryAttribute({
  231. componentDatatype: ComponentDatatype.DOUBLE,
  232. componentsPerAttribute: 3,
  233. values: subdividedPositions,
  234. }),
  235. }),
  236. indices: indices,
  237. primitiveType: PrimitiveType.LINES,
  238. }),
  239. });
  240. }
  241. /**
  242. * A description of the outline of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy.
  243. *
  244. * @alias PolygonOutlineGeometry
  245. * @constructor
  246. *
  247. * @param {Object} options Object with the following properties:
  248. * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
  249. * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface.
  250. * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface.
  251. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  252. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  253. * @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.
  254. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  255. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}.
  256. *
  257. * @see PolygonOutlineGeometry#createGeometry
  258. * @see PolygonOutlineGeometry#fromPositions
  259. *
  260. * @example
  261. * // 1. create a polygon outline from points
  262. * var polygon = new Cesium.PolygonOutlineGeometry({
  263. * polygonHierarchy : new Cesium.PolygonHierarchy(
  264. * Cesium.Cartesian3.fromDegreesArray([
  265. * -72.0, 40.0,
  266. * -70.0, 35.0,
  267. * -75.0, 30.0,
  268. * -70.0, 30.0,
  269. * -68.0, 40.0
  270. * ])
  271. * )
  272. * });
  273. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon);
  274. *
  275. * // 2. create a nested polygon with holes outline
  276. * var polygonWithHole = new Cesium.PolygonOutlineGeometry({
  277. * polygonHierarchy : new Cesium.PolygonHierarchy(
  278. * Cesium.Cartesian3.fromDegreesArray([
  279. * -109.0, 30.0,
  280. * -95.0, 30.0,
  281. * -95.0, 40.0,
  282. * -109.0, 40.0
  283. * ]),
  284. * [new Cesium.PolygonHierarchy(
  285. * Cesium.Cartesian3.fromDegreesArray([
  286. * -107.0, 31.0,
  287. * -107.0, 39.0,
  288. * -97.0, 39.0,
  289. * -97.0, 31.0
  290. * ]),
  291. * [new Cesium.PolygonHierarchy(
  292. * Cesium.Cartesian3.fromDegreesArray([
  293. * -105.0, 33.0,
  294. * -99.0, 33.0,
  295. * -99.0, 37.0,
  296. * -105.0, 37.0
  297. * ]),
  298. * [new Cesium.PolygonHierarchy(
  299. * Cesium.Cartesian3.fromDegreesArray([
  300. * -103.0, 34.0,
  301. * -101.0, 34.0,
  302. * -101.0, 36.0,
  303. * -103.0, 36.0
  304. * ])
  305. * )]
  306. * )]
  307. * )]
  308. * )
  309. * });
  310. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygonWithHole);
  311. *
  312. * // 3. create extruded polygon outline
  313. * var extrudedPolygon = new Cesium.PolygonOutlineGeometry({
  314. * polygonHierarchy : new Cesium.PolygonHierarchy(
  315. * Cesium.Cartesian3.fromDegreesArray([
  316. * -72.0, 40.0,
  317. * -70.0, 35.0,
  318. * -75.0, 30.0,
  319. * -70.0, 30.0,
  320. * -68.0, 40.0
  321. * ])
  322. * ),
  323. * extrudedHeight: 300000
  324. * });
  325. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(extrudedPolygon);
  326. */
  327. function PolygonOutlineGeometry(options) {
  328. //>>includeStart('debug', pragmas.debug);
  329. Check.typeOf.object("options", options);
  330. Check.typeOf.object("options.polygonHierarchy", options.polygonHierarchy);
  331. if (options.perPositionHeight && defined(options.height)) {
  332. throw new DeveloperError(
  333. "Cannot use both options.perPositionHeight and options.height"
  334. );
  335. }
  336. if (
  337. defined(options.arcType) &&
  338. options.arcType !== ArcType.GEODESIC &&
  339. options.arcType !== ArcType.RHUMB
  340. ) {
  341. throw new DeveloperError(
  342. "Invalid arcType. Valid options are ArcType.GEODESIC and ArcType.RHUMB."
  343. );
  344. }
  345. //>>includeEnd('debug');
  346. var polygonHierarchy = options.polygonHierarchy;
  347. var ellipsoid = defaultValue(options.ellipsoid, Ellipsoid.WGS84);
  348. var granularity = defaultValue(
  349. options.granularity,
  350. CesiumMath.RADIANS_PER_DEGREE
  351. );
  352. var perPositionHeight = defaultValue(options.perPositionHeight, false);
  353. var perPositionHeightExtrude =
  354. perPositionHeight && defined(options.extrudedHeight);
  355. var arcType = defaultValue(options.arcType, ArcType.GEODESIC);
  356. var height = defaultValue(options.height, 0.0);
  357. var extrudedHeight = defaultValue(options.extrudedHeight, height);
  358. if (!perPositionHeightExtrude) {
  359. var h = Math.max(height, extrudedHeight);
  360. extrudedHeight = Math.min(height, extrudedHeight);
  361. height = h;
  362. }
  363. this._ellipsoid = Ellipsoid.clone(ellipsoid);
  364. this._granularity = granularity;
  365. this._height = height;
  366. this._extrudedHeight = extrudedHeight;
  367. this._arcType = arcType;
  368. this._polygonHierarchy = polygonHierarchy;
  369. this._perPositionHeight = perPositionHeight;
  370. this._perPositionHeightExtrude = perPositionHeightExtrude;
  371. this._offsetAttribute = options.offsetAttribute;
  372. this._workerName = "createPolygonOutlineGeometry";
  373. /**
  374. * The number of elements used to pack the object into an array.
  375. * @type {Number}
  376. */
  377. this.packedLength =
  378. PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) +
  379. Ellipsoid.packedLength +
  380. 8;
  381. }
  382. /**
  383. * Stores the provided instance into the provided array.
  384. *
  385. * @param {PolygonOutlineGeometry} value The value to pack.
  386. * @param {Number[]} array The array to pack into.
  387. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  388. *
  389. * @returns {Number[]} The array that was packed into
  390. */
  391. PolygonOutlineGeometry.pack = function (value, array, startingIndex) {
  392. //>>includeStart('debug', pragmas.debug);
  393. Check.typeOf.object("value", value);
  394. Check.defined("array", array);
  395. //>>includeEnd('debug');
  396. startingIndex = defaultValue(startingIndex, 0);
  397. startingIndex = PolygonGeometryLibrary.packPolygonHierarchy(
  398. value._polygonHierarchy,
  399. array,
  400. startingIndex
  401. );
  402. Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  403. startingIndex += Ellipsoid.packedLength;
  404. array[startingIndex++] = value._height;
  405. array[startingIndex++] = value._extrudedHeight;
  406. array[startingIndex++] = value._granularity;
  407. array[startingIndex++] = value._perPositionHeightExtrude ? 1.0 : 0.0;
  408. array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0;
  409. array[startingIndex++] = value._arcType;
  410. array[startingIndex++] = defaultValue(value._offsetAttribute, -1);
  411. array[startingIndex] = value.packedLength;
  412. return array;
  413. };
  414. var scratchEllipsoid = Ellipsoid.clone(Ellipsoid.UNIT_SPHERE);
  415. var dummyOptions = {
  416. polygonHierarchy: {},
  417. };
  418. /**
  419. * Retrieves an instance from a packed array.
  420. *
  421. * @param {Number[]} array The packed array.
  422. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  423. * @param {PolygonOutlineGeometry} [result] The object into which to store the result.
  424. * @returns {PolygonOutlineGeometry} The modified result parameter or a new PolygonOutlineGeometry instance if one was not provided.
  425. */
  426. PolygonOutlineGeometry.unpack = function (array, startingIndex, result) {
  427. //>>includeStart('debug', pragmas.debug);
  428. Check.defined("array", array);
  429. //>>includeEnd('debug');
  430. startingIndex = defaultValue(startingIndex, 0);
  431. var polygonHierarchy = PolygonGeometryLibrary.unpackPolygonHierarchy(
  432. array,
  433. startingIndex
  434. );
  435. startingIndex = polygonHierarchy.startingIndex;
  436. delete polygonHierarchy.startingIndex;
  437. var ellipsoid = Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  438. startingIndex += Ellipsoid.packedLength;
  439. var height = array[startingIndex++];
  440. var extrudedHeight = array[startingIndex++];
  441. var granularity = array[startingIndex++];
  442. var perPositionHeightExtrude = array[startingIndex++] === 1.0;
  443. var perPositionHeight = array[startingIndex++] === 1.0;
  444. var arcType = array[startingIndex++];
  445. var offsetAttribute = array[startingIndex++];
  446. var packedLength = array[startingIndex];
  447. if (!defined(result)) {
  448. result = new PolygonOutlineGeometry(dummyOptions);
  449. }
  450. result._polygonHierarchy = polygonHierarchy;
  451. result._ellipsoid = Ellipsoid.clone(ellipsoid, result._ellipsoid);
  452. result._height = height;
  453. result._extrudedHeight = extrudedHeight;
  454. result._granularity = granularity;
  455. result._perPositionHeight = perPositionHeight;
  456. result._perPositionHeightExtrude = perPositionHeightExtrude;
  457. result._arcType = arcType;
  458. result._offsetAttribute =
  459. offsetAttribute === -1 ? undefined : offsetAttribute;
  460. result.packedLength = packedLength;
  461. return result;
  462. };
  463. /**
  464. * A description of a polygon outline from an array of positions.
  465. *
  466. * @param {Object} options Object with the following properties:
  467. * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon.
  468. * @param {Number} [options.height=0.0] The height of the polygon.
  469. * @param {Number} [options.extrudedHeight] The height of the polygon extrusion.
  470. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  471. * @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.
  472. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  473. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link LinkType.GEODESIC} and {@link ArcType.RHUMB}.
  474. * @returns {PolygonOutlineGeometry}
  475. *
  476. *
  477. * @example
  478. * // create a polygon from points
  479. * var polygon = Cesium.PolygonOutlineGeometry.fromPositions({
  480. * positions : Cesium.Cartesian3.fromDegreesArray([
  481. * -72.0, 40.0,
  482. * -70.0, 35.0,
  483. * -75.0, 30.0,
  484. * -70.0, 30.0,
  485. * -68.0, 40.0
  486. * ])
  487. * });
  488. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon);
  489. *
  490. * @see PolygonOutlineGeometry#createGeometry
  491. */
  492. PolygonOutlineGeometry.fromPositions = function (options) {
  493. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  494. //>>includeStart('debug', pragmas.debug);
  495. Check.defined("options.positions", options.positions);
  496. //>>includeEnd('debug');
  497. var newOptions = {
  498. polygonHierarchy: {
  499. positions: options.positions,
  500. },
  501. height: options.height,
  502. extrudedHeight: options.extrudedHeight,
  503. ellipsoid: options.ellipsoid,
  504. granularity: options.granularity,
  505. perPositionHeight: options.perPositionHeight,
  506. arcType: options.arcType,
  507. offsetAttribute: options.offsetAttribute,
  508. };
  509. return new PolygonOutlineGeometry(newOptions);
  510. };
  511. /**
  512. * Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere.
  513. *
  514. * @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline.
  515. * @returns {Geometry|undefined} The computed vertices and indices.
  516. */
  517. PolygonOutlineGeometry.createGeometry = function (polygonGeometry) {
  518. var ellipsoid = polygonGeometry._ellipsoid;
  519. var granularity = polygonGeometry._granularity;
  520. var polygonHierarchy = polygonGeometry._polygonHierarchy;
  521. var perPositionHeight = polygonGeometry._perPositionHeight;
  522. var arcType = polygonGeometry._arcType;
  523. var polygons = PolygonGeometryLibrary.polygonOutlinesFromHierarchy(
  524. polygonHierarchy,
  525. !perPositionHeight,
  526. ellipsoid
  527. );
  528. if (polygons.length === 0) {
  529. return undefined;
  530. }
  531. var geometryInstance;
  532. var geometries = [];
  533. var minDistance = CesiumMath.chordLength(
  534. granularity,
  535. ellipsoid.maximumRadius
  536. );
  537. var height = polygonGeometry._height;
  538. var extrudedHeight = polygonGeometry._extrudedHeight;
  539. var extrude =
  540. polygonGeometry._perPositionHeightExtrude ||
  541. !CesiumMath.equalsEpsilon(height, extrudedHeight, 0, CesiumMath.EPSILON2);
  542. var offsetValue;
  543. var i;
  544. if (extrude) {
  545. for (i = 0; i < polygons.length; i++) {
  546. geometryInstance = createGeometryFromPositionsExtruded(
  547. ellipsoid,
  548. polygons[i],
  549. minDistance,
  550. perPositionHeight,
  551. arcType
  552. );
  553. geometryInstance.geometry = PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(
  554. geometryInstance.geometry,
  555. height,
  556. extrudedHeight,
  557. ellipsoid,
  558. perPositionHeight
  559. );
  560. if (defined(polygonGeometry._offsetAttribute)) {
  561. var size =
  562. geometryInstance.geometry.attributes.position.values.length / 3;
  563. var offsetAttribute = new Uint8Array(size);
  564. if (polygonGeometry._offsetAttribute === GeometryOffsetAttribute.TOP) {
  565. offsetAttribute = arrayFill(offsetAttribute, 1, 0, size / 2);
  566. } else {
  567. offsetValue =
  568. polygonGeometry._offsetAttribute === GeometryOffsetAttribute.NONE
  569. ? 0
  570. : 1;
  571. offsetAttribute = arrayFill(offsetAttribute, offsetValue);
  572. }
  573. geometryInstance.geometry.attributes.applyOffset = new GeometryAttribute(
  574. {
  575. componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
  576. componentsPerAttribute: 1,
  577. values: offsetAttribute,
  578. }
  579. );
  580. }
  581. geometries.push(geometryInstance);
  582. }
  583. } else {
  584. for (i = 0; i < polygons.length; i++) {
  585. geometryInstance = createGeometryFromPositions(
  586. ellipsoid,
  587. polygons[i],
  588. minDistance,
  589. perPositionHeight,
  590. arcType
  591. );
  592. geometryInstance.geometry.attributes.position.values = PolygonPipeline.scaleToGeodeticHeight(
  593. geometryInstance.geometry.attributes.position.values,
  594. height,
  595. ellipsoid,
  596. !perPositionHeight
  597. );
  598. if (defined(polygonGeometry._offsetAttribute)) {
  599. var length =
  600. geometryInstance.geometry.attributes.position.values.length;
  601. var applyOffset = new Uint8Array(length / 3);
  602. offsetValue =
  603. polygonGeometry._offsetAttribute === GeometryOffsetAttribute.NONE
  604. ? 0
  605. : 1;
  606. arrayFill(applyOffset, offsetValue);
  607. geometryInstance.geometry.attributes.applyOffset = new GeometryAttribute(
  608. {
  609. componentDatatype: ComponentDatatype.UNSIGNED_BYTE,
  610. componentsPerAttribute: 1,
  611. values: applyOffset,
  612. }
  613. );
  614. }
  615. geometries.push(geometryInstance);
  616. }
  617. }
  618. var geometry = GeometryPipeline.combineInstances(geometries)[0];
  619. var boundingSphere = BoundingSphere.fromVertices(
  620. geometry.attributes.position.values
  621. );
  622. return new Geometry({
  623. attributes: geometry.attributes,
  624. indices: geometry.indices,
  625. primitiveType: geometry.primitiveType,
  626. boundingSphere: boundingSphere,
  627. offsetAttribute: polygonGeometry._offsetAttribute,
  628. });
  629. };
  630. export default PolygonOutlineGeometry;