createPolygonOutlineGeometry.js 26 KB

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