外业数据库
需求:
- 自建类似谷歌地球的微型服务器:用于管理、展示空间数据(如无人机影像);
- 将无人机照片 + RTK 点位等外业数据统一管理和展示:方便查看、浏览与组织外业成果。
工作流程
- 外业采集阶段:
- 使用 RTK 采集点位 + 拍摄无人机照片(包含 EXIF GPS);
- 同步照片、日志、点位文件(如 CSV/GPX/GeoJSON);
- 数据处理阶段:
- 使用 WebODM 或 ODM 处理照片,输出正射图 / DSM / 点云;
- 将 RTK 点位导入 PostGIS,统一坐标系统,加入属性信息;
- 将生成的栅格图层(GeoTIFF)发布到 GeoServer;
- 可视化展示阶段:
- 搭建 CesiumJS 页面或部署 TerriaMap;
- 加载你发布的图层与点位,实现 Google Earth 类的展示体验;
- 如果有拍摄照片的缩略图,也可以点击点位弹出原图(Pop-up);
WebODM + Cesium
功能与环境
能将无人机影像处理成果(正射影像、点云、DSM、RTK点)以 Google Earth 类方式展示。
在本地搭建 WebODM(用于无人机影像处理);
使用 CesiumJS 加载并三维展示处理成果(正射影像、DSM、高程、RTK点位);
整体构建一个类似 Google Earth 的微型数据管理和展示平台。
🖥️ 服务器系统
- 操作系统:Debian +**
- 内存推荐:≥16GB(大图像处理消耗资源)
- 安装路径:建议统一放在
~/uav-platform/
Part 1: 安装 WebODM
(无人机影像处理平台)
使用官方 Docker 版本(推荐)
# 1. 安装 Docker
# https://docs.docker.com/engine/install/ubuntu/
# 2. 克隆 WebODM
git clone https://github.com/OpenDroneMap/WebODM.git
cd WebODM
# 3. 启动 WebODM(首次运行会下载大量依赖)
./webodm.sh start
👉 默认会在本地运行 http://localhost:8000
手动安装 Docker Compose v2
错误
./webodm.sh start
Checking for docker... OK
Checking for docker compose... not found, we'll attempt to install it
##################### 19.2%curl: (92) HTTP/2 stream 1 was not closed cleanly: PROTOCOL_ERROR (err 1)
🔍 步骤 1:确认 Docker 版本
docker --version
Docker 版本 ≥ 20.10 支持集成的 docker compose 子命令。
然后确认是否已有 Compose:
docker compose version
如果你得到 docker: 'compose' is not a docker command.,说明未安装 compose 插件。
🧩 步骤 2:安装 Docker Compose 插件
✅ 对于 Linux(Ubuntu、WSL2)
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.24.2/docker-compose-linux-x86_64 \
-o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
然后确认安装成功:
docker compose version
🔒如果你被防火墙或代理限制了 GitHub 下载,可以用以下国内镜像地址:
https://ghproxy.com/https://github.com/docker/compose/releases/download/...
🧪 步骤 3:重新启动 WebODM
cd WebODM
./webodm.sh start
此时应该不再尝试 curl 安装 compose,系统也能正确启动 WebODM 容器。
docker compose -f docker-compose.yml -f docker-compose.nodeodm.yml up --scale node-odm=1
[+] Running 5/5
✘ broker Error 15.9s
✘ node-odm Error 15.9s
✘ db Error 15.9s
✘ worker Error 15.9s
✘ webapp Error 15.9s
Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
使用代理访问 Docker Hub
如果你使用的是单位/校园网络,Docker 无法访问外网,可以使用代理转发:
1. 设置系统 HTTP 代理:
编辑 Docker 的 systemd 服务文件:
bash复制编辑sudo mkdir -p /etc/systemd/system/docker.service.d sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf填入你的代理地址:
ini复制编辑[Service] Environment="HTTP_PROXY=http://127.0.0.1:7890" Environment="HTTPS_PROXY=http://127.0.0.1:7890"然后执行:
sudo systemctl daemon-reexec sudo systemctl daemon-reload sudo systemctl restart docker你也可以在运行
webodm.sh start时设置环境变量:HTTP_PROXY=http://127.0.0.1:7890 ./webodm.sh start
📁 成果数据结构
- 处理成果通常包括:
odm_orthophoto/odm_orthophoto.tif(正射影像)odm_georeferencing/odm_georeferenced_model.laz(点云)odm_texturing/odm_textured_model.obj(三维模型)
Part 2: 安装 CesiumJS
(前端三维展示平台)
本地 Node.js + Cesium
# 安装 Node.js(推荐用 nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
source ~/.bashrc
nvm install --lts
# 创建 Cesium 项目
mkdir ~/cesium-demo && cd ~/cesium-demo
npm init -y
npm install cesium
添加基本项目结构
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>海洋工程环境观测技术学科外业</title>
<!-- 引入 Cesium 样式与主库 -->
<script src="Cesium/Build/Cesium/Cesium.js"></script>
<link href="Cesium/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<!-- 自定义样式 -->
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<!-- Cesium 容器 -->
<div id="cesiumContainer" style="width: 100%; height: 100vh;"></div>
<!-- 设置 Cesium Ion Access Token
<script>
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxYjkzZWRlYi0zMGMwLTQzMjAtOTY1Ny0wMjY0Y2EwNTNjZmUiLCJpZCI6MzI2MzU0LCJpYXQiOjE3NTM3NTE0NjV9.VlmifFkdXPWiZxhWhboqQuubajCj1rRwRVF-uAzkNzYn8';
</script>
-->
<!-- 加载主应用逻辑 -->
<script src="js/app.js"></script>
</body>
</html>
CesiumTerrainProvider问题
从 CesiumJS v1.83 开始,createWorldTerrain() 被移到了 Cesium.Terrain 命名空间下,在新版打包方式中如果你直接加载 Build/Cesium/Cesium.js,默认不会带上 createWorldTerrain() 方法,除非你明确打包 Terrain.js 模块,如terrainProvider: new Cesium.CesiumTerrainProvider({ url: Cesium.IonResource.fromAssetId(1) // 世界地形(Cesium World Terrain)AssetId = 1
✅ 最简单修复方式
请将 terrainProvider 行替换成如下代码:
const viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider: new Cesium.CesiumTerrainProvider({
url: Cesium.IonResource.fromAssetId(1) // 世界地形(Cesium World Terrain)AssetId = 1
}),
imageryProvider: new Cesium.UrlTemplateImageryProvider({
url: './data/ortho.tms/{z}/{x}/{y}.png',
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 20
}),
baseLayerPicker: false
});
这行代码将直接用 CesiumTerrainProvider 手动加载 Cesium Ion 上的世界地形(无需 createWorldTerrain())。
局域网访问
启动服务器
绑定到局域网 IP(不是 127.0.0.1)
以最常见的开发方式举例:
👉 Python(推荐,轻量):
cd your_project_folder
python -m http.server 8000 --bind 0.0.0.0
然后在其他设备浏览器访问:
http://192.168.1.100:8000
👉 Node.js(http-server):
npm install -g http-server
http-server -p 8000 -a 0.0.0.0
然后其他设备访问 http://<你电脑IP>:端口
如果局域网打不开
step1. 查看是否启用了防火墙
sudo ufw status
如果看到是 inactive,说明没启用。
如果启用,请添加规则:
sudo ufw allow 7101/tcp
step 2:确认网络连接
- 在服务器上运行:
curl http://localhost:7101
- 然后在 局域网中另一台电脑打开浏览器:
http://<服务器局域网IP>:7101
例如:
http://192.168.1.10:7101
如果能访问说明配置成功。
如你还想让公网用户也能访问,还需:
- 有公网 IP(或者配置内网穿透工具如 frp/ngrok)。
- 路由器开放端口并设置端口映射。
- 可使用域名绑定(可选)。
总结
1. 项目结构
├── Cesium
│ ├── Apps
│ ├── Build
│ ├── Cesium-1.131.zip
│ ├── CHANGES.md
│ ├── eslint.config.js
│ ├── favicon.ico
│ ├── gulpfile.js
│ ├── index.cjs
│ ├── index.html
│ ├── LICENSE.md
│ ├── package.json
│ ├── packages
│ ├── README.md
│ ├── scripts
│ ├── server.js
│ ├── Source
│ ├── Specs
│ ├── ThirdParty
│ └── web.config
├── css
│ └── style.css
├── data
│ └── rtk_points.geojson
├── index.html
└── js
├── app.js
├── app.js.old
├── app.js.old1
└── app.js.old2
2. index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>海洋工程环境观测技术学科外业</title>
<!-- 引入 Cesium 样式与主库 -->
<script src="Cesium/Build/Cesium/Cesium.js"></script>
<link href="Cesium/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
<!-- 自定义样式 -->
<link href="css/style.css" rel="stylesheet">
</head>
<body>
<!-- Cesium 容器 -->
<div id="cesiumContainer" style="width: 100%; height: 100vh;"></div>
<!-- 设置 Cesium Ion Access Token
<script>
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIxYjkzZWRlYi0zMGMwLTQzMjAtOTY1Ny0wMjY0Y2EwNTNjZmUiLCJpZCI6MzI2MzU0LCJpYXQiOjE3NTM3NTE0NjV9.VlmifFkdXPWiZxhWhboqQuubajCj1rRwRVF-uAzkNzYn8';
</script>
-->
<!-- 加载主应用逻辑 -->
<script src="js/app.js"></script>
</body>
</html>
3. app.js
// 创建 Cesium Viewer,设置 ESRI World Imagery 为基础图层
const viewer = new Cesium.Viewer('cesiumContainer', {
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
}),
// terrainProvider: new Cesium.CesiumTerrainProvider(),
// baseLayerPicker: false
});
// 加载本地 ortho.tms 影像图层(叠加图层)
const orthoLayer = new Cesium.ImageryLayer(
new Cesium.UrlTemplateImageryProvider({
url: './data/ortho.tms/{z}/{x}/{y}.png',
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 20
})
);
viewer.imageryLayers.add(orthoLayer); // 添加为覆盖层
// 加载 GeoJSON 数据并飞行至数据区域
Cesium.GeoJsonDataSource.load('./data/rtk_points.geojson', {
markerSize: 20,
stroke: Cesium.Color.YELLOW,
fill: Cesium.Color.CYAN.withAlpha(0.6)
}).then(dataSource => {
viewer.dataSources.add(dataSource);
viewer.flyTo(dataSource);
});
// 修复 Home 按钮不能飞到全球视图的问题
viewer.scene.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(0.0, 20.0, 20000000.0) // 初始视角设为全球
});
4. rtk_points.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": { "name": "RTK点1" },
"geometry": {
"type": "Point",
"coordinates": [110.3401, 18.2512]
}
},
{
"type": "Feature",
"properties": { "name": "RTK点2" },
"geometry": {
"type": "Point",
"coordinates": [110.3420, 18.2520]
}
}
]
}
5. 启动服务
python
python3 -m http.server 71001 --bind 0.0.0.0
npm
sudo npm install -g http-server
http-server -p 71001 -a 0.0.0.0
6. 网络访问
本地访问
localhost:71001
局域网访问
192.168.0.100:71001
外网访问:使用 FRP + 自有 VPS + 自定义域名
🧱 网络结构示意图
公网用户 → yourdomain.com:7101
↓
[公网 VPS:frps]
↓
[家庭内网服务器:frpc → 127.0.0.1:7101]
🛠️ 配置步骤详解
✅ 第一步:准备工作
- 确认 VPS 开放端口:
- 确保你的 VPS 可以开放如
7101、7000、7500(frps监听端口) - 如果有防火墙(如 ufw 或云服务安全组),请放行这些端口
- 确保你的 VPS 可以开放如
- 购买或已有域名(如 yourdomain.com),并在 DNS 提供商(如 Cloudflare)处控制解析
✅ 第二步:VPS 端部署 frps(服务端)
- 安装 frp
cd ~
wget https://github.com/fatedier/frp/releases/download/v0.58.0/frp_0.58.0_linux_amd64.tar.gz
tar -xzf frp_0.58.0_linux_amd64.tar.gz
cd frp_0.58.0_linux_amd64
- 编辑
frps.ini
[common]
bind_port = 7000 # FRP通信端口
dashboard_port = 7500 # 控制面板(可选)
dashboard_user = admin # 控制台账号
dashboard_pwd = admin
vhost_http_port = 8080 # 若要穿透 HTTP 服务
vhost_https_port = 8443 # 可用于 HTTPS
- 启动 frps
./frps -c frps.ini
✅ 建议设置为 systemd 服务,保持开机自启(我可帮你写好 .service 文件)
✅ 第三步:内网客户端部署 frpc
你的家庭服务器(局域网那台)上部署客户端。
- 下载 frp 同版本
去 https://github.com/fatedier/frp/releases 下载对应操作系统版本。
- 编辑
frpc.ini
[common]
server_addr = <你的VPS公网IP>
server_port = 7000
[my-http]
type = http
local_ip = 127.0.0.1
local_port = 7101
custom_domains = my.yourdomain.com
你也可以用 tcp:
[my-tcp]
type = tcp
local_ip = 127.0.0.1
local_port = 7101
remote_port = 7101
- 启动 frpc
./frpc -c frpc.ini
✅ 第四步:域名绑定与 DNS 设置
- 登录你的 DNS 服务提供商(如 Cloudflare)
- 添加一条 A 记录:
| 类型 | 主机记录(名称) | 内容 | 代理状态 |
|---|---|---|---|
| A | my |
<VPS公网IP> |
关闭(灰色云朵) |
- 等 DNS 生效后,可以访问:
http://my.yourdomain.com # 如果用 HTTP 类型穿透
或
http://<VPS_IP>:7101 # 如果用 TCP 端口穿透
🛡️ 安全建议
- 使用域名 + HTTPS:可通过 Nginx + Let’s Encrypt 部署反向代理
- frps 设置密码认证和 TLS
- VPS 设置防火墙,仅开放必要端口
Part 3: WebODM 导入 Cesium
将无人机拍摄的 GeoTIFF 文件转换为 Cesium 可加载的瓦片形式({z}/{x}/{y}.png 结构):
0. 准备工具环境
你需要以下工具支持:
| 工具 | 说明 |
|---|---|
| GDAL | 用于地理数据转换,支持 gdal2tiles.py 工具 |
| Node.js + Express | 启动静态瓦片服务(你项目已具备) |
| GeoTIFF 文件 | 无人机拍摄的 .tif 文件(需带地理参考) |
使用 gdalwarp 进行投影转换
确实正确!在将 .tif 影像切片为瓦片前,必须确保其为 Web Mercator 投影(EPSG:3857),这也是在线地图(如Cesium、Google Maps等)使用的标准投影系统。
1. 完整流程说明
- 原始
.tif为 CGCS2000 投影(如 EPSG:4490) - 使用
gdalwarp进行重投影为 Web Mercator(EPSG:3857) - 用
gdal2tiles.py将其切片为{z}/{x}/{y}.png瓦片 - 通过本地服务器发布该瓦片目录
data/fie1.tms/ - 在 Cesium 中用
UrlTemplateImageryProvider加载
2. 投影及其转换
使用 gdalwarp 进行投影转换
gdalwarp -t_srs EPSG:3857 -r bilinear -of GTiff -co COMPRESS=DEFLATE -co TILED=YES result.tif result_3857.tif
| 参数 | 说明 |
|---|---|
-t_srs EPSG:3857 |
目标投影是 Web Mercator |
-r bilinear |
重采样方式 |
-co TILED=YES |
输出更适合瓦片切割 |
| 输出文件为 `result_3857.tif |
常用 EPSG代码:
| 名称 | 代码 | 意义 | 基准面 |
|---|---|---|---|
| WGS 84 (World Geodetic System 1984) | EPSG:4326 | 使用经纬度表示 (longitude, latitude)。GPS、国际地图服务(如Google Earth)、Web前端地图库(Leaflet, OpenLayers)的基础坐标系。 |
全球通用坐标系(大地基准面) |
| Web Mercator / Pseudo-Mercator | EPSG:3857 | 基于WGS 84的球形墨卡托投影。单位为米。几乎所有在线地图切片服务(Google Maps, OpenStreetMap, Bing Maps, Mapbox, ArcGIS Online)使用的标准投影。用于地图可视化。 | 全球通用坐标系(大地基准面) |
| CGCS2000 (China Geodetic Coordinate System 2000) | EPSG:4490 | 使用经纬度表示 (longitude, latitude)。中国国家大地坐标系,2000国家大地坐标系。国内测绘和GIS项目的官方标准基准面。 |
中国常用坐标系(大地基准面) |
| EPSG:4479 | CGCS2000 的3D版本(包含椭球高) | … | |
| 注意:CGCS2000与WGS84在定义和实现上非常接近,但在中国境内进行高精度测量和法定测绘时,必须使用CGCS2000。 | …. | ||
| UTM (Universal Transverse Mercator) Zones - WGS84 | EPSG:326XX | 北半球UTM带(XX为带号) | 投影坐标系(Projected - 单位为米) |
| EPSG:32650 | WGS84 / UTM zone 50N (东经114°-120°) | 投影坐标系 | |
| EPSG:32651 | WGS84 / UTM zone 51N (东经120°-126°) (覆盖中国东部大部分地区) | 投影坐标系 | |
| UTM Zones - CGCS2000 | EPSG:449X | CGCS2000的UTM投影正在逐步标准化,具体代码需查表。常见做法是先使用CGCS2000地理坐标系(4490),再进行投影转换。 | 投影坐标系 |
| Gauss-Kruger (GK) / Transverse Mercator Zones - CGCS2000 (3°带) | EPSG:451X | 中国官方定义的CGCS2000高斯-克吕格投影分带(3度带) | 投影坐标系 |
| EPSG:4513 | CGCS2000 / 3-degree Gauss-Kruger CM 75E (中央经线75°E) | 投影坐标系 | |
| EPSG:4514 | CGCS2000 / 3-degree Gauss-Kruger CM 78E | 投影坐标系 | |
| EPSG:4522 | CGCS2000 / 3-degree Gauss-Kruger CM 135E | 投影坐标系 | |
| 国内地形图、工程测量常用投影) | 投影坐标系 | ||
| Albers Equal Area Conic (China) | 102025 (非官方但常用) 或 CGCS2000/Albers | 中国全境或区域使用的等积圆锥投影,适合面积量算分析。标准参数(双标准纬线25°N, 47°N,中央经线105°E,原点0°N)。 | 投影坐标系 |
| EGM2008 geoid | EPSG:3855 | 全球重力大地水准面模型。用于将WGS84椭球高转换为近似海拔高(正高) | 垂向基准 |
| Yellow Sea 1985 | EPSG:5730 | 中国常用的高程基准(验潮站平均海平面定义)。用于表示海拔高。 | 垂向基准 |
EPSG 选择依据
| 使用场景 | 首选EPSG代码 | 备注 |
|---|---|---|
| 全球数据交换/GPS | 4326 (WGS84地理) |
通用标准 |
| Web地图显示 | 3857 (Web墨卡托) |
在线地图标准 |
| 中国法定测绘/GIS | 4490 (CGCS2000地理) |
国家基准面 |
| 中国地形图/工程图(投影) | 451X系列 (CGCS2000/GK) |
如4518(中央经线111°E) |
| 中国区域面积分析 | 102025 (Albers中国) |
需确认具体定义 |
| 国内在线地图(实际坐标) | GCJ-02/BD-09 | 非标!需用专门SDK转换 |
| 海拔高程 | 5730 (黄海85) 或 3855 |
国内用5730,全球近似用3855 |
重要提示:
- 转换是关键: 不同坐标系间转换需使用精确参数和可靠软件(如PROJ库、ArcGIS、QGIS、GDAL)。简单平移旋转无法满足精度要求。
- 中国特殊性: 国内数据处理务必注意GCJ-02/BD-09偏移问题。公开地图服务返回的坐标通常已偏移。
- 查证来源: 遇到不熟悉的EPSG代码,使用 epsg.io 网站查询详细定义。
- CGCS2000优先: 在中国进行新项目,强烈推荐使用CGCS2000 (
4490或投影451X)作为基准。
3. 将 GeoTIFF 切片为 Web 瓦片(XYZ 瓦片)
使用 gdal2tiles.py 命令将 GeoTIFF 切为 {z}/{x}/{y}.png 的标准 XYZ 结构:
gdal2tiles.py -z 0-18 -r bilinear -w none path/to/your_image.tif path/to/output_tiles/
例如:
gdal2tiles.py -z 0-18 -r bilinear -w none --processes=4 reproj_3857.tif ../repo/cesium-dem/data/dan3.tms
参数解释:
| 参数 | 说明 |
|---|---|
-z 0-18 |
生成 0 到 18 级的瓦片(等级越大越清晰) |
-r bilinear |
使用双线性插值(也可换成 near、cubic) |
-w none |
不生成 HTML 或 Google Maps 示例 |
| –processes=4 | 加快切片速度 |
path/to/your_image.tif |
原始无人机 GeoTIFF 文件路径 |
path/to/output_tiles/ |
输出的瓦片文件夹路径(例如 public/uploads/tiles) |
转换成功后,会生成如下结构:
output_tiles/
├── 0/
│ └── 0/
│ └── 0.png
├── 1/
│ └── 0/
│ └── 0.png
├── ...
└── 18/
└── ...
使用 gdal2tiles.py 将 GeoTIFF (result.tif) 转换为了 Web Mercator 格式的瓦片,并在本地生成了一个标准的 {z}/{x}/{y}.png 结构。这是展示无人机影像在 Cesium 中的标准方式之一。
但是 Cesium 默认采用的是 Google Maps / XYZ 瓦片格式(右上角为原点)。
关键:调整为 XYZ 格式
在使用 gdal2tiles.py 时增加 --xyz 参数:
gdal2tiles.py --xyz -z 0-18 -r bilinear -w none result.tif ../output_tiles/
这样生成的瓦片就是 Cesium 兼容的 {z}/{x}/{y}.png 结构(XYZ格式,右上角为原点)。
4. 前端 Cesium 中加载瓦片
// 加载本地 dan1.tms 影像图层(叠加图层)
const orthoProvider = new Cesium.UrlTemplateImageryProvider({
url: './data/dan1.tms/{z}/{x}/{y}.png',
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 18,
credit: "Drone Imagery"
});
const orthoLayer = new Cesium.ImageryLayer(orthoProvider);
viewer.imageryLayers.add(orthoLayer); // add dan1
// 加载 dan3.tif 转换的瓦片
const dan3Provider = new Cesium.UrlTemplateImageryProvider({
url: "./data/dan3.tms/{z}/{x}/{y}.png",
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 18,
credit: "Haian Imagery"
});
const dan3Layer = new Cesium.ImageryLayer(dan3Provider);
viewer.imageryLayers.add(dan3Layer); // add dan3
确保你已经在 .tif 切片时提供了 maximumLevel: 18 等级。
5.常见问题排查
| 问题 | 原因 | 解决方式 |
|---|---|---|
| 瓦片不显示 | 没有地理参考 | 用 gdalinfo your.tif 检查投影坐标系统 |
| 加载偏移或坐标不对 | 不是 Web Mercator 投影 | 使用 gdalwarp 先转为 EPSG:3857 |
| Cesium 加载报错 | 路径错误或跨域 | 确保路径、端口、CORS 设置正确 |
可选:提前投影为 Web Mercator
gdalwarp -t_srs EPSG:3857 input.tif warped.tif
点云 / 三维模型(可选)
- WebODM 生成的
.obj可以使用 obj2gltf 转换为.gltf,Cesium 原生支持。
npm install -g obj2gltf
obj2gltf -i odm_texturing/odm_textured_model.obj -o model.gltf
然后用以下方式加载:
viewer.scene.primitives.add(
Cesium.Model.fromGltf({
url: "./model.gltf",
modelMatrix: Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(110.311, 18.311, 10)
),
scale: 1.0,
})
);







