ym-gis-2d 1.0.49 → 1.0.50

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 (86) hide show
  1. package/API.md +771 -0
  2. package/README.md +33 -76
  3. package/assets/main.css +16 -3
  4. package/capabilities/index.js +1 -1
  5. package/controls/ControlManager.js +1 -1
  6. package/controls/LegendControl.js +1 -1
  7. package/controls/MousePositionControl.js +1 -1
  8. package/controls/SwipeLayerControl.d.ts +4 -0
  9. package/controls/SwipeLayerControl.d.ts.map +1 -1
  10. package/controls/SwipeLayerControl.js +1 -1
  11. package/controls/SwipeLayerControl.js.map +1 -1
  12. package/conver/kml/geoJSONToKml.js +1 -1
  13. package/conver/kml/index.js +1 -1
  14. package/conver/kml/kmlToGeoJSON.js +1 -1
  15. package/entity/Feature.js +1 -1
  16. package/entity/GeometryType.js +1 -1
  17. package/entity/measure/AreaMeasureUnits.js +1 -1
  18. package/entity/measure/DistanceMeasureUnits.js +1 -1
  19. package/feature/FeatureManager.js +1 -1
  20. package/index.js +1 -1
  21. package/interaction/AreaMeasure.js +1 -1
  22. package/interaction/Difference.js +1 -1
  23. package/interaction/DistanceMeasure.js +1 -1
  24. package/interaction/Draw.js +1 -1
  25. package/interaction/InteractionManager.js +1 -1
  26. package/interaction/Modify.js +1 -1
  27. package/interaction/Repair.js +1 -1
  28. package/interaction/Select.js +1 -1
  29. package/interaction/Snap.js +1 -1
  30. package/interaction/Split.js +1 -1
  31. package/layers/ArcgisDynamicLayer.js +1 -1
  32. package/layers/ArcgisFeatureLayer.js +1 -1
  33. package/layers/ArcgisTileLayer.js +1 -1
  34. package/layers/ArcgisWMSLayer.js +1 -1
  35. package/layers/ArcgisWMTSLayer.js +1 -1
  36. package/layers/GeoserverVectorTile.js +1 -1
  37. package/layers/GeoserverWFSLayer.js +1 -1
  38. package/layers/GeoserverWMSLayer.js +1 -1
  39. package/layers/GeoserverWMTSLayer.js +1 -1
  40. package/layers/LayerManager.js +1 -1
  41. package/layers/MapTileLayer.js +1 -1
  42. package/layers/TDTLayer.js +1 -1
  43. package/mapView/Map.js +1 -1
  44. package/mapView/View.js +1 -1
  45. package/package.json +1 -1
  46. package/plot/Plot.js +1 -1
  47. package/plot/geometry/point/Point.js +1 -1
  48. package/plot/geometry/polygon/BasePolygon.js +1 -1
  49. package/plot/geometry/polygon/Circle.js +1 -1
  50. package/plot/geometry/polygon/Polygon.js +1 -1
  51. package/plot/geometry/polygon/RectAngle.js +1 -1
  52. package/plot/geometry/polyline/BaseLine.js +1 -1
  53. package/plot/geometry/polyline/Polyline.js +1 -1
  54. package/style/PointStyleFormat.js +1 -1
  55. package/style/PolygonStyleFormat.js +1 -1
  56. package/style/PolylineStyleFormat.js +1 -1
  57. package/style/StyleManager.js +1 -1
  58. package/style/common.js +1 -1
  59. package/style.css +1 -1
  60. package/utils/ArrayUtil.js +1 -1
  61. package/utils/AxiosUtil.js +1 -1
  62. package/utils/EsriUtil.js +1 -1
  63. package/utils/GeometryUtil.js +1 -1
  64. package/utils/LayerUtil.js +1 -1
  65. package/utils/RegisterProjUtil.js +1 -1
  66. package/utils/ResolutionUtil.js +1 -1
  67. package/utils/StringUtil.js +1 -1
  68. package/utils/StyleUtil.js +1 -1
  69. package/utils/UrlUtil.js +1 -1
  70. package/utils/XmlUtil.js +1 -1
  71. package/utils/format/CQL.js +1 -1
  72. package/utils/format/IsMatchCql.js +1 -1
  73. package/utils/gcj02Util.js +1 -1
  74. package/utils/plug/canvas/ImageCache.js +1 -1
  75. package/utils/plug/canvas/PinBuilder.js +1 -1
  76. package/utils/plug/canvas/PinIcon.js +1 -1
  77. package/utils/plug/canvas/writeTextToCanvas.js +1 -1
  78. package/utils/tasks/esri/Identify.js +1 -1
  79. package/utils/tasks/esri/Query.js +1 -1
  80. package/utils/tasks/esri/Task.js +1 -1
  81. package/utils/tasks/geoserver/QueryTask.js +1 -1
  82. package/utils/tasks/index.d.ts.map +1 -1
  83. package/utils/tasks/index.js +1 -1
  84. package/utils/tasks/index.js.map +1 -1
  85. package/ym-gis-2d.es.js +1 -1
  86. package/ym-gis-2d.umd.js +1 -1
package/API.md ADDED
@@ -0,0 +1,771 @@
1
+ # ym-gis-2d API 文档
2
+
3
+ > 基于 [OpenLayers 9](https://openlayers.org/) 封装的二维 GIS 核心库,提供地图初始化、多源图层加载、空间查询、要素编辑与几何运算等能力。
4
+ > 当前版本:`1.0.49`
5
+ > npm 包名:`ym-gis-2d`
6
+
7
+ ---
8
+
9
+ ## 目录
10
+
11
+ - [简介](#简介)
12
+ - [安装与依赖](#安装与依赖)
13
+ - [快速开始](#快速开始)
14
+ - [模块导入方式](#模块导入方式)
15
+ - [核心类 OLMap](#核心类-olmap)
16
+ - [图层配置 IMapService](#图层配置-imapservice)
17
+ - [支持的图层类型](#支持的图层类型)
18
+ - [要素管理 FeatureManager](#要素管理-featuremanager)
19
+ - [地图交互 Interaction](#地图交互-interaction)
20
+ - [地图控件 Control](#地图控件-control)
21
+ - [服务元数据 capabilities](#服务元数据-capabilities)
22
+ - [空间查询 tasks](#空间查询-tasks)
23
+ - [几何工具 GeometryUtil](#几何工具-geometryutil)
24
+ - [坐标系 RegisterProjUtil](#坐标系-registerprojutil)
25
+ - [KML 转换](#kml-转换)
26
+ - [类型定义 entity](#类型定义-entity)
27
+ - [完整示例](#完整示例)
28
+ - [注意事项](#注意事项)
29
+
30
+ ---
31
+
32
+ ## 简介
33
+
34
+ `ym-gis-2d` 是对 OpenLayers 的业务封装,主要能力包括:
35
+
36
+ | 能力 | 说明 |
37
+ |------|------|
38
+ | 地图视图 | 默认 CGCS2000(EPSG:4490),支持中心点、范围、缩放级别等初始化 |
39
+ | 图层加载 | ArcGIS / GeoServer / 天地图 / XYZ 瓦片等多种服务 |
40
+ | 临时矢量层 | 点/线/面三套临时图层,用于绘制、选中、定位高亮 |
41
+ | 空间编辑 | 绘制、选择、修改、吸附、分割、挖除、修补等交互 |
42
+ | 空间查询 | 支持 ArcGIS 与 GeoServer 服务的属性/空间查询 |
43
+ | 几何运算 | WKT/GeoJSON 转换、缓冲、求交、合并、分割等 |
44
+ | 服务解析 | 自动读取 WMS/WMTS/WFS/ArcGIS MapServer 元数据 |
45
+
46
+ 推荐与 UI 组件库 `ym-giswidget-2d` 配合使用,也可单独集成到 Vue / React / 原生 JS 项目。
47
+
48
+ ---
49
+
50
+ ## 安装与依赖
51
+
52
+ ```bash
53
+ npm install ym-gis-2d
54
+ # 或
55
+ pnpm add ym-gis-2d
56
+ ```
57
+
58
+ ### peer 依赖
59
+
60
+ 本包内部依赖以下库,请确保项目中版本兼容:
61
+
62
+ | 依赖 | 用途 |
63
+ |------|------|
64
+ | `ol` ^9.x | 地图渲染核心 |
65
+ | `axios` | HTTP 请求 |
66
+ | `proj4` | 坐标系转换 |
67
+ | `@turf/turf` | 部分几何运算 |
68
+ | `jsts` | 拓扑运算(分割、合并等) |
69
+
70
+ ### 样式引入
71
+
72
+ 地图组件会自动引入 OpenLayers 与包内样式,若样式未生效,请手动引入:
73
+
74
+ ```typescript
75
+ import 'ol/ol.css';
76
+ import 'ym-gis-2d/assets/main.css';
77
+ ```
78
+
79
+ ---
80
+
81
+ ## 快速开始
82
+
83
+ ```html
84
+ <div id="map" style="width: 100%; height: 500px;"></div>
85
+ ```
86
+
87
+ ```typescript
88
+ import OLMap from 'ym-gis-2d/mapView/Map';
89
+ import type { IMapService } from 'ym-gis-2d/entity';
90
+
91
+ // 1. 创建地图(默认 EPSG:4490,中心合肥附近)
92
+ const map = new OLMap('map', {
93
+ projection: 4490,
94
+ center: [117.22, 31.82],
95
+ zoom: 10,
96
+ extent: [89.7, 26.7, 94.8, 29.8], // 可选:初始 fit 到范围
97
+ });
98
+
99
+ // 2. 加载天地图矢量
100
+ const vecLayer: IMapService = {
101
+ id: 'tdt-vec',
102
+ title: '天地图矢量',
103
+ url: 'http://t0.tianditu.gov.cn/vec_c/wmts?tk=YOUR_TOKEN',
104
+ sublayers: ['vec'],
105
+ layerType: 'tdt-c',
106
+ opacity: 1,
107
+ mapIndex: 0,
108
+ checked: true,
109
+ thumbnail: '',
110
+ };
111
+
112
+ await map.addMapLayer(vecLayer);
113
+
114
+ // 3. 叠加 WKT 并定位
115
+ map.addWKT(
116
+ 'POINT(91.1 29.6)',
117
+ 'EPSG:4490',
118
+ 'marker',
119
+ true,
120
+ { name: '拉萨' },
121
+ { color: '#f03437', opacity: 0.5, outlineColor: 'red', outlineWidth: 2 }
122
+ );
123
+ ```
124
+
125
+ ---
126
+
127
+ ## 模块导入方式
128
+
129
+ 包采用**子路径导入**(与源码目录结构一致),常用入口如下:
130
+
131
+ ```typescript
132
+ // 地图
133
+ import OLMap, { OlMapOptions, ChangeLayerEvent } from 'ym-gis-2d/mapView/Map';
134
+ import OLView from 'ym-gis-2d/mapView/View';
135
+
136
+ // 类型
137
+ import type { IMapService, IMapServiceTree, ILayerField } from 'ym-gis-2d/entity';
138
+ import Feature from 'ym-gis-2d/entity/Feature';
139
+ import type IStyle from 'ym-gis-2d/entity/style/IStyle';
140
+
141
+ // 要素 / 交互 / 工具
142
+ import FeatureManager from 'ym-gis-2d/feature/FeatureManager';
143
+ import Draw from 'ym-gis-2d/interaction/Draw';
144
+ import Select from 'ym-gis-2d/interaction/Select';
145
+ import { selectFeaturesByGeo } from 'ym-gis-2d/utils/tasks';
146
+ import { fromWKT, toWKT, getArea, getLength } from 'ym-gis-2d/utils/GeometryUtil';
147
+ import { getWmtsLayers, getWmsLayers } from 'ym-gis-2d/capabilities';
148
+ import { toKml, toGeoJSON } from 'ym-gis-2d/conver/kml';
149
+ ```
150
+
151
+ > 根入口 `ym-gis-2d` 仅导出 `Map2D` 别名,实际项目请使用上述子路径。
152
+
153
+ ---
154
+
155
+ ## 核心类 OLMap
156
+
157
+ `OLMap` 继承自 `ol/Map`,是地图操作的中心入口。
158
+
159
+ ### 构造函数
160
+
161
+ ```typescript
162
+ new OLMap(
163
+ element: string | HTMLElement,
164
+ options?: OlMapOptions,
165
+ view?: OLView
166
+ )
167
+ ```
168
+
169
+ #### OlMapOptions
170
+
171
+ | 属性 | 类型 | 默认值 | 说明 |
172
+ |------|------|--------|------|
173
+ | `projection` | `number` | `4490` | 坐标系 WKID,如 4490、4326 |
174
+ | `center` | `number[]` | `[117.22, 31.82]` | 地图中心 `[x, y]` |
175
+ | `extent` | `number[]` | - | 初始范围 `[xmin, ymin, xmax, ymax]`,设置后自动 fit |
176
+ | `zoom` | `number` | `10` | 初始缩放级别 |
177
+ | `minZoom` | `number` | `0` | 最小缩放 |
178
+ | `maxZoom` | `number` | `28` | 最大缩放 |
179
+ | `minResolution` | `number` | - | 最小分辨率 |
180
+ | `maxResolution` | `number` | - | 最大分辨率 |
181
+ | `constrainResolution` | `boolean` | `false` | 是否强制整数缩放级别 |
182
+
183
+ ### 实例属性
184
+
185
+ | 属性 | 类型 | 说明 |
186
+ |------|------|------|
187
+ | `currentEditLayer` | `IMapService` | 当前编辑目标图层,配合 FeatureManager 使用 |
188
+ | `interactionManager` | `InteractionManager` | 交互管理器 |
189
+ | `controlManager` | `ControlManager` | 控件管理器 |
190
+
191
+ ### 图层方法
192
+
193
+ | 方法 | 说明 |
194
+ |------|------|
195
+ | `addMapLayer(layerInfo)` | 按 `layerType` 异步创建并添加图层 |
196
+ | `addMapLayers(layerInfo[])` | 批量添加图层 |
197
+ | `addLayer(layer, fitLayer?)` | 直接添加 OpenLayers 图层 |
198
+ | `removeLayerById(id)` | 按 id 移除图层 |
199
+ | `removeLayerByIds(ids[])` | 批量移除 |
200
+ | `getLayerById(id)` | 按 id 查找图层 |
201
+ | `getLayerByLayerTag(layerTag)` | 按 layerTag 查找 |
202
+ | `getLayersByIds(ids[])` | 批量查找 |
203
+ | `fitLayer(layer)` | 缩放到图层范围 |
204
+ | `fitLayerById(id)` | 按 id 缩放 |
205
+ | `fitFilterByLayerTag(layerTag, filter, isSelected?, tag?)` | 查询并定位到过滤结果 |
206
+ | `refresh()` | 刷新地图渲染 |
207
+
208
+ ### WKT / 定位方法
209
+
210
+ | 方法 | 说明 |
211
+ |------|------|
212
+ | `addWKT(wkt, proj, tag?, location?, properties?, style?)` | 添加 WKT 到临时图层 |
213
+ | `addWKTs(wkts[], proj, tag?, location?, style?, properties?)` | 批量添加 WKT |
214
+ | `locationWKT(wkt, proj?, ratio?, isFlash?)` | 定位到 WKT |
215
+ | `locationWKTs(wkts[], proj?, ratio?, isFlash?)` | 定位到多个 WKT |
216
+ | `locationGeometry(geometry, proj?, ratio?, isFlash?)` | 定位到 Geometry |
217
+ | `locationGeometrys(geometrys[], proj?, ratio?, isFlash?)` | 定位到多个 Geometry |
218
+
219
+ #### addWKT 参数示例
220
+
221
+ ```typescript
222
+ map.addWKT(
223
+ 'POLYGON((117.0 31.0, 117.1 31.0, 117.1 31.1, 117.0 31.1, 117.0 31.0))',
224
+ 'EPSG:4490',
225
+ 'plot-001', // tag:用于后续按标签清除
226
+ true, // 是否自动定位
227
+ { id: 1 }, // 属性
228
+ {
229
+ color: 'rgba(255,0,0,0.2)',
230
+ opacity: 0.2,
231
+ outlineColor: 'red',
232
+ outlineWidth: 2,
233
+ }
234
+ );
235
+ ```
236
+
237
+ ### 临时图层
238
+
239
+ | 方法 | 说明 |
240
+ |------|------|
241
+ | `getPointTempLayer()` | 临时点图层 |
242
+ | `getLineTempLayer()` | 临时线图层 |
243
+ | `getPolygonTempLayer()` | 临时面图层 |
244
+ | `getTempLayerByGeoType(geoType)` | 按几何类型获取临时层 |
245
+ | `getTempLayerById(id)` | 按 id 获取/创建临时层 |
246
+ | `sortTemLayer()` | 调整临时层叠放顺序 |
247
+
248
+ ### 其他方法
249
+
250
+ | 方法 | 说明 |
251
+ |------|------|
252
+ | `getExtent()` | 获取当前视图范围 |
253
+ | `createOverlay(id, element?)` | 创建地图 Overlay |
254
+ | `resetViewProjection(projection)` | 切换视图坐标系,如 `'EPSG:4326'` |
255
+ | `getView()` | 返回扩展的 `OLView` 实例 |
256
+
257
+ ### 图层变更事件
258
+
259
+ 添加/移除图层时会派发 `ChangeLayerEvent`:
260
+
261
+ ```typescript
262
+ map.on('changelayer', (evt: ChangeLayerEvent) => {
263
+ console.log(evt.changetype); // 'add' | 'remove' | 'update'
264
+ console.log(evt.layerIds);
265
+ });
266
+ ```
267
+
268
+ ---
269
+
270
+ ## 图层配置 IMapService
271
+
272
+ 图层统一使用 `IMapService` 描述,核心字段如下:
273
+
274
+ ```typescript
275
+ interface IMapService {
276
+ id: string; // 唯一 id
277
+ title: string; // 显示名称
278
+ url?: string; // 服务地址
279
+ sublayers?: string[]; // 子图层名 / 图层索引
280
+ layerType?: string; // 服务类型(见下表)
281
+ layerTypeName?: string; // 类型名称
282
+ layerTag?: string; // 业务标识,用于查询/过滤
283
+ mapIndex?: number; // 图层层级(zIndex)
284
+ opacity?: number; // 透明度 0~1
285
+ geometryType?: number; // 1 点 / 2 线 / 3 面
286
+ editType?: boolean; // 是否可编辑
287
+ selectIndex?: string; // 空间查询图层名
288
+ tableName?: string; // 数据源表名
289
+ primaryKey?: string; // 主键字段
290
+ loadFilter?: string; // 加载过滤 CQL/SQL
291
+ minScale?: number; // 最小显示比例尺(-1 不限)
292
+ maxScale?: number; // 最大显示比例尺(-1 不限)
293
+ checked?: boolean; // 是否默认加载
294
+ thumbnail: string; // 缩略图路径
295
+ legend?: ILegend[]; // 自定义图例
296
+ showLegend?: boolean;
297
+ parentId?: string; // 目录树父节点
298
+ showIndex?: number; // 目录树排序
299
+ }
300
+ ```
301
+
302
+ ---
303
+
304
+ ## 支持的图层类型
305
+
306
+ 通过 `map.addMapLayer()` 加载,`layerType` 取值如下:
307
+
308
+ | layerType | 说明 | url 示例 | sublayers |
309
+ |-----------|------|----------|-----------|
310
+ | `tdt-c` | 天地图 WMTS(4490) | `http://t0.tianditu.gov.cn/vec_c/wmts?tk=xxx` | `['vec']` / `['img']` / `['cva']` |
311
+ | `tile` | XYZ 瓦片 | `http://host/tile/{x}/{y}/{z}.png` | - |
312
+ | `geoserver-wms` | GeoServer WMS | `http://host/geoserver/wms` | `['workspace:layer']` |
313
+ | `geoserver-wmts` | GeoServer WMTS | `http://host/geoserver/gwc/service/wmts` | `['layer']` |
314
+ | `geoserver-wfs` | GeoServer WFS 矢量 | `http://host/geoserver/wfs` | `['workspace:layer']` |
315
+ | `geoserver-vector-tile` | GeoServer 矢量切片 | WMTS 地址 | `['layer']` |
316
+ | `arcgis-dynamic` | ArcGIS 动态地图 | MapServer 根地址 | 图层 id 字符串数组 |
317
+ | `arcgis-tile` | ArcGIS 切片 | MapServer 根地址 | - |
318
+ | `arcgis-feature` | ArcGIS 要素 | MapServer 根地址 | 图层 id 数组 |
319
+ | `arcgis-wms` | ArcGIS WMS | WMS 地址 | `['layer']` |
320
+ | `arcgis-wmts` | ArcGIS WMTS | WMTS 地址 | `['layer']` |
321
+
322
+ ### 天地图示例
323
+
324
+ ```typescript
325
+ await map.addMapLayer({
326
+ id: '001',
327
+ title: '天地图矢量',
328
+ url: 'http://t0.tianditu.gov.cn/vec_c/wmts?tk=YOUR_TOKEN',
329
+ sublayers: ['vec'],
330
+ layerType: 'tdt-c',
331
+ opacity: 1,
332
+ mapIndex: 0,
333
+ checked: true,
334
+ thumbnail: './img/vec.png',
335
+ });
336
+ ```
337
+
338
+ ### GeoServer WMS 示例
339
+
340
+ ```typescript
341
+ await map.addMapLayer({
342
+ id: 'wms-001',
343
+ title: '市界',
344
+ url: 'http://192.168.1.185:8082/geoserver/qinghai/wms',
345
+ sublayers: ['qinghai_sheng_yy'],
346
+ layerType: 'geoserver-wms',
347
+ layerTag: 'boundary',
348
+ selectIndex: 'qinghai_sheng_yy',
349
+ geometryType: 3,
350
+ opacity: 1,
351
+ mapIndex: 4,
352
+ editType: true,
353
+ thumbnail: '',
354
+ });
355
+ ```
356
+
357
+ ### XYZ 瓦片示例
358
+
359
+ ```typescript
360
+ await map.addMapLayer({
361
+ id: 'xyz-001',
362
+ title: '自定义影像',
363
+ url: 'http://host/vt/x={x}&y={y}&z={z}&scale=1.jpg',
364
+ layerType: 'tile',
365
+ opacity: 1,
366
+ mapIndex: 0,
367
+ thumbnail: '',
368
+ });
369
+ ```
370
+
371
+ > XYZ 模板支持 OpenLayers 占位符:`{x}` `{y}` `{z}` `{-y}`(TMS Y 轴翻转)。
372
+
373
+ ---
374
+
375
+ ## 要素管理 FeatureManager
376
+
377
+ ```typescript
378
+ import FeatureManager from 'ym-gis-2d/feature/FeatureManager';
379
+
380
+ const fm = new FeatureManager(map);
381
+
382
+ // 设置当前编辑图层
383
+ map.currentEditLayer = layerInfo;
384
+
385
+ // 获取可编辑要素
386
+ const editFeatures = fm.getEditFeatures();
387
+ const editFeaturesFiltered = fm.getEditFeatures('status', ['draft']);
388
+
389
+ // 获取选中要素
390
+ const selected = fm.getSelectedFeatures(); // 全部
391
+ const byLayer = fm.getSelectedFeatures('layer-id'); // 指定图层
392
+
393
+ // 闪烁高亮
394
+ fm.flashFeatures(features, 3);
395
+ fm.flashGeometrys([geometry], 3);
396
+
397
+ // 清除临时要素
398
+ fm.clearTempFeatures(); // 清除全部
399
+ fm.clearTempFeatures('tag'); // 按 tag 清除
400
+
401
+ // KML 导入
402
+ const features = await fm.kmlImport(kmlString);
403
+ ```
404
+
405
+ ### Feature 扩展属性
406
+
407
+ `ym-gis-2d/entity/Feature` 在 OpenLayers Feature 基础上扩展:
408
+
409
+ | 属性 | 类型 | 说明 |
410
+ |------|------|------|
411
+ | `isSelected` | `boolean` | 是否选中 |
412
+ | `fromType` | `'draw' \| 'import' \| 'cut' \| ...` | 来源类型 |
413
+ | `layerId` | `string` | 关联图层 id |
414
+ | `tag` | `string` | 业务标签 |
415
+ | `tempLayer` | `VectorLayer` | 所在临时图层 |
416
+
417
+ ---
418
+
419
+ ## 地图交互 Interaction
420
+
421
+ 所有交互通过 `map.interactionManager` 注册:
422
+
423
+ ```typescript
424
+ map.interactionManager.addInteraction('draw', drawInstance);
425
+ map.interactionManager.removeInteraction('draw');
426
+ map.interactionManager.getInteraction('draw');
427
+ map.interactionManager.removeAllInteractions();
428
+ ```
429
+
430
+ ### Draw — 绘制
431
+
432
+ ```typescript
433
+ import Draw from 'ym-gis-2d/interaction/Draw';
434
+ import GeometryType from 'ym-gis-2d/entity/GeometryType';
435
+
436
+ const draw = new Draw(map, GeometryType.Polygon, {
437
+ style: { color: 'rgba(0,0,255,0.2)', outlineColor: 'blue', outlineWidth: 2 },
438
+ showTip: true,
439
+ tipText: '点击绘制多边形',
440
+ });
441
+
442
+ draw.on('drawEnd', (evt) => {
443
+ const feature = evt.feature;
444
+ });
445
+
446
+ map.interactionManager.addInteraction('draw', draw);
447
+ draw.setActive(true);
448
+ ```
449
+
450
+ 支持的 `GeometryType`:
451
+
452
+ | 常量 | 说明 |
453
+ |------|------|
454
+ | `Point` | 点 |
455
+ | `PolyLine` | 折线 |
456
+ | `Polygon` | 多边形 |
457
+ | `Rectangle` | 矩形 |
458
+ | `Circle` | 圆 |
459
+ | `Curve` | 曲线 |
460
+ | `Arrow` / `ArrowAttack` / `ArrowPincerlike` | 箭头类 |
461
+ | 等 | 见 `entity/GeometryType.ts` |
462
+
463
+ Draw 事件:`drawStart` `drawEnd` `drawAbort` `drawAddPoint` `drawMoving`
464
+
465
+ ### Select — 选择 / 查询
466
+
467
+ ```typescript
468
+ import Select from 'ym-gis-2d/interaction/Select';
469
+
470
+ const select = new Select(map, {
471
+ pixelDistance: 5,
472
+ addTempLayer: true,
473
+ });
474
+
475
+ select.on('selected', (evt) => {
476
+ console.log(evt.features);
477
+ });
478
+
479
+ map.interactionManager.addInteraction('select', select);
480
+ ```
481
+
482
+ ### 其他交互
483
+
484
+ | 类 | 导入路径 | 说明 |
485
+ |----|----------|------|
486
+ | `Modify` | `interaction/Modify` | 节点编辑 |
487
+ | `Snap` | `interaction/Snap` | 吸附 |
488
+ | `Split` | `interaction/Split` | 面分割 |
489
+ | `Difference` | `interaction/Difference` | 挖除/差集 |
490
+ | `Repair` | `interaction/Repair` | 面修补 |
491
+ | `AreaMeasure` | `interaction/AreaMeasure` | 面积量测 |
492
+ | `DistanceMeasure` | `interaction/DistanceMeasure` | 距离量测 |
493
+
494
+ 量测单位配置见 `entity/measure/AreaMeasureUnits`、`DistanceMeasureUnits`。
495
+
496
+ ---
497
+
498
+ ## 地图控件 Control
499
+
500
+ 通过 `map.controlManager` 管理,用法与 `interactionManager` 类似。
501
+
502
+ | 类 | 导入路径 | 说明 |
503
+ |----|----------|------|
504
+ | `MousePositionControl` | `controls/MousePositionControl` | 鼠标坐标显示 |
505
+ | `LegendControl` | `controls/LegendControl` | 图例 |
506
+ | `SwipeLayerControl` | `controls/SwipeLayerControl` | 卷帘对比 |
507
+
508
+ ```typescript
509
+ import MousePositionControl from 'ym-gis-2d/controls/MousePositionControl';
510
+
511
+ const mousePos = new MousePositionControl({
512
+ fractionDigits: 4,
513
+ showSpheroid: true,
514
+ });
515
+
516
+ map.controlManager.addControl('mousePosition', mousePos);
517
+ ```
518
+
519
+ ---
520
+
521
+ ## 服务元数据 capabilities
522
+
523
+ 用于管理后台解析服务能力、图层列表与字段信息:
524
+
525
+ ```typescript
526
+ import {
527
+ getWmtsLayers,
528
+ getWmsLayers,
529
+ getWfLayers,
530
+ getArcgisDynamicLayers,
531
+ getArcgisDynamicLayerFields,
532
+ getWmsLayerFields,
533
+ getSourceLayerFields,
534
+ getDynamicLayerInfo,
535
+ getWMTSLayerCapabilities,
536
+ getWMSLayerCapabilities,
537
+ getWFSLayerCapabilities,
538
+ } from 'ym-gis-2d/capabilities';
539
+
540
+ // 获取 WMTS 图层列表
541
+ const layers = await getWmtsLayers('http://host/geoserver/gwc/service/wmts');
542
+
543
+ // 获取图层字段
544
+ const fields = await getSourceLayerFields(url, 'workspace:layer', 'geoserver-wfs');
545
+ ```
546
+
547
+ ---
548
+
549
+ ## 空间查询 tasks
550
+
551
+ ```typescript
552
+ import { selectFeaturesByGeo } from 'ym-gis-2d/utils/tasks';
553
+
554
+ const features = await selectFeaturesByGeo(
555
+ geometry, // 查询几何(可选)
556
+ 'EPSG:4490', // 几何坐标系
557
+ serviceUrl,
558
+ layerName, // selectIndex / 图层名
559
+ 'geoserver-wms', // 服务类型
560
+ "id=1", // 属性过滤(可选)
561
+ resolution // 当前地图分辨率(栅格 WMS 查询时使用)
562
+ );
563
+ ```
564
+
565
+ 支持的服务类型:`arcgis-dynamic`、`arcgis-feature`、`geoserver-wfs`、`geoserver-wms`、`geoserver-wmts`。
566
+
567
+ ---
568
+
569
+ ## 几何工具 GeometryUtil
570
+
571
+ ```typescript
572
+ import {
573
+ fromWKT, toWKT,
574
+ fromWKTs,
575
+ fromGeoJSON, toGeoJSON,
576
+ fromEsriJSON, toEsriJSON,
577
+ getArea, getLength,
578
+ bufferOp, bufferPixel,
579
+ contains, crosses, intersects, intersection,
580
+ union, unions, difference,
581
+ jstlSplit, splitLineByLine,
582
+ expandExtent,
583
+ polygonToLines,
584
+ getGeometryCenter,
585
+ isGeometryEmpty,
586
+ } from 'ym-gis-2d/utils/GeometryUtil';
587
+ ```
588
+
589
+ 常用示例:
590
+
591
+ ```typescript
592
+ const geom = fromWKT('POINT(117 31)', 'EPSG:4490', 'EPSG:4490');
593
+ const wkt = toWKT(geom);
594
+ const area = getArea(polygon, 'EPSG:4490', true); // 第三个参数:是否椭球面积
595
+ const len = getLength(line, 'EPSG:4490', true);
596
+ const merged = union(geom1, geom2);
597
+ ```
598
+
599
+ ---
600
+
601
+ ## 坐标系 RegisterProjUtil
602
+
603
+ ```typescript
604
+ import { registerProj, isSpheroid, getSpheroidProjection } from 'ym-gis-2d/utils/RegisterProjUtil';
605
+
606
+ // 注册坐标系(OLMap 构造时会自动注册 projection 选项)
607
+ registerProj('EPSG:4490');
608
+ registerProj('EPSG:4326');
609
+
610
+ // 判断是否大地坐标系
611
+ isSpheroid(projection);
612
+ ```
613
+
614
+ ### GCJ-02 转换
615
+
616
+ ```typescript
617
+ import { gcj02towgs84, wgs84togcj02 } from 'ym-gis-2d/utils/gcj02Util';
618
+ const [lng, lat] = gcj02towgs84(116.404, 39.915);
619
+ ```
620
+
621
+ ---
622
+
623
+ ## KML 转换
624
+
625
+ ```typescript
626
+ import { toKml, toGeoJSON } from 'ym-gis-2d/conver/kml';
627
+
628
+ // GeoJSON → KML 字符串
629
+ const kml = toKml(geojson, options);
630
+
631
+ // KML → GeoJSON(支持字符串、URL、Blob、KMZ)
632
+ const geojson = await toGeoJSON(kmlString, null);
633
+ ```
634
+
635
+ ---
636
+
637
+ ## 类型定义 entity
638
+
639
+ ```typescript
640
+ import type {
641
+ IMapService,
642
+ IMapServiceTree,
643
+ IMapServiceQuery,
644
+ IMapServiceType,
645
+ ILayerField,
646
+ } from 'ym-gis-2d/entity';
647
+
648
+ import type IStyle from 'ym-gis-2d/entity/style/IStyle';
649
+ ```
650
+
651
+ ### IStyle 样式
652
+
653
+ ```typescript
654
+ interface IStyle {
655
+ color?: string | number[]; // 填充色
656
+ opacity?: number; // 填充透明度
657
+ outlineColor?: string | number[];
658
+ outlineOpacity?: number;
659
+ outlineWidth?: number;
660
+ imgurl?: string; // 点图标
661
+ radius?: number; // 点半径(米)
662
+ scale?: number; // 图标缩放
663
+ rotation?: number; // 图标旋转
664
+ text?: string; // 标注文字
665
+ font?: IFont;
666
+ }
667
+ ```
668
+
669
+ ### 图层目录树
670
+
671
+ ```typescript
672
+ import { mapServiceTreeTransform } from 'ym-gis-2d/utils/LayerUtil';
673
+
674
+ const tree: IMapServiceTree[] = mapServiceTreeTransform(flatLayerList);
675
+ ```
676
+
677
+ ---
678
+
679
+ ## 完整示例
680
+
681
+ Vue 3 集成示例(参考 `comm-web` 项目):
682
+
683
+ ```vue
684
+ <template>
685
+ <div id="map"></div>
686
+ </template>
687
+
688
+ <script setup lang="ts">
689
+ import { onMounted } from 'vue';
690
+ import OLMap from 'ym-gis-2d/mapView/Map';
691
+ import type { IMapService } from 'ym-gis-2d/entity';
692
+ import Draw from 'ym-gis-2d/interaction/Draw';
693
+ import GeometryType from 'ym-gis-2d/entity/GeometryType';
694
+ import FeatureManager from 'ym-gis-2d/feature/FeatureManager';
695
+
696
+ const layers: IMapService[] = [
697
+ {
698
+ id: 'vec',
699
+ title: '天地图矢量',
700
+ url: 'http://t0.tianditu.gov.cn/vec_c/wmts?tk=YOUR_TOKEN',
701
+ sublayers: ['vec'],
702
+ layerType: 'tdt-c',
703
+ mapIndex: 0,
704
+ opacity: 1,
705
+ checked: true,
706
+ thumbnail: '',
707
+ },
708
+ {
709
+ id: 'boundary',
710
+ title: '行政边界',
711
+ url: 'http://host/geoserver/wms',
712
+ sublayers: ['ws:boundary'],
713
+ layerType: 'geoserver-wms',
714
+ layerTag: 'boundary',
715
+ selectIndex: 'ws:boundary',
716
+ geometryType: 3,
717
+ editType: true,
718
+ mapIndex: 1,
719
+ opacity: 1,
720
+ thumbnail: '',
721
+ },
722
+ ];
723
+
724
+ onMounted(async () => {
725
+ const map = new OLMap('map', {
726
+ projection: 4490,
727
+ extent: [89.7, 26.7, 94.8, 29.8],
728
+ });
729
+
730
+ for (const layer of layers) {
731
+ await map.addMapLayer(layer);
732
+ }
733
+
734
+ map.currentEditLayer = layers[1];
735
+
736
+ const draw = new Draw(map, GeometryType.Polygon);
737
+ draw.on('drawEnd', () => {
738
+ const fm = new FeatureManager(map);
739
+ console.log(fm.getEditFeatures());
740
+ });
741
+ map.interactionManager.addInteraction('draw', draw);
742
+ });
743
+ </script>
744
+
745
+ <style>
746
+ #map { width: 100%; height: 100vh; }
747
+ </style>
748
+ ```
749
+
750
+ ---
751
+
752
+ ## 注意事项
753
+
754
+ 1. **坐标系**:默认 EPSG:4490(CGCS2000),与天地图 `tdt-c` 服务匹配;使用 WGS84 服务时需设置 `projection: 4326`。
755
+ 2. **跨域**:WMS/WMTS/XYZ 服务需配置 CORS,或在开发环境使用代理。
756
+ 3. **天地图 Token**:`tdt-c` 类型 URL 需携带有效 `tk` 参数。
757
+ 4. **异步加载**:`addMapLayer` 为异步方法,WMS/WMTS 会先请求 GetCapabilities,请使用 `await` 或 `.then()`。
758
+ 5. **临时图层**:绘制、选中、定位高亮均写入临时矢量层,不会直接修改服务端数据;持久化需自行对接后端。
759
+ 6. **发布产物**:npm 包为编译后的 JS + `.d.ts` 声明文件,子路径导入方式与源码一致。
760
+ 7. **UI 组件**:工具栏、图例、卷帘等 UI 在 `ym-giswidget-2d` 包中,本包仅提供 GIS 核心能力。
761
+
762
+ ---
763
+
764
+ ## 相关包
765
+
766
+ | 包名 | 说明 |
767
+ |------|------|
768
+ | `ym-giswidget-2d` | 二维 GIS UI 组件(工具栏、图例、量测、导入导出等) |
769
+ | `ol` | OpenLayers 官方库 |
770
+
771
+ 如有问题,请联系包维护者或查阅 monorepo 内 `comm-web`、`gis-2d-docs` 示例项目。