首页地图功能分析

首页地图功能分析

一、地图组件结构

1.1 组件层级关系

复制代码
homepage.vue (首页)
├── Map3DVisual.vue (三维地图)
├── Map2DVisual.vue (二维地图)
└── mapVisualUtils.js (地图工具函数)

1.2 地图版本切换

根据环境变量 VUE_APP_VERSION_MAP 决定使用二维还是三维地图:

vue 复制代码
<!-- homepage.vue -->
<template>
  <div v-if="regionLevel === 1" class="onemap-box">
    <!-- 三维地图 -->
    <map3-d-visual v-if="versionMap === '3d'" :url="config3DUrl" @onload="onMap3DLoad" />
    <!-- 二维地图 -->
    <map2-d-visual v-else :url="config2DUrl" @onload="onMap2DLoad" />
  </div>
</template>

1.3 .env 环境变量配置

ini 复制代码
# .env 文件配置

# 系统内外网版本标识
# intranet : 内网版本
# internet :外网版本
VUE_APP_VERSION_STATE='internet'

# 使用的地图
# 2d 二维
# 3d 三维
VUE_APP_VERSION_MAP='3d'

配置说明:

环境变量 说明
VUE_APP_VERSION_STATE 'internet''intranet' 内外网版本标识,内网使用自定义底图服务
VUE_APP_VERSION_MAP '2d''3d' 地图类型选择,二维或三维

配置生效方式:

javascript 复制代码
// homepage.vue - data
versionMap: process.env.VUE_APP_VERSION_MAP,  // 读取环境变量

通过 process.env.VUE_APP_VERSION_MAP 读取环境变量,决定渲染三维地图组件还是二维地图组件。


二、地图加载流程

2.1 配置文件加载

javascript 复制代码
// homepage.vue - data
versionMap: process.env.VUE_APP_VERSION_MAP,  // '2d' 或 '3d'
config3DUrl: basePathUrl + 'config/map3dVisualConfig.json',
config2DUrl: basePathUrl + 'config/map2dVisualConfig.json',

2.2 三维地图加载回调

javascript 复制代码
// homepage.vue - onMap3DLoad
onMap3DLoad({ map }) {
  // 1. 添加矢量图层
  const graphicLayer = addLayer(map);
  // 2. 添加边界信息(GeoJson)
  addBoundaryInfo(map);
  // 3. 添加周边圆圈刻度尺
  addOutCircle(graphicLayer);
  // 4. 异步加载统计点数据
  this.getMapData().then((cityDatas) => {
    if (cityDatas.length < 1) {
      addCenterPoint(map, cityData, CENTER_LAYER);
    } else {
      addCenterPoint(map, cityDatas, CENTER_LAYER);
    }
  });
}

2.3 二维地图加载回调

javascript 复制代码
// homepage.vue - onMap2DLoad
onMap2DLoad({ map }) {
  // 1. 添加边界信息
  add2dBoundaryInfo(map);
  // 2. 异步加载统计点数据
  this.getMapData().then((cityDatas) => {
    if (cityDatas.length < 1) {
      add2dCenterPoint(map, cityData, CENTER_LAYER);
    } else {
      add2dCenterPoint(map, cityDatas, CENTER_LAYER);
    }
  });
}

三、点的渲染实现

3.1 三维地图统计点渲染

javascript 复制代码
// mapVisualUtils.js - addCenterPoint
export function addCenterPoint(mapInstance, items = [], layerId) {
  // 获取或创建图层
  let graphicLayer = mapInstance.getLayer(layerId, 'id');
  if (graphicLayer) {
    graphicLayer.clear();
  } else {
    graphicLayer = new mars3d.layer.GraphicLayer({ id: layerId });
    mapInstance.addLayer(graphicLayer);
  }

  items.forEach((item) => {
    const graphic = new mars3d.graphic.DivGraphic({
      position: [item.lon, item.lat],  // 经纬度
      style: {
        html: `<div class='marsBlackPanel animation-spaceInDown'>
                <div class='marsBlackPanel-text'>
                  <div>${item.adnm}</div>           <!-- 行政区名称 -->
                  <div>采矿权:${item.ckq}</div>   <!-- 采矿权数量 -->
                  <div>探矿权:${item.tkq}</div>   <!-- 探矿权数量 -->
                </div>
              </div>`,
        horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
        clampToGround: true,
        // 距离显示条件:0-2000000米范围内可见
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 2000000)
      }
    });
    graphicLayer.addGraphic(graphic);
  });
}

3.2 二维地图统计点渲染

javascript 复制代码
// mapVisualUtils.js - add2dCenterPoint
export function add2dCenterPoint(mapInstance, items = [], layerId) {
  let graphicLayer = mapInstance.getLayer(layerId, 'id');
  if (graphicLayer) {
    graphicLayer.clear();
  } else {
    graphicLayer = new mars2d.layer.GraphicLayer({ id: layerId });
    mapInstance.addLayer(graphicLayer);
  }

  items.forEach((item) => {
    const graphic = new mars2d.graphic.DivGraphic({
      latlng: [item.lat, item.lon],
      style: {
        html: `<div class='marsBlackPanel animation-spaceInDown'>
                <div class='marsBlackPanel-text'>
                  <div>${item.adnm}</div>
                  <div>采矿权:${item.ckq}</div>
                  <div>探矿权:${item.tkq}</div>
                </div>
              </div>`
      }
    });
    graphicLayer.addGraphic(graphic);
  });
}

3.3 数据格式

统计点数据结构:

字段 类型 说明
lon Number 经度
lat Number 纬度
adnm String 行政区名称
ckq Number 采矿权数量
tkq Number 探矿权数量

四、地图初始化组件

4.1 三维地图组件(Map3DVisual.vue)

javascript 复制代码
// 核心初始化逻辑
initialMap(options) {
  // 创建三维地球场景
  const map = new mars3d.Map(`mapContainer3d`, options);
  map.unbindContextMenu();

  // 开启动画飞行后触发回调
  map.openFlyAnimation({ duration1: 5 }).then(() => {
    this.$emit('onload', { map });
  });
}

4.2 二维地图组件(Map2DVisual.vue)

javascript 复制代码
// 核心初始化逻辑
initialMap(mapOptions) {
  if (this[`map${this.mapKey}`]) {
    return;  // 防止重复初始化
  }

  const map = new mars2d.Map(`mapContainer2d${this.mapKey}`, mapOptions);
  this[`map${this.mapKey}`] = map;

  // 抛出事件
  this.$emit('onload', { map });
}

五、边界信息加载

5.1 三维边界加载

javascript 复制代码
// mapVisualUtils.js - addBoundaryInfo
export function addBoundaryInfo(mapInstance) {
  const diffHeight = 2000;
  
  const shiLayer = new mars3d.layer.GeoJsonLayer({
    name: '河北各市边界线',
    url: './data/130000_full.json',
    symbol: {
      type: 'polyline',
      styleOptions: {
        materialType: mars3d.MaterialType.PolyGradient,
        color: 'rgba(77, 190, 192)',
        setHeight: diffHeight,
        width: 3
      },
      styleField: 'name',
      callback: function (attr, styleOpt) {
        const randomHeight = (attr.childrenNum || 1) * 750;
        return {
          materialOptions: { color: 'rgba(77, 190, 192)' },
          height: 0,
          diffHeight: randomHeight
        };
      }
    }
  });
  mapInstance.addLayer(shiLayer);
}

5.2 二维边界加载

javascript 复制代码
// mapVisualUtils.js - add2dBoundaryInfo
export function add2dBoundaryInfo(mapInstance) {
  const boundLayer = new mars2d.layer.GeoJsonLayer({
    name: '河北各市边界线',
    url: './data/130000_full.json',
    symbol: {
      styleOptions: {
        fill: true,
        fillColor: '#C0C0C0',
        fillOpacity: 0.6,
        outline: true,
        outlineColor: '#6495ED',
        outlineWidth: 20,
        outlineOpacity: 0.5
      }
    }
  });
  mapInstance.addLayer(boundLayer);
}

六、数据获取流程

javascript 复制代码
// homepage.vue - getMapData
async getMapData() {
  let mapdata = await this.$store.dispatch('getMapData', { nd: this.year });
  if (mapdata.code === 200) {
    return mapdata.data.data;
  } else {
    return [];
  }
}

数据来源:通过 Vuex store 派发 getMapData 动作,根据年度参数获取统计数据。


七、核心技术要点

要点 说明
地图库 Mars3D/Mars2D (基于 Cesium/Leaflet)
事件机制 地图初始化完成后通过 $emit('onload') 通知父组件
图层管理 使用 GraphicLayer 管理动态渲染内容
DOM绑定 DivGraphic 允许自定义HTML内容作为地图标注
性能优化 distanceDisplayCondition 控制远距离时隐藏标注
内外网适配 通过 VUE_APP_VERSION_STATE 判断,内网使用自定义底图服务

八、文件路径汇总

文件 路径
首页组件 src/views/homepage/homepage.vue
三维地图组件 src/components/map3d/Map3DVisual.vue
二维地图组件 src/components/map2d/Map2DVisual.vue
地图工具函数 src/lib/mapVisualUtils.js
三维配置文件 config/map3dVisualConfig.json
二维配置文件 config/map2dVisualConfig.json
相关推荐
Lhappy嘻嘻4 小时前
Java IO|File 文件操作 + 字节流 / 字符流完整笔记 + 递归删除文件实战
java·笔记·php
伊玛目的门徒4 小时前
试用leetcode之典中典 二数之和问题
java·算法·leetcode
懒鸟一枚7 小时前
深入理解 Linux 内存、Swap 交换分区与分页机制的关系
java·linux·数据库
我命由我123459 小时前
执行 Gradle 指令报错,无法将“grep”项识别为 cmdlet、函数、脚本文件或可运行程序的名称
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
考虑考虑9 小时前
Sentinel安装
java·后端·微服务
凤凰院凶涛QAQ10 小时前
《Java版数据结构 & 集合类剖析》栈与队列:“push/pop 是栈的灵魂,offer/poll 是队列的骨架——四组 API,两种人生”
java·开发语言·数据结构
掘金_答案11 小时前
上线那天,一个 ConcurrentHashMap 差点送走我的 AI 客服——3 天排查 JVM 血泪史
java·后端·架构
猿与禅12 小时前
CosId 分布式 ID 生成器完全教程:从架构原理到生产落地
java·shardingsphere·雪花算法·分布式id·高性能·cosid·号段模式
MindUp12 小时前
企业网盘权限模型解析:多层级访问控制与审计能力选型指南
java·linux·运维
NG47712 小时前
【软件设计与体系结构】-策略设计模式
java·设计模式·软件工程