80 lines
3.1 KiB
Python
80 lines
3.1 KiB
Python
"""
|
|
一次性脚本:从 PostgreSQL 导出静态底图为 GeoPackage 文件。
|
|
运行一次即可,之后服务直接读本地 GPKG。
|
|
|
|
用法: python -m app.script.export_static_layers
|
|
"""
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
# 确保项目根目录在 sys.path 中
|
|
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
if project_root not in sys.path:
|
|
sys.path.insert(0, project_root)
|
|
|
|
import geopandas as gpd
|
|
from sqlalchemy import create_engine
|
|
from config import settings
|
|
|
|
# GPKG 输出目录(相对于项目根目录)
|
|
GPKG_DIR = os.path.join(project_root, getattr(settings, "QGIS_GPKG_DIR", "app/data/gpkg"))
|
|
|
|
# 静态图层定义: {显示名: (schema.table, geom_column, srid)}
|
|
STATIC_LAYERS = {
|
|
"水库": ("qgis.rivers", "Geometry", 0),
|
|
"市州驻地": ("qgis.sx_capital", "geometry", 0),
|
|
"河流": ("qgis.river", "Geometry", 0),
|
|
"active_fault": ("qgis.active_fault", "Geometry", 0),
|
|
"陕西省": ("qgis.sx", "Geometry", 0),
|
|
"乡镇驻地": ("qgis.sx_street", "dgeom", 0),
|
|
"区县驻地": ("qgis.sx_xa_county", "Geometry", 0),
|
|
"县界": ("qgis.sx_xa_county_boundary", "Geometry", 0),
|
|
"周边区县": ("qgis.sx_zb_county_boundary", "Geometry", 0),
|
|
"周边市州": ("qgis.sx_zb_city", "Geometry", 4326),
|
|
"周边县区": ("qgis.sx_zb_county", "Geometry", 0),
|
|
"traffic_expressway": ("qgis.traffic_expressway", "Geometry", 0),
|
|
"traffic_provincial": ("qgis.traffic_provincial", "Geometry", 0),
|
|
"traffic_railway": ("qgis.traffic_railway", "Geometry", 0),
|
|
"traffic_township": ("qgis.traffic_township", "Geometry", 0),
|
|
"traffic_trunk_line": ("qgis.traffic_trunk_line", "Geometry", 0),
|
|
}
|
|
|
|
|
|
def export_layers():
|
|
os.makedirs(GPKG_DIR, exist_ok=True)
|
|
|
|
conn_str = (
|
|
f"postgresql://{settings.DB_USER}:{settings.DB_PASSWORD}"
|
|
f"@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}"
|
|
)
|
|
engine = create_engine(conn_str)
|
|
|
|
for layer_name, (table_ref, geom_col, srid) in STATIC_LAYERS.items():
|
|
t0 = time.time()
|
|
schema, table = table_ref.split(".", 1)
|
|
print(f"导出 {layer_name} ({table_ref}) ...", end=" ", flush=True)
|
|
|
|
try:
|
|
sql = f'SELECT * FROM "{schema}"."{table}"'
|
|
gdf = gpd.read_postgis(sql, engine, geom_col=geom_col)
|
|
|
|
if srid and srid > 0:
|
|
gdf = gdf.set_crs(epsg=srid, allow_override=True)
|
|
elif gdf.crs is None:
|
|
gdf = gdf.set_crs(epsg=4326)
|
|
|
|
gpkg_path = os.path.join(GPKG_DIR, f"{table}.gpkg")
|
|
gdf.to_file(gpkg_path, driver="GPKG")
|
|
|
|
print(f"✓ {len(gdf)} 行, {time.time() - t0:.1f}s")
|
|
|
|
except Exception as e:
|
|
print(f"✗ 失败: {e}")
|
|
|
|
engine.dispose()
|
|
print(f"\n导出完成!文件目录: {GPKG_DIR}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
export_layers() |