Map.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. import * as THREE from "../../../libs/three.js/build/three.module.js";
  2. import { EventDispatcher } from "../../EventDispatcher.js";
  3. let texLoader = new THREE.TextureLoader()
  4. texLoader.crossOrigin = "anonymous"
  5. let createErrorMaterial = function() {
  6. var t = new THREE.MeshBasicMaterial({
  7. transparent: !0,
  8. depthWrite: !1,
  9. depthTest: !0,
  10. opacity: 1,
  11. side: THREE.DoubleSide
  12. });
  13. return t.color = new THREE.Color(3355443),
  14. t
  15. }
  16. let tempVector = new THREE.Vector3, //sharedata
  17. face1 = new THREE.Face3(0,1,2),
  18. face2 = new THREE.Face3(2,3,0),
  19. errorMaterial = createErrorMaterial(),
  20. uv00 = new THREE.Vector2(0,0),
  21. uv01 = new THREE.Vector2(0,1),
  22. uv10 = new THREE.Vector2(1,0),
  23. uv11 = new THREE.Vector2(1,1),
  24. face1UV = [uv00, uv10, uv11],
  25. face2UV = [uv11, uv01, uv00]
  26. const HALF_WORLD_SIZE = 21e6
  27. const MAX_VERTICAL_DIST = 2
  28. const MAX_VERTICAL_DIST_TO_BEST = 1
  29. export class MapLayer extends EventDispatcher{ // 包括了 MapLayerBase SceneLayer
  30. constructor(viewer_, viewport){
  31. super()
  32. this.sceneGroup = new THREE.Object3D;
  33. this.sceneGroup.name = "MapLayer"
  34. this.loadingInProgress = 0
  35. this.maps = []
  36. this.frustum = new THREE.Frustum
  37. this.frustumMatrix = new THREE.Matrix4
  38. this.tileColor = /* i && i.tileColor ? i.tileColor : */new THREE.Color(16777215)
  39. //添加地图
  40. var map = new TiledMapOpenStreetMap(this, this.tileColor )
  41. this.addMap(map)
  42. this.viewport = viewport
  43. this.changeViewer(viewer_)
  44. /* this.on('needUpdate',()=>{
  45. this.mapLayer.update()
  46. })
  47. */
  48. }
  49. addMapEntity(data){
  50. if(!data || !data[0]){
  51. Potree.Log('平面图无数据','red')
  52. return
  53. }
  54. var floorplan = new TiledMapFromEntity(this, this.tileColor, data[0] )//[0]?
  55. this.addMap(floorplan)
  56. floorplan.updateProjection()
  57. floorplan.updateObjectGroup()
  58. this.needUpdate = true
  59. this.dispatchEvent({type:'floorplanLoaded', floorplan})
  60. }
  61. addMap(t){
  62. this.maps.push(t)
  63. //this.view.invalidateScene()
  64. this.needUpdate = true
  65. }
  66. removeMap(t){
  67. var e = this.maps.indexOf(t);
  68. if(e >= 0){
  69. t.removeFromSceneGroup(this.sceneGroup)
  70. this.maps.splice(e, 1)
  71. }
  72. /* this.view.invalidateScene() */
  73. this.needUpdate = true
  74. this.viewer.dispatchEvent({
  75. type:'content_changed'
  76. })
  77. }
  78. changeViewer(viewer_){//add
  79. this.viewer = viewer_
  80. }
  81. initProjection(){
  82. this.maps.forEach(map=>{
  83. map.updateProjection()
  84. map.updateObjectGroup()
  85. })
  86. }
  87. visibilityChanged(){
  88. if (!this.visible)
  89. for (var t = 0, e = this.maps; t < e.length; t++){
  90. e[t].removeFromSceneGroup(this.sceneGroup)
  91. }
  92. }
  93. onAfterRenderViewport(e){
  94. var n = this;
  95. /* this.isVisibleInViewport(e) && (this.updateTimer || this.loadingInProgress || (this.updateTimer = window.setTimeout((function(){
  96. n.update(e).then((function(t){
  97. t && n.loadComplete.emit(!0)
  98. }
  99. )).catch(u.handleWarning)
  100. }
  101. ), 100))) */
  102. }
  103. update(){
  104. this.needUpdate = false
  105. if(this.disabled || !this.maps.find(e=>!e.disabled) || !this.maps.find(e=>e.objectGroup.visible) )return //add
  106. var e, n, i, r, o;
  107. this.updateTimer = void 0,
  108. e = this.viewport.camera,
  109. n = e.projectionMatrix.clone(),
  110. n.elements[0] /= 1.5,
  111. n.elements[5] /= 1.5,
  112. this.frustumMatrix.multiplyMatrices(n, e.matrixWorldInverse),
  113. this.frustum.setFromProjectionMatrix(this.frustumMatrix),
  114. this.frustum.planes[4].setComponents(0, 0, 0, 0),
  115. this.frustum.planes[5].setComponents(0, 0, 0, 0),
  116. i = !0
  117. for (r = 0; r < this.maps.length; r++){
  118. var map = this.maps[r]
  119. i = map.update(this.frustum, this.sceneGroup) && i;
  120. }
  121. return [2, i]
  122. }
  123. getAttributions(){
  124. for (var t = {}, e = 0, n = this.maps; e < n.length; e++){
  125. n[e].fillAttributions(t)
  126. }
  127. return t
  128. }
  129. updateProjection(){
  130. for (var t = 0, e = this.maps; t < e.length; t++){
  131. var n = e[t];
  132. n.clearProjection(),
  133. n.updateObjectGroup()
  134. }
  135. }
  136. }
  137. export class TiledMapBase extends EventDispatcher{
  138. constructor(/* t, */name, mapLayer, tileColor, projection){
  139. super();
  140. this.name = name
  141. //this.TransformService = t,
  142. this.mapLayer = mapLayer,
  143. this.tileColor = tileColor,
  144. this.bias = 0
  145. this.zIndex = -1
  146. this.objectGroup = new THREE.Object3D;
  147. this.objectGroup.name = name
  148. this.objectGroupAdded = !1,
  149. this.baseTile = new MapTile(this,/* this.mapLayer, */this.objectGroup,this.tileColor),
  150. this.isTileVisibleBox = new THREE.Box3,
  151. this.isTileVisibleVec = new THREE.Vector3
  152. this.projection = projection
  153. this._zoomLevel = 0;//1-20
  154. }
  155. get zoomLevel(){
  156. return this._zoomLevel
  157. }
  158. set zoomLevel(zoomLevel){
  159. if(this._zoomLevel != zoomLevel){
  160. this._zoomLevel = zoomLevel
  161. this.emit('zoomLevelChange',zoomLevel)
  162. }
  163. }
  164. updateObjectGroup(){
  165. this.position && this.objectGroup.position.copy(this.position),
  166. this.quaternion && this.objectGroup.quaternion.copy(this.quaternion),
  167. this.objectGroup.updateMatrixWorld(!0)
  168. }
  169. updateProjection(){
  170. //this.transformMapToLocal || (this.transformMapToLocal = this.TransformService.getTransform(this.projection, this.TransformService.crsLocal))
  171. if(!this.transformMapToLocal){
  172. if(proj4.defs("NAVVIS:TMERC")){
  173. if(this.projection == "EPSG:4550"){
  174. this.transformMapToLocal = {
  175. forward:(e)=>{
  176. var a = viewer.transform.lonlatTo4550.inverse(e)
  177. return viewer.transform.lonlatToLocal.forward(a)
  178. },
  179. }
  180. }else{
  181. this.transformMapToLocal = proj4(this.projection, "NAVVIS:TMERC")
  182. }
  183. //this.transformMapToLocal = proj4(this.projection, "NAVVIS:TMERC")
  184. }
  185. }
  186. }
  187. setEnable(enable){//add
  188. if(!this.disabled == enable)return
  189. this.disabled = !enable
  190. viewer.updateVisible(this.objectGroup, 'setEnable', enable)
  191. if(!enable){
  192. this.baseTile.remove()
  193. }else{
  194. this.mapLayer.needUpdate = true
  195. }
  196. this.mapLayer.viewer.dispatchEvent({
  197. type:'content_changed'
  198. })
  199. }
  200. /* clearProjection(){
  201. this.transformMapToLocal = void 0,
  202. this.projection.name !== this.TransformService.NAVVIS_LOCAL && this.baseTile.remove()
  203. } */
  204. update(e, n){
  205. if(this.disabled || !this.objectGroup.visible)return
  206. this.updateProjection()
  207. if(!this.transformMapToLocal)return
  208. if ( !this.isTileVisible(new THREE.Vector3(0,0,0), this.mapSizeM, e))
  209. return this.removeFromSceneGroup(n), !0;
  210. let viewport = this.mapLayer.viewport
  211. var i = new THREE.Vector3(-.5 * this.mapSizeM,0,0);
  212. i.applyMatrix4(this.objectGroup.matrixWorld),
  213. i.project(viewport.camera);
  214. var o = new THREE.Vector3(.5 * this.mapSizeM,0,0);
  215. o.applyMatrix4(this.objectGroup.matrixWorld),
  216. o.project(viewport.camera);
  217. var a = viewport.resolution.x
  218. , s = viewport.resolution.y
  219. if (a <= 0 || s <= 0 || isNaN(i.x) || isNaN(o.x)) return !1;
  220. i.sub(o),
  221. i.x *= a / 2,
  222. i.y *= s / 2;
  223. var c = this.tileSizePx / i.length()
  224. , level = Math.ceil(-Math.log(c) / Math.log(2) - this.bias);
  225. level = Math.max(level, 0)
  226. level = Math.min(level, void 0 === this.maxDepth ? 1 / 0 : this.maxDepth)
  227. this.zoomLevel = level//add
  228. //console.log(level)
  229. this.addToSceneGroup(n)
  230. return this.baseTile.update(this, e, level, this.mapSizeM, 0, 0, "")
  231. }
  232. isTileVisible(e, n, i){
  233. if (n > HALF_WORLD_SIZE) return !0;
  234. var r = .5 * n;
  235. this.transformMapToLocal.forward(e)
  236. this.isTileVisibleBox.makeEmpty()
  237. this.isTileVisibleVec.set(e.x - r, e.y - r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
  238. this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
  239. this.isTileVisibleVec.set(e.x - r, e.y + r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
  240. this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
  241. this.isTileVisibleVec.set(e.x + r, e.y - r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
  242. this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
  243. this.isTileVisibleVec.set(e.x + r, e.y + r, e.z).applyMatrix4(this.objectGroup.matrixWorld)
  244. this.isTileVisibleBox.expandByPoint(this.isTileVisibleVec)
  245. return i.intersectsBox(this.isTileVisibleBox)
  246. }
  247. addToSceneGroup(t){
  248. this.objectGroupAdded || (t.add(this.objectGroup),
  249. this.objectGroupAdded = !0)
  250. }
  251. removeFromSceneGroup(t){
  252. this.baseTile.remove(),
  253. this.objectGroupAdded && (t.remove(this.objectGroup),
  254. this.objectGroupAdded = !1)
  255. }
  256. }
  257. export class MapTile{
  258. constructor(map,/* t, */ e, n){
  259. this.map = map;
  260. //this.mapLayer = t,
  261. this.objectGroup = e,
  262. this.tileColor = n,
  263. this.meshAdded = !1,
  264. this.textureLoaded = !1,
  265. this.children = []
  266. }
  267. update(e, n, i, r, o, a, s){
  268. return !!this.doesNotContainTilesToBeDisplayed(e) || (0 === i ? this.updateTile(e, r, o, a) : this.updateSubTiles(e, n, i, r, o, a, s))
  269. }
  270. doesNotContainTilesToBeDisplayed(t){
  271. return t.tilePresenceMap && t.tilePresenceMap.empty
  272. }
  273. updateTile(t, e, n, i){
  274. if(!this.mesh){
  275. this.createTileObject(t, e, n, i)
  276. }
  277. if(!this.meshAdded){
  278. this.objectGroup.add(this.mesh)
  279. this.meshAdded = !0
  280. }
  281. if(this.textureLoaded){
  282. this.removeChildren()
  283. }
  284. return this.textureLoaded
  285. }
  286. updateSubTiles(entity, n, level, o, a, s, c){
  287. for (var l = !0, u = [-.25 * o, .25 * o, -.25 * o, .25 * o], d = [.25 * o, .25 * o, -.25 * o, -.25 * o], p = 0; p < 4; ++p){
  288. var h = c + p.toString(10);
  289. //一级(512):0 1 2 3分别为左上、右上、左下、右下。二级(1024)就是把一级的每一块分裂,如00 01 02 03分别是0的左上、右上、左下、右下……
  290. /* if(entity.name == 'floorplan'){
  291. console.log(1)
  292. } */
  293. if (!entity.tilePresenceMap || entity.tilePresenceMap[h]){
  294. //去掉判断,直接显示
  295. var f = a + u[p]
  296. , m = s + d[p];
  297. tempVector.set(f, m, 0);
  298. if (entity.isTileVisible(tempVector, .5 * o, n)){
  299. this.children[p] || (this.children[p] = new MapTile(this.map, this.objectGroup,this.tileColor))
  300. l = this.children[p].update(entity, n, level - 1, .5 * o, f, m, h) && l
  301. } else {
  302. if (this.children[p]){
  303. this.children[p].remove()
  304. delete this.children[p]
  305. }
  306. }
  307. }
  308. }
  309. return l && this.removeObject3D(),
  310. l
  311. }
  312. createTileObject(t, e, n, a){
  313. var s = this;
  314. this.mesh = this.createMesh(t.transformMapToLocal, e, n, a),
  315. this.textureLoaded = !1;
  316. var c = t.mapSizeM / e
  317. , l = Math.log(c) / Math.log(2)
  318. , u = n / e + .5 * (c - 1)
  319. , d = -a / e + .5 * (c - 1)
  320. , p = t.getTileUrl(Math.round(l), Math.round(u), Math.round(d));
  321. viewer.setObjectLayers(this.mesh, 'map' )
  322. this.mesh.renderOrder = -(1e6 - l - 100 * (t.zIndex || 0));
  323. var h = this.mesh.material;
  324. var loadDone = ()=>{
  325. this.map.mapLayer.loadingInProgress--
  326. if(this.map.mapLayer.loadingInProgress == 0){
  327. this.map.mapLayer.emit('loadDone')
  328. }
  329. }
  330. h.map = texLoader.load(p, (tex)=>{
  331. if(this.mesh){//如果还要显示的话
  332. this.textureLoaded = true
  333. this.mesh.material.opacity = 1
  334. //this.mapLayer.view.invalidateScene()
  335. this.map.mapLayer.viewer.dispatchEvent({
  336. type:'content_changed'
  337. })
  338. this.map.mapLayer.needUpdate = true //表示还要继续update(以removeChildren)
  339. }else{
  340. tex.dispose()
  341. }
  342. loadDone()
  343. } , void 0, (()=>{//error
  344. this.textureLoaded = !0
  345. if(this.mesh){
  346. this.mesh.material.dispose() //o.disposeMeshMaterial(this.mesh)
  347. this.mesh.material = errorMaterial
  348. //this.map.mapLayer.view.invalidateScene())
  349. this.map.mapLayer.viewer.dispatchEvent({
  350. type:'content_changed'
  351. })
  352. }
  353. loadDone()
  354. }))
  355. h.map.anisotropy = 0,
  356. h.map.generateMipmaps = !1,
  357. h.map.minFilter = THREE.LinearFilter,
  358. h.map.magFilter = THREE.LinearFilter,
  359. this.map.mapLayer.loadingInProgress++
  360. }
  361. createMesh(t, e, n, o){
  362. var a = new THREE.Geometry;
  363. return tempVector.set(n - e / 2, o - e / 2, 0),
  364. a.vertices.push(new THREE.Vector3().copy(t.forward(tempVector))),
  365. tempVector.set(n + e / 2, o - e / 2, 0),
  366. a.vertices.push(new THREE.Vector3().copy(t.forward(tempVector))),
  367. tempVector.set(n + e / 2, o + e / 2, 0),
  368. a.vertices.push(new THREE.Vector3().copy(t.forward(tempVector))),
  369. tempVector.set(n - e / 2, o + e / 2, 0),
  370. a.vertices.push(new THREE.Vector3().copy(t.forward(tempVector))),
  371. a.faces.push(face1),
  372. a.faces.push(face2),
  373. a.faceVertexUvs[0].push(face1UV),
  374. a.faceVertexUvs[0].push(face2UV),
  375. new THREE.Mesh(a,this.createMaterial())
  376. }
  377. createMaterial(){
  378. var t = new THREE.MeshBasicMaterial({
  379. transparent: !0,
  380. depthWrite: !1,
  381. depthTest: !0,
  382. opacity: 0,
  383. side: THREE.DoubleSide
  384. });
  385. return t.color = this.tileColor ? this.tileColor : new THREE.Color(16777215),
  386. t
  387. }
  388. remove(){
  389. this.removeObject3D(),
  390. this.removeChildren()
  391. }
  392. removeObject3D(){
  393. if (this.mesh){
  394. if (this.objectGroup.remove(this.mesh),
  395. this.textureLoaded){
  396. var t = this.mesh.material.map;
  397. t && t.dispose()
  398. }
  399. this.mesh.material.dispose() //o.disposeMeshMaterial(this.mesh),
  400. this.mesh.geometry.dispose()
  401. this.mesh = void 0
  402. }
  403. this.meshAdded = !1,
  404. this.textureLoaded = !1
  405. }
  406. removeChildren(){
  407. for (var t = 0, e = this.children; t < e.length; t++){
  408. var n = e[t];
  409. n && (n.removeObject3D(),
  410. n.removeChildren())
  411. }
  412. this.children.length = 0
  413. }
  414. }
  415. proj4.defs("EPSG:3857", "+title=WGS 84 / Pseudo-Mercator +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs")
  416. //这里地图世界的中心是不是lon:0,lat:0
  417. export class TiledMapOpenStreetMap extends TiledMapBase{
  418. constructor(mapLayer, tileColor){
  419. super('map', mapLayer, tileColor, /* "EPSG:4550" */ "EPSG:3857" ) //EPSG projection
  420. this.baseUrl = "https://wprd03.is.autonavi.com/appmaptile?style=7&x=${x}&y=${y}&z=${z}",
  421. //this.baseUrl = "https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x=${x}&y=${y}&z=${z}" //最高只到18 level
  422. this.attribution = "© PopSmart, © 高德地图",
  423. this.tileSizePx = 256
  424. this.mapSizeM = 40075017
  425. this.maxDepth = 20
  426. this.bias = 0.5
  427. }
  428. getTileUrl(t, e, n){
  429. return this.baseUrl.replace(/\${z}/, t.toString(10)).replace(/\${x}/, e.toString(10)).replace(/\${y}/, n.toString(10))
  430. }
  431. fillAttributions(t){
  432. t[this.attribution] = {
  433. score: 50
  434. }
  435. }
  436. }
  437. export class TiledMapFromEntity extends TiledMapBase{
  438. constructor(mapLayer, tileColor, data){
  439. super('floorplan', mapLayer, tileColor, "NAVVIS:TMERC" /* "EPSG:3857" *//* "WGS84" */) //直接就是本地坐标,没有projec
  440. var entity = this.fillFromData(data)
  441. this.tiledMapEntity = entity
  442. //c.RestService = s,
  443. this.tileSizePx = entity.tileSizePx,
  444. this.mapSizeM = entity.mapSizeM,
  445. this.maxDepth = entity.maxDepth,
  446. //this.projection = n.crsLocal,
  447. this.zIndex = 0,
  448. this.tilePresenceMap = this.decodeBitStream(this.tiledMapEntity.quadtree) //包含tile分裂信息,如果写错了会造成tile显示不全
  449. }
  450. fillFromData(e){
  451. let data = {}
  452. data.id = e.id
  453. data.globalLocation = Potree.Utils.VectorFactory.fromArray3(e.location),
  454. data.orientation = Potree.Utils.QuaternionFactory.fromArray(e.orientation)
  455. if(Potree.fileServer){
  456. data.filePath = `https://${Potree.config.urls.prefix}${e.file_path}`
  457. }else{
  458. data.filePath = `https://${Potree.config.urls.prefix}/data/${Potree.settings.number}/${e.file_path}`
  459. }
  460. //if(!data.filePath.includes('building_1'))data.filePath = data.filePath.replace('building','building_1')//暂时
  461. data.fileName = '$DEPTH/$X/$Y.png',//e.file_name,
  462. data.type = e.type,
  463. data.mapSizeM = e.map_size_m,
  464. data.tileSizePx = e.tile_size_px,
  465. data.maxDepth = e.max_depth,
  466. data.quadtree = e.quadtree,
  467. data.floorId = e.floor_id,
  468. data.bundleId = e.bundle_id
  469. //this.computeLocalCoordinates()
  470. return data
  471. }
  472. computeLocalCoordinates(){
  473. if(proj4.defs("NAVVIS:TMERC")){
  474. this.tiledMapEntity.location = new THREE.Vector3().copy(viewer.transform.lonlatToLocal.forward(this.tiledMapEntity.globalLocation))
  475. }
  476. }
  477. updateProjection() {
  478. super.updateProjection()
  479. if(!this.position){
  480. this.computeLocalCoordinates()
  481. }
  482. /* this.projection = this.TransformService.crsLocal,
  483. t.prototype.updateProjection.call(this) */
  484. }
  485. get position(){
  486. return this.tiledMapEntity.location
  487. /* enumerable: !0,
  488. configurable: !0 */
  489. }
  490. get quaternion(){
  491. return this.tiledMapEntity.orientation
  492. /* enumerable: !0,
  493. configurable: !0 */
  494. }
  495. getTileUrl(t, e, n) {
  496. var i = (this.tiledMapEntity.filePath + "/" + this.tiledMapEntity.fileName).replace(/\$DEPTH/g, t.toString(10)).replace(/\$X/g, e.toString(10)).replace(/\$Y/g, n.toString(10));
  497. return i += "?t=" + (new Date).getTime()
  498. //this.RestService.addAuthorizationQueryParameter(i) //????
  499. }
  500. fillAttributions(t) {
  501. t.NavVis = {
  502. score: 100
  503. }
  504. }
  505. decodeBitStream(t) {
  506. if (!t)
  507. return {
  508. empty: !0
  509. };
  510. for (var e = {}, n = [e], i = 0; i < t.length; i++) {
  511. var r = n.shift()
  512. , o = parseInt(t.substr(i, 1), 16);
  513. if (1 & o) {
  514. var a = {};
  515. r[0] = a,
  516. n.push(a)
  517. }
  518. 2 & o && (a = {},
  519. r[1] = a,
  520. n.push(a)),
  521. 4 & o && (a = {},
  522. r[2] = a,
  523. n.push(a)),
  524. 8 & o && (a = {},
  525. r[3] = a,
  526. n.push(a))
  527. }
  528. var s = {
  529. empty: !0
  530. };
  531. return this.computeHashes(s, e, ""),
  532. s
  533. }
  534. computeHashes(t, e, n) {
  535. for (var i = 0; i < 4; i++)
  536. e[i] && (t[n + i.toString(10)] = !0,
  537. t.empty = !1,
  538. this.computeHashes(t, e[i], n + i.toString(10)))
  539. }
  540. }
  541. /* {
  542. "bundle_id": 1, //t-CwfhfqJ
  543. "file_name": "$DEPTH/$X/$Y.png",
  544. "file_path": "data/bundle_t-CwfhfqJ/building_1/map_tiles/11",
  545. "floor_id": 11,
  546. "id": 1,
  547. "location": [
  548. 113.5957510575092,
  549. 22.366605927999239,
  550. 0.0
  551. ],
  552. "map_size_m": 61.44,
  553. "max_depth": 3,
  554. "orientation": [
  555. 0.7071067811865476,
  556. 0.0,
  557. 0.0,
  558. 0.7071067811865475
  559. ],
  560. "quadtree": "fe5f7c7fcffff7f53",
  561. "sceneCode": "t-CwfhfqJ",
  562. "tile_size_px": 256,
  563. "type": "TILED_PYRAMID"
  564. }
  565. */