GIS项目成果展示太丑?Streamlit Cloud一键部署全流程(附:地图组件源码)
《GIS项目成果展示太丑?Streamlit Cloud一键部署全流程(附:地图组件源码)》这篇文章,解决的是一个很常见的问题:你已经用 Python、GeoPandas、QGIS 或 PostGIS 做完了空间分析,但最后只能把截图、PPT 或压缩包发给老师、甲方或面试官,展示效果不直观,也不够“项目化”。
本文会用一个可复现的流程,把 GIS 成果做成一个在线 Web 页面:左侧选择图层和字段,右侧显示交互地图,并部署到 Streamlit Cloud。你不需要从零学习前端框架,也不需要自己买服务器,适合 GIS 学生、初级 GIS 工程师、空间数据分析师和 Python GIS 用户快速做项目展示。

引言:为什么 GIS 项目成果展示经常“不像一个项目”
很多 GIS 项目不是分析过程不扎实,而是成果展示太弱。常见情况包括:
- 只给一张静态地图截图,别人无法缩放、点击、查看属性。
- 只发 Shapefile、GeoJSON 或 Excel,非 GIS 用户打不开或看不懂。
- 用 QGIS 或 ArcGIS Pro 制图很好看,但无法在线交互演示。
- WebGIS 开发成本太高,Leaflet、OpenLayers、前后端部署对初学者门槛较高。
- 面试或课程答辩时,只能口头解释分析过程,缺少一个可访问的在线链接。
Streamlit Cloud 的优势在于:你用 Python 写一个简单页面,把地图、图表、表格和说明组织起来,然后通过 GitHub 部署成一个公网可访问的链接。对于 GIS 项目成果展示来说,它不是替代专业 WebGIS 平台,而是非常适合“快速展示分析结果”的工具。
背景:本文要实现的 GIS 项目展示效果
本文以一个典型 GIS 成果展示页面为目标,页面包含以下功能:
- 在浏览器中打开在线项目页面。
- 加载本地 GeoJSON 空间数据。
- 使用交互式地图展示点、线或面要素。
- 支持点击地图要素查看属性。
- 在侧边栏显示图层说明、字段选择和项目介绍。
- 通过 Streamlit Cloud 一键部署,生成可分享链接。
为了让流程更通用,本文使用 GeoJSON 作为演示数据格式。GeoJSON 对 Web 地图友好,结构清晰,适合从 QGIS、ArcGIS Pro、GeoPandas 或 PostGIS 导出。如果你的数据是 Shapefile,也可以先转换成 GeoJSON。
原理:Streamlit Cloud 为什么适合 GIS 项目成果展示
Streamlit 是一个 Python Web 应用框架,特点是用很少的代码把数据分析结果变成网页。Streamlit Cloud 是官方提供的在线部署平台,可以直接连接 GitHub 仓库,把你的 Python 应用发布到公网。
在 GIS 场景中,一个简单的展示链路通常是:
- 用 QGIS、ArcGIS Pro、GeoPandas 或 PostGIS 完成数据处理和空间分析。
- 把结果导出为 GeoJSON、CSV、GeoPackage 或栅格切片等适合展示的格式。
- 用 Streamlit 编写页面布局、说明文字、图表和筛选控件。
- 用 Folium、PyDeck 或 st.map 等组件展示地图。
- 把代码和数据提交到 GitHub。
- 在 Streamlit Cloud 中选择仓库和入口文件完成部署。
这里需要理解一个关键点:Streamlit Cloud 适合展示轻量级成果,不适合直接承载超大规模生产级 WebGIS 服务。如果你的数据有几十万到几百万个要素,应该先做抽稀、切片、矢量瓦片或服务化,而不是把完整 GeoJSON 直接塞进页面。
步骤:准备 GIS 数据与项目目录
建议先建立一个清晰的项目目录。下面是一个适合初学者的目录结构:
gis-streamlit-demo/
├── app.py
├── requirements.txt
├── data/
│ └── sample.geojson
└── README.md
其中:
- app.py:Streamlit 应用入口文件。
- requirements.txt:记录项目依赖库,Streamlit Cloud 会根据它安装环境。
- data/sample.geojson:用于地图展示的 GIS 数据。
- README.md:项目说明,可选但建议保留。
如果你已有 Shapefile,可以在 QGIS 中这样导出 GeoJSON:
- 打开 QGIS,加载 Shapefile 图层。
- 右键图层,选择“导出”或“另存为”。
- 格式选择 GeoJSON。
- 坐标系建议选择 EPSG:4326,也就是 WGS 84 经纬度坐标系。
- 文件名保存为 data/sample.geojson。
为什么建议使用 EPSG:4326?因为大多数 Web 地图组件都以经纬度数据为输入,底图显示通常基于 Web Mercator。如果你的 GeoJSON 坐标仍是投影坐标,例如 CGCS2000 高斯投影或地方坐标,地图可能会显示到错误位置,甚至完全看不到。
步骤:安装本地 Streamlit 开发环境
建议使用 Python 虚拟环境,避免和已有 GIS Python 环境冲突。以下命令适合 Windows、macOS 和 Linux 的常规 Python 环境。
cd gis-streamlit-demo
python -m venv .venv
# Windows
.venvScriptsactivate
# macOS / Linux
source .venv/bin/activate
pip install streamlit geopandas folium streamlit-folium
然后生成 requirements.txt:
pip freeze > requirements.txt
如果你只是展示 GeoJSON,并不做复杂空间分析,也可以减少依赖,避免 GeoPandas 在云端安装较慢。一个更轻量的依赖文件可以这样写:
streamlit
folium
streamlit-folium
对于 Streamlit Cloud 部署,依赖越简单,成功率越高。GeoPandas、GDAL、Fiona、Rasterio 这类库功能强大,但在云端环境中安装时间和兼容性成本更高。如果只是展示成果,优先使用轻量方案。
步骤:地图组件源码 app.py
下面是一份可以直接运行的 Streamlit GIS 地图组件源码。它使用 Folium 加载 GeoJSON,并通过 streamlit-folium 嵌入到 Streamlit 页面中。
import json
from pathlib import Path
import folium
import streamlit as st
from streamlit_folium import st_folium
st.set_page_config(
page_title="GIS项目成果展示",
page_icon="🗺️",
layout="wide"
)
st.title("GIS项目成果展示 Demo")
st.caption("使用 Streamlit Cloud 部署的交互式 GIS 成果展示页面")
DATA_PATH = Path("data/sample.geojson")
@st.cache_data
def load_geojson(path):
with open(path, "r", encoding="utf-8") as f:
return json.load(f)
def get_center_from_geojson(geojson_data):
coords = []
def collect_coordinates(obj):
if isinstance(obj, list):
if len(obj) >= 2 and isinstance(obj[0], (int, float)) and isinstance(obj[1], (int, float)):
coords.append(obj[:2])
else:
for item in obj:
collect_coordinates(item)
for feature in geojson_data.get("features", []):
geometry = feature.get("geometry")
if geometry:
collect_coordinates(geometry.get("coordinates", []))
if not coords:
return [31.2304, 121.4737]
lon_avg = sum(c[0] for c in coords) / len(coords)
lat_avg = sum(c[1] for c in coords) / len(coords)
return [lat_avg, lon_avg]
with st.sidebar:
st.header("项目说明")
st.write("这是一个用于课程作业、作品集或项目汇报的 GIS 成果展示模板。")
st.subheader("数据文件")
st.code(str(DATA_PATH))
map_style = st.selectbox(
"选择底图",
["OpenStreetMap", "CartoDB positron", "CartoDB dark_matter"]
)
show_geojson = st.checkbox("显示 GeoJSON 图层", value=True)
if not DATA_PATH.exists():
st.error("未找到 data/sample.geojson,请先准备 GeoJSON 数据文件。")
st.stop()
geojson_data = load_geojson(DATA_PATH)
center = get_center_from_geojson(geojson_data)
col_map, col_info = st.columns([3, 1])
with col_map:
m = folium.Map(
location=center,
zoom_start=10,
tiles=map_style
)
if show_geojson:
folium.GeoJson(
geojson_data,
name="GIS成果图层",
tooltip=folium.GeoJsonTooltip(
fields=list(geojson_data["features"][0]["properties"].keys())[:5],
aliases=list(geojson_data["features"][0]["properties"].keys())[:5],
localize=True
),
style_function=lambda feature: {
"fillColor": "#3186cc",
"color": "#1f4e79",
"weight": 2,
"fillOpacity": 0.45
}
).add_to(m)
folium.LayerControl().add_to(m)
st_folium(
m,
width=900,
height=600,
returned_objects=[]
)
with col_info:
st.subheader("成果摘要")
feature_count = len(geojson_data.get("features", []))
st.metric("要素数量", feature_count)
if feature_count > 0:
properties = geojson_data["features"][0].get("properties", {})
st.write("字段预览")
st.json(properties)
st.subheader("使用建议")
st.write("点击地图要素可以查看属性信息。")
st.write("如果地图位置不正确,请检查 GeoJSON 坐标系是否为 EPSG:4326。")
这段代码做了几件关键事情:
- 使用 st.set_page_config 设置页面标题、图标和宽屏布局。
- 使用 st.sidebar 放置项目说明和地图开关。
- 使用 folium.GeoJson 加载 GeoJSON 图层。
- 使用 GeoJsonTooltip 显示属性字段。
- 使用 st.cache_data 缓存数据读取,减少重复加载。
- 自动从 GeoJSON 坐标计算地图中心点。
步骤:本地运行和调试
在项目根目录运行:
streamlit run app.py
命令执行后,浏览器会自动打开本地页面。如果没有自动打开,可以访问终端中显示的本地地址,通常类似:
http://localhost:8501
本地调试时重点检查以下内容:
- 页面是否能正常打开。
- GeoJSON 是否成功加载。
- 地图是否定位到正确区域。
- 点击或悬停要素时是否能看到属性字段。
- 侧边栏控件是否正常工作。
- 终端是否出现文件路径、编码或依赖错误。
如果地图空白,优先检查 GeoJSON 的坐标顺序。GeoJSON 标准坐标顺序是 经度、纬度,也就是 lon, lat。很多 GIS 初学者会把它和地图显示中的“纬度、经度”混淆。
步骤:上传到 GitHub
Streamlit Cloud 需要从 GitHub 仓库读取代码。你可以新建一个公开仓库,然后把项目文件提交上去。
git init
git add .
git commit -m "init gis streamlit demo"
git branch -M main
git remote add origin https://github.com/你的用户名/gis-streamlit-demo.git
git push -u origin main
如果你不熟悉 Git,也可以在 GitHub 网页端手动上传以下文件:
- app.py
- requirements.txt
- data/sample.geojson
- README.md
注意不要上传敏感数据。很多 GIS 项目包含内部道路、管线、客户边界、人口数据或涉密坐标数据。部署到公网前,必须确认数据可以公开展示。课程作业和作品集建议使用脱敏数据、公开数据或模拟数据。
步骤:Streamlit Cloud 一键部署
完成 GitHub 上传后,就可以进入 Streamlit Cloud 部署应用。基本流程如下:
- 打开 Streamlit Cloud 官网并登录。
- 选择使用 GitHub 账号授权。
- 点击创建新应用。
- 选择刚才上传的 GitHub 仓库。
- 分支选择 main。
- 入口文件填写 app.py。
- 点击部署。
部署过程中,Streamlit Cloud 会读取 requirements.txt 并安装依赖。安装完成后,系统会自动启动应用,并生成一个在线访问链接。
如果部署失败,不要急着改代码。先查看部署日志,通常能看到明确原因,例如依赖安装失败、文件路径错误、Python 包版本冲突或数据文件不存在。
常见坑:Streamlit Cloud 部署 GIS 项目最容易出错的地方
1. data 文件夹没有上传
本地运行正常,云端报错找不到 data/sample.geojson,通常是因为数据文件没有提交到 GitHub。检查仓库页面是否能看到 data 文件夹和 GeoJSON 文件。
2. 文件路径写成了本地绝对路径
错误示例:
C:UsersadminDesktopgisdatasample.geojson
云端服务器不存在你的本地桌面路径。应使用相对路径:
data/sample.geojson
3. GeoJSON 坐标系不是 EPSG:4326
如果地图图层显示到海里、非洲附近,或者根本看不到,最常见原因是坐标系不对。请在 QGIS 或 ArcGIS Pro 中把数据另存为 WGS 84,经纬度坐标系对应 EPSG:4326。
4. GeoJSON 文件太大
Streamlit Cloud 适合轻量展示。如果 GeoJSON 几十 MB 甚至上百 MB,页面加载会明显变慢。建议:
- 删除无用字段。
- 简化面边界。
- 抽样展示点数据。
- 按行政区或类别拆分文件。
- 改用矢量瓦片、PostGIS 服务或专门的 WebGIS 后端。
5. requirements.txt 依赖过重
如果只是展示 GeoJSON,不要一开始就加入大量 GIS 库。GDAL、Fiona、Rasterio、GeoPandas 在某些云环境中可能安装较慢或出现兼容问题。展示项目优先使用轻量依赖,分析过程可以在本地完成。
6. GitHub 仓库是私有仓库但授权不足
如果 Streamlit Cloud 看不到你的仓库,可能是 GitHub 授权范围不够。可以先用公开仓库测试流程,确认部署成功后,再根据项目需要调整权限。
方法比较:Streamlit、QGIS2Web、Leaflet 和传统 WebGIS 怎么选
| 方法 | 适合场景 | 优点 | 限制 |
|---|---|---|---|
| Streamlit Cloud | 课程作业、作品集、分析成果展示、快速原型 | Python 友好,部署简单,能同时展示地图、表格和图表 | 不适合超大数据和复杂生产系统 |
| QGIS2Web | 把 QGIS 图层快速导出为网页地图 | 不需要写太多代码,适合静态图层展示 | 交互逻辑和数据分析能力有限 |
| Leaflet | 轻量级 Web 地图开发 | 前端生态成熟,地图交互灵活 | 需要 JavaScript 和前端部署基础 |
| OpenLayers | 较复杂的 WebGIS 项目 | 功能强,适合多源地图和专业 GIS 交互 | 学习成本高于 Leaflet 和 Streamlit |
| GeoServer + PostGIS | 正式生产级 GIS 服务 | 适合多用户、多图层、空间查询和服务发布 | 部署和运维成本较高 |
如果你的目标是“让别人快速看到项目成果”,Streamlit Cloud 很合适。如果你的目标是“建设长期运行的专业 WebGIS 系统”,则应考虑 PostGIS、GeoServer、OpenLayers、Leaflet、Cesium 等更完整的技术栈。
检查清单:发布前请逐项确认
- 项目标题是否清楚说明了 GIS 分析主题。
- 地图是否能在浏览器中正常缩放和平移。
- GeoJSON 坐标系是否为 EPSG:4326。
- 属性字段是否经过清理,避免出现无意义字段名。
- 是否删除了敏感字段和敏感空间位置。
- requirements.txt 是否只保留必要依赖。
- GitHub 仓库是否包含 app.py、requirements.txt 和 data 文件夹。
- Streamlit Cloud 入口文件是否填写为 app.py。
- 移动端或小屏幕下页面是否仍能基本阅读。
- README 是否说明了项目背景、数据来源和使用方法。
FAQ:GIS项目成果展示与 Streamlit Cloud 常见问题
GIS项目成果展示一定要做成 WebGIS 吗?
不一定。如果只是提交制图成果,高质量 PDF 或图片也可以。但如果你需要展示交互查询、字段信息、分析结果对比和在线访问链接,Web 化展示会更有说服力。Streamlit Cloud 适合快速把 GIS 分析成果做成可访问页面。
Streamlit Cloud 可以部署 Shapefile 吗?
可以通过 GeoPandas 读取 Shapefile,但不建议初学者直接这样做。Shapefile 是一组文件,包含 shp、shx、dbf、prj 等,上传和路径管理容易出错。更推荐先在 QGIS 中导出为 GeoJSON,再用于 Streamlit 地图展示。
为什么我的地图显示位置不对?
最常见原因是坐标系错误。Web 地图展示通常需要经纬度坐标,建议把数据转换为 EPSG:4326。另一个原因是坐标顺序错误,GeoJSON 的坐标顺序应为经度在前、纬度在后。
Streamlit Cloud 适合展示多大的 GIS 数据?
它更适合轻量数据展示。对于课程作业、城市样区、少量点位、简化后的行政区边界,一般比较合适。对于大范围道路网、建筑物轮廓、轨迹点或高精度面数据,建议先做数据简化、抽样或切片。
地图组件应该选 Folium 还是 PyDeck?
Folium 更适合传统 Leaflet 风格地图,容易加载 GeoJSON,适合点线面成果展示。PyDeck 更适合大量点数据、三维柱状、流向和 Deck.gl 风格可视化。如果你刚开始做 GIS 项目展示,Folium 更容易上手。
可以把 PostGIS 查询结果放到 Streamlit 页面吗?
可以。你可以在 Streamlit 中连接 PostGIS,执行 SQL 或空间查询,然后把结果转成 GeoJSON 展示。但线上部署时要注意数据库连接安全,不要把密码直接写在代码里,应使用 Streamlit Cloud 的 secrets 配置。
Streamlit Cloud 部署后,别人打不开怎么办?
先确认应用链接是否正确,应用是否处于运行状态。然后检查 GitHub 仓库权限、部署日志和依赖安装情况。如果应用长时间未访问,云端可能需要重新唤醒,首次打开会稍慢。
结论:用 Streamlit Cloud 把 GIS 成果变成可分享的在线作品
GIS 项目成果展示不一定要从复杂 WebGIS 系统开始。对于课程作业、毕业设计、作品集、项目汇报和分析原型,Streamlit Cloud 可以用较低成本完成在线展示。
推荐的实践路径是:先在 QGIS、ArcGIS Pro、GeoPandas 或 PostGIS 中完成严谨的数据处理,再导出轻量 GeoJSON,最后用 Streamlit 组织地图、说明、图表和指标。这样既能保留 GIS 分析的专业性,也能让非 GIS 用户通过一个链接快速理解你的成果。
如果你后续需要更复杂的能力,例如用户登录、海量数据加载、空间查询服务、矢量瓦片或三维场景,再逐步升级到 PostGIS、GeoServer、Leaflet、OpenLayers 或 Cesium 技术栈,会比一开始就搭建完整 WebGIS 更稳妥。