laycon.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. /* *********************************************************** */
  2. // Created by Macheng on 2019/07/31.
  3. // Description:
  4. // This is a class of map engine.
  5. // Ver 1.0 save marker path by each copy, this will cost more space.
  6. /* *********************************************************** */
  7. import * as maptalks from 'maptalks'
  8. import { ThreeLayer } from 'maptalks.three'
  9. import * as THREE from 'three'
  10. import { HeatLayer } from 'maptalks.heatmap'
  11. import { ClusterLayer } from './MyClusterLayer'
  12. class Laycon {
  13. _mapEng = null
  14. name = ''
  15. title = ''
  16. layer = null
  17. type = 'vector'
  18. enableAltitude = false
  19. imgUrl = ''
  20. hideInEdit = false
  21. constructor(opts, mapEng = null, layer = null) {
  22. if (!opts) opts = {}
  23. this.init(opts, mapEng, layer)
  24. }
  25. addGeometry(geo) {
  26. if (this.layer) {
  27. this.layer.addGeometry(geo)
  28. }
  29. return this
  30. }
  31. addToMapEng(mapEng) {
  32. if (mapEng) {
  33. this._mapEng = mapEng
  34. this.layer.remove()
  35. this._mapEng.addLaycon(this)
  36. }
  37. return this
  38. }
  39. clear() {
  40. if (this.layer) {
  41. this.layer.clear()
  42. }
  43. }
  44. init(opts, mapEng = null, layer = null) {
  45. this.name = opts.name || this.name
  46. this.title = opts.title || this.title
  47. for (const v of LAYER_DEFINES) {
  48. if (v.name === this.name) {
  49. this.enableAltitude = v.enableAltitude
  50. }
  51. }
  52. this.type = opts.type || this.type
  53. this.imgUrl = opts.imgUrl || this.imgUrl
  54. this.hideInEdit = opts.hideInEdit || this.hideInEdit
  55. if (this.layer) {
  56. this.layer.remove()
  57. this.layer = null
  58. }
  59. if (layer) {
  60. this.layer = layer
  61. this.layer.config('enableAltitude', this.enableAltitude)
  62. } else {
  63. switch (this.type) {
  64. case 'vector':
  65. this.layer = new maptalks.VectorLayer(this.name, [], {
  66. enableAltitude: this.enableAltitude
  67. })
  68. break
  69. case 'vec3d':
  70. this.layer = new ThreeLayer(this.name, {
  71. forceRenderOnMoving: true,
  72. forceRenderOnRotating: true,
  73. enableAltitude: true
  74. })
  75. this.layer.prepareToDraw = function(gl, scene, camera) {
  76. const light = new THREE.PointLight(0xffffff)
  77. // const light = new THREE.DirectionalLight(0xffffff);
  78. // light.position.set(0, 0, 60).normalize();
  79. //light.position.set(0, -10, 30).normalize();
  80. camera.add(light)
  81. }
  82. break
  83. case 'image':
  84. this.layer = new maptalks.ImageLayer(this.name,
  85. [
  86. {
  87. url: this.imgUrl,
  88. extent: [-10000, -10000, 10000, 10000],
  89. opacity: 1
  90. }
  91. ], {
  92. forceRenderOnMoving: true,
  93. forceRenderOnZooming: true,
  94. forceRenderOnRotating: true
  95. })
  96. break
  97. case 'heat':
  98. this.layer = new HeatLayer(this.name)
  99. break
  100. case 'cluster':
  101. const option = {
  102. 'noClusterWithOneMarker': true,
  103. 'maxClusterZoom': 21,
  104. //"count" is an internal variable: marker count in the cluster.
  105. 'symbol': {
  106. 'markerType': 'ellipse',
  107. 'markerFill': { property: 'count', type: 'interval', stops: [[0, '#1bbc9b'], [9, '#1bbc9b'], [99, '#1bbc9b']] },
  108. 'markerFillOpacity': 0.7,
  109. 'markerLineOpacity': 1,
  110. 'markerLineWidth': 3,
  111. 'markerLineColor': '#fff',
  112. 'markerWidth': { property: 'count', type: 'interval', stops: [[0, 40], [9, 60], [99, 80]] },
  113. 'markerHeight': { property: 'count', type: 'interval', stops: [[0, 40], [9, 60], [99, 80]] }
  114. },
  115. 'drawClusterText': true,
  116. 'geometryEvents': true,
  117. 'single': true
  118. }
  119. if (this.name == 'tag') {
  120. option.symbol.markerType = 'square'
  121. option.symbol.markerFill = { property: 'count', type: 'interval', stops: [[0, '#1bbcff'], [9, '#1bbcff'], [99, '#1bbcff']] }
  122. }
  123. this.layer = new ClusterLayer(this.name, [], option)
  124. this.layer.on('compute-grid', () => {
  125. if (this.mapEng.cbOnClusterChange) {
  126. this.mapEng.cbOnClusterChange()
  127. }
  128. })
  129. break
  130. }
  131. }
  132. if (mapEng) {
  133. this.addToMapEng(mapEng)
  134. }
  135. return this
  136. }
  137. getAltas() {
  138. if (this.layer) {
  139. return this.layer.getMap()
  140. }
  141. return null
  142. }
  143. getCamera() {
  144. if (this.layer) {
  145. return this.layer.getCamera()
  146. }
  147. return null
  148. }
  149. getGeometries() {
  150. if (this.layer) {
  151. return this.layer.getGeometries()
  152. }
  153. return []
  154. }
  155. getId() {
  156. return this.name
  157. }
  158. getScene() {
  159. if (this.layer) {
  160. return this.layer.getScene()
  161. }
  162. return null
  163. }
  164. hide() {
  165. if (this.layer) {
  166. this.layer.hide()
  167. }
  168. return this
  169. }
  170. isVisible() {
  171. if (this.layer) {
  172. return this.layer.isVisible()
  173. }
  174. return false
  175. }
  176. remove() {
  177. if (this.layer) {
  178. this.layer.remove()
  179. if (this._mapEng) {
  180. this._mapEng.removeLaycon(this.name)
  181. this._mapEng = null
  182. }
  183. }
  184. return this
  185. }
  186. show() {
  187. if (this.layer) {
  188. this.layer.show()
  189. }
  190. return this
  191. }
  192. }
  193. const LAYER_ID_DEFS = {
  194. 'IdBg': 0,
  195. 'IdBorder': 1,
  196. 'IdWall': 2,
  197. 'IdThing': 3,
  198. 'IdTrace': 4,
  199. 'Id3d': 5,
  200. 'IdArea': 6,
  201. 'IdLabel': 7,
  202. 'IdSign': 8,
  203. 'IdTag': 9,
  204. 'IdHeat': 10,
  205. 'IdStat': 11,
  206. 'IdSheet': 12,
  207. 'IdAnchor': 13,
  208. 'IdDevice': 14,
  209. 'IdData': 15
  210. }
  211. const LAYER_DEFINES = [
  212. { idx: LAYER_ID_DEFS['IdBg'], name: 'bg', title: '背景图', layer: null, type: 'image', runShow: true, enableAltitude: false, imgUrl: 'static/img/white.png' },
  213. { idx: LAYER_ID_DEFS['IdBorder'], name: 'border', title: '底框图层', layer: null, type: 'vector', runShow: true, enableAltitude: false },
  214. { idx: LAYER_ID_DEFS['IdWall'], name: 'wall', title: '墙壁图层', layer: null, type: 'vector', runShow: true, enableAltitude: true },
  215. { idx: LAYER_ID_DEFS['IdThing'], name: 'thing', title: '物件图层', layer: null, type: 'vector', runShow: true, enableAltitude: true },
  216. { idx: LAYER_ID_DEFS['IdTrace'], name: 'trace', title: '轨迹图层', layer: null, type: 'vector', runShow: true, enableAltitude: false },
  217. { idx: LAYER_ID_DEFS['Id3d'], name: '3d', title: '3D图层', layer: null, type: 'vec3d', runShow: true, enableAltitude: true },
  218. { idx: LAYER_ID_DEFS['IdArea'], name: 'area', title: '区域图层', layer: null, type: 'vector', runShow: false, enableAltitude: true },
  219. { idx: LAYER_ID_DEFS['IdLabel'], name: 'label', title: '文本图层', layer: null, type: 'vector', runShow: true, enableAltitude: true },
  220. { idx: LAYER_ID_DEFS['IdSign'], name: 'sign', title: '标记图层', layer: null, type: 'cluster', runShow: true, enableAltitude: true },
  221. { idx: LAYER_ID_DEFS['IdTag'], name: 'tag', title: '标签图层', layer: null, type: 'cluster', runShow: true, enableAltitude: true },
  222. { idx: LAYER_ID_DEFS['IdHeat'], name: 'heat', title: '热力图层', layer: null, type: 'heat', runShow: true, enableAltitude: false },
  223. { idx: LAYER_ID_DEFS['IdStat'], name: 'stat', title: '统计图层', layer: null, type: 'vector', runShow: true, enableAltitude: false },
  224. { idx: LAYER_ID_DEFS['IdSheet'], name: 'sheet', title: '权限图层', layer: null, type: 'vector', runShow: false, enableAltitude: true },
  225. { idx: LAYER_ID_DEFS['IdAnchor'], name: 'anchor', title: '信标图层', layer: null, type: 'vector', runShow: true, enableAltitude: true },
  226. { idx: LAYER_ID_DEFS['IdDevice'], name: 'device', title: '设备图层', layer: null, type: 'vector', runShow: false, enableAltitude: true },
  227. { idx: LAYER_ID_DEFS['IdData'], name: 'data', title: '数据图层', layer: null, type: 'vector', runShow: true, enableAltitude: true }
  228. ]
  229. export {
  230. Laycon,
  231. LAYER_ID_DEFS,
  232. LAYER_DEFINES
  233. }