学习工作赛道 | GeoModel3D 三维地质建模系统——复赛

【类别】TRAE AI 创造力大赛 - 复赛专区

【标签】 学习工作

【标题】 学习工作赛道 | GeoModel3D 三维地质建模系统

自己 / 团队介绍

我是一名独立开发者,现就读于长安大学地质学专业。我们地质人经常会与钻孔数据、地层剖面、储量估算这些专业工具打交道。我在校期间也在老师的带领下熟悉 3DMine、Surpac 等桌面端地质建模软件的使用,也深知它们在野外的局限性——动辄几十万的授权费,笨重的安装环境,到了野外根本用不上。

编程年限约 2 年,主要做数据可视化和简单的算法建立,但 Web 端、后端、鸿蒙 ArkTS 和 Android 原生开发、OpenGL ES 3D 渲染都是第一次深度接触,全程靠 TRAE 辅助学习和技术落地。Vibe Coding 约 1 年,几乎全程用 TRAE 做原型验证和复杂逻辑实现。性格上属于"想到就做"型,喜欢把专业领域的知识直接转化为可用产品。

这个作品的诞生源于一次野外实习:我拿着手机看高德地图,想确认几个钻孔的位置,却发现没有一个工具能把钻孔数据和地形叠在一起看,更不用说在手机上做三维建模了。当时就想,如果能有一个移动端的三维地质工具,实习时就能实时决策,而不是回到学校机房再花几天时间处理数据。作为学生,我买不起 3DMine 的授权,但我学过编程,还有 TRAE——为什么不能自己做一个?

产品简介

是什么

GeoModel3D 是一款 Android 端三维地质建模系统,把传统桌面端地质软件的核心功能搬到了手机上。从钻孔数据管理、三维地层建模、剖面分析到储量估算,全部在一部 Android 手机上完成,不需要工作站,不需要授权费。

这个产品并非一蹴而就。它的开发经历了三个阶段:先用 Web 技术(Three.js)做原型验证地质建模的可行性,再在鸿蒙端(ArkTS + C++ NAPI)做移动端初赛 Demo,最终在 Android 端(Kotlin + JNI + OpenGL ES 3.0)完成复赛成品。虽然最终只提交了 Android 版,但前两个阶段的技术积累——三维渲染架构、插值算法、储量计算逻辑——直接奠定了 Android 版的基础。

面向谁

核心目标用户是地质专业师生、地质勘探工程师和矿山技术人员。典型使用场景:

• 高校地质教学:课堂演示三维地质建模过程,学生课后用自己的电脑/手机练习,不再受实验室授权电脑数量限制

• 野外实习时,实时查看钻孔空间分布和地层信息,不用翻纸质资料

• 矿山现场快速切剖面,分析矿体形态和延伸方向

• 野外地质编录,GPS 定位 + 拍照 + 记录一体化,不用手写记录本

• 项目汇报时,手机上直接展示三维模型和储量计算结果

完整功能清单与使用路径

应用采用底部 Tab 导航 + 独立页面的架构,共 8 个核心页面:

首页 — 应用主入口。顶部为青色渐变 Hero 区域,展示当前项目名称和矿产类型;下方是 4 列快捷工具网格,可一键跳转到建模、剖面、储量、野外记录;再往下是统计卡片(钻孔数 / 含矿钻孔数 / 平均深度 / 平均品位)和地层图例。首页支持全文搜索,按钻孔 / 地层 / 记录分组展示结果。

地图页 — 基于 Leaflet + 高德瓦片的地图系统,展示钻孔空间分布。功能包括:标准 / 卫星地图切换、全屏模式、在线 / 离线模式切换、离线瓦片下载(可选缩放级别 10-14、最大缩放级别 14-18、下载半径 1/2/5/10 公里,实时显示预计瓦片数量和存储大小)、GPS 实时定位。钻孔标记区分含矿(橙色圆点)和不含矿(绿色圆点),点击弹出钻孔名称、深度、品位信息。用户定位为蓝色圆点 + 精度圆。

钻孔数据页 — 独立页面,支持从本地 CSV 文件导入真实钻孔数据(中英文表头兼容),也可加载内置示例数据。每条钻孔可展开完整的地质分层表,包含层号、地层名称、起始深度、厚度、品位,以及岩性描述。导入的 CSV 数据自动保存到全局项目存储,供建模、剖面、储量等页面共享使用。

三维建模页 — 应用核心。使用 OpenGL ES 3.0 GPU 硬件加速渲染,支持 IDW / Kriging / RBF 三种插值算法构建地层曲面。左侧栏为参数面板(插值方法选择、网格精度滑块、地层选择、透明度调节),底部为"选择数据"按钮和视角控制按钮(放大 / 缩小 / 复位视角 / 自动旋转),不遮挡 3D 画面。底部新增水平滚动的地层图例栏,显示各地层名称和对应颜色,与剖面 2D 页面的图例样式一致。底部为毛玻璃状态栏,显示当前渲染状态。支持单指旋转、双指缩放、双击折叠面板。数据选择面板支持切换示例项目和用户导入的自定义项目,切换后 3D 场景实时刷新。

剖面分析页 — 沿任意方向切剖面,2D 剖面图实时生成。顶部新增"2D/3D"切换按钮,3D 模式下使用 Geo3DView 渲染矿体曲面,支持触摸旋转、双指缩放,左下角配有放大、缩小、复位、自动旋转四个控制按钮。2D 模式下左侧工具栏有缩放 / 缩小 / 复位按钮,支持双指缩放和拖拽,双击复位。中部为剖面图显示区,右侧为参数面板。左下角"选择数据"按钮弹出面板,支持示例项目和用户导入项目切换,切换后自动重建矿体曲面和剖面参数。剖面图使用完整数据指纹(钻孔名 + 深度 + 坐标 + 剖面参数)确保当场绘制,杜绝缓存图问题。3D 模式下底部同样显示地层图例和状态栏。

储量估算页 — 三种专业储量算法:平行断面法(沿钻孔主方向切剖面,相邻剖面间用截锥公式计算体积)、地质块段法(按钻孔分块段,逐块计算面积 × 厚度)、算术平均法(全域平均厚度 × 面积)。支持工业品位、边界品位、矿石密度、断面间距参数联动。数据源列表自动加载用户导入的自定义项目数据,选中后可直接对导入数据进行储量估算。结果卡片展示体积、吨位、品位等关键指标。

野外记录页 — GPS 定位(静默权限检查 + 按需请求)、相机拍照、照片管理一体化。表单字段包括点位编号、岩石名称、颜色、结构、构造、产状、风化程度等。新增"权限管理"卡片,用绿色 / 红色标签显示 GPS / 相机 / 照片三项权限状态和操作提示。

项目管理页 — 右下角"+"悬浮按钮可创建新项目,对话框支持输入项目名称、选择矿种类型、填写描述,并可直接从本地导入 CSV 钻孔数据到项目中。示例项目展示铁矿一期数据。点击项目卡片切换全局数据源,同步更新钻孔数据、地层定义、建模和分析页面内容。

相比初赛 Demo 的升级

产品的开发经历了 Web 原型(初赛提交)→ 鸿蒙移动端 → Android 复赛成品三个阶段。初赛提交的是浏览器直接打开的 Web 版 Demo(Three.js 渲染、7 层地层、17 个钻孔、3 种插值算法、全国工作地图),复赛完成了从鸿蒙端到 Android 的全面迁移和重构:

维度 初赛 Demo(Web 版) 复赛成品(Android)
平台 浏览器(HTML + JS + Three.js) Android (Kotlin + Jetpack Compose)
3D 渲染 Three.js(浏览器 WebGL) OpenGL ES 3.0 GPU 硬件加速 (SurfaceView + JNI/C++)
地图 Leaflet + 中国 GeoJSON 轮廓 高德地图(标准 + 卫星)+ 离线下载 + IndexedDB 缓存 + 全屏
储量估算 网格法 + 平行断面法 + 算术平均法(雏形) 三种专业算法完善,参数联动,支持导入数据估算
数据导入 固定示例数据(17 个钻孔) CSV 本地文件导入,中英文表头兼容,全局数据共享
数据选择 无 建模 / 剖面 / 钻孔 / 储量四页面统一数据选择面板
搜索 无 全文搜索,按类型分组
设计系统 基础侧栏 + 深色主题 Material 3 Expressive,地质青配色,毛玻璃效果
应用图标 无(网页) 3D 地层立方体造型,自适应图标,5 种密度
剖面 3D 无 2D/3D 切换,3D 模式支持触摸旋转 + 双指缩放
地层图例 无 建模 / 剖面页面底部水平滚动图例栏
原生能力 无(浏览器限制) GPS 定位、相机拍照、离线缓存、文件系统访问

产品演示视频

地质3D建模软件演示视频_哔哩哔哩_bilibili

产品创作历程

灵感来源

作为地质专业的学生,我深刻体会到一个问题:数据采集在野外,数据分析在实验室,两者之间隔着几天甚至几周。野外实习时想看看附近钻孔打到什么地层、矿体往哪个方向延伸——这些在桌面软件上点几下就能完成的事,到了野外就只能靠经验和脑补。

3DMine 和 Surpac 这类专业软件功能强大,但它们是为桌面工作站设计的。一套授权几十万,安装包几个 G,野外根本用不上。我上"矿床学"课程时,老师用 3DMine 演示矿体三维模型,但实验室只有 5 台授权电脑,全班 40 个人排队用。课后想自己练习,个人根本买不起正版软件。更实际的一个场景是:暑期去矿区实习,采集了钻孔数据,要等开学回到学校机房才能建模,如果当时发现数据有问题(比如某层厚度异常),又得重新跑一趟野外——这对学生来说时间和经费都扛不住。

于是我决定自己做一个。不是什么宏大的创业计划,就是想解决自己学习和实习中的痛点。不需要工作站,不需要授权费,打开手机就能用。核心功能就是地质学习和实习中最需要的:钻孔数据管理、三维地层可视化、剖面分析、储量估算。再加上野外编录功能,把记录和建模打通。我是地质专业的,算法逻辑我清楚;编程方面有 TRAE 帮我,从 Web 到 Android 都能搞定。

阶段一:Web 原型验证

在决定做移动端之前,我先用 Web 技术验证地质建模的可行性。选择 Web 起步而不是直接上原生开发,是因为我编程基础不强,Web 的调试反馈最快——改一行代码刷新浏览器就能看到效果。而且 Web 应用零安装成本,传给同学直接就能用,课堂演示也方便。Three.js / WebGL 在浏览器中的 3D 渲染性能已经非常成熟,完全能够胜任地质模型的实时渲染。

用原生 JavaScript + Three.js 搭了一个纯前端的三维地质建模工具,单个 HTML 文件 + 依赖库,浏览器直接打开即可运行。功能包括:实时渲染 7 层三维地层模型(第四系表土、砂砾石、白垩系砂岩、侏罗系泥岩、三叠系灰岩、二叠系页岩、石炭系灰岩)和独立矿体模型,17 个钻孔以 3D 彩色柱体呈现,鼠标悬停红色标记球弹出钻孔信息卡片。内置 IDW / Kriging / RBF 三种空间插值算法,每层地层和矿体可独立控制显示/隐藏。还内嵌了中国 GeoJSON 轮廓 + 340+ 城市标记的工作地图,支持 AI 辅助生成标准化野外地质记录文档。

Web 原型开发中踩了不少坑。矿体建模从"方块"到"透镜体"反复了 3 次:初始版本是长方体,告诉 TRAE"矿体不能是方块,要改成透镜体形状,中间厚边缘薄",TRAE 用参数化曲面生成透镜体但表面全是网格线,再让 TRAE 把 wireframe 改成 MeshPhongMaterial 并调高 shininess 才达到满意效果。钻孔标记球被矿体遮挡的问题也是实际使用中才发现的——旋转到某些角度标记球被矿体挡住看不见,让 TRAE 把标记球高度提升到 z=65m 并在 Raycaster 检测中优先检测标记球才解决。地层和矿体最初混在同一个 Group 里无法独立控制,重构后拆成 8 个独立实体各绑 checkbox。地图上 340+ 城市圆点看似"信息丰富"实际是视觉噪音,去掉后页面瞬间干净了——做减法有时候比做加法更重要。

这一阶段的核心收获是跑通了地质建模的算法链路——IDW / Kriging / RBF 三种插值算法的实现、钻孔数据到三维曲面的转换逻辑、矿体圈定的品位阈值过滤——这些逻辑后来原封不动地搬到了鸿蒙端和 Android 端。Web 原型还实现了 autoBindButtons() 自动事件绑定系统,自动扫描页面中所有没有 onclick 事件的按钮,根据 data-action 属性绑定对应函数,避免手动逐个绑定遗漏,这个设计也延续到了后续版本。

但 Web 版的局限也很明显:Three.js 在手机浏览器上性能不理想,无法离线使用,也无法调用 GPS、相机等原生能力。我需要把它变成一个真正的移动应用。

阶段二:鸿蒙端移动原型(初赛后探索)

初赛 Web 版提交后,我发现浏览器有根本性局限:无法离线使用、无法调用 GPS 和相机、手机上体验差。于是开始探索移动端方案,选择了鸿蒙平台。当时想法很简单——学校实验室有鸿蒙开发板,DevEco Studio 也是免费的,想着先试一下移动端能不能跑。用 ArkTS + C++ NAPI 开发了移动端原型,用 Canvas2D 渲染三维模型,XComponent 作为渲染组件。功能包括基础的钻孔数据展示、简陋的三维模型、剖面分析框架和储量估算雏形,还实现了登录界面、野外记录功能的权限管理系统(GPS 静默检查 + 按需请求、相机 / 照片权限管理)。

鸿蒙端开发中遇到了 Previewer 无法显示 NAPI 原生渲染的问题,最终用 Canvas 2D 替代 XComponent 解决。另外还踩了一个 C++ 层的坑:OH_NativeXComponent_Callback 必须声明为 static 变量,否则栈帧销毁后函数指针被覆盖,导致 OnSurfaceCreated 回调中 SIGSEGV。

Demo 验证了移动端思路可行——手机端确实能跑地质建模工具,但问题也很明显:Canvas2D 渲染在移动端帧率低、卡顿严重;没有地图功能,钻孔位置无法可视化;储量算法太简单,不符合实际工程需求;UI 设计也不够专业;更关键的是,鸿蒙生态覆盖面有限,我同学和老师用的都是 Android 手机。这段探索虽然没作为最终提交,但积累的 C++ NAPI 渲染经验直接为 Android 端的 JNI 架构打下了基础。

阶段三:复赛 Android 成品

复赛完成了从鸿蒙到 Android 的全面迁移和重构。以下三个关键决策决定了最终产品的形态:

决策一:从 HarmonyOS 迁移到 Android。 鸿蒙生态覆盖面有限,我同学和老师用的都是 Android 手机。迁移意味着几乎重写整个应用——ArkTS 换成 Kotlin Compose,NAPI 换成 JNI,XComponent 换成 SurfaceView。对一个编程自学起步的学生来说,这个工作量不小,但换来的是更广泛的设备兼容性。Android 7.0 起步,覆盖 arm64-v8a / armeabi-v7a / x86_64 三个 ABI。鸿蒙端积累的 C++ NAPI 渲染经验直接迁移到了 JNI 层,插值算法和储量计算的 C++ 实现几乎原样复用。

决策二:3D 渲染从零搭建。 初赛的 Canvas2D 渲染体验太差,复赛决定用 OpenGL ES 3.0 GPU 硬件加速。说实话,OpenGL ES 对我来说是个完全陌生的领域——之前只用过 Three.js 这种封装好的库,底层渲染管线从来没碰过。架构是 SurfaceView + SurfaceHolder.Callback + JNI/C++,C++ 层管理 EGL 上下文、VBO/VAO 顶点缓冲、GLSL 着色器。顶点数据布局是 10 个 float / 顶点(position 3 + color 4 + normal 3),通过 JNI 一次性上传。着色器实现 MVP 矩阵变换 + 方向光照 + 透明度混合。Web 版用 Three.js 封装好的渲染管线,在 Android 上需要从 EGL 初始化到 GLSL 着色器全部手写,这是整个复赛技术难度最大的部分——完全靠 TRAE 一行一行带着我写。

这个过程中踩了不少坑。最典型的是顶点数据布局不匹配:着色器定义为 position(3) + color(4) + normal(3) = 10 个 float,但缓冲区 stride 计算误用了 9,导致画面花屏。还有 eglTerminate() 终止进程级共享 EGL 显示连接后,后续 GL 函数访问已释放 GPU 内存引发 SIGSEGV——改为按需渲染(移除 30fps 定时器,仅在数据变化、触摸交互、自动旋转时绘制)后解决。

决策三:地图系统全面集成。 这是初赛完全没有的功能。使用 WebView 加载 Leaflet + 高德瓦片图层,无需 API Key。钻孔坐标从 CGCS2000 米制转换到经纬度显示。后来又陆续加了卫星地图、离线地图下载(IndexedDB 缓存瓦片)、全屏模式。

离线地图遇到过一个 CORS 坑:自定义瓦片图层加了 crossOrigin = ‘anonymous’ 属性后,WebView 要求高德瓦片服务器返回 CORS 头,但高德服务器不返回这些头,图片直接被阻止加载。解决方案是移除 crossOrigin,改用 img.src 直接加载瓦片(不受 CORS 限制),同时在后台用 fetch 异步缓存到 IndexedDB。

计算性能也做了多轮优化:RBF 算法预计算并缓存平滑参数 c,将每次调用复杂度从 O(n²) 降至 O(1);页面加载时仅构建矿体曲面而非全部 6 个地层,计算量减少 6 倍;自动构建使用 16×16 网格(较 32×32 降低 4 倍计算量);手动构建限制最大精度为 32,防止用户拖到 128×128 时卡死。

数据流转架构设计

复赛开发中遇到的最复杂的工程问题不是单个功能,而是跨页面数据共享。用户在钻孔页面导入 CSV 数据后,需要在建模、剖面、储量页面都能使用这份数据。解决方案是创建 CustomProjectStore 单例对象作为全局数据存储,在钻孔页面或项目管理页面创建项目时写入,在建模 / 剖面 / 钻孔 / 储量四个页面的数据选择面板中统一读取。每个页面的数据选择面板结构一致——"我的数据"在上方默认展开,"示例项目"在下方默认折叠,用户导入数据后自动选中。

TRAE 实践过程

开发流程

整个产品从想法到复赛成品,经历了 Web 原型 → 鸿蒙初赛 → Android 复赛三个阶段,全部使用 TRAE 完成开发。我的开发节奏始终如一:

1. 自然语言描述需求 — 把功能需求和技术约束用中文描述给 TRAE,比如"3D 渲染使用 OpenGL ES 3.0 GPU 硬件加速"、“3D 视图组件使用 SurfaceView”、“JNI 桥接层通过 RegisterNatives 注册 native 方法”

2. TRAE 生成代码 — TRAE 理解需求后生成 JavaScript / ArkTS / Kotlin / Compose / C++ / HTML 代码,一次通常生成完整的文件或功能模块

3. 编译验证 — 让 TRAE 执行编译(Webpack / DevEco / Gradle),它会自动定位编译错误并修复

4. 真机测试 — 浏览器验证 Web 版,DevEco Previewer 验证鸿蒙版,ADB 安装到华为手机验证 Android 版

5. 迭代调整 — 基于测试反馈,用自然语言描述修改需求,TRAE 重新生成

这个过程最让我惊讶的是,TRAE 对地质专业术语的理解非常准确。我描述"平行断面法——沿钻孔主方向切剖面,相邻剖面间用截锥公式计算体积",TRAE 生成的代码和我在课堂上学到的、在 3DMine 里看到的算法逻辑完全一致。而且同一套地质算法逻辑,TRAE 能在 Three.js、ArkTS、Kotlin 三种技术栈间准确迁移。对于我这样一个地质专业、编程自学起步的学生来说,TRAE 像是一个全能的技术搭档——我负责地质专业知识,它负责代码实现,遇到不懂的技术栈它还能边教我边写。

关键开发步骤

步骤一:Web 原型——地质建模算法链路验证

我对 TRAE 说的第一句话大概是:“我想用浏览器做一个三维地质建模的工具,能显示地层和矿体,类似 3DMine 那种效果,但是轻量级的。” 当时我刚学完"构造地质学"和"矿床学",脑子里全是地层的概念,但 Web 前端只懂一点 HTML。TRAE 没有直接扔代码,而是先帮我理清了关键问题:地层和矿体用什么数据结构?插值算法用哪种?交互方式怎么设计?然后给出了技术选型:Three.js 做 3D 渲染,OrbitControls 做相机控制,BufferGeometry 做高性能网格,侧栏面板 + 3D 视口的布局。

关键 Prompt 示例:“用 Three.js 创建一个地质三维建模场景,包含 7 层地层(第四系表土、砂砾石、白垩系砂岩、侏罗系泥岩、三叠系灰岩、二叠系页岩、石炭系灰岩),每层用不同颜色,地层要有顶面和底面形成闭合体,使用半透明材质。矿体独立于地层,用金黄色带自发光。钻孔用彩色柱体表示,孔口用红色球体标记。” TRAE 一次性就生成了可运行的地层建模代码,7 层颜色、闭合体结构、矿体分离都对了。如果自己从零写 Three.js,光是搞清楚 BufferGeometry 的顶点索引就要卡半天。

逐步迭代中踩了几个典型的坑:矿体从方块改成透镜体反复了 3 次(形状对了但表面粗糙 → 改成 MeshPhongMaterial + 高细分度才光滑);钻孔标记球被矿体遮挡(提升到 z=65m + Raycaster 优先检测);地层和矿体混在同一 Group 里无法独立控制(重构为 8 个独立实体);OrbitControls 默认极角限制导致旋转有"撞墙"感(地质模型需要从任意角度观察包括正下方,取消极角限制);地图 340+ 城市圆点造成视觉噪音(去掉只保留省界轮廓)。

最硬核的一步是三种插值算法的实现。关键 Prompt:“实现三种空间插值算法:1) IDW 反距离加权法;2) 克里金法(含半变异函数拟合:球状/指数/高斯模型);3) RBF 径向基函数法(自适应形状参数)。用这三种算法根据 9 个钻孔的分层数据,插值生成 7 层地层的顶面和底面网格。” 这些算法我在"数学地质"课上学过理论,但从来没自己实现过。TRAE 一次性实现了三种算法的完整代码,克里金的半变异函数拟合、RBF 的自适应形状参数计算,这些在课上只考公式推导,TRAE 直接帮我把理论变成了可运行的代码。之后还让 TRAE 评估改进了储量估算模块,支持网格法、平行断面法、算术平均法三种方法,并扩展了数据模型(新增 density 和 grade 字段)和 UI。

还实现了全国工作地图模块:用 Leaflet.js 渲染中国 GeoJSON 轮廓 + 340+ 城市标记,点击地图任意位置可添加工作记录。最后让 TRAE 自主规划功能改进:“还有什么你觉得可以加的功能就加上去,但是质量一定要好,一定要能用”,TRAE 在 28 分钟内自动规划并实现了 10 项功能改进。这一阶段跑通了从钻孔数据到三维曲面的完整算法链路,后续鸿蒙端和 Android 端的算法实现都以此为基础。

步骤二:鸿蒙端初赛——移动端原型开发

向 TRAE 描述了鸿蒙版需求:“学校实验室有鸿蒙开发板,我想试试把地质建模工具搬到鸿蒙上”。TRAE 生成 ArkTS + C++ NAPI 项目结构。实现了钻孔数据展示、Canvas2D 三维渲染(XComponent 组件)、剖面分析框架、储量估算雏形。野外记录功能实现了完整的权限管理系统:GPS 静默检查 + 按需请求(双 Provider 监听、Looper 调用、超时兜底)、相机 / 照片权限管理、权限管理卡片 UI。鸿蒙端开发中解决了 Previewer 无法显示 NAPI 原生渲染的问题(用 Canvas 2D 替代 XComponent)和 OH_NativeXComponent_Callback 必须声明为 static 变量的问题。

模拟器演示

实机演示

步骤三:Android 平台迁移与 UI 重构

向 TRAE 描述了迁移需求:“保留当前这个软件,然后导入新的安卓端前端设计。记住之前那个前端要点,调整过的部分都要记住。” TRAE 理解了 ArkTS 到 Kotlin Compose 的映射关系,完成了 9 个核心文件的完全重写,包括 HomeScreen 的青色渐变 Hero 区域、4 列快捷工具网格、28dp 大圆角统计卡片,以及 MainActivity 底部导航栏的药丸指示器和统一选中色。所有功能逻辑保持不变。

步骤四:3D 渲染引擎搭建

描述了完整的技术约束链:“3D 渲染使用 OpenGL ES 3.0 GPU 硬件加速,替代原 Canvas2D 软件渲染”、“3D 视图组件使用 SurfaceView + SurfaceHolder.Callback,替代原 XComponent”、“JNI 桥接层通过 RegisterNatives 注册 native 方法,替代原 NAPI”、“C++ 层使用 VBO/VAO 存储顶点数据,通过 GLSL 着色器实现 MVP 变换 + 方向光照 + 透明度混合”。TRAE 生成了从 Kotlin Scene 数据转换到 JNI 桥接到 C++ OpenGL 渲染的完整链路,包括 GLSL 顶点着色器和片段着色器代码、EGL 环境初始化、相机控制矩阵计算。鸿蒙端 C++ NAPI 层的插值算法和储量计算逻辑几乎原样复用到了 JNI 层。

步骤五:地图系统集成

描述了地图需求:“地图必须使用高德地图源”、“地图使用 WebView 加载 Leaflet + 高德瓦片图层,无需 API Key”、“钻孔坐标转换:局部坐标(CGCS2000 米制)通过参考点转换为经纬度显示在地图上”。TRAE 生成了完整的 amap.html(含 Leaflet 初始化、自定义 OfflineTileLayer、IndexedDB 缓存逻辑、卫星瓦片切换)和 MapScreen.kt(WebView 封装、坐标转换、标记渲染、全屏模式、离线下载面板)。

步骤六:储量估算三种算法

描述了算法需求:“储量估算实现三种算法:平行断面法(沿钻孔主方向切剖面,相邻剖面间用截锥公式计算体积)、地质块段法(按钻孔分块段,逐块计算面积 × 厚度)、算术平均法(全域平均厚度 × 面积),支持工业品位、边界品位、矿石密度、断面间距参数联动,切换数据源自动加载对应矿种的地层定义”。TRAE 准确理解了每种算法的数学逻辑——这套算法逻辑早在 Web 原型阶段就跑通过一次,这次在 Kotlin 上重新实现。生成了完整的 ReserveScreen.kt,包括参数输入 UI(56dp 高输入框、20sp 字体、Chip 选中态)和结果卡片。后续又让 TRAE 将数据源列表接入 CustomProjectStore,使用户导入的 CSV 数据也能直接进行储量估算。

步骤七:离线地图下载系统

描述了离线需求:“离线地图做一下”、“卫星地图也要有”、“地图可以到全屏”、“加一个下载离线地图的功能”。TRAE 逐步实现了:自定义 OfflineTileLayer(在线直接加载 img.src 避免 CORS,后台 fetch 缓存到 IndexedDB)、卫星瓦片图层(webst0{1-4}.is.autonavi.com,style=6)、全屏模式切换、离线下载面板(可选最小缩放级别 10-14、最大缩放级别 14-18、下载半径 1/2/5/10 公里,实时显示预计瓦片数量和存储大小)。

步骤八:CSV 数据导入与全局数据共享

描述了数据导入需求:“导入这个钻孔数据的时候,你要从本地选择,不能虚构”、“项目管理里面不是有个项目导入吗?项目导入下面应该可以加上那个导入数据的功能”、“3D 建模的功能要和剖面的功能一样,搞一个选择数据的功能”、“把示例全部折叠起来,我只要能看到我的那个新导入数据就行”、“储量估算为什么不同步,也要有导入数据的估算”。TRAE 实现了:ActivityResultContracts.OpenDocument 文件选择器、支持中英文表头的 CSV 解析器(钻孔编号 / 地层名称 / X 坐标 / Y 坐标 / 高程 / 终孔深度 / 倾角 / 方位角 / 层号 / 顶界深度 / 底界深度 / 岩性编码 / 颜色 / 描述 / 密度 / 品位)、CustomProjectStore 全局单例存储、四个页面(钻孔 / 建模 / 剖面 / 储量)统一的数据选择面板。

关键任务对话 Session ID

以下为 TRAE 开发过程中三个阶段的关键会话 ID:

Web 原型阶段(初赛提交版本):

6. Session ID: 6a2fff9904057b2cef39648f

• 开发内容:初始项目创建、3D 场景搭建、7 层地层/矿体建模、透镜体矿体反复调优、钻孔悬停交互(标记球遮挡修复)、地层与矿体独立显示控制面板

7. Session ID: 6a3bcab72c96c067f7e15cab

• 开发内容:三种空间插值算法实现(IDW / 克里金含半变异函数拟合 / RBF 自适应形状参数)、储量估算模块评估与改进(网格法 / 平行断面法 / 算术平均法)、数据模型扩展(density / grade 字段)、UI 增强

8. Session ID: 6a3bb49a7bb60f8a0bb6ae3a

• 开发内容:全国工作地图模块开发、Leaflet.js + 中国 GeoJSON 轮廓渲染、340+ 城市标记优化(去噪)、AI 辅助野外地质记录生成

9. Session ID: 6a62d0c0380cc0a5f3768a1d

• 开发内容:GeoModel3D 功能迭代与 Bug 修复

鸿蒙端初赛阶段:

10. Session ID: 6a6330a7ad64658cb8408f40

• 开发内容:ArkTS + C++ NAPI 鸿蒙原生开发(插值引擎、储量计算器、剖面分析器)、Previewer 渲染问题解决(NAPI → Canvas 2D)

11. Session ID: 6a6849ea7546695959d59504

• 开发内容:HarmonyOS 原型阶段的登录界面实现、编译错误修复(VerticalAlign / HorizontalAlign 类型不匹配、maxHeight 属性问题)、野外记录功能的权限管理系统(GPS 静默检查 + 按需请求、相机 / 照片权限管理、权限管理卡片 UI)

Android 端复赛阶段:

12. Session ID: 6a69f89af185f13ef33dc41c(跨 7 月 31 日 - 8 月 4 日,覆盖复赛全部核心开发)

• 阶段一:数据源切换功能(10 个示例项目、矿种筛选、全局数据源切换)、高德地图集成(Leaflet + 高德瓦片、坐标转换、差异化标记)、GPS 定位修复(双 Provider 监听、Looper 调用、超时兜底)

• 阶段二:剖面分析缩放功能(双指缩放、拖拽、双击复位)、储量估算三种算法实现、全页面字体适配修复、Canvas 当场绘制机制重构

• 阶段三:Android 平台迁移(ArkTS → Kotlin Compose、NAPI → JNI、XComponent → SurfaceView)、UI 全面重构(Material 3 Expressive 设计系统、地质青配色、毛玻璃效果)、3D 启动图标设计(3D 地层立方体造型、自适应图标、5 种密度)

• 阶段四:搜索功能完善、消息功能移除

• 阶段五:离线地图下载(IndexedDB 缓存、瓦片下载器、进度显示)、卫星地图(高德卫星瓦片、地图类型切换)、全屏地图模式

• 阶段六:CSV 本地文件导入(ActivityResultContracts.OpenDocument、中英文表头解析)、CustomProjectStore 全局数据存储、四页面统一数据选择面板(钻孔 / 建模 / 剖面 / 储量)、示例数据精简为单个、储量估算页接入自定义数据源

13. Session ID: 6a6dfed18bc4852c4d72cd2b(8 月 1 日,复赛功能完善阶段)

• 开发内容:储量估算页数据源选择卡片开发(接入 CustomProjectStore 加载用户导入的 CSV 数据)、3D 建模页底部地层图例栏(水平滚动,与剖面 2D 页面图例样式一致)、剖面分析页 2D/3D 切换功能(3D 模式使用 Geo3DView 渲染矿体曲面,支持触摸旋转、双指缩放、左下角控制按钮组)

技术方案分享

技术栈

产品的技术栈经历了三次演进,每个阶段的技术选型都为下一阶段积累了经验:
层级 Web 原型阶段 鸿蒙初赛阶段 Android 复赛成品
UI 框架 HTML5 + CSS3 + 原生 JavaScript ArkTS (类 TypeScript) Kotlin + Jetpack Compose
3D 渲染 Three.js + OrbitControls Canvas2D 软件渲染 (XComponent) OpenGL ES 3.0 GPU 硬件加速 (SurfaceView)
原生桥接 无 NAPI + C++ JNI + C++ (CMake 构建, RegisterNatives)
着色器 Three.js 内置材质 无 GLSL ES 3.0 (MVP 变换 + 方向光照 + 透明度混合)
地图 无 无 WebView + Leaflet.js + 高德瓦片
离线缓存 无 无 IndexedDB (瓦片级 Blob 存储)
数据导入 无 无 ActivityResultContracts + CSV 解析 (中英文表头)
全局数据 无 无 CustomProjectStore 单例 (跨页面共享)
设计系统 基础深色主题 基础深色主题 Material 3 Expressive, 地质青 #00D4FF
兼容性 浏览器 HarmonyOS 设备 Android 7.0 (API 24) 起, arm64-v8a / armeabi-v7a / x86_64

三阶段的核心算法(IDW / Kriging / RBF 插值、平行断面法 / 地质块段法 / 算术平均法储量估算)逻辑一致,只是实现语言从 JavaScript → C++ → Kotlin/C++ 逐步迁移。

关键实现思路

3D 渲染管线:Kotlin 层构建 Scene 对象(含网格顶点、颜色、法线),转换为 FloatArray(10 floats / 顶点)后通过 JNI 上传至 C++ 层。C++ 层在 Surface 创建时初始化 EGL 环境(EGL_OPENGL_ES3_BIT + 24bit 深度缓冲),创建 VBO/VAO 存储顶点数据,编译链接 GLSL 着色器程序。每帧渲染时,顶点着色器执行 MVP 矩阵变换,片段着色器计算方向光照(Lambert 漫反射)和透明度混合。相机支持单指旋转(yaw/pitch)、双指缩放(pinch)、自动旋转模式。

渲染性能优化:从 30fps setInterval 定时器改为按需渲染——仅在数据变化、触摸事件、自动旋转时请求重绘,消除空闲帧的 GPU 负载。页面加载时只构建矿体曲面(1×256 次插值)而非全部地层(6×1024 次),计算量减少约 24 倍。RBF 算法预计算平滑参数 c 并缓存,将每次插值调用复杂度从 O(n²) 降至 O(1)。自动构建使用 16×16 网格,手动构建限制最大 32×32 防止卡死。

离线地图架构:自定义 OfflineTileLayer 继承 L.TileLayer,重写 createTile 方法。在线模式下直接 tile.src = url 加载瓦片(绕过 CORS 限制),同时在后台用 fetch() 异步获取瓦片 Blob 并缓存到 IndexedDB。离线模式下优先从 IndexedDB 读取缓存的 Blob,通过 URL.createObjectURL() 转为 Object URL 加载。瓦片下载器根据中心点经纬度、缩放级别范围和半径计算瓦片网格,批量 fetch 并缓存,实时报告进度。

储量估算三种算法:平行断面法沿钻孔主方向(X 或 Y)切平行剖面,每条剖面计算矿体截面积,相邻剖面间用截锥公式 V = (S1+S2+√(S1×S2))/3 × L 计算体积;地质块段法按钻孔位置分块段,每块用钻孔厚度 × 影响面积计算体积;算术平均法取全域平均厚度 × 总面积。三种算法共享品位阈值和密度参数,切换数据源时自动加载对应矿种的地层定义表。

全局数据流转:CustomProjectStore 作为单例对象,管理用户导入的项目列表。钻孔页面导入 CSV 时创建 SampleProjectInfo 并写入 Store;项目管理页面创建项目时同样写入 Store。建模 / 剖面 / 钻孔 / 储量四个页面的数据选择面板通过 CustomProjectStore.projects 读取列表,选中项目后调用各自的 loadDataProject 函数切换数据源。CustomProjectStore 还提供 inferStratumDefs 方法,从导入的钻孔数据中自动推断地层定义(按地层名去重、保留颜色映射)。

跨阶段算法迁移:产品的核心地质算法经历了三次技术栈迁移。Web 原型阶段用 JavaScript 实现了 IDW / Kriging / RBF 三种插值算法和平行断面法等储量计算逻辑,验证了算法正确性;鸿蒙端用 C++ 在 NAPI 层重新实现了同一套算法,积累了 C++ 地质算法引擎的经验;Android 端的 C++ 实现几乎原样复用了鸿蒙端的代码,只需适配 JNI 桥接层的接口差异。TRAE 在这个过程中展现了跨语言迁移能力——同一套算法逻辑,从 JavaScript 到 C++ 再到 Kotlin,TRAE 都能准确理解并转换。对我这个地质专业的学生来说,这等于用三种不同的编程语言把课堂上学到的算法理论各实现了一遍,每一遍都加深了对算法本身的理解。

社会价值分析

地质勘探行业的信息化程度参差不齐。大型矿山能负担 3DMine、Surpac 这些专业软件,但大量中小型矿山、勘探队伍和基层地质工作者缺乏可用的数字化工具。作为一名地质专业学生,我更关注的是教育层面的价值——GeoModel3D 把核心的建模和分析功能放到手机上,降低了学习和使用门槛:

• 高校地质教学:课堂演示三维地质建模过程,学生课后用自己的手机练习,不再受实验室授权电脑数量限制。我自己的同学试用了这个 App,反馈说比在实验室排队等 3DMine 直观得多

• 野外实习时,实时查看钻孔空间分布和地层信息,不用翻纸质资料,也不用等回学校才处理数据

• 小型矿山和勘探队伍用一部手机就能完成储量估算,不需要采购几十万的专业软件

• 支持 CSV 数据导入,用户可以使用自己的真实钻孔数据,学生也能用实习采集的数据做练习

• 降低了地质信息化的入门门槛:不是每个地质人都要学编程,但 TRAE 让有专业知识的地质人能把想法变成工具

产品迭代规划

14. 本地数据管理 — 支持 SQLite 持久化存储钻孔数据,CSV / Excel 导入导出,方便同学之间共享实习数据

15. 云端协同 — 多人共享项目数据,野外实习团队实时同步,导师也能远程查看

16. AI 辅助分析 — 基于钻孔数据自动推荐插值算法和参数配置,降低非地质专业用户的使用门槛

17. 更多矿种扩展 — 稀有金属、非金属矿的示例数据和地层定义,覆盖更多课程实验需求

18. 跨平台 — 基于 WebGL 的 Web 端版本,课堂演示不用安装 App,浏览器打开就能用