expo-gaode-map 0.1.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/.eslintrc.js +5 -0
- package/PUBLISHING.md +244 -0
- package/README.md +990 -0
- package/android/build.gradle +48 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +455 -0
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +337 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/CameraManager.kt +128 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/OverlayManager.kt +324 -0
- package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +122 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/LocationManager.kt +247 -0
- package/android/src/main/java/expo/modules/gaodemap/modules/SDKInitializer.kt +45 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/CircleView.kt +151 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +127 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/HeatMapView.kt +97 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +204 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/MultiPointView.kt +103 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolygonView.kt +114 -0
- package/android/src/main/java/expo/modules/gaodemap/overlays/PolylineView.kt +138 -0
- package/build/ExpoGaodeMap.types.d.ts +24 -0
- package/build/ExpoGaodeMap.types.d.ts.map +1 -0
- package/build/ExpoGaodeMap.types.js +14 -0
- package/build/ExpoGaodeMap.types.js.map +1 -0
- package/build/ExpoGaodeMapModule.d.ts +7 -0
- package/build/ExpoGaodeMapModule.d.ts.map +1 -0
- package/build/ExpoGaodeMapModule.js +14 -0
- package/build/ExpoGaodeMapModule.js.map +1 -0
- package/build/ExpoGaodeMapView.d.ts +31 -0
- package/build/ExpoGaodeMapView.d.ts.map +1 -0
- package/build/ExpoGaodeMapView.js +141 -0
- package/build/ExpoGaodeMapView.js.map +1 -0
- package/build/components/overlays/Circle.d.ts +18 -0
- package/build/components/overlays/Circle.d.ts.map +1 -0
- package/build/components/overlays/Circle.js +63 -0
- package/build/components/overlays/Circle.js.map +1 -0
- package/build/components/overlays/Cluster.d.ts +22 -0
- package/build/components/overlays/Cluster.d.ts.map +1 -0
- package/build/components/overlays/Cluster.js +35 -0
- package/build/components/overlays/Cluster.js.map +1 -0
- package/build/components/overlays/HeatMap.d.ts +21 -0
- package/build/components/overlays/HeatMap.d.ts.map +1 -0
- package/build/components/overlays/HeatMap.js +34 -0
- package/build/components/overlays/HeatMap.js.map +1 -0
- package/build/components/overlays/Marker.d.ts +17 -0
- package/build/components/overlays/Marker.d.ts.map +1 -0
- package/build/components/overlays/Marker.js +57 -0
- package/build/components/overlays/Marker.js.map +1 -0
- package/build/components/overlays/MultiPoint.d.ts +21 -0
- package/build/components/overlays/MultiPoint.d.ts.map +1 -0
- package/build/components/overlays/MultiPoint.js +34 -0
- package/build/components/overlays/MultiPoint.js.map +1 -0
- package/build/components/overlays/Polygon.d.ts +22 -0
- package/build/components/overlays/Polygon.d.ts.map +1 -0
- package/build/components/overlays/Polygon.js +100 -0
- package/build/components/overlays/Polygon.js.map +1 -0
- package/build/components/overlays/Polyline.d.ts +20 -0
- package/build/components/overlays/Polyline.d.ts.map +1 -0
- package/build/components/overlays/Polyline.js +60 -0
- package/build/components/overlays/Polyline.js.map +1 -0
- package/build/components/overlays/index.d.ts +8 -0
- package/build/components/overlays/index.d.ts.map +1 -0
- package/build/components/overlays/index.js +18 -0
- package/build/components/overlays/index.js.map +1 -0
- package/build/index.d.ts +10 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +28 -0
- package/build/index.js.map +1 -0
- package/build/modules/AMapLocation.d.ts +58 -0
- package/build/modules/AMapLocation.d.ts.map +1 -0
- package/build/modules/AMapLocation.js +141 -0
- package/build/modules/AMapLocation.js.map +1 -0
- package/build/modules/AMapSDK.d.ts +27 -0
- package/build/modules/AMapSDK.d.ts.map +1 -0
- package/build/modules/AMapSDK.js +43 -0
- package/build/modules/AMapSDK.js.map +1 -0
- package/build/modules/AMapView.d.ts +39 -0
- package/build/modules/AMapView.d.ts.map +1 -0
- package/build/modules/AMapView.js +61 -0
- package/build/modules/AMapView.js.map +1 -0
- package/build/types/common.types.d.ts +133 -0
- package/build/types/common.types.d.ts.map +1 -0
- package/build/types/common.types.js +31 -0
- package/build/types/common.types.js.map +1 -0
- package/build/types/index.d.ts +12 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/index.js +17 -0
- package/build/types/index.js.map +1 -0
- package/build/types/location.types.d.ts +306 -0
- package/build/types/location.types.d.ts.map +1 -0
- package/build/types/location.types.js +93 -0
- package/build/types/location.types.js.map +1 -0
- package/build/types/map-view.types.d.ts +213 -0
- package/build/types/map-view.types.d.ts.map +1 -0
- package/build/types/map-view.types.js +6 -0
- package/build/types/map-view.types.js.map +1 -0
- package/build/types/overlays.types.d.ts +296 -0
- package/build/types/overlays.types.d.ts.map +1 -0
- package/build/types/overlays.types.js +6 -0
- package/build/types/overlays.types.js.map +1 -0
- package/build/types/sdk.types.d.ts +113 -0
- package/build/types/sdk.types.d.ts.map +1 -0
- package/build/types/sdk.types.js +6 -0
- package/build/types/sdk.types.js.map +1 -0
- package/docs/followUserLocation.md +186 -0
- package/expo-module.config.json +9 -0
- package/ios/ExpoGaodeMap.podspec +29 -0
- package/ios/ExpoGaodeMapModule.swift +48 -0
- package/ios/ExpoGaodeMapView.swift +38 -0
- package/package.json +45 -0
- package/src/ExpoGaodeMap.types.ts +68 -0
- package/src/ExpoGaodeMapModule.ts +21 -0
- package/src/ExpoGaodeMapView.tsx +151 -0
- package/src/components/overlays/Circle.tsx +73 -0
- package/src/components/overlays/Cluster.tsx +38 -0
- package/src/components/overlays/HeatMap.tsx +37 -0
- package/src/components/overlays/Marker.tsx +66 -0
- package/src/components/overlays/MultiPoint.tsx +37 -0
- package/src/components/overlays/Polygon.tsx +107 -0
- package/src/components/overlays/Polyline.tsx +69 -0
- package/src/components/overlays/index.ts +18 -0
- package/src/index.ts +55 -0
- package/src/modules/AMapLocation.ts +164 -0
- package/src/modules/AMapSDK.ts +48 -0
- package/src/modules/AMapView.ts +68 -0
- package/src/types/README.md +186 -0
- package/src/types/common.types.ts +155 -0
- package/src/types/index.ts +74 -0
- package/src/types/location.types.ts +364 -0
- package/src/types/map-view.types.ts +249 -0
- package/src/types/overlays.types.ts +346 -0
- package/src/types/sdk.types.ts +128 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
|
|
3
|
+
public class ExpoGaodeMapModule: Module {
|
|
4
|
+
// Each module class must implement the definition function. The definition consists of components
|
|
5
|
+
// that describes the module's functionality and behavior.
|
|
6
|
+
// See https://docs.expo.dev/modules/module-api for more details about available components.
|
|
7
|
+
public func definition() -> ModuleDefinition {
|
|
8
|
+
// Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument.
|
|
9
|
+
// Can be inferred from module's class name, but it's recommended to set it explicitly for clarity.
|
|
10
|
+
// The module will be accessible from `requireNativeModule('ExpoGaodeMap')` in JavaScript.
|
|
11
|
+
Name("ExpoGaodeMap")
|
|
12
|
+
|
|
13
|
+
// Defines constant property on the module.
|
|
14
|
+
Constant("PI") {
|
|
15
|
+
Double.pi
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Defines event names that the module can send to JavaScript.
|
|
19
|
+
Events("onChange")
|
|
20
|
+
|
|
21
|
+
// Defines a JavaScript synchronous function that runs the native code on the JavaScript thread.
|
|
22
|
+
Function("hello") {
|
|
23
|
+
return "Hello world! 👋"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Defines a JavaScript function that always returns a Promise and whose native code
|
|
27
|
+
// is by default dispatched on the different thread than the JavaScript runtime runs on.
|
|
28
|
+
AsyncFunction("setValueAsync") { (value: String) in
|
|
29
|
+
// Send an event to JavaScript.
|
|
30
|
+
self.sendEvent("onChange", [
|
|
31
|
+
"value": value
|
|
32
|
+
])
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Enables the module to be used as a native view. Definition components that are accepted as part of the
|
|
36
|
+
// view definition: Prop, Events.
|
|
37
|
+
View(ExpoGaodeMapView.self) {
|
|
38
|
+
// Defines a setter for the `url` prop.
|
|
39
|
+
Prop("url") { (view: ExpoGaodeMapView, url: URL) in
|
|
40
|
+
if view.webView.url != url {
|
|
41
|
+
view.webView.load(URLRequest(url: url))
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
Events("onLoad")
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import ExpoModulesCore
|
|
2
|
+
import WebKit
|
|
3
|
+
|
|
4
|
+
// This view will be used as a native component. Make sure to inherit from `ExpoView`
|
|
5
|
+
// to apply the proper styling (e.g. border radius and shadows).
|
|
6
|
+
class ExpoGaodeMapView: ExpoView {
|
|
7
|
+
let webView = WKWebView()
|
|
8
|
+
let onLoad = EventDispatcher()
|
|
9
|
+
var delegate: WebViewDelegate?
|
|
10
|
+
|
|
11
|
+
required init(appContext: AppContext? = nil) {
|
|
12
|
+
super.init(appContext: appContext)
|
|
13
|
+
clipsToBounds = true
|
|
14
|
+
delegate = WebViewDelegate { url in
|
|
15
|
+
self.onLoad(["url": url])
|
|
16
|
+
}
|
|
17
|
+
webView.navigationDelegate = delegate
|
|
18
|
+
addSubview(webView)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
override func layoutSubviews() {
|
|
22
|
+
webView.frame = bounds
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
class WebViewDelegate: NSObject, WKNavigationDelegate {
|
|
27
|
+
let onUrlChange: (String) -> Void
|
|
28
|
+
|
|
29
|
+
init(onUrlChange: @escaping (String) -> Void) {
|
|
30
|
+
self.onUrlChange = onUrlChange
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation) {
|
|
34
|
+
if let url = webView.url {
|
|
35
|
+
onUrlChange(url.absoluteString)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "expo-gaode-map",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "高德地图 react-native 安卓和 ios",
|
|
5
|
+
"main": "build/index.js",
|
|
6
|
+
"types": "build/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "expo-module build",
|
|
9
|
+
"clean": "expo-module clean",
|
|
10
|
+
"lint": "expo-module lint",
|
|
11
|
+
"test": "expo-module test",
|
|
12
|
+
"prepare": "expo-module prepare",
|
|
13
|
+
"prepublishOnly": "expo-module prepublishOnly",
|
|
14
|
+
"expo-module": "expo-module",
|
|
15
|
+
"open:ios": "xed example/ios",
|
|
16
|
+
"open:android": "open -a \"Android Studio\" example/android"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react-native",
|
|
20
|
+
"expo",
|
|
21
|
+
"expo-gaode-map",
|
|
22
|
+
"ExpoGaodeMap"
|
|
23
|
+
],
|
|
24
|
+
"repository": "https://github.com/TomWq/expo-gaode-map",
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/TomWq/expo-gaode-map/issues"
|
|
27
|
+
},
|
|
28
|
+
"author": "尚博信_王强 <wangqiang03@sunboxsoft.com> (https://github.com/TomWq)",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"homepage": "https://github.com/TomWq/expo-gaode-map#readme",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"supercluster": "^8.0.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/react": "~19.1.0",
|
|
36
|
+
"expo": "^54.0.18",
|
|
37
|
+
"expo-module-scripts": "^5.0.7",
|
|
38
|
+
"react-native": "0.81.5"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"expo": "*",
|
|
42
|
+
"react": "*",
|
|
43
|
+
"react-native": "*"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-11-13 14:03:56
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-11-13 14:30:00
|
|
6
|
+
* @FilePath : /expo-gaode-map/src/ExpoGaodeMap.types.ts
|
|
7
|
+
* @Description : 高德地图 Expo Module 主类型定义文件
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// 导出所有类型定义
|
|
13
|
+
export * from './types';
|
|
14
|
+
|
|
15
|
+
// 重新导出常用类型,方便直接从主模块导入
|
|
16
|
+
export type {
|
|
17
|
+
// 通用类型
|
|
18
|
+
LatLng,
|
|
19
|
+
Point,
|
|
20
|
+
CameraPosition,
|
|
21
|
+
LatLngBounds,
|
|
22
|
+
MapPoi,
|
|
23
|
+
|
|
24
|
+
// 地图视图
|
|
25
|
+
MapViewProps,
|
|
26
|
+
CameraEvent,
|
|
27
|
+
|
|
28
|
+
// 定位
|
|
29
|
+
Coordinates,
|
|
30
|
+
ReGeocode,
|
|
31
|
+
LocationOptions,
|
|
32
|
+
|
|
33
|
+
// 覆盖物
|
|
34
|
+
MarkerProps,
|
|
35
|
+
PolylineProps,
|
|
36
|
+
PolygonProps,
|
|
37
|
+
CircleProps,
|
|
38
|
+
HeatMapProps,
|
|
39
|
+
MultiPointProps,
|
|
40
|
+
ClusterProps,
|
|
41
|
+
} from './types';
|
|
42
|
+
|
|
43
|
+
export {
|
|
44
|
+
MapType,
|
|
45
|
+
LocationMode,
|
|
46
|
+
LocationAccuracy,
|
|
47
|
+
CoordinateType,
|
|
48
|
+
} from './types';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Expo 模块事件类型
|
|
52
|
+
*/
|
|
53
|
+
export type ExpoGaodeMapModuleEvents = {
|
|
54
|
+
/**
|
|
55
|
+
* 定位更新事件
|
|
56
|
+
*/
|
|
57
|
+
onLocationUpdate: (location: any) => void;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 定位错误事件
|
|
61
|
+
*/
|
|
62
|
+
onLocationError: (error: { code: number; message: string }) => void;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Expo 地图视图属性(用于主视图组件)
|
|
67
|
+
*/
|
|
68
|
+
export type { MapViewProps as ExpoGaodeMapViewProps } from './types';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-11-13 14:03:56
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-11-13 14:58:00
|
|
6
|
+
* @FilePath : /expo-gaode-map/src/ExpoGaodeMapModule.ts
|
|
7
|
+
* @Description :
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
import { NativeModule, requireNativeModule } from 'expo';
|
|
12
|
+
import type { ExpoGaodeMapModuleEvents } from './ExpoGaodeMap.types';
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
declare class ExpoGaodeMapModule extends NativeModule<ExpoGaodeMapModuleEvents> {
|
|
16
|
+
// 地图控制方法已移至 MapView 的 ref 调用
|
|
17
|
+
// 使用方式: mapRef.current.moveCamera() 等
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// This call loads the native module object from the JSI.
|
|
21
|
+
export default requireNativeModule<ExpoGaodeMapModule>('ExpoGaodeMap');
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-11-13 14:03:56
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-11-13 19:35:20
|
|
6
|
+
* @FilePath : /expo-gaode-map/src/ExpoGaodeMapView.tsx
|
|
7
|
+
* @Description : 高德地图视图组件
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
|
|
15
|
+
import type {
|
|
16
|
+
MapViewProps,
|
|
17
|
+
MapViewRef,
|
|
18
|
+
NativeMapViewRef,
|
|
19
|
+
CameraPosition,
|
|
20
|
+
LatLng,
|
|
21
|
+
Point,
|
|
22
|
+
CircleProps,
|
|
23
|
+
MarkerProps,
|
|
24
|
+
PolylineProps,
|
|
25
|
+
PolygonProps,
|
|
26
|
+
} from './types';
|
|
27
|
+
|
|
28
|
+
// 重新导出 MapViewRef 供外部使用
|
|
29
|
+
export type { MapViewRef } from './types';
|
|
30
|
+
|
|
31
|
+
const NativeView: React.ComponentType<MapViewProps & { ref?: React.Ref<NativeMapViewRef> }> = requireNativeViewManager('ExpoGaodeMap');
|
|
32
|
+
|
|
33
|
+
// 创建 Context 用于子组件访问 MapRef
|
|
34
|
+
export const MapContext = React.createContext<React.RefObject<MapViewRef | null> | null>(null);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 高德地图视图组件
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* import { MapView } from 'expo-gaode-map';
|
|
42
|
+
*
|
|
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
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
const ExpoGaodeMapView = React.forwardRef<MapViewRef, MapViewProps>((props, ref) => {
|
|
61
|
+
const nativeRef = React.useRef<NativeMapViewRef>(null);
|
|
62
|
+
const internalRef = React.useRef<MapViewRef | null>(null);
|
|
63
|
+
|
|
64
|
+
const apiRef: MapViewRef = React.useMemo(() => ({
|
|
65
|
+
moveCamera: async (position: CameraPosition, duration: number = 0) => {
|
|
66
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
67
|
+
return nativeRef.current.moveCamera(position, duration);
|
|
68
|
+
},
|
|
69
|
+
getLatLng: async (point: Point) => {
|
|
70
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
71
|
+
return nativeRef.current.getLatLng(point);
|
|
72
|
+
},
|
|
73
|
+
setCenter: async (center: LatLng, animated: boolean = false) => {
|
|
74
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
75
|
+
return nativeRef.current.setCenter(center, animated);
|
|
76
|
+
},
|
|
77
|
+
setZoom: async (zoom: number, animated: boolean = false) => {
|
|
78
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
79
|
+
return nativeRef.current.setZoom(zoom, animated);
|
|
80
|
+
},
|
|
81
|
+
getCameraPosition: async () => {
|
|
82
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
83
|
+
return nativeRef.current.getCameraPosition();
|
|
84
|
+
},
|
|
85
|
+
addCircle: async (id: string, props: CircleProps) => {
|
|
86
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
87
|
+
return nativeRef.current.addCircle(id, props);
|
|
88
|
+
},
|
|
89
|
+
removeCircle: async (id: string) => {
|
|
90
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
91
|
+
return nativeRef.current.removeCircle(id);
|
|
92
|
+
},
|
|
93
|
+
updateCircle: async (id: string, props: Partial<CircleProps>) => {
|
|
94
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
95
|
+
return nativeRef.current.updateCircle(id, props);
|
|
96
|
+
},
|
|
97
|
+
addMarker: async (id: string, props: MarkerProps) => {
|
|
98
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
99
|
+
return nativeRef.current.addMarker(id, props);
|
|
100
|
+
},
|
|
101
|
+
removeMarker: async (id: string) => {
|
|
102
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
103
|
+
return nativeRef.current.removeMarker(id);
|
|
104
|
+
},
|
|
105
|
+
updateMarker: async (id: string, props: Partial<MarkerProps>) => {
|
|
106
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
107
|
+
return nativeRef.current.updateMarker(id, props);
|
|
108
|
+
},
|
|
109
|
+
addPolyline: async (id: string, props: PolylineProps) => {
|
|
110
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
111
|
+
return nativeRef.current.addPolyline(id, props);
|
|
112
|
+
},
|
|
113
|
+
removePolyline: async (id: string) => {
|
|
114
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
115
|
+
return nativeRef.current.removePolyline(id);
|
|
116
|
+
},
|
|
117
|
+
updatePolyline: async (id: string, props: Partial<PolylineProps>) => {
|
|
118
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
119
|
+
return nativeRef.current.updatePolyline(id, props);
|
|
120
|
+
},
|
|
121
|
+
addPolygon: async (id: string, props: PolygonProps) => {
|
|
122
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
123
|
+
return nativeRef.current.addPolygon(id, props);
|
|
124
|
+
},
|
|
125
|
+
removePolygon: async (id: string) => {
|
|
126
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
127
|
+
return nativeRef.current.removePolygon(id);
|
|
128
|
+
},
|
|
129
|
+
updatePolygon: async (id: string, props: Partial<PolygonProps>) => {
|
|
130
|
+
if (!nativeRef.current) throw new Error('MapView not initialized');
|
|
131
|
+
return nativeRef.current.updatePolygon(id, props);
|
|
132
|
+
},
|
|
133
|
+
}), []);
|
|
134
|
+
|
|
135
|
+
// 设置 internalRef 和外部 ref
|
|
136
|
+
React.useEffect(() => {
|
|
137
|
+
internalRef.current = apiRef;
|
|
138
|
+
}, [apiRef]);
|
|
139
|
+
|
|
140
|
+
React.useImperativeHandle(ref, () => apiRef, [apiRef]);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<MapContext.Provider value={internalRef}>
|
|
144
|
+
<NativeView ref={nativeRef} {...props} />
|
|
145
|
+
</MapContext.Provider>
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
ExpoGaodeMapView.displayName = 'ExpoGaodeMapView';
|
|
150
|
+
|
|
151
|
+
export default ExpoGaodeMapView;
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
import * as React from 'react';
|
|
13
|
+
import type { CircleProps } from '../../types';
|
|
14
|
+
import { MapContext } from '../../ExpoGaodeMapView';
|
|
15
|
+
|
|
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
|
+
export default function Circle(props: CircleProps) {
|
|
32
|
+
const mapRef = React.useContext(MapContext);
|
|
33
|
+
const circleIdRef = React.useRef<string | null>(null);
|
|
34
|
+
|
|
35
|
+
console.log('Circle 组件渲染,props:', JSON.stringify(props));
|
|
36
|
+
|
|
37
|
+
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;
|
|
48
|
+
|
|
49
|
+
mapRef.current.addCircle(circleId, props);
|
|
50
|
+
console.log('✅ 圆形已添加:', circleId);
|
|
51
|
+
|
|
52
|
+
// 清理函数 - 移除圆形
|
|
53
|
+
return () => {
|
|
54
|
+
console.log('Circle useEffect cleanup - 移除圆形');
|
|
55
|
+
if (circleIdRef.current && mapRef?.current) {
|
|
56
|
+
mapRef.current.removeCircle(circleIdRef.current);
|
|
57
|
+
console.log('✅ 圆形已移除:', circleIdRef.current);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
62
|
+
// 当 props 变化时更新圆形
|
|
63
|
+
React.useEffect(() => {
|
|
64
|
+
console.log('Circle props 变化,更新圆形');
|
|
65
|
+
if (circleIdRef.current && mapRef?.current) {
|
|
66
|
+
mapRef.current.updateCircle(circleIdRef.current, props);
|
|
67
|
+
console.log('✅ 圆形已更新:', circleIdRef.current);
|
|
68
|
+
}
|
|
69
|
+
}, [props.center, props.radius, props.fillColor, props.strokeColor, props.strokeWidth]);
|
|
70
|
+
|
|
71
|
+
// 不渲染任何 UI
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import type { ClusterProps } from '../../types';
|
|
15
|
+
|
|
16
|
+
const NativeCluster = requireNativeViewManager('ExpoGaodeMap_ClusterView');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 地图点聚合组件
|
|
20
|
+
* 将相近的标记点聚合显示,提高大量标记的展示性能
|
|
21
|
+
*
|
|
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
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export default function Cluster(props: ClusterProps) {
|
|
37
|
+
return <NativeCluster {...props} />;
|
|
38
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
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
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import type { HeatMapProps } from '../../types';
|
|
15
|
+
|
|
16
|
+
const NativeHeatMap = requireNativeViewManager('ExpoGaodeMap_HeatMapView');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 地图热力图组件
|
|
20
|
+
*
|
|
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
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export default function HeatMap(props: HeatMapProps) {
|
|
36
|
+
return <NativeHeatMap {...props} />;
|
|
37
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-11-13 15:01:10
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-11-13 18:55:00
|
|
6
|
+
* @FilePath : /expo-gaode-map/src/components/overlays/Marker.tsx
|
|
7
|
+
* @Description : 地图标记组件 - 使用命令式 API
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import * as React from 'react';
|
|
13
|
+
import { MapContext } from '../../ExpoGaodeMapView';
|
|
14
|
+
import type { MarkerProps } from '../../types';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 地图标记组件
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <MapView>
|
|
22
|
+
* <Marker
|
|
23
|
+
* position={{ latitude: 39.9, longitude: 116.4 }}
|
|
24
|
+
* title="标记点"
|
|
25
|
+
* onPress={() => console.log('Marker pressed')}
|
|
26
|
+
* />
|
|
27
|
+
* </MapView>
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export default function Marker(props: MarkerProps) {
|
|
31
|
+
const mapRef = React.useContext(MapContext);
|
|
32
|
+
const markerIdRef = React.useRef<string>(`marker_${Date.now()}_${Math.random()}`);
|
|
33
|
+
|
|
34
|
+
console.log('Marker 组件渲染,props:', props);
|
|
35
|
+
|
|
36
|
+
// 添加标记
|
|
37
|
+
React.useEffect(() => {
|
|
38
|
+
const markerId = markerIdRef.current;
|
|
39
|
+
|
|
40
|
+
console.log('Marker useEffect - 添加标记到地图');
|
|
41
|
+
mapRef?.current?.addMarker?.(markerId, props).then(() => {
|
|
42
|
+
console.log('✅ 标记已添加:', markerId);
|
|
43
|
+
}).catch((error: any) => {
|
|
44
|
+
console.error('❌ 添加标记失败:', error);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
return () => {
|
|
48
|
+
console.log('Marker useEffect cleanup - 移除标记');
|
|
49
|
+
mapRef?.current?.removeMarker?.(markerId).catch((error: any) => {
|
|
50
|
+
console.error('❌ 移除标记失败:', error);
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
}, []);
|
|
54
|
+
|
|
55
|
+
// 监听 Props 变化,更新标记
|
|
56
|
+
React.useEffect(() => {
|
|
57
|
+
const markerId = markerIdRef.current;
|
|
58
|
+
|
|
59
|
+
console.log('Marker props 变化,更新标记:', props);
|
|
60
|
+
mapRef?.current?.updateMarker?.(markerId, props).catch((error: any) => {
|
|
61
|
+
console.error('❌ 更新标记失败:', error);
|
|
62
|
+
});
|
|
63
|
+
}, [props.position, props.title, props.draggable]);
|
|
64
|
+
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* @Author : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
3
|
+
* @Date : 2025-11-13 15:02:35
|
|
4
|
+
* @LastEditors : 尚博信_王强 wangqiang03@sunboxsoft.com
|
|
5
|
+
* @LastEditTime : 2025-11-13 18:19:09
|
|
6
|
+
* @FilePath : /expo-gaode-map/src/components/overlays/MultiPoint.tsx
|
|
7
|
+
* @Description : 地图海量点组件
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2025 by 尚博信_王强, All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
13
|
+
import * as React from 'react';
|
|
14
|
+
import type { MultiPointProps } from '../../types';
|
|
15
|
+
|
|
16
|
+
const NativeMultiPoint = requireNativeViewManager('ExpoGaodeMap_MultiPointView');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 地图海量点组件
|
|
20
|
+
* 用于展示大量标记点,性能优于普通 Marker
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <MapView>
|
|
25
|
+
* <MultiPoint
|
|
26
|
+
* points={[
|
|
27
|
+
* { latitude: 39.9, longitude: 116.4, id: '1' },
|
|
28
|
+
* { latitude: 39.91, longitude: 116.41, id: '2' },
|
|
29
|
+
* ]}
|
|
30
|
+
* icon={require('./marker.png')}
|
|
31
|
+
* />
|
|
32
|
+
* </MapView>
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export default function MultiPoint(props: MultiPointProps) {
|
|
36
|
+
return <NativeMultiPoint {...props} />;
|
|
37
|
+
}
|