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

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

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 上图面板显示状态
相关推荐
程序员黑豆1 小时前
AI全栈开发 - Java:变量
java·前端·ai编程
我是一颗柠檬1 小时前
【Java项目技术亮点】分库分表+数据路由策略:单表5000万后的架构升级方案
java·开发语言·分布式·架构
布朗克1682 小时前
25 IO流高级操作——序列化、NIO与Files工具类
java·数据库·io·nio
小研说技术2 小时前
Spring AI实现rag流程(简易版)
java·后端
亓才孓2 小时前
【本地项目引用外部库的类,想修改字段遇到的请缓存的问题】
java·maven
小林敲代码77882 小时前
记录一下IDEA中很多变量变色的方案
java·开发语言·spring boot·idea
南知意-2 小时前
IDEA 2026.1最新版安装教程
java·ide·intellij-idea·idea安装·idea激活
星子落怀aa2 小时前
Java 反复报错?Gemini助力修复
java
半夜修仙2 小时前
RabbitMQ中如何保证消息的可靠性传输
java·分布式·中间件·rabbitmq·github·java-rabbitmq