
GitHub Trending 上周出现了一个增长速度异常的项目:opengeos/GeoLibre,一个完全免费开源的云原生 GIS 平台,上线不到两个月已获得 2600+ Star,日均新增 400+。它在 Reddit r/gis 社区获得了 178 个赞,开发者 Qiusheng Wu(吴秋生)是地理空间 Python 生态中最活跃的贡献者之一,其此前作品 geehtml、leafmap、geemap 累计 GitHub Star 超过 4000。
GeoLibre 的定位很明确:用一套代码同时覆盖浏览器、桌面(Tauri v2)、Android 原生应用和 Jupyter Notebook 四个平台,全部数据本地处理,无需账号、无需服务器。它构建在 MapLibre GL JS、DuckDB-WASM Spatial、deck.gl 和 Tauri v2 之上,对标的是 Google Earth Pro 和 ArcGIS Online,但运行成本为零。
架构:一套 monorepo,四个平台

GeoLibre 采用 npm workspaces monorepo 结构,核心包分工明确:
| 包 | 职责 |
|---|---|
@geolibre/core | 领域类型、项目 JSON Schema、全局状态(Zustand) |
@geolibre/map | MapLibre 生命周期、图层同步、GeoJSON/栅格/瓦片处理 |
@geolibre/ui | 共享 UI 组件(shadcn 风格) |
@geolibre/processing | 客户端算法注册表 |
@geolibre/plugins | 插件接口及内置插件 |
geolibre-desktop | Shell 布局、Tauri I/O、组合层 |
状态流的设计是一个亮点。用户添加数据后,本地矢量数据直接解析或通过 DuckDB-WASM Spatial 转为 GeoJSON,传递给 store 的 addGeoJsonLayer。瓦片、服务、栅格、ArcGIS、MBTiles 等图层创建 GeoLibreLayer 记录,携带源元数据和原生 MapLibre 图层 ID。MapCanvas 订阅 layers,MapController.syncLayers 更新 MapLibre 的 sources 和 layers,保持图层控制同步。
这种设计的关键在于 store 是引擎无关的:它持有的是纯 GeoLibreLayer 记录和 MapViewState,而非 MapLibre 对象。这使得后续接入 CesiumJS 3D 地球视图时,第二个渲染器只需订阅同一个 store 即可,无需任何引擎抽象层。
DuckDB-WASM:浏览器里的空间数据库
GeoLibre 最具技术深度的部分是将 DuckDB 的 Spatial 扩展编译为 WebAssembly,在浏览器内完成矢量文件的格式转换。工作流程如下:
INSTALL spatial;
LOAD spatial;GeoParquet 通过 DuckDB 的 Parquet reader 读取后加载 Spatial 扩展。其他本地矢量格式由 Spatial 的 ST_Read 函数处理(依赖 GDAL 支持的读取器)。压缩的 Shapefile 先用 shpjs 解析,失败后回退到 DuckDB Spatial。KML 文件由自研解析器处理,保留嵌入的符号样式,输出符合 simplestyle-spec 的属性(fill、stroke、stroke-width),使带样式的 KML 在渲染时与 Google Earth 中显示一致。
这意味着用户在浏览器里拖入一个 Shapefile 或 GeoPackage,不需要任何后端服务,DuckDB-WASM 就能在客户端完成空间查询和格式转换。
3D 地球视图:MapLibre 与 CesiumJS 的双引擎协同

GeoLibre 的 2D MapLibre 地图可以与 CesiumJS 渲染的 3D 地球并排显示,作为分屏面板而非全局引擎替换。实现上有几个关键工程决策:
延迟加载:Cesium 引擎约 4.8 MB,仅在面板切换到地球视图时通过动态 import() 加载,单独构建为独立 chunk,不影响 2D 启动路径。
相机同步:packages/map/src/cesium-camera.ts 负责在 MapLibre 的 Web 墨卡托 MapViewState(zoom、天底角俯仰 pitch、方位 bearing)与 Cesium 的相机参数(米制距离 range、地平线角俯仰、航向 heading)之间转换。匹配基准是地面分辨率(每像素米数),确保两个面板的屏幕比例尺保持同步,即使面板高度不同。CesiumCanvas 从共享的 mapView 初始化相机,双向写入相机移动,并带有容差检查以消除应用→moveEnd 的回声循环。
图层同步:CesiumLayerSync 将 store 中的 GeoLibreLayer[] 映射到地球视图上,复用与 MapController.syncLayers 相同的分面板可见性覆盖逻辑。它渲染 Cesium 擅长的图层类型:GeoJSON(作为 draped GeoJsonDataSource,从图层的填充/描边/透明度参数读取样式)、XYZ/栅格/WMTS/WMS(作为 ImageryLayer)和 3D Tiles(作为 Cesium3DTileset 图元)。其他图层类型(PMTiles、MBTiles、Zarr、LiDAR、高斯泼溅、deck.gl 可视化)在地球视图中跳过,仅在 2D 面板中渲染。
行星地图:不止于地球
GeoLibre 不局限于地球。通过 OpenPlanetaryMap 和 USGS 天体地质学数据,它覆盖了月球、火星、水星、金星、木星的伽利略卫星(木卫一、木卫二、木卫三、木卫四)、土卫六、冥王星和冥卫一。每个项目配置独立的椭球体参数,其半径驱动距离、面积和比例尺测量,确保你在绘制火星地图时的测量数据是基于火星的参数计算的,而非地球的。
处理引擎:三选一的矢量分析
GeoLibre 的矢量分析工具有三种执行引擎:
- Turf.js(客户端):Processing → Vector 菜单下的工具使用 Turf.js,无需任何后端
- GeoPandas/Shapely(Python sidecar):通过 FastAPI 管理的本地 sidecar 运行,提供投影感知的结果
- GeoPandas via Pyodide(浏览器内):将同一份 GeoPandas/Shapely 代码通过 Pyodide(编译为 WebAssembly 的 CPython)在浏览器中运行
第三种引擎的巧妙之处在于代码复用:几何逻辑模块 backend/geolibre_server/geolibre_server/vector_ops.py 同时被 sidecar 和浏览器运行。一个 Vite 插件将该模块复制到应用 bundle 中,一个 Web Worker 从 CDN 加载 Pyodide,安装 geopandas,并通过 JSON 字符串边界调用 run_vector_tool。单一代码源意味着 Sidecar 和 Pyodide 引擎返回完全一致的结果。
SQL Workspace 同样支持三种引擎:DuckDB、PostGIS(通过 PGlite)和 Apache Sedona。在桌面端,Sedona 运行在 SedonaDB(单节点 Rust 引擎,基于 DataFusion + Arrow)上;在浏览器中,它通过 CereusDB(SedonaDB 的 WebAssembly 构建)完全在客户端运行。
离线支持:PWA 的缓存策略
独立 Web 版本是一个可安装的 PWA。缓存策略分三层:
- 预缓存(App Shell):HTML 和启动地图所需的 JS/CSS chunk 在首次访问后被预缓存,之后无需网络即可加载
- 运行时缓存(CacheFirst):构建产物中内容哈希命名的资源(MapLibre bundle、DuckDB-WASM 及其 spatial 扩展、MapLibre feature-plugin chunks)在首次使用时缓存。文件名哈希使 CacheFirst 安全可靠:重新部署生成新 URL,永远不会将过期缓存当作当前版本
- 底图缓存:来自 CORS 友好的默认主机(OpenFreeMap、CARTO)的瓦片和样式被运行时缓存
这套设计使得本地文件工作流(DuckDB Spatial 转换)在首次在线使用后可以离线运行。
安装方式
GeoLibre 的分发渠道覆盖全面:
- Web:直接访问 web.geolibre.app,无需安装
- 桌面:Windows、macOS、Linux 安装包,通过 geolibre.app/downloads/ 获取
- Windows:上架 Microsoft Store
- Arch Linux:AUR 包
geolibre-bin - Flatpak:FlatHub 上架
app.geolibre.GeoLibre - Docker:
ghcr.io/opengeos/geolibre,容器内捆绑 Python sidecar - Python/Jupyter:
pip install geolibre或conda install -c conda-forge geolibre
数据源支持
GeoLibre v2.3 支持的数据源包括:XYZ 瓦片、WMS、WFS、矢量文件(GeoJSON、Shapefile、GeoPackage、GeoParquet)、矢量瓦片源、分隔文本、栅格瓦片模板、COG 和 GeoTIFF 栅格、MBTiles、ArcGIS FeatureServer/VectorTileServer、GPX 航点/轨迹/路线、3D Tiles、PMTiles、FlatGeobuf、Zarr、LiDAR 点云、高斯泼溅(Gaussian splats)。
此外还有通过插件提供的数据源:Microsoft Planetary Computer、Google Earth Engine、Overture Maps、联邦 Web Services(USDA、NOAA 等)。Time Slider 插件支持时间序列栅格和矢量数据的动画播放(COG、XYZ/WMTS、WMS-Time、时间过滤 GeoJSON)。
开源生态定位
GeoLibre 出现在 GIS 软件生态的一个重要变化节点。商业 GIS 软件 ArcGIS Online 的年订阅费用从数百到数千美元不等,且核心数据需要上传到 Esri 的云服务。Google Earth Pro 虽然免费但不开源、不支持自定义分析。QGIS 是成熟的开源桌面 GIS,但基于 Qt/C++ 技术栈,不具备 Web 原生能力和云原生数据处理能力。
GeoLibre 选择的技术栈(WebGPU、WebAudio、Web Workers、WebAssembly、WebSocket)让它从第一天就具备了浏览器原生的优势。所有计算在客户端完成,数据不离开用户设备。对于需要处理敏感地理空间数据的场景(国防、企业内部数据、个人隐私数据),这个架构特点具有实际意义。
项目作者 Qiusheng Wu 在地理空间 Python 生态的长期投入(Tennessee 大学研究教授,geehtml/leafmap/geemap/whiteboxgui 作者)为项目的持续维护提供了可信度。GeoLibre 采用 MIT 许可证,接受社区贡献,已有外部开发者提交的 issue 报告、反馈和功能改进。
来源:
- GitHub: opengeos/GeoLibre
- 官网: geolibre.app
- 架构文档: docs/architecture.md
- 功能列表: geolibre.app/features
- Reddit 讨论: r/gis 帖子
- DOI: 10.5281/zenodo.20785400