iTowns:在 Web 端构建专业级 GIS 和 3D 地图应用

如果你曾经尝试过用 Web 技术做地图应用,你一定知道这有多难。地理数据格式五花八门、投影坐标系统复杂、还要处理大规模矢量数据的渲染……最后往往要么自己从头造轮子,要么被迫依赖一些商业 GIS 库。

iTowns 就是为了解决这个问题而生的。它是一个开源框架,让你用 JavaScript/WebGL 的方式就能构建专业级的 3D 地图和地理信息系统应用。不管你是做城市规划、地产展示,还是需要展示卫星影像和地形数据,iTowns 都能胜任。

什么是 iTowns

一句话说:一个基于 Three.js 的 Web GIS 框架,专为 3D 地理空间数据可视化设计

它由法国 IGN(国家地理信息研究所)的 MATIS 实验室开发,已经在多个商业项目中验证过。1.2k stars、51+ 贡献者、3000+ 次提交,这个数字说明它不是一个玩具项目。

核心特点:

  • 基于 Three.js,所以你用的还是熟悉的 WebGL 生态
  • 原生支持 WMS/WMTS 标准地图服务(这是 GIS 行业的标准协议)
  • 支持多种数据格式:3D Tiles、矢量切片、点云(Potree/COPC)、Geotiff、GeoJSON 等
  • 两种视图模式:全球球形视角和局部平面投影
  • 双开源许可证(CECILL-B V1.0 和 MIT),适应不同项目需求

能做什么

球形地球和平面地图切换

很多 GIS 应用需要在全球视图和局部投影坐标系之间切换。比如城市规划部门需要看全国范围的规划图,也需要放大查看某个城区的细节——这两种坐标系是不一样的。iTowns 内置了这两种视图模式,切换时数据自动适配,不用你手动处理坐标转换。

加载企业级地图数据

如果你的组织已经有了 WMS/WMTS 地图服务(很多政府部门和大型企业都有),iTowns 可以直接连接。不用自己写协议解析,不用转换数据格式,配置好服务地址就能用。这对于集成现有 GIS 基础设施来说,节省了大量工作量。

处理复杂数据格式

地理数据的格式林林总总:栅格数据(卫星影像、DEM 数字高程模型)、矢量数据(建筑物、道路边界)、点云(激光扫描的三维点阵)。很多开发者的做法是每种格式用一个库,整个项目依赖一大堆。iTowns 在一个框架里就能处理这些,减少了依赖复杂度。

大规模矢量数据渲染

想象一个应用要展示一个城市的所有建筑物轮廓,可能有几十万个多边形。直接渲染会卡。iTowns 内置了矢量切片支持——它会自动按缩放级别加载不同细节等级的数据,只渲染当前视口内的对象。这就是为什么 Google Maps 能在浏览器里流畅地展示全球数据。

点云和 3D 模型

如果你有激光扫描或无人机采集的点云数据(COPC、EPT 格式),或者 3D Tiles 格式的建筑模型,iTowns 都能渲染。用于城市规划、建筑设计、遗产保护这些领域都很常见。

怎么用

安装

npm install --save itowns

或者本地开发的话:

git clone https://github.com/itowns/itowns.git
cd itowns
npm install
npm start

运行后访问 http://localhost:8080/ (opens in a new tab)

快速开始:创建一个球形地球视图

最简单的例子是创建一个可以交互的地球:

import { GlobeView, Extent } from 'itowns';
 
// 1. 创建一个容器(HTML 中需要有 id="viewerDiv" 的 div)
const viewerDiv = document.getElementById('viewerDiv');
 
// 2. 初始化地球视图
const view = new GlobeView(viewerDiv, {
  // 相机初始位置
  position: new Coordinates('EPSG:4326', 2.3, 48.86, 25000000),
});
 
// 3. 加载底图数据(这里用的是 OpenStreetMap 的 WMTS 服务)
const layer = new WMTSSource({
  url: 'https://a.tile.openstreetmap.org/${z}/${x}/${y}.png',
  projection: 'EPSG:3857',
});
 
view.addLayer(layer);

这段代码做了什么:

  • 第 2 步创建了一个地球对象,并设置了初始摄像机位置(巴黎附近,高度 2500 万米)
  • 第 3-5 步加载了 OpenStreetMap 的瓦片数据作为底图
  • 用户可以用鼠标拖拽旋转地球、滚轮缩放

加载高程数据

如果你想要山峰的起伏效果,需要加载高程数据(Digital Elevation Model):

// 加载 SRTM 高程数据(全球免费的高程数据源)
const dem = new WMTSSource({
  url: 'https://services.ign.fr/wxs/xxx/alti/wmts?REQUEST=GetTile&...',
  format: 'image/geotiff',
});
 
view.addLayer(dem, { isElevationLayer: true });

加上这个之后,地球表面就不再是光滑的球面,而是真实的地形起伏。

平面视图模式

如果你要做的是城市层面的应用(比如城市规划、地产展示),用平面视图更合适。这时用局部投影坐标系而非全球坐标系:

const view = new PlanarView(viewerDiv, {
  // 使用投影坐标系统(以米为单位)
  projection: 'EPSG:3857',
  extent: new Extent('EPSG:3857', -20037508, 20037508, -20037508, 20037508),
});

这种模式下,数据显示的是真实的地理位置,更适合量测、编辑这类操作。

添加交互控件

实际项目中,用户需要导航控件、层面板这些 UI:

import { Navigation } from 'itowns/widgets';
 
const navigation = new Navigation(view, {
  position: 'bottom-right',
  translate: { y: -40 },
});

这会在右下角添加一个导航控件(旋转、倾斜、缩放按钮)。

适用场景

城市规划和建筑可视化:显示建筑物轮廓、地块规划、公共设施分布。用矢量切片加载建筑数据,用 3D Tiles 显示精细的建筑模型,可以给客户展示城市改造的效果。

地产和房产展示:在地图上标记楼盘位置,显示周边设施(学校、医院、地铁站),加载街景或无人机拍摄的影像。用 PlanarView 模式能精确显示地理位置。

政府和军事制图:接入国家或地区的地理信息基础设施(很多都提供 WMS 服务),实现统一的信息门户。开源协议对政府项目友好。

环保监测和林业管理:显示卫星影像、热红外数据、森林覆盖率分布。点云数据用于林木检测、高度测量。

基础设施管理:电网、供水、通信管网这些需要在地图上可视化分布情况。加载 GeoJSON 格式的线路数据,交互式编辑网络拓扑。

教育和科研:地理信息专业的实验教学、气候变化可视化、地形分析研究。开源特性对学校免费,社区活跃方便学生提问。

与其他方案的差异

如果你用过 Leaflet 或 Mapbox GL,你可能会问:iTowns 有什么不一样?

Leaflet 主要做 2D 平面地图,没有 3D 能力。Mapbox GL 能做 3D,但主要面向轻量级应用(展示地图、标记点这类)。iTowns 的设计就不一样了——它是为大规模地理数据和复杂 GIS 操作而生的。

更具体地说:

  • 数据格式支持:Mapbox GL 主要支持 Mapbox Vector Tiles,不支持点云。iTowns 支持的格式更广。
  • 坐标系统:Leaflet 和 Mapbox GL 都只用 Web Mercator 投影。如果你需要用高斯克吕格投影或其他地方坐标系,只能自己转换。iTowns 原生支持多种投影,自动处理转换。
  • 数据规模:Mapbox GL 适合百万级对象。如果要展示千万级的矢量数据(比如整个国家的建筑物轮廓),iTowns 的瓦片机制更高效。
  • 许可证:Mapbox GL 是开源但商业软件。iTowns 是真正的开源,没有商业限制。

不过,如果你只需要一个漂亮的地图,Mapbox GL 可能更轻便。如果你需要 GIS 的功能深度,iTowns 更合适。

写在最后

iTowns 最大的价值在于它解决了一个长期问题:怎样用开源、轻量的 Web 技术构建专业级 GIS 应用。以前这类工作要么用桌面 GIS(ArcGIS、QGIS),要么依赖商业 Web GIS 库,成本都很高。

现在,如果你有地理数据需要可视化,需要支持企业级的 WMS 服务,需要处理点云或 3D Tiles,iTowns 都能满足。它的社区活跃,文档齐全,已经在生产环境中被验证。

唯一的学习成本是地理坐标系统和投影变换的知识,但这是 GIS 工作的基础,与框架无关。如果你项目涉及地理数据,值得花时间研究一下。

GitHub 项目链接:https://github.com/iTowns/itowns (opens in a new tab)