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

Cesium3DTileFeature.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. import Color from "../Core/Color.js";
  2. import defined from "../Core/defined.js";
  3. /** @import Cesium3DTileBatchTable from "./Cesium3DTileBatchTable.js"; */
  4. /** @import Cesium3DTileContent from "./Cesium3DTileContent.js"; */
  5. /** @import Cesium3DTileset from "./Cesium3DTileset.js"; */
  6. /**
  7. * A feature of a {@link Cesium3DTileset}.
  8. * <p>
  9. * Provides access to a feature's properties stored in the tile's batch table, as well
  10. * as the ability to show/hide a feature and change its highlight color via
  11. * {@link Cesium3DTileFeature#show} and {@link Cesium3DTileFeature#color}, respectively.
  12. * </p>
  13. * <p>
  14. * Modifications to a <code>Cesium3DTileFeature</code> object have the lifetime of the tile's
  15. * content. If the tile's content is unloaded, e.g., due to it going out of view and needing
  16. * to free space in the cache for visible tiles, listen to the {@link Cesium3DTileset#tileUnload} event to save any
  17. * modifications. Also listen to the {@link Cesium3DTileset#tileVisible} event to reapply any modifications.
  18. * </p>
  19. * <p>
  20. * Do not construct this directly. Access it through {@link Cesium3DTileContent#getFeature}
  21. * or picking using {@link Scene#pick}.
  22. * </p>
  23. *
  24. * @example
  25. * // On mouse over, display all the properties for a feature in the console log.
  26. * handler.setInputAction(function(movement) {
  27. * const feature = scene.pick(movement.endPosition);
  28. * if (feature instanceof Cesium.Cesium3DTileFeature) {
  29. * const propertyIds = feature.getPropertyIds();
  30. * const length = propertyIds.length;
  31. * for (let i = 0; i < length; ++i) {
  32. * const propertyId = propertyIds[i];
  33. * console.log(`{propertyId}: ${feature.getProperty(propertyId)}`);
  34. * }
  35. * }
  36. * }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  37. */
  38. class Cesium3DTileFeature {
  39. /**
  40. * @param {Cesium3DTileContent} content
  41. * @param {number} batchId
  42. */
  43. constructor(content, batchId) {
  44. this._content = content;
  45. this._batchId = batchId;
  46. this._color = undefined; // for calling getColor
  47. }
  48. /**
  49. * Gets or sets if the feature will be shown. This is set for all features
  50. * when a style's show is evaluated.
  51. *
  52. * @type {boolean}
  53. *
  54. * @default true
  55. */
  56. get show() {
  57. return this._content.batchTable.getShow(this._batchId);
  58. }
  59. set show(value) {
  60. this._content.batchTable.setShow(this._batchId, value);
  61. }
  62. /**
  63. * Gets or sets the highlight color multiplied with the feature's color. When
  64. * this is white, the feature's color is not changed. This is set for all features
  65. * when a style's color is evaluated.
  66. *
  67. * @type {Color}
  68. *
  69. * @default {@link Color.WHITE}
  70. */
  71. get color() {
  72. if (!defined(this._color)) {
  73. this._color = new Color();
  74. }
  75. return this._content.batchTable.getColor(this._batchId, this._color);
  76. }
  77. set color(value) {
  78. this._content.batchTable.setColor(this._batchId, value);
  79. }
  80. /**
  81. * Gets a typed array containing the ECEF positions of the polyline.
  82. * Returns undefined if {@link Cesium3DTileset#vectorKeepDecodedPositions} is false
  83. * or the feature is not a polyline in a vector tile.
  84. *
  85. * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
  86. *
  87. * @type {Float64Array}
  88. */
  89. get polylinePositions() {
  90. if (!defined(this._content.getPolylinePositions)) {
  91. return undefined;
  92. }
  93. return this._content.getPolylinePositions(this._batchId);
  94. }
  95. /**
  96. * Gets the content of the tile containing the feature.
  97. *
  98. * @type {Cesium3DTileContent}
  99. *
  100. * @readonly
  101. * @private
  102. */
  103. get content() {
  104. return this._content;
  105. }
  106. /**
  107. * Gets the tileset containing the feature.
  108. *
  109. * @type {Cesium3DTileset}
  110. *
  111. * @readonly
  112. */
  113. get tileset() {
  114. return this._content.tileset;
  115. }
  116. /**
  117. * All objects returned by {@link Scene#pick} have a <code>primitive</code> property. This returns
  118. * the tileset containing the feature.
  119. *
  120. * @type {Cesium3DTileset}
  121. *
  122. * @readonly
  123. */
  124. get primitive() {
  125. return this._content.tileset;
  126. }
  127. /**
  128. * Get the feature ID associated with this feature. For 3D Tiles 1.0, the
  129. * batch ID is returned. For EXT_mesh_features, this is the feature ID from
  130. * the selected feature ID set.
  131. *
  132. * @type {number}
  133. *
  134. * @readonly
  135. * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
  136. */
  137. get featureId() {
  138. return this._batchId;
  139. }
  140. /**
  141. * @private
  142. */
  143. get pickId() {
  144. return this._content.batchTable.getPickColor(this._batchId);
  145. }
  146. /**
  147. * Returns whether the feature contains this property. This includes properties from this feature's
  148. * class and inherited classes when using a batch table hierarchy.
  149. *
  150. * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
  151. *
  152. * @param {string} name The case-sensitive name of the property.
  153. * @returns {boolean} Whether the feature contains this property.
  154. */
  155. hasProperty(name) {
  156. return this._content.batchTable.hasProperty(this._batchId, name);
  157. }
  158. /**
  159. * Returns an array of property IDs for the feature. This includes properties from this feature's
  160. * class and inherited classes when using a batch table hierarchy.
  161. *
  162. * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
  163. *
  164. * @param {string[]} [results] An array into which to store the results.
  165. * @returns {string[]} The IDs of the feature's properties.
  166. */
  167. getPropertyIds(results) {
  168. return this._content.batchTable.getPropertyIds(this._batchId, results);
  169. }
  170. /**
  171. * Returns a copy of the value of the feature's property with the given name. This includes properties from this feature's
  172. * class and inherited classes when using a batch table hierarchy.
  173. *
  174. * @see {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_batch_table_hierarchy}
  175. *
  176. * @param {string} name The case-sensitive name of the property.
  177. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property.
  178. *
  179. * @example
  180. * // Display all the properties for a feature in the console log.
  181. * const propertyIds = feature.getPropertyIds();
  182. * const length = propertyIds.length;
  183. * for (let i = 0; i < length; ++i) {
  184. * const propertyId = propertyIds[i];
  185. * console.log(`{propertyId}: ${feature.getProperty(propertyId)}`);
  186. * }
  187. */
  188. getProperty(name) {
  189. return this._content.batchTable.getProperty(this._batchId, name);
  190. }
  191. /**
  192. * Returns a copy of the feature's property with the given name, examining all
  193. * the metadata from 3D Tiles 1.0 formats, the EXT_structural_metadata and legacy
  194. * EXT_feature_metadata glTF extensions, and the metadata present either in the
  195. * tileset JSON (3D Tiles 1.1) or in the 3DTILES_metadata 3D Tiles extension.
  196. * Metadata is checked against name from most specific to most general and the
  197. * first match is returned. Metadata is checked in this order:
  198. *
  199. * <ol>
  200. * <li>Batch table (structural metadata) property by semantic</li>
  201. * <li>Batch table (structural metadata) property by property ID</li>
  202. * <li>Content metadata property by semantic</li>
  203. * <li>Content metadata property by property</li>
  204. * <li>Tile metadata property by semantic</li>
  205. * <li>Tile metadata property by property ID</li>
  206. * <li>Subtree metadata property by semantic</li>
  207. * <li>Subtree metadata property by property ID</li>
  208. * <li>Group metadata property by semantic</li>
  209. * <li>Group metadata property by property ID</li>
  210. * <li>Tileset metadata property by semantic</li>
  211. * <li>Tileset metadata property by property ID</li>
  212. * <li>Otherwise, return undefined</li>
  213. * </ol>
  214. * <p>
  215. * For 3D Tiles Next details, see the {@link https://github.com/CesiumGS/3d-tiles/tree/main/extensions/3DTILES_metadata|3DTILES_metadata Extension}
  216. * for 3D Tiles, as well as the {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_structural_metadata|EXT_structural_metadata Extension}
  217. * for glTF. For the legacy glTF extension, see {@link https://github.com/CesiumGS/glTF/tree/3d-tiles-next/extensions/2.0/Vendor/EXT_feature_metadata|EXT_feature_metadata Extension}
  218. * </p>
  219. *
  220. * @param {Cesium3DTileContent} content The content for accessing the metadata
  221. * @param {number} batchId The batch ID (or feature ID) of the feature to get a property for
  222. * @param {string} name The semantic or property ID of the feature. Semantics are checked before property IDs in each granularity of metadata.
  223. * @privateParam {Cesium3DTileBatchTable} [batchTable] Batch table in which to look up the feature property. If unspecified, `content.batchTable` is used.
  224. * @return {*} The value of the property or <code>undefined</code> if the feature does not have this property.
  225. *
  226. * @experimental This feature is using part of the 3D Tiles spec that is not final and is subject to change without Cesium's standard deprecation policy.
  227. */
  228. static getPropertyInherited(
  229. content,
  230. batchId,
  231. name,
  232. batchTable = content.batchTable,
  233. ) {
  234. if (defined(batchTable)) {
  235. if (batchTable.hasPropertyBySemantic(batchId, name)) {
  236. return batchTable.getPropertyBySemantic(batchId, name);
  237. }
  238. if (batchTable.hasProperty(batchId, name)) {
  239. return batchTable.getProperty(batchId, name);
  240. }
  241. }
  242. const contentMetadata = content.metadata;
  243. if (defined(contentMetadata)) {
  244. if (contentMetadata.hasPropertyBySemantic(name)) {
  245. return contentMetadata.getPropertyBySemantic(name);
  246. }
  247. if (contentMetadata.hasProperty(name)) {
  248. return contentMetadata.getProperty(name);
  249. }
  250. }
  251. const tile = content.tile;
  252. const tileMetadata = tile.metadata;
  253. if (defined(tileMetadata)) {
  254. if (tileMetadata.hasPropertyBySemantic(name)) {
  255. return tileMetadata.getPropertyBySemantic(name);
  256. }
  257. if (tileMetadata.hasProperty(name)) {
  258. return tileMetadata.getProperty(name);
  259. }
  260. }
  261. let subtreeMetadata;
  262. if (defined(tile.implicitSubtree)) {
  263. subtreeMetadata = tile.implicitSubtree.metadata;
  264. }
  265. if (defined(subtreeMetadata)) {
  266. if (subtreeMetadata.hasPropertyBySemantic(name)) {
  267. return subtreeMetadata.getPropertyBySemantic(name);
  268. }
  269. if (subtreeMetadata.hasProperty(name)) {
  270. return subtreeMetadata.getProperty(name);
  271. }
  272. }
  273. const groupMetadata = defined(content.group)
  274. ? content.group.metadata
  275. : undefined;
  276. if (defined(groupMetadata)) {
  277. if (groupMetadata.hasPropertyBySemantic(name)) {
  278. return groupMetadata.getPropertyBySemantic(name);
  279. }
  280. if (groupMetadata.hasProperty(name)) {
  281. return groupMetadata.getProperty(name);
  282. }
  283. }
  284. const tilesetMetadata = content.tileset.metadata;
  285. if (defined(tilesetMetadata)) {
  286. if (tilesetMetadata.hasPropertyBySemantic(name)) {
  287. return tilesetMetadata.getPropertyBySemantic(name);
  288. }
  289. if (tilesetMetadata.hasProperty(name)) {
  290. return tilesetMetadata.getProperty(name);
  291. }
  292. }
  293. return undefined;
  294. }
  295. /**
  296. * Returns a copy of the value of the feature's property with the given name.
  297. * If the feature is contained within a tileset that has metadata (3D Tiles 1.1)
  298. * or uses the <code>3DTILES_metadata</code> extension, tileset, group and tile
  299. * metadata is inherited.
  300. * <p>
  301. * To resolve name conflicts, this method resolves names from most specific to
  302. * least specific by metadata granularity in the order: feature, tile, group,
  303. * tileset. Within each granularity, semantics are resolved first, then other
  304. * properties.
  305. * </p>
  306. * @param {string} name The case-sensitive name of the property.
  307. * @returns {*} The value of the property or <code>undefined</code> if the feature does not have this property.
  308. * @private
  309. */
  310. getPropertyInherited(name) {
  311. return Cesium3DTileFeature.getPropertyInherited(
  312. this._content,
  313. this._batchId,
  314. name,
  315. );
  316. }
  317. /**
  318. * Sets the value of the feature's property with the given name.
  319. * <p>
  320. * If a property with the given name doesn't exist, it is created.
  321. * </p>
  322. *
  323. * @param {string} name The case-sensitive name of the property.
  324. * @param {*} value The value of the property that will be copied.
  325. *
  326. * @exception {DeveloperError} Inherited batch table hierarchy property is read only.
  327. *
  328. * @example
  329. * const height = feature.getProperty('Height'); // e.g., the height of a building
  330. *
  331. * @example
  332. * const name = 'clicked';
  333. * if (feature.getProperty(name)) {
  334. * console.log('already clicked');
  335. * } else {
  336. * feature.setProperty(name, true);
  337. * console.log('first click');
  338. * }
  339. */
  340. setProperty(name, value) {
  341. this._content.batchTable.setProperty(this._batchId, name, value);
  342. // PERFORMANCE_IDEA: Probably overkill, but maybe only mark the tile dirty if the
  343. // property is in one of the style's expressions or - if it can be done quickly -
  344. // if the new property value changed the result of an expression.
  345. this._content.featurePropertiesDirty = true;
  346. }
  347. /**
  348. * Returns whether the feature's class name equals <code>className</code>. Unlike {@link Cesium3DTileFeature#isClass}
  349. * this function only checks the feature's exact class and not inherited classes.
  350. * <p>
  351. * This function returns <code>false</code> if no batch table hierarchy is present.
  352. * </p>
  353. *
  354. * @param {string} className The name to check against.
  355. * @returns {boolean} Whether the feature's class name equals <code>className</code>
  356. *
  357. * @private
  358. */
  359. isExactClass(className) {
  360. return this._content.batchTable.isExactClass(this._batchId, className);
  361. }
  362. /**
  363. * Returns whether the feature's class or any inherited classes are named <code>className</code>.
  364. * <p>
  365. * This function returns <code>false</code> if no batch table hierarchy is present.
  366. * </p>
  367. *
  368. * @param {string} className The name to check against.
  369. * @returns {boolean} Whether the feature's class or inherited classes are named <code>className</code>
  370. *
  371. * @private
  372. */
  373. isClass(className) {
  374. return this._content.batchTable.isClass(this._batchId, className);
  375. }
  376. /**
  377. * Returns the feature's class name.
  378. * <p>
  379. * This function returns <code>undefined</code> if no batch table hierarchy is present.
  380. * </p>
  381. *
  382. * @returns {string} The feature's class name.
  383. *
  384. * @private
  385. */
  386. getExactClassName() {
  387. return this._content.batchTable.getExactClassName(this._batchId);
  388. }
  389. }
  390. export default Cesium3DTileFeature;