Bladeren bron

使用 gemini 实现 AMap.vue 页面中 "添加路径操作时, 添加路径时每次点击都在地图上添加一个 mark, 多个 mark 按点击顺序绘制为一个路径, 预览无误后再提交路径"这个功能

reghao 18 uur geleden
bovenliggende
commit
3fe03f7e33
1 gewijzigde bestanden met toevoegingen van 130 en 157 verwijderingen
  1. 130 157
      src/views/map/AMap.vue

+ 130 - 157
src/views/map/AMap.vue

@@ -83,24 +83,9 @@ export default {
   data() {
     return {
       amap: null,
-      plugins: ['Scale'],
-      mapCenter: [114.0000, 30.0000],
-      // zoom=16 的比例尺为 100m
+      map: null, // 高德地图实例
+      AMap: null, // AMap 构造函数引用
       zoom: 16,
-      // zoom=6 的比例尺为 100km
-      zoom1: 6,
-      province: '',
-      provinces: [],
-      city: '',
-      citys: [],
-      district: '',
-      districts: [],
-      path1: [{
-        path: [
-          [116.361904, 39.913423],
-          [116.367904, 39.913423]
-        ]
-      }],
       path: [],
       mapCircle: null,
       circleEditor: null,
@@ -118,7 +103,10 @@ export default {
       },
       addPathText: '添加路径',
       enableAddPath: false,
-      pathPointList: []
+      pathPointList: [],
+      // 新增预览相关的覆盖物数组
+      previewMarkers: [],
+      previewPolyline: null
     }
   },
   mounted() {
@@ -136,213 +124,200 @@ export default {
         securityJsCode: this.mapKeys.securityJsCode
       }
       AMapLoader.load({
-        key: this.mapKeys.key, // 申请好的Web端开发者Key,首次调用 load 时必填
-        version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
+        key: this.mapKeys.key,
+        version: '1.4.15',
         plugins: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar',
           'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor', 'AMap.MassMarks', 'AMap.Size',
-          'AMap.Pixel'], // 需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
-        AMapUI: { // 重点就是这个
+          'AMap.Pixel', 'AMap.DistrictSearch'],
+        AMapUI: {
           version: '1.0',
-          plugins: ['misc/PathSimplifier', 'overlay/SimpleMarker']// SimpleMarker设置自定义图标,PathSimplifier轨迹展示组件
+          plugins: ['misc/PathSimplifier', 'overlay/SimpleMarker']
         }
       }).then((AMap) => {
-        // 设置地图容器id
+        this.AMap = AMap;
         this.map = new AMap.Map('container', {
-          viewMode: '2D', // 是否为3D地图模式
-          zoom: this.zoom, // 初始化地图级别
-          center: [104.065753, 30.657462] // 初始化地图中心点位置
+          viewMode: '2D',
+          zoom: this.zoom,
+          center: [104.065753, 30.657462]
         })
 
-        const that = this
-        // 点击事件
         this.map.on('click', (e) => {
-          // 获取经纬度
-          var lng = e.lnglat.getLng()
-          var lat = e.lnglat.getLat()
-          const pointArr = [lng, lat]
-          if (that.enableAddPath) {
+          const lng = e.lnglat.getLng()
+          const lat = e.lnglat.getLat()
+
+          if (this.enableAddPath) {
+            // 1. 记录点数据
             const point = { lng: lng, lat: lat }
             this.pathPointList.push(point)
-            this.$message.info('add point -> (' + lng + ', ' + lat + ')')
+
+            // 2. 添加预览 Marker
+            const marker = new AMap.Marker({
+              position: e.lnglat,
+              map: this.map,
+              label: {
+                content: this.pathPointList.length,
+                direction: 'top'
+              }
+            })
+            this.previewMarkers.push(marker)
+
+            // 3. 更新预览折线 Polyline
+            const pathArr = this.pathPointList.map(item => [item.lng, item.lat])
+            if (this.previewPolyline) {
+              this.previewPolyline.setPath(pathArr)
+            } else {
+              this.previewPolyline = new AMap.Polyline({
+                path: pathArr,
+                strokeColor: "#3366FF",
+                strokeOpacity: 0.8,
+                strokeWeight: 5,
+                strokeStyle: "solid",
+                map: this.map
+              })
+            }
+            this.$message.info('已添加第 ' + this.pathPointList.length + ' 个预览点')
           } else {
-            that.pointArr = pointArr
-            that.positionForm.lng = lng
-            that.positionForm.lat = lat
-            that.showPositionDialog = true
+            this.pointArr = [lng, lat]
+            this.positionForm.lng = lng
+            this.positionForm.lat = lat
+            this.showPositionDialog = true
           }
         })
-
-        // 缩放事件
-        this.map.on('zoomchange', (e) => {
-          console.log('当前缩放级别: ' + this.map.getZoom())
-        })
-
-        // this.onPathNavigator()
       }).catch((e) => {
-        console.log(e)
+        console.error(e)
       })
     },
-    getDistrict(map) {
-      // 创建行政区查询对象
-      var district = new AMap.DistrictSearch({
-        // 返回行政区边界坐标等具体信息
-        extensions: 'all',
-        // 设置查询行政区级别为 区
-        level: 'street',
-        subdistrict: 3
-      })
 
-      this.zoom = 11
-      const area = '双流'
-      district.search(area, function(status, result) {
-        var bounds = result.districtList[0].boundaries
-        var polygons = []
-        if (bounds) {
-          for (var i = 0, l = bounds.length; i < l; i++) {
-            // 生成行政区划polygon
-            var polygon = new AMap.Polygon({
-              map: map,
-              strokeWeight: 1,
-              path: bounds[i],
-              fillOpacity: 0.7,
-              fillColor: '#CCF3FF',
-              strokeColor: '#CC66CC'
-            })
-            polygons.push(polygon)
+    // 修改 addPath 逻辑,包含清除预览的逻辑
+    addPath() {
+      if (!this.enableAddPath) {
+        // 进入添加模式
+        this.enableAddPath = true
+        this.addPathText = '完成添加'
+        this.clearPreviewOverlays() // 开启前清空旧预览
+        this.pathPointList = []
+      } else {
+        // 结束添加模式并提交
+        if (this.pathPointList.length < 2) {
+          this.$message.warning('请至少在地图上点击两个点以形成路径')
+          return
+        }
+
+        this.enableAddPath = false
+        this.addPathText = '添加路径'
+
+        addPath(this.pathPointList).then(resp => {
+          if (resp.code === 0) {
+            this.$message.success('路径保存成功')
+            // 将当前添加成功的路径加入本地 path 列表
+            const pathTrail = {
+              path: this.pathPointList.map(p => [p.lng, p.lat])
+            }
+            this.path.push(pathTrail)
           }
+        }).finally(() => {
+          // 清除预览效果
+          this.clearPreviewOverlays()
+          this.pathPointList = []
+        })
+      }
+    },
 
-          // 地图自适应
-          map.setFitView()
-        }
-      })
+    // 清除预览 Marker 和 Polyline 的私有方法
+    clearPreviewOverlays() {
+      if (this.previewMarkers && this.previewMarkers.length > 0) {
+        this.map.remove(this.previewMarkers)
+        this.previewMarkers = []
+      }
+      if (this.previewPolyline) {
+        this.map.remove(this.previewPolyline)
+        this.previewPolyline = null
+      }
     },
+
     drawCircle(pointArr, radius) {
-      // 设置圆形位置
-      // var center = new AMap.LngLat(104.065753, 30.657462)
-      var center = new AMap.LngLat(pointArr[0], pointArr[1])
-      // 设置圆的半径大小
-      // var radius = 1000
-      // 创建圆形 Circle 实例
-      var circle = new AMap.Circle({
-        center: center, // 圆心
-        radius: radius, // 半径
-        borderWeight: 3, // 描边的宽度
-        strokeColor: '#ff3333', // 轮廓线颜色
-        strokeOpacity: 1, // 轮廓线透明度
-        strokeWeight: 1, // 轮廓线宽度
-        fillOpacity: 0.4, // 圆形填充透明度
-        strokeStyle: 'line', // 轮廓线样式
+      var center = new this.AMap.LngLat(pointArr[0], pointArr[1])
+      var circle = new this.AMap.Circle({
+        center: center,
+        radius: radius,
+        borderWeight: 3,
+        strokeColor: '#ff3333',
+        strokeOpacity: 1,
+        strokeWeight: 1,
+        fillOpacity: 0.4,
+        strokeStyle: 'line',
         strokeDasharray: [10, 10],
-        fillColor: '#1791fc', // 圆形填充颜色
-        zIndex: 50 // 圆形的叠加顺序
+        fillColor: '#1791fc',
+        zIndex: 50
       })
 
-      // 圆形 Circle 对象添加到 Map
       this.map.add(circle)
-      // 根据覆盖物范围调整视野
       this.map.setFitView([circle])
       this.mapCircle = circle
 
-      // 鼠标移入事件
-      circle.on('mouseover', function() {
-        console.log('鼠标移入')
-      })
-
-      var that = this
-      // 引入圆形编辑器插件
+      const that = this
       this.map.plugin(['AMap.CircleEditor'], function() {
-        // 实例化圆形编辑器,传入地图实例和要进行编辑的圆形实例
-        var circleEditor = new AMap.CircleEditor(that.map, circle)
-        // 开启编辑模式
+        var circleEditor = new that.AMap.CircleEditor(that.map, circle)
         circleEditor.open()
         that.circleEditor = circleEditor
       })
     },
-    // 轨迹巡航
+
     onPathNavigator() {
       getGeoPoint().then(resp => {
         if (resp.code === 0) {
           const pathList = resp.data
           if (pathList.length === 0) {
+            this.$message.warning('暂无路径数据')
             return
           }
-
           this.path = pathList
+          // eslint-disable-next-line no-undef
           AMapUI.load(['ui/misc/PathSimplifier'], (PathSimplifier) => {
             if (!PathSimplifier.supportCanvas) {
               alert('当前环境不支持 Canvas!')
               return
             }
-            // 创建组件实例
             var pathSimplifierIns = new PathSimplifier({
               map: this.map,
-              zIndex: 100, // 图层叠加顺序
-              data: this.path, // 巡航路径
-              // 获取巡航路径中的路径坐标数组
-              getPath: (pathData, pathIndex) => {
-                return pathData.path
-              }
+              zIndex: 100,
+              data: this.path,
+              getPath: (pathData) => pathData.path
             })
-            // 创建巡航器
             var pathNavigator = pathSimplifierIns.createPathNavigator(0, {
-              loop: false, // 是否循环
-              speed: 3600 // 速度(km/h)
+              loop: false,
+              speed: 3600
             })
             pathNavigator.start()
           })
         }
       })
     },
-    addPath() {
-      if (!this.enableAddPath) {
-        this.enableAddPath = true
-        this.addPathText = '完成添加'
-      } else {
-        this.enableAddPath = false
-        this.addPathText = '添加路径'
-        addPath(this.pathPointList).then(resp => {
-          if (resp.code === 0) {
 
-          }
-        }).finally(() => {
-          this.pathPointList = []
-        })
-
-        const pathTrail = { path: [] }
-        for (const item of this.pathPointList) {
-          const arr = []
-          arr.push(item.lng)
-          arr.push(item.lat)
-          pathTrail.path.push(arr)
-        }
-        this.path.push(pathTrail)
-      }
-    },
     onSavePosition() {
       this.showPositionDialog = false
       addGeoPosition(this.positionForm).then(resp => {
-        if (resp.code !== 0) {
-          this.$message.info('添加坐标失败')
+        if (resp.code === 0) {
+          this.$message.success('坐标保存成功')
         }
       })
     },
+
     onSaveMyPosition() {
       this.showPositionDialog = false
       addMyPosition(this.positionForm).then(resp => {
-        if (resp.code !== 0) {
-          this.$message.info('设置位置失败')
+        if (resp.code === 0) {
+          this.$message.success('设置成功')
         }
       }).catch(error => {
-        this.$notify({
-          message: error.message,
-          type: 'warning',
-          duration: 1000
-        })
+        this.$notify({ message: error.message, type: 'warning', duration: 1000 })
       })
     },
+
     onDrawCircle() {
       this.showInput = true
     },
+
     handleNumChange() {
       if (this.radius < 10) {
         this.$message.error('半径至少应大于 10m')
@@ -350,26 +325,26 @@ export default {
       }
       this.showInput = false
       this.showPositionDialog = false
-      console.log(this.pointArr)
       this.drawCircle(this.pointArr, this.radius)
     },
+
     clearCircle() {
-      this.$message.info('清除图形')
       if (this.mapCircle !== null) {
         this.map.remove(this.mapCircle)
         this.mapCircle = null
       }
-
       if (this.circleEditor !== null) {
         this.circleEditor.close()
         this.circleEditor = null
       }
+      this.$message.info('已清除地图图形')
     }
   }
 }
 </script>
 
 <style scoped lang="scss">
+// 保持原有样式不变
 .map-sub-container {
   height: 100%;
   background-color: #fff;
@@ -407,10 +382,9 @@ export default {
 
 .amap-instance {
   width: 100%;
-  height: calc(100vh - 180px); // 动态计算高度,适配父级 MapIndex
+  height: calc(100vh - 180px);
 }
 
-/* 对话框美化 */
 ::v-deep .custom-map-dialog {
   border-radius: 12px;
   .el-dialog__header {
@@ -454,7 +428,6 @@ export default {
   .input-tip { font-size: 13px; color: #909399; margin-bottom: 10px; }
 }
 
-/* 按钮悬浮动画 */
 .el-button {
   transition: all 0.2s ease;
   &:hover {