createPolygonOutlineGeometry.js 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /**
  2. * Cesium - https://github.com/AnalyticalGraphicsInc/cesium
  3. *
  4. * Copyright 2011-2017 Cesium Contributors
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * Columbus View (Pat. Pend.)
  19. *
  20. * Portions licensed separately.
  21. * See https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md for full licensing details.
  22. */
  23. define(['./when-8d13db60', './Check-70bec281', './Math-61ede240', './Cartographic-fe4be337', './Cartesian2-85064f09', './BoundingSphere-775c5788', './Cartesian4-5af5bb24', './RuntimeError-ba10bc3e', './WebGLConstants-4c11ee5f', './ComponentDatatype-5862616f', './GeometryAttribute-91704ebb', './PrimitiveType-97893bc7', './FeatureDetection-7bd32c34', './Transforms-b2e71640', './buildModuleUrl-14bfe498', './GeometryAttributes-aacecde6', './AttributeCompression-84a90a13', './GeometryPipeline-f95a0a6f', './EncodedCartesian3-a569cba8', './IndexDatatype-9435b55f', './IntersectionTests-397d9494', './Plane-8390418f', './GeometryOffsetAttribute-ca302482', './GeometryInstance-93a01b5d', './arrayRemoveDuplicates-f0b089b1', './EllipsoidTangentPlane-a815c96f', './ArcType-66bc286a', './EllipsoidRhumbLine-f161e674', './earcut-2.2.1-b404d9e6', './PolygonPipeline-6a35d737', './PolygonGeometryLibrary-073be5ba'], function (when, Check, _Math, Cartographic, Cartesian2, BoundingSphere, Cartesian4, RuntimeError, WebGLConstants, ComponentDatatype, GeometryAttribute, PrimitiveType, FeatureDetection, Transforms, buildModuleUrl, GeometryAttributes, AttributeCompression, GeometryPipeline, EncodedCartesian3, IndexDatatype, IntersectionTests, Plane, GeometryOffsetAttribute, GeometryInstance, arrayRemoveDuplicates, EllipsoidTangentPlane, ArcType, EllipsoidRhumbLine, earcut2_2_1, PolygonPipeline, PolygonGeometryLibrary) { 'use strict';
  24. var createGeometryFromPositionsPositions = [];
  25. var createGeometryFromPositionsSubdivided = [];
  26. function createGeometryFromPositions(ellipsoid, positions, minDistance, perPositionHeight, arcType) {
  27. var tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
  28. var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions);
  29. var originalWindingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(positions2D);
  30. if (originalWindingOrder === PolygonPipeline.WindingOrder.CLOCKWISE) {
  31. positions2D.reverse();
  32. positions = positions.slice().reverse();
  33. }
  34. var subdividedPositions;
  35. var i;
  36. var length = positions.length;
  37. var index = 0;
  38. if (!perPositionHeight) {
  39. var numVertices = 0;
  40. if (arcType === ArcType.ArcType.GEODESIC) {
  41. for (i = 0; i < length; i++) {
  42. numVertices += PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance);
  43. }
  44. } else if (arcType === ArcType.ArcType.RHUMB) {
  45. for (i = 0; i < length; i++) {
  46. numVertices += PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideRhumbLineCount(ellipsoid, positions[i], positions[(i + 1) % length], minDistance);
  47. }
  48. }
  49. subdividedPositions = new Float64Array(numVertices * 3);
  50. for (i = 0; i < length; i++) {
  51. var tempPositions;
  52. if (arcType === ArcType.ArcType.GEODESIC) {
  53. tempPositions = PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
  54. } else if (arcType === ArcType.ArcType.RHUMB) {
  55. tempPositions = PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideRhumbLine(ellipsoid, positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
  56. }
  57. var tempPositionsLength = tempPositions.length;
  58. for (var j = 0; j < tempPositionsLength; ++j) {
  59. subdividedPositions[index++] = tempPositions[j];
  60. }
  61. }
  62. } else {
  63. subdividedPositions = new Float64Array(length * 2 * 3);
  64. for (i = 0; i < length; i++) {
  65. var p0 = positions[i];
  66. var p1 = positions[(i + 1) % length];
  67. subdividedPositions[index++] = p0.x;
  68. subdividedPositions[index++] = p0.y;
  69. subdividedPositions[index++] = p0.z;
  70. subdividedPositions[index++] = p1.x;
  71. subdividedPositions[index++] = p1.y;
  72. subdividedPositions[index++] = p1.z;
  73. }
  74. }
  75. length = subdividedPositions.length / 3;
  76. var indicesSize = length * 2;
  77. var indices = IndexDatatype.IndexDatatype.createTypedArray(length, indicesSize);
  78. index = 0;
  79. for (i = 0; i < length - 1; i++) {
  80. indices[index++] = i;
  81. indices[index++] = i + 1;
  82. }
  83. indices[index++] = length - 1;
  84. indices[index++] = 0;
  85. return new GeometryInstance.GeometryInstance({
  86. geometry : new GeometryAttribute.Geometry({
  87. attributes : new GeometryAttributes.GeometryAttributes({
  88. position : new GeometryAttribute.GeometryAttribute({
  89. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  90. componentsPerAttribute : 3,
  91. values : subdividedPositions
  92. })
  93. }),
  94. indices : indices,
  95. primitiveType : PrimitiveType.PrimitiveType.LINES
  96. })
  97. });
  98. }
  99. function createGeometryFromPositionsExtruded(ellipsoid, positions, minDistance, perPositionHeight, arcType) {
  100. var tangentPlane = EllipsoidTangentPlane.EllipsoidTangentPlane.fromPoints(positions, ellipsoid);
  101. var positions2D = tangentPlane.projectPointsOntoPlane(positions, createGeometryFromPositionsPositions);
  102. var originalWindingOrder = PolygonPipeline.PolygonPipeline.computeWindingOrder2D(positions2D);
  103. if (originalWindingOrder === PolygonPipeline.WindingOrder.CLOCKWISE) {
  104. positions2D.reverse();
  105. positions = positions.slice().reverse();
  106. }
  107. var subdividedPositions;
  108. var i;
  109. var length = positions.length;
  110. var corners = new Array(length);
  111. var index = 0;
  112. if (!perPositionHeight) {
  113. var numVertices = 0;
  114. if (arcType === ArcType.ArcType.GEODESIC) {
  115. for (i = 0; i < length; i++) {
  116. numVertices += PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideLineCount(positions[i], positions[(i + 1) % length], minDistance);
  117. }
  118. } else if (arcType === ArcType.ArcType.RHUMB) {
  119. for (i = 0; i < length; i++) {
  120. numVertices += PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideRhumbLineCount(ellipsoid, positions[i], positions[(i + 1) % length], minDistance);
  121. }
  122. }
  123. subdividedPositions = new Float64Array(numVertices * 3 * 2);
  124. for (i = 0; i < length; ++i) {
  125. corners[i] = index / 3;
  126. var tempPositions;
  127. if (arcType === ArcType.ArcType.GEODESIC) {
  128. tempPositions = PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideLine(positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
  129. } else if (arcType === ArcType.ArcType.RHUMB) {
  130. tempPositions = PolygonGeometryLibrary.PolygonGeometryLibrary.subdivideRhumbLine(ellipsoid, positions[i], positions[(i + 1) % length], minDistance, createGeometryFromPositionsSubdivided);
  131. }
  132. var tempPositionsLength = tempPositions.length;
  133. for (var j = 0; j < tempPositionsLength; ++j) {
  134. subdividedPositions[index++] = tempPositions[j];
  135. }
  136. }
  137. } else {
  138. subdividedPositions = new Float64Array(length * 2 * 3 * 2);
  139. for (i = 0; i < length; ++i) {
  140. corners[i] = index / 3;
  141. var p0 = positions[i];
  142. var p1 = positions[(i + 1) % length];
  143. subdividedPositions[index++] = p0.x;
  144. subdividedPositions[index++] = p0.y;
  145. subdividedPositions[index++] = p0.z;
  146. subdividedPositions[index++] = p1.x;
  147. subdividedPositions[index++] = p1.y;
  148. subdividedPositions[index++] = p1.z;
  149. }
  150. }
  151. length = subdividedPositions.length / (3 * 2);
  152. var cornersLength = corners.length;
  153. var indicesSize = ((length * 2) + cornersLength) * 2;
  154. var indices = IndexDatatype.IndexDatatype.createTypedArray(length, indicesSize);
  155. index = 0;
  156. for (i = 0; i < length; ++i) {
  157. indices[index++] = i;
  158. indices[index++] = (i + 1) % length;
  159. indices[index++] = i + length;
  160. indices[index++] = ((i + 1) % length) + length;
  161. }
  162. for (i = 0; i < cornersLength; i++) {
  163. var corner = corners[i];
  164. indices[index++] = corner;
  165. indices[index++] = corner + length;
  166. }
  167. return new GeometryInstance.GeometryInstance({
  168. geometry : new GeometryAttribute.Geometry({
  169. attributes : new GeometryAttributes.GeometryAttributes({
  170. position : new GeometryAttribute.GeometryAttribute({
  171. componentDatatype : ComponentDatatype.ComponentDatatype.DOUBLE,
  172. componentsPerAttribute : 3,
  173. values : subdividedPositions
  174. })
  175. }),
  176. indices : indices,
  177. primitiveType : PrimitiveType.PrimitiveType.LINES
  178. })
  179. });
  180. }
  181. /**
  182. * A description of the outline of a polygon on the ellipsoid. The polygon is defined by a polygon hierarchy.
  183. *
  184. * @alias PolygonOutlineGeometry
  185. * @constructor
  186. *
  187. * @param {Object} options Object with the following properties:
  188. * @param {PolygonHierarchy} options.polygonHierarchy A polygon hierarchy that can include holes.
  189. * @param {Number} [options.height=0.0] The distance in meters between the polygon and the ellipsoid surface.
  190. * @param {Number} [options.extrudedHeight] The distance in meters between the polygon's extruded face and the ellipsoid surface.
  191. * @param {VertexFormat} [options.vertexFormat=VertexFormat.DEFAULT] The vertex attributes to be computed.
  192. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  193. * @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.
  194. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  195. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link ArcType.GEODESIC} and {@link ArcType.RHUMB}.
  196. *
  197. * @see PolygonOutlineGeometry#createGeometry
  198. * @see PolygonOutlineGeometry#fromPositions
  199. *
  200. * @example
  201. * // 1. create a polygon outline from points
  202. * var polygon = new Cesium.PolygonOutlineGeometry({
  203. * polygonHierarchy : new Cesium.PolygonHierarchy(
  204. * Cesium.Cartesian3.fromDegreesArray([
  205. * -72.0, 40.0,
  206. * -70.0, 35.0,
  207. * -75.0, 30.0,
  208. * -70.0, 30.0,
  209. * -68.0, 40.0
  210. * ])
  211. * )
  212. * });
  213. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon);
  214. *
  215. * // 2. create a nested polygon with holes outline
  216. * var polygonWithHole = new Cesium.PolygonOutlineGeometry({
  217. * polygonHierarchy : new Cesium.PolygonHierarchy(
  218. * Cesium.Cartesian3.fromDegreesArray([
  219. * -109.0, 30.0,
  220. * -95.0, 30.0,
  221. * -95.0, 40.0,
  222. * -109.0, 40.0
  223. * ]),
  224. * [new Cesium.PolygonHierarchy(
  225. * Cesium.Cartesian3.fromDegreesArray([
  226. * -107.0, 31.0,
  227. * -107.0, 39.0,
  228. * -97.0, 39.0,
  229. * -97.0, 31.0
  230. * ]),
  231. * [new Cesium.PolygonHierarchy(
  232. * Cesium.Cartesian3.fromDegreesArray([
  233. * -105.0, 33.0,
  234. * -99.0, 33.0,
  235. * -99.0, 37.0,
  236. * -105.0, 37.0
  237. * ]),
  238. * [new Cesium.PolygonHierarchy(
  239. * Cesium.Cartesian3.fromDegreesArray([
  240. * -103.0, 34.0,
  241. * -101.0, 34.0,
  242. * -101.0, 36.0,
  243. * -103.0, 36.0
  244. * ])
  245. * )]
  246. * )]
  247. * )]
  248. * )
  249. * });
  250. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygonWithHole);
  251. *
  252. * // 3. create extruded polygon outline
  253. * var extrudedPolygon = new Cesium.PolygonOutlineGeometry({
  254. * polygonHierarchy : new Cesium.PolygonHierarchy(
  255. * Cesium.Cartesian3.fromDegreesArray([
  256. * -72.0, 40.0,
  257. * -70.0, 35.0,
  258. * -75.0, 30.0,
  259. * -70.0, 30.0,
  260. * -68.0, 40.0
  261. * ])
  262. * ),
  263. * extrudedHeight: 300000
  264. * });
  265. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(extrudedPolygon);
  266. */
  267. function PolygonOutlineGeometry(options) {
  268. //>>includeStart('debug', pragmas.debug);
  269. Check.Check.typeOf.object('options', options);
  270. Check.Check.typeOf.object('options.polygonHierarchy', options.polygonHierarchy);
  271. if (options.perPositionHeight && when.defined(options.height)) {
  272. throw new Check.DeveloperError('Cannot use both options.perPositionHeight and options.height');
  273. }
  274. if (when.defined(options.arcType) && options.arcType !== ArcType.ArcType.GEODESIC && options.arcType !== ArcType.ArcType.RHUMB) {
  275. throw new Check.DeveloperError('Invalid arcType. Valid options are ArcType.GEODESIC and ArcType.RHUMB.');
  276. }
  277. //>>includeEnd('debug');
  278. var polygonHierarchy = options.polygonHierarchy;
  279. var ellipsoid = when.defaultValue(options.ellipsoid, Cartesian2.Ellipsoid.WGS84);
  280. var granularity = when.defaultValue(options.granularity, _Math.CesiumMath.RADIANS_PER_DEGREE);
  281. var perPositionHeight = when.defaultValue(options.perPositionHeight, false);
  282. var perPositionHeightExtrude = perPositionHeight && when.defined(options.extrudedHeight);
  283. var arcType = when.defaultValue(options.arcType, ArcType.ArcType.GEODESIC);
  284. var height = when.defaultValue(options.height, 0.0);
  285. var extrudedHeight = when.defaultValue(options.extrudedHeight, height);
  286. if (!perPositionHeightExtrude) {
  287. var h = Math.max(height, extrudedHeight);
  288. extrudedHeight = Math.min(height, extrudedHeight);
  289. height = h;
  290. }
  291. this._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid);
  292. this._granularity = granularity;
  293. this._height = height;
  294. this._extrudedHeight = extrudedHeight;
  295. this._arcType = arcType;
  296. this._polygonHierarchy = polygonHierarchy;
  297. this._perPositionHeight = perPositionHeight;
  298. this._perPositionHeightExtrude = perPositionHeightExtrude;
  299. this._offsetAttribute = options.offsetAttribute;
  300. this._workerName = 'createPolygonOutlineGeometry';
  301. /**
  302. * The number of elements used to pack the object into an array.
  303. * @type {Number}
  304. */
  305. this.packedLength = PolygonGeometryLibrary.PolygonGeometryLibrary.computeHierarchyPackedLength(polygonHierarchy) + Cartesian2.Ellipsoid.packedLength + 8;
  306. }
  307. /**
  308. * Stores the provided instance into the provided array.
  309. *
  310. * @param {PolygonOutlineGeometry} value The value to pack.
  311. * @param {Number[]} array The array to pack into.
  312. * @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.
  313. *
  314. * @returns {Number[]} The array that was packed into
  315. */
  316. PolygonOutlineGeometry.pack = function(value, array, startingIndex) {
  317. //>>includeStart('debug', pragmas.debug);
  318. Check.Check.typeOf.object('value', value);
  319. Check.Check.defined('array', array);
  320. //>>includeEnd('debug');
  321. startingIndex = when.defaultValue(startingIndex, 0);
  322. startingIndex = PolygonGeometryLibrary.PolygonGeometryLibrary.packPolygonHierarchy(value._polygonHierarchy, array, startingIndex);
  323. Cartesian2.Ellipsoid.pack(value._ellipsoid, array, startingIndex);
  324. startingIndex += Cartesian2.Ellipsoid.packedLength;
  325. array[startingIndex++] = value._height;
  326. array[startingIndex++] = value._extrudedHeight;
  327. array[startingIndex++] = value._granularity;
  328. array[startingIndex++] = value._perPositionHeightExtrude ? 1.0 : 0.0;
  329. array[startingIndex++] = value._perPositionHeight ? 1.0 : 0.0;
  330. array[startingIndex++] = value._arcType;
  331. array[startingIndex++] = when.defaultValue(value._offsetAttribute, -1);
  332. array[startingIndex] = value.packedLength;
  333. return array;
  334. };
  335. var scratchEllipsoid = Cartesian2.Ellipsoid.clone(Cartesian2.Ellipsoid.UNIT_SPHERE);
  336. var dummyOptions = {
  337. polygonHierarchy : {}
  338. };
  339. /**
  340. * Retrieves an instance from a packed array.
  341. *
  342. * @param {Number[]} array The packed array.
  343. * @param {Number} [startingIndex=0] The starting index of the element to be unpacked.
  344. * @param {PolygonOutlineGeometry} [result] The object into which to store the result.
  345. * @returns {PolygonOutlineGeometry} The modified result parameter or a new PolygonOutlineGeometry instance if one was not provided.
  346. */
  347. PolygonOutlineGeometry.unpack = function(array, startingIndex, result) {
  348. //>>includeStart('debug', pragmas.debug);
  349. Check.Check.defined('array', array);
  350. //>>includeEnd('debug');
  351. startingIndex = when.defaultValue(startingIndex, 0);
  352. var polygonHierarchy = PolygonGeometryLibrary.PolygonGeometryLibrary.unpackPolygonHierarchy(array, startingIndex);
  353. startingIndex = polygonHierarchy.startingIndex;
  354. delete polygonHierarchy.startingIndex;
  355. var ellipsoid = Cartesian2.Ellipsoid.unpack(array, startingIndex, scratchEllipsoid);
  356. startingIndex += Cartesian2.Ellipsoid.packedLength;
  357. var height = array[startingIndex++];
  358. var extrudedHeight = array[startingIndex++];
  359. var granularity = array[startingIndex++];
  360. var perPositionHeightExtrude = array[startingIndex++] === 1.0;
  361. var perPositionHeight = array[startingIndex++] === 1.0;
  362. var arcType = array[startingIndex++];
  363. var offsetAttribute = array[startingIndex++];
  364. var packedLength = array[startingIndex];
  365. if (!when.defined(result)) {
  366. result = new PolygonOutlineGeometry(dummyOptions);
  367. }
  368. result._polygonHierarchy = polygonHierarchy;
  369. result._ellipsoid = Cartesian2.Ellipsoid.clone(ellipsoid, result._ellipsoid);
  370. result._height = height;
  371. result._extrudedHeight = extrudedHeight;
  372. result._granularity = granularity;
  373. result._perPositionHeight = perPositionHeight;
  374. result._perPositionHeightExtrude = perPositionHeightExtrude;
  375. result._arcType = arcType;
  376. result._offsetAttribute = offsetAttribute === -1 ? undefined : offsetAttribute;
  377. result.packedLength = packedLength;
  378. return result;
  379. };
  380. /**
  381. * A description of a polygon outline from an array of positions.
  382. *
  383. * @param {Object} options Object with the following properties:
  384. * @param {Cartesian3[]} options.positions An array of positions that defined the corner points of the polygon.
  385. * @param {Number} [options.height=0.0] The height of the polygon.
  386. * @param {Number} [options.extrudedHeight] The height of the polygon extrusion.
  387. * @param {Ellipsoid} [options.ellipsoid=Ellipsoid.WGS84] The ellipsoid to be used as a reference.
  388. * @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.
  389. * @param {Boolean} [options.perPositionHeight=false] Use the height of options.positions for each position instead of using options.height to determine the height.
  390. * @param {ArcType} [options.arcType=ArcType.GEODESIC] The type of path the outline must follow. Valid options are {@link LinkType.GEODESIC} and {@link ArcType.RHUMB}.
  391. * @returns {PolygonOutlineGeometry}
  392. *
  393. *
  394. * @example
  395. * // create a polygon from points
  396. * var polygon = Cesium.PolygonOutlineGeometry.fromPositions({
  397. * positions : Cesium.Cartesian3.fromDegreesArray([
  398. * -72.0, 40.0,
  399. * -70.0, 35.0,
  400. * -75.0, 30.0,
  401. * -70.0, 30.0,
  402. * -68.0, 40.0
  403. * ])
  404. * });
  405. * var geometry = Cesium.PolygonOutlineGeometry.createGeometry(polygon);
  406. *
  407. * @see PolygonOutlineGeometry#createGeometry
  408. */
  409. PolygonOutlineGeometry.fromPositions = function(options) {
  410. options = when.defaultValue(options, when.defaultValue.EMPTY_OBJECT);
  411. //>>includeStart('debug', pragmas.debug);
  412. Check.Check.defined('options.positions', options.positions);
  413. //>>includeEnd('debug');
  414. var newOptions = {
  415. polygonHierarchy : {
  416. positions : options.positions
  417. },
  418. height : options.height,
  419. extrudedHeight : options.extrudedHeight,
  420. ellipsoid : options.ellipsoid,
  421. granularity : options.granularity,
  422. perPositionHeight : options.perPositionHeight,
  423. arcType: options.arcType,
  424. offsetAttribute : options.offsetAttribute
  425. };
  426. return new PolygonOutlineGeometry(newOptions);
  427. };
  428. /**
  429. * Computes the geometric representation of a polygon outline, including its vertices, indices, and a bounding sphere.
  430. *
  431. * @param {PolygonOutlineGeometry} polygonGeometry A description of the polygon outline.
  432. * @returns {Geometry|undefined} The computed vertices and indices.
  433. */
  434. PolygonOutlineGeometry.createGeometry = function(polygonGeometry) {
  435. var ellipsoid = polygonGeometry._ellipsoid;
  436. var granularity = polygonGeometry._granularity;
  437. var polygonHierarchy = polygonGeometry._polygonHierarchy;
  438. var perPositionHeight = polygonGeometry._perPositionHeight;
  439. var arcType = polygonGeometry._arcType;
  440. var polygons = PolygonGeometryLibrary.PolygonGeometryLibrary.polygonOutlinesFromHierarchy(polygonHierarchy, !perPositionHeight, ellipsoid);
  441. if (polygons.length === 0) {
  442. return undefined;
  443. }
  444. var geometryInstance;
  445. var geometries = [];
  446. var minDistance = _Math.CesiumMath.chordLength(granularity, ellipsoid.maximumRadius);
  447. var height = polygonGeometry._height;
  448. var extrudedHeight = polygonGeometry._extrudedHeight;
  449. var extrude = polygonGeometry._perPositionHeightExtrude || !_Math.CesiumMath.equalsEpsilon(height, extrudedHeight, 0, _Math.CesiumMath.EPSILON2);
  450. var offsetValue;
  451. var i;
  452. if (extrude) {
  453. for (i = 0; i < polygons.length; i++) {
  454. geometryInstance = createGeometryFromPositionsExtruded(ellipsoid, polygons[i], minDistance, perPositionHeight, arcType);
  455. geometryInstance.geometry = PolygonGeometryLibrary.PolygonGeometryLibrary.scaleToGeodeticHeightExtruded(geometryInstance.geometry, height, extrudedHeight, ellipsoid, perPositionHeight);
  456. if (when.defined(polygonGeometry._offsetAttribute)) {
  457. var size = geometryInstance.geometry.attributes.position.values.length / 3;
  458. var offsetAttribute = new Uint8Array(size);
  459. if (polygonGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.TOP) {
  460. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, 1, 0, size / 2);
  461. } else {
  462. offsetValue = polygonGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  463. offsetAttribute = GeometryOffsetAttribute.arrayFill(offsetAttribute, offsetValue);
  464. }
  465. geometryInstance.geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  466. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  467. componentsPerAttribute : 1,
  468. values : offsetAttribute
  469. });
  470. }
  471. geometries.push(geometryInstance);
  472. }
  473. } else {
  474. for (i = 0; i < polygons.length; i++) {
  475. geometryInstance = createGeometryFromPositions(ellipsoid, polygons[i], minDistance, perPositionHeight, arcType);
  476. geometryInstance.geometry.attributes.position.values = PolygonPipeline.PolygonPipeline.scaleToGeodeticHeight(geometryInstance.geometry.attributes.position.values, height, ellipsoid, !perPositionHeight);
  477. if (when.defined(polygonGeometry._offsetAttribute)) {
  478. var length = geometryInstance.geometry.attributes.position.values.length;
  479. var applyOffset = new Uint8Array(length / 3);
  480. offsetValue = polygonGeometry._offsetAttribute === GeometryOffsetAttribute.GeometryOffsetAttribute.NONE ? 0 : 1;
  481. GeometryOffsetAttribute.arrayFill(applyOffset, offsetValue);
  482. geometryInstance.geometry.attributes.applyOffset = new GeometryAttribute.GeometryAttribute({
  483. componentDatatype : ComponentDatatype.ComponentDatatype.UNSIGNED_BYTE,
  484. componentsPerAttribute : 1,
  485. values: applyOffset
  486. });
  487. }
  488. geometries.push(geometryInstance);
  489. }
  490. }
  491. var geometry = GeometryPipeline.GeometryPipeline.combineInstances(geometries)[0];
  492. var boundingSphere = BoundingSphere.BoundingSphere.fromVertices(geometry.attributes.position.values);
  493. return new GeometryAttribute.Geometry({
  494. attributes : geometry.attributes,
  495. indices : geometry.indices,
  496. primitiveType : geometry.primitiveType,
  497. boundingSphere : boundingSphere,
  498. offsetAttribute : polygonGeometry._offsetAttribute
  499. });
  500. };
  501. function createPolygonOutlineGeometry(polygonGeometry, offset) {
  502. if (when.defined(offset)) {
  503. polygonGeometry = PolygonOutlineGeometry.unpack(polygonGeometry, offset);
  504. }
  505. polygonGeometry._ellipsoid = Cartesian2.Ellipsoid.clone(polygonGeometry._ellipsoid);
  506. return PolygonOutlineGeometry.createGeometry(polygonGeometry);
  507. }
  508. return createPolygonOutlineGeometry;
  509. });