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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. import AssociativeArray from "../Core/AssociativeArray.js";
  2. import BoundingSphere from "../Core/BoundingSphere.js";
  3. import Check from "../Core/Check.js";
  4. import defined from "../Core/defined.js";
  5. import destroyObject from "../Core/destroyObject.js";
  6. import ClassificationType from "../Scene/ClassificationType.js";
  7. import PolylineColorAppearance from "../Scene/PolylineColorAppearance.js";
  8. import PolylineMaterialAppearance from "../Scene/PolylineMaterialAppearance.js";
  9. import ShadowMode from "../Scene/ShadowMode.js";
  10. import BoundingSphereState from "./BoundingSphereState.js";
  11. import ColorMaterialProperty from "./ColorMaterialProperty.js";
  12. import DynamicGeometryBatch from "./DynamicGeometryBatch.js";
  13. import PolylineGeometryUpdater from "./PolylineGeometryUpdater.js";
  14. import StaticGeometryColorBatch from "./StaticGeometryColorBatch.js";
  15. import StaticGeometryPerMaterialBatch from "./StaticGeometryPerMaterialBatch.js";
  16. import StaticGroundPolylinePerMaterialBatch from "./StaticGroundPolylinePerMaterialBatch.js";
  17. const emptyArray = [];
  18. function removeUpdater(that, updater) {
  19. //We don't keep track of which batch an updater is in, so just remove it from all of them.
  20. const batches = that._batches;
  21. const length = batches.length;
  22. for (let i = 0; i < length; i++) {
  23. batches[i].remove(updater);
  24. }
  25. }
  26. function insertUpdaterIntoBatch(that, time, updater) {
  27. if (updater.isDynamic) {
  28. that._dynamicBatch.add(time, updater);
  29. return;
  30. }
  31. if (updater.clampToGround && updater.fillEnabled) {
  32. // Also checks for support
  33. const classificationType =
  34. updater.classificationTypeProperty.getValue(time);
  35. that._groundBatches[classificationType].add(time, updater);
  36. return;
  37. }
  38. let shadows;
  39. if (updater.fillEnabled) {
  40. shadows = updater.shadowsProperty.getValue(time);
  41. }
  42. let multiplier = 0;
  43. if (defined(updater.depthFailMaterialProperty)) {
  44. multiplier =
  45. updater.depthFailMaterialProperty instanceof ColorMaterialProperty
  46. ? 1
  47. : 2;
  48. }
  49. let index;
  50. if (defined(shadows)) {
  51. index = shadows + multiplier * ShadowMode.NUMBER_OF_SHADOW_MODES;
  52. }
  53. if (updater.fillEnabled) {
  54. if (updater.fillMaterialProperty instanceof ColorMaterialProperty) {
  55. that._colorBatches[index].add(time, updater);
  56. } else {
  57. that._materialBatches[index].add(time, updater);
  58. }
  59. }
  60. }
  61. /**
  62. * A visualizer for polylines represented by {@link Primitive} instances.
  63. * @alias PolylineVisualizer
  64. * @constructor
  65. *
  66. * @param {Scene} scene The scene the primitives will be rendered in.
  67. * @param {EntityCollection} entityCollection The entityCollection to visualize.
  68. * @param {PrimitiveCollection} [primitives=scene.primitives] A collection to add primitives related to the entities
  69. * @param {PrimitiveCollection} [groundPrimitives=scene.groundPrimitives] A collection to add ground primitives related to the entities
  70. */
  71. function PolylineVisualizer(
  72. scene,
  73. entityCollection,
  74. primitives,
  75. groundPrimitives,
  76. ) {
  77. //>>includeStart('debug', pragmas.debug);
  78. Check.defined("scene", scene);
  79. Check.defined("entityCollection", entityCollection);
  80. //>>includeEnd('debug');
  81. groundPrimitives = groundPrimitives ?? scene.groundPrimitives;
  82. primitives = primitives ?? scene.primitives;
  83. this._scene = scene;
  84. this._primitives = primitives;
  85. this._entityCollection = undefined;
  86. this._addedObjects = new AssociativeArray();
  87. this._removedObjects = new AssociativeArray();
  88. this._changedObjects = new AssociativeArray();
  89. let i;
  90. const numberOfShadowModes = ShadowMode.NUMBER_OF_SHADOW_MODES;
  91. this._colorBatches = new Array(numberOfShadowModes * 3);
  92. this._materialBatches = new Array(numberOfShadowModes * 3);
  93. for (i = 0; i < numberOfShadowModes; ++i) {
  94. this._colorBatches[i] = new StaticGeometryColorBatch(
  95. primitives,
  96. PolylineColorAppearance,
  97. undefined,
  98. false,
  99. i,
  100. ); // no depth fail appearance
  101. this._materialBatches[i] = new StaticGeometryPerMaterialBatch(
  102. primitives,
  103. PolylineMaterialAppearance,
  104. undefined,
  105. false,
  106. i,
  107. );
  108. this._colorBatches[i + numberOfShadowModes] = new StaticGeometryColorBatch(
  109. primitives,
  110. PolylineColorAppearance,
  111. PolylineColorAppearance,
  112. false,
  113. i,
  114. ); //depth fail appearance variations
  115. this._materialBatches[i + numberOfShadowModes] =
  116. new StaticGeometryPerMaterialBatch(
  117. primitives,
  118. PolylineMaterialAppearance,
  119. PolylineColorAppearance,
  120. false,
  121. i,
  122. );
  123. this._colorBatches[i + numberOfShadowModes * 2] =
  124. new StaticGeometryColorBatch(
  125. primitives,
  126. PolylineColorAppearance,
  127. PolylineMaterialAppearance,
  128. false,
  129. i,
  130. );
  131. this._materialBatches[i + numberOfShadowModes * 2] =
  132. new StaticGeometryPerMaterialBatch(
  133. primitives,
  134. PolylineMaterialAppearance,
  135. PolylineMaterialAppearance,
  136. false,
  137. i,
  138. );
  139. }
  140. this._dynamicBatch = new DynamicGeometryBatch(primitives, groundPrimitives);
  141. const numberOfClassificationTypes =
  142. ClassificationType.NUMBER_OF_CLASSIFICATION_TYPES;
  143. this._groundBatches = new Array(numberOfClassificationTypes);
  144. for (i = 0; i < numberOfClassificationTypes; ++i) {
  145. this._groundBatches[i] = new StaticGroundPolylinePerMaterialBatch(
  146. groundPrimitives,
  147. i,
  148. );
  149. }
  150. this._batches = this._colorBatches.concat(
  151. this._materialBatches,
  152. this._dynamicBatch,
  153. this._groundBatches,
  154. );
  155. this._subscriptions = new AssociativeArray();
  156. this._updaters = new AssociativeArray();
  157. this._entityCollection = entityCollection;
  158. entityCollection.collectionChanged.addEventListener(
  159. PolylineVisualizer.prototype._onCollectionChanged,
  160. this,
  161. );
  162. this._onCollectionChanged(
  163. entityCollection,
  164. entityCollection.values,
  165. emptyArray,
  166. );
  167. }
  168. /**
  169. * Updates all of the primitives created by this visualizer to match their
  170. * Entity counterpart at the given time.
  171. *
  172. * @param {JulianDate} time The time to update to.
  173. * @returns {boolean} True if the visualizer successfully updated to the provided time,
  174. * false if the visualizer is waiting for asynchronous primitives to be created.
  175. */
  176. PolylineVisualizer.prototype.update = function (time) {
  177. //>>includeStart('debug', pragmas.debug);
  178. Check.defined("time", time);
  179. //>>includeEnd('debug');
  180. const addedObjects = this._addedObjects;
  181. const added = addedObjects.values;
  182. const removedObjects = this._removedObjects;
  183. const removed = removedObjects.values;
  184. const changedObjects = this._changedObjects;
  185. const changed = changedObjects.values;
  186. let i;
  187. let entity;
  188. let id;
  189. let updater;
  190. for (i = changed.length - 1; i > -1; i--) {
  191. entity = changed[i];
  192. id = entity.id;
  193. updater = this._updaters.get(id);
  194. //If in a single update, an entity gets removed and a new instance
  195. //re-added with the same id, the updater no longer tracks the
  196. //correct entity, we need to both remove the old one and
  197. //add the new one, which is done by pushing the entity
  198. //onto the removed/added lists.
  199. if (updater.entity === entity) {
  200. removeUpdater(this, updater);
  201. insertUpdaterIntoBatch(this, time, updater);
  202. } else {
  203. removed.push(entity);
  204. added.push(entity);
  205. }
  206. }
  207. for (i = removed.length - 1; i > -1; i--) {
  208. entity = removed[i];
  209. id = entity.id;
  210. updater = this._updaters.get(id);
  211. removeUpdater(this, updater);
  212. updater.destroy();
  213. this._updaters.remove(id);
  214. this._subscriptions.get(id)();
  215. this._subscriptions.remove(id);
  216. }
  217. for (i = added.length - 1; i > -1; i--) {
  218. entity = added[i];
  219. id = entity.id;
  220. updater = new PolylineGeometryUpdater(entity, this._scene);
  221. this._updaters.set(id, updater);
  222. insertUpdaterIntoBatch(this, time, updater);
  223. this._subscriptions.set(
  224. id,
  225. updater.geometryChanged.addEventListener(
  226. PolylineVisualizer._onGeometryChanged,
  227. this,
  228. ),
  229. );
  230. }
  231. addedObjects.removeAll();
  232. removedObjects.removeAll();
  233. changedObjects.removeAll();
  234. let isUpdated = true;
  235. const batches = this._batches;
  236. const length = batches.length;
  237. for (i = 0; i < length; i++) {
  238. isUpdated = batches[i].update(time) && isUpdated;
  239. }
  240. return isUpdated;
  241. };
  242. const getBoundingSphereArrayScratch = [];
  243. const getBoundingSphereBoundingSphereScratch = new BoundingSphere();
  244. /**
  245. * Computes a bounding sphere which encloses the visualization produced for the specified entity.
  246. * The bounding sphere is in the fixed frame of the scene's globe.
  247. *
  248. * @param {Entity} entity The entity whose bounding sphere to compute.
  249. * @param {BoundingSphere} result The bounding sphere onto which to store the result.
  250. * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere,
  251. * BoundingSphereState.PENDING if the result is still being computed, or
  252. * BoundingSphereState.FAILED if the entity has no visualization in the current scene.
  253. * @private
  254. */
  255. PolylineVisualizer.prototype.getBoundingSphere = function (entity, result) {
  256. //>>includeStart('debug', pragmas.debug);
  257. Check.defined("entity", entity);
  258. Check.defined("result", result);
  259. //>>includeEnd('debug');
  260. const boundingSpheres = getBoundingSphereArrayScratch;
  261. const tmp = getBoundingSphereBoundingSphereScratch;
  262. let count = 0;
  263. let state = BoundingSphereState.DONE;
  264. const batches = this._batches;
  265. const batchesLength = batches.length;
  266. const updater = this._updaters.get(entity.id);
  267. for (let i = 0; i < batchesLength; i++) {
  268. state = batches[i].getBoundingSphere(updater, tmp);
  269. if (state === BoundingSphereState.PENDING) {
  270. return BoundingSphereState.PENDING;
  271. } else if (state === BoundingSphereState.DONE) {
  272. boundingSpheres[count] = BoundingSphere.clone(
  273. tmp,
  274. boundingSpheres[count],
  275. );
  276. count++;
  277. }
  278. }
  279. if (count === 0) {
  280. return BoundingSphereState.FAILED;
  281. }
  282. boundingSpheres.length = count;
  283. BoundingSphere.fromBoundingSpheres(boundingSpheres, result);
  284. return BoundingSphereState.DONE;
  285. };
  286. /**
  287. * Returns true if this object was destroyed; otherwise, false.
  288. *
  289. * @returns {boolean} True if this object was destroyed; otherwise, false.
  290. */
  291. PolylineVisualizer.prototype.isDestroyed = function () {
  292. return false;
  293. };
  294. /**
  295. * Removes and destroys all primitives created by this instance.
  296. */
  297. PolylineVisualizer.prototype.destroy = function () {
  298. this._entityCollection.collectionChanged.removeEventListener(
  299. PolylineVisualizer.prototype._onCollectionChanged,
  300. this,
  301. );
  302. this._addedObjects.removeAll();
  303. this._removedObjects.removeAll();
  304. let i;
  305. const batches = this._batches;
  306. let length = batches.length;
  307. for (i = 0; i < length; i++) {
  308. batches[i].removeAllPrimitives();
  309. }
  310. const subscriptions = this._subscriptions.values;
  311. length = subscriptions.length;
  312. for (i = 0; i < length; i++) {
  313. subscriptions[i]();
  314. }
  315. this._subscriptions.removeAll();
  316. return destroyObject(this);
  317. };
  318. /**
  319. * @private
  320. */
  321. PolylineVisualizer._onGeometryChanged = function (updater) {
  322. const removedObjects = this._removedObjects;
  323. const changedObjects = this._changedObjects;
  324. const entity = updater.entity;
  325. const id = entity.id;
  326. if (!defined(removedObjects.get(id)) && !defined(changedObjects.get(id))) {
  327. changedObjects.set(id, entity);
  328. }
  329. };
  330. /**
  331. * @private
  332. */
  333. PolylineVisualizer.prototype._onCollectionChanged = function (
  334. entityCollection,
  335. added,
  336. removed,
  337. ) {
  338. const addedObjects = this._addedObjects;
  339. const removedObjects = this._removedObjects;
  340. const changedObjects = this._changedObjects;
  341. let i;
  342. let id;
  343. let entity;
  344. for (i = removed.length - 1; i > -1; i--) {
  345. entity = removed[i];
  346. id = entity.id;
  347. if (!addedObjects.remove(id)) {
  348. removedObjects.set(id, entity);
  349. changedObjects.remove(id);
  350. }
  351. }
  352. for (i = added.length - 1; i > -1; i--) {
  353. entity = added[i];
  354. id = entity.id;
  355. if (removedObjects.remove(id)) {
  356. changedObjects.set(id, entity);
  357. } else {
  358. addedObjects.set(id, entity);
  359. }
  360. }
  361. };
  362. export default PolylineVisualizer;