my-openlayer 0.1.18 → 1.0.0

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.
package/README.md CHANGED
@@ -1,28 +1,69 @@
1
1
  # my-openlayer
2
2
 
3
- 基于 OpenLayers 的地图组件库,提供了一系列便捷的地图操作功能,支持天地图底图加载、要素绘制、图层管理等功能。
4
-
5
- ## 功能特点
6
-
7
- - **底图管理**
8
- - 支持天地图矢量图、影像图、地形图
9
- - 支持底图动态切换
10
- - 支持注记图层控制
11
- - 支持地图裁剪
12
-
13
- - **要素操作**
14
- - 点位标注(支持图标、文字)
15
- - 线要素绘制(支持样式自定义)
16
- - 面要素绘制
17
- - DOM点位(支持Vue组件)
18
- - 点位聚合展示
19
- - 闪烁点位效果
20
-
21
- - **地图工具**
22
- - 图层管理
23
- - 事件监听
24
- - 坐标转换
25
- - 视图控制
3
+ my-openlayer 是一个基于 [OpenLayers](https://openlayers.org/) 的现代地图组件库,专为 Web GIS 应用开发者设计。提供完整的 TypeScript 支持、模块化的类型定义、强大的错误处理和事件管理系统,支持天地图底图加载、要素绘制、图层管理、事件监听等丰富功能,极大提升地图开发效率。
4
+
5
+ [![npm version](https://img.shields.io/npm/v/my-openlayer.svg)](https://www.npmjs.com/package/my-openlayer)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ ---
10
+
11
+ ## 目录
12
+
13
+ - [功能亮点](#功能亮点)
14
+ - [安装](#安装)
15
+ - [快速上手](#快速上手)
16
+ - [详细用法](#详细用法)
17
+ - [高级功能](#高级功能)
18
+ - [API 文档与示例](#api-文档与示例)
19
+ - [类型定义](#类型定义)
20
+ - [迁移指南](#迁移指南)
21
+ - [依赖](#依赖)
22
+ - [贡献指南](#贡献指南)
23
+ - [常见问题](#常见问题)
24
+ - [许可证](#许可证)
25
+ - [联系方式](#联系方式)
26
+
27
+ ---
28
+
29
+ ## 功能亮点
30
+
31
+ - **🗺️ 底图管理**
32
+ - 支持天地图矢量、影像、地形底图
33
+ - 动态切换底图与注记图层
34
+ - 地图裁剪与自定义范围显示
35
+ - 支持自定义底图源
36
+
37
+ - **📍 要素操作**
38
+ - 点位标注(支持自定义图标、文字、聚合、闪烁)
39
+ - 线要素绘制(支持样式自定义、河流分级显示)
40
+ - 面要素绘制与分区高亮
41
+ - DOM 点位(支持 Vue 组件渲染)
42
+ - 热力图、图片图层
43
+ - 动态要素颜色更新
44
+
45
+ - **🛠️ 地图工具**
46
+ - 图层管理(获取、移除、显隐控制)
47
+ - 地图事件监听(点击、悬停、移动等)
48
+ - 坐标转换、视图控制
49
+ - 测量工具(距离、面积)
50
+ - 配置管理器
51
+
52
+ - **⚡ 高级特性**
53
+ - **TypeScript 完全支持**:模块化类型定义,更好的开发体验
54
+ - **错误处理系统**:统一的错误处理和日志记录
55
+ - **事件管理系统**:强大的事件监听和管理机制
56
+ - **配置管理**:默认配置、配置合并、验证工具
57
+ - **向后兼容**:保持 API 稳定性
58
+
59
+ - **🔧 开发友好**
60
+ - 支持自定义图层、样式、交互逻辑
61
+ - 兼容主流前端框架(Vue、React、Angular)
62
+ - 完整的 JSDoc 注释
63
+ - 详细的迁移指南
64
+ - 丰富的示例代码
65
+
66
+ ---
26
67
 
27
68
  ## 安装
28
69
 
@@ -30,96 +71,115 @@
30
71
  npm install my-openlayer
31
72
  ```
32
73
 
33
- ## 使用方法
74
+ ---
34
75
 
35
- ### 基础初始化
76
+ ## 快速上手
36
77
 
37
- ```javascript
38
- import MyOl from 'my-openlayer';
78
+ ### 1. 初始化地图
39
79
 
40
- const map = new MyOl('map-container', {
41
- // 中心点坐标
42
- center: [119.81, 29.969],
43
- // 缩放级别
44
- zoom: 10,
45
- // 最小缩放级别
46
- minZoom: 8,
47
- // 最大缩放级别
48
- maxZoom: 20,
49
- // 天地图token
50
- token: 'your-tianditu-token',
51
- // 是否显示注记
52
- annotation: true,
53
- // 地图裁剪
54
- mapClip: false,
55
- mapClipData: undefined,
56
- // 图层配置
57
- layers: {
58
- vec_c: [], // 矢量图层
59
- img_c: [], // 影像图层
60
- ter_c: [] // 地形图层
61
- }
62
- });
80
+ ```typescript
81
+ // 方式一:默认导入(推荐)
82
+ import MyOl, { MapInitType } from 'my-openlayer';
83
+
84
+ // 方式二:命名导入
85
+ // import { MyOl, MapInitType } from 'my-openlayer';
86
+
87
+ // 地图初始化配置
88
+ const mapConfig: MapInitType = {
89
+ center: [119.81, 29.969],
90
+ zoom: 10,
91
+ minZoom: 8,
92
+ maxZoom: 20,
93
+ token: 'your-tianditu-token',
94
+ annotation: true,
95
+ layers: {
96
+ vec_c: [],
97
+ img_c: [],
98
+ ter_c: []
99
+ }
100
+ };
101
+
102
+ // 创建地图实例
103
+ const map = new MyOl('map-container', mapConfig);
63
104
  ```
64
105
 
65
- ### 底图操作
106
+ ### 2. 容器 HTML
107
+
108
+ ```html
109
+ <div id="map-container" style="width: 100vw; height: 100vh;"></div>
110
+ ```
111
+
112
+ ---
113
+
114
+ ## 详细用法
115
+
116
+ ### 底图管理
66
117
 
67
118
  ```javascript
68
- // 获取底图管理实例
69
119
  const baseLayers = map.getMapBaseLayers();
70
120
 
71
121
  // 切换底图
72
- baseLayers.switchBaseLayer('vec_c'); // 切换到矢量图
73
- baseLayers.switchBaseLayer('img_c'); // 切换到影像图
74
- baseLayers.switchBaseLayer('ter_c'); // 切换到地形图
122
+ baseLayers.switchBaseLayer('vec_c');
123
+ baseLayers.switchBaseLayer('img_c');
124
+ baseLayers.switchBaseLayer('ter_c');
75
125
 
76
126
  // 添加注记图层
77
127
  baseLayers.addAnnotationLayer({
78
- type: 'cva_c', // 注记类型
79
- zIndex: 11, // 图层层级
80
- visible: true // 是否可见
128
+ type: 'cva_c',
129
+ zIndex: 11,
130
+ visible: true
81
131
  });
82
132
  ```
83
133
 
84
134
  ### 点位操作
85
135
 
86
- ```javascript
87
- // 获取点位操作实例
136
+ ```typescript
137
+ import { PointOptions, ClusterOptions, PointData } from 'my-openlayer';
138
+
88
139
  const point = map.getPoint();
89
140
 
141
+ // 点位数据
142
+ const pointData: PointData[] = [
143
+ { lgtd: 119.81, lttd: 29.969, name: '测试点位', type: 'marker' }
144
+ ];
145
+
90
146
  // 添加普通点位
91
- point.addPoint([
92
- {
93
- lgtd: 119.81,
94
- lttd: 29.969,
95
- name: '测试点位'
96
- }
97
- ], {
98
- type: 'test-point',
99
- nameKey: 'name', // 名称字段
100
- img: 'marker.png', // 图标路径
101
- hasImg: true, // 是否显示图标
102
- textFont: '12px sans-serif', // 文字样式
103
- textFillColor: '#FFF', // 文字颜色
104
- textStrokeColor: '#000', // 文字描边颜色
105
- textStrokeWidth: 3, // 文字描边宽度
106
- textOffsetY: 20, // 文字Y轴偏移
107
- zIndex: 4, // 图层层级
108
- visible: true // 是否可见
109
- });
147
+ const pointOptions: PointOptions = {
148
+ layerName: 'test-point',
149
+ nameKey: 'name',
150
+ img: 'marker.png',
151
+ hasImg: true,
152
+ scale: 1.2,
153
+ textFont: '12px sans-serif',
154
+ textFillColor: '#FFF',
155
+ textStrokeColor: '#000',
156
+ textStrokeWidth: 3,
157
+ textOffsetY: 20,
158
+ zIndex: 4,
159
+ visible: true
160
+ };
161
+ point.addPoint(pointData, pointOptions);
110
162
 
111
163
  // 添加聚合点位
112
- point.addClusterPoint(pointData, 'cluster-point', {
113
- nameKey: 'name',
114
- img: 'cluster.png',
115
- zIndex: 4
116
- });
117
-
118
- // 添加Vue组件点位
164
+ const clusterData: PointData[] = [
165
+ { lgtd: 119.81, lttd: 29.969, name: 'A' },
166
+ { lgtd: 119.82, lttd: 29.97, name: 'B' }
167
+ ];
168
+ const clusterOptions: ClusterOptions = {
169
+ layerName: 'cluster-point',
170
+ nameKey: 'name',
171
+ img: 'cluster.png',
172
+ distance: 50,
173
+ minDistance: 20,
174
+ zIndex: 4
175
+ };
176
+ point.addClusterPoint(clusterData, clusterOptions);
177
+
178
+ // 添加 Vue 组件点位
119
179
  const domPoints = point.setDomPointVue(
120
- [{ lgtd: 119.81, lttd: 29.969 }],
121
- YourVueComponent,
122
- Vue
180
+ [{ lgtd: 119.81, lttd: 29.969 }],
181
+ YourVueComponent,
182
+ Vue
123
183
  );
124
184
 
125
185
  // 控制组件点位显隐
@@ -134,32 +194,277 @@ point.locationAction(119.81, 29.969, 15, 1000);
134
194
 
135
195
  ### 线要素操作
136
196
 
137
- ```javascript
138
- // 获取线要素操作实例
197
+ ```typescript
198
+ import { LineOptions, MapJSONData } from 'my-openlayer';
199
+
139
200
  const line = map.getLine();
140
201
 
202
+ // 线要素数据(GeoJSON 格式)
203
+ const lineGeoJSON: MapJSONData = {
204
+ type: 'FeatureCollection',
205
+ features: [
206
+ {
207
+ type: 'Feature',
208
+ properties: { name: '测试线路', type: 'highway' },
209
+ geometry: {
210
+ type: 'LineString',
211
+ coordinates: [[119.81, 29.969], [119.82, 29.97]]
212
+ }
213
+ }
214
+ ]
215
+ };
216
+
141
217
  // 添加普通线要素
142
- line.addLineCommon(lineGeoJSON, {
143
- type: 'test-line', // 线要素类型
144
- strokeColor: '#037AFF', // 线条颜色
145
- strokeWidth: 3, // 线条宽度
146
- zIndex: 3 // 图层层级
147
- });
218
+ const lineOptions: LineOptions = {
219
+ layerName: 'test-line',
220
+ type: 'test-line',
221
+ strokeColor: '#037AFF',
222
+ strokeWidth: 3,
223
+ lineDash: [5, 5], // 虚线样式
224
+ zIndex: 3,
225
+ textVisible: true,
226
+ textCallBack: (feature) => feature.get('name')
227
+ };
228
+ line.addLineCommon(lineGeoJSON, lineOptions);
148
229
 
149
230
  // 添加河流要素(支持分级显示)
150
- line.addRiverLayersByZoom(riverGeoJSON, {
151
- type: 'river',
152
- strokeColor: '#0071FF',
153
- strokeWidth: 3,
154
- zIndex: 6,
155
- visible: true
231
+ const riverOptions: LineOptions = {
232
+ layerName: 'river',
233
+ type: 'river',
234
+ strokeColor: '#0071FF',
235
+ strokeWidth: 3,
236
+ zIndex: 6,
237
+ visible: true
238
+ };
239
+ line.addRiverLayersByZoom(riverGeoJSON, riverOptions);
240
+
241
+ // 控制河流图层显隐
242
+ line.showRiverLayer(true); // 显示
243
+ line.showRiverLayer(false); // 隐藏
244
+ ```
245
+
246
+ ### 面要素操作
247
+
248
+ ```typescript
249
+ import MyOl, { PolygonOptions, HeatMapOptions, FeatureColorUpdateOptions, PointData } from 'my-openlayer';
250
+
251
+ const polygon = map.getPolygon();
252
+
253
+ // 面要素数据(GeoJSON 格式)
254
+ const borderGeoJSON: MapJSONData = {
255
+ type: 'FeatureCollection',
256
+ features: [
257
+ {
258
+ type: 'Feature',
259
+ properties: { name: '边界区域' },
260
+ geometry: {
261
+ type: 'Polygon',
262
+ coordinates: [[[119.8, 29.96], [119.82, 29.96], [119.82, 29.98], [119.8, 29.98], [119.8, 29.96]]]
263
+ }
264
+ }
265
+ ]
266
+ };
267
+
268
+ // 添加边界面
269
+ const borderOptions: PolygonOptions = {
270
+ layerName: 'border',
271
+ fillColor: 'rgba(255,255,255,0)',
272
+ strokeColor: '#EBEEF5',
273
+ strokeWidth: 2,
274
+ zIndex: 1
275
+ };
276
+ polygon.addBorderPolygon(borderGeoJSON, borderOptions);
277
+
278
+ // 添加分区面
279
+ const zoneOptions: PolygonOptions = {
280
+ layerName: 'zone',
281
+ fillColor: 'rgba(1, 111, 255, 0.3)',
282
+ strokeColor: '#037AFF',
283
+ strokeWidth: 2,
284
+ textVisible: true,
285
+ nameKey: 'name',
286
+ textFont: '14px Calibri,sans-serif',
287
+ textFillColor: '#FFF',
288
+ textStrokeColor: '#409EFF',
289
+ textStrokeWidth: 2,
290
+ zIndex: 2
291
+ };
292
+ polygon.addPolygon(zoneGeoJSON, zoneOptions);
293
+
294
+ // 更新面颜色
295
+ const colorUpdateOptions: FeatureColorUpdateOptions = {
296
+ nameKey: 'name'
297
+ };
298
+ polygon.updateFeatureColor('zone', { 'A区': 'rgba(255,0,0,0.6)' }, colorUpdateOptions);
299
+
300
+ // 添加图片图层
301
+ const extent = [119.8, 29.96, 119.82, 29.98]; // [minx, miny, maxx, maxy]
302
+ polygon.addImage('imgLayer', 'img.png', extent, { zIndex: 10 });
303
+
304
+ // 添加热力图
305
+ const heatData: PointData[] = [
306
+ { lgtd: 119.81, lttd: 29.969, value: 10 },
307
+ { lgtd: 119.82, lttd: 29.97, value: 20 }
308
+ ];
309
+ const heatOptions: HeatMapOptions = {
310
+ layerName: 'heatLayer',
311
+ valueKey: 'value',
312
+ radius: 20,
313
+ blur: 15,
314
+ opacity: 0.8,
315
+ zIndex: 5
316
+ };
317
+ polygon.addHeatmap('heatLayer', heatData, heatOptions);
318
+ ```
319
+
320
+ ## 高级功能
321
+
322
+ ### 错误处理系统
323
+
324
+ ```typescript
325
+ import { MyOl, ErrorHandler, ErrorType, MyOpenLayersError } from 'my-openlayer';
326
+
327
+ // 获取错误处理器实例
328
+ const errorHandler = ErrorHandler.getInstance();
329
+
330
+ // 设置全局错误回调
331
+ errorHandler.addErrorCallback((error: MyOpenLayersError) => {
332
+ console.log('地图错误:', error.message);
333
+ console.log('错误类型:', error.type);
334
+ console.log('错误详情:', error.details);
335
+
336
+ // 发送错误到监控系统
337
+ sendToMonitoring({
338
+ type: error.type,
339
+ message: error.message,
340
+ timestamp: new Date().toISOString()
341
+ });
156
342
  });
343
+
344
+ // 手动验证和错误处理
345
+ try {
346
+ // 验证坐标
347
+ ErrorHandler.validateCoordinates(longitude, latitude);
348
+
349
+ // 验证图层名称
350
+ ErrorHandler.validateLayerName(layerName);
351
+
352
+ // 验证颜色格式
353
+ ErrorHandler.validateColor(color);
354
+
355
+ } catch (error) {
356
+ if (error instanceof MyOpenLayersError) {
357
+ console.error(`${error.type}错误:`, error.message);
358
+ }
359
+ }
360
+
361
+ // 错误类型
362
+ // ErrorType.COORDINATE_ERROR - 坐标错误
363
+ // ErrorType.LAYER_ERROR - 图层错误
364
+ // ErrorType.STYLE_ERROR - 样式错误
365
+ // ErrorType.DATA_ERROR - 数据错误
366
+ // ErrorType.CONFIG_ERROR - 配置错误
367
+ ```
368
+
369
+ ### 事件管理系统
370
+
371
+ ```typescript
372
+ import { MyOl, EventManager, MapEventType, EventCallback, MapEventData } from 'my-openlayer';
373
+
374
+ // 创建事件管理器
375
+ const eventManager = new EventManager(map.map); // 传入原生 ol.Map
376
+
377
+ // 监听点击事件
378
+ const clickCallback: EventCallback = (eventData: MapEventData) => {
379
+ console.log('点击位置:', eventData.coordinate);
380
+ console.log('点击要素:', eventData.feature);
381
+ console.log('像素位置:', eventData.pixel);
382
+ };
383
+ const clickListenerId = eventManager.on('click', clickCallback);
384
+
385
+ // 监听缩放事件
386
+ eventManager.on('zoomend', (eventData) => {
387
+ console.log('当前缩放级别:', eventData.zoom);
388
+ console.log('地图范围:', eventData.extent);
389
+ });
390
+
391
+ // 监听鼠标悬停事件
392
+ eventManager.on('pointermove', (eventData) => {
393
+ if (eventData.feature) {
394
+ console.log('悬停要素:', eventData.feature.get('name'));
395
+ }
396
+ });
397
+
398
+ // 移除特定事件监听
399
+ eventManager.off(clickListenerId);
400
+
401
+ // 移除所有事件监听
402
+ eventManager.removeAllListeners();
403
+
404
+ // 一次性事件监听
405
+ eventManager.on('click', (eventData) => {
406
+ console.log('只触发一次');
407
+ }, { once: true });
408
+
409
+ // 带过滤器的事件监听
410
+ eventManager.on('click', (eventData) => {
411
+ console.log('点击了要素');
412
+ }, {
413
+ filter: (eventData) => eventData.feature !== undefined
414
+ });
415
+
416
+ // 事件统计
417
+ console.log('点击事件监听器数量:', eventManager.getListenerCount('click'));
418
+ console.log('总事件触发次数:', eventManager.getTotalEventCount());
419
+ ```
420
+
421
+ ### 配置管理系统
422
+
423
+ ```typescript
424
+ import { MyOl, ConfigManager, PointOptions, LineOptions } from 'my-openlayer';
425
+
426
+ // 使用默认配置
427
+ const pointOptions: PointOptions = ConfigManager.mergeOptions(
428
+ ConfigManager.DEFAULT_POINT_OPTIONS,
429
+ {
430
+ strokeColor: '#ff0000',
431
+ scale: 1.5,
432
+ textVisible: true
433
+ }
434
+ );
435
+
436
+ // 获取默认配置
437
+ const defaultPointConfig = ConfigManager.DEFAULT_POINT_OPTIONS;
438
+ const defaultLineConfig = ConfigManager.DEFAULT_LINE_OPTIONS;
439
+ const defaultPolygonConfig = ConfigManager.DEFAULT_POLYGON_OPTIONS;
440
+
441
+ // 验证工具
442
+ if (ConfigManager.isValidCoordinate(lng, lat)) {
443
+ console.log('坐标有效');
444
+ }
445
+
446
+ if (ConfigManager.isValidColor('#ff0000')) {
447
+ console.log('颜色格式有效');
448
+ }
449
+
450
+ if (ConfigManager.isValidZIndex(10)) {
451
+ console.log('层级有效');
452
+ }
453
+
454
+ // 生成唯一ID
455
+ const layerId = ConfigManager.generateId('layer'); // layer_1234567890
456
+ const pointId = ConfigManager.generateId('point'); // point_1234567890
457
+
458
+ // 深度合并配置
459
+ const mergedConfig = ConfigManager.mergeOptions(
460
+ { a: 1, b: { c: 2 } },
461
+ { b: { d: 3 }, e: 4 }
462
+ ); // { a: 1, b: { c: 2, d: 3 }, e: 4 }
157
463
  ```
158
464
 
159
465
  ### 地图工具
160
466
 
161
467
  ```javascript
162
- // 获取工具实例
163
468
  const tools = map.getTools();
164
469
 
165
470
  // 获取图层
@@ -168,173 +473,769 @@ const layer = tools.getLayerByLayerName('layerName');
168
473
  // 移除图层
169
474
  tools.removeLayer('layerName');
170
475
 
476
+ // 设置图层可见性
477
+ tools.setLayerVisible('layerName', true);
478
+
171
479
  // 事件监听
172
- MapTools.mapOnEvent(map, 'click', (feature, event) => {
173
- console.log('点击要素:', feature);
480
+ map.mapOnEvent('click', (feature, event) => {
481
+ console.log('点击要素:', feature);
174
482
  });
175
483
 
176
- // 支持的事件类型
177
- // - click: 点击事件
178
- // - moveend: 地图移动结束事件
179
- // - hover: 鼠标悬停事件
484
+ // 支持事件类型:click、moveend、hover
180
485
  ```
181
486
 
182
- ## API文档
487
+ ### 测量工具
183
488
 
184
- ### MyOl
489
+ ```javascript
490
+ import { MyOl, MeasureHandler } from 'my-openlayer';
491
+ const measure = new MeasureHandler(map.map); // 传入原生 ol.Map
492
+ measure.start('Polygon'); // 开始绘制多边形测量
493
+ // measure.start('LineString'); // 开始绘制线测量
494
+ // 结束测量
495
+ measure.end();
496
+ // 清除所有测量结果
497
+ measure.clean();
498
+ // 销毁测量工具
499
+ measure.destory();
500
+ ```
501
+
502
+ ---
185
503
 
186
- 主类,用于创建和管理地图实例。
504
+ ## API 文档与示例
505
+
506
+ ### MyOl
187
507
 
188
508
  #### 构造函数
189
509
 
190
- ```
191
- constructor(id: string, options: MapInitType)
510
+ ```typescript
511
+ new MyOl(id: string, options: MapInitType)
192
512
  ```
193
513
 
194
- 参数:
195
- - `id`: 地图容器ID
196
- - `options`: 地图初始化配置
197
- - `center`: 中心点坐标 [经度, 纬度]
198
- - `zoom`: 缩放级别
199
- - `minZoom`: 最小缩放级别
200
- - `maxZoom`: 最大缩放级别
201
- - `token`: 天地图token
202
- - `annotation`: 是否显示注记
203
- - `mapClip`: 是否启用地图裁剪
204
- - `mapClipData`: 裁剪数据
205
- - `layers`: 图层配置
206
-
207
514
  #### 方法
208
515
 
209
- - `getPoint()`: 获取点位操作实例
210
- - `getLine()`: 获取线要素操作实例
211
- - `getPolygon()`: 获取面要素操作实例
212
- - `getTools()`: 获取地图工具实例
213
- - `getMapBaseLayers()`: 获取底图图层管理实例
214
- - `restPosition(duration?: number)`: 重置地图位置
215
- - `locationAction(lgtd: number, lttd: number, zoom?: number, duration?: number)`: 地图定位
216
- - `mapOnEvent(eventType: string, callback: Function, clickType?: string)`: 地图事件监听
217
- - `showMapLayer(layerName: string, show: boolean)`: 控制图层显隐
516
+ - **getPoint()**
517
+ > 获取点位操作实例。
518
+ ```javascript
519
+ const point = map.getPoint();
520
+ ```
521
+
522
+ - **getLine()**
523
+ > 获取线要素操作实例。
524
+ ```javascript
525
+ const line = map.getLine();
526
+ ```
527
+
528
+ - **getPolygon()**
529
+ > 获取面要素操作实例。
530
+ ```javascript
531
+ const polygon = map.getPolygon();
532
+ ```
533
+
534
+ - **getTools()**
535
+ > 获取地图工具实例。
536
+ ```javascript
537
+ const tools = map.getTools();
538
+ ```
539
+
540
+ - **getMapBaseLayers()**
541
+ > 获取底图图层管理实例。
542
+ ```javascript
543
+ const baseLayers = map.getMapBaseLayers();
544
+ ```
545
+
546
+ - **resetPosition(duration?: number)**
547
+ > 重置地图位置。
548
+ ```javascript
549
+ map.resetPosition(1000); // 1秒动画重置
550
+ ```
551
+
552
+ - **locationAction(lgtd: number, lttd: number, zoom?: number, duration?: number)**
553
+ > 地图定位到指定点。
554
+ ```javascript
555
+ map.locationAction(119.81, 29.969, 15, 1000);
556
+ ```
557
+
558
+ - **mapOnEvent(eventType: string, callback: Function, clickType?: string)**
559
+ > 地图事件监听。
560
+ ```javascript
561
+ map.mapOnEvent('click', (feature, event) => {
562
+ console.log('点击要素:', feature);
563
+ });
564
+ ```
565
+
566
+ ---
218
567
 
219
568
  ### MapBaseLayers
220
569
 
221
- 底图图层管理类。
570
+ - **switchBaseLayer(type: TiandituType)**
571
+ > 切换底图。
572
+ ```javascript
573
+ baseLayers.switchBaseLayer('img_c');
574
+ ```
575
+
576
+ - **addAnnotationLayer(options: AnnotationLayerOptions)**
577
+ > 添加注记图层。
578
+ ```javascript
579
+ baseLayers.addAnnotationLayer({
580
+ type: 'cva_c',
581
+ zIndex: 11,
582
+ visible: true
583
+ });
584
+ ```
222
585
 
223
- #### 方法
586
+ - **initLayer()**
587
+ > 初始化底图图层。
588
+ ```javascript
589
+ baseLayers.initLayer();
590
+ ```
224
591
 
225
- - `switchBaseLayer(type: TiandituType)`: 切换底图
226
- - `addAnnotationLayer(options: AnnotationLayerOptions)`: 添加注记图层
227
- - `initLayer()`: 初始化图层
592
+ ---
228
593
 
229
594
  ### Point
230
595
 
231
- 点位操作类。
232
-
233
- #### 方法
596
+ - **addPoint(pointData: PointData[], options: OptionsType)**
597
+ > 添加普通点位。
598
+ ```javascript
599
+ point.addPoint([
600
+ { lgtd: 119.81, lttd: 29.969, name: '测试点位' }
601
+ ], {
602
+ layerName: 'test-point',
603
+ nameKey: 'name',
604
+ img: 'marker.png',
605
+ hasImg: true
606
+ });
607
+ ```
608
+
609
+ - **addClusterPoint(pointData: PointData[], options: OptionsType)**
610
+ > 添加聚合点位。
611
+ ```javascript
612
+ point.addClusterPoint([
613
+ { lgtd: 119.81, lttd: 29.969, name: 'A' },
614
+ { lgtd: 119.82, lttd: 29.97, name: 'B' }
615
+ ], {
616
+ layerName: 'cluster-point',
617
+ nameKey: 'name',
618
+ img: 'cluster.png',
619
+ zIndex: 4
620
+ });
621
+ ```
234
622
 
235
- - `addPoint(pointData: PointData[], type: string, options: OptionsType)`: 添加点位
236
- - `addClusterPoint(pointData: any[], type: string, options: OptionsType)`: 添加聚合点位
237
- - `setDomPointVue(pointInfoList: any[], template: any, Vue: any)`: 添加Vue组件点位
238
- - `locationAction(lgtd: number, lttd: number, zoom?: number, duration?: number)`: 地图定位
623
+ - **setDomPointVue(pointInfoList: any[], template: any, Vue: any)**
624
+ > 添加 Vue 组件点位。
625
+ ```javascript
626
+ const domPoints = point.setDomPointVue(
627
+ [{ lgtd: 119.81, lttd: 29.969 }],
628
+ YourVueComponent,
629
+ Vue
630
+ );
631
+ domPoints.setVisible(true);
632
+ domPoints.remove();
633
+ ```
239
634
 
240
- ### Line
635
+ - **locationAction(lgtd: number, lttd: number, zoom?: number, duration?: number)**
636
+ > 地图定位。
637
+ ```javascript
638
+ point.locationAction(119.81, 29.969, 15, 1000);
639
+ ```
241
640
 
242
- 线要素操作类。
641
+ ---
243
642
 
244
- #### 方法
643
+ ### Line
245
644
 
246
- - `addLineCommon(data: MapJSONData, options: OptionsType)`: 添加普通线要素
247
- - `addRiverLayersByZoom(data: MapJSONData, options: OptionsType)`: 添加河流要素
248
- - `showRiverLayer(show: boolean)`: 控制河流图层显隐
645
+ - **addLineCommon(data: MapJSONData, options: OptionsType)**
646
+ > 添加普通线要素。
647
+ ```javascript
648
+ line.addLineCommon(lineGeoJSON, {
649
+ layerName: 'test-line',
650
+ type: 'test-line',
651
+ strokeColor: '#037AFF',
652
+ strokeWidth: 3
653
+ });
654
+ ```
655
+
656
+ - **addRiverLayersByZoom(data: MapJSONData, options: OptionsType)**
657
+ > 添加河流要素(分级显示)。
658
+ ```javascript
659
+ line.addRiverLayersByZoom(riverGeoJSON, {
660
+ layerName: 'river',
661
+ type: 'river',
662
+ strokeColor: '#0071FF',
663
+ strokeWidth: 3,
664
+ zIndex: 6,
665
+ visible: true
666
+ });
667
+ ```
668
+
669
+ - **showRiverLayer(show: boolean)**
670
+ > 控制河流图层显隐。
671
+ ```javascript
672
+ line.showRiverLayer(true); // 显示
673
+ line.showRiverLayer(false); // 隐藏
674
+ ```
675
+
676
+ ---
677
+
678
+ ### Polygon
679
+
680
+ - **addBorderPolygon(data: MapJSONData, options?: OptionsType)**
681
+ > 添加边界面。
682
+ ```javascript
683
+ polygon.addBorderPolygon(borderGeoJSON, {
684
+ layerName: 'border',
685
+ fillColor: 'rgba(255,255,255,0)',
686
+ strokeColor: '#EBEEF5',
687
+ strokeWidth: 2
688
+ });
689
+ ```
690
+
691
+ - **addPolygon(data: MapJSONData, options?: OptionsType)**
692
+ > 添加分区面。
693
+ ```javascript
694
+ polygon.addPolygon(zoneGeoJSON, {
695
+ layerName: 'zone',
696
+ fillColor: 'rgba(1, 111, 255, 0.3)',
697
+ strokeColor: '#037AFF',
698
+ strokeWidth: 2,
699
+ textVisible: true,
700
+ nameKey: 'name',
701
+ textFont: '14px Calibri,sans-serif',
702
+ textFillColor: '#FFF',
703
+ textStrokeColor: '#409EFF',
704
+ textStrokeWidth: 2
705
+ });
706
+ ```
707
+
708
+ - **updateFeatureColor(layerName: string, colorObj?: { [propName: string]: string }, options?: OptionsType)**
709
+ > 更新面颜色。
710
+ ```javascript
711
+ polygon.updateFeatureColor('zone', { 'A区': 'rgba(255,0,0,0.6)' }, { nameKey: 'name' });
712
+ ```
713
+
714
+ - **addImage(layerName: string, img?: string, extent?: number[], options?: OptionsType)**
715
+ > 添加图片图层。
716
+ ```javascript
717
+ polygon.addImage('imgLayer', 'img.png', [minx, miny, maxx, maxy], { zIndex: 10 });
718
+ ```
719
+
720
+ - **addHeatmap(layerName: string, pointData: PointData[], options: HeatMapOptions)**
721
+ > 添加热力图。
722
+ ```javascript
723
+ polygon.addHeatmap('heatLayer', [
724
+ { lgtd: 119.81, lttd: 29.969, value: 10 },
725
+ { lgtd: 119.82, lttd: 29.97, value: 20 }
726
+ ], {
727
+ valueKey: 'value',
728
+ radius: 20,
729
+ blur: 15
730
+ });
731
+ ```
732
+
733
+ - **removePolygonLayer(layerName: string)**
734
+ > 移除面图层。
735
+ ```javascript
736
+ polygon.removePolygonLayer('zone');
737
+ ```
738
+
739
+ ---
249
740
 
250
741
  ### MapTools
251
742
 
252
- 地图工具类。
743
+ - **getLayerByLayerName(layerName: string)**
744
+ > 获取图层。
745
+ ```javascript
746
+ const layer = tools.getLayerByLayerName('myLayer');
747
+ ```
748
+
749
+ - **removeLayer(layerName: string)**
750
+ > 移除图层。
751
+ ```javascript
752
+ tools.removeLayer('myLayer');
753
+ ```
754
+
755
+ - **setLayerVisible(layerName: string, visible: boolean)**
756
+ > 设置图层可见性。
757
+ ```javascript
758
+ tools.setLayerVisible('myLayer', true);
759
+ ```
760
+
761
+ - **mapOnEvent(eventType: string, callback: Function, clickType?: string)**
762
+ > 地图事件监听。
763
+ ```javascript
764
+ tools.mapOnEvent('click', (feature, event) => {
765
+ console.log('点击要素:', feature);
766
+ });
767
+ ```
768
+
769
+ - **static setMapClip(baseLayer: any, data: MapJSONData)**
770
+ > 设置地图裁剪。
771
+ ```javascript
772
+ MapTools.setMapClip(baseLayer, clipGeoJSON);
773
+ ```
774
+
775
+ ---
776
+
777
+ ### MeasureHandler
778
+
779
+ - **start(type: 'Polygon' | 'LineString')**
780
+ > 开始测量。
781
+ ```javascript
782
+ measure.start('Polygon');
783
+ measure.start('LineString');
784
+ ```
785
+
786
+ - **end()**
787
+ > 结束测量。
788
+ ```javascript
789
+ measure.end();
790
+ ```
791
+
792
+ - **clean()**
793
+ > 清除所有测量结果。
794
+ ```javascript
795
+ measure.clean();
796
+ ```
797
+
798
+ - **destory()**
799
+ > 销毁测量工具。
800
+ ```javascript
801
+ measure.destory();
802
+ ```
803
+
804
+ ---
253
805
 
254
- #### 方法
806
+ ## 类型定义
255
807
 
256
- - `getLayerByLayerName(layerName: string)`: 获取图层
257
- - `removeLayer(layerName: string)`: 移除图层
258
- - `static mapOnEvent(map: Map, eventType: string, callback: Function, clickType?: string)`: 事件监听
259
- - `static setMapClip(baseLayer: any, data: MapJSONData)`: 设置地图裁剪
808
+ 本库提供完整的 TypeScript 类型定义,采用模块化设计,详见 [src/types.ts](src/types.ts)
260
809
 
261
- ## 类型定义
810
+ ### 核心类型
262
811
 
263
812
  ```typescript
813
+ // 地图初始化配置
264
814
  interface MapInitType {
265
- layers?: undefined;
266
- zoom?: number;
267
- center?: number[];
268
- minZoom?: number;
269
- maxZoom?: number;
270
- extent?: undefined;
271
- token?: string;
272
- annotation?: boolean;
273
- mapClip?: boolean;
274
- mapClipData?: any;
815
+ layers?: BaseLayer[] | { [key: string]: BaseLayer[] },
816
+ zoom?: number,
817
+ center?: number[],
818
+ minZoom?: number,
819
+ maxZoom?: number,
820
+ extent?: number[],
821
+ mapClipData?: MapJSONData,
822
+ token?: string,
823
+ annotation?: boolean
824
+ }
825
+
826
+ // 点位数据
827
+ interface PointData {
828
+ lgtd: number, // 经度
829
+ lttd: number, // 纬度
830
+ [key: string]: any // 其他属性
831
+ }
832
+
833
+ // GeoJSON 数据
834
+ interface MapJSONData {
835
+ type: string,
836
+ name?: string,
837
+ features: Feature[]
838
+ }
839
+
840
+ // 事件类型
841
+ type EventType = 'click' | 'hover' | 'moveend';
842
+
843
+ // 天地图类型
844
+ type TiandituType = 'vec_c' | 'img_c' | 'ter_c' | string;
845
+ ```
846
+
847
+ ### 模块化选项接口
848
+
849
+ ```typescript
850
+ // 基础选项 - 所有图层的公共配置
851
+ interface BaseOptions {
852
+ /** 图层名称 */
853
+ layerName?: string;
854
+ /** 图层层级 */
855
+ zIndex?: number;
856
+ /** 图层可见性 */
857
+ visible?: boolean;
858
+ /** 图层透明度 */
859
+ opacity?: number;
860
+ /** 是否适应视图 */
861
+ fitView?: boolean;
862
+ // ... 其他基础属性
863
+ }
864
+
865
+ // 样式选项 - 图形样式相关配置
866
+ interface StyleOptions {
867
+ /** 描边颜色 */
868
+ strokeColor?: string | number[];
869
+ /** 描边宽度 */
870
+ strokeWidth?: number;
871
+ /** 线条虚线样式 */
872
+ lineDash?: number[];
873
+ /** 填充颜色 */
874
+ fillColor?: string;
875
+ // ... 其他样式属性
275
876
  }
276
877
 
277
- type TiandituType = 'vec_c' | 'img_c' | 'ter_c';
878
+ // 文本选项 - 文本标注相关配置
879
+ interface TextOptions {
880
+ /** 文本可见性 */
881
+ textVisible?: boolean;
882
+ /** 文本内容回调函数 */
883
+ textCallBack?: (feature: any) => string;
884
+ /** 文本字体 */
885
+ textFont?: string;
886
+ /** 文本填充颜色 */
887
+ textFillColor?: string;
888
+ // ... 其他文本属性
889
+ }
890
+
891
+ // 点位选项 - 点位图层专用配置
892
+ interface PointOptions extends BaseOptions, StyleOptions, TextOptions {
893
+ /** 名称字段键 */
894
+ nameKey?: string;
895
+ /** 图标图片 */
896
+ img?: string;
897
+ /** 图标缩放比例 */
898
+ scale?: number;
899
+ /** 是否有图标 */
900
+ hasImg?: boolean;
901
+ /** 图标颜色 */
902
+ iconColor?: string;
903
+ }
904
+
905
+ // 线条选项 - 线条图层专用配置
906
+ interface LineOptions extends BaseOptions, StyleOptions, TextOptions {
907
+ /** 线条类型 */
908
+ type?: string;
909
+ }
910
+
911
+ // 多边形选项 - 多边形图层专用配置
912
+ interface PolygonOptions extends BaseOptions, StyleOptions, TextOptions {
913
+ /** 名称字段键 */
914
+ nameKey?: string;
915
+ /** 是否为蒙版 */
916
+ mask?: boolean;
917
+ }
278
918
 
279
- interface AnnotationLayerOptions {
280
- type: string;
281
- token: string;
282
- zIndex?: number;
283
- visible?: boolean;
919
+ // 聚合选项 - 聚合点位专用配置
920
+ interface ClusterOptions extends PointOptions {
921
+ /** 聚合距离 */
922
+ distance?: number;
923
+ /** 最小聚合距离 */
924
+ minDistance?: number;
284
925
  }
285
926
 
286
- interface OptionsType {
287
- type?: string;
288
- nameKey?: string;
289
- img?: string;
290
- hasImg?: boolean;
291
- textFont?: string;
292
- textFillColor?: string;
293
- textStrokeColor?: string;
294
- textStrokeWidth?: number;
295
- textOffsetY?: number;
296
- zIndex?: number;
297
- visible?: boolean;
298
- strokeColor?: string;
299
- strokeWidth?: number;
927
+ // 热力图选项
928
+ interface HeatMapOptions {
929
+ layerName?: string,
930
+ radius?: number,
931
+ blur?: number,
932
+ gradient?: string[],
933
+ opacity?: number,
934
+ visible?: boolean,
935
+ zIndex?: number,
936
+ valueKey?: string,
300
937
  }
301
938
  ```
302
939
 
940
+ ### 兼容性类型
941
+
942
+ ```typescript
943
+ /**
944
+ * 兼容性类型别名 - 保持向后兼容
945
+ * @deprecated 请使用具体的选项接口:PointOptions, LineOptions, PolygonOptions
946
+ */
947
+ type OptionsType = BaseOptions & StyleOptions & TextOptions & {
948
+ nameKey?: string;
949
+ img?: string;
950
+ scale?: number;
951
+ hasImg?: boolean;
952
+ iconColor?: string;
953
+ type?: string;
954
+ mask?: boolean;
955
+ };
956
+ ```
957
+
958
+ ## 迁移指南
959
+
960
+ 如果您正在从旧版本的 `OptionsType` 迁移到新的模块化类型接口,请参考详细的 [迁移指南](MIGRATION_GUIDE.md)。
961
+
962
+ ### 快速迁移示例
963
+
964
+ ```typescript
965
+ // 旧写法
966
+ import { MyOl, OptionsType } from 'my-openlayer';
967
+ const options: OptionsType = {
968
+ layerName: 'points',
969
+ strokeColor: '#ff0000',
970
+ img: '/icons/marker.png'
971
+ };
972
+
973
+ // 新写法
974
+ import { MyOl, PointOptions } from 'my-openlayer';
975
+ const options: PointOptions = {
976
+ layerName: 'points',
977
+ strokeColor: '#ff0000',
978
+ img: '/icons/marker.png'
979
+ };
980
+ ```
981
+
982
+ ### 迁移优势
983
+
984
+ - **类型安全**:更精确的类型检查
985
+ - **代码提示**:更好的 IDE 支持
986
+ - **可维护性**:清晰的模块化结构
987
+ - **向后兼容**:保留 `OptionsType` 作为兼容性类型
988
+
989
+ ---
990
+
303
991
  ## 依赖
304
992
 
305
- - ol ^6.15.1
306
- - proj4 ^2.7.5
307
- - turf ^3.0.14
993
+ ### 运行时依赖
994
+
995
+ - **[OpenLayers](https://openlayers.org/)** `^6.15.1` - 核心地图库
996
+ - **[proj4](https://github.com/proj4js/proj4js)** `^2.7.5` - 坐标系转换
997
+ - **[turf](https://turfjs.org/)** `^3.0.14` - 地理空间分析
998
+
999
+ ### 开发依赖
1000
+
1001
+ - **[TypeScript](https://www.typescriptlang.org/)** `~5.6.2` - 类型支持
1002
+ - **[Vite](https://vitejs.dev/)** `^5.4.10` - 构建工具
1003
+ - **[@types/proj4](https://www.npmjs.com/package/@types/proj4)** `^2.5.2` - proj4 类型定义
1004
+ - **[@types/turf](https://www.npmjs.com/package/@types/turf)** `^3.5.32` - turf 类型定义
1005
+
1006
+ ### 对等依赖
1007
+
1008
+ - **[OpenLayers](https://openlayers.org/)** `^6.15.1` - 确保版本兼容性
1009
+
1010
+ > **注意**:本库与 OpenLayers 6.15.1 完全兼容,建议使用相同版本以获得最佳体验。
1011
+
1012
+ ---
1013
+
1014
+ ## 贡献指南
1015
+
1016
+ 欢迎提交 Issue 或 Pull Request!
1017
+
1018
+ 1. Fork 本仓库
1019
+ 2. 新建分支:`git checkout -b feature/your-feature`
1020
+ 3. 提交更改:`git commit -m 'feat: 新功能描述'`
1021
+ 4. 推送分支:`git push origin feature/your-feature`
1022
+ 5. 提交 Pull Request
1023
+
1024
+ ---
1025
+
1026
+ ## 常见问题
1027
+
1028
+ ### 基础配置
1029
+
1030
+ **Q: 如何获取天地图 token?**
1031
+
1032
+ A: 访问 [天地图开发者平台](https://lbs.tianditu.gov.cn/) 注册账号并申请密钥(token)。申请后在初始化地图时传入 `token` 参数。
1033
+
1034
+ **Q: 为什么地图无法加载?**
1035
+
1036
+ A: 请检查以下几点:
1037
+ - 天地图 token 是否正确且有效
1038
+ - 网络连接是否正常
1039
+ - 坐标系是否正确(默认使用 EPSG:4326)
1040
+ - 容器元素是否存在且有正确的尺寸
1041
+
1042
+ ### 类型和开发
1043
+
1044
+ **Q: 如何从旧版本迁移到新的类型系统?**
1045
+
1046
+ A: 参考 [迁移指南](MIGRATION_GUIDE.md),主要是将 `OptionsType` 替换为具体的类型接口如 `PointOptions`、`LineOptions` 等。
1047
+
1048
+ **Q: TypeScript 报错怎么办?**
1049
+
1050
+ A:
1051
+ - 确保安装了正确的类型定义包
1052
+ - 使用具体的类型接口而不是通用的 `OptionsType`
1053
+ - 检查导入语句是否正确
1054
+
1055
+ ### 功能使用
308
1056
 
1057
+ **Q: 如何自定义点位样式?**
1058
+
1059
+ A: 通过 `PointOptions` 配置样式:
1060
+ ```typescript
1061
+ const options: PointOptions = {
1062
+ img: '/path/to/icon.png',
1063
+ scale: 1.2,
1064
+ strokeColor: '#ff0000',
1065
+ textVisible: true
1066
+ };
1067
+ ```
1068
+
1069
+ **Q: 如何监听地图事件?**
1070
+
1071
+ A: 使用 `EventManager` 或 `mapOnEvent` 方法:
1072
+ ```typescript
1073
+ // 使用 EventManager
1074
+ const eventManager = new EventManager(map.map);
1075
+ eventManager.on('click', (eventData) => {
1076
+ console.log('点击位置:', eventData.coordinate);
1077
+ });
1078
+
1079
+ // 使用 mapOnEvent
1080
+ map.mapOnEvent('click', (feature, event) => {
1081
+ console.log('点击要素:', feature);
1082
+ });
1083
+ ```
1084
+
1085
+ **Q: 如何处理错误?**
1086
+
1087
+ A: 使用 `ErrorHandler` 进行错误处理:
1088
+ ```typescript
1089
+ import { MyOl, ErrorHandler } from 'my-openlayer';
1090
+
1091
+ // 设置全局错误回调
1092
+ ErrorHandler.getInstance().addErrorCallback((error) => {
1093
+ console.error('地图错误:', error.message);
1094
+ });
1095
+
1096
+ // 手动验证
1097
+ try {
1098
+ ErrorHandler.validateCoordinates(lng, lat);
1099
+ } catch (error) {
1100
+ console.error('坐标验证失败:', error.message);
1101
+ }
1102
+ ```
1103
+
1104
+ ### 框架集成
1105
+
1106
+ **Q: 如何在 Vue 中使用?**
1107
+
1108
+ A: 在组件生命周期中初始化和销毁:
1109
+ ```vue
1110
+ <template>
1111
+ <div id="map-container" style="width: 100%; height: 400px;"></div>
1112
+ </template>
1113
+
1114
+ <script setup>
1115
+ import { onMounted, onUnmounted } from 'vue';
1116
+ import { MyOl } from 'my-openlayer';
1117
+
1118
+ let map = null;
1119
+
1120
+ onMounted(() => {
1121
+ map = new MyOl('map-container', {
1122
+ center: [119.81, 29.969],
1123
+ zoom: 10,
1124
+ token: 'your-token'
1125
+ });
1126
+ });
1127
+
1128
+ onUnmounted(() => {
1129
+ if (map) {
1130
+ map.map.dispose();
1131
+ }
1132
+ });
1133
+ </script>
1134
+ ```
1135
+
1136
+ **Q: 如何在 React 中使用?**
1137
+
1138
+ A: 使用 useEffect 钩子:
1139
+ ```jsx
1140
+ import React, { useEffect, useRef } from 'react';
1141
+ import MyOl from 'my-openlayer';
1142
+
1143
+ function MapComponent() {
1144
+ const mapRef = useRef(null);
1145
+ const containerRef = useRef(null);
1146
+
1147
+ useEffect(() => {
1148
+ if (containerRef.current) {
1149
+ mapRef.current = new MyOl(containerRef.current, {
1150
+ center: [119.81, 29.969],
1151
+ zoom: 10,
1152
+ token: 'your-token'
1153
+ });
1154
+ }
1155
+
1156
+ return () => {
1157
+ if (mapRef.current) {
1158
+ mapRef.current.map.dispose();
1159
+ }
1160
+ };
1161
+ }, []);
1162
+
1163
+ return <div ref={containerRef} style={{ width: '100%', height: '400px' }} />;
1164
+ }
1165
+ ```
1166
+
1167
+ ### 性能优化
1168
+
1169
+ **Q: 如何优化大量点位的性能?**
1170
+
1171
+ A:
1172
+ - 使用聚合功能:`addClusterPoint`
1173
+ - 设置合适的 `distance` 和 `minDistance` 参数
1174
+ - 考虑使用分层加载或虚拟化技术
1175
+
1176
+ **Q: 如何减少内存占用?**
1177
+
1178
+ A:
1179
+ - 及时移除不需要的图层:`tools.removeLayer(layerName)`
1180
+ - 使用事件管理器的 `removeAllListeners()` 清理事件监听
1181
+ - 在组件销毁时调用 `map.dispose()`
1182
+
1183
+ ---
309
1184
 
310
1185
  ## 许可证
311
1186
 
312
1187
  [MIT](LICENSE)
313
1188
 
1189
+ ---
1190
+
1191
+ ## 联系方式
1192
+
1193
+ 如有问题或建议,欢迎通过以下方式联系:
1194
+
1195
+ - 📧 **邮箱**: 2364184627@qq.com
1196
+ - 🐛 **问题反馈**: [GitHub Issues](https://github.com/cuteyuchen/my-openlayer/issues)
1197
+ - 💡 **功能建议**: [GitHub Discussions](https://github.com/cuteyuchen/my-openlayer/discussions)
1198
+ - 📖 **文档**: [在线文档](https://github.com/cuteyuchen/my-openlayer/blob/main/README.md)
1199
+
1200
+ ## 相关资源
1201
+
1202
+ - 🌐 **OpenLayers 官网**: [https://openlayers.org/](https://openlayers.org/)
1203
+ - 🗺️ **天地图开发者平台**: [https://lbs.tianditu.gov.cn/](https://lbs.tianditu.gov.cn/)
1204
+ - 📚 **TypeScript 文档**: [https://www.typescriptlang.org/](https://www.typescriptlang.org/)
1205
+ - 🛠️ **Vite 构建工具**: [https://vitejs.dev/](https://vitejs.dev/)
314
1206
 
315
1207
  ## 更新日志
316
1208
 
317
- ### 0.1.1
318
- - 初始版本发布
319
- - 支持基础地图功能
320
- - 支持点线面要素操作
321
- - 支持天地图底图
1209
+ ### v1.0.0 (最新)
1210
+ - ✨ 重构类型定义,采用模块化设计
1211
+ - 🛠️ 新增错误处理系统
1212
+ - 📊 新增事件管理系统
1213
+ - ⚙️ 新增配置管理器
1214
+ - 📝 完善 TypeScript 类型支持
1215
+ - 📖 新增详细的迁移指南
1216
+ - 🔧 优化 API 设计,提升开发体验
322
1217
 
323
- ## 常见问题
1218
+ 查看完整的 [更新日志](CHANGELOG.md)
324
1219
 
325
- 1. **如何获取天地图token?**
326
- - 访问天地图开发者平台注册账号
327
- - 申请密钥(token)
1220
+ ---
328
1221
 
329
- 2. **为什么地图无法加载?**
330
- - 检查token是否正确
331
- - 检查网络连接
332
- - 确认坐标系是否正确
1222
+ ## 致谢
333
1223
 
334
- 3. **如何自定义点位样式?**
335
- - 通过options参数配置样式
336
- - 支持自定义图标和文字样式
1224
+ 感谢以下开源项目的支持:
337
1225
 
338
- ## 联系方式
1226
+ - [OpenLayers](https://openlayers.org/) - 强大的地图库
1227
+ - [TypeScript](https://www.typescriptlang.org/) - 类型安全的 JavaScript
1228
+ - [Vite](https://vitejs.dev/) - 快速的构建工具
1229
+
1230
+ ---
1231
+
1232
+ <div align="center">
1233
+
1234
+ **⭐ 如果这个项目对您有帮助,请给我们一个 Star!⭐**
1235
+
1236
+ [![GitHub stars](https://img.shields.io/github/stars/cuteyuchen/my-openlayer.svg?style=social&label=Star)](https://github.com/cuteyuchen/my-openlayer)
1237
+ [![GitHub forks](https://img.shields.io/github/forks/cuteyuchen/my-openlayer.svg?style=social&label=Fork)](https://github.com/cuteyuchen/my-openlayer/fork)
1238
+
1239
+ **本项目长期维护,欢迎 Star、Fork 和贡献代码!**
339
1240
 
340
- 如有问题或建议,请提交 [Issue](https://github.com/cuteyuchen/my-openlayer/issues)
1241
+ </div>