Map1.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. <template>
  2. <el-row class="movie-list">
  3. <el-col :md="24">
  4. <el-row style="padding-right: 5px; padding-left: 5px; padding-bottom: 5px">
  5. <el-card class="box-card">
  6. <div slot="header" class="clearfix">
  7. <el-select v-model="selectedOption" placeholder="选择标签" @change="onChange">
  8. <el-option
  9. v-for="(item, index) in selectOptions"
  10. :key="index"
  11. :label="item.name"
  12. :value="item.value"
  13. />
  14. </el-select>
  15. </div>
  16. <div class="text item amap-wrapper">
  17. <el-amap
  18. class="amap-box"
  19. :vid="'amap-vue'"
  20. :amap-manager="amapManager"
  21. :zoom="zoom"
  22. :center="mapCenter"
  23. :plugin="plugins"
  24. :events="mapEvents"
  25. >
  26. <el-amap-marker
  27. v-for="(marker, index) in markers"
  28. :key="index"
  29. :position="marker.position"
  30. :label="marker.label"
  31. :events="markerEvents"
  32. :ext-data="marker.extData"
  33. />
  34. </el-amap>
  35. </div>
  36. </el-card>
  37. </el-row>
  38. </el-col>
  39. <!-- marker 内容弹窗 -->
  40. <el-dialog
  41. append-to-body
  42. :visible.sync="showMarkerDialog"
  43. :before-close="handleDialogClose"
  44. width="30%"
  45. center
  46. >
  47. <el-card class="box-card">
  48. <div slot="header" class="clearfix">
  49. <el-button
  50. v-clipboard:copy="earthPoint.lat + ' ' + earthPoint.lng"
  51. v-clipboard:success="onCopy"
  52. v-clipboard:error="onCopyError"
  53. type="text"
  54. >GoogleEarth 坐标</el-button>
  55. </div>
  56. <div class="text item">
  57. <el-image v-if="markerInfo.photoUrl !== null" :src="markerInfo.photoUrl" min-width="40" height="30" />
  58. <br>
  59. <label>
  60. 商品 <span v-text="markerInfo.itemId" />
  61. </label>
  62. <br>
  63. <label>
  64. SKU <span v-text="markerInfo.sku" />
  65. </label>
  66. <br>
  67. <label>
  68. 评论 <span style="color: blue" v-text="markerInfo.replyContent" />
  69. </label>
  70. <br>
  71. <!-- <label v-if="markerInfo.appendContent !== undefined || markerInfo.appendContent !== null">
  72. 追加 <span style="color: blue" v-text="markerInfo.appendContent"/>
  73. </label>-->
  74. </div>
  75. </el-card>
  76. </el-dialog>
  77. </el-row>
  78. </template>
  79. <script>
  80. import { getGeoItems, getMapMarkers, getMarkerInfo } from '@/api/map'
  81. import Vue from 'vue'
  82. import VueAMap from 'vue-amap'
  83. Vue.use(VueAMap)
  84. VueAMap.initAMapApiLoader({
  85. key: 'your amap key',
  86. plugin: [
  87. 'AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar',
  88. 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor', 'AMap.MassMarks', 'AMap.Size',
  89. 'AMap.Pixel'
  90. ],
  91. // 默认高德 sdk 版本为 1.4.4
  92. v: '1.4.15'
  93. })
  94. import { AMapManager, lazyAMapApiLoaderInstance } from 'vue-amap'
  95. const amapManager = new AMapManager()
  96. export default {
  97. name: 'Map1',
  98. data() {
  99. return {
  100. amap: null,
  101. plugins: ['Scale'],
  102. mapCenter: [104.069045, 30.577861],
  103. // zoom=10 的比例尺为 10km
  104. zoom: 10,
  105. markers: [],
  106. markerEvents: {
  107. click: (e) => {
  108. const id = e.target.getExtData().id
  109. const position = e.target.getPosition()
  110. const item = {
  111. id: id,
  112. position: {
  113. lng: position.lng,
  114. lat: position.lat
  115. }
  116. }
  117. this.getMarkerInfoWrapper(item)
  118. }
  119. },
  120. /* 海量点 */
  121. massMarks: null,
  122. amapManager,
  123. mapEvents: {
  124. init: this.mapInit,
  125. zoomchange: this.zoomchange
  126. },
  127. /* 弹框数据 */
  128. showMarkerDialog: false,
  129. markerInfo: {
  130. itemId: null,
  131. sku: null,
  132. replyId: null,
  133. replyContent: null,
  134. appendContent: null,
  135. photoUrl: null
  136. },
  137. earthPoint: {
  138. lat: null,
  139. lng: null
  140. },
  141. selectedOption: 1,
  142. selectOptions: [
  143. { name: '全部', value: 1 }
  144. ],
  145. value: []
  146. }
  147. },
  148. created() {
  149. document.title = '地图'
  150. this.getItems()
  151. },
  152. methods: {
  153. getItems() {
  154. getGeoItems().then(resp => {
  155. if (resp.code === 0) {
  156. this.selectOptions = resp.data
  157. }
  158. })
  159. },
  160. mapInit(o) {
  161. this.amap = o
  162. lazyAMapApiLoaderInstance.load().then(() => {
  163. // 图标样式
  164. var styleObject = {
  165. url: '//webapi.amap.com/theme/v1.3/markers/n/mark_b.png', // 图标地址
  166. size: new AMap.Size(11, 11), // 图标大小
  167. anchor: new AMap.Pixel(5, 5) // 图标显示位置偏移量,基准点为图标左上角
  168. }
  169. // 海量点样式
  170. const massMarks = new AMap.MassMarks([], {
  171. zIndex: 5, // 海量点图层叠加的顺序
  172. zooms: [3, 10], // 在指定地图缩放级别范围内展示海量点图层
  173. style: styleObject // 设置样式对象
  174. })
  175. // 将海量标点添加至地图实例
  176. massMarks.setMap(o)
  177. // 添加点击事件
  178. massMarks.on('click', (e) => {
  179. console.log('massMark 点击事件')
  180. })
  181. this.massMarks = massMarks
  182. // this.getMapMarkersWrapper(this.selectedOption)
  183. // this.getMapMarkersWrapper1(type)
  184. })
  185. },
  186. zoomchange(e) {
  187. console.log('当前缩放级别: ' + this.amap.getZoom())
  188. },
  189. getMapMarkersWrapper(type) {
  190. this.markers = []
  191. getMapMarkers(type).then(res => {
  192. if (res.code === 0) {
  193. this.$notify({
  194. message: '加载了 ' + res.data.length + ' 条数据',
  195. type: 'warning',
  196. duration: 5000
  197. })
  198. for (const item of res.data) {
  199. this.markers.push({
  200. position: [item.position.lng, item.position.lat],
  201. label: { content: item.title, offset: [0, 0] },
  202. extData: { id: item.id }
  203. })
  204. }
  205. } else {
  206. this.$notify({
  207. message: res.msg,
  208. type: 'warning',
  209. duration: 3000
  210. })
  211. }
  212. }).catch(error => {
  213. this.$notify({
  214. message: error.message,
  215. type: 'warning',
  216. duration: 3000
  217. })
  218. })
  219. },
  220. // 渲染海量点
  221. getMapMarkersWrapper1(type) {
  222. this.massMarks.setData([])
  223. getMapMarkers(type).then(res => {
  224. if (res.code === 0) {
  225. this.$notify({
  226. message: '加载了 ' + res.data.length + ' 条数据',
  227. type: 'warning',
  228. duration: 5000
  229. })
  230. const massMarkers = []
  231. for (const item of res.data) {
  232. massMarkers.push({
  233. lnglat: [item.position.lng, item.position.lat],
  234. id: item.id
  235. })
  236. }
  237. this.massMarks.setData(massMarkers)
  238. this.zoom = 5
  239. } else {
  240. this.$notify({
  241. message: res.msg,
  242. type: 'warning',
  243. duration: 3000
  244. })
  245. }
  246. }).catch(error => {
  247. this.$notify({
  248. message: error.message,
  249. type: 'warning',
  250. duration: 3000
  251. })
  252. })
  253. },
  254. getMarkerInfoWrapper(item) {
  255. this.earthPoint = item.position
  256. this.showMarkerDialog = true
  257. this.markerInfo = {
  258. itemId: null,
  259. sku: null,
  260. replyId: null,
  261. replyContent: null,
  262. appendContent: null,
  263. photoUrl: null
  264. }
  265. getMarkerInfo(item.id).then(res => {
  266. if (res.code === 0) {
  267. this.markerInfo = res.data
  268. } else {
  269. this.showMarkerDialog = false
  270. }
  271. }).catch(error => {
  272. this.showMarkerDialog = false
  273. console.log(error)
  274. })
  275. },
  276. /* 弹出框 */
  277. handleDialogClose(done) {
  278. this.showMarkerDialog = false
  279. this.earthPoint = { lat: null, lng: null }
  280. done()
  281. },
  282. onCopy(e) {
  283. this.$notify({
  284. message: 'GoogleEarth 坐标已复制, 快到 GoogleEarth 中去找这个地方吧~',
  285. type: 'warning',
  286. duration: 3000
  287. })
  288. },
  289. onCopyError(e) {
  290. this.$notify({
  291. message: '复制 GoogleEarth 坐标失败!',
  292. type: 'error',
  293. duration: 3000
  294. })
  295. },
  296. onChange() {
  297. this.getMapMarkersWrapper(this.selectedOption)
  298. }
  299. }
  300. }
  301. </script>
  302. <style>
  303. .amap-wrapper {
  304. width: 100%;
  305. height: 600px;
  306. }
  307. .movie-list {
  308. padding-top: 15px;
  309. padding-left: 3%;
  310. padding-right: 3%;
  311. }
  312. </style>