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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. import AssociativeArray from "../Core/AssociativeArray.js";
  2. import BoundingRectangle from "../Core/BoundingRectangle.js";
  3. import Cartesian2 from "../Core/Cartesian2.js";
  4. import Cartesian3 from "../Core/Cartesian3.js";
  5. import Color from "../Core/Color.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 NearFarScalar from "../Core/NearFarScalar.js";
  11. import HeightReference from "../Scene/HeightReference.js";
  12. import HorizontalOrigin from "../Scene/HorizontalOrigin.js";
  13. import VerticalOrigin from "../Scene/VerticalOrigin.js";
  14. import BoundingSphereState from "./BoundingSphereState.js";
  15. import Property from "./Property.js";
  16. import SplitDirection from "../Scene/SplitDirection.js";
  17. const defaultColor = Color.WHITE;
  18. const defaultEyeOffset = Cartesian3.ZERO;
  19. const defaultHeightReference = HeightReference.NONE;
  20. const defaultPixelOffset = Cartesian2.ZERO;
  21. const defaultScale = 1.0;
  22. const defaultRotation = 0.0;
  23. const defaultAlignedAxis = Cartesian3.ZERO;
  24. const defaultHorizontalOrigin = HorizontalOrigin.CENTER;
  25. const defaultVerticalOrigin = VerticalOrigin.CENTER;
  26. const defaultSizeInMeters = false;
  27. const defaultSplitDirection = SplitDirection.NONE;
  28. const positionScratch = new Cartesian3();
  29. const colorScratch = new Color();
  30. const eyeOffsetScratch = new Cartesian3();
  31. const pixelOffsetScratch = new Cartesian2();
  32. const scaleByDistanceScratch = new NearFarScalar();
  33. const translucencyByDistanceScratch = new NearFarScalar();
  34. const pixelOffsetScaleByDistanceScratch = new NearFarScalar();
  35. const boundingRectangleScratch = new BoundingRectangle();
  36. const distanceDisplayConditionScratch = new DistanceDisplayCondition();
  37. function EntityData(entity) {
  38. this.entity = entity;
  39. this.billboard = undefined;
  40. this.textureValue = undefined;
  41. }
  42. /**
  43. * A {@link Visualizer} which maps {@link Entity#billboard} to a {@link Billboard}.
  44. * @alias BillboardVisualizer
  45. * @constructor
  46. *
  47. * @param {EntityCluster} entityCluster The entity cluster to manage the collection of billboards and optionally cluster with other entities.
  48. * @param {EntityCollection} entityCollection The entityCollection to visualize.
  49. */
  50. function BillboardVisualizer(entityCluster, entityCollection) {
  51. //>>includeStart('debug', pragmas.debug);
  52. if (!defined(entityCluster)) {
  53. throw new DeveloperError("entityCluster is required.");
  54. }
  55. if (!defined(entityCollection)) {
  56. throw new DeveloperError("entityCollection is required.");
  57. }
  58. //>>includeEnd('debug');
  59. entityCollection.collectionChanged.addEventListener(
  60. BillboardVisualizer.prototype._onCollectionChanged,
  61. this,
  62. );
  63. this._cluster = entityCluster;
  64. this._entityCollection = entityCollection;
  65. this._items = new AssociativeArray();
  66. this._onCollectionChanged(entityCollection, entityCollection.values, [], []);
  67. }
  68. /**
  69. * Updates the primitives created by this visualizer to match their
  70. * Entity counterpart at the given time.
  71. *
  72. * @param {JulianDate} time The time to update to.
  73. * @returns {boolean} This function always returns true.
  74. */
  75. BillboardVisualizer.prototype.update = function (time) {
  76. //>>includeStart('debug', pragmas.debug);
  77. if (!defined(time)) {
  78. throw new DeveloperError("time is required.");
  79. }
  80. //>>includeEnd('debug');
  81. const items = this._items.values;
  82. const cluster = this._cluster;
  83. for (let i = 0, len = items.length; i < len; i++) {
  84. const item = items[i];
  85. const entity = item.entity;
  86. const billboardGraphics = entity._billboard;
  87. let textureValue;
  88. let billboard = item.billboard;
  89. let show =
  90. entity.isShowing &&
  91. entity.isAvailable(time) &&
  92. Property.getValueOrDefault(billboardGraphics._show, time, true);
  93. let position;
  94. if (show) {
  95. position = Property.getValueOrUndefined(
  96. entity._position,
  97. time,
  98. positionScratch,
  99. );
  100. textureValue = Property.getValueOrUndefined(
  101. billboardGraphics._image,
  102. time,
  103. );
  104. show = defined(position) && defined(textureValue);
  105. }
  106. if (!show) {
  107. //don't bother creating or updating anything else
  108. returnPrimitive(item, entity, cluster);
  109. continue;
  110. }
  111. if (!Property.isConstant(entity._position)) {
  112. cluster._clusterDirty = true;
  113. }
  114. if (!defined(billboard)) {
  115. billboard = cluster.getBillboard(entity);
  116. billboard.id = entity;
  117. item.billboard = billboard;
  118. item.textureValue = undefined;
  119. }
  120. billboard.show = show;
  121. billboard.position = position;
  122. billboard.color = Property.getValueOrDefault(
  123. billboardGraphics._color,
  124. time,
  125. defaultColor,
  126. colorScratch,
  127. );
  128. billboard.eyeOffset = Property.getValueOrDefault(
  129. billboardGraphics._eyeOffset,
  130. time,
  131. defaultEyeOffset,
  132. eyeOffsetScratch,
  133. );
  134. billboard.heightReference = Property.getValueOrDefault(
  135. billboardGraphics._heightReference,
  136. time,
  137. defaultHeightReference,
  138. );
  139. billboard.pixelOffset = Property.getValueOrDefault(
  140. billboardGraphics._pixelOffset,
  141. time,
  142. defaultPixelOffset,
  143. pixelOffsetScratch,
  144. );
  145. billboard.scale = Property.getValueOrDefault(
  146. billboardGraphics._scale,
  147. time,
  148. defaultScale,
  149. );
  150. billboard.rotation = Property.getValueOrDefault(
  151. billboardGraphics._rotation,
  152. time,
  153. defaultRotation,
  154. );
  155. billboard.alignedAxis = Property.getValueOrDefault(
  156. billboardGraphics._alignedAxis,
  157. time,
  158. defaultAlignedAxis,
  159. );
  160. billboard.horizontalOrigin = Property.getValueOrDefault(
  161. billboardGraphics._horizontalOrigin,
  162. time,
  163. defaultHorizontalOrigin,
  164. );
  165. billboard.verticalOrigin = Property.getValueOrDefault(
  166. billboardGraphics._verticalOrigin,
  167. time,
  168. defaultVerticalOrigin,
  169. );
  170. billboard.width = Property.getValueOrUndefined(
  171. billboardGraphics._width,
  172. time,
  173. );
  174. billboard.height = Property.getValueOrUndefined(
  175. billboardGraphics._height,
  176. time,
  177. );
  178. billboard.scaleByDistance = Property.getValueOrUndefined(
  179. billboardGraphics._scaleByDistance,
  180. time,
  181. scaleByDistanceScratch,
  182. );
  183. billboard.translucencyByDistance = Property.getValueOrUndefined(
  184. billboardGraphics._translucencyByDistance,
  185. time,
  186. translucencyByDistanceScratch,
  187. );
  188. billboard.pixelOffsetScaleByDistance = Property.getValueOrUndefined(
  189. billboardGraphics._pixelOffsetScaleByDistance,
  190. time,
  191. pixelOffsetScaleByDistanceScratch,
  192. );
  193. billboard.sizeInMeters = Property.getValueOrDefault(
  194. billboardGraphics._sizeInMeters,
  195. time,
  196. defaultSizeInMeters,
  197. );
  198. billboard.distanceDisplayCondition = Property.getValueOrUndefined(
  199. billboardGraphics._distanceDisplayCondition,
  200. time,
  201. distanceDisplayConditionScratch,
  202. );
  203. billboard.disableDepthTestDistance = Property.getValueOrUndefined(
  204. billboardGraphics._disableDepthTestDistance,
  205. time,
  206. );
  207. billboard.splitDirection = Property.getValueOrDefault(
  208. billboardGraphics._splitDirection,
  209. time,
  210. defaultSplitDirection,
  211. );
  212. // Apply .image last, so any necessary property values are available
  213. // in Billboard#_computeImageTextureSize before adding to the atlas.
  214. if (item.textureValue !== textureValue) {
  215. billboard.image = textureValue;
  216. item.textureValue = textureValue;
  217. }
  218. const subRegion = Property.getValueOrUndefined(
  219. billboardGraphics._imageSubRegion,
  220. time,
  221. boundingRectangleScratch,
  222. );
  223. if (defined(subRegion)) {
  224. billboard.setImageSubRegion(billboard.image, subRegion);
  225. }
  226. }
  227. return true;
  228. };
  229. /**
  230. * Computes a bounding sphere which encloses the visualization produced for the specified entity.
  231. * The bounding sphere is in the fixed frame of the scene's globe.
  232. *
  233. * @param {Entity} entity The entity whose bounding sphere to compute.
  234. * @param {BoundingSphere} result The bounding sphere onto which to store the result.
  235. * @returns {BoundingSphereState} BoundingSphereState.DONE if the result contains the bounding sphere,
  236. * BoundingSphereState.PENDING if the result is still being computed, or
  237. * BoundingSphereState.FAILED if the entity has no visualization in the current scene.
  238. * @private
  239. */
  240. BillboardVisualizer.prototype.getBoundingSphere = function (entity, result) {
  241. //>>includeStart('debug', pragmas.debug);
  242. if (!defined(entity)) {
  243. throw new DeveloperError("entity is required.");
  244. }
  245. if (!defined(result)) {
  246. throw new DeveloperError("result is required.");
  247. }
  248. //>>includeEnd('debug');
  249. const item = this._items.get(entity.id);
  250. if (!defined(item) || !defined(item.billboard)) {
  251. return BoundingSphereState.FAILED;
  252. }
  253. const billboard = item.billboard;
  254. if (billboard.heightReference === HeightReference.NONE) {
  255. result.center = Cartesian3.clone(billboard.position, result.center);
  256. } else {
  257. if (!defined(billboard._clampedPosition)) {
  258. return BoundingSphereState.PENDING;
  259. }
  260. result.center = Cartesian3.clone(billboard._clampedPosition, result.center);
  261. }
  262. result.radius = 0;
  263. return BoundingSphereState.DONE;
  264. };
  265. /**
  266. * Returns true if this object was destroyed; otherwise, false.
  267. *
  268. * @returns {boolean} True if this object was destroyed; otherwise, false.
  269. */
  270. BillboardVisualizer.prototype.isDestroyed = function () {
  271. return false;
  272. };
  273. /**
  274. * Removes and destroys all primitives created by this instance.
  275. */
  276. BillboardVisualizer.prototype.destroy = function () {
  277. this._entityCollection.collectionChanged.removeEventListener(
  278. BillboardVisualizer.prototype._onCollectionChanged,
  279. this,
  280. );
  281. const entities = this._entityCollection.values;
  282. for (let i = 0; i < entities.length; i++) {
  283. this._cluster.removeBillboard(entities[i]);
  284. }
  285. return destroyObject(this);
  286. };
  287. BillboardVisualizer.prototype._onCollectionChanged = function (
  288. entityCollection,
  289. added,
  290. removed,
  291. changed,
  292. ) {
  293. let i;
  294. let entity;
  295. const items = this._items;
  296. const cluster = this._cluster;
  297. for (i = added.length - 1; i > -1; i--) {
  298. entity = added[i];
  299. if (defined(entity._billboard) && defined(entity._position)) {
  300. items.set(entity.id, new EntityData(entity));
  301. }
  302. }
  303. for (i = changed.length - 1; i > -1; i--) {
  304. entity = changed[i];
  305. if (defined(entity._billboard) && defined(entity._position)) {
  306. if (!items.contains(entity.id)) {
  307. items.set(entity.id, new EntityData(entity));
  308. }
  309. } else {
  310. returnPrimitive(items.get(entity.id), entity, cluster);
  311. items.remove(entity.id);
  312. }
  313. }
  314. for (i = removed.length - 1; i > -1; i--) {
  315. entity = removed[i];
  316. returnPrimitive(items.get(entity.id), entity, cluster);
  317. items.remove(entity.id);
  318. }
  319. };
  320. function returnPrimitive(item, entity, cluster) {
  321. if (defined(item)) {
  322. item.billboard = undefined;
  323. cluster.removeBillboard(entity);
  324. }
  325. }
  326. export default BillboardVisualizer;