基于cesium和vue的大疆司空模仿程序

项目技术架构与模块详解

一、项目整体结构概览

本项目采用前后端分离架构,前端基于 Vue2 + Element Plus + Cesium 实现三维航线可视化与交互,后端基于 Flask 提供航线数据、文件生成、数据库存储等服务。项目目录主要分为 src(前端)和 application(后端)两大部分。

1.1 目录结构

复制代码
/c:/aaa/learn/vue2/
├── src/                # 前端源码目录
│   ├── components/     # Vue组件
│   ├── modules/        # 业务逻辑与工具模块
│   ├── utils/          # 工具函数
│   ├── stores/         # Pinia状态管理
│   ├── views/          # 页面视图
│   ├── assets/         # 静态资源
│   ├── types/          # 类型定义
│   ├── router/         # 路由配置
│   ├── main.js         # 入口文件
│   └── App.vue         # 根组件
└── backend/application/
    ├── routes/         # Flask路由
    ├── generateKml/    # KML文件生成
    ├── generateWpml/   # WPML文件生成
    ├── database.py     # 数据库连接
    ├── app.py          # Flask应用入口
    └── ...

二、前端模块详解(src目录)

2.1 组件层(components)

2.1.1 典型组件举例
  • SimulatedFlight.vue:模拟飞行主界面,负责航线点的展示、模拟飞行控制、与三维模型的联动。
  • DroneLen.vue:无人机镜头视角控制,响应模拟飞行过程中的相机参数变化。
  • ModelAdd.vue:模型导入与管理界面。
  • Upload.vue:航线导出与下载界面。
  • ImportRoute.vue:航线文件导入界面。
2.1.2 组件代码片段分析

Upload.vue 为例,展示如何通过 axios 请求后端接口并下载航线压缩包:

js 复制代码
const downloadKmz = async () => {
  try {
    const response = await axios.get('http://localhost:8080/download_kmz', {
      responseType: 'blob'
    });
    const blob = new Blob([response.data], { type: 'application/vnd.google-earth.kmz' });
    const url = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = 'airline.kmz';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    window.URL.revokeObjectURL(url);
  } catch (error) {
    ElMessage.error('下载KMZ失败: ' + (error.message || error));
  }
};

该函数实现了前端对后端生成的 KMZ 文件的下载,体现了前后端文件流交互的典型用法。

2.2 业务逻辑层(modules)

2.2.1 航线点与行为管理
  • punctateRoute/punctateRoute.js:负责航线点的绘制、编辑、行为组(actionGroup)组装、与 Cesium 三维场景的交互。
  • collectData/airlineCollect.js:航线点、无人机类型、航线名称等数据的集中存储与获取。
  • netRequest/downloadAirline.jsdownloadAirline_wpml.js:负责与后端的航线文件生成、下载相关的 API 请求。
2.2.2 关键代码片段分析

punctateRoute.js 的航点行为组组装为例:

js 复制代码
const pointInfo = {
  longitude: Cesium.Math.toDegrees(cartographic.longitude),
  latitude: Cesium.Math.toDegrees(cartographic.latitude),
  height: cartographic.height - terrainHeight,
  ellipsoidHeight: cartographic.height,
  actionGroup: index > 0 && AllPointActions[index - 1] && AllPointActions[index - 1].actions ? (() => {
    // ...
    return {
      actionGroupId: index - 1,
      actionGroupStartIndex: 1,
      actionGroupMode: 'sequence',
      actionTrigger: { actionTriggerType: 'reachPoint' },
      actions: AllPointActions[index - 1].actions.map((action, actionIndex) => ({
        actionId: actionIndex,
        actionActuatorFunc: action.actionActuatorFunc,
        actionActuatorFuncParam: {
          param: action.actionActuatorFuncParam,
        }
      }))
    };
  })() : null
};

该片段展示了如何将前端行为按钮的参数组装为后端可识别的 actionGroup 结构。

2.3 工具与状态管理

  • utils/:如 viewerManager.js 管理 Cesium Viewer 实例,cesUtil.js 提供三维空间相关工具函数。
  • stores/:如 actionButtonStore.jsflightControlStore.js,基于 Pinia 实现航点行为、飞行参数等全局状态管理。

三、后端模块详解(application目录)

3.1 路由与接口层(routes)

  • upload.py:核心路由文件,包含航线文件上传、下载、数据库存储、KMZ 压缩包生成等接口。
3.1.1 典型接口代码片段

/download_kmz 接口为例:

python 复制代码
@upload_bp.route('/download_kmz', methods=['GET'])
def download_kmz():
    try:
        base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        kml_path = os.path.join(base_dir, 'generateKml', 'output', 'airline.kml')
        wpml_path = os.path.join(base_dir, 'generateWpml', 'output', 'airline.wpml')
        
        if os.path.exists(wpmz_dir):
            shutil.rmtree(wpmz_dir)
        os.makedirs(wpmz_dir, exist_ok=True)
        shutil.copy(kml_path, os.path.join(wpmz_dir, 'template.kml'))
        shutil.copy(wpml_path, os.path.join(wpmz_dir, 'waylines.wpml'))
        zip_path = os.path.join(base_dir, 'airline.zip')
        
        with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
            for root, dirs, files in os.walk(wpmz_dir):
                for file in files:
                    file_path = os.path.join(root, file)
                    arcname = os.path.relpath(file_path, os.path.dirname(wpmz_dir))
                    zipf.write(file_path, arcname)
                    
        kmz_path = os.path.join(base_dir, 'airline.kmz')
        if os.path.exists(kmz_path):
            os.remove(kmz_path)
        os.rename(zip_path, kmz_path)
        return send_file(
            kmz_path,
            mimetype='application/vnd.google-earth.kmz',
            as_attachment=True,
            download_name='airline.kmz'
        )
    except Exception as e:
        return jsonify({'code': 500, 'message': f'生成KMZ失败: {str(e)}', 'data': None})

该接口实现了后端对航线文件的整合、压缩与下载,体现了 Python 文件操作与 Flask 文件流响应的结合。

3.2 文件生成模块

  • generateKml/kml_generator.py:负责将前端传来的航点、行为组等数据生成 DJI 兼容的 KML 文件。
  • generateWpml/wpml_generate.py:负责生成 WPML 文件,结构与 KML 类似但参数更丰富。
3.2.1 KML 生成核心代码片段
python 复制代码
def add_waypoint_action(self, placemark_element, waypoint):
    try:
        if 'actionGroup' not in waypoint or waypoint['actionGroup'] is None:
            return
        action_group_data = waypoint['actionGroup']
        if not isinstance(action_group_data, dict):
            return
        ET.SubElement(action_group, 'wpml:actionGroupId').text = str(self.action_group_index)
        self.action_group_index += 1
        trigger_data = action_group_data.get('actionTrigger', {})
        actions = action_group_data.get('actions', [])
        for action in actions:
            action_element = ET.SubElement(action_group, 'wpml:action')
            action_func = action.get('actionActuatorFunc')
            if not action_func:
                continue
            action_params = action.get('actionActuatorFuncParam', {})
            param1 = action_params.get('param1', 0)
            param2 = action_params.get('param2', 0)
            # ... 省略不同类型的参数写入 ...
    except Exception as e:
        print(f"Error in add_waypoint_action: {str(e)}")

3.3 数据库与配置

  • database.py:封装 MySQL 数据库连接,供路由层调用。
  • routes/upload.py:部分接口支持将航线点、任务配置等数据存入数据库,便于后续查询与管理。

四、前后端交互流程

  1. 用户在前端界面绘制航线、配置行为,通过 API 提交数据到后端。
  2. 后端根据数据生成 KML、WPML 文件,并存储于指定目录。
  3. 用户点击"下载"按钮,前端请求 /download_kmz,后端将 KML、WPML 整合压缩为 KMZ 返回。
  4. 用户可通过"导入"功能上传 KMZ 文件,前端解析后可还原航线。

五、技术难点与亮点分析

5.1 三维航线点与行为组的动态组装

  • 前端通过 Vue 响应式数据流,动态维护航点、行为组、参数等,确保每次导出都能反映最新配置。
  • 行为组(actionGroup)结构需严格对齐后端生成器要求,涉及多层嵌套与参数校验。

5.2 文件流与大文件处理

  • 前后端均采用流式处理,避免大文件下载时内存溢出。
  • 后端压缩包生成采用 Python 标准库 zipfile,支持多文件夹、多格式灵活打包。

5.3 跨端数据一致性

  • 前端与后端均有详细的参数注释与类型校验,减少数据结构不一致导致的 bug。
  • 通过接口文档与代码注释,团队成员可快速定位数据流向与结构。
相关推荐
vx_Biye_Design11 小时前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
Cult Of11 小时前
Alicea Wind的个人网站开发日志(2)
开发语言·python·vue
qq5_81151751511 小时前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育11 小时前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育
百锦再11 小时前
Vue高阶知识:利用 defineModel 特性开发搜索组件组合
前端·vue.js·学习·flutter·typescript·前端框架
hdsoft_huge11 小时前
1panel面板中部署SpringBoot和Vue前后端分离系统 【图文教程】
vue.js·spring boot·后端
啊阿狸不会拉杆11 小时前
《机器学习导论》第 5 章-多元方法
人工智能·python·算法·机器学习·numpy·matplotlib·多元方法
wangsir.12 小时前
测试之自动化测试常用函数
python·测试
铁蛋AI编程实战12 小时前
MemoryLake 实战:构建超长对话 AI 助手的完整代码教程
人工智能·python·microsoft·机器学习