expo-gaode-map 1.0.1 → 1.0.3

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 (106) hide show
  1. package/README.md +1 -0
  2. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +17 -1
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +52 -5
  4. package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +184 -6
  5. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +24 -51
  6. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +3 -0
  7. package/build/ExpoGaodeMap.types.d.ts.map +1 -1
  8. package/build/ExpoGaodeMap.types.js +0 -10
  9. package/build/ExpoGaodeMap.types.js.map +1 -1
  10. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  11. package/build/ExpoGaodeMapModule.js +0 -10
  12. package/build/ExpoGaodeMapModule.js.map +1 -1
  13. package/build/ExpoGaodeMapView.d.ts +39 -20
  14. package/build/ExpoGaodeMapView.d.ts.map +1 -1
  15. package/build/ExpoGaodeMapView.js +215 -31
  16. package/build/ExpoGaodeMapView.js.map +1 -1
  17. package/build/components/overlays/Circle.d.ts +0 -15
  18. package/build/components/overlays/Circle.d.ts.map +1 -1
  19. package/build/components/overlays/Circle.js +28 -46
  20. package/build/components/overlays/Circle.js.map +1 -1
  21. package/build/components/overlays/Cluster.d.ts +3 -15
  22. package/build/components/overlays/Cluster.d.ts.map +1 -1
  23. package/build/components/overlays/Cluster.js +3 -25
  24. package/build/components/overlays/Cluster.js.map +1 -1
  25. package/build/components/overlays/HeatMap.d.ts +3 -14
  26. package/build/components/overlays/HeatMap.d.ts.map +1 -1
  27. package/build/components/overlays/HeatMap.js +3 -24
  28. package/build/components/overlays/HeatMap.js.map +1 -1
  29. package/build/components/overlays/Marker.d.ts +2 -15
  30. package/build/components/overlays/Marker.d.ts.map +1 -1
  31. package/build/components/overlays/Marker.js +60 -46
  32. package/build/components/overlays/Marker.js.map +1 -1
  33. package/build/components/overlays/MultiPoint.d.ts +3 -14
  34. package/build/components/overlays/MultiPoint.d.ts.map +1 -1
  35. package/build/components/overlays/MultiPoint.js +3 -24
  36. package/build/components/overlays/MultiPoint.js.map +1 -1
  37. package/build/components/overlays/Polygon.d.ts +13 -16
  38. package/build/components/overlays/Polygon.d.ts.map +1 -1
  39. package/build/components/overlays/Polygon.js +41 -75
  40. package/build/components/overlays/Polygon.js.map +1 -1
  41. package/build/components/overlays/Polyline.d.ts +12 -14
  42. package/build/components/overlays/Polyline.d.ts.map +1 -1
  43. package/build/components/overlays/Polyline.js +34 -35
  44. package/build/components/overlays/Polyline.js.map +1 -1
  45. package/build/components/overlays/index.d.ts.map +1 -1
  46. package/build/components/overlays/index.js +0 -10
  47. package/build/components/overlays/index.js.map +1 -1
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +0 -10
  50. package/build/index.js.map +1 -1
  51. package/build/modules/AMapLocation.d.ts +47 -10
  52. package/build/modules/AMapLocation.d.ts.map +1 -1
  53. package/build/modules/AMapLocation.js +48 -20
  54. package/build/modules/AMapLocation.js.map +1 -1
  55. package/build/modules/AMapPermissions.d.ts +3 -1
  56. package/build/modules/AMapPermissions.d.ts.map +1 -1
  57. package/build/modules/AMapPermissions.js +3 -11
  58. package/build/modules/AMapPermissions.js.map +1 -1
  59. package/build/modules/AMapSDK.d.ts +5 -4
  60. package/build/modules/AMapSDK.d.ts.map +1 -1
  61. package/build/modules/AMapSDK.js +5 -14
  62. package/build/modules/AMapSDK.js.map +1 -1
  63. package/build/modules/AMapView.d.ts.map +1 -1
  64. package/build/modules/AMapView.js +0 -8
  65. package/build/modules/AMapView.js.map +1 -1
  66. package/build/types/index.d.ts.map +1 -1
  67. package/build/types/index.js +0 -10
  68. package/build/types/index.js.map +1 -1
  69. package/build/types/map-view.types.d.ts +30 -0
  70. package/build/types/map-view.types.d.ts.map +1 -1
  71. package/build/types/map-view.types.js.map +1 -1
  72. package/build/types/overlays.types.d.ts +25 -1
  73. package/build/types/overlays.types.d.ts.map +1 -1
  74. package/build/types/overlays.types.js.map +1 -1
  75. package/docs/API.md +40 -0
  76. package/docs/EXAMPLES.md +86 -2
  77. package/docs/RELEASE_GUIDE.md +178 -0
  78. package/expo-module.config.json +1 -1
  79. package/ios/ExpoGaodeMapModule.swift +42 -14
  80. package/ios/ExpoGaodeMapView.swift +210 -7
  81. package/ios/managers/OverlayManager.swift +78 -10
  82. package/ios/overlays/CircleView.swift +41 -12
  83. package/ios/overlays/MarkerView.swift +55 -3
  84. package/ios/overlays/PolygonView.swift +25 -5
  85. package/ios/overlays/PolylineView.swift +23 -4
  86. package/ios/utils/ColorParser.swift +0 -5
  87. package/package.json +1 -1
  88. package/src/ExpoGaodeMap.types.ts +1 -10
  89. package/src/ExpoGaodeMapModule.ts +1 -10
  90. package/src/ExpoGaodeMapView.tsx +257 -38
  91. package/src/components/overlays/Circle.tsx +32 -50
  92. package/src/components/overlays/Cluster.tsx +4 -26
  93. package/src/components/overlays/HeatMap.tsx +4 -25
  94. package/src/components/overlays/Marker.tsx +69 -52
  95. package/src/components/overlays/MultiPoint.tsx +4 -25
  96. package/src/components/overlays/Polygon.tsx +48 -78
  97. package/src/components/overlays/Polyline.tsx +41 -38
  98. package/src/components/overlays/index.ts +0 -11
  99. package/src/index.ts +0 -11
  100. package/src/modules/AMapLocation.ts +56 -20
  101. package/src/modules/AMapPermissions.ts +4 -11
  102. package/src/modules/AMapSDK.ts +7 -14
  103. package/src/modules/AMapView.ts +0 -8
  104. package/src/types/index.ts +1 -10
  105. package/src/types/map-view.types.ts +25 -0
  106. package/src/types/overlays.types.ts +30 -1
@@ -1,24 +1,13 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 14:03:56
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-15 01:50:18
6
- * @FilePath : /expo-gaode-map/src/ExpoGaodeMapView.tsx
7
- * @Description : 高德地图视图组件
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
-
12
1
  import { requireNativeViewManager } from 'expo-modules-core';
13
2
  import * as React from 'react';
14
3
 
15
- import type {
16
- MapViewProps,
4
+ import type {
5
+ MapViewProps,
17
6
  MapViewRef,
18
7
  NativeMapViewRef,
19
- CameraPosition,
20
- LatLng,
21
- Point,
8
+ CameraPosition,
9
+ LatLng,
10
+ Point,
22
11
  CircleProps,
23
12
  MarkerProps,
24
13
  PolylineProps,
@@ -33,115 +22,345 @@ const NativeView: React.ComponentType<MapViewProps & { ref?: React.Ref<NativeMap
33
22
  // 创建 Context 用于子组件访问 MapRef
34
23
  export const MapContext = React.createContext<React.RefObject<MapViewRef | null> | null>(null);
35
24
 
25
+ // Marker 事件管理器
26
+ type MarkerEventCallbacks = {
27
+ onPress?: () => void;
28
+ onDragStart?: () => void;
29
+ onDrag?: () => void;
30
+ onDragEnd?: (event: { nativeEvent: LatLng }) => void;
31
+ };
32
+
33
+ class MarkerEventManager {
34
+ private callbacks = new Map<string, MarkerEventCallbacks>();
35
+
36
+ register(markerId: string, callbacks: MarkerEventCallbacks) {
37
+ this.callbacks.set(markerId, callbacks);
38
+ }
39
+
40
+ unregister(markerId: string) {
41
+ this.callbacks.delete(markerId);
42
+ }
43
+
44
+ trigger(markerId: string, eventType: keyof MarkerEventCallbacks, data?: any) {
45
+ const callbacks = this.callbacks.get(markerId);
46
+ if (callbacks && callbacks[eventType]) {
47
+ callbacks[eventType]!(data);
48
+ }
49
+ }
50
+ }
51
+
52
+ export const MarkerEventContext = React.createContext<MarkerEventManager | null>(null);
53
+
54
+ // Circle 事件管理器
55
+ type CircleEventCallbacks = {
56
+ onPress?: () => void;
57
+ };
58
+
59
+ class CircleEventManager {
60
+ private callbacks = new Map<string, CircleEventCallbacks>();
61
+
62
+ register(circleId: string, callbacks: CircleEventCallbacks) {
63
+ this.callbacks.set(circleId, callbacks);
64
+ }
65
+
66
+ unregister(circleId: string) {
67
+ this.callbacks.delete(circleId);
68
+ }
69
+
70
+ trigger(circleId: string, eventType: keyof CircleEventCallbacks) {
71
+ const callbacks = this.callbacks.get(circleId);
72
+ if (callbacks && callbacks[eventType]) {
73
+ callbacks[eventType]!();
74
+ }
75
+ }
76
+ }
77
+
78
+ export const CircleEventContext = React.createContext<CircleEventManager | null>(null);
79
+
36
80
  /**
37
- * 高德地图视图组件
81
+ * 高德地图视图组件,提供地图操作API和覆盖物管理功能
82
+ *
83
+ * @param props - 组件属性
84
+ * @param ref - 外部ref引用,用于访问地图API方法
85
+ * @returns 返回包含地图视图和上下文提供者的React组件
86
+ *
87
+ * @remarks
88
+ * 该组件内部维护两个ref:
89
+ * - nativeRef: 指向原生地图视图的引用
90
+ * - internalRef: 内部使用的API引用,通过MapContext共享
38
91
  *
39
- * @example
40
- * ```tsx
41
- * import { MapView } from 'expo-gaode-map';
92
+ * 提供的主要API功能包括:
93
+ * - 相机控制(移动、缩放、获取当前位置)
94
+ * - 覆盖物管理(添加/删除/更新标记、折线、多边形、圆形等)
42
95
  *
43
- * function MyMap() {
44
- * const mapRef = React.useRef(null);
45
- *
46
- * return (
47
- * <MapView
48
- * ref={mapRef}
49
- * style={{ flex: 1 }}
50
- * initialCameraPosition={{
51
- * target: { latitude: 39.9, longitude: 116.4 },
52
- * zoom: 10,
53
- * }}
54
- * onLoad={() => console.log('地图加载完成')}
55
- * />
56
- * );
57
- * }
58
- * ```
96
+ * 所有API方法都会检查地图是否已初始化,未初始化时抛出错误
59
97
  */
60
98
  const ExpoGaodeMapView = React.forwardRef<MapViewRef, MapViewProps>((props, ref) => {
61
99
  const nativeRef = React.useRef<NativeMapViewRef>(null);
62
100
  const internalRef = React.useRef<MapViewRef | null>(null);
101
+ const markerEventManager = React.useRef(new MarkerEventManager()).current;
102
+ const circleEventManager = React.useRef(new CircleEventManager()).current;
103
+
104
+ // 处理 Marker 事件
105
+ const handleMarkerPress = React.useCallback((event: any) => {
106
+ const markerId = event.nativeEvent?.markerId;
107
+ if (markerId) {
108
+ markerEventManager.trigger(markerId, 'onPress');
109
+ }
110
+ props.onMarkerPress?.(event);
111
+ }, [props.onMarkerPress]);
112
+
113
+ const handleMarkerDragStart = React.useCallback((event: any) => {
114
+ const markerId = event.nativeEvent?.markerId;
115
+ if (markerId) {
116
+ markerEventManager.trigger(markerId, 'onDragStart');
117
+ }
118
+ props.onMarkerDragStart?.(event);
119
+ }, [props.onMarkerDragStart]);
120
+
121
+ const handleMarkerDrag = React.useCallback((event: any) => {
122
+ const markerId = event.nativeEvent?.markerId;
123
+ if (markerId) {
124
+ markerEventManager.trigger(markerId, 'onDrag');
125
+ }
126
+ props.onMarkerDrag?.(event);
127
+ }, [props.onMarkerDrag]);
128
+
129
+ const handleMarkerDragEnd = React.useCallback((event: any) => {
130
+ const markerId = event.nativeEvent?.markerId;
131
+ if (markerId) {
132
+ markerEventManager.trigger(markerId, 'onDragEnd', {
133
+ nativeEvent: {
134
+ latitude: event.nativeEvent.latitude,
135
+ longitude: event.nativeEvent.longitude
136
+ }
137
+ });
138
+ }
139
+ props.onMarkerDragEnd?.(event);
140
+ }, [props.onMarkerDragEnd]);
141
+
142
+ const handleCirclePress = React.useCallback((event: any) => {
143
+ const circleId = event.nativeEvent?.circleId;
144
+ if (circleId) {
145
+ circleEventManager.trigger(circleId, 'onPress');
146
+ }
147
+ props.onCirclePress?.(event);
148
+ }, [props.onCirclePress]);
63
149
 
64
150
  const apiRef: MapViewRef = React.useMemo(() => ({
151
+ /**
152
+ * 移动地图相机到指定位置
153
+ * @param position 相机位置参数对象,包含目标经纬度、缩放级别等信息
154
+ * @param duration 动画持续时间(毫秒),默认300毫秒
155
+ * @throws 如果地图视图未初始化则抛出错误
156
+ * @returns Promise<void> 异步操作完成后的Promise
157
+ */
65
158
  moveCamera: async (position: CameraPosition, duration: number = 300) => {
66
159
  if (!nativeRef.current) throw new Error('MapView not initialized');
67
160
  return nativeRef.current.moveCamera(position, duration);
68
161
  },
162
+ /**
163
+ * 将屏幕坐标点转换为地理坐标(经纬度)
164
+ * @param point 屏幕坐标点 {x: number, y: number}
165
+ * @returns 返回Promise,解析为对应的地理坐标 {latitude: number, longitude: number}
166
+ * @throws 如果地图视图未初始化,抛出错误 'MapView not initialized'
167
+ */
69
168
  getLatLng: async (point: Point) => {
70
169
  if (!nativeRef.current) throw new Error('MapView not initialized');
71
170
  return nativeRef.current.getLatLng(point);
72
171
  },
172
+ /**
173
+ * 设置地图中心点坐标
174
+ * @param center 要设置的中心点坐标(LatLng格式)
175
+ * @param animated 是否使用动画效果移动地图(默认为false)
176
+ * @throws 如果地图视图未初始化则抛出错误
177
+ */
73
178
  setCenter: async (center: LatLng, animated: boolean = false) => {
74
179
  if (!nativeRef.current) throw new Error('MapView not initialized');
75
180
  return nativeRef.current.setCenter(center, animated);
76
181
  },
182
+ /**
183
+ * 设置地图的缩放级别
184
+ * @param zoom 目标缩放级别
185
+ * @param animated 是否使用动画过渡效果,默认为false
186
+ * @throws 如果地图视图未初始化,抛出错误
187
+ */
77
188
  setZoom: async (zoom: number, animated: boolean = false) => {
78
189
  if (!nativeRef.current) throw new Error('MapView not initialized');
79
190
  return nativeRef.current.setZoom(zoom, animated);
80
191
  },
192
+ /**
193
+ * 获取当前地图的相机位置(视角中心点、缩放级别、倾斜角度等)
194
+ * @returns 返回一个Promise,解析为当前相机位置的对象
195
+ * @throws 如果地图视图未初始化,则抛出错误
196
+ */
81
197
  getCameraPosition: async () => {
82
198
  if (!nativeRef.current) throw new Error('MapView not initialized');
83
199
  return nativeRef.current.getCameraPosition();
84
200
  },
201
+ /**
202
+ * 在地图上添加圆形覆盖物
203
+ * @param id - 圆形覆盖物的唯一标识符
204
+ * @param props - 圆形覆盖物的属性配置
205
+ * @returns Promise<void> 添加操作的异步结果
206
+ * @throws 如果地图视图未初始化,抛出错误'MapView not initialized'
207
+ */
85
208
  addCircle: async (id: string, props: CircleProps) => {
86
209
  if (!nativeRef.current) throw new Error('MapView not initialized');
87
210
  return nativeRef.current.addCircle(id, props);
88
211
  },
212
+ /**
213
+ * 从地图上移除指定的圆形覆盖物
214
+ * @param id - 要移除的圆形覆盖物的唯一标识符
215
+ * @throws 如果地图视图未初始化,抛出错误
216
+ * @returns Promise<void> 异步操作完成
217
+ */
89
218
  removeCircle: async (id: string) => {
90
219
  if (!nativeRef.current) throw new Error('MapView not initialized');
91
220
  return nativeRef.current.removeCircle(id);
92
221
  },
222
+ /**
223
+ * 更新地图上的圆形覆盖物
224
+ * @param id 要更新的圆形覆盖物的唯一标识符
225
+ * @param props 要更新的圆形属性(部分属性)
226
+ * @throws 如果地图视图未初始化,抛出错误
227
+ * @returns Promise<void> 表示更新操作完成
228
+ */
93
229
  updateCircle: async (id: string, props: Partial<CircleProps>) => {
94
230
  if (!nativeRef.current) throw new Error('MapView not initialized');
95
231
  return nativeRef.current.updateCircle(id, props);
96
232
  },
233
+ /**
234
+ * 添加一个标记点到地图上
235
+ * @param id 标记点的唯一标识符
236
+ * @param props 标记点的配置属性
237
+ * @returns Promise<void> 添加操作完成后的Promise
238
+ * @throws 如果地图视图未初始化则抛出错误
239
+ */
97
240
  addMarker: async (id: string, props: MarkerProps) => {
98
241
  if (!nativeRef.current) throw new Error('MapView not initialized');
99
242
  return nativeRef.current.addMarker(id, props);
100
243
  },
244
+ /**
245
+ * 从地图上移除指定ID的标记点
246
+ * @param id 要移除的标记点ID
247
+ * @throws 如果地图视图未初始化则抛出错误
248
+ * @returns Promise<void> 异步操作完成
249
+ */
101
250
  removeMarker: async (id: string) => {
102
251
  if (!nativeRef.current) throw new Error('MapView not initialized');
103
252
  return nativeRef.current.removeMarker(id);
104
253
  },
254
+ /**
255
+ * 更新地图上指定ID的标记点属性
256
+ * @param id - 要更新的标记点唯一标识符
257
+ * @param props - 需要更新的标记点属性对象(部分属性)
258
+ * @throws 如果地图视图未初始化则抛出错误
259
+ * @returns Promise对象,表示异步更新操作
260
+ */
105
261
  updateMarker: async (id: string, props: Partial<MarkerProps>) => {
106
262
  if (!nativeRef.current) throw new Error('MapView not initialized');
107
263
  return nativeRef.current.updateMarker(id, props);
108
264
  },
265
+ /**
266
+ * 添加折线覆盖物到地图
267
+ * @param id - 折线的唯一标识符
268
+ * @param props - 折线的配置属性
269
+ * @returns Promise<void> 添加操作的异步结果
270
+ * @throws 如果地图视图未初始化则抛出错误
271
+ */
109
272
  addPolyline: async (id: string, props: PolylineProps) => {
110
273
  if (!nativeRef.current) throw new Error('MapView not initialized');
111
274
  return nativeRef.current.addPolyline(id, props);
112
275
  },
276
+ /**
277
+ * 移除地图上的指定折线
278
+ * @param id - 要移除的折线的唯一标识符
279
+ * @throws 如果地图视图未初始化,抛出错误
280
+ * @returns Promise<void>
281
+ */
113
282
  removePolyline: async (id: string) => {
114
283
  if (!nativeRef.current) throw new Error('MapView not initialized');
115
284
  return nativeRef.current.removePolyline(id);
116
285
  },
286
+ /**
287
+ * 更新地图上的折线覆盖物
288
+ *
289
+ * @param id 要更新的折线覆盖物的唯一标识符
290
+ * @param props 要更新的折线属性,包含部分PolylineProps属性
291
+ * @returns Promise<void> 异步操作结果
292
+ * @throws 如果地图视图未初始化,抛出错误
293
+ */
117
294
  updatePolyline: async (id: string, props: Partial<PolylineProps>) => {
118
295
  if (!nativeRef.current) throw new Error('MapView not initialized');
119
296
  return nativeRef.current.updatePolyline(id, props);
120
297
  },
298
+ /**
299
+ * 向地图添加多边形覆盖物
300
+ * @param id - 多边形的唯一标识符
301
+ * @param props - 多边形的配置属性
302
+ * @returns Promise<void> 添加操作的异步结果
303
+ * @throws 如果地图视图未初始化则抛出错误
304
+ */
121
305
  addPolygon: async (id: string, props: PolygonProps) => {
122
306
  if (!nativeRef.current) throw new Error('MapView not initialized');
123
307
  return nativeRef.current.addPolygon(id, props);
124
308
  },
309
+ /**
310
+ * 移除地图上的多边形覆盖物
311
+ * @param id - 要移除的多边形覆盖物的唯一标识符
312
+ * @throws 如果地图视图未初始化,抛出错误 'MapView not initialized'
313
+ * @returns Promise<void> 异步操作完成
314
+ */
125
315
  removePolygon: async (id: string) => {
126
316
  if (!nativeRef.current) throw new Error('MapView not initialized');
127
317
  return nativeRef.current.removePolygon(id);
128
318
  },
319
+ /**
320
+ * 更新多边形覆盖物的属性
321
+ *
322
+ * @param id - 要更新的多边形覆盖物的唯一标识符
323
+ * @param props - 要更新的多边形属性对象,包含需要更新的部分属性
324
+ * @throws {Error} 当地图视图未初始化时抛出错误
325
+ * @returns Promise<void> 异步操作完成后的Promise
326
+ */
129
327
  updatePolygon: async (id: string, props: Partial<PolygonProps>) => {
130
328
  if (!nativeRef.current) throw new Error('MapView not initialized');
131
329
  return nativeRef.current.updatePolygon(id, props);
132
330
  },
133
331
  }), []);
134
332
 
135
- // 设置 internalRef 和外部 ref
333
+ /**
334
+ * 将传入的apiRef赋值给internalRef.current
335
+ * 用于在组件内部保存对地图API实例的引用
336
+ */
136
337
  React.useEffect(() => {
137
338
  internalRef.current = apiRef;
138
339
  }, [apiRef]);
139
340
 
341
+ /**
342
+ * 获取当前地图实例的API引用
343
+ * @returns 返回地图API的引用对象,可用于调用地图相关方法
344
+ */
140
345
  React.useImperativeHandle(ref, () => apiRef, [apiRef]);
141
346
 
142
347
  return (
143
348
  <MapContext.Provider value={internalRef}>
144
- <NativeView ref={nativeRef} {...props} />
349
+ <MarkerEventContext.Provider value={markerEventManager}>
350
+ <CircleEventContext.Provider value={circleEventManager}>
351
+ <NativeView
352
+ ref={nativeRef}
353
+ {...props}
354
+ onMarkerPress={handleMarkerPress}
355
+ onMarkerDragStart={handleMarkerDragStart}
356
+ onMarkerDrag={handleMarkerDrag}
357
+ onMarkerDragEnd={handleMarkerDragEnd}
358
+ onCirclePress={handleCirclePress}
359
+ >
360
+ {props.children}
361
+ </NativeView>
362
+ </CircleEventContext.Provider>
363
+ </MarkerEventContext.Provider>
145
364
  </MapContext.Provider>
146
365
  );
147
366
  });
@@ -1,73 +1,55 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 15:02:00
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-13 18:43:00
6
- * @FilePath : /expo-gaode-map/src/components/overlays/Circle.tsx
7
- * @Description : 地图圆形组件 - 使用命令式 API
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
-
12
1
  import * as React from 'react';
13
2
  import type { CircleProps } from '../../types';
14
- import { MapContext } from '../../ExpoGaodeMapView';
3
+ import { MapContext, CircleEventContext } from '../../ExpoGaodeMapView';
15
4
 
16
- /**
17
- * 地图圆形组件
18
- *
19
- * @example
20
- * ```tsx
21
- * <MapView>
22
- * <Circle
23
- * center={{ latitude: 39.9, longitude: 116.4 }}
24
- * radius={1000}
25
- * fillColor={0x440000FF}
26
- * strokeColor={0xFFFF0000}
27
- * />
28
- * </MapView>
29
- * ```
30
- */
31
5
  export default function Circle(props: CircleProps) {
32
6
  const mapRef = React.useContext(MapContext);
7
+ const eventManager = React.useContext(CircleEventContext);
33
8
  const circleIdRef = React.useRef<string | null>(null);
9
+ const propsRef = React.useRef(props);
34
10
 
35
- console.log('Circle 组件渲染,props:', JSON.stringify(props));
11
+ React.useEffect(() => {
12
+ propsRef.current = props;
13
+ }, [props]);
36
14
 
37
15
  React.useEffect(() => {
38
- console.log('Circle useEffect - 添加圆形到地图');
39
-
40
- if (!mapRef?.current) {
41
- console.warn('MapRef 不可用');
42
- return;
43
- }
44
-
45
- // 添加圆形
46
- const circleId = `circle_${Date.now()}_${Math.random()}`;
47
- circleIdRef.current = circleId;
16
+ const checkAndAdd = () => {
17
+ if (!mapRef?.current) {
18
+ setTimeout(checkAndAdd, 50);
19
+ return;
20
+ }
21
+
22
+ const circleId = `circle_${Date.now()}_${Math.random()}`;
23
+ circleIdRef.current = circleId;
24
+
25
+ if (eventManager && props.onPress) {
26
+ eventManager.register(circleId, {
27
+ onPress: props.onPress,
28
+ });
29
+ }
30
+
31
+ mapRef.current.addCircle(circleId, propsRef.current);
32
+ };
48
33
 
49
- mapRef.current.addCircle(circleId, props);
50
- console.log('✅ 圆形已添加:', circleId);
34
+ checkAndAdd();
51
35
 
52
- // 清理函数 - 移除圆形
53
36
  return () => {
54
- console.log('Circle useEffect cleanup - 移除圆形');
55
- if (circleIdRef.current && mapRef?.current) {
56
- mapRef.current.removeCircle(circleIdRef.current);
57
- console.log('✅ 圆形已移除:', circleIdRef.current);
37
+ if (circleIdRef.current) {
38
+ if (eventManager) {
39
+ eventManager.unregister(circleIdRef.current);
40
+ }
41
+ if (mapRef?.current) {
42
+ mapRef.current.removeCircle(circleIdRef.current);
43
+ }
58
44
  }
59
45
  };
60
46
  }, []);
61
-
62
- // 当 props 变化时更新圆形
47
+
63
48
  React.useEffect(() => {
64
- console.log('Circle props 变化,更新圆形');
65
49
  if (circleIdRef.current && mapRef?.current) {
66
50
  mapRef.current.updateCircle(circleIdRef.current, props);
67
- console.log('✅ 圆形已更新:', circleIdRef.current);
68
51
  }
69
52
  }, [props.center, props.radius, props.fillColor, props.strokeColor, props.strokeWidth]);
70
53
 
71
- // 不渲染任何 UI
72
54
  return null;
73
55
  }
@@ -1,37 +1,15 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 15:02:50
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-13 18:19:20
6
- * @FilePath : /expo-gaode-map/src/components/overlays/Cluster.tsx
7
- * @Description : 地图点聚合组件
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
-
12
1
  import { requireNativeViewManager } from 'expo-modules-core';
13
2
  import * as React from 'react';
14
3
  import type { ClusterProps } from '../../types';
15
4
 
16
5
  const NativeCluster = requireNativeViewManager('ExpoGaodeMap_ClusterView');
17
6
 
7
+
18
8
  /**
19
- * 地图点聚合组件
20
- * 将相近的标记点聚合显示,提高大量标记的展示性能
9
+ * 高德地图点聚合组件
21
10
  *
22
- * @example
23
- * ```tsx
24
- * <MapView>
25
- * <Cluster
26
- * points={[
27
- * { latitude: 39.9, longitude: 116.4, id: '1' },
28
- * { latitude: 39.91, longitude: 116.41, id: '2' },
29
- * ]}
30
- * radius={60}
31
- * minClusterSize={2}
32
- * />
33
- * </MapView>
34
- * ```
11
+ * @param props 点聚合组件的属性配置
12
+ * @returns 渲染原生点聚合组件
35
13
  */
36
14
  export default function Cluster(props: ClusterProps) {
37
15
  return <NativeCluster {...props} />;
@@ -1,36 +1,15 @@
1
- /*
2
- * @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
3
- * @Date : 2025-11-13 15:02:15
4
- * @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
5
- * @LastEditTime : 2025-11-13 18:12:07
6
- * @FilePath : /expo-gaode-map/src/components/overlays/HeatMap.tsx
7
- * @Description : 地图热力图组件
8
- *
9
- * Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
10
- */
11
-
12
1
  import { requireNativeViewManager } from 'expo-modules-core';
13
2
  import * as React from 'react';
14
3
  import type { HeatMapProps } from '../../types';
15
4
 
16
5
  const NativeHeatMap = requireNativeViewManager('ExpoGaodeMap_HeatMapView');
17
6
 
7
+
18
8
  /**
19
- * 地图热力图组件
9
+ * 高德地图热力图组件
20
10
  *
21
- * @example
22
- * ```tsx
23
- * <MapView>
24
- * <HeatMap
25
- * data={[
26
- * { latitude: 39.9, longitude: 116.4, intensity: 100 },
27
- * { latitude: 39.91, longitude: 116.41, intensity: 80 },
28
- * ]}
29
- * radius={50}
30
- * opacity={0.6}
31
- * />
32
- * </MapView>
33
- * ```
11
+ * @param props - 热力图配置属性,继承自NativeHeatMap组件的属性
12
+ * @returns 渲染高德地图原生热力图组件
34
13
  */
35
14
  export default function HeatMap(props: HeatMapProps) {
36
15
  return <NativeHeatMap {...props} />;