@dsh-gis/dsh-opengis-skill 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/.editorconfig +19 -0
  2. package/CHANGELOG.md +96 -0
  3. package/LICENSE +21 -21
  4. package/README.md +91 -30
  5. package/THIRD_PARTY_NOTICES.md +37 -10
  6. package/assets/gdal/reference/raster-tools.md +538 -538
  7. package/assets/gdal/reference/vector-tools.md +149 -149
  8. package/assets/gdal-api/reference/raster-api.md +424 -424
  9. package/assets/gdal-api/reference/vector-api.md +724 -724
  10. package/assets/geometry-api-net/reference/geometry-types.md +243 -243
  11. package/assets/geopandas/reference/core-api.md +221 -221
  12. package/assets/geotools/reference/raster-rendering.md +108 -108
  13. package/assets/geotools/reference/vector-io.md +149 -149
  14. package/assets/jts/reference/geometry-operations.md +303 -303
  15. package/assets/mapsui/SKILL.md +283 -283
  16. package/assets/opengis-all/reference/data-stages.md +608 -608
  17. package/assets/opengis-all/reference/workflow-cheatsheets.md +324 -324
  18. package/assets/opengis-utils-for-java/reference/common-tasks.md +384 -384
  19. package/assets/opengis-utils-for-net/reference/code-patterns.md +124 -124
  20. package/assets/opengis-utils-for-net/reference/util-classes.md +291 -291
  21. package/assets/pyqgis/reference/processing-rendering.md +292 -292
  22. package/assets/pyqgis/reference/vector-raster-layers.md +318 -318
  23. package/assets/qgis-process/SKILL.md +414 -414
  24. package/assets/qgis-process/reference/algorithm-cheatsheet.md +194 -194
  25. package/assets/shapely/reference/operations-reference.md +199 -199
  26. package/cordis.patch.yml +6 -3
  27. package/lib/catalog.d.ts +50 -0
  28. package/lib/catalog.js +238 -0
  29. package/lib/index.d.ts +47 -6
  30. package/lib/index.js +32 -44
  31. package/lib/markdown-links.d.ts +11 -0
  32. package/lib/markdown-links.js +103 -0
  33. package/lib/skill-file.js +104 -17
  34. package/locale/en.json +1 -1
  35. package/locale/zh.json +1 -1
  36. package/package.json +11 -5
  37. package/upstream.json +64 -2
@@ -1,324 +1,324 @@
1
- # OpenGIS Workflow Examples and Cheatsheets
2
-
3
- End-to-end workflow examples, built-in algorithm cheatsheet, GDAL CLI cheatsheet, data formats and env vars split from SKILL.md.
4
-
5
- ---
6
-
7
- ## 端到端工作流示例
8
-
9
- ### 示例 1:从 Shapefile 到地图服务(全自动)
10
-
11
- 完整流程:数据检查 → 重投影 → 缓冲区分析 → 发布到 GeoServer
12
-
13
- ```bash
14
- #!/bin/bash
15
- # === 阶段一:数据检查 ===
16
- echo "=== 检查输入数据 ==="
17
- ogrinfo -json buildings.shp | jq '.layers[0].featureCount'
18
-
19
- # === 阶段二:数据处理 ===
20
- echo "=== 重投影到 EPSG:4326 ==="
21
- ogr2ogr -t_srs EPSG:4326 -f GPKG buildings_4326.gpkg buildings.shp
22
-
23
- # === 阶段三:空间分析 ===
24
- echo "=== 缓冲区分析(50米) ==="
25
- qgis_process run native:buffer --json -- \
26
- INPUT=buildings_4326.gpkg DISTANCE=50 SEGMENTS=16 OUTPUT=buildings_buffer.gpkg
27
-
28
- echo "=== 融合 ==="
29
- qgis_process run native:dissolve --json -- \
30
- INPUT=buildings_buffer.gpkg OUTPUT=buildings_dissolved.gpkg
31
-
32
- # === 阶段四:发布到 GeoServer ===
33
- GEOSERVER="http://localhost:8080/geoserver"
34
- AUTH="admin:geoserver"
35
-
36
- echo "=== 创建工作空间 ==="
37
- curl -u $AUTH -XPOST \
38
- -H "Content-Type: application/json" \
39
- -d '{"workspace":{"name":"analysis"}}' \
40
- "$GEOSERVER/rest/workspaces"
41
-
42
- echo "=== 上传并发布图层 ==="
43
- # 将 GeoPackage 转换为 Shapefile ZIP 以便上传
44
- ogr2ogr buildings_result.shp buildings_dissolved.gpkg
45
- zip buildings_result.zip buildings_result.*
46
-
47
- curl -u $AUTH -XPUT \
48
- -H "Content-Type: application/zip" \
49
- --data-binary @buildings_result.zip \
50
- "$GEOSERVER/rest/workspaces/analysis/datastores/buildings/file.shp"
51
-
52
- echo "=== 完成!==="
53
- echo "WMS 地址: $GEOSERVER/wms?service=WMS&version=1.1.1&request=GetMap&layers=analysis:buildings_result&bbox=..."
54
- ```
55
-
56
- ### 示例 2:DEM 处理到坡度图服务(Python 全流程)
57
-
58
- ```python
59
- """从 DEM 生成坡度分析并发布到 GeoServer"""
60
- import subprocess
61
- import requests
62
- from requests.auth import HTTPBasicAuth
63
-
64
- GEOSERVER = "http://localhost:8080/geoserver"
65
- AUTH = HTTPBasicAuth("admin", "geoserver")
66
-
67
- # === 阶段一:数据检查 ===
68
- subprocess.run(["gdalinfo", "dem.tif"], check=True)
69
-
70
- # === 阶段二:数据处理 — 裁剪并重投影 ===
71
- subprocess.run([
72
- "gdalwarp", "-t_srs", "EPSG:4326",
73
- "-cutline", "boundary.shp", "-crop_to_cutline",
74
- "dem.tif", "dem_clipped.tif"
75
- ], check=True)
76
-
77
- # === 阶段三:空间分析 — 坡度分析 ===
78
- subprocess.run([
79
- "qgis_process", "run", "gdal:slope", "--",
80
- "INPUT=dem_clipped.tif", "OUTPUT=slope.tif"
81
- ], check=True)
82
-
83
- # === 阶段四:发布到 GeoServer ===
84
- # 创建工作空间
85
- requests.post(
86
- f"{GEOSERVER}/rest/workspaces",
87
- json={"workspace": {"name": "terrain"}},
88
- auth=AUTH
89
- )
90
-
91
- # 上传坡度栅格
92
- with open("slope.tif", "rb") as f:
93
- requests.put(
94
- f"{GEOSERVER}/rest/workspaces/terrain/coveragestores/slope/file.geotiff",
95
- data=f,
96
- headers={"Content-Type": "image/tiff"},
97
- auth=AUTH
98
- )
99
-
100
- print("坡度图层已发布!")
101
- print(f"WMS: {GEOSERVER}/wms?service=WMS&version=1.1.1&request=GetMap&layers=terrain:slope")
102
- ```
103
-
104
- ### 示例 3:PyQGIS 完整分析流程
105
-
106
- ```python
107
- """PyQGIS 独立脚本:加载数据 → 分析 → 导出 → 发布"""
108
- import sys
109
- import requests
110
- from requests.auth import HTTPBasicAuth
111
- from qgis.core import QgsApplication, QgsVectorLayer, QgsProject
112
- import processing
113
- from processing.core.Processing import Processing
114
-
115
- # 初始化 QGIS
116
- qgs = QgsApplication([], False)
117
- qgs.setPrefixPath("/usr", True)
118
- qgs.initQgis()
119
- Processing.initialize()
120
-
121
- # === 阶段一:加载数据 ===
122
- layer = QgsVectorLayer("/data/buildings.shp", "buildings", "ogr")
123
- assert layer.isValid(), "图层加载失败"
124
- print(f"加载完成: {layer.featureCount()} 个要素")
125
-
126
- # === 阶段二:重投影 ===
127
- result1 = processing.run("native:reprojectlayer", {
128
- 'INPUT': layer,
129
- 'TARGET_CRS': 'EPSG:4326',
130
- 'OUTPUT': 'memory:reprojected'
131
- })
132
-
133
- # === 阶段三:缓冲区 + 融合 ===
134
- result2 = processing.run("native:buffer", {
135
- 'INPUT': result1['OUTPUT'],
136
- 'DISTANCE': 100,
137
- 'SEGMENTS': 16,
138
- 'OUTPUT': 'memory:buffered'
139
- })
140
-
141
- result3 = processing.run("native:dissolve", {
142
- 'INPUT': result2['OUTPUT'],
143
- 'OUTPUT': '/data/buildings_analysis.gpkg'
144
- })
145
- print(f"分析完成: {result3['OUTPUT']}")
146
-
147
- # === 阶段四:发布到 GeoServer ===
148
- GEOSERVER = "http://localhost:8080/geoserver"
149
- AUTH = HTTPBasicAuth("admin", "geoserver")
150
-
151
- # 转换为 Shapefile ZIP 以上传
152
- processing.run("native:reprojectlayer", {
153
- 'INPUT': result3['OUTPUT'],
154
- 'TARGET_CRS': 'EPSG:4326',
155
- 'OUTPUT': '/data/for_upload.shp'
156
- })
157
-
158
- import zipfile, glob
159
- with zipfile.ZipFile("/data/for_upload.zip", "w") as zf:
160
- for f in glob.glob("/data/for_upload.*"):
161
- zf.write(f, f.split("/")[-1])
162
-
163
- requests.post(f"{GEOSERVER}/rest/workspaces",
164
- json={"workspace": {"name": "analysis"}}, auth=AUTH)
165
-
166
- with open("/data/for_upload.zip", "rb") as f:
167
- requests.put(
168
- f"{GEOSERVER}/rest/workspaces/analysis/datastores/buildings/file.shp",
169
- data=f, headers={"Content-Type": "application/zip"}, auth=AUTH
170
- )
171
-
172
- print("图层已发布到 GeoServer!")
173
-
174
- qgs.exitQgis()
175
- ```
176
-
177
- ### 示例 4:使用 qgis_process JSON 模式的自动化流水线
178
-
179
- ```bash
180
- #!/bin/bash
181
- # 适用于 CI/CD 自动化流水线
182
- export QT_QPA_PLATFORM=offscreen
183
-
184
- # 步骤 1:缓冲区分析(JSON 输入)
185
- echo '{
186
- "inputs": {
187
- "INPUT": "/data/roads.shp",
188
- "DISTANCE": 50,
189
- "SEGMENTS": 10,
190
- "OUTPUT": "/data/roads_buffer.gpkg"
191
- }
192
- }' | qgis_process run native:buffer -
193
-
194
- # 步骤 2:解析输出路径
195
- BUFFER_OUTPUT=$(echo '{
196
- "inputs": {
197
- "INPUT": "/data/roads.shp",
198
- "DISTANCE": 50,
199
- "SEGMENTS": 10,
200
- "OUTPUT": "/data/roads_buffer.gpkg"
201
- }
202
- }' | qgis_process run native:buffer - | jq -r '.results.OUTPUT')
203
-
204
- # 步骤 3:融合
205
- qgis_process run native:dissolve --json -- \
206
- INPUT="$BUFFER_OUTPUT" OUTPUT=/data/roads_dissolved.gpkg
207
-
208
- # 步骤 4:发布到 GeoServer
209
- ogr2ogr roads_final.shp /data/roads_dissolved.gpkg
210
- zip roads_final.zip roads_final.*
211
-
212
- curl -u admin:geoserver -XPUT \
213
- -H "Content-Type: application/zip" \
214
- --data-binary @roads_final.zip \
215
- "http://localhost:8080/geoserver/rest/workspaces/myws/datastores/roads/file.shp"
216
- ```
217
-
218
- ---
219
-
220
- ## 常用内置算法速查(qgis_process / PyQGIS)
221
-
222
- ### 矢量分析
223
-
224
- | 算法 ID | 说明 | 关键参数 |
225
- |---------|------|---------|
226
- | `native:buffer` | 缓冲区分析 | INPUT, DISTANCE, SEGMENTS, DISSOLVE |
227
- | `native:clip` | 矢量裁剪 | INPUT, OVERLAY |
228
- | `native:dissolve` | 融合 | INPUT, FIELD |
229
- | `native:intersection` | 交集 | INPUT, OVERLAY |
230
- | `native:union` | 联合 | INPUT, OVERLAY |
231
- | `native:difference` | 差集 | INPUT, OVERLAY |
232
- | `native:symmetricaldifference` | 对称差 | INPUT, OVERLAY |
233
- | `native:centroids` | 质心 | INPUT |
234
- | `native:convexhull` | 凸包 | INPUT |
235
- | `native:simplifygeometries` | 简化几何 | INPUT, TOLERANCE |
236
- | `native:reprojectlayer` | 重投影 | INPUT, TARGET_CRS |
237
- | `native:mergevectorlayers` | 合并图层 | LAYERS |
238
- | `native:splitvectorlayer` | 拆分图层 | INPUT, FIELD |
239
- | `native:extractbyattribute` | 按属性提取 | INPUT, FIELD, OPERATOR, VALUE |
240
- | `native:extractbylocation` | 按位置提取 | INPUT, INTERSECT, PREDICATE |
241
- | `native:joinattributesbylocation` | 按位置连接属性 | INPUT, JOIN, PREDICATE |
242
- | `native:fixgeometries` | 修复几何 | INPUT |
243
- | `native:countpointsinpolygon` | 多边形内点计数 | POLYGONS, POINTS |
244
- | `native:voronoipolygons` | 泰森多边形 | INPUT |
245
- | `native:creategrid` | 创建网格 | TYPE, EXTENT, HSPACING, VSPACING |
246
- | `native:fieldcalculator` | 字段计算器 | INPUT, FIELD_NAME, FORMULA |
247
-
248
- ### 栅格分析
249
-
250
- | 算法 ID | 说明 | 关键参数 |
251
- |---------|------|---------|
252
- | `native:rasterlayerstatistics` | 栅格统计 | INPUT |
253
- | `gdal:cliprasterbyextent` | 按范围裁剪栅格 | INPUT, EXTENT |
254
- | `gdal:cliprasterbymask` | 按掩膜裁剪栅格 | INPUT, MASK |
255
- | `gdal:merge` | 栅格合并 | INPUT |
256
- | `gdal:warpreproject` | 栅格重投影 | INPUT, TARGET_CRS |
257
- | `gdal:contour` | 等值线提取 | INPUT, INTERVAL |
258
- | `gdal:polygonize` | 栅格转矢量 | INPUT |
259
- | `gdal:rasterize` | 矢量转栅格 | INPUT, FIELD |
260
- | `gdal:hillshade` | 山体阴影 | INPUT |
261
- | `gdal:slope` | 坡度分析 | INPUT |
262
- | `gdal:aspect` | 坡向分析 | INPUT |
263
- | `gdal:roughness` | 粗糙度 | INPUT |
264
- | `gdal:buildvirtualraster` | 构建虚拟栅格 | INPUT |
265
-
266
- ---
267
-
268
- ## GDAL 命令行工具速查
269
-
270
- ### 矢量工具
271
-
272
- | 命令 | 说明 |
273
- |------|------|
274
- | `ogrinfo` | 矢量数据信息查询 |
275
- | `ogr2ogr` | 矢量格式转换和处理 |
276
-
277
- ### 栅格工具
278
-
279
- | 命令 | 说明 |
280
- |------|------|
281
- | `gdalinfo` | 栅格数据信息查询 |
282
- | `gdal_translate` | 栅格格式转换和重采样 |
283
- | `gdalwarp` | 栅格重投影和镶嵌 |
284
- | `gdal_merge.py` | 栅格镶嵌融合 |
285
- | `gdal_calc.py` | 栅格计算器(NumPy 语法) |
286
- | `gdal_contour` | 等值线提取 |
287
- | `gdal_grid` | 散点数据插值创建网格 |
288
- | `gdal_polygonize.py` | 栅格转矢量 |
289
- | `gdaltindex` | 创建栅格瓦片索引 |
290
- | `gdal_edit.py` | 编辑栅格元数据 |
291
- | `nearblack` | 清理黑白边界 |
292
-
293
- ---
294
-
295
- ## 数据格式支持
296
-
297
- ### 矢量格式
298
-
299
- | 格式 | 扩展名 | 说明 |
300
- |------|--------|------|
301
- | Shapefile | .shp | ESRI 标准格式 |
302
- | GeoJSON | .geojson | Web 标准 JSON |
303
- | GeoPackage | .gpkg | SQLite 基础,推荐 |
304
- | KML | .kml | Google Maps 格式 |
305
- | PostGIS | N/A | 数据库矢量存储 |
306
- | GML | .gml | ISO 标准 XML |
307
- | CSV | .csv | 点数据 |
308
- | FlatGeobuf | .fgb | 高性能流式二进制格式 |
309
-
310
- ### 栅格格式
311
-
312
- | 格式 | 扩展名 | 说明 |
313
- |------|--------|------|
314
- | GeoTIFF | .tif | 标准地理栅格(推荐) |
315
- | COG | .tif | 云优化 GeoTIFF |
316
- | PNG | .png | Web 图像 |
317
- | JPEG | .jpg | 有损压缩 |
318
- | NetCDF | .nc | 科学数据 |
319
- | HDF5 | .h5 | 多维数据 |
320
- | JPEG2000 | .jp2 | 高质量压缩 |
321
- | ASCII Grid | .asc | 简单栅格 |
322
-
323
- ---
324
-
1
+ # OpenGIS Workflow Examples and Cheatsheets
2
+
3
+ End-to-end workflow examples, built-in algorithm cheatsheet, GDAL CLI cheatsheet, data formats and env vars split from SKILL.md.
4
+
5
+ ---
6
+
7
+ ## 端到端工作流示例
8
+
9
+ ### 示例 1:从 Shapefile 到地图服务(全自动)
10
+
11
+ 完整流程:数据检查 → 重投影 → 缓冲区分析 → 发布到 GeoServer
12
+
13
+ ```bash
14
+ #!/bin/bash
15
+ # === 阶段一:数据检查 ===
16
+ echo "=== 检查输入数据 ==="
17
+ ogrinfo -json buildings.shp | jq '.layers[0].featureCount'
18
+
19
+ # === 阶段二:数据处理 ===
20
+ echo "=== 重投影到 EPSG:4326 ==="
21
+ ogr2ogr -t_srs EPSG:4326 -f GPKG buildings_4326.gpkg buildings.shp
22
+
23
+ # === 阶段三:空间分析 ===
24
+ echo "=== 缓冲区分析(50米) ==="
25
+ qgis_process run native:buffer --json -- \
26
+ INPUT=buildings_4326.gpkg DISTANCE=50 SEGMENTS=16 OUTPUT=buildings_buffer.gpkg
27
+
28
+ echo "=== 融合 ==="
29
+ qgis_process run native:dissolve --json -- \
30
+ INPUT=buildings_buffer.gpkg OUTPUT=buildings_dissolved.gpkg
31
+
32
+ # === 阶段四:发布到 GeoServer ===
33
+ GEOSERVER="http://localhost:8080/geoserver"
34
+ AUTH="admin:geoserver"
35
+
36
+ echo "=== 创建工作空间 ==="
37
+ curl -u $AUTH -XPOST \
38
+ -H "Content-Type: application/json" \
39
+ -d '{"workspace":{"name":"analysis"}}' \
40
+ "$GEOSERVER/rest/workspaces"
41
+
42
+ echo "=== 上传并发布图层 ==="
43
+ # 将 GeoPackage 转换为 Shapefile ZIP 以便上传
44
+ ogr2ogr buildings_result.shp buildings_dissolved.gpkg
45
+ zip buildings_result.zip buildings_result.*
46
+
47
+ curl -u $AUTH -XPUT \
48
+ -H "Content-Type: application/zip" \
49
+ --data-binary @buildings_result.zip \
50
+ "$GEOSERVER/rest/workspaces/analysis/datastores/buildings/file.shp"
51
+
52
+ echo "=== 完成!==="
53
+ echo "WMS 地址: $GEOSERVER/wms?service=WMS&version=1.1.1&request=GetMap&layers=analysis:buildings_result&bbox=..."
54
+ ```
55
+
56
+ ### 示例 2:DEM 处理到坡度图服务(Python 全流程)
57
+
58
+ ```python
59
+ """从 DEM 生成坡度分析并发布到 GeoServer"""
60
+ import subprocess
61
+ import requests
62
+ from requests.auth import HTTPBasicAuth
63
+
64
+ GEOSERVER = "http://localhost:8080/geoserver"
65
+ AUTH = HTTPBasicAuth("admin", "geoserver")
66
+
67
+ # === 阶段一:数据检查 ===
68
+ subprocess.run(["gdalinfo", "dem.tif"], check=True)
69
+
70
+ # === 阶段二:数据处理 — 裁剪并重投影 ===
71
+ subprocess.run([
72
+ "gdalwarp", "-t_srs", "EPSG:4326",
73
+ "-cutline", "boundary.shp", "-crop_to_cutline",
74
+ "dem.tif", "dem_clipped.tif"
75
+ ], check=True)
76
+
77
+ # === 阶段三:空间分析 — 坡度分析 ===
78
+ subprocess.run([
79
+ "qgis_process", "run", "gdal:slope", "--",
80
+ "INPUT=dem_clipped.tif", "OUTPUT=slope.tif"
81
+ ], check=True)
82
+
83
+ # === 阶段四:发布到 GeoServer ===
84
+ # 创建工作空间
85
+ requests.post(
86
+ f"{GEOSERVER}/rest/workspaces",
87
+ json={"workspace": {"name": "terrain"}},
88
+ auth=AUTH
89
+ )
90
+
91
+ # 上传坡度栅格
92
+ with open("slope.tif", "rb") as f:
93
+ requests.put(
94
+ f"{GEOSERVER}/rest/workspaces/terrain/coveragestores/slope/file.geotiff",
95
+ data=f,
96
+ headers={"Content-Type": "image/tiff"},
97
+ auth=AUTH
98
+ )
99
+
100
+ print("坡度图层已发布!")
101
+ print(f"WMS: {GEOSERVER}/wms?service=WMS&version=1.1.1&request=GetMap&layers=terrain:slope")
102
+ ```
103
+
104
+ ### 示例 3:PyQGIS 完整分析流程
105
+
106
+ ```python
107
+ """PyQGIS 独立脚本:加载数据 → 分析 → 导出 → 发布"""
108
+ import sys
109
+ import requests
110
+ from requests.auth import HTTPBasicAuth
111
+ from qgis.core import QgsApplication, QgsVectorLayer, QgsProject
112
+ import processing
113
+ from processing.core.Processing import Processing
114
+
115
+ # 初始化 QGIS
116
+ qgs = QgsApplication([], False)
117
+ qgs.setPrefixPath("/usr", True)
118
+ qgs.initQgis()
119
+ Processing.initialize()
120
+
121
+ # === 阶段一:加载数据 ===
122
+ layer = QgsVectorLayer("/data/buildings.shp", "buildings", "ogr")
123
+ assert layer.isValid(), "图层加载失败"
124
+ print(f"加载完成: {layer.featureCount()} 个要素")
125
+
126
+ # === 阶段二:重投影 ===
127
+ result1 = processing.run("native:reprojectlayer", {
128
+ 'INPUT': layer,
129
+ 'TARGET_CRS': 'EPSG:4326',
130
+ 'OUTPUT': 'memory:reprojected'
131
+ })
132
+
133
+ # === 阶段三:缓冲区 + 融合 ===
134
+ result2 = processing.run("native:buffer", {
135
+ 'INPUT': result1['OUTPUT'],
136
+ 'DISTANCE': 100,
137
+ 'SEGMENTS': 16,
138
+ 'OUTPUT': 'memory:buffered'
139
+ })
140
+
141
+ result3 = processing.run("native:dissolve", {
142
+ 'INPUT': result2['OUTPUT'],
143
+ 'OUTPUT': '/data/buildings_analysis.gpkg'
144
+ })
145
+ print(f"分析完成: {result3['OUTPUT']}")
146
+
147
+ # === 阶段四:发布到 GeoServer ===
148
+ GEOSERVER = "http://localhost:8080/geoserver"
149
+ AUTH = HTTPBasicAuth("admin", "geoserver")
150
+
151
+ # 转换为 Shapefile ZIP 以上传
152
+ processing.run("native:reprojectlayer", {
153
+ 'INPUT': result3['OUTPUT'],
154
+ 'TARGET_CRS': 'EPSG:4326',
155
+ 'OUTPUT': '/data/for_upload.shp'
156
+ })
157
+
158
+ import zipfile, glob
159
+ with zipfile.ZipFile("/data/for_upload.zip", "w") as zf:
160
+ for f in glob.glob("/data/for_upload.*"):
161
+ zf.write(f, f.split("/")[-1])
162
+
163
+ requests.post(f"{GEOSERVER}/rest/workspaces",
164
+ json={"workspace": {"name": "analysis"}}, auth=AUTH)
165
+
166
+ with open("/data/for_upload.zip", "rb") as f:
167
+ requests.put(
168
+ f"{GEOSERVER}/rest/workspaces/analysis/datastores/buildings/file.shp",
169
+ data=f, headers={"Content-Type": "application/zip"}, auth=AUTH
170
+ )
171
+
172
+ print("图层已发布到 GeoServer!")
173
+
174
+ qgs.exitQgis()
175
+ ```
176
+
177
+ ### 示例 4:使用 qgis_process JSON 模式的自动化流水线
178
+
179
+ ```bash
180
+ #!/bin/bash
181
+ # 适用于 CI/CD 自动化流水线
182
+ export QT_QPA_PLATFORM=offscreen
183
+
184
+ # 步骤 1:缓冲区分析(JSON 输入)
185
+ echo '{
186
+ "inputs": {
187
+ "INPUT": "/data/roads.shp",
188
+ "DISTANCE": 50,
189
+ "SEGMENTS": 10,
190
+ "OUTPUT": "/data/roads_buffer.gpkg"
191
+ }
192
+ }' | qgis_process run native:buffer -
193
+
194
+ # 步骤 2:解析输出路径
195
+ BUFFER_OUTPUT=$(echo '{
196
+ "inputs": {
197
+ "INPUT": "/data/roads.shp",
198
+ "DISTANCE": 50,
199
+ "SEGMENTS": 10,
200
+ "OUTPUT": "/data/roads_buffer.gpkg"
201
+ }
202
+ }' | qgis_process run native:buffer - | jq -r '.results.OUTPUT')
203
+
204
+ # 步骤 3:融合
205
+ qgis_process run native:dissolve --json -- \
206
+ INPUT="$BUFFER_OUTPUT" OUTPUT=/data/roads_dissolved.gpkg
207
+
208
+ # 步骤 4:发布到 GeoServer
209
+ ogr2ogr roads_final.shp /data/roads_dissolved.gpkg
210
+ zip roads_final.zip roads_final.*
211
+
212
+ curl -u admin:geoserver -XPUT \
213
+ -H "Content-Type: application/zip" \
214
+ --data-binary @roads_final.zip \
215
+ "http://localhost:8080/geoserver/rest/workspaces/myws/datastores/roads/file.shp"
216
+ ```
217
+
218
+ ---
219
+
220
+ ## 常用内置算法速查(qgis_process / PyQGIS)
221
+
222
+ ### 矢量分析
223
+
224
+ | 算法 ID | 说明 | 关键参数 |
225
+ |---------|------|---------|
226
+ | `native:buffer` | 缓冲区分析 | INPUT, DISTANCE, SEGMENTS, DISSOLVE |
227
+ | `native:clip` | 矢量裁剪 | INPUT, OVERLAY |
228
+ | `native:dissolve` | 融合 | INPUT, FIELD |
229
+ | `native:intersection` | 交集 | INPUT, OVERLAY |
230
+ | `native:union` | 联合 | INPUT, OVERLAY |
231
+ | `native:difference` | 差集 | INPUT, OVERLAY |
232
+ | `native:symmetricaldifference` | 对称差 | INPUT, OVERLAY |
233
+ | `native:centroids` | 质心 | INPUT |
234
+ | `native:convexhull` | 凸包 | INPUT |
235
+ | `native:simplifygeometries` | 简化几何 | INPUT, TOLERANCE |
236
+ | `native:reprojectlayer` | 重投影 | INPUT, TARGET_CRS |
237
+ | `native:mergevectorlayers` | 合并图层 | LAYERS |
238
+ | `native:splitvectorlayer` | 拆分图层 | INPUT, FIELD |
239
+ | `native:extractbyattribute` | 按属性提取 | INPUT, FIELD, OPERATOR, VALUE |
240
+ | `native:extractbylocation` | 按位置提取 | INPUT, INTERSECT, PREDICATE |
241
+ | `native:joinattributesbylocation` | 按位置连接属性 | INPUT, JOIN, PREDICATE |
242
+ | `native:fixgeometries` | 修复几何 | INPUT |
243
+ | `native:countpointsinpolygon` | 多边形内点计数 | POLYGONS, POINTS |
244
+ | `native:voronoipolygons` | 泰森多边形 | INPUT |
245
+ | `native:creategrid` | 创建网格 | TYPE, EXTENT, HSPACING, VSPACING |
246
+ | `native:fieldcalculator` | 字段计算器 | INPUT, FIELD_NAME, FORMULA |
247
+
248
+ ### 栅格分析
249
+
250
+ | 算法 ID | 说明 | 关键参数 |
251
+ |---------|------|---------|
252
+ | `native:rasterlayerstatistics` | 栅格统计 | INPUT |
253
+ | `gdal:cliprasterbyextent` | 按范围裁剪栅格 | INPUT, EXTENT |
254
+ | `gdal:cliprasterbymask` | 按掩膜裁剪栅格 | INPUT, MASK |
255
+ | `gdal:merge` | 栅格合并 | INPUT |
256
+ | `gdal:warpreproject` | 栅格重投影 | INPUT, TARGET_CRS |
257
+ | `gdal:contour` | 等值线提取 | INPUT, INTERVAL |
258
+ | `gdal:polygonize` | 栅格转矢量 | INPUT |
259
+ | `gdal:rasterize` | 矢量转栅格 | INPUT, FIELD |
260
+ | `gdal:hillshade` | 山体阴影 | INPUT |
261
+ | `gdal:slope` | 坡度分析 | INPUT |
262
+ | `gdal:aspect` | 坡向分析 | INPUT |
263
+ | `gdal:roughness` | 粗糙度 | INPUT |
264
+ | `gdal:buildvirtualraster` | 构建虚拟栅格 | INPUT |
265
+
266
+ ---
267
+
268
+ ## GDAL 命令行工具速查
269
+
270
+ ### 矢量工具
271
+
272
+ | 命令 | 说明 |
273
+ |------|------|
274
+ | `ogrinfo` | 矢量数据信息查询 |
275
+ | `ogr2ogr` | 矢量格式转换和处理 |
276
+
277
+ ### 栅格工具
278
+
279
+ | 命令 | 说明 |
280
+ |------|------|
281
+ | `gdalinfo` | 栅格数据信息查询 |
282
+ | `gdal_translate` | 栅格格式转换和重采样 |
283
+ | `gdalwarp` | 栅格重投影和镶嵌 |
284
+ | `gdal_merge.py` | 栅格镶嵌融合 |
285
+ | `gdal_calc.py` | 栅格计算器(NumPy 语法) |
286
+ | `gdal_contour` | 等值线提取 |
287
+ | `gdal_grid` | 散点数据插值创建网格 |
288
+ | `gdal_polygonize.py` | 栅格转矢量 |
289
+ | `gdaltindex` | 创建栅格瓦片索引 |
290
+ | `gdal_edit.py` | 编辑栅格元数据 |
291
+ | `nearblack` | 清理黑白边界 |
292
+
293
+ ---
294
+
295
+ ## 数据格式支持
296
+
297
+ ### 矢量格式
298
+
299
+ | 格式 | 扩展名 | 说明 |
300
+ |------|--------|------|
301
+ | Shapefile | .shp | ESRI 标准格式 |
302
+ | GeoJSON | .geojson | Web 标准 JSON |
303
+ | GeoPackage | .gpkg | SQLite 基础,推荐 |
304
+ | KML | .kml | Google Maps 格式 |
305
+ | PostGIS | N/A | 数据库矢量存储 |
306
+ | GML | .gml | ISO 标准 XML |
307
+ | CSV | .csv | 点数据 |
308
+ | FlatGeobuf | .fgb | 高性能流式二进制格式 |
309
+
310
+ ### 栅格格式
311
+
312
+ | 格式 | 扩展名 | 说明 |
313
+ |------|--------|------|
314
+ | GeoTIFF | .tif | 标准地理栅格(推荐) |
315
+ | COG | .tif | 云优化 GeoTIFF |
316
+ | PNG | .png | Web 图像 |
317
+ | JPEG | .jpg | 有损压缩 |
318
+ | NetCDF | .nc | 科学数据 |
319
+ | HDF5 | .h5 | 多维数据 |
320
+ | JPEG2000 | .jp2 | 高质量压缩 |
321
+ | ASCII Grid | .asc | 简单栅格 |
322
+
323
+ ---
324
+