@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,384 +1,384 @@
1
- # OpenGIS Utils for Java Common Tasks Reference
2
-
3
- Common task quick reference split from SKILL.md.
4
-
5
- ---
6
-
7
- ## Quick Reference: Common Tasks
8
-
9
- ### 1. Read a GIS Layer (Shapefile / GeoJSON / PostGIS / FileGDB / TXT)
10
-
11
- ```java
12
- import com.znlgis.ogu4j.datasource.OguLayerUtil;
13
- import com.znlgis.ogu4j.engine.enums.DataFormatType;
14
- import com.znlgis.ogu4j.engine.enums.GisEngineType;
15
- import com.znlgis.ogu4j.engine.model.layer.OguLayer;
16
-
17
- // Read Shapefile (GeoTools engine)
18
- OguLayer layer = OguLayerUtil.readLayer(
19
- DataFormatType.SHP, // format
20
- "/path/to/file.shp", // path or connection string
21
- null, // layer name (null for single-layer formats)
22
- null, // attribute filter (CQL expression, e.g. "NAME = 'Beijing'")
23
- null, // spatial filter (WKT geometry)
24
- GisEngineType.AUTO // engine: AUTO, GEOTOOLS, or GDAL
25
- );
26
-
27
- // Read GeoJSON
28
- OguLayer layer = OguLayerUtil.readLayer(
29
- DataFormatType.GEOJSON, "/path/to/file.geojson",
30
- null, null, null, GisEngineType.GEOTOOLS
31
- );
32
-
33
- // Read FileGDB layer (requires GDAL)
34
- OguLayer layer = OguLayerUtil.readLayer(
35
- DataFormatType.FILEGDB, "/path/to/data.gdb",
36
- "layerName", null, null, GisEngineType.GDAL
37
- );
38
-
39
- // Read PostGIS (use environment variables or secure config for credentials in production)
40
- String connStr = "PG: host=localhost port=5432 dbname=gisdb user=postgres password=*** active_schema=public";
41
- OguLayer layer = OguLayerUtil.readLayer(
42
- DataFormatType.POSTGIS, connStr,
43
- "table_name", null, null, GisEngineType.GEOTOOLS
44
- );
45
-
46
- // Read National Land TXT
47
- import com.znlgis.ogu4j.datasource.GtTxtUtil;
48
- OguLayer layer = GtTxtUtil.loadTxt("/path/to/file.txt", null); // null = auto-detect fields
49
- ```
50
-
51
- ### 2. Write a GIS Layer
52
-
53
- ```java
54
- import com.znlgis.ogu4j.datasource.OguLayerUtil;
55
-
56
- // Write to Shapefile
57
- OguLayerUtil.writeLayer(
58
- DataFormatType.SHP,
59
- layer, // OguLayer object
60
- "/path/to/output.shp", // output path
61
- null, // layer name
62
- null, // options map (format-specific)
63
- GisEngineType.GEOTOOLS
64
- );
65
-
66
- // Write to GeoJSON
67
- OguLayerUtil.writeLayer(
68
- DataFormatType.GEOJSON, layer,
69
- "/path/to/output.geojson", null, null, GisEngineType.GEOTOOLS
70
- );
71
-
72
- // Write to FileGDB (with options)
73
- Map<String, Object> options = new HashMap<>();
74
- options.put("featureDataset", "datasetName");
75
- OguLayerUtil.writeLayer(
76
- DataFormatType.FILEGDB, layer,
77
- "/path/to/data.gdb", "layerName", options, GisEngineType.GDAL
78
- );
79
-
80
- // Write to PostGIS
81
- OguLayerUtil.writeLayer(
82
- DataFormatType.POSTGIS, layer,
83
- connStr, "table_name", null, GisEngineType.GEOTOOLS
84
- );
85
-
86
- // Write National Land TXT
87
- import com.znlgis.ogu4j.engine.model.layer.OguLayerMetadata;
88
- OguLayerMetadata metadata = new OguLayerMetadata();
89
- metadata.setCoordinateSystemName("2000国家大地坐标系");
90
- metadata.setZoneDivision("3");
91
- metadata.setProjectionType("高斯克吕格");
92
- metadata.setMeasureUnit("米");
93
- GtTxtUtil.saveTxt(layer, "/path/to/output.txt", metadata, null, 39);
94
- ```
95
-
96
- ### 3. Format Conversion (One-Step)
97
-
98
- ```java
99
- // SHP → GeoJSON
100
- OguLayer layer = OguLayerUtil.readLayer(DataFormatType.SHP, shpPath, null, null, null, GisEngineType.AUTO);
101
- OguLayerUtil.writeLayer(DataFormatType.GEOJSON, layer, geojsonPath, null, null, GisEngineType.AUTO);
102
-
103
- // GeoJSON → PostGIS
104
- OguLayer layer = OguLayerUtil.readLayer(DataFormatType.GEOJSON, geojsonPath, null, null, null, GisEngineType.AUTO);
105
- OguLayerUtil.writeLayer(DataFormatType.POSTGIS, layer, connStr, "tableName", null, GisEngineType.AUTO);
106
- ```
107
-
108
- ### 4. Work with the Layer Model
109
-
110
- ```java
111
- import com.znlgis.ogu4j.engine.model.layer.*;
112
- import com.znlgis.ogu4j.engine.enums.*;
113
-
114
- // Create a layer from scratch
115
- OguLayer layer = new OguLayer();
116
- layer.setName("cities");
117
- layer.setWkid(4490); // CGCS2000 geographic
118
- layer.setGeometryType(GeometryType.POINT);
119
-
120
- // Define fields
121
- List<OguField> fields = new ArrayList<>();
122
- fields.add(new OguField("name", "城市名称", FieldDataType.STRING));
123
- fields.add(new OguField("population", "人口", FieldDataType.INTEGER));
124
- layer.setFields(fields);
125
-
126
- // Create features
127
- OguFeature feature = new OguFeature();
128
- feature.setId("1");
129
- feature.setGeometry("POINT(116.4 39.9)"); // WKT format
130
- List<OguFieldValue> attrs = new ArrayList<>();
131
- attrs.add(new OguFieldValue(fields.get(0), "北京"));
132
- attrs.add(new OguFieldValue(fields.get(1), 21540000));
133
- feature.setAttributes(attrs);
134
- layer.setFeatures(List.of(feature));
135
-
136
- // Validate layer
137
- layer.validate(); // throws LayerValidationException if invalid
138
-
139
- // Serialize to/from JSON
140
- String json = layer.toJSON();
141
- OguLayer restored = OguLayer.fromJSON(json);
142
-
143
- // Filter features by attribute
144
- List<OguFeature> filtered = layer.filter(f -> {
145
- Integer pop = f.getAttribute("population").getIntValue();
146
- return pop != null && pop > 10000000; // population > 10 million
147
- });
148
-
149
- // Access feature attributes
150
- OguFeature f = layer.getFeatures().get(0);
151
- String name = f.getAttribute("name").getStringValue();
152
- Object val = f.getValue("name");
153
- f.setValue("name", "新名称");
154
-
155
- // Get counts
156
- int featureCount = layer.getFeatureCount();
157
- int fieldCount = layer.getFieldCount();
158
- ```
159
-
160
- ### 5. Geometry Operations (GeometryUtil)
161
-
162
- ```java
163
- import com.znlgis.ogu4j.geometry.GeometryUtil;
164
- import org.locationtech.jts.geom.Geometry;
165
-
166
- // === Format Conversions ===
167
- Geometry geom = GeometryUtil.wkt2Geometry("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))");
168
- String wkt = GeometryUtil.geometry2Wkt(geom);
169
- String geojson = GeometryUtil.geometry2Geojson(geom);
170
- String esriJson = GeometryUtil.geometry2EsriJson(geom, 4490);
171
-
172
- // WKT ↔ GeoJSON
173
- String geojson = GeometryUtil.wkt2Geojson(wkt);
174
- String wkt = GeometryUtil.geojson2Wkt(geojson);
175
-
176
- // WKT ↔ ESRI JSON
177
- String esriJson = GeometryUtil.wkt2EsriJson(wkt, 4490);
178
- String wkt = GeometryUtil.esriJson2Wkt(esriJson);
179
-
180
- // GeoJSON ↔ ESRI JSON
181
- String esriJson = GeometryUtil.geoJson2EsriJson(4490, geojson);
182
- String geojson = GeometryUtil.esriJson2GeoJson(esriJson);
183
-
184
- // GeoJSON / ESRI JSON → JTS Geometry
185
- Geometry geom = GeometryUtil.geojson2Geometry(geojson);
186
- Geometry geom = GeometryUtil.esriJson2Geometry(esriJson);
187
-
188
- // === Spatial Relations (JTS Geometry-based) ===
189
- boolean result = GeometryUtil.intersects(geomA, geomB);
190
- boolean result = GeometryUtil.contains(geomA, geomB);
191
- boolean result = GeometryUtil.within(geomA, geomB);
192
- boolean result = GeometryUtil.touches(geomA, geomB);
193
- boolean result = GeometryUtil.crosses(geomA, geomB);
194
- boolean result = GeometryUtil.overlaps(geomA, geomB);
195
- boolean result = GeometryUtil.disjoint(geomA, geomB);
196
- String de9im = GeometryUtil.relate(geomA, geomB);
197
- boolean result = GeometryUtil.relatePattern(geomA, geomB, "T*T***FF*");
198
-
199
- // === Spatial Analysis (JTS Geometry-based) ===
200
- Geometry buffer = GeometryUtil.buffer(geom, 100.0);
201
- Geometry intersection = GeometryUtil.intersection(geomA, geomB);
202
- Geometry union = GeometryUtil.union(geomA, geomB); // also accepts varargs
203
- Geometry difference = GeometryUtil.difference(geomA, geomB);
204
- Geometry symDiff = GeometryUtil.symDifference(geomA, geomB);
205
- Geometry convexHull = GeometryUtil.convexHull(geom);
206
- Geometry concaveHull = GeometryUtil.concaveHull(geom);
207
- Geometry splitResult = GeometryUtil.splitPolygon(polygon, line);
208
- Geometry polygonized = GeometryUtil.polygonize(geom);
209
-
210
- // === Geometry Properties ===
211
- double area = GeometryUtil.area(geom);
212
- double length = GeometryUtil.length(geom);
213
- double distance = GeometryUtil.distance(geomA, geomB);
214
- boolean withinDist = GeometryUtil.isWithinDistance(geomA, geomB, 500.0);
215
- Geometry centroid = GeometryUtil.centroid(geom);
216
- Geometry interiorPt = GeometryUtil.interiorPoint(geom);
217
- Geometry boundary = GeometryUtil.boundary(geom);
218
- Geometry envelope = GeometryUtil.envelope(geom);
219
- int dimension = GeometryUtil.dimension(geom);
220
- int numPts = GeometryUtil.numPoints(geom);
221
- boolean empty = GeometryUtil.isEmpty(geom);
222
- GeometryType type = GeometryUtil.geometryType(geom);
223
-
224
- // === Topology Validation ===
225
- TopologyValidationResult validResult = GeometryUtil.isValid(geom);
226
- // validResult.isValid(), .getErrorType(), .getCoordinate(), .getMessage()
227
-
228
- SimpleGeometryResult simpleResult = GeometryUtil.isSimple(geom);
229
- // simpleResult.isSimple(), .getNonSimplePts()
230
-
231
- Geometry validated = GeometryUtil.validate(geom); // auto-fix invalid geometry
232
-
233
- // === Simplification & Densification ===
234
- Geometry simplified = GeometryUtil.simplify(geom, 1.0);
235
- Geometry densified = GeometryUtil.densify(geom, 0.5);
236
-
237
- // === Geometry Equality ===
238
- boolean exact = GeometryUtil.equalsExact(geomA, geomB);
239
- boolean exactTol = GeometryUtil.equalsExactTolerance(geomA, geomB, 0.001);
240
- boolean norm = GeometryUtil.equalsNorm(geomA, geomB);
241
- boolean topo = GeometryUtil.equalsTopo(geomA, geomB);
242
- ```
243
-
244
- ### 6. WKT-Based Geometry Operations (ESRI Geometry API)
245
-
246
- These methods work directly with WKT strings, without creating JTS Geometry objects. Useful when geometry data is in WKT format. Method names end with `Wkt`.
247
-
248
- ```java
249
- // Spatial relations (require wkid for coordinate system context)
250
- boolean result = GeometryUtil.intersectsWkt(wktA, wktB, 4490);
251
- boolean result = GeometryUtil.containsWkt(wktA, wktB, 4490);
252
- boolean result = GeometryUtil.withinWkt(wktA, wktB, 4490);
253
- boolean result = GeometryUtil.touchesWkt(wktA, wktB, 4490);
254
- boolean result = GeometryUtil.crossesWkt(wktA, wktB, 4490);
255
- boolean result = GeometryUtil.overlapsWkt(wktA, wktB, 4490);
256
- boolean result = GeometryUtil.disjointWkt(wktA, wktB, 4490);
257
- boolean result = GeometryUtil.equalsWkt(wktA, wktB, 4490);
258
- boolean result = GeometryUtil.relatePatternWkt(wktA, wktB, 4490, "T*T***FF*");
259
-
260
- // Spatial analysis (returns WKT strings)
261
- String buffer = GeometryUtil.bufferWkt(wkt, 4490, 100.0);
262
- String intersection = GeometryUtil.intersectionWkt(wktA, wktB, 4490);
263
- String union = GeometryUtil.unionWkt(wktList, 4490); // List<String>
264
- String difference = GeometryUtil.differenceWkt(wktA, wktB, 4490);
265
- String symDiff = GeometryUtil.symDifferenceWkt(wktA, wktB, 4490);
266
- String convexHull = GeometryUtil.convexHullWkt(wkt);
267
- String boundary = GeometryUtil.boundaryWkt(wkt);
268
-
269
- // Properties (WKT-based)
270
- double area = GeometryUtil.areaWkt(wkt);
271
- double length = GeometryUtil.lengthWkt(wkt);
272
- double distance = GeometryUtil.distanceWkt(wktA, wktB, 4490);
273
- String centroid = GeometryUtil.centroidWkt(wkt);
274
- int dimension = GeometryUtil.dimensionWkt(wkt);
275
- boolean empty = GeometryUtil.isEmptyWkt(wkt);
276
- GeometryType type = GeometryUtil.geometryTypeWkt(wkt);
277
- boolean simple = GeometryUtil.isSimpleWkt(wkt, 4490);
278
-
279
- // Simplification
280
- String simplified = GeometryUtil.simplifyWkt(wkt, 4490);
281
- ```
282
-
283
- ### 7. Coordinate Reference System (CrsUtil)
284
-
285
- ```java
286
- import com.znlgis.ogu4j.engine.util.CrsUtil;
287
-
288
- // Transform WKT geometry between coordinate systems
289
- String transformedWkt = CrsUtil.transform(wkt, 4490, 4528); // CGCS2000 geo → CGCS2000 / 3-degree zone 39
290
-
291
- // Transform JTS Geometry
292
- Geometry transformed = CrsUtil.transform(geometry, 4490, 4528);
293
-
294
- // Reproject an entire layer
295
- OguLayer reprojected = CrsUtil.reproject(layer, 4528);
296
-
297
- // Get zone number
298
- int zoneNumber = CrsUtil.getDh(geometry); // from JTS Geometry
299
- int zoneNumber = CrsUtil.getDh(wkt); // from WKT string
300
- int zoneNumber = CrsUtil.getDh(4528); // from projected WKID
301
-
302
- // Get WKID for geometry
303
- Integer wkid = CrsUtil.getWkid(geometry);
304
-
305
- // Get projected WKID from zone number
306
- Integer projectedWkid = CrsUtil.getProjectedWkid(39); // zone number
307
- Integer projectedWkid = CrsUtil.getProjectedWkid(geometry); // from geometry
308
-
309
- // Check CRS type
310
- boolean isProjected = CrsUtil.isProjectedCRS(crs);
311
-
312
- // Get tolerance for CRS
313
- double tolerance = CrsUtil.getTolerance(4490);
314
-
315
- // Get all supported CRS (EPSG 4490-4554, CGCS2000 series)
316
- Map<Integer, CoordinateReferenceSystem> crsList = CrsUtil.getSupportedCRSList();
317
- Map.Entry<Integer, CoordinateReferenceSystem> entry = CrsUtil.getSupportedCRS(4490);
318
- ```
319
-
320
- ### 8. Engine API (Advanced Usage)
321
-
322
- ```java
323
- import com.znlgis.ogu4j.engine.*;
324
- import com.znlgis.ogu4j.engine.enums.*;
325
-
326
- // Get engine via factory
327
- GisEngine engine = GisEngineFactory.getEngine(GisEngineType.AUTO);
328
- GisEngine engine = GisEngineFactory.getEngine(DataFormatType.GEOJSON); // auto-select
329
- GisEngine engine = GisEngineFactory.getEngine(GisEngineType.GEOTOOLS, DataFormatType.SHP);
330
-
331
- // Check engine capabilities
332
- boolean available = engine.isAvailable();
333
- boolean supports = engine.supports(DataFormatType.FILEGDB);
334
-
335
- // Read/write via engine
336
- OguLayer layer = engine.readLayer(DataFormatType.SHP, path, layerName, attrFilter, spatialFilter);
337
- engine.writeLayer(DataFormatType.SHP, layer, path, layerName, options);
338
-
339
- // Get reader/writer directly
340
- LayerReader reader = engine.getReader(DataFormatType.GEOJSON);
341
- LayerWriter writer = engine.getWriter(DataFormatType.GEOJSON);
342
- OguLayer layer = reader.read(path, layerName, attrFilter, spatialFilterWkt);
343
- writer.write(layer, path, layerName, options);
344
- ```
345
-
346
- ### 9. Utility Classes
347
-
348
- ```java
349
- // ZIP operations
350
- import com.znlgis.ogu4j.utils.ZipUtil;
351
- ZipUtil.zip(folder, "output.zip"); // default GBK encoding
352
- ZipUtil.zip(folder, "output.zip", StandardCharsets.UTF_8); // custom encoding
353
- ZipUtil.unzip("input.zip", destPath);
354
- ZipUtil.unzip(zipFile, destPath);
355
-
356
- // File encoding detection
357
- import com.znlgis.ogu4j.utils.EncodingUtil;
358
- Charset charset = EncodingUtil.getFileEncoding(file); // detects UTF-8, GBK, GB2312, GB18030
359
-
360
- // Natural sorting (handles numbers within strings)
361
- import com.znlgis.ogu4j.utils.SortUtil;
362
- int cmp = SortUtil.compareString("item2", "item10"); // returns negative (2 < 10)
363
-
364
- // Remove scientific notation
365
- import com.znlgis.ogu4j.utils.NumUtil;
366
- String plain = NumUtil.getPlainString(1.234E10); // "12340000000"
367
-
368
- // FileGDB structure inspection (requires GDAL)
369
- import com.znlgis.ogu4j.engine.util.GdalCmdUtil;
370
- GdbGroupModel structure = GdalCmdUtil.getGdbDataStructure("/path/to/data.gdb");
371
-
372
- // PostGIS helpers
373
- import com.znlgis.ogu4j.engine.util.PostgisUtil;
374
- String gdalConn = PostgisUtil.toGdalPostgisConnStr(dbConnModel);
375
- JDBCDataStore ds = PostgisUtil.getGeotoolsPostgisDataSource(dbConnModel);
376
-
377
- // Shapefile helpers
378
- import com.znlgis.ogu4j.engine.util.ShpUtil;
379
- ShpUtil.formatFieldName(fields); // truncate to 10 chars
380
- Charset charset = ShpUtil.check("/path/to/file.shp"); // verify & detect encoding
381
- ```
382
-
383
- ---
384
-
1
+ # OpenGIS Utils for Java Common Tasks Reference
2
+
3
+ Common task quick reference split from SKILL.md.
4
+
5
+ ---
6
+
7
+ ## Quick Reference: Common Tasks
8
+
9
+ ### 1. Read a GIS Layer (Shapefile / GeoJSON / PostGIS / FileGDB / TXT)
10
+
11
+ ```java
12
+ import com.znlgis.ogu4j.datasource.OguLayerUtil;
13
+ import com.znlgis.ogu4j.engine.enums.DataFormatType;
14
+ import com.znlgis.ogu4j.engine.enums.GisEngineType;
15
+ import com.znlgis.ogu4j.engine.model.layer.OguLayer;
16
+
17
+ // Read Shapefile (GeoTools engine)
18
+ OguLayer layer = OguLayerUtil.readLayer(
19
+ DataFormatType.SHP, // format
20
+ "/path/to/file.shp", // path or connection string
21
+ null, // layer name (null for single-layer formats)
22
+ null, // attribute filter (CQL expression, e.g. "NAME = 'Beijing'")
23
+ null, // spatial filter (WKT geometry)
24
+ GisEngineType.AUTO // engine: AUTO, GEOTOOLS, or GDAL
25
+ );
26
+
27
+ // Read GeoJSON
28
+ OguLayer layer = OguLayerUtil.readLayer(
29
+ DataFormatType.GEOJSON, "/path/to/file.geojson",
30
+ null, null, null, GisEngineType.GEOTOOLS
31
+ );
32
+
33
+ // Read FileGDB layer (requires GDAL)
34
+ OguLayer layer = OguLayerUtil.readLayer(
35
+ DataFormatType.FILEGDB, "/path/to/data.gdb",
36
+ "layerName", null, null, GisEngineType.GDAL
37
+ );
38
+
39
+ // Read PostGIS (use environment variables or secure config for credentials in production)
40
+ String connStr = "PG: host=localhost port=5432 dbname=gisdb user=postgres password=*** active_schema=public";
41
+ OguLayer layer = OguLayerUtil.readLayer(
42
+ DataFormatType.POSTGIS, connStr,
43
+ "table_name", null, null, GisEngineType.GEOTOOLS
44
+ );
45
+
46
+ // Read National Land TXT
47
+ import com.znlgis.ogu4j.datasource.GtTxtUtil;
48
+ OguLayer layer = GtTxtUtil.loadTxt("/path/to/file.txt", null); // null = auto-detect fields
49
+ ```
50
+
51
+ ### 2. Write a GIS Layer
52
+
53
+ ```java
54
+ import com.znlgis.ogu4j.datasource.OguLayerUtil;
55
+
56
+ // Write to Shapefile
57
+ OguLayerUtil.writeLayer(
58
+ DataFormatType.SHP,
59
+ layer, // OguLayer object
60
+ "/path/to/output.shp", // output path
61
+ null, // layer name
62
+ null, // options map (format-specific)
63
+ GisEngineType.GEOTOOLS
64
+ );
65
+
66
+ // Write to GeoJSON
67
+ OguLayerUtil.writeLayer(
68
+ DataFormatType.GEOJSON, layer,
69
+ "/path/to/output.geojson", null, null, GisEngineType.GEOTOOLS
70
+ );
71
+
72
+ // Write to FileGDB (with options)
73
+ Map<String, Object> options = new HashMap<>();
74
+ options.put("featureDataset", "datasetName");
75
+ OguLayerUtil.writeLayer(
76
+ DataFormatType.FILEGDB, layer,
77
+ "/path/to/data.gdb", "layerName", options, GisEngineType.GDAL
78
+ );
79
+
80
+ // Write to PostGIS
81
+ OguLayerUtil.writeLayer(
82
+ DataFormatType.POSTGIS, layer,
83
+ connStr, "table_name", null, GisEngineType.GEOTOOLS
84
+ );
85
+
86
+ // Write National Land TXT
87
+ import com.znlgis.ogu4j.engine.model.layer.OguLayerMetadata;
88
+ OguLayerMetadata metadata = new OguLayerMetadata();
89
+ metadata.setCoordinateSystemName("2000国家大地坐标系");
90
+ metadata.setZoneDivision("3");
91
+ metadata.setProjectionType("高斯克吕格");
92
+ metadata.setMeasureUnit("米");
93
+ GtTxtUtil.saveTxt(layer, "/path/to/output.txt", metadata, null, 39);
94
+ ```
95
+
96
+ ### 3. Format Conversion (One-Step)
97
+
98
+ ```java
99
+ // SHP → GeoJSON
100
+ OguLayer layer = OguLayerUtil.readLayer(DataFormatType.SHP, shpPath, null, null, null, GisEngineType.AUTO);
101
+ OguLayerUtil.writeLayer(DataFormatType.GEOJSON, layer, geojsonPath, null, null, GisEngineType.AUTO);
102
+
103
+ // GeoJSON → PostGIS
104
+ OguLayer layer = OguLayerUtil.readLayer(DataFormatType.GEOJSON, geojsonPath, null, null, null, GisEngineType.AUTO);
105
+ OguLayerUtil.writeLayer(DataFormatType.POSTGIS, layer, connStr, "tableName", null, GisEngineType.AUTO);
106
+ ```
107
+
108
+ ### 4. Work with the Layer Model
109
+
110
+ ```java
111
+ import com.znlgis.ogu4j.engine.model.layer.*;
112
+ import com.znlgis.ogu4j.engine.enums.*;
113
+
114
+ // Create a layer from scratch
115
+ OguLayer layer = new OguLayer();
116
+ layer.setName("cities");
117
+ layer.setWkid(4490); // CGCS2000 geographic
118
+ layer.setGeometryType(GeometryType.POINT);
119
+
120
+ // Define fields
121
+ List<OguField> fields = new ArrayList<>();
122
+ fields.add(new OguField("name", "城市名称", FieldDataType.STRING));
123
+ fields.add(new OguField("population", "人口", FieldDataType.INTEGER));
124
+ layer.setFields(fields);
125
+
126
+ // Create features
127
+ OguFeature feature = new OguFeature();
128
+ feature.setId("1");
129
+ feature.setGeometry("POINT(116.4 39.9)"); // WKT format
130
+ List<OguFieldValue> attrs = new ArrayList<>();
131
+ attrs.add(new OguFieldValue(fields.get(0), "北京"));
132
+ attrs.add(new OguFieldValue(fields.get(1), 21540000));
133
+ feature.setAttributes(attrs);
134
+ layer.setFeatures(List.of(feature));
135
+
136
+ // Validate layer
137
+ layer.validate(); // throws LayerValidationException if invalid
138
+
139
+ // Serialize to/from JSON
140
+ String json = layer.toJSON();
141
+ OguLayer restored = OguLayer.fromJSON(json);
142
+
143
+ // Filter features by attribute
144
+ List<OguFeature> filtered = layer.filter(f -> {
145
+ Integer pop = f.getAttribute("population").getIntValue();
146
+ return pop != null && pop > 10000000; // population > 10 million
147
+ });
148
+
149
+ // Access feature attributes
150
+ OguFeature f = layer.getFeatures().get(0);
151
+ String name = f.getAttribute("name").getStringValue();
152
+ Object val = f.getValue("name");
153
+ f.setValue("name", "新名称");
154
+
155
+ // Get counts
156
+ int featureCount = layer.getFeatureCount();
157
+ int fieldCount = layer.getFieldCount();
158
+ ```
159
+
160
+ ### 5. Geometry Operations (GeometryUtil)
161
+
162
+ ```java
163
+ import com.znlgis.ogu4j.geometry.GeometryUtil;
164
+ import org.locationtech.jts.geom.Geometry;
165
+
166
+ // === Format Conversions ===
167
+ Geometry geom = GeometryUtil.wkt2Geometry("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))");
168
+ String wkt = GeometryUtil.geometry2Wkt(geom);
169
+ String geojson = GeometryUtil.geometry2Geojson(geom);
170
+ String esriJson = GeometryUtil.geometry2EsriJson(geom, 4490);
171
+
172
+ // WKT ↔ GeoJSON
173
+ String geojson = GeometryUtil.wkt2Geojson(wkt);
174
+ String wkt = GeometryUtil.geojson2Wkt(geojson);
175
+
176
+ // WKT ↔ ESRI JSON
177
+ String esriJson = GeometryUtil.wkt2EsriJson(wkt, 4490);
178
+ String wkt = GeometryUtil.esriJson2Wkt(esriJson);
179
+
180
+ // GeoJSON ↔ ESRI JSON
181
+ String esriJson = GeometryUtil.geoJson2EsriJson(4490, geojson);
182
+ String geojson = GeometryUtil.esriJson2GeoJson(esriJson);
183
+
184
+ // GeoJSON / ESRI JSON → JTS Geometry
185
+ Geometry geom = GeometryUtil.geojson2Geometry(geojson);
186
+ Geometry geom = GeometryUtil.esriJson2Geometry(esriJson);
187
+
188
+ // === Spatial Relations (JTS Geometry-based) ===
189
+ boolean result = GeometryUtil.intersects(geomA, geomB);
190
+ boolean result = GeometryUtil.contains(geomA, geomB);
191
+ boolean result = GeometryUtil.within(geomA, geomB);
192
+ boolean result = GeometryUtil.touches(geomA, geomB);
193
+ boolean result = GeometryUtil.crosses(geomA, geomB);
194
+ boolean result = GeometryUtil.overlaps(geomA, geomB);
195
+ boolean result = GeometryUtil.disjoint(geomA, geomB);
196
+ String de9im = GeometryUtil.relate(geomA, geomB);
197
+ boolean result = GeometryUtil.relatePattern(geomA, geomB, "T*T***FF*");
198
+
199
+ // === Spatial Analysis (JTS Geometry-based) ===
200
+ Geometry buffer = GeometryUtil.buffer(geom, 100.0);
201
+ Geometry intersection = GeometryUtil.intersection(geomA, geomB);
202
+ Geometry union = GeometryUtil.union(geomA, geomB); // also accepts varargs
203
+ Geometry difference = GeometryUtil.difference(geomA, geomB);
204
+ Geometry symDiff = GeometryUtil.symDifference(geomA, geomB);
205
+ Geometry convexHull = GeometryUtil.convexHull(geom);
206
+ Geometry concaveHull = GeometryUtil.concaveHull(geom);
207
+ Geometry splitResult = GeometryUtil.splitPolygon(polygon, line);
208
+ Geometry polygonized = GeometryUtil.polygonize(geom);
209
+
210
+ // === Geometry Properties ===
211
+ double area = GeometryUtil.area(geom);
212
+ double length = GeometryUtil.length(geom);
213
+ double distance = GeometryUtil.distance(geomA, geomB);
214
+ boolean withinDist = GeometryUtil.isWithinDistance(geomA, geomB, 500.0);
215
+ Geometry centroid = GeometryUtil.centroid(geom);
216
+ Geometry interiorPt = GeometryUtil.interiorPoint(geom);
217
+ Geometry boundary = GeometryUtil.boundary(geom);
218
+ Geometry envelope = GeometryUtil.envelope(geom);
219
+ int dimension = GeometryUtil.dimension(geom);
220
+ int numPts = GeometryUtil.numPoints(geom);
221
+ boolean empty = GeometryUtil.isEmpty(geom);
222
+ GeometryType type = GeometryUtil.geometryType(geom);
223
+
224
+ // === Topology Validation ===
225
+ TopologyValidationResult validResult = GeometryUtil.isValid(geom);
226
+ // validResult.isValid(), .getErrorType(), .getCoordinate(), .getMessage()
227
+
228
+ SimpleGeometryResult simpleResult = GeometryUtil.isSimple(geom);
229
+ // simpleResult.isSimple(), .getNonSimplePts()
230
+
231
+ Geometry validated = GeometryUtil.validate(geom); // auto-fix invalid geometry
232
+
233
+ // === Simplification & Densification ===
234
+ Geometry simplified = GeometryUtil.simplify(geom, 1.0);
235
+ Geometry densified = GeometryUtil.densify(geom, 0.5);
236
+
237
+ // === Geometry Equality ===
238
+ boolean exact = GeometryUtil.equalsExact(geomA, geomB);
239
+ boolean exactTol = GeometryUtil.equalsExactTolerance(geomA, geomB, 0.001);
240
+ boolean norm = GeometryUtil.equalsNorm(geomA, geomB);
241
+ boolean topo = GeometryUtil.equalsTopo(geomA, geomB);
242
+ ```
243
+
244
+ ### 6. WKT-Based Geometry Operations (ESRI Geometry API)
245
+
246
+ These methods work directly with WKT strings, without creating JTS Geometry objects. Useful when geometry data is in WKT format. Method names end with `Wkt`.
247
+
248
+ ```java
249
+ // Spatial relations (require wkid for coordinate system context)
250
+ boolean result = GeometryUtil.intersectsWkt(wktA, wktB, 4490);
251
+ boolean result = GeometryUtil.containsWkt(wktA, wktB, 4490);
252
+ boolean result = GeometryUtil.withinWkt(wktA, wktB, 4490);
253
+ boolean result = GeometryUtil.touchesWkt(wktA, wktB, 4490);
254
+ boolean result = GeometryUtil.crossesWkt(wktA, wktB, 4490);
255
+ boolean result = GeometryUtil.overlapsWkt(wktA, wktB, 4490);
256
+ boolean result = GeometryUtil.disjointWkt(wktA, wktB, 4490);
257
+ boolean result = GeometryUtil.equalsWkt(wktA, wktB, 4490);
258
+ boolean result = GeometryUtil.relatePatternWkt(wktA, wktB, 4490, "T*T***FF*");
259
+
260
+ // Spatial analysis (returns WKT strings)
261
+ String buffer = GeometryUtil.bufferWkt(wkt, 4490, 100.0);
262
+ String intersection = GeometryUtil.intersectionWkt(wktA, wktB, 4490);
263
+ String union = GeometryUtil.unionWkt(wktList, 4490); // List<String>
264
+ String difference = GeometryUtil.differenceWkt(wktA, wktB, 4490);
265
+ String symDiff = GeometryUtil.symDifferenceWkt(wktA, wktB, 4490);
266
+ String convexHull = GeometryUtil.convexHullWkt(wkt);
267
+ String boundary = GeometryUtil.boundaryWkt(wkt);
268
+
269
+ // Properties (WKT-based)
270
+ double area = GeometryUtil.areaWkt(wkt);
271
+ double length = GeometryUtil.lengthWkt(wkt);
272
+ double distance = GeometryUtil.distanceWkt(wktA, wktB, 4490);
273
+ String centroid = GeometryUtil.centroidWkt(wkt);
274
+ int dimension = GeometryUtil.dimensionWkt(wkt);
275
+ boolean empty = GeometryUtil.isEmptyWkt(wkt);
276
+ GeometryType type = GeometryUtil.geometryTypeWkt(wkt);
277
+ boolean simple = GeometryUtil.isSimpleWkt(wkt, 4490);
278
+
279
+ // Simplification
280
+ String simplified = GeometryUtil.simplifyWkt(wkt, 4490);
281
+ ```
282
+
283
+ ### 7. Coordinate Reference System (CrsUtil)
284
+
285
+ ```java
286
+ import com.znlgis.ogu4j.engine.util.CrsUtil;
287
+
288
+ // Transform WKT geometry between coordinate systems
289
+ String transformedWkt = CrsUtil.transform(wkt, 4490, 4528); // CGCS2000 geo → CGCS2000 / 3-degree zone 39
290
+
291
+ // Transform JTS Geometry
292
+ Geometry transformed = CrsUtil.transform(geometry, 4490, 4528);
293
+
294
+ // Reproject an entire layer
295
+ OguLayer reprojected = CrsUtil.reproject(layer, 4528);
296
+
297
+ // Get zone number
298
+ int zoneNumber = CrsUtil.getDh(geometry); // from JTS Geometry
299
+ int zoneNumber = CrsUtil.getDh(wkt); // from WKT string
300
+ int zoneNumber = CrsUtil.getDh(4528); // from projected WKID
301
+
302
+ // Get WKID for geometry
303
+ Integer wkid = CrsUtil.getWkid(geometry);
304
+
305
+ // Get projected WKID from zone number
306
+ Integer projectedWkid = CrsUtil.getProjectedWkid(39); // zone number
307
+ Integer projectedWkid = CrsUtil.getProjectedWkid(geometry); // from geometry
308
+
309
+ // Check CRS type
310
+ boolean isProjected = CrsUtil.isProjectedCRS(crs);
311
+
312
+ // Get tolerance for CRS
313
+ double tolerance = CrsUtil.getTolerance(4490);
314
+
315
+ // Get all supported CRS (EPSG 4490-4554, CGCS2000 series)
316
+ Map<Integer, CoordinateReferenceSystem> crsList = CrsUtil.getSupportedCRSList();
317
+ Map.Entry<Integer, CoordinateReferenceSystem> entry = CrsUtil.getSupportedCRS(4490);
318
+ ```
319
+
320
+ ### 8. Engine API (Advanced Usage)
321
+
322
+ ```java
323
+ import com.znlgis.ogu4j.engine.*;
324
+ import com.znlgis.ogu4j.engine.enums.*;
325
+
326
+ // Get engine via factory
327
+ GisEngine engine = GisEngineFactory.getEngine(GisEngineType.AUTO);
328
+ GisEngine engine = GisEngineFactory.getEngine(DataFormatType.GEOJSON); // auto-select
329
+ GisEngine engine = GisEngineFactory.getEngine(GisEngineType.GEOTOOLS, DataFormatType.SHP);
330
+
331
+ // Check engine capabilities
332
+ boolean available = engine.isAvailable();
333
+ boolean supports = engine.supports(DataFormatType.FILEGDB);
334
+
335
+ // Read/write via engine
336
+ OguLayer layer = engine.readLayer(DataFormatType.SHP, path, layerName, attrFilter, spatialFilter);
337
+ engine.writeLayer(DataFormatType.SHP, layer, path, layerName, options);
338
+
339
+ // Get reader/writer directly
340
+ LayerReader reader = engine.getReader(DataFormatType.GEOJSON);
341
+ LayerWriter writer = engine.getWriter(DataFormatType.GEOJSON);
342
+ OguLayer layer = reader.read(path, layerName, attrFilter, spatialFilterWkt);
343
+ writer.write(layer, path, layerName, options);
344
+ ```
345
+
346
+ ### 9. Utility Classes
347
+
348
+ ```java
349
+ // ZIP operations
350
+ import com.znlgis.ogu4j.utils.ZipUtil;
351
+ ZipUtil.zip(folder, "output.zip"); // default GBK encoding
352
+ ZipUtil.zip(folder, "output.zip", StandardCharsets.UTF_8); // custom encoding
353
+ ZipUtil.unzip("input.zip", destPath);
354
+ ZipUtil.unzip(zipFile, destPath);
355
+
356
+ // File encoding detection
357
+ import com.znlgis.ogu4j.utils.EncodingUtil;
358
+ Charset charset = EncodingUtil.getFileEncoding(file); // detects UTF-8, GBK, GB2312, GB18030
359
+
360
+ // Natural sorting (handles numbers within strings)
361
+ import com.znlgis.ogu4j.utils.SortUtil;
362
+ int cmp = SortUtil.compareString("item2", "item10"); // returns negative (2 < 10)
363
+
364
+ // Remove scientific notation
365
+ import com.znlgis.ogu4j.utils.NumUtil;
366
+ String plain = NumUtil.getPlainString(1.234E10); // "12340000000"
367
+
368
+ // FileGDB structure inspection (requires GDAL)
369
+ import com.znlgis.ogu4j.engine.util.GdalCmdUtil;
370
+ GdbGroupModel structure = GdalCmdUtil.getGdbDataStructure("/path/to/data.gdb");
371
+
372
+ // PostGIS helpers
373
+ import com.znlgis.ogu4j.engine.util.PostgisUtil;
374
+ String gdalConn = PostgisUtil.toGdalPostgisConnStr(dbConnModel);
375
+ JDBCDataStore ds = PostgisUtil.getGeotoolsPostgisDataSource(dbConnModel);
376
+
377
+ // Shapefile helpers
378
+ import com.znlgis.ogu4j.engine.util.ShpUtil;
379
+ ShpUtil.formatFieldName(fields); // truncate to 10 chars
380
+ Charset charset = ShpUtil.check("/path/to/file.shp"); // verify & detect encoding
381
+ ```
382
+
383
+ ---
384
+