heshui.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. import * as mars3d from "mars3d"
  2. export let map // mars3d.Map三维地图对象
  3. export let graphicLayer // 图层
  4. // 需要覆盖config.json中地图属性参数(当前示例框架中自动处理合并)
  5. export const mapOptions = {
  6. scene: {
  7. center: { lat: 30.422407, lng: 115.820222, alt: 3498, heading: 67, pitch: -32 },
  8. globe: {
  9. depthTestAgainstTerrain: true
  10. }
  11. }
  12. }
  13. // 初始化地图业务,生命周期钩子函数(必须),框架在地图初始化完成后自动调用该函数
  14. export function onMounted(mapInstance) {
  15. map = mapInstance // 记录map
  16. // 创建矢量数据图层
  17. graphicLayer = new mars3d.layer.GraphicLayer()
  18. map.addLayer(graphicLayer)
  19. // 在layer上绑定监听事件
  20. graphicLayer.on(mars3d.EventType.click, function (event) {
  21. console.log("监听layer,单击了矢量对象", event)
  22. })
  23. bindLayerPopup() // 在图层上绑定popup,对所有加到这个图层的矢量数据都生效
  24. bindLayerContextMenu() // 在图层绑定右键菜单,对所有加到这个图层的矢量数据都生效
  25. // 加一些演示数据
  26. addDemoGraphic1()
  27. }
  28. // 释放当前地图业务的生命周期函数,具体项目中时必须写onMounted的反向操作(如解绑事件、对象销毁、变量置空)
  29. export function onUnmounted() {
  30. map = null
  31. clear()
  32. }
  33. // 立体围墙扩散效果,面状
  34. function addDemoGraphic1() {
  35. const dynamicRiver = new mars3d.graphic.DynamicRiver({
  36. positions: [
  37. [115.906607, 30.441582, 555.9],
  38. [115.899964, 30.438543, 467.3],
  39. [115.893105, 30.440714, 374.6],
  40. [115.88362, 30.443924, 340.7],
  41. [115.873948, 30.444827, 299],
  42. [115.864003, 30.442111, 292.2],
  43. [115.850741, 30.438108, 189.9]
  44. ],
  45. style: {
  46. image: "https://data.mars3d.cn/img/textures/poly-rivers.png",
  47. width: 280,
  48. height: 30,
  49. speed: 10
  50. }
  51. })
  52. graphicLayer.addGraphic(dynamicRiver)
  53. }
  54. // 生成演示数据(测试数据量)
  55. export function addRandomGraphicByCount(count) {
  56. graphicLayer.clear()
  57. graphicLayer.enabledEvent = false // 关闭事件,大数据addGraphic时影响加载时间
  58. const bbox = [116.984788, 31.625909, 117.484068, 32.021504]
  59. const result = mars3d.PolyUtil.getGridPoints(bbox, count, 30)
  60. console.log("生成的测试网格坐标", result)
  61. for (let j = 0; j < result.points.length; ++j) {
  62. const position = result.points[j]
  63. const index = j + 1
  64. const pt1 = mars3d.PointUtil.getPositionByDirectionAndLen(position, 225, result.radius)
  65. const pt2 = mars3d.PointUtil.getPositionByDirectionAndLen(position, 315, result.radius)
  66. const graphic = new mars3d.graphic.DynamicRiver({
  67. positions: [pt1, position, pt2],
  68. style: {
  69. image: "https://data.mars3d.cn/img/textures/poly-rivers.png",
  70. width: 280,
  71. height: 30,
  72. speed: 10
  73. },
  74. attr: { index }
  75. })
  76. graphicLayer.addGraphic(graphic)
  77. }
  78. graphicLayer.enabledEvent = true // 恢复事件
  79. return result.points.length
  80. }
  81. // 开始绘制
  82. export async function startDrawGraphic() {
  83. const graphic = await graphicLayer.startDraw({
  84. type: "dynamicRiver",
  85. style: {
  86. image: "https://data.mars3d.cn/img/textures/poly-rivers.png",
  87. width: 280,
  88. height: 30,
  89. speed: 10
  90. }
  91. })
  92. console.log("标绘完成", graphic.toJSON())
  93. }
  94. let dynamicRiver
  95. export function getGraphic(graphicId) {
  96. dynamicRiver = graphicLayer.getGraphicById(graphicId)
  97. return dynamicRiver
  98. }
  99. // 宽发生改变
  100. export function widthChange(value) {
  101. if (dynamicRiver) {
  102. dynamicRiver.width = value
  103. }
  104. }
  105. // 高发生改变
  106. export function heightChange(value) {
  107. if (dynamicRiver) {
  108. dynamicRiver.height = value
  109. }
  110. }
  111. // 速度发生改变
  112. export function speedChange(value) {
  113. if (dynamicRiver) {
  114. dynamicRiver.speed = value
  115. }
  116. }
  117. let onOff = true
  118. // 升高30米动画
  119. export function addHeight() {
  120. if (!dynamicRiver) {
  121. return
  122. }
  123. if (!onOff) {
  124. globalMsg("上次操作未完成")
  125. return
  126. }
  127. dynamicRiver.setOffsetHeight(30, 5) // 5秒内抬高30米
  128. throttle()
  129. }
  130. // 下降30米动画
  131. export function lowerHeight() {
  132. if (!dynamicRiver) {
  133. return
  134. }
  135. if (!onOff) {
  136. globalMsg("上次操作未完成")
  137. return
  138. }
  139. dynamicRiver.setOffsetHeight(-30, 5) // 5秒内降低30米
  140. throttle()
  141. }
  142. function throttle() {
  143. setTimeout(() => {
  144. onOff = true
  145. }, 2000)
  146. onOff = false
  147. }
  148. // 清除
  149. export function clear() {
  150. graphicLayer.clear()
  151. }
  152. // 在图层绑定Popup弹窗
  153. export function bindLayerPopup() {
  154. graphicLayer.bindPopup(function (event) {
  155. const attr = event.graphic.attr || {}
  156. attr["类型"] = event.graphic.type
  157. attr["来源"] = "我是layer上绑定的Popup"
  158. attr["备注"] = "我支持鼠标交互"
  159. return mars3d.Util.getTemplateHtml({ title: "矢量图层", template: "all", attr })
  160. })
  161. }
  162. // 绑定右键菜单
  163. export function bindLayerContextMenu() {
  164. graphicLayer.bindContextMenu([
  165. {
  166. text: "开始编辑对象",
  167. icon: "fa fa-edit",
  168. show: function (e) {
  169. const graphic = e.graphic
  170. if (!graphic || !graphic.hasEdit) {
  171. return false
  172. }
  173. return !graphic.isEditing
  174. },
  175. callback: (e) => {
  176. const graphic = e.graphic
  177. if (!graphic) {
  178. return false
  179. }
  180. if (graphic) {
  181. graphicLayer.startEditing(graphic)
  182. }
  183. }
  184. },
  185. {
  186. text: "停止编辑对象",
  187. icon: "fa fa-edit",
  188. show: function (e) {
  189. const graphic = e.graphic
  190. if (!graphic || !graphic.hasEdit) {
  191. return false
  192. }
  193. return graphic.isEditing
  194. },
  195. callback: (e) => {
  196. const graphic = e.graphic
  197. if (!graphic) {
  198. return false
  199. }
  200. if (graphic) {
  201. graphic.stopEditing()
  202. }
  203. }
  204. },
  205. {
  206. text: "复制",
  207. icon: "fa fa-copy",
  208. callback: (e) => {
  209. const graphic = e.graphic
  210. if (!graphic) {
  211. return false
  212. }
  213. if (graphic) {
  214. map.contextmenu.copyGraphic = graphic.toJSON() // map内置右键中"粘贴"菜单使用
  215. map.contextmenu.copyGraphic.layerId = graphicLayer.id
  216. }
  217. }
  218. },
  219. {
  220. text: "剪切",
  221. icon: "fa fa-scissors",
  222. callback: (e) => {
  223. const graphic = e.graphic
  224. if (!graphic) {
  225. return false
  226. }
  227. if (graphic) {
  228. map.contextmenu.copyGraphic = graphic.toJSON() // map内置右键中"粘贴"菜单使用
  229. map.contextmenu.copyGraphic.layerId = graphicLayer.id
  230. graphic.remove(true) // 移除原有对象
  231. }
  232. }
  233. },
  234. {
  235. text: "还原编辑(还原到初始)",
  236. icon: "fa fa-pencil",
  237. show: (event) => {
  238. function hasRestore(graphic) {
  239. if (!graphic || !graphic.hasEdit || !graphic.isEditing) {
  240. return false
  241. }
  242. return graphic.editing?.hasRestore()
  243. }
  244. const graphic = event.graphic
  245. if (hasRestore(graphic)) {
  246. return true
  247. }
  248. if (graphic.isPrivate && graphic.parent) {
  249. return hasRestore(graphic.parent) // 右击是编辑点时
  250. }
  251. return false
  252. },
  253. callback: (event) => {
  254. const graphic = event.graphic
  255. if (graphic.editing?.restore) {
  256. graphic.editing.restore() // 撤销编辑,可直接调用
  257. } else if (graphic.parent?.editing?.restore) {
  258. graphic.parent.editing.restore() // 右击是编辑点时
  259. }
  260. }
  261. },
  262. {
  263. text: "撤销编辑(还原到上一步)",
  264. icon: "fa fa-pencil",
  265. show: (event) => {
  266. function hasRevoke(graphic) {
  267. if (!graphic || !graphic.hasEdit || !graphic.isEditing) {
  268. return false
  269. }
  270. return graphic.editing?.hasRevoke()
  271. }
  272. const graphic = event.graphic
  273. if (hasRevoke(graphic)) {
  274. return true
  275. }
  276. if (graphic.isPrivate && graphic.parent) {
  277. return hasRevoke(graphic.parent) // 右击是编辑点时
  278. }
  279. return false
  280. },
  281. callback: (event) => {
  282. const graphic = event.graphic
  283. if (graphic.editing?.revoke) {
  284. graphic.editing.revoke() // 撤销编辑,可直接调用
  285. } else if (graphic.parent?.editing?.revoke) {
  286. graphic.parent.editing.revoke() // 右击是编辑点时
  287. }
  288. }
  289. },
  290. {
  291. text: "删除对象",
  292. icon: "fa fa-trash-o",
  293. show: (event) => {
  294. const graphic = event.graphic
  295. if (!graphic || graphic.isDestroy || graphic.isPrivate || graphic.graphicIds) {
  296. return false
  297. } else {
  298. return true
  299. }
  300. },
  301. callback: (e) => {
  302. const graphic = e.graphic
  303. if (!graphic) {
  304. return
  305. }
  306. const parent = graphic.parent // 右击是编辑点时
  307. graphicLayer.removeGraphic(graphic)
  308. if (parent) {
  309. graphicLayer.removeGraphic(parent)
  310. }
  311. }
  312. },
  313. {
  314. text: "查看聚合列表",
  315. icon: "fa fa-info",
  316. show: (event) => {
  317. const graphic = event.graphic
  318. if (graphic.cluster && graphic.graphics) {
  319. return true
  320. } else {
  321. return false
  322. }
  323. },
  324. callback: (e) => {
  325. const graphics = e.graphic?.graphics
  326. if (graphics) {
  327. const names = []
  328. for (let index = 0; index < graphics.length; index++) {
  329. const g = graphics[index]
  330. names.push(g.attr.name || g.attr.text || g.id)
  331. }
  332. return globalAlert(`${names.join(",")}`, `共${graphics.length}个聚合对象`)
  333. }
  334. }
  335. }
  336. ])
  337. }