expo-gaode-map 1.0.6 → 1.0.8

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 (60) hide show
  1. package/README.en.md +320 -0
  2. package/README.md +2 -0
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +1 -298
  4. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +19 -3
  5. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +126 -0
  6. package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +22 -0
  7. package/android/src/main/java/expo/modules/gaodemap/overlays/CircleViewModule.kt +41 -0
  8. package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterViewModule.kt +29 -0
  9. package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapViewModule.kt +27 -0
  10. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +53 -0
  11. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +49 -0
  12. package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointViewModule.kt +21 -0
  13. package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonViewModule.kt +37 -0
  14. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +2 -0
  15. package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineViewModule.kt +45 -0
  16. package/build/ExpoGaodeMapView.js +1 -1
  17. package/build/ExpoGaodeMapView.js.map +1 -1
  18. package/build/components/overlays/Cluster.d.ts.map +1 -1
  19. package/build/components/overlays/Cluster.js +1 -1
  20. package/build/components/overlays/Cluster.js.map +1 -1
  21. package/build/components/overlays/HeatMap.d.ts.map +1 -1
  22. package/build/components/overlays/HeatMap.js +1 -1
  23. package/build/components/overlays/HeatMap.js.map +1 -1
  24. package/build/components/overlays/Marker.d.ts.map +1 -1
  25. package/build/components/overlays/Marker.js +29 -0
  26. package/build/components/overlays/Marker.js.map +1 -1
  27. package/build/components/overlays/MultiPoint.d.ts.map +1 -1
  28. package/build/components/overlays/MultiPoint.js +1 -1
  29. package/build/components/overlays/MultiPoint.js.map +1 -1
  30. package/build/types/map-view.types.d.ts +2 -1
  31. package/build/types/map-view.types.d.ts.map +1 -1
  32. package/build/types/map-view.types.js.map +1 -1
  33. package/docs/API.en.md +418 -0
  34. package/docs/API.md +2 -0
  35. package/docs/ARCHITECTURE.en.md +423 -0
  36. package/docs/ARCHITECTURE.md +2 -0
  37. package/docs/EXAMPLES.en.md +642 -0
  38. package/docs/EXAMPLES.md +2 -0
  39. package/docs/INITIALIZATION.en.md +346 -0
  40. package/docs/INITIALIZATION.md +2 -0
  41. package/expo-module.config.json +22 -2
  42. package/ios/ExpoGaodeMapModule.swift +0 -334
  43. package/ios/ExpoGaodeMapView.swift +19 -5
  44. package/ios/ExpoGaodeMapViewModule.swift +155 -0
  45. package/ios/managers/UIManager.swift +32 -4
  46. package/ios/overlays/CircleViewModule.swift +31 -0
  47. package/ios/overlays/ClusterViewModule.swift +23 -0
  48. package/ios/overlays/HeatMapViewModule.swift +21 -0
  49. package/ios/overlays/MarkerView.swift +50 -2
  50. package/ios/overlays/MarkerViewModule.swift +53 -0
  51. package/ios/overlays/MultiPointViewModule.swift +15 -0
  52. package/ios/overlays/PolygonViewModule.swift +27 -0
  53. package/ios/overlays/PolylineViewModule.swift +39 -0
  54. package/package.json +1 -1
  55. package/src/ExpoGaodeMapView.tsx +1 -1
  56. package/src/components/overlays/Cluster.tsx +2 -1
  57. package/src/components/overlays/HeatMap.tsx +2 -1
  58. package/src/components/overlays/Marker.tsx +47 -0
  59. package/src/components/overlays/MultiPoint.tsx +2 -1
  60. package/src/types/map-view.types.ts +2 -1
package/README.en.md ADDED
@@ -0,0 +1,320 @@
1
+ # expo-gaode-map
2
+
3
+ English | [简体中文](./README.md)
4
+
5
+ A full-featured AMap (Gaode Map) React Native component library, **built with Expo Modules**, providing map display, location, overlays, and more:
6
+ - Android: [AMap Android SDK](https://lbs.amap.com/api/android-sdk/summary)
7
+ - iOS: [AMap iOS SDK](https://lbs.amap.com/api/ios-sdk/summary)
8
+
9
+ > 💡 This component is built with [Expo Modules API](https://docs.expo.dev/modules/overview/), providing type-safe native module interfaces and excellent developer experience.
10
+
11
+ ## ✨ Features
12
+
13
+ - ✅ Complete map functionality (multiple map types, gesture control, camera operations)
14
+ - ✅ Accurate location (continuous location, single location, coordinate conversion)
15
+ - ✅ Rich overlays (Circle, Marker, Polyline, Polygon)
16
+ - ✅ Complete TypeScript type definitions (zero any types)
17
+ - ✅ Modular architecture design
18
+ - ✅ Support both declarative components and imperative API
19
+ - ✅ Cross-platform support (Android, iOS)
20
+ - ✅ Support custom styles and event listeners
21
+ - ✅ Support both React Native architectures (Paper & Fabric)
22
+
23
+ ## 📦 Installation
24
+
25
+ ```bash
26
+ npm install expo-gaode-map
27
+ # or
28
+ yarn add expo-gaode-map
29
+ # or
30
+ pnpm add expo-gaode-map
31
+ ```
32
+
33
+ ### Expo Projects
34
+
35
+ If you're using an Expo managed project (using `expo prebuild` or development builds), you need to rebuild native code after installation:
36
+
37
+ ```bash
38
+ # Using EAS Build
39
+ eas build --platform android
40
+
41
+ # Or using local build
42
+ npx expo prebuild
43
+ npx expo run:android
44
+ ```
45
+
46
+ ### Pure React Native Projects
47
+
48
+ For pure React Native projects (created with `react-native init`), ensure `expo` package is installed as a dependency:
49
+
50
+ ```bash
51
+ npm install expo
52
+ # Then rebuild the app
53
+ npx react-native run-android
54
+ ```
55
+
56
+ ## 🚀 Quick Start
57
+
58
+ ### 1. Get AMap API Key
59
+
60
+ Visit [AMap Open Platform](https://lbs.amap.com/) to register and create an application to get API Key.
61
+
62
+ > ⚠️ **Important: Native Configuration and Permissions**
63
+ >
64
+ > AMap SDK requires configuration in native projects:
65
+ >
66
+ > **Android Required Configuration:**
67
+ > 1. Configure API Key in `AndroidManifest.xml`
68
+ > 2. Add required permissions (network, location, etc.)
69
+ > 3. Configure privacy compliance (required)
70
+ >
71
+ > **iOS Required Configuration:**
72
+ > 1. Configure API Key in `Info.plist`
73
+ > 2. Add location permission descriptions (NSLocationWhenInUseUsageDescription, etc.)
74
+ > 3. Configure privacy compliance (required)
75
+ >
76
+ > **Detailed Configuration Guides:**
77
+ > - **Android**: [AMap Android SDK Configuration Guide](https://lbs.amap.com/api/android-sdk/guide/create-project/android-studio-create-project)
78
+ > - **iOS**: [AMap iOS SDK Configuration Guide](https://lbs.amap.com/api/ios-sdk/guide/create-project/cocoapods)
79
+ >
80
+ > For Expo projects, use `npx expo prebuild` to generate native code before configuration.
81
+
82
+ ### 2. Initialization and Permission Management
83
+
84
+ **Recommended initialization process**:
85
+
86
+ ```tsx
87
+ import { useEffect, useState } from 'react';
88
+ import {
89
+ MapView,
90
+ initSDK,
91
+ checkLocationPermission,
92
+ requestLocationPermission,
93
+ getCurrentLocation,
94
+ } from 'expo-gaode-map';
95
+
96
+ export default function App() {
97
+ const [initialPosition, setInitialPosition] = useState(null);
98
+
99
+ useEffect(() => {
100
+ const initialize = async () => {
101
+ // 1. Initialize SDK
102
+ initSDK({
103
+ androidKey: 'your-android-api-key',
104
+ iosKey: 'your-ios-api-key',
105
+ });
106
+
107
+ // 2. Check and request permission
108
+ const status = await checkLocationPermission();
109
+ if (!status.granted) {
110
+ await requestLocationPermission();
111
+ }
112
+
113
+ // 3. Get location and set map
114
+ try {
115
+ const location = await getCurrentLocation();
116
+ setInitialPosition({
117
+ target: { latitude: location.latitude, longitude: location.longitude },
118
+ zoom: 15
119
+ });
120
+ } catch (error) {
121
+ // Use default location
122
+ setInitialPosition({
123
+ target: { latitude: 39.9, longitude: 116.4 },
124
+ zoom: 10
125
+ });
126
+ }
127
+ };
128
+
129
+ initialize();
130
+ }, []);
131
+
132
+ if (!initialPosition) return null;
133
+
134
+ return (
135
+ <MapView
136
+ style={{ flex: 1 }}
137
+ initialCameraPosition={initialPosition}
138
+ myLocationEnabled={true}
139
+ />
140
+ );
141
+ }
142
+ ```
143
+
144
+ > 📖 **Detailed Initialization Guide**: [INITIALIZATION.en.md](docs/INITIALIZATION.en.md)
145
+ >
146
+ > Includes complete permission handling, error handling, and best practices.
147
+
148
+ ### 3. Basic Map Usage
149
+
150
+ ```tsx
151
+ import { MapView } from 'expo-gaode-map';
152
+
153
+ export default function MapScreen() {
154
+ return (
155
+ <MapView
156
+ style={{ flex: 1 }}
157
+ initialCameraPosition={{
158
+ target: { latitude: 39.9, longitude: 116.4 },
159
+ zoom: 10,
160
+ }}
161
+ myLocationEnabled={true}
162
+ onLoad={() => console.log('Map loaded')}
163
+ />
164
+ );
165
+ }
166
+ ```
167
+
168
+ ## 📚 Feature Overview
169
+
170
+ ### 🗺️ Map Display
171
+ - Multiple map types (normal, satellite, night, etc.)
172
+ - Camera control (move, zoom, rotate, tilt)
173
+ - Gesture control and UI control configuration
174
+ - Zoom level limits
175
+
176
+ ### 📍 Location Features
177
+ - Continuous and single location
178
+ - Reverse geocoding (address resolution)
179
+ - Location configuration (accuracy, interval, mode, etc.)
180
+ - Custom location blue dot style
181
+
182
+ ### 🎨 Overlays
183
+ - Circle
184
+ - Marker
185
+ - Polyline
186
+ - Polygon
187
+ - Support both declarative and imperative usage
188
+
189
+ ### 📝 More Examples
190
+
191
+ For detailed usage examples, see: [EXAMPLES.en.md](docs/EXAMPLES.en.md)
192
+
193
+ Includes:
194
+ - Basic map application
195
+ - Location tracking application
196
+ - Overlay operation examples
197
+ - Advanced usage and best practices
198
+
199
+ ## 📝 Documentation
200
+
201
+ - [API Documentation](docs/API.en.md) - Complete API reference
202
+ - [Usage Examples](docs/EXAMPLES.en.md) - Detailed code examples
203
+ - [Initialization Guide](docs/INITIALIZATION.en.md) - SDK initialization and permission management
204
+ - [Architecture Documentation](docs/ARCHITECTURE.en.md) - Project structure and file descriptions
205
+
206
+ ## 🎨 Advanced Usage
207
+
208
+ ### followUserLocation Explained
209
+
210
+ `followUserLocation` controls whether the map automatically follows user location:
211
+
212
+ **Browse Mode (default - `false`):**
213
+ ```tsx
214
+ <MapView
215
+ myLocationEnabled={true}
216
+ followUserLocation={false} // or omit
217
+ />
218
+ ```
219
+ - ✅ Show location dot
220
+ - ✅ User can freely scroll map
221
+ - ✅ Map won't auto-move
222
+
223
+ **Navigation Mode (`true`):**
224
+ ```tsx
225
+ <MapView
226
+ myLocationEnabled={true}
227
+ followUserLocation={true}
228
+ />
229
+ ```
230
+ - ✅ Show location dot
231
+ - ✅ Map auto-follows user movement
232
+ - ⚠️ Suitable for navigation scenarios
233
+
234
+ ### Imperative API Batch Operations
235
+
236
+ ```tsx
237
+ const mapRef = useRef<MapViewRef>(null);
238
+
239
+ // Add multiple overlays
240
+ const addMultipleOverlays = async () => {
241
+ await mapRef.current?.addCircle('circle1', {
242
+ center: { latitude: 39.9, longitude: 116.4 },
243
+ radius: 1000,
244
+ fillColor: 0x8800FF00,
245
+ });
246
+
247
+ await mapRef.current?.addCircle('circle2', {
248
+ center: { latitude: 40.0, longitude: 116.5 },
249
+ radius: 500,
250
+ fillColor: 0x880000FF,
251
+ });
252
+
253
+ await mapRef.current?.addMarker('marker1', {
254
+ position: { latitude: 39.95, longitude: 116.45 },
255
+ title: 'Beijing',
256
+ });
257
+ };
258
+
259
+ // Batch clear
260
+ const clearAll = async () => {
261
+ await mapRef.current?.removeCircle('circle1');
262
+ await mapRef.current?.removeCircle('circle2');
263
+ await mapRef.current?.removeMarker('marker1');
264
+ };
265
+ ```
266
+
267
+ ### Color Format
268
+
269
+ Overlay colors support two formats:
270
+
271
+ 1. **String format** (ARGB): `"#AARRGGBB"`
272
+ ```tsx
273
+ <Circle fillColor="#8800FF00" /> // 50% transparent green
274
+ ```
275
+
276
+ 2. **Number format** (imperative API): `0xAARRGGBB`
277
+ ```tsx
278
+ await mapRef.current?.addCircle('circle1', {
279
+ fillColor: 0x8800FF00, // 50% transparent green
280
+ });
281
+ ```
282
+
283
+ ### Performance Optimization
284
+
285
+ - ✅ Use imperative API for large numbers of overlays
286
+ - ✅ Remove unnecessary overlays promptly
287
+ - ✅ Avoid complex operations in high-frequency events like `onPress`
288
+ - ✅ Don't set location interval too small (recommend >= 1000ms)
289
+
290
+ ## 🤝 Contributing
291
+
292
+ Issues and Pull Requests are welcome!
293
+
294
+ ## 📄 License
295
+
296
+ MIT
297
+
298
+ ## 🔗 Related Links
299
+
300
+ - [AMap Open Platform](https://lbs.amap.com/)
301
+ - [AMap Android SDK](https://lbs.amap.com/api/android-sdk/summary)
302
+ - [Expo Modules API](https://docs.expo.dev/modules/overview/)
303
+ - [GitHub Repository](https://github.com/TomWq/expo-gaode-map)
304
+
305
+ ## 🙏 Acknowledgments
306
+
307
+ This project referenced the following excellent projects during development:
308
+
309
+ - **[react-native-amap3d](https://github.com/qiuxiang/react-native-amap3d)** - An excellent React Native AMap component that provided important references for this project's design and implementation
310
+
311
+ Thanks to the contributors of these open-source projects for bringing valuable experience and code to the community.
312
+
313
+ ## 📮 Feedback and Support
314
+
315
+ If you encounter problems or have suggestions:
316
+
317
+ - 📝 Submit [GitHub Issue](https://github.com/TomWq/expo-gaode-map/issues)
318
+ - 💬 Join [Discussions](https://github.com/TomWq/expo-gaode-map/discussions)
319
+ - ⭐ Star the project to show support
320
+ - 💬 Join QQ Group: 952241387
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # expo-gaode-map
2
2
 
3
+ [English](./README.en.md) | 简体中文
4
+
3
5
  一个功能完整的高德地图 React Native 组件库,**基于 Expo Modules 开发**,提供地图显示、定位、覆盖物等功能:
4
6
  - Android: [高德地图 Android SDK](https://lbs.amap.com/api/android-sdk/summary)
5
7
  - iOS: [高德地图 iOS SDK](https://lbs.amap.com/api/ios-sdk/summary)
@@ -1,20 +1,17 @@
1
1
  package expo.modules.gaodemap
2
2
 
3
-
4
3
  import expo.modules.kotlin.modules.Module
5
4
  import expo.modules.kotlin.modules.ModuleDefinition
6
5
  import expo.modules.gaodemap.modules.SDKInitializer
7
6
  import expo.modules.gaodemap.modules.LocationManager
8
- import expo.modules.gaodemap.overlays.*
9
7
 
10
8
  /**
11
9
  * 高德地图 Expo 模块
12
- *
10
+ *
13
11
  * 负责:
14
12
  * - SDK 初始化和版本管理
15
13
  * - 定位功能和配置
16
14
  * - 权限管理
17
- * - 地图视图和覆盖物注册
18
15
  */
19
16
  class ExpoGaodeMapModule : Module() {
20
17
 
@@ -317,302 +314,8 @@ class ExpoGaodeMapModule : Module() {
317
314
  handler.postDelayed(checkPermission, 100)
318
315
  }
319
316
 
320
- // ==================== 事件 ====================
321
-
322
317
  Events("onLocationUpdate")
323
318
 
324
- // ==================== 视图定义 ====================
325
-
326
- View(ExpoGaodeMapView::class) {
327
-
328
- // 事件
329
- Events("onMapPress", "onMapLongPress", "onLoad", "onMarkerPress", "onMarkerDragStart", "onMarkerDrag", "onMarkerDragEnd", "onCirclePress", "onPolygonPress", "onPolylinePress")
330
-
331
- // 地图类型
332
- Prop<Int>("mapType") { view, type ->
333
- view.mapType = type
334
- view.setMapType(type)
335
- }
336
-
337
- // 初始相机位置
338
- Prop<Map<String, Any?>?>("initialCameraPosition") { view, position ->
339
- view.initialCameraPosition = position
340
- position?.let { view.setInitialCameraPosition(it) }
341
- }
342
-
343
- // 控件显示
344
- Prop<Boolean>("zoomControlsEnabled") { view, show -> view.setShowsZoomControls(show) }
345
- Prop<Boolean>("compassEnabled") { view, show -> view.setShowsCompass(show) }
346
- Prop<Boolean>("scaleControlsEnabled") { view, show -> view.setShowsScale(show) }
347
-
348
- // 手势控制
349
- Prop<Boolean>("zoomGesturesEnabled") { view, enabled -> view.setZoomEnabled(enabled) }
350
- Prop<Boolean>("scrollGesturesEnabled") { view, enabled -> view.setScrollEnabled(enabled) }
351
- Prop<Boolean>("rotateGesturesEnabled") { view, enabled -> view.setRotateEnabled(enabled) }
352
- Prop<Boolean>("tiltGesturesEnabled") { view, enabled -> view.setTiltEnabled(enabled) }
353
-
354
- // 缩放级别限制
355
- Prop<Float>("maxZoom") { view, maxZoom -> view.setMaxZoom(maxZoom) }
356
- Prop<Float>("minZoom") { view, minZoom -> view.setMinZoom(minZoom) }
357
-
358
- // 地图图层
359
- Prop<Boolean>("myLocationEnabled") { view, show -> view.setShowsUserLocation(show) }
360
- Prop<Boolean>("followUserLocation") { view, follow -> view.setFollowUserLocation(follow) }
361
- Prop<Map<String, Any>?>("userLocationRepresentation") { view, representation ->
362
- representation?.let { view.setUserLocationRepresentation(it) }
363
- }
364
- Prop<Boolean>("trafficEnabled") { view, show -> view.setShowsTraffic(show) }
365
- Prop<Boolean>("buildingsEnabled") { view, show -> view.setShowsBuildings(show) }
366
- Prop<Boolean>("indoorViewEnabled") { view, show -> view.setShowsIndoorMap(show) }
367
-
368
- // 生命周期方法
369
- OnViewDidUpdateProps { view: ExpoGaodeMapView ->
370
- if (view.mapType != 0) {
371
- view.setMapType(view.mapType)
372
- }
373
-
374
- view.initialCameraPosition?.let { position ->
375
- view.setInitialCameraPosition(position)
376
- }
377
- }
378
-
379
- // 相机控制方法
380
- AsyncFunction("moveCamera") { view: ExpoGaodeMapView, position: Map<String, Any>, duration: Int ->
381
- view.moveCamera(position, duration)
382
- }
383
-
384
- AsyncFunction("getLatLng") { view: ExpoGaodeMapView, point: Map<String, Double> ->
385
- view.getLatLng(point)
386
- }
387
-
388
- AsyncFunction("setCenter") { view: ExpoGaodeMapView, center: Map<String, Double>, animated: Boolean ->
389
- view.setCenter(center, animated)
390
- }
391
-
392
- AsyncFunction("setZoom") { view: ExpoGaodeMapView, zoom: Double, animated: Boolean ->
393
- view.setZoomLevel(zoom.toFloat(), animated)
394
- }
395
-
396
- AsyncFunction("getCameraPosition") { view: ExpoGaodeMapView ->
397
- view.getCameraPosition()
398
- }
399
-
400
- // Circle 命令
401
- AsyncFunction("addCircle") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
402
- view.addCircle(id, props)
403
- }
404
-
405
- AsyncFunction("removeCircle") { view: ExpoGaodeMapView, id: String ->
406
- view.removeCircle(id)
407
- }
408
-
409
- AsyncFunction("updateCircle") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
410
- view.updateCircle(id, props)
411
- }
412
-
413
- // Marker 命令
414
- AsyncFunction("addMarker") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
415
- view.addMarker(id, props)
416
- }
417
-
418
- AsyncFunction("removeMarker") { view: ExpoGaodeMapView, id: String ->
419
- view.removeMarker(id)
420
- }
421
-
422
- AsyncFunction("updateMarker") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
423
- view.updateMarker(id, props)
424
- }
425
-
426
- // Polyline 命令
427
- AsyncFunction("addPolyline") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
428
- view.addPolyline(id, props)
429
- }
430
-
431
- AsyncFunction("removePolyline") { view: ExpoGaodeMapView, id: String ->
432
- view.removePolyline(id)
433
- }
434
-
435
- AsyncFunction("updatePolyline") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
436
- view.updatePolyline(id, props)
437
- }
438
-
439
- // Polygon 命令
440
- AsyncFunction("addPolygon") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
441
- view.addPolygon(id, props)
442
- }
443
-
444
- AsyncFunction("removePolygon") { view: ExpoGaodeMapView, id: String ->
445
- view.removePolygon(id)
446
- }
447
-
448
- AsyncFunction("updatePolygon") { view: ExpoGaodeMapView, id: String, props: Map<String, Any> ->
449
- view.updatePolygon(id, props)
450
- }
451
- }
452
-
453
- // ==================== 覆盖物视图注册 ====================
454
-
455
- // Marker - 标记点
456
- View(MarkerView::class) {
457
- Events("onPress", "onDragStart", "onDrag", "onDragEnd")
458
-
459
- Prop<Map<String, Double>>("position") { view: MarkerView, position ->
460
- view.setPosition(position)
461
- }
462
-
463
- Prop<String>("title") { view: MarkerView, title ->
464
- view.setTitle(title)
465
- }
466
-
467
- Prop<String>("description") { view: MarkerView, description ->
468
- view.setDescription(description)
469
- }
470
-
471
- Prop<Boolean>("draggable") { view: MarkerView, draggable ->
472
- view.setDraggable(draggable)
473
- }
474
-
475
- Prop<Float>("opacity") { view: MarkerView, opacity ->
476
- view.setOpacity(opacity)
477
- }
478
-
479
- Prop<Boolean>("flat") { view: MarkerView, flat ->
480
- view.setFlat(flat)
481
- }
482
-
483
- Prop<Float>("zIndex") { view: MarkerView, zIndex ->
484
- view.setZIndex(zIndex)
485
- }
486
-
487
- Prop<Map<String, Float>>("anchor") { view: MarkerView, anchor ->
488
- view.setAnchor(anchor)
489
- }
490
- }
491
-
492
- // Circle - 圆形
493
- View(CircleView::class) {
494
- Events("onPress")
495
-
496
- Prop<Map<String, Double>>("center") { view, center ->
497
- view.setCenter(center)
498
- }
499
-
500
- Prop<Double>("radius") { view, radius ->
501
- view.setRadius(radius)
502
- }
503
-
504
- Prop<Int>("fillColor") { view, color ->
505
- view.setFillColor(color)
506
- }
507
-
508
- Prop<Int>("strokeColor") { view, color ->
509
- view.setStrokeColor(color)
510
- }
511
-
512
- Prop<Float>("strokeWidth") { view, width ->
513
- view.setStrokeWidth(width)
514
- }
515
-
516
- Prop<Float>("zIndex") { view, zIndex ->
517
- view.setZIndex(zIndex)
518
- }
519
- }
520
-
521
- // Polyline - 折线
522
- View(PolylineView::class) {
523
- Events("onPress")
524
-
525
- Prop<List<Map<String, Double>>>("points") { view: PolylineView, points ->
526
- view.setPoints(points)
527
- }
528
-
529
- Prop<Float>("strokeWidth") { view: PolylineView, width ->
530
- view.setStrokeWidth(width)
531
- }
532
-
533
- Prop<Int>("strokeColor") { view: PolylineView, color ->
534
- view.setStrokeColor(color)
535
- }
536
-
537
- Prop<String?>("texture") { view: PolylineView, texture ->
538
- view.setTexture(texture)
539
- }
540
-
541
- Prop<Boolean>("dotted") { view: PolylineView, dotted ->
542
- view.setDotted(dotted)
543
- }
544
-
545
- Prop<Boolean>("geodesic") { view: PolylineView, geodesic ->
546
- view.setGeodesic(geodesic)
547
- }
548
-
549
- Prop<Float>("zIndex") { view: PolylineView, zIndex ->
550
- view.setZIndex(zIndex)
551
- }
552
- }
553
-
554
- // Polygon - 多边形
555
- View(PolygonView::class) {
556
- Events("onPress")
557
-
558
- Prop<List<Map<String, Double>>>("points") { view: PolygonView, points ->
559
- view.setPoints(points)
560
- }
561
-
562
- Prop<Int>("fillColor") { view: PolygonView, color ->
563
- view.setFillColor(color)
564
- }
565
-
566
- Prop<Int>("strokeColor") { view: PolygonView, color ->
567
- view.setStrokeColor(color)
568
- }
569
-
570
- Prop<Float>("strokeWidth") { view: PolygonView, width ->
571
- view.setStrokeWidth(width)
572
- }
573
- }
574
-
575
- // MultiPoint - 海量点
576
- View(MultiPointView::class) {
577
- Events("onPress")
578
-
579
- Prop<List<Map<String, Any>>>("points") { view: MultiPointView, points ->
580
- view.setPoints(points)
581
- }
582
- }
583
-
584
- // HeatMap - 热力图
585
- View(HeatMapView::class) {
586
- Prop<List<Map<String, Any>>>("data") { view: HeatMapView, data ->
587
- view.setData(data)
588
- }
589
-
590
- Prop<Int>("radius") { view: HeatMapView, radius ->
591
- view.setRadius(radius)
592
- }
593
-
594
- Prop<Double>("opacity") { view: HeatMapView, opacity ->
595
- view.setOpacity(opacity)
596
- }
597
- }
598
-
599
- // Cluster - 点聚合
600
- View(ClusterView::class) {
601
- Events("onPress", "onClusterPress")
602
-
603
- Prop<List<Map<String, Any>>>("points") { view: ClusterView, points ->
604
- view.setPoints(points)
605
- }
606
-
607
- Prop<Int>("radius") { view: ClusterView, radius ->
608
- view.setRadius(radius)
609
- }
610
-
611
- Prop<Int>("minClusterSize") { view: ClusterView, size ->
612
- view.setMinClusterSize(size)
613
- }
614
- }
615
-
616
319
  OnDestroy {
617
320
  locationManager?.destroy()
618
321
  locationManager = null
@@ -46,6 +46,7 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
46
46
  private val onMapPress by EventDispatcher()
47
47
  private val onMapLongPress by EventDispatcher()
48
48
  private val onLoad by EventDispatcher()
49
+ private val onLocation by EventDispatcher()
49
50
  private val onMarkerPress by EventDispatcher()
50
51
  private val onMarkerDragStart by EventDispatcher()
51
52
  private val onMarkerDrag by EventDispatcher()
@@ -80,7 +81,17 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
80
81
 
81
82
  // 初始化管理器
82
83
  cameraManager = CameraManager(aMap)
83
- uiManager = UIManager(aMap, context)
84
+ uiManager = UIManager(aMap, context).apply {
85
+ // 设置定位变化回调
86
+ onLocationChanged = { latitude, longitude, accuracy ->
87
+ this@ExpoGaodeMapView.onLocation(mapOf(
88
+ "latitude" to latitude,
89
+ "longitude" to longitude,
90
+ "accuracy" to accuracy.toDouble(),
91
+ "timestamp" to System.currentTimeMillis()
92
+ ))
93
+ }
94
+ }
84
95
  overlayManager = OverlayManager(aMap, context).apply {
85
96
  onMarkerPress = { id, lat, lng ->
86
97
  this@ExpoGaodeMapView.onMarkerPress(mapOf(
@@ -479,12 +490,17 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
479
490
  * 添加子视图时自动连接到地图
480
491
  */
481
492
  override fun addView(child: View?, index: Int) {
493
+ if (child is MarkerView) {
494
+ // 不添加到视图层级,只调用 setMap
495
+ child.setMap(aMap)
496
+ return
497
+ }
498
+
482
499
  super.addView(child, index)
483
500
 
484
- // 自动将地图实例传递给覆盖物子视图
501
+ // 自动将地图实例传递给其他覆盖物子视图
485
502
  child?.let {
486
503
  when (it) {
487
- is MarkerView -> it.setMap(aMap)
488
504
  is PolylineView -> it.setMap(aMap)
489
505
  is PolygonView -> it.setMap(aMap)
490
506
  is CircleView -> it.setMap(aMap)