智慧水务管理系统 - 精河县供水工程综合管理平台

PolylineGeometryUpdater.js 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. import ArcType from "../Core/ArcType.js";
  2. import BoundingSphere from "../Core/BoundingSphere.js";
  3. import Check from "../Core/Check.js";
  4. import Color from "../Core/Color.js";
  5. import ColorGeometryInstanceAttribute from "../Core/ColorGeometryInstanceAttribute.js";
  6. import defined from "../Core/defined.js";
  7. import destroyObject from "../Core/destroyObject.js";
  8. import DeveloperError from "../Core/DeveloperError.js";
  9. import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js";
  10. import DistanceDisplayConditionGeometryInstanceAttribute from "../Core/DistanceDisplayConditionGeometryInstanceAttribute.js";
  11. import Event from "../Core/Event.js";
  12. import GeometryInstance from "../Core/GeometryInstance.js";
  13. import GroundPolylineGeometry from "../Core/GroundPolylineGeometry.js";
  14. import Iso8601 from "../Core/Iso8601.js";
  15. import oneTimeWarning from "../Core/oneTimeWarning.js";
  16. import PolylineGeometry from "../Core/PolylineGeometry.js";
  17. import PolylinePipeline from "../Core/PolylinePipeline.js";
  18. import ShowGeometryInstanceAttribute from "../Core/ShowGeometryInstanceAttribute.js";
  19. import Entity from "../DataSources/Entity.js";
  20. import ClassificationType from "../Scene/ClassificationType.js";
  21. import GroundPolylinePrimitive from "../Scene/GroundPolylinePrimitive.js";
  22. import PolylineCollection from "../Scene/PolylineCollection.js";
  23. import PolylineColorAppearance from "../Scene/PolylineColorAppearance.js";
  24. import PolylineMaterialAppearance from "../Scene/PolylineMaterialAppearance.js";
  25. import ShadowMode from "../Scene/ShadowMode.js";
  26. import BoundingSphereState from "./BoundingSphereState.js";
  27. import ColorMaterialProperty from "./ColorMaterialProperty.js";
  28. import ConstantProperty from "./ConstantProperty.js";
  29. import MaterialProperty from "./MaterialProperty.js";
  30. import Property from "./Property.js";
  31. const defaultZIndex = new ConstantProperty(0);
  32. //We use this object to create one polyline collection per-scene.
  33. const polylineCollections = {};
  34. const scratchColor = new Color();
  35. const defaultMaterial = new ColorMaterialProperty(Color.WHITE);
  36. const defaultShow = new ConstantProperty(true);
  37. const defaultShadows = new ConstantProperty(ShadowMode.DISABLED);
  38. const defaultDistanceDisplayCondition = new ConstantProperty(
  39. new DistanceDisplayCondition(),
  40. );
  41. const defaultClassificationType = new ConstantProperty(ClassificationType.BOTH);
  42. function GeometryOptions() {
  43. this.vertexFormat = undefined;
  44. this.positions = undefined;
  45. this.width = undefined;
  46. this.arcType = undefined;
  47. this.granularity = undefined;
  48. }
  49. function GroundGeometryOptions() {
  50. this.positions = undefined;
  51. this.width = undefined;
  52. this.arcType = undefined;
  53. this.granularity = undefined;
  54. }
  55. /**
  56. * A {@link GeometryUpdater} for polylines.
  57. * Clients do not normally create this class directly, but instead rely on {@link DataSourceDisplay}.
  58. * @alias PolylineGeometryUpdater
  59. * @constructor
  60. *
  61. * @param {Entity} entity The entity containing the geometry to be visualized.
  62. * @param {Scene} scene The scene where visualization is taking place.
  63. */
  64. function PolylineGeometryUpdater(entity, scene) {
  65. //>>includeStart('debug', pragmas.debug);
  66. if (!defined(entity)) {
  67. throw new DeveloperError("entity is required");
  68. }
  69. if (!defined(scene)) {
  70. throw new DeveloperError("scene is required");
  71. }
  72. //>>includeEnd('debug');
  73. this._entity = entity;
  74. this._scene = scene;
  75. this._entitySubscription = entity.definitionChanged.addEventListener(
  76. PolylineGeometryUpdater.prototype._onEntityPropertyChanged,
  77. this,
  78. );
  79. this._fillEnabled = false;
  80. this._dynamic = false;
  81. this._geometryChanged = new Event();
  82. this._showProperty = undefined;
  83. this._materialProperty = undefined;
  84. this._shadowsProperty = undefined;
  85. this._distanceDisplayConditionProperty = undefined;
  86. this._classificationTypeProperty = undefined;
  87. this._depthFailMaterialProperty = undefined;
  88. this._geometryOptions = new GeometryOptions();
  89. this._groundGeometryOptions = new GroundGeometryOptions();
  90. this._id = `polyline-${entity.id}`;
  91. this._clampToGround = false;
  92. this._supportsPolylinesOnTerrain = Entity.supportsPolylinesOnTerrain(scene);
  93. this._zIndex = 0;
  94. this._onEntityPropertyChanged(entity, "polyline", entity.polyline, undefined);
  95. }
  96. Object.defineProperties(PolylineGeometryUpdater.prototype, {
  97. /**
  98. * Gets the unique ID associated with this updater
  99. * @memberof PolylineGeometryUpdater.prototype
  100. * @type {string}
  101. * @readonly
  102. */
  103. id: {
  104. get: function () {
  105. return this._id;
  106. },
  107. },
  108. /**
  109. * Gets the entity associated with this geometry.
  110. * @memberof PolylineGeometryUpdater.prototype
  111. *
  112. * @type {Entity}
  113. * @readonly
  114. */
  115. entity: {
  116. get: function () {
  117. return this._entity;
  118. },
  119. },
  120. /**
  121. * Gets a value indicating if the geometry has a fill component.
  122. * @memberof PolylineGeometryUpdater.prototype
  123. *
  124. * @type {boolean}
  125. * @readonly
  126. */
  127. fillEnabled: {
  128. get: function () {
  129. return this._fillEnabled;
  130. },
  131. },
  132. /**
  133. * Gets a value indicating if fill visibility varies with simulation time.
  134. * @memberof PolylineGeometryUpdater.prototype
  135. *
  136. * @type {boolean}
  137. * @readonly
  138. */
  139. hasConstantFill: {
  140. get: function () {
  141. return (
  142. !this._fillEnabled ||
  143. (!defined(this._entity.availability) &&
  144. Property.isConstant(this._showProperty))
  145. );
  146. },
  147. },
  148. /**
  149. * Gets the material property used to fill the geometry.
  150. * @memberof PolylineGeometryUpdater.prototype
  151. *
  152. * @type {MaterialProperty}
  153. * @readonly
  154. */
  155. fillMaterialProperty: {
  156. get: function () {
  157. return this._materialProperty;
  158. },
  159. },
  160. /**
  161. * Gets the material property used to fill the geometry when it fails the depth test.
  162. * @memberof PolylineGeometryUpdater.prototype
  163. *
  164. * @type {MaterialProperty}
  165. * @readonly
  166. */
  167. depthFailMaterialProperty: {
  168. get: function () {
  169. return this._depthFailMaterialProperty;
  170. },
  171. },
  172. /**
  173. * Gets a value indicating if the geometry has an outline component.
  174. * @memberof PolylineGeometryUpdater.prototype
  175. *
  176. * @type {boolean}
  177. * @readonly
  178. */
  179. outlineEnabled: {
  180. value: false,
  181. },
  182. /**
  183. * Gets a value indicating if outline visibility varies with simulation time.
  184. * @memberof PolylineGeometryUpdater.prototype
  185. *
  186. * @type {boolean}
  187. * @readonly
  188. */
  189. hasConstantOutline: {
  190. value: true,
  191. },
  192. /**
  193. * Gets the {@link Color} property for the geometry outline.
  194. * @memberof PolylineGeometryUpdater.prototype
  195. *
  196. * @type {Property}
  197. * @readonly
  198. */
  199. outlineColorProperty: {
  200. value: undefined,
  201. },
  202. /**
  203. * Gets the property specifying whether the geometry
  204. * casts or receives shadows from light sources.
  205. * @memberof PolylineGeometryUpdater.prototype
  206. *
  207. * @type {Property}
  208. * @readonly
  209. */
  210. shadowsProperty: {
  211. get: function () {
  212. return this._shadowsProperty;
  213. },
  214. },
  215. /**
  216. * Gets or sets the {@link DistanceDisplayCondition} Property specifying at what distance from the camera that this geometry will be displayed.
  217. * @memberof PolylineGeometryUpdater.prototype
  218. *
  219. * @type {Property}
  220. * @readonly
  221. */
  222. distanceDisplayConditionProperty: {
  223. get: function () {
  224. return this._distanceDisplayConditionProperty;
  225. },
  226. },
  227. /**
  228. * Gets or sets the {@link ClassificationType} Property specifying if this geometry will classify terrain, 3D Tiles, or both when on the ground.
  229. * @memberof PolylineGeometryUpdater.prototype
  230. *
  231. * @type {Property}
  232. * @readonly
  233. */
  234. classificationTypeProperty: {
  235. get: function () {
  236. return this._classificationTypeProperty;
  237. },
  238. },
  239. /**
  240. * Gets a value indicating if the geometry is time-varying.
  241. *
  242. * @memberof PolylineGeometryUpdater.prototype
  243. *
  244. * @type {boolean}
  245. * @readonly
  246. */
  247. isDynamic: {
  248. get: function () {
  249. return this._dynamic;
  250. },
  251. },
  252. /**
  253. * Gets a value indicating if the geometry is closed.
  254. * This property is only valid for static geometry.
  255. * @memberof PolylineGeometryUpdater.prototype
  256. *
  257. * @type {boolean}
  258. * @readonly
  259. */
  260. isClosed: {
  261. value: false,
  262. },
  263. /**
  264. * Gets an event that is raised whenever the public properties
  265. * of this updater change.
  266. * @memberof PolylineGeometryUpdater.prototype
  267. *
  268. * @type {boolean}
  269. * @readonly
  270. */
  271. geometryChanged: {
  272. get: function () {
  273. return this._geometryChanged;
  274. },
  275. },
  276. /**
  277. * Gets a value indicating if the path of the line.
  278. * @memberof PolylineGeometryUpdater.prototype
  279. *
  280. * @type {ArcType}
  281. * @readonly
  282. */
  283. arcType: {
  284. get: function () {
  285. return this._arcType;
  286. },
  287. },
  288. /**
  289. * Gets a value indicating if the geometry is clamped to the ground.
  290. * Returns false if polylines on terrain is not supported.
  291. * @memberof PolylineGeometryUpdater.prototype
  292. *
  293. * @type {boolean}
  294. * @readonly
  295. */
  296. clampToGround: {
  297. get: function () {
  298. return this._clampToGround && this._supportsPolylinesOnTerrain;
  299. },
  300. },
  301. /**
  302. * Gets the zindex
  303. * @type {number}
  304. * @memberof PolylineGeometryUpdater.prototype
  305. * @readonly
  306. */
  307. zIndex: {
  308. get: function () {
  309. return this._zIndex;
  310. },
  311. },
  312. });
  313. /**
  314. * Checks if the geometry is outlined at the provided time.
  315. *
  316. * @param {JulianDate} time The time for which to retrieve visibility.
  317. * @returns {boolean} true if geometry is outlined at the provided time, false otherwise.
  318. */
  319. PolylineGeometryUpdater.prototype.isOutlineVisible = function (time) {
  320. return false;
  321. };
  322. /**
  323. * Checks if the geometry is filled at the provided time.
  324. *
  325. * @param {JulianDate} time The time for which to retrieve visibility.
  326. * @returns {boolean} true if geometry is filled at the provided time, false otherwise.
  327. */
  328. PolylineGeometryUpdater.prototype.isFilled = function (time) {
  329. const entity = this._entity;
  330. const visible =
  331. this._fillEnabled &&
  332. entity.isAvailable(time) &&
  333. this._showProperty.getValue(time);
  334. return visible ?? false;
  335. };
  336. /**
  337. * Creates the geometry instance which represents the fill of the geometry.
  338. *
  339. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  340. * @returns {GeometryInstance} The geometry instance representing the filled portion of the geometry.
  341. *
  342. * @exception {DeveloperError} This instance does not represent a filled geometry.
  343. */
  344. PolylineGeometryUpdater.prototype.createFillGeometryInstance = function (time) {
  345. //>>includeStart('debug', pragmas.debug);
  346. if (!defined(time)) {
  347. throw new DeveloperError("time is required.");
  348. }
  349. if (!this._fillEnabled) {
  350. throw new DeveloperError(
  351. "This instance does not represent a filled geometry.",
  352. );
  353. }
  354. //>>includeEnd('debug');
  355. const entity = this._entity;
  356. const isAvailable = entity.isAvailable(time);
  357. const show = new ShowGeometryInstanceAttribute(
  358. isAvailable && entity.isShowing && this._showProperty.getValue(time),
  359. );
  360. const distanceDisplayCondition =
  361. this._distanceDisplayConditionProperty.getValue(time);
  362. const distanceDisplayConditionAttribute =
  363. DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(
  364. distanceDisplayCondition,
  365. );
  366. const attributes = {
  367. show: show,
  368. distanceDisplayCondition: distanceDisplayConditionAttribute,
  369. };
  370. let currentColor;
  371. if (this._materialProperty instanceof ColorMaterialProperty) {
  372. if (
  373. defined(this._materialProperty.color) &&
  374. (this._materialProperty.color.isConstant || isAvailable)
  375. ) {
  376. currentColor = this._materialProperty.color.getValue(time, scratchColor);
  377. }
  378. if (!defined(currentColor)) {
  379. currentColor = Color.WHITE;
  380. }
  381. attributes.color = ColorGeometryInstanceAttribute.fromColor(currentColor);
  382. }
  383. if (this.clampToGround) {
  384. return new GeometryInstance({
  385. id: entity,
  386. geometry: new GroundPolylineGeometry(this._groundGeometryOptions),
  387. attributes: attributes,
  388. });
  389. }
  390. if (
  391. defined(this._depthFailMaterialProperty) &&
  392. this._depthFailMaterialProperty instanceof ColorMaterialProperty
  393. ) {
  394. if (
  395. defined(this._depthFailMaterialProperty.color) &&
  396. (this._depthFailMaterialProperty.color.isConstant || isAvailable)
  397. ) {
  398. currentColor = this._depthFailMaterialProperty.color.getValue(
  399. time,
  400. scratchColor,
  401. );
  402. }
  403. if (!defined(currentColor)) {
  404. currentColor = Color.WHITE;
  405. }
  406. attributes.depthFailColor =
  407. ColorGeometryInstanceAttribute.fromColor(currentColor);
  408. }
  409. return new GeometryInstance({
  410. id: entity,
  411. geometry: new PolylineGeometry(this._geometryOptions),
  412. attributes: attributes,
  413. });
  414. };
  415. /**
  416. * Creates the geometry instance which represents the outline of the geometry.
  417. *
  418. * @param {JulianDate} time The time to use when retrieving initial attribute values.
  419. * @returns {GeometryInstance} The geometry instance representing the outline portion of the geometry.
  420. *
  421. * @exception {DeveloperError} This instance does not represent an outlined geometry.
  422. */
  423. PolylineGeometryUpdater.prototype.createOutlineGeometryInstance = function (
  424. time,
  425. ) {
  426. //>>includeStart('debug', pragmas.debug);
  427. throw new DeveloperError(
  428. "This instance does not represent an outlined geometry.",
  429. );
  430. //>>includeEnd('debug');
  431. };
  432. /**
  433. * Returns true if this object was destroyed; otherwise, false.
  434. *
  435. * @returns {boolean} True if this object was destroyed; otherwise, false.
  436. */
  437. PolylineGeometryUpdater.prototype.isDestroyed = function () {
  438. return false;
  439. };
  440. /**
  441. * Destroys and resources used by the object. Once an object is destroyed, it should not be used.
  442. *
  443. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
  444. */
  445. PolylineGeometryUpdater.prototype.destroy = function () {
  446. this._entitySubscription();
  447. destroyObject(this);
  448. };
  449. PolylineGeometryUpdater.prototype._onEntityPropertyChanged = function (
  450. entity,
  451. propertyName,
  452. newValue,
  453. oldValue,
  454. ) {
  455. if (!(propertyName === "availability" || propertyName === "polyline")) {
  456. return;
  457. }
  458. const polyline = this._entity.polyline;
  459. if (!defined(polyline)) {
  460. if (this._fillEnabled) {
  461. this._fillEnabled = false;
  462. this._geometryChanged.raiseEvent(this);
  463. }
  464. return;
  465. }
  466. const positionsProperty = polyline.positions;
  467. const show = polyline.show;
  468. if (
  469. (defined(show) &&
  470. show.isConstant &&
  471. !show.getValue(Iso8601.MINIMUM_VALUE)) || //
  472. !defined(positionsProperty)
  473. ) {
  474. if (this._fillEnabled) {
  475. this._fillEnabled = false;
  476. this._geometryChanged.raiseEvent(this);
  477. }
  478. return;
  479. }
  480. const zIndex = polyline.zIndex;
  481. const material = polyline.material ?? defaultMaterial;
  482. const isColorMaterial = material instanceof ColorMaterialProperty;
  483. this._materialProperty = material;
  484. this._depthFailMaterialProperty = polyline.depthFailMaterial;
  485. this._showProperty = show ?? defaultShow;
  486. this._shadowsProperty = polyline.shadows ?? defaultShadows;
  487. this._distanceDisplayConditionProperty =
  488. polyline.distanceDisplayCondition ?? defaultDistanceDisplayCondition;
  489. this._classificationTypeProperty =
  490. polyline.classificationType ?? defaultClassificationType;
  491. this._fillEnabled = true;
  492. this._zIndex = zIndex ?? defaultZIndex;
  493. const width = polyline.width;
  494. const arcType = polyline.arcType;
  495. const clampToGround = polyline.clampToGround;
  496. const granularity = polyline.granularity;
  497. if (
  498. !positionsProperty.isConstant ||
  499. !Property.isConstant(width) ||
  500. !Property.isConstant(arcType) ||
  501. !Property.isConstant(granularity) ||
  502. !Property.isConstant(clampToGround) ||
  503. !Property.isConstant(zIndex)
  504. ) {
  505. if (!this._dynamic) {
  506. this._dynamic = true;
  507. this._geometryChanged.raiseEvent(this);
  508. }
  509. } else {
  510. const geometryOptions = this._geometryOptions;
  511. const positions = positionsProperty.getValue(
  512. Iso8601.MINIMUM_VALUE,
  513. geometryOptions.positions,
  514. );
  515. //Because of the way we currently handle reference properties,
  516. //we can't automatically assume the positions are always valid.
  517. if (!defined(positions) || positions.length < 2) {
  518. if (this._fillEnabled) {
  519. this._fillEnabled = false;
  520. this._geometryChanged.raiseEvent(this);
  521. }
  522. return;
  523. }
  524. let vertexFormat;
  525. if (
  526. isColorMaterial &&
  527. (!defined(this._depthFailMaterialProperty) ||
  528. this._depthFailMaterialProperty instanceof ColorMaterialProperty)
  529. ) {
  530. vertexFormat = PolylineColorAppearance.VERTEX_FORMAT;
  531. } else {
  532. vertexFormat = PolylineMaterialAppearance.VERTEX_FORMAT;
  533. }
  534. geometryOptions.vertexFormat = vertexFormat;
  535. geometryOptions.positions = positions;
  536. geometryOptions.width = defined(width)
  537. ? width.getValue(Iso8601.MINIMUM_VALUE)
  538. : undefined;
  539. geometryOptions.arcType = defined(arcType)
  540. ? arcType.getValue(Iso8601.MINIMUM_VALUE)
  541. : undefined;
  542. geometryOptions.granularity = defined(granularity)
  543. ? granularity.getValue(Iso8601.MINIMUM_VALUE)
  544. : undefined;
  545. const groundGeometryOptions = this._groundGeometryOptions;
  546. groundGeometryOptions.positions = positions;
  547. groundGeometryOptions.width = geometryOptions.width;
  548. groundGeometryOptions.arcType = geometryOptions.arcType;
  549. groundGeometryOptions.granularity = geometryOptions.granularity;
  550. this._clampToGround = defined(clampToGround)
  551. ? clampToGround.getValue(Iso8601.MINIMUM_VALUE)
  552. : false;
  553. if (!this._clampToGround && defined(zIndex)) {
  554. oneTimeWarning(
  555. "Entity polylines must have clampToGround: true when using zIndex. zIndex will be ignored.",
  556. );
  557. }
  558. this._dynamic = false;
  559. this._geometryChanged.raiseEvent(this);
  560. }
  561. };
  562. /**
  563. * Creates the dynamic updater to be used when GeometryUpdater#isDynamic is true.
  564. *
  565. * @param {PrimitiveCollection} primitives The primitive collection to use.
  566. * @param {PrimitiveCollection|OrderedGroundPrimitiveCollection} groundPrimitives The primitive collection to use for ordered ground primitives.
  567. * @returns {DynamicGeometryUpdater} The dynamic updater used to update the geometry each frame.
  568. *
  569. * @exception {DeveloperError} This instance does not represent dynamic geometry.
  570. * @private
  571. */
  572. PolylineGeometryUpdater.prototype.createDynamicUpdater = function (
  573. primitives,
  574. groundPrimitives,
  575. ) {
  576. //>>includeStart('debug', pragmas.debug);
  577. Check.defined("primitives", primitives);
  578. Check.defined("groundPrimitives", groundPrimitives);
  579. if (!this._dynamic) {
  580. throw new DeveloperError(
  581. "This instance does not represent dynamic geometry.",
  582. );
  583. }
  584. //>>includeEnd('debug');
  585. return new DynamicGeometryUpdater(primitives, groundPrimitives, this);
  586. };
  587. /**
  588. * @private
  589. */
  590. const generateCartesianArcOptions = {
  591. positions: undefined,
  592. granularity: undefined,
  593. height: undefined,
  594. ellipsoid: undefined,
  595. };
  596. function DynamicGeometryUpdater(primitives, groundPrimitives, geometryUpdater) {
  597. this._line = undefined;
  598. this._primitives = primitives;
  599. this._groundPrimitives = groundPrimitives;
  600. this._groundPolylinePrimitive = undefined;
  601. this._material = undefined;
  602. this._geometryUpdater = geometryUpdater;
  603. this._positions = [];
  604. }
  605. function getLine(dynamicGeometryUpdater) {
  606. if (defined(dynamicGeometryUpdater._line)) {
  607. return dynamicGeometryUpdater._line;
  608. }
  609. const primitives = dynamicGeometryUpdater._primitives;
  610. const polylineCollectionId =
  611. dynamicGeometryUpdater._geometryUpdater._scene.id + primitives._guid;
  612. let polylineCollection = polylineCollections[polylineCollectionId];
  613. if (!defined(polylineCollection) || polylineCollection.isDestroyed()) {
  614. polylineCollection = new PolylineCollection();
  615. polylineCollections[polylineCollectionId] = polylineCollection;
  616. primitives.add(polylineCollection);
  617. } else if (!primitives.contains(polylineCollection)) {
  618. primitives.add(polylineCollection);
  619. }
  620. const line = polylineCollection.add();
  621. line.id = dynamicGeometryUpdater._geometryUpdater._entity;
  622. dynamicGeometryUpdater._line = line;
  623. return line;
  624. }
  625. DynamicGeometryUpdater.prototype.update = function (time) {
  626. const geometryUpdater = this._geometryUpdater;
  627. const entity = geometryUpdater._entity;
  628. const polyline = entity.polyline;
  629. const positionsProperty = polyline.positions;
  630. let positions = Property.getValueOrUndefined(
  631. positionsProperty,
  632. time,
  633. this._positions,
  634. );
  635. // Synchronize with geometryUpdater for GroundPolylinePrimitive
  636. geometryUpdater._clampToGround = Property.getValueOrDefault(
  637. polyline._clampToGround,
  638. time,
  639. false,
  640. );
  641. geometryUpdater._groundGeometryOptions.positions = positions;
  642. geometryUpdater._groundGeometryOptions.width = Property.getValueOrDefault(
  643. polyline._width,
  644. time,
  645. 1,
  646. );
  647. geometryUpdater._groundGeometryOptions.arcType = Property.getValueOrDefault(
  648. polyline._arcType,
  649. time,
  650. ArcType.GEODESIC,
  651. );
  652. geometryUpdater._groundGeometryOptions.granularity =
  653. Property.getValueOrDefault(polyline._granularity, time, 9999);
  654. const groundPrimitives = this._groundPrimitives;
  655. if (defined(this._groundPolylinePrimitive)) {
  656. groundPrimitives.remove(this._groundPolylinePrimitive); // destroys by default
  657. this._groundPolylinePrimitive = undefined;
  658. }
  659. if (geometryUpdater.clampToGround) {
  660. if (
  661. !entity.isShowing ||
  662. !entity.isAvailable(time) ||
  663. !Property.getValueOrDefault(polyline._show, time, true)
  664. ) {
  665. return;
  666. }
  667. if (!defined(positions) || positions.length < 2) {
  668. return;
  669. }
  670. const fillMaterialProperty = geometryUpdater.fillMaterialProperty;
  671. let appearance;
  672. if (fillMaterialProperty instanceof ColorMaterialProperty) {
  673. appearance = new PolylineColorAppearance();
  674. } else {
  675. const material = MaterialProperty.getValue(
  676. time,
  677. fillMaterialProperty,
  678. this._material,
  679. );
  680. appearance = new PolylineMaterialAppearance({
  681. material: material,
  682. translucent: material.isTranslucent(),
  683. });
  684. this._material = material;
  685. }
  686. this._groundPolylinePrimitive = groundPrimitives.add(
  687. new GroundPolylinePrimitive({
  688. geometryInstances: geometryUpdater.createFillGeometryInstance(time),
  689. appearance: appearance,
  690. classificationType:
  691. geometryUpdater.classificationTypeProperty.getValue(time),
  692. asynchronous: false,
  693. }),
  694. Property.getValueOrUndefined(geometryUpdater.zIndex, time),
  695. );
  696. // Hide the polyline in the collection, if any
  697. if (defined(this._line)) {
  698. this._line.show = false;
  699. }
  700. return;
  701. }
  702. const line = getLine(this);
  703. if (
  704. !entity.isShowing ||
  705. !entity.isAvailable(time) ||
  706. !Property.getValueOrDefault(polyline._show, time, true)
  707. ) {
  708. line.show = false;
  709. return;
  710. }
  711. if (!defined(positions) || positions.length < 2) {
  712. line.show = false;
  713. return;
  714. }
  715. let arcType = ArcType.GEODESIC;
  716. arcType = Property.getValueOrDefault(polyline._arcType, time, arcType);
  717. const globe = geometryUpdater._scene.globe;
  718. const ellipsoid = geometryUpdater._scene.ellipsoid;
  719. if (arcType !== ArcType.NONE && defined(globe)) {
  720. generateCartesianArcOptions.ellipsoid = ellipsoid;
  721. generateCartesianArcOptions.positions = positions;
  722. generateCartesianArcOptions.granularity = Property.getValueOrUndefined(
  723. polyline._granularity,
  724. time,
  725. );
  726. generateCartesianArcOptions.height = PolylinePipeline.extractHeights(
  727. positions,
  728. ellipsoid,
  729. );
  730. if (arcType === ArcType.GEODESIC) {
  731. positions = PolylinePipeline.generateCartesianArc(
  732. generateCartesianArcOptions,
  733. );
  734. } else {
  735. positions = PolylinePipeline.generateCartesianRhumbArc(
  736. generateCartesianArcOptions,
  737. );
  738. }
  739. }
  740. line.show = true;
  741. line.positions = positions.slice();
  742. line.material = MaterialProperty.getValue(
  743. time,
  744. geometryUpdater.fillMaterialProperty,
  745. line.material,
  746. );
  747. line.width = Property.getValueOrDefault(polyline._width, time, 1);
  748. line.distanceDisplayCondition = Property.getValueOrUndefined(
  749. polyline._distanceDisplayCondition,
  750. time,
  751. line.distanceDisplayCondition,
  752. );
  753. };
  754. DynamicGeometryUpdater.prototype.getBoundingSphere = function (result) {
  755. //>>includeStart('debug', pragmas.debug);
  756. Check.defined("result", result);
  757. //>>includeEnd('debug');
  758. if (!this._geometryUpdater.clampToGround) {
  759. const line = getLine(this);
  760. if (line.show && line.positions.length > 0) {
  761. BoundingSphere.fromPoints(line.positions, result);
  762. return BoundingSphereState.DONE;
  763. }
  764. } else {
  765. const groundPolylinePrimitive = this._groundPolylinePrimitive;
  766. if (
  767. defined(groundPolylinePrimitive) &&
  768. groundPolylinePrimitive.show &&
  769. groundPolylinePrimitive.ready
  770. ) {
  771. const attributes = groundPolylinePrimitive.getGeometryInstanceAttributes(
  772. this._geometryUpdater._entity,
  773. );
  774. if (defined(attributes) && defined(attributes.boundingSphere)) {
  775. BoundingSphere.clone(attributes.boundingSphere, result);
  776. return BoundingSphereState.DONE;
  777. }
  778. }
  779. if (defined(groundPolylinePrimitive) && !groundPolylinePrimitive.ready) {
  780. return BoundingSphereState.PENDING;
  781. }
  782. return BoundingSphereState.DONE;
  783. }
  784. return BoundingSphereState.FAILED;
  785. };
  786. DynamicGeometryUpdater.prototype.isDestroyed = function () {
  787. return false;
  788. };
  789. DynamicGeometryUpdater.prototype.destroy = function () {
  790. const geometryUpdater = this._geometryUpdater;
  791. const polylineCollectionId =
  792. geometryUpdater._scene.id + this._primitives._guid;
  793. const polylineCollection = polylineCollections[polylineCollectionId];
  794. if (defined(polylineCollection)) {
  795. polylineCollection.remove(this._line);
  796. if (polylineCollection.length === 0) {
  797. this._primitives.removeAndDestroy(polylineCollection);
  798. delete polylineCollections[polylineCollectionId];
  799. }
  800. }
  801. if (defined(this._groundPolylinePrimitive)) {
  802. this._groundPrimitives.remove(this._groundPolylinePrimitive);
  803. }
  804. destroyObject(this);
  805. };
  806. export default PolylineGeometryUpdater;