fix: 测试数据打包进套件 data/,去掉外部输入参数
- 去掉 province/cities 参数,只保留 output_path - GeoJSON 数据放在 data/ 目录,脚本自动读取 - 版本升到 1.0.1 - MEMORY.md / TOOLS.md 补充 platform 发布参数说明 Ref: SuiteHub/agent-profiles#22
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Step 1: GeoJSON → SHP
|
Step 1: GeoJSON → SHP
|
||||||
将省界和城市 GeoJSON 文件转换为 Shapefile
|
从内置 data/ 目录读取 GeoJSON,转为 Shapefile
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
@@ -9,47 +9,47 @@ import os
|
|||||||
import geopandas as gpd
|
import geopandas as gpd
|
||||||
|
|
||||||
|
|
||||||
|
def get_data_dir():
|
||||||
|
"""返回内置 data/ 目录路径(相对脚本位置)"""
|
||||||
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
return os.path.normpath(os.path.join(script_dir, "..", "data"))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
province_path = os.environ.get("PARAM_PROVINCE", "")
|
|
||||||
cities_param = os.environ.get("PARAM_CITIES", "")
|
|
||||||
output_dir = os.environ.get("PARAM_OUTPUT_DIR", "/tmp/output/shp")
|
output_dir = os.environ.get("PARAM_OUTPUT_DIR", "/tmp/output/shp")
|
||||||
|
|
||||||
if not province_path:
|
|
||||||
print(json.dumps({"error": "缺少 province 参数", "success": False}))
|
|
||||||
sys.exit(1)
|
|
||||||
if not cities_param:
|
|
||||||
print(json.dumps({"error": "缺少 cities 参数", "success": False}))
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
os.makedirs(output_dir, exist_ok=True)
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
# 读取并转换省界
|
data_dir = get_data_dir()
|
||||||
print(json.dumps({"msg": f"读取省界: {province_path}"}))
|
|
||||||
province_gdf = gpd.read_file(province_path)
|
# 数据文件映射
|
||||||
province_shp = os.path.join(output_dir, "province.shp")
|
geo_files = {
|
||||||
province_gdf.to_file(province_shp, driver="ESRI Shapefile")
|
"province": "yunnan.geojson",
|
||||||
print(json.dumps({"msg": f"省界已转为 SHP: {province_shp}", "count": len(province_gdf)}))
|
"kunming": "kunming.geojson",
|
||||||
|
"dali": "dali.geojson",
|
||||||
|
"baise": "baise.geojson",
|
||||||
|
}
|
||||||
|
|
||||||
# 读取并转换每个城市 GeoJSON
|
|
||||||
city_files = [c.strip() for c in cities_param.split(",") if c.strip()]
|
|
||||||
converted = []
|
converted = []
|
||||||
for cf in city_files:
|
for name, filename in geo_files.items():
|
||||||
if not os.path.isfile(cf):
|
filepath = os.path.join(data_dir, filename)
|
||||||
print(json.dumps({"warn": f"文件不存在,跳过: {cf}"}))
|
if not os.path.isfile(filepath):
|
||||||
|
print(json.dumps({"warn": f"内置数据文件不存在,跳过: {filepath}"}))
|
||||||
continue
|
continue
|
||||||
print(json.dumps({"msg": f"读取城市: {cf}"}))
|
print(json.dumps({"msg": f"读取内置数据: {filename}"}))
|
||||||
gdf = gpd.read_file(cf)
|
gdf = gpd.read_file(filepath)
|
||||||
base = os.path.splitext(os.path.basename(cf))[0]
|
shp_path = os.path.join(output_dir, f"{name}.shp")
|
||||||
shp_path = os.path.join(output_dir, f"{base}.shp")
|
|
||||||
gdf.to_file(shp_path, driver="ESRI Shapefile")
|
gdf.to_file(shp_path, driver="ESRI Shapefile")
|
||||||
converted.append(base)
|
converted.append(name)
|
||||||
print(json.dumps({"msg": f"已转换: {cf} → {shp_path}", "count": len(gdf)}))
|
print(json.dumps({"msg": f"已转换: {filename} → {shp_path}", "count": len(gdf)}))
|
||||||
|
|
||||||
|
if not converted:
|
||||||
|
print(json.dumps({"error": "未找到任何内置 GeoJSON 数据", "success": False}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"success": True,
|
"success": True,
|
||||||
"province_shp": province_shp,
|
"output_dir": output_dir,
|
||||||
"city_count": len(converted),
|
"converted": converted
|
||||||
"cities": converted
|
|
||||||
}
|
}
|
||||||
print(json.dumps(result))
|
print(json.dumps(result))
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""
|
"""
|
||||||
Step 2: 叠加分析
|
Step 2: 叠加分析
|
||||||
判断各城市是否在省界内(spatial join),输出分析结果
|
判断各城市是否在省界内(使用投影坐标系避免 CRS 警告)
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
@@ -29,9 +29,7 @@ def main():
|
|||||||
print(json.dumps({"error": "省界数据为空", "success": False}))
|
print(json.dumps({"error": "省界数据为空", "success": False}))
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# 确保坐标系一致
|
# 使用投影坐标系(墨卡托)计算中心点
|
||||||
source_crs = province.crs or "EPSG:4326"
|
|
||||||
# 使用投影坐标系(墨卡托)计算中心点以避免 geographic CRS 警告
|
|
||||||
projected_crs = "EPSG:3857"
|
projected_crs = "EPSG:3857"
|
||||||
province_proj = province.to_crs(projected_crs)
|
province_proj = province.to_crs(projected_crs)
|
||||||
|
|
||||||
@@ -58,11 +56,11 @@ def main():
|
|||||||
|
|
||||||
city = city.to_crs(projected_crs)
|
city = city.to_crs(projected_crs)
|
||||||
|
|
||||||
# 空间判断:城市中心点是否在省界内(使用投影坐标系避免 CRS 警告)
|
# 空间判断:城市中心点是否在省界内
|
||||||
city_centroid = city.geometry.centroid.iloc[0]
|
city_centroid = city.geometry.centroid.iloc[0]
|
||||||
in_province = province_proj.geometry.contains(city_centroid).any()
|
in_province = province_proj.geometry.contains(city_centroid).any()
|
||||||
|
|
||||||
# 也检查 intersect 作为辅助判断
|
# 检查 intersect 作为辅助判断
|
||||||
intersects = province_proj.geometry.intersects(city.geometry).any()
|
intersects = province_proj.geometry.intersects(city.geometry).any()
|
||||||
|
|
||||||
status = "通过 ✅" if in_province else "不通过 ❌"
|
status = "通过 ✅" if in_province else "不通过 ❌"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: 云南省界叠加分析(Linux 测试)
|
name: 云南省界叠加分析(Linux 测试)
|
||||||
description: 验证 GIS Actions 4.0 Linux 双平台执行链路的测试套件。将示例 GeoJSON 转为 SHP → 叠加分析(判断城市是否在省内)→ 输出 Excel
|
description: 验证 GIS Actions 4.0 Linux 双平台执行链路的测试套件。内置云南/昆明/大理/百色 GeoJSON 示例数据,开箱即用。
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
author: SuiteForge
|
author: SuiteForge
|
||||||
platform: linux
|
platform: linux
|
||||||
slug: test-yunnan-overlay-linux
|
slug: test-yunnan-overlay-linux
|
||||||
@@ -8,14 +8,6 @@ tags: [测试, 叠加分析, Linux, 云南省]
|
|||||||
category: 测试验证
|
category: 测试验证
|
||||||
|
|
||||||
params:
|
params:
|
||||||
province:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
desc: 省界 GeoJSON 文件路径
|
|
||||||
cities:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
desc: 待分析城市 GeoJSON 文件路径,多个文件用逗号分隔
|
|
||||||
output_path:
|
output_path:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
@@ -29,8 +21,6 @@ steps:
|
|||||||
runtime: docker
|
runtime: docker
|
||||||
script_id: convert
|
script_id: convert
|
||||||
params:
|
params:
|
||||||
province: $params.province
|
|
||||||
cities: $params.cities
|
|
||||||
output_dir: /tmp/output/shp
|
output_dir: /tmp/output/shp
|
||||||
|
|
||||||
- id: overlay
|
- id: overlay
|
||||||
|
|||||||
@@ -1,60 +1,58 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""
|
"""
|
||||||
Step 1: GeoJSON → SHP (arcpy)
|
Step 1: GeoJSON → SHP (arcpy)
|
||||||
将省界和城市 GeoJSON 文件转换为 Shapefile
|
从内置 data/ 目录读取 GeoJSON,转为 Shapefile
|
||||||
使用 arcpy 的 JSON To Feature Class 工具
|
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import arcpy
|
import arcpy
|
||||||
|
|
||||||
# 允许覆写输出
|
|
||||||
arcpy.env.overwriteOutput = True
|
arcpy.env.overwriteOutput = True
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def get_data_dir():
|
||||||
province_path = os.environ.get("PARAM_PROVINCE", "")
|
"""返回内置 data/ 目录路径(相对脚本位置)"""
|
||||||
cities_param = os.environ.get("PARAM_CITIES", "")
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
output_dir = os.environ.get("PARAM_OUTPUT_DIR", r"C:\temp\output\shp")
|
return os.path.normpath(os.path.join(script_dir, "..", "data"))
|
||||||
|
|
||||||
if not province_path:
|
|
||||||
print json.dumps({"error": "缺少 province 参数", "success": False})
|
def main():
|
||||||
sys.exit(1)
|
output_dir = os.environ.get("PARAM_OUTPUT_DIR", r"C:\temp\output\shp")
|
||||||
if not cities_param:
|
|
||||||
print json.dumps({"error": "缺少 cities 参数", "success": False})
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if not os.path.isdir(output_dir):
|
if not os.path.isdir(output_dir):
|
||||||
os.makedirs(output_dir)
|
os.makedirs(output_dir)
|
||||||
|
|
||||||
# 转换省界
|
data_dir = get_data_dir()
|
||||||
print json.dumps({"msg": "转换省界: " + province_path})
|
|
||||||
province_name = os.path.splitext(os.path.basename(province_path))[0]
|
# 数据文件映射
|
||||||
province_shp = os.path.join(output_dir, "province.shp")
|
geo_files = {
|
||||||
# GeoJSON → Feature Class → Shapefile
|
"province": "yunnan.geojson",
|
||||||
arcpy.JSONToFeatures_conversion(province_path, province_shp)
|
"kunming": "kunming.geojson",
|
||||||
print json.dumps({"msg": "省界已转为 SHP: " + province_shp})
|
"dali": "dali.geojson",
|
||||||
|
"baise": "baise.geojson",
|
||||||
|
}
|
||||||
|
|
||||||
# 转换每个城市
|
|
||||||
city_files = [c.strip() for c in cities_param.split(",") if c.strip()]
|
|
||||||
converted = []
|
converted = []
|
||||||
for cf in city_files:
|
for name, filename in geo_files.items():
|
||||||
if not os.path.isfile(cf):
|
filepath = os.path.join(data_dir, filename)
|
||||||
print json.dumps({"warn": "文件不存在,跳过: " + cf})
|
if not os.path.isfile(filepath):
|
||||||
|
print json.dumps({"warn": u"内置数据文件不存在,跳过: " + filepath})
|
||||||
continue
|
continue
|
||||||
print json.dumps({"msg": "转换城市: " + cf})
|
print json.dumps({"msg": u"读取内置数据: " + filename})
|
||||||
base = os.path.splitext(os.path.basename(cf))[0]
|
shp_path = os.path.join(output_dir, name + ".shp")
|
||||||
shp_path = os.path.join(output_dir, base + ".shp")
|
arcpy.JSONToFeatures_conversion(filepath, shp_path)
|
||||||
arcpy.JSONToFeatures_conversion(cf, shp_path)
|
converted.append(name)
|
||||||
converted.append(base)
|
print json.dumps({"msg": u"已转换: " + filename + u" → " + shp_path})
|
||||||
print json.dumps({"msg": "已转换: " + cf + " -> " + shp_path})
|
|
||||||
|
if not converted:
|
||||||
|
print json.dumps({"error": u"未找到任何内置 GeoJSON 数据", "success": False})
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"success": True,
|
"success": True,
|
||||||
"province_shp": province_shp,
|
"output_dir": output_dir,
|
||||||
"city_count": len(converted),
|
"converted": converted
|
||||||
"cities": converted
|
|
||||||
}
|
}
|
||||||
print json.dumps(result)
|
print json.dumps(result)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: 云南省界叠加分析(Windows 测试)
|
name: 云南省界叠加分析(Windows 测试)
|
||||||
description: 验证 GIS Actions 4.0 Windows 执行链路的测试套件。将示例 GeoJSON 转为 SHP → 叠加分析(arcpy)→ 输出 Excel
|
description: 验证 GIS Actions 4.0 Windows 执行链路的测试套件。内置云南/昆明/大理/百色 GeoJSON 示例数据,开箱即用。
|
||||||
version: 1.0.0
|
version: 1.0.1
|
||||||
author: SuiteForge
|
author: SuiteForge
|
||||||
platform: windows
|
platform: windows
|
||||||
slug: test-yunnan-overlay-windows
|
slug: test-yunnan-overlay-windows
|
||||||
@@ -8,14 +8,6 @@ tags: [测试, 叠加分析, Windows, 云南省]
|
|||||||
category: 测试验证
|
category: 测试验证
|
||||||
|
|
||||||
params:
|
params:
|
||||||
province:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
desc: 省界 GeoJSON 文件路径
|
|
||||||
cities:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
desc: 待分析城市 GeoJSON 文件路径,多个文件用逗号分隔
|
|
||||||
output_path:
|
output_path:
|
||||||
type: string
|
type: string
|
||||||
required: true
|
required: true
|
||||||
@@ -27,8 +19,6 @@ steps:
|
|||||||
runtime: arcpy
|
runtime: arcpy
|
||||||
script_id: arcpy_convert
|
script_id: arcpy_convert
|
||||||
params:
|
params:
|
||||||
province: $params.province
|
|
||||||
cities: $params.cities
|
|
||||||
output_dir: /tmp/output/shp
|
output_dir: /tmp/output/shp
|
||||||
|
|
||||||
- id: overlay
|
- id: overlay
|
||||||
|
|||||||
Reference in New Issue
Block a user