项目技术架构与模块详解

一、项目整体结构概览
本项目采用前后端分离架构,前端基于 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.js、downloadAirline_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.js、flightControlStore.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:部分接口支持将航线点、任务配置等数据存入数据库,便于后续查询与管理。
四、前后端交互流程
- 用户在前端界面绘制航线、配置行为,通过 API 提交数据到后端。
- 后端根据数据生成 KML、WPML 文件,并存储于指定目录。
- 用户点击"下载"按钮,前端请求
/download_kmz,后端将 KML、WPML 整合压缩为 KMZ 返回。 - 用户可通过"导入"功能上传 KMZ 文件,前端解析后可还原航线。
五、技术难点与亮点分析
5.1 三维航线点与行为组的动态组装
- 前端通过 Vue 响应式数据流,动态维护航点、行为组、参数等,确保每次导出都能反映最新配置。
- 行为组(actionGroup)结构需严格对齐后端生成器要求,涉及多层嵌套与参数校验。
5.2 文件流与大文件处理
- 前后端均采用流式处理,避免大文件下载时内存溢出。
- 后端压缩包生成采用 Python 标准库 zipfile,支持多文件夹、多格式灵活打包。
5.3 跨端数据一致性
- 前端与后端均有详细的参数注释与类型校验,减少数据结构不一致导致的 bug。
- 通过接口文档与代码注释,团队成员可快速定位数据流向与结构。