You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

S3MTilesLayer.js 11KB

3 lat temu
3 lat temu
3 lat temu
3 lat temu
3 lat temu
3 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. import S3MTile from './S3MTile.js'
  2. import S3MLayerScheduler from './S3MLayerScheduler.js'
  3. import S3MLayerCache from './S3MLayerCache.js'
  4. import OperationType from './Enum/OperationType.js'
  5. import Style3D from './Style3D.js'
  6. const { Cesium } = DC.Namespace
  7. function S3MTilesLayer(options) {
  8. options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT)
  9. Cesium.Check.defined('options.url', options.url)
  10. Cesium.Check.defined('options.context', options.context)
  11. this.id = Cesium.createGuid()
  12. this.name = options.name
  13. this.context = options.context
  14. this.heightOffset = options.heightOffset || 0
  15. this._url = undefined
  16. this._basePath = undefined
  17. this._baseResource = undefined
  18. this.modelMatrix = new Cesium.Matrix4()
  19. this.invModelMatrix = new Cesium.Matrix4()
  20. this._visibleDistanceMax = Cesium.defaultValue(
  21. options.maxVisibleDistance,
  22. Number.MAX_VALUE
  23. )
  24. this._visibleDistanceMin = Cesium.defaultValue(
  25. options.minVisibleDistance,
  26. 0.0
  27. )
  28. this._lodRangeScale = Cesium.defaultValue(options.lodRangeScale, 1.0)
  29. this._selectedColor = new Cesium.Color(0.7, 0.7, 1.0, 1.0)
  30. this.fileType = undefined
  31. this._position = undefined
  32. this._rectangle = undefined
  33. this._rootTiles = []
  34. this._schuduler = new S3MLayerScheduler()
  35. this._selections = []
  36. this._objsOperationList = {}
  37. this._requestTiles = []
  38. this._processTiles = []
  39. this._selectedTiles = []
  40. this._cache = new S3MLayerCache()
  41. this._maximumMemoryUsage = -1
  42. this._totalMemoryUsageInBytes = 0
  43. this._style3D = new Style3D()
  44. this._maximumPriority = {
  45. foveatedFactor: -Number.MAX_VALUE,
  46. depth: -Number.MAX_VALUE,
  47. distance: -Number.MAX_VALUE,
  48. pixel: -Number.MAX_VALUE
  49. }
  50. this._minimumPriority = {
  51. foveatedFactor: Number.MAX_VALUE,
  52. depth: Number.MAX_VALUE,
  53. distance: Number.MAX_VALUE,
  54. pixel: Number.MAX_VALUE
  55. }
  56. this._readyPromise = Promise
  57. this.loadConfig(options.url)
  58. }
  59. Object.defineProperties(S3MTilesLayer.prototype, {
  60. ready: {
  61. get: function() {
  62. return this._rootTiles.length > 0
  63. }
  64. },
  65. readyPromise: {
  66. get: function() {
  67. return this._readyPromise
  68. }
  69. },
  70. rectangle: {
  71. get: function() {
  72. return this._rectangle
  73. }
  74. },
  75. visibleDistanceMax: {
  76. get: function() {
  77. return this._visibleDistanceMax
  78. },
  79. set: function(value) {
  80. Cesium.Check.typeOf.number('max visible distance', value)
  81. this._visibleDistanceMax = value
  82. }
  83. },
  84. visibleDistanceMin: {
  85. get: function() {
  86. return this._visibleDistanceMin
  87. },
  88. set: function(value) {
  89. Cesium.Check.typeOf.number('min visible distance', value)
  90. this._visibleDistanceMin = value
  91. }
  92. },
  93. lodRangeScale: {
  94. get: function() {
  95. return this._lodRangeScale
  96. },
  97. set: function(value) {
  98. Cesium.Check.typeOf.number('set layer lod range scale', value)
  99. this._lodRangeScale = value
  100. }
  101. },
  102. totalMemoryUsageInBytes: {
  103. get: function() {
  104. return this._totalMemoryUsageInBytes
  105. },
  106. set: function(value) {
  107. this._totalMemoryUsageInBytes = value
  108. }
  109. },
  110. maximumMemoryUsage: {
  111. get: function() {
  112. return this._maximumMemoryUsage
  113. },
  114. set: function(value) {
  115. this._maximumMemoryUsage = value
  116. }
  117. },
  118. style3D: {
  119. get: function() {
  120. return this._style3D
  121. },
  122. set: function(value) {
  123. this._style3D = value
  124. }
  125. }
  126. })
  127. // Cesium.Scene.prototype.hookPickFunc = Cesium.Scene.prototype.pick;
  128. //
  129. // Cesium.Scene.prototype.pick = function(windowPosition, width, height) {
  130. // let picked = this.hookPickFunc(windowPosition, width, height);
  131. // if (picked) {
  132. // let isS3MTilesLayer = picked.primitive && picked.primitive instanceof S3MTilesLayer;
  133. // if(isS3MTilesLayer){
  134. // picked.primitive.setSelection(picked.id);
  135. // }
  136. // }
  137. // else{
  138. // for(let i = 0,j = this.primitives.length;i < j;i++){
  139. // let primitive = this.primitives.get(i);
  140. // primitive instanceof S3MTilesLayer && primitive.releaseSelection();
  141. // }
  142. // }
  143. //
  144. // return picked;
  145. // };
  146. S3MTilesLayer.prototype.loadConfig = function(url) {
  147. let that = this
  148. Promise.resolve(url)
  149. .then(function(url) {
  150. let basePath
  151. let resource = Cesium.Resource.createIfNeeded(url)
  152. basePath = resource.getBaseUri(true)
  153. that._url = resource.url
  154. that._basePath = basePath
  155. that._baseResource = resource
  156. return resource.fetchJson()
  157. })
  158. .then(function(config) {
  159. let extensions = config.extensions
  160. that.fileType = extensions['s3m:FileType']
  161. let lon = config.position.x
  162. let lat = config.position.y
  163. let height = config.position.z
  164. that._position = Cesium.Cartesian3.fromDegrees(lon, lat, height + that.heightOffset)
  165. that.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(
  166. that._position
  167. )
  168. that.invModelMatrix = Cesium.Matrix4.inverse(
  169. that.modelMatrix,
  170. that.invModelMatrix
  171. )
  172. that._rectangle = Cesium.Rectangle.fromDegrees(
  173. config.geoBounds.left,
  174. config.geoBounds.bottom,
  175. config.geoBounds.right,
  176. config.geoBounds.top
  177. )
  178. if (config.heightRange) {
  179. that._minHeight = config.heightRange.min
  180. that._maxHeight = config.heightRange.max
  181. }
  182. if (config.wDescript) {
  183. let wDescript = config.wDescript.range
  184. that._minWValue = wDescript.min
  185. that._maxWValue = wDescript.max
  186. }
  187. for (let i = 0, len = config.tiles.length; i < len; i++) {
  188. let fileName = config.tiles[i].url
  189. let boundingVolume = {
  190. box: config.tiles[i].boundingbox
  191. }
  192. let tile = new S3MTile(that, undefined, boundingVolume, fileName)
  193. tile.isRootTile = true
  194. that._cache.add(tile)
  195. that._rootTiles.push(tile)
  196. }
  197. that._readyPromise.resolve(that)
  198. })
  199. .catch(function(error) {
  200. that._readyPromise.reject(error)
  201. })
  202. }
  203. S3MTilesLayer.prototype._tranverseRenderEntity = function(options, callback) {
  204. let stack = []
  205. for (let i = 0, j = this._rootTiles.length; i < j; i++) {
  206. let rootTile = this._rootTiles[i]
  207. stack.push(rootTile)
  208. }
  209. while (stack.length) {
  210. let tile = stack.pop()
  211. for (let i = 0, j = tile.renderEntities.length; i < j; i++) {
  212. const renderEntity = tile.renderEntities[i]
  213. if (renderEntity.ready) {
  214. callback(renderEntity, options)
  215. }
  216. }
  217. for (let i = 0, j = tile.children.length; i < j; i++) {
  218. stack.push(tile.children[i])
  219. }
  220. }
  221. }
  222. function updateObjsOperationCallback(renderEntity, options) {
  223. renderEntity.updateObjsOperation(options.ids, options)
  224. }
  225. S3MTilesLayer.prototype._updateObjsOperation = function(ids) {
  226. this._tranverseRenderEntity(
  227. {
  228. ids: ids
  229. },
  230. updateObjsOperationCallback
  231. )
  232. }
  233. S3MTilesLayer.prototype._setObjsOperationType = function(ids, operationType) {
  234. Cesium.Check.defined('set Objs Operation ids', ids)
  235. Cesium.Check.defined('set Objs Operation operationType', operationType)
  236. if (!Array.isArray(ids)) {
  237. ids = [ids]
  238. }
  239. let tmpArr = new Cesium.AssociativeArray()
  240. let id
  241. for (let i = 0, j = ids.length; i < j; i++) {
  242. id = ids[i]
  243. if (!Cesium.defined(id)) {
  244. continue
  245. }
  246. let operation = Cesium.defaultValue(this._objsOperationList[id], 0)
  247. if (operation === operationType) {
  248. continue
  249. }
  250. operation = operation | operationType
  251. this._objsOperationList[id] = operation
  252. tmpArr.set(id, operation)
  253. }
  254. if (tmpArr.length > 0) {
  255. this._updateObjsOperation(tmpArr._hash)
  256. }
  257. }
  258. S3MTilesLayer.prototype._removeObjsOperationType = function(
  259. ids,
  260. operationType
  261. ) {
  262. Cesium.Check.defined('set Objs Operation ids', ids)
  263. if (!Array.isArray(ids)) {
  264. ids = [ids]
  265. }
  266. let nonOperationType = OperationType.ALL ^ operationType
  267. let tmpArr = new Cesium.AssociativeArray()
  268. let id
  269. for (let i = 0, j = ids.length; i < j; i++) {
  270. id = ids[i]
  271. let operation = this._objsOperationList[id]
  272. if (!Cesium.defined(operation)) {
  273. continue
  274. }
  275. operation &= nonOperationType
  276. if (operation === OperationType.RESET) {
  277. delete this._objsOperationList[id]
  278. } else {
  279. this._objsOperationList[id] = operation
  280. }
  281. tmpArr.set(id, operation)
  282. }
  283. if (tmpArr.length > 0) {
  284. this._updateObjsOperation(tmpArr._hash)
  285. }
  286. }
  287. S3MTilesLayer.prototype.releaseSelection = function() {
  288. if (this._selections.length < 1) {
  289. return
  290. }
  291. this._removeObjsOperationType(this._selections, OperationType.SELECTED)
  292. this._selections.length = 0
  293. }
  294. S3MTilesLayer.prototype.setSelection = function(ids) {
  295. Cesium.Check.defined('setSelection ids', ids)
  296. if (!Array.isArray(ids)) {
  297. ids = [ids]
  298. }
  299. this.releaseSelection()
  300. this._selections = this._selections.concat(ids)
  301. this._setObjsOperationType(ids, OperationType.SELECTED)
  302. }
  303. function sortRequestByPriority(a, b) {
  304. return a.priority - b.priority
  305. }
  306. function requestTiles(layer) {
  307. let requestTiles = layer._requestTiles
  308. let length = requestTiles.length
  309. requestTiles.sort(sortRequestByPriority)
  310. for (let i = 0; i < length; ++i) {
  311. let tile = requestTiles[i]
  312. tile.requestContent()
  313. }
  314. }
  315. function processTiles(layer, frameState) {
  316. let tiles = layer._processTiles
  317. let length = tiles.length
  318. for (let i = 0; i < length; ++i) {
  319. let tile = tiles[i]
  320. tile.update(frameState, layer)
  321. }
  322. }
  323. function updateTiles(layer, frameState) {
  324. let selectedTiles = layer._selectedTiles
  325. let length = selectedTiles.length
  326. for (let i = 0; i < length; i++) {
  327. selectedTiles[i].update(frameState, layer)
  328. }
  329. }
  330. function unloadTile(layer, tile) {
  331. tile.free()
  332. }
  333. function freeResource(layer) {
  334. layer._cache.unloadTiles(layer, unloadTile)
  335. }
  336. S3MTilesLayer.prototype.prePassesUpdate = function(frameState) {
  337. if (!this.ready) {
  338. return
  339. }
  340. if (frameState.newFrame) {
  341. this._cache.reset()
  342. this._requestTiles.length = 0
  343. this._processTiles.length = 0
  344. this._selectedTiles.length = 0
  345. }
  346. }
  347. S3MTilesLayer.prototype.postPassesUpdate = function(frameState) {
  348. if (!this.ready) {
  349. return
  350. }
  351. freeResource(this)
  352. }
  353. S3MTilesLayer.prototype.update = function(frameState) {
  354. if (!this.ready) {
  355. return
  356. }
  357. this._schuduler.schedule(this, frameState)
  358. requestTiles(this)
  359. processTiles(this, frameState)
  360. updateTiles(this, frameState)
  361. }
  362. S3MTilesLayer.prototype.isDestroyed = function() {
  363. return false
  364. }
  365. S3MTilesLayer.prototype.destroy = function() {
  366. this._cache.reset()
  367. freeResource(this)
  368. this._rootTiles.length = 0
  369. this._requestTiles.length = 0
  370. this._processTiles.length = 0
  371. this._selectedTiles.length = 0
  372. return Cesium.destroyObject(this)
  373. }
  374. export default S3MTilesLayer