105 lines
5.2 KiB
Python
105 lines
5.2 KiB
Python
"""
|
||
scripts/example_workflow.py
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
端到端示例:演示 geo_tools 的完整工作流。
|
||
|
||
运行方式
|
||
--------
|
||
cd F:\\@Project\\python\\geo_tools
|
||
python scripts/example_workflow.py
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
# 添加项目根目录到路径(开发模式未安装时使用)
|
||
import sys
|
||
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||
|
||
import geo_tools
|
||
from geo_tools.utils.logger import get_logger
|
||
|
||
logger = get_logger("example_workflow")
|
||
|
||
DATA_DIR = Path(__file__).parent.parent / "data" / "sample"
|
||
OUTPUT_DIR = Path(__file__).parent.parent / "output"
|
||
OUTPUT_DIR.mkdir(exist_ok=True)
|
||
|
||
|
||
def main() -> None:
|
||
logger.info("=" * 60)
|
||
logger.info("geo_tools 端到端工作流示例 v%s", geo_tools.__version__)
|
||
logger.info("=" * 60)
|
||
|
||
# ── 1. 读取示例点数据 ──────────────────────────────────────────
|
||
logger.info("\n[步骤 1] 读取示例点数据(GeoJSON)")
|
||
points = geo_tools.read_vector(DATA_DIR / "sample_points.geojson")
|
||
logger.info(" 读取完成:%d 条要素,CRS=%s", len(points), points.crs)
|
||
logger.info(" 字段:%s", list(points.columns))
|
||
|
||
# ── 2. 读取示例面数据 ──────────────────────────────────────────
|
||
logger.info("\n[步骤 2] 读取示例区域多边形(GeoJSON)")
|
||
regions = geo_tools.read_vector(DATA_DIR / "sample_regions.geojson")
|
||
logger.info(" 区域列表:%s", regions["name"].tolist())
|
||
|
||
# ── 3. 数据校验 ───────────────────────────────────────────────
|
||
logger.info("\n[步骤 3] 几何有效性校验")
|
||
stats = geo_tools.validate_geometry(points)
|
||
logger.info(" 点数据校验结果:%s", stats)
|
||
stats = geo_tools.validate_geometry(regions)
|
||
logger.info(" 面数据校验结果:%s", stats)
|
||
|
||
# ── 4. 坐标系信息 ─────────────────────────────────────────────
|
||
logger.info("\n[步骤 4] 查询 CRS 信息")
|
||
crs_info = geo_tools.get_crs_info("EPSG:4326")
|
||
logger.info(" WGS84 信息:%s", crs_info)
|
||
proj_crs = geo_tools.suggest_projected_crs(116.4, 39.9)
|
||
logger.info(" 北京适合的投影 CRS:%s", proj_crs)
|
||
|
||
# ── 5. 重投影 ─────────────────────────────────────────────────
|
||
logger.info("\n[步骤 5] 重投影到 Web Mercator(用于可视化)")
|
||
points_3857 = geo_tools.reproject(points, "EPSG:3857")
|
||
logger.info(" 重投影完成:CRS=%s", points_3857.crs)
|
||
|
||
# ── 6. 面积加权均值 ───────────────────────────────────────────
|
||
logger.info("\n[步骤 6] 面积加权均值计算(示例:用 buffer 生成面数据)")
|
||
# 先将点缓冲生成面数据
|
||
points_buffered = points.to_crs("EPSG:3857").copy()
|
||
points_buffered["geometry"] = points_buffered.geometry.buffer(100_000) # 100km缓冲
|
||
points_buffered = points_buffered.to_crs("EPSG:4326")
|
||
from geo_tools.analysis.stats import area_weighted_mean
|
||
aw_result = area_weighted_mean(points_buffered, value_col="value")
|
||
logger.info(" 全局面积加权均值:%.4f", aw_result["area_weighted_mean"])
|
||
|
||
# ── 7. 按位置选择 ─────────────────────────────────────────────
|
||
logger.info("\n[步骤 7] 按位置选择:筛选华南区域内的城市")
|
||
hua_nan = regions[regions["name"] == "华南"]
|
||
points_in_huanan = geo_tools.select_by_location(points, hua_nan, predicate="intersects")
|
||
logger.info(" 华南区域内的城市:%s", points_in_huanan["name"].tolist())
|
||
|
||
# ── 8. 统计汇总 ───────────────────────────────────────────────
|
||
logger.info("\n[步骤 8] 属性统计汇总")
|
||
from geo_tools.analysis.stats import summarize_attributes
|
||
summary = summarize_attributes(points, columns=["value"], group_col="category")
|
||
logger.info(" 按分类汇总:\n%s", summary.to_string(index=False))
|
||
|
||
# ── 9. 写出结果 ───────────────────────────────────────────────
|
||
logger.info("\n[步骤 9] 写出处理结果")
|
||
out_geojson = OUTPUT_DIR / "result_points_3857.geojson"
|
||
geo_tools.write_vector(points_3857, out_geojson)
|
||
logger.info(" GeoJSON 写出:%s", out_geojson)
|
||
|
||
out_gpkg = OUTPUT_DIR / "results.gpkg"
|
||
geo_tools.write_gpkg(points, out_gpkg, layer="original_points")
|
||
geo_tools.write_gpkg(regions, out_gpkg, layer="regions", mode="a")
|
||
logger.info(" GPKG 写出(2 图层):%s", out_gpkg)
|
||
|
||
logger.info("\n" + "=" * 60)
|
||
logger.info("工作流演示完成!输出目录:%s", OUTPUT_DIR)
|
||
logger.info("=" * 60)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main()
|