地图上图、空间拓扑查询示例

一、点击左侧矿山树节点功能

1.1 功能概述

点击左侧树形结构中的矿山节点时,地图会执行以下操作:

  • 地图定位到该矿山位置
  • 显示矿山详情面板

1.2 事件处理

javascript 复制代码
// src/views/oneMap/index.vue - handleDetailOpenClick
handleDetailOpenClick(xkzh) {
  // 1. 显示详情面板,隐藏其他面板
  this.isShowDetail = true;
  this.isShowComputeBox = false;
  this.isShowDiscardedBox = false;
  this.isShowNearbyMinesBox = false;
  
  // 2. 隐藏返回上级按钮(非计算结果进入)
  this.$refs.detailBoxRef.isShowTheBackTitle = '';
  
  this.$nextTick(() => {
    // 3. 地图定位到该矿山
    if (this.versionMap === D3) {
      flyToGraphic(this.map3dInstance, xkzh, MINE_LAYER);
      flyToGraphic(this.map3dInstance, xkzh, 'scksPointLayer');
    } else {
      flyToGraphic2d(this.map2dInstance, xkzh, MINE_LAYER);
    }
    
    // 4. 加载并显示详情
    this.$refs.detailBoxRef.bindDetailInfo(xkzh);
  });
}

1.3 地图定位方法

三维地图:

javascript 复制代码
// src/lib/map3dUtils.js - flyToGraphic
export function flyToGraphic(mapInstance, graphicId, layerId) {
  const layer = mapInstance.getLayer(layerId, 'id');
  if (layer) {
    const graphic = layer.getGraphicById(graphicId);
    if (graphic) {
      // 飞行动画
      graphic.flyTo({
        radius: 5000,   // 距离目标点 5000 米
        duration: 2     // 飞行时间 2 秒
      });
    }
  }
}

二维地图:

javascript 复制代码
// src/lib/map2dUtils.js - flyToGraphic2d
export function flyToGraphic2d(mapInstance, graphicId, layerId) {
  const layer = mapInstance.getLayer(layerId, 'id');
  if (layer) {
    const graphic = layer.getGraphicById(graphicId);
    if (graphic) {
      mapInstance.flyToBounds(graphic.getBounds(), { padding: [50, 50] });
    }
  }
}

1.4 数据流向

复制代码
用户点击树节点
    ↓
触发 handleDetailOpenClick(xkzh)
    ↓
调用 flyToGraphic() 定位地图
    ↓
调用 bindDetailInfo(xkzh) 加载详情
    ↓
显示右侧详情面板

二、上图功能(SHP文件/文本坐标/手绘图形)

2.1 功能概述

上图功能支持三种方式在地图上添加自定义图形:

  • SHP 文件上传
  • 文本坐标输入(点/面)
  • 手绘图形

2.2 界面结构

vue 复制代码
<!-- src/views/oneMap/index.vue -->
<div :class="{ 'above-active': aboveShow }" class="above" @click.stop="changeAbovePanel">
  <div class="icon"></div>
  <div class="label">上 图</div>
  <div v-if="aboveShow" class="search-panel">
    <!-- 标签切换 -->
    <div class="above-type-warp">
      <div :class="{ 'tab-item-active': activeTab === '1' }" @click="tabChange('1')">shp文件</div>
      <div :class="{ 'tab-item-active': activeTab === '2' }" @click="tabChange('2')">文本坐标</div>
      <div :class="{ 'tab-item-active': activeTab === '3' }" @click="tabChange('3')">手绘图形</div>
    </div>
    <!-- 操作区域 -->
    <div class="operation-box">
      <!-- 根据 activeTab 显示不同内容 -->
    </div>
  </div>
</div>

2.3 SHP 文件上图

上传处理:

javascript 复制代码
// src/views/oneMap/index.vue - determineAbove (activeTab === '1')
if (this.activeTab === '1') {
  let formData = new FormData();
  formData.append('shpFile', this.file[0]);
  
  // 调用后端解析 SHP 文件
  this.$store.dispatch('getShpAnalysis', formData).then((result) => {
    if (result.data.code === 200) {
      const data = result.data.data.shpDataList;
      let list = [];
      
      data.forEach((el) => {
        // 保存原始坐标用于后续计算
        this.calculationData.coordinates.push(el.coordinates);
        
        // 解析 WKT 坐标
        list.push({
          ...el,
          coordinates: WKT.parse(el.coordinates)
        });
      });
      
      // 在地图上绘制
      this.addSubjectPolygon(list);
    } else {
      this.$message.error(result.data.msg);
    }
  });
}

2.4 文本坐标上图

坐标类型切换:

vue 复制代码
<!-- 点/面切换 -->
<el-radio-group v-model="coordinatesType" @change="chengeType">
  <el-radio :label="1" style="color: #fff">点</el-radio>
  <el-radio :label="3" style="color: #fff">面</el-radio>
</el-radio-group>

点坐标输入:

javascript 复制代码
// 点坐标参数
const params = {
  type: 1,                    // 1-点,3-面
  x: this.coordinates.x,      // 经度
  y: this.coordinates.y,      // 纬度
  polygon: null
};

面坐标输入:

javascript 复制代码
// 面坐标参数
const params = {
  type: 3,
  x: null,
  y: null,
  polygon: this.coordinates.surface.replaceAll(' ', '\n')  // WKT 格式
};

支持的坐标格式:

格式类型 示例
十进制经纬度 114.955719,38.237663
度分秒格式 114°57′20.00″,38°14′15.00″
投影坐标 4226415.03,38583328.63

坐标解析:

javascript 复制代码
// src/views/oneMap/index.vue - determineAbove (else 分支)
const params = {
  type: this.coordinatesType,
  x: this.coordinates.x ?? null,
  y: this.coordinates.y ?? null,
  polygon: this.coordinates.surface?.replaceAll(' ', '\n') ?? null
};

this.$store.dispatch('getCoordAnalysis', params).then((result) => {
  if (result.data.code === 200) {
    const data = result.data.data;
    data.forEach((el) => {
      this.calculationData.coordinates.push(el.coordinates);
      list.push({
        ...el,
        coordinates: WKT.parse(el.coordinates)
      });
    });
    this.addSubjectPolygon(list);
  }
});

2.5 手绘图形上图

javascript 复制代码
// src/views/oneMap/index.vue - handlePlotPolygon
handlePlotPolygon(clampToGround = false) {
  if (this.versionMap === D3) {
    const drawLayer = this.map3dInstance.getLayerById(DRAW_LAYER);
    if (drawLayer) {
      drawLayer.startDraw({
        type: 'polygon',
        style: {
          color: clampToGround ? '#0ab8f1' : '#f00',
          opacity: 0.5,
          outline: true,
          outlineColor: '#ffffff',
          outlineWidth: 2.0,
          clampToGround: clampToGround
        }
      }).then((graphic) => {
        // 获取绘制的多边形坐标
        const polygon = graphic.outlinePositions;
        let jkList = [];
        let str = '';
        
        polygon.forEach((item) => {
          // 坐标转换:Cartesian3 -> LngLatPoint
          const a = mars3d.LngLatPoint.fromCartesian(
            new Cesium.Cartesian3(item.x, item.y, item.z)
          );
          jkList.push(a);
        });
        
        // 拼接成 WKT 格式字符串
        jkList.forEach((ls) => {
          str += ls.lng + ' ' + ls.lat + ',';
        });
        
        // 保存坐标用于计算
        this.calculationData.coordinates.push(str);
      });
    }
  } else {
    // 二维地图绘制
    const drawLayer = this.map2dInstance.getLayerById(DRAW_LAYER);
    if (drawLayer) {
      drawLayer.startDraw({
        type: 'polygon',
        style: {
          fill: true,
          fillColor: '#f00',
          fillOpacity: 0.2,
          outlineColor: '#ffffff',
          outline: true,
          outlineWidth: 2.0
        }
      });
    }
  }
}

2.6 在地图上绘制图形

javascript 复制代码
// src/views/oneMap/index.vue - addSubjectPolygon
addSubjectPolygon(list) {
  if (this.versionMap === D3) {
    add3DSubjectPolygon(this.map3dInstance, list, ABOVE_MINE_BOUND_LAYER);
  } else {
    add2DSubjectPolygon(this.map2dInstance, list, ABOVE_MINE_BOUND_LAYER);
  }
}

2.7 上图流程图

复制代码
用户点击"上图"按钮
    ↓
选择上图方式(SHP/坐标/手绘)
    ↓
├── SHP文件 → 上传文件 → getShpAnalysis → 解析坐标 → addSubjectPolygon
├── 文本坐标 → 输入坐标 → getCoordAnalysis → 解析坐标 → addSubjectPolygon
└── 手绘图形 → 绘制多边形 → 获取坐标 → 保存到 calculationData

三、计算压覆矿权功能

3.1 功能概述

根据上图的区域范围,计算该范围内包含的所有矿权信息,并展示计算结果。

3.2 计算方法

javascript 复制代码
// src/views/oneMap/index.vue - calculation
calculation() {
  // 1. 设置计算类型
  if (this.activeTab !== '3') {
    this.calculationData.type = 1;  // 文件/坐标上传
  } else {
    this.calculationData.type = 2;  // 手绘图形
  }
  
  // 2. 验证是否有计算范围
  if (this.calculationData.coordinates.length === 0) {
    this.$message.error('没有地图范围');
    return;
  }
  
  // 3. 调用后端计算接口
  this.$store.dispatch('kqxxCalculate', this.calculationData).then((result) => {
    const data = result.data.data;
    
    // 4. 将结果传递给计算结果面板
    this.$refs.computeBoxRef.computeTableData = data;
    
    // 5. 显示计算结果面板
    this.isShowComputeBox = true;
    this.isShowDetail = false;
    this.isShowDiscardedBox = false;
    this.isShowNearbyMinesBox = false;
  });
}

3.3 计算数据结构

javascript 复制代码
// calculationData 结构
{
  type: 1,                    // 1-上传,2-手绘
  coordinates: [              // WKT 格式坐标数组
    "POLYGON((114.95 38.23, 114.96 38.23, ...))",
    "POINT(115.0 38.0)"
  ]
}

3.4 计算结果处理

计算结果面板显示:

javascript 复制代码
// 计算成功后
this.$refs.computeBoxRef.computeTableData = data;
this.isShowComputeBox = true;

点击结果行查看详情:

javascript 复制代码
// src/views/oneMap/index.vue - handleRowClick
handleRowClick(xkzh) {
  // 显示详情面板
  this.isShowDetail = true;
  this.isShowComputeBox = false;
  
  // 设置返回按钮文字
  this.$refs.detailBoxRef.isShowTheBackTitle = '返回压盖矿权计算结果';
  
  // 加载矿权详情
  this.$refs.detailBoxRef.bindDetailInfo(xkzh);
}

返回计算结果列表:

javascript 复制代码
// src/views/oneMap/index.vue - goBackCompat
goBackCompat() {
  this.isShowComputeBox = true;
  this.isShowDetail = false;
}

3.5 清除上图数据

javascript 复制代码
// src/views/oneMap/index.vue - clearAboveLayer
clearAboveLayer() {
  // 1. 清空坐标输入
  this.coordinates = { x: null, y: null, surface: null };
  
  // 2. 清空计算数据
  this.calculationData = { coordinates: [], type: null };
  
  // 3. 清空上传文件
  this.file = [];
  
  // 4. 清空地图图层
  if (this.versionMap === D3) {
    clearLayer(this.map3dInstance, ABOVE_MINE_BOUND_LAYER);
    this.map3dInstance.flyHome();  // 返回初始视角
    
    // 清除手绘图层
    const drawLayer = this.map3dInstance.getLayerById(DRAW_LAYER);
    drawLayer && drawLayer.clear();
  } else {
    clearLayer2d(this.map2dInstance, ABOVE_MINE_BOUND_LAYER);
    this.map2dInstance.flyHome();
    const drawLayer = this.map2dInstance.getLayerById(DRAW_LAYER);
    drawLayer && drawLayer.clear();
  }
  
  // 5. 清空表格数据
  this.$refs.computeBoxRef.computeTableData = [];
}

3.6 压覆矿权计算流程图

复制代码
用户点击"计算压覆矿权"按钮
    ↓
验证 calculationData.coordinates 是否为空
    ↓
调用 kqxxCalculate 接口
    ↓
后端执行空间查询(判断矿权是否在给定范围内)
    ↓
返回压覆的矿权列表
    ↓
显示计算结果面板(calculationDetailBox)
    ↓
├── 点击行 → handleRowClick → 显示矿权详情
│       ↓
│   点击"返回" → goBackCompat → 返回计算结果
│
└── 点击"重置" → clearAboveLayer → 清空所有数据

四、核心变量说明

变量名 类型 说明
activeTab String 当前上图方式:'1'-SHP,'2'-坐标,'3'-手绘
coordinatesType Number 坐标类型:1-点,3-面
coordinates Object 坐标输入值:{x, y, surface}
calculationData Object 计算数据:{type, coordinates}
file Array 上传的文件列表
aboveShow Boolean 上图面板显示状态
相关推荐
OxYGC18 分钟前
[AI工程] Spring AI 第十四篇:Agent 五种模式在 2.0 里怎么写
java·spring·ai·ai编程
code2cat18 分钟前
【随笔】从聊天到调用工具:理解MCP在AI应用中的位置
java·人工智能
2501_9339232527 分钟前
Spring Bean作用域揭秘:单例、原型、请求与会话的区别
java·后端·spring·java-ee
学编程就要猛44 分钟前
基于Spring AI 的智能聊天机器人
java·spring ai·chat robot
修炼室1 小时前
Java开发工程师笔试经验贴【高频知识】
java
木井巳1 小时前
【记忆化搜索】最长递增子序列
java·算法·leetcode·深度优先·剪枝·推荐算法
杨杨杨大侠1 小时前
知识库已经有了,Java 程序员还要做什么?Spring AI RAG 实战
java·openai·ai编程
伊信1 小时前
Spring AI 基础学习与应用
java·后端
夜郎king1 小时前
基于 Java + Playwright 实现网站自动访问与数据采集(以腾讯云开发者社区为例)
java·playwright·网页数据获取
Anastasiozzzz1 小时前
重新定义 Agent 基建:Redis 在现代 AI 与智能体系统中的工程实践
java·人工智能·redis·ai