Mac 下使用 Homebrew 安装 Nginx 并发布 Cesium 地形与影像切片
在 Apple Silicon Mac 环境下,通过 Homebrew 安装 Nginx,并使用 Nginx 静态发布 Cesium 可访问的地形切片、影像切片等资源。
1. 文档说明#
适用场景:
- 发布 Cesium quantized-mesh 地形切片;
- 发布本地影像瓦片;
- 供本地 Vue / Cesium 前端项目访问;
- 解决 Cesium 访问本地切片时的跨域问题;
- 使用简单静态文件服务替代复杂 GIS 服务进行本地调试。
本文示例使用的本地资源根目录为:
bash/Volumes/Lenovo/xlgl/terrain/ # Cesium 地形切片目录,包含 layer.json 和 0/1/2... 等层级目录 /Volumes/Lenovo/xlgl/imagery/ # 影像切片目录,可选 如果当前阶段只发布 terrain 地形数据,则只需要保证以下目录存在: ```bash /Volumes/Lenovo/xlgl/terrain/
2. 安装 Nginx#
2.1 使用 Homebrew 安装#
在终端执行:
bashbrew install nginx
安装完成后,Homebrew 会输出类似信息:
bash==> Caveats Docroot is: /opt/homebrew/var/www The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that nginx can run without sudo. nginx will load all files in /opt/homebrew/etc/nginx/servers/. To start nginx now and restart at login: brew services start nginx Or, if you don't want/need a background service you can just run: /opt/homebrew/opt/nginx/bin/nginx -g daemon\ off\;
2.2 Homebrew Nginx 的关键路径#
Apple Silicon Mac 下,Homebrew 默认安装在:
bash/opt/homebrew
Nginx 相关路径通常如下:
bash/opt/homebrew/etc/nginx/nginx.conf # Nginx 主配置文件 /opt/homebrew/etc/nginx/servers/ # 自定义 server 配置目录 /opt/homebrew/var/www # 默认网站根目录 /opt/homebrew/opt/nginx/bin/nginx # Nginx 可执行文件
Homebrew 安装的 Nginx 默认监听端口一般为:
bash8080
这样做的好处是无需使用 sudo 即可启动 Nginx。
3. 准备 Cesium 切片目录#
调整后的本地磁盘目录结构如下:
bash/Volumes/Lenovo/xlgl/ ├── terrain/ │ ├── layer.json │ ├── 0/ │ ├── 1/ │ ├── 2/ │ └── ... │ └── imagery/ ├── 0/ ├── 1/ ├── 2/ └── ...
其中:
| 目录 | 说明 |
|---|---|
/Volumes/Lenovo/xlgl/terrain/ |
Cesium 地形切片目录 |
/Volumes/Lenovo/xlgl/terrain/layer.json |
Cesium 地形服务入口文件 |
/Volumes/Lenovo/xlgl/terrain/0/0/0.terrain |
quantized-mesh 地形切片示例 |
/Volumes/Lenovo/xlgl/imagery/ |
影像切片目录,可选 |
检查地形目录是否存在:
bashls /Volumes/Lenovo/xlgl/terrain/
至少应能看到:
bashlayer.json 0 1 2 ...
如果你的当前目录仍然是:
bash/Volumes/Lenovo/xlgl/terrain/xlgl/
可以先把里面的内容移动到上一层:
bashmv /Volumes/Lenovo/xlgl/terrain/xlgl/* /Volumes/Lenovo/xlgl/terrain/
确认移动完成后,可根据实际情况删除空目录:
bashrmdir /Volumes/Lenovo/xlgl/terrain/xlgl
影像目录如有同样情况,也可以调整:
bashmv /Volumes/Lenovo/xlgl/imagery/xlgl/* /Volumes/Lenovo/xlgl/imagery/ rmdir /Volumes/Lenovo/xlgl/imagery/xlgl
4. 新建 Nginx 配置文件#
4.1 创建配置文件#
Homebrew Nginx 会自动加载以下目录中的配置文件:
bash/opt/homebrew/etc/nginx/servers/
因此,新建一个 Cesium 切片服务配置文件:
bashnano $(brew --prefix)/etc/nginx/servers/cesium_tiles.conf
也可以直接使用完整路径:
bashnano /opt/homebrew/etc/nginx/servers/cesium_tiles.conf
5. Nginx 配置内容#
将下面内容写入:
bash/opt/homebrew/etc/nginx/servers/cesium_tiles.conf
完整配置如下:
nginxserver { listen 8080; server_name localhost; # 只发布 /Volumes/Lenovo/xlgl 下面的内容 # Nginx root 会将请求 URI 拼接到该目录后面 root /Volumes/Lenovo/xlgl; # terrain 根路径 location /terrain/ { autoindex off; add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always; } # quantized-mesh / .terrain 文件 location ~ ^/terrain/.*\.terrain$ { default_type application/octet-stream; # Cesium quantized-mesh 地形切片通常是 gzip 编码 add_header Content-Encoding gzip always; add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always; } # layer.json location ~ ^/terrain/.*layer\.json$ { default_type application/json; add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always; } # 影像切片,可选 location /imagery/ { autoindex off; add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always; } # 可选:处理浏览器预检请求 if ($request_method = OPTIONS) { return 204; } }
6. root 路径映射说明#
本配置使用的是:
nginxroot /Volumes/Lenovo/xlgl;
在 Nginx 中,root 的作用是将请求 URI 直接拼接到 root 指定的目录后面。
也就是说:
text磁盘根目录 + 请求 URI = 实际文件路径
6.1 layer.json 映射关系#
请求地址:
texthttp://localhost:8080/terrain/layer.json
实际访问文件:
bash/Volumes/Lenovo/xlgl/terrain/layer.json
6.2 terrain 文件映射关系#
请求地址:
texthttp://localhost:8080/terrain/0/0/0.terrain
实际访问文件:
bash/Volumes/Lenovo/xlgl/terrain/0/0/0.terrain
6.3 影像切片映射关系#
如果存在影像切片:
bash/Volumes/Lenovo/xlgl/imagery/
则请求地址类似:
texthttp://localhost:8080/imagery/0/0/0.png
实际访问文件:
bash/Volumes/Lenovo/xlgl/imagery/0/0/0.png
7. root 与 alias 的区别说明#
当前配置使用 root,原因是 URL 路径和磁盘目录结构一致。
例如:
textURL: /terrain/layer.json 磁盘: /Volumes/Lenovo/xlgl/terrain/layer.json
这种情况下,使用 root 最简单。
如果 URL 路径和磁盘路径不一致,例如希望:
texthttp://localhost:8080/terrain/
映射到:
bash/Volumes/Lenovo/xlgl/terrain_data/
此时才更适合使用 alias。
当前不需要使用 alias。
8. 检查 Nginx 配置是否正确#
保存配置后,执行:
bashnginx -t
如果提示:
bashnginx: the configuration file /opt/homebrew/etc/nginx/nginx.conf syntax is ok nginx: configuration file /opt/homebrew/etc/nginx/nginx.conf test is successful
说明配置语法正确。
如果命令找不到,可以使用完整路径:
bash/opt/homebrew/opt/nginx/bin/nginx -t
9. 启动 Nginx#
9.1 使用 Homebrew 服务方式启动#
推荐方式:
bashbrew services start nginx
启动后,Nginx 会作为后台服务运行,并在系统登录后自动启动。
9.2 重启 Nginx#
修改配置后,需要重启 Nginx:
bashbrew services restart nginx
9.3 停止 Nginx#
bashbrew services stop nginx
9.4 前台运行方式#
如果不希望作为后台服务运行,也可以使用:
bash/opt/homebrew/opt/nginx/bin/nginx -g 'daemon off;'
10. 测试访问#
10.1 测试 layer.json#
在浏览器中访问:
texthttp://localhost:8080/terrain/layer.json
如果能看到 JSON 内容,说明地形服务入口文件可以访问。
也可以使用 curl 测试:
bashcurl -I http://localhost:8080/terrain/layer.json
正常情况下应返回类似:
textHTTP/1.1 200 OK Content-Type: application/json Access-Control-Allow-Origin: *
10.2 测试 terrain 文件#
访问:
texthttp://localhost:8080/terrain/0/0/0.terrain
或使用:
bashcurl -I http://localhost:8080/terrain/0/0/0.terrain
正常情况下应包含:
textHTTP/1.1 200 OK Content-Type: application/octet-stream Content-Encoding: gzip Access-Control-Allow-Origin: *
10.3 测试影像切片#
如果配置了影像切片,可以访问:
texthttp://localhost:8080/imagery/0/0/0.png
实际路径对应:
bash/Volumes/Lenovo/xlgl/imagery/0/0/0.png
11. Cesium 前端调用示例#
11.1 加载 Cesium 地形#
在 Cesium 中可以这样加载:
javascriptconst viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider: await Cesium.CesiumTerrainProvider.fromUrl( "http://localhost:8080/terrain/" ) });
如果你的 Cesium 版本较旧,也可能使用:
javascriptconst terrainProvider = new Cesium.CesiumTerrainProvider({ url: "http://localhost:8080/terrain/" }); const viewer = new Cesium.Viewer("cesiumContainer", { terrainProvider });
11.2 加载本地影像切片#
如果影像切片是 XYZ 结构,可以使用:
javascriptconst imageryProvider = new Cesium.UrlTemplateImageryProvider({ url: "http://localhost:8080/imagery/{z}/{x}/{y}.png" }); viewer.imageryLayers.addImageryProvider(imageryProvider);
具体 {z}/{x}/{y} 是否正确,需要根据实际切片目录结构确定。
12. 常见问题处理#
12.1 访问 layer.json 返回 404#
检查文件是否真实存在:
bashls /Volumes/Lenovo/xlgl/terrain/layer.json
如果不存在,说明地形目录路径不正确。
同时确认 Nginx 配置中的 root 是否为:
nginxroot /Volumes/Lenovo/xlgl;
12.2 访问 terrain 文件返回 404#
检查示例切片是否存在:
bashls /Volumes/Lenovo/xlgl/terrain/0/0/0.terrain
如果不存在,查看真实的地形切片层级结构,例如:
bashfind /Volumes/Lenovo/xlgl/terrain -name "*.terrain" | head
根据实际结果调整访问地址。
12.3 Cesium 报跨域错误#
确保配置中包含:
nginxadd_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods "GET, OPTIONS" always; add_header Access-Control-Allow-Headers "*" always;
修改配置后执行:
bashnginx -t brew services restart nginx
12.4 Cesium 地形无法正常解析#
重点检查 .terrain 文件是否返回了:
textContent-Encoding: gzip
对应 Nginx 配置为:
nginxlocation ~ ^/terrain/.*\.terrain$ { default_type application/octet-stream; add_header Content-Encoding gzip always; }
如果你的 .terrain 文件本身不是 gzip 编码,则不能强制添加:
nginxadd_header Content-Encoding gzip always;
但 Cesium quantized-mesh 地形切片多数情况下是 gzip 编码的,需要该响应头。
12.5 8080 端口被占用#
检查端口占用:
bashlsof -i :8080
如果已有其他服务占用,可以修改配置中的端口,例如改为:
nginxlisten 8090;
然后重启:
bashnginx -t brew services restart nginx
访问地址也相应改为:
texthttp://localhost:8090/terrain/layer.json
12.6 配置修改后不生效#
执行:
bashnginx -t brew services restart nginx
如果仍不生效,可以查看当前 Nginx 是否由 Homebrew 启动:
bashbrew services list
13. 推荐最终目录结构#
建议最终目录结构保持清晰,便于后续扩展:
bash/Volumes/Lenovo/xlgl/ ├── terrain/ │ ├── layer.json │ ├── 0/ │ ├── 1/ │ ├── 2/ │ └── ... │ ├── imagery/ │ ├── 0/ │ ├── 1/ │ ├── 2/ │ └── ... │ ├── vector/ │ └── ... │ └── docs/ └── ...
Nginx 配置文件:
bash/opt/homebrew/etc/nginx/servers/cesium_tiles.conf
14. 最终访问地址汇总#
| 类型 | URL |
|---|---|
| 地形 layer.json | http://localhost:8080/terrain/layer.json |
| 地形服务根地址 | http://localhost:8080/terrain/ |
| terrain 示例切片 | http://localhost:8080/terrain/0/0/0.terrain |
| 影像切片根地址 | http://localhost:8080/imagery/ |
| 影像切片示例 | http://localhost:8080/imagery/0/0/0.png |
15. 完整操作命令汇总#
bash# 1. 安装 Nginx brew install nginx # 2. 创建 Nginx server 配置目录,通常已存在 mkdir -p $(brew --prefix)/etc/nginx/servers # 3. 新建 Cesium 切片配置文件 nano $(brew --prefix)/etc/nginx/servers/cesium_tiles.conf # 4. 检查配置 nginx -t # 5. 启动 Nginx brew services start nginx # 6. 修改配置后重启 brew services restart nginx # 7. 测试 layer.json curl -I http://localhost:8080/terrain/layer.json # 8. 测试 terrain 文件 curl -I http://localhost:8080/terrain/0/0/0.terrain
16. 当前配置结论#
当前配置适合本地 Cesium 地形和影像切片调试。
核心点如下:
- 使用 Homebrew 安装 Nginx;
- 使用
/opt/homebrew/etc/nginx/servers/cesium_tiles.conf管理自定义配置; - 使用
root /Volumes/Lenovo/xlgl;保持 URL 与磁盘目录结构一致; - 地形访问地址为:
texthttp://localhost:8080/terrain/
layer.json实际映射到:
bash/Volumes/Lenovo/xlgl/terrain/layer.json
.terrain文件需要正确设置:
nginxContent-Encoding: gzip
- 所有 Cesium 资源路径均添加 CORS 响应头,方便前端项目直接访问;