Cookiecutter Data Science与地理空间数据项目:目录结构定制指南
你是否还在为地理空间数据项目的文件杂乱无章而烦恼?是否因 shp 文件与 Python 脚本混放导致团队协作效率低下?本文将带你基于 Cookiecutter Data Science 框架,打造专属于地理空间数据项目的目录结构,实现从原始遥感影像到空间分析报告的全流程规范化管理。读完本文,你将掌握:地理空间目录扩展技巧、自动化配置脚本编写、GDAL 工具链集成方案,以及如何通过 hooks 实现模板动态调整。
项目结构基础:理解默认模板
Cookiecutter Data Science 提供了数据科学项目的标准化结构,核心目录设计如下:
{{ cookiecutter.repo_name }}/
├── data/ # 数据存储层
│ ├── external/ # 外部数据集
│ ├── interim/ # 中间处理数据
│ ├── processed/ # 最终分析数据
│ └── raw/ # 原始数据(不可修改)
├── models/ # 模型文件
├── notebooks/ # Jupyter分析文档
├── reports/ # 成果报告
│ └── figures/ # 可视化图表
└── {{ cookiecutter.module_name }}/ # 源代码
├── data/ # 数据处理脚本
├── features/ # 特征工程
├── models/ # 模型训练代码
└── visualization/ # 可视化工具
这种结构通过分离数据、代码和文档,解决了传统项目"一锅烩"的问题。但地理空间数据有其特殊性:投影文件(.prj)、元数据(.xml)、瓦片数据(.mbtiles)等需要特殊管理。接下来我们将通过三步定制,让这个框架完美适配地理空间场景。
第一步:扩展地理空间专用目录
1.1 数据目录改造
在默认数据目录基础上,我们需要为地理空间数据增加专用子目录:
# 在 data 目录下创建地理空间专用子目录
mkdir -p data/geospatial/{raw,processed,temp,tiles}
mkdir -p data/geospatial/raw/{shp,tif,gpkg} # 按格式分类原始数据
修改后的目录结构如下:
data/
├── geospatial/ # 地理空间数据根目录
│ ├── raw/ # 原始地理数据
│ │ ├── shp/ # 矢量数据
│ │ ├── tif/ # 栅格影像
│ │ └── gpkg/ # GeoPackage 容器
│ ├── processed/ # 投影转换后的处理数据
│ ├── temp/ # 处理过程临时文件
│ └── tiles/ # 地图瓦片(MBTiles/XYZ)
1.2 源代码目录适配
地理空间分析需要专用模块处理坐标转换、空间索引等操作,建议在 {{ cookiecutter.module_name }} 下新增 geospatial 子模块:
{{ cookiecutter.module_name }}/
├── geospatial/ # 地理空间处理模块
│ ├── __init__.py
│ ├── transform.py # 坐标转换工具
│ ├── raster_ops.py # 栅格处理(GDAL封装)
│ └── vector_ops.py # 矢量分析(PyShp/GeoPandas)
1.3 配置文件修改
通过修改 cookiecutter.json 可以实现模板参数化,但当前版本已 deprecated 该配置方式,需要使用 ccds 命令替代 cookiecutter 命令。具体配置变更可参考 hooks/pre_gen_project.py 中的版本检查逻辑。
第二步:编写地理空间专用配置脚本
2.1 自定义Hook脚本
Cookiecutter 提供了项目生成前后的钩子机制,通过修改 hooks/post_gen_project.py 可以自动创建地理空间目录:
# 在 post_gen_project.py 末尾添加地理空间目录生成代码
import os
from pathlib import Path
# 创建地理空间专用目录
geo_dirs = [
"data/geospatial/raw/shp",
"data/geospatial/raw/tif",
"data/geospatial/raw/gpkg",
"data/geospatial/processed",
"data/geospatial/temp",
"data/geospatial/tiles",
"{{ cookiecutter.module_name }}/geospatial"
]
for dir_path in geo_dirs:
Path(dir_path).mkdir(parents=True, exist_ok=True)
# 创建 .gitkeep 文件确保空目录被版本控制
with open(os.path.join(dir_path, ".gitkeep"), "w") as f:
pass
2.2 依赖项自动安装
地理空间项目通常需要 GDAL、PyProj 等特殊依赖,可通过修改 hooks/post_gen_project.py 中的 packages 列表实现自动安装:
# 在 packages 列表添加地理空间依赖
packages += [
"gdal", # 地理数据处理库
"geopandas", # 空间数据框操作
"rasterio", # 栅格数据IO
"fiona", # 矢量数据IO
"pyproj", # 坐标转换
"contextily", # 底图加载
]
pip_only_packages += ["gdal"] # GDAL 需通过 pip 安装
第三步:集成地理空间工作流
3.1 数据处理流水线
创建 {{ cookiecutter.module_name }}/data/make_geodata.py 实现地理数据自动化处理:
# 地理空间数据处理示例代码
import rasterio
from rasterio.warp import reproject, Resampling
from {{ cookiecutter.module_name }}.geospatial.transform import project_shapefile
def process_remote_sensing_image(input_path, output_path, target_crs="EPSG:4326"):
"""遥感影像投影转换与裁剪"""
with rasterio.open(input_path) as src:
# 定义目标坐标系
dst_crs = target_crs
# 计算转换后尺寸
transform, width, height = calculate_default_transform(
src.crs, dst_crs, src.width, src.height, *src.bounds
)
# 创建输出文件
with rasterio.open(
output_path, "w",
driver="GTiff",
height=height,
width=width,
count=src.count,
dtype=src.dtypes[0],
crs=dst_crs,
transform=transform
) as dst:
for i in range(1, src.count + 1):
reproject(
source=rasterio.band(src, i),
destination=rasterio.band(dst, i),
src_transform=src.transform,
src_crs=src.crs,
dst_transform=transform,
dst_crs=dst_crs,
resampling=Resampling.bilinear
)
return output_path
3.2 可视化模板
在 reports/figures 目录下创建地理空间可视化模板 spatial_figure.ipynb,包含:
- 交互式地图展示(folium/ipyleaflet)
- 空间分布热力图
- 投影信息标注
- 图例标准化样式
高级技巧:动态配置与条件生成
通过 ccds/hook_utils/custom_config.py 中的 write_custom_config 函数,可实现基于项目类型的动态目录生成。例如当检测到 geo_project: true 配置时,自动激活地理空间模块:
# 动态配置示例(custom_config.py 片段)
def write_custom_config(user_input_config):
if user_input_config.get("geo_project", False):
# 激活地理空间模块
copy_tree("templates/geospatial", ".")
# 修改 README.md 添加地理空间说明
with open("README.md", "a") as f:
f.write("\n## 地理空间数据说明\n\n详见 [data/geospatial/README.md](https://link.gitcode.com/i/4a0660882f379bd7dea0476aca57502c)")
这种机制通过 hooks/post_gen_project.py 第 78 行的调用触发,实现了模板的灵活性与标准化的平衡。
总结与最佳实践
通过本文介绍的三个步骤,我们构建了完整的地理空间数据项目框架:
- 目录扩展:在 data 下新增 geospatial 目录树,分离管理矢量、栅格和瓦片数据
- 自动化配置:通过 hooks 脚本实现地理目录自动创建和依赖安装
- 工作流集成:开发地理空间专用数据处理和可视化工具
建议配合以下最佳实践使用:
- 原始地理数据必须包含元数据文件(.xml 或 .md)
- 所有处理步骤通过脚本实现,避免手动 GIS 操作
- 使用环境变量管理 GDAL 数据路径:
export GDAL_DATA=/path/to/gdal_data - 大型栅格数据建议使用 Cloud Optimized GeoTIFF (COG) 格式
完整配置示例可参考项目 tests/ 目录下的地理空间测试用例,更多高级用法详见官方文档 docs/。现在就用 ccds https://gitcode.com/gh_mirrors/coo/cookiecutter-data-science 命令,创建你的第一个规范化地理空间项目吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



