expo-gaode-map 2.2.30-next.0 → 2.2.30

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 (82) hide show
  1. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +4 -2
  2. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +117 -57
  3. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapViewModule.kt +8 -15
  4. package/android/src/main/java/expo/modules/gaodemap/managers/UIManager.kt +20 -6
  5. package/android/src/main/java/expo/modules/gaodemap/overlays/ClusterView.kt +24 -13
  6. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerBitmapRenderer.kt +351 -0
  7. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +94 -310
  8. package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerViewModule.kt +3 -3
  9. package/build/ExpoGaodeMapModule.d.ts +13 -5
  10. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  11. package/build/ExpoGaodeMapModule.js +166 -34
  12. package/build/ExpoGaodeMapModule.js.map +1 -1
  13. package/build/ExpoGaodeMapView.d.ts.map +1 -1
  14. package/build/ExpoGaodeMapView.js +12 -0
  15. package/build/ExpoGaodeMapView.js.map +1 -1
  16. package/build/components/AreaMaskOverlay.d.ts +5 -0
  17. package/build/components/AreaMaskOverlay.d.ts.map +1 -0
  18. package/build/components/AreaMaskOverlay.js +20 -0
  19. package/build/components/AreaMaskOverlay.js.map +1 -0
  20. package/build/components/FoldableMapView.d.ts.map +1 -1
  21. package/build/components/FoldableMapView.js +115 -104
  22. package/build/components/FoldableMapView.js.map +1 -1
  23. package/build/components/RouteOverlay.d.ts +5 -0
  24. package/build/components/RouteOverlay.d.ts.map +1 -0
  25. package/build/components/RouteOverlay.js +20 -0
  26. package/build/components/RouteOverlay.js.map +1 -0
  27. package/build/components/overlays/Cluster.d.ts.map +1 -1
  28. package/build/components/overlays/Cluster.js +12 -0
  29. package/build/components/overlays/Cluster.js.map +1 -1
  30. package/build/components/overlays/Marker.d.ts.map +1 -1
  31. package/build/components/overlays/Marker.js +86 -3
  32. package/build/components/overlays/Marker.js.map +1 -1
  33. package/build/hooks/useRoutePlayback.d.ts +4 -0
  34. package/build/hooks/useRoutePlayback.d.ts.map +1 -0
  35. package/build/hooks/useRoutePlayback.js +310 -0
  36. package/build/hooks/useRoutePlayback.js.map +1 -0
  37. package/build/index.d.ts +4 -1
  38. package/build/index.d.ts.map +1 -1
  39. package/build/index.js +4 -2
  40. package/build/index.js.map +1 -1
  41. package/build/types/common.types.d.ts +29 -5
  42. package/build/types/common.types.d.ts.map +1 -1
  43. package/build/types/common.types.js +5 -5
  44. package/build/types/common.types.js.map +1 -1
  45. package/build/types/index.d.ts +3 -2
  46. package/build/types/index.d.ts.map +1 -1
  47. package/build/types/index.js.map +1 -1
  48. package/build/types/location.types.d.ts +28 -0
  49. package/build/types/location.types.d.ts.map +1 -1
  50. package/build/types/location.types.js +5 -0
  51. package/build/types/location.types.js.map +1 -1
  52. package/build/types/map-view.types.d.ts +22 -22
  53. package/build/types/map-view.types.d.ts.map +1 -1
  54. package/build/types/map-view.types.js.map +1 -1
  55. package/build/types/native-module.types.d.ts +2 -2
  56. package/build/types/native-module.types.d.ts.map +1 -1
  57. package/build/types/native-module.types.js.map +1 -1
  58. package/build/types/overlays.types.d.ts +14 -0
  59. package/build/types/overlays.types.d.ts.map +1 -1
  60. package/build/types/overlays.types.js.map +1 -1
  61. package/build/types/route-playback.types.d.ts +118 -0
  62. package/build/types/route-playback.types.d.ts.map +1 -0
  63. package/build/types/route-playback.types.js +2 -0
  64. package/build/types/route-playback.types.js.map +1 -0
  65. package/build/utils/RouteUtils.d.ts +8 -0
  66. package/build/utils/RouteUtils.d.ts.map +1 -0
  67. package/build/utils/RouteUtils.js +140 -0
  68. package/build/utils/RouteUtils.js.map +1 -0
  69. package/ios/ExpoGaodeMapModule.swift +41 -22
  70. package/ios/ExpoGaodeMapView.swift +236 -241
  71. package/ios/ExpoGaodeMapViewModule.swift +16 -11
  72. package/ios/managers/UIManager.swift +5 -4
  73. package/ios/modules/LocationManager.swift +32 -9
  74. package/ios/overlays/ClusterView.swift +114 -12
  75. package/ios/overlays/ClusterViewModule.swift +5 -1
  76. package/ios/overlays/MarkerView.swift +195 -18
  77. package/ios/overlays/MarkerViewModule.swift +7 -7
  78. package/package.json +6 -6
  79. package/build/utils/throttle.d.ts +0 -10
  80. package/build/utils/throttle.d.ts.map +0 -1
  81. package/build/utils/throttle.js +0 -19
  82. package/build/utils/throttle.js.map +0 -1
@@ -0,0 +1,118 @@
1
+ import type { NativeSyntheticEvent } from 'react-native';
2
+ import type { LatLng, LatLngBounds, LatLngPoint, Point } from './common.types';
3
+ import type { MarkerProps, PolygonProps, PolylineProps } from './overlays.types';
4
+ export interface RouteBounds {
5
+ center: LatLng;
6
+ bounds: {
7
+ north: number;
8
+ south: number;
9
+ east: number;
10
+ west: number;
11
+ };
12
+ span: {
13
+ latitudeDelta: number;
14
+ longitudeDelta: number;
15
+ };
16
+ recommendedZoom: number;
17
+ }
18
+ export interface FitToCoordinatesOptions {
19
+ duration?: number;
20
+ paddingFactor?: number;
21
+ minZoom?: number;
22
+ maxZoom?: number;
23
+ singlePointZoom?: number;
24
+ bearing?: number;
25
+ tilt?: number;
26
+ preserveBearing?: boolean;
27
+ preserveTilt?: boolean;
28
+ }
29
+ export interface SmoothMoveProgressEvent {
30
+ position: LatLng;
31
+ angle: number;
32
+ progress: number;
33
+ distance: number;
34
+ totalDistance: number;
35
+ }
36
+ export interface SmoothMoveEndEvent {
37
+ position: LatLng;
38
+ angle: number;
39
+ totalDistance: number;
40
+ }
41
+ export interface RoutePlaybackOptions {
42
+ durationSeconds?: number;
43
+ minDurationSeconds?: number;
44
+ speedMultiplier?: number;
45
+ baseSpeedMps?: number;
46
+ updateIntervalMs?: number;
47
+ followCamera?: boolean;
48
+ followZoom?: number;
49
+ bearingSmoothing?: number;
50
+ lookAheadDistanceMeters?: number;
51
+ simplificationTolerance?: number;
52
+ autoFit?: boolean;
53
+ fitOptions?: FitToCoordinatesOptions;
54
+ onProgress?: (state: RoutePlaybackState) => void;
55
+ onComplete?: (state: RoutePlaybackState) => void;
56
+ }
57
+ export interface RoutePlaybackState {
58
+ isPlaying: boolean;
59
+ isPaused: boolean;
60
+ progress: number;
61
+ currentPosition: LatLng | null;
62
+ currentAngle: number;
63
+ totalDistance: number;
64
+ traveledDistance: number;
65
+ durationSeconds: number;
66
+ smoothMovePath?: LatLng[];
67
+ smoothMoveDuration?: number;
68
+ }
69
+ export interface RoutePlaybackController extends RoutePlaybackState {
70
+ start(): void;
71
+ pause(): void;
72
+ resume(): void;
73
+ stop(): void;
74
+ seek(progress: number): void;
75
+ setSpeedMultiplier(multiplier: number): void;
76
+ }
77
+ export interface RouteOverlayProps {
78
+ points: LatLngPoint[];
79
+ showStartMarker?: boolean;
80
+ showEndMarker?: boolean;
81
+ polylineProps?: Omit<PolylineProps, 'points'>;
82
+ startMarkerProps?: Omit<MarkerProps, 'position'>;
83
+ endMarkerProps?: Omit<MarkerProps, 'position'>;
84
+ }
85
+ export interface AreaMaskOverlayProps {
86
+ rings: LatLngPoint[][] | string;
87
+ polygonProps?: Omit<PolygonProps, 'points'>;
88
+ }
89
+ export interface MultiRingPolyline {
90
+ rings: LatLng[][];
91
+ bounds: LatLngBounds | null;
92
+ }
93
+ export type SmoothMoveProgressEventHandler = (event: NativeSyntheticEvent<SmoothMoveProgressEvent>) => void;
94
+ export type SmoothMoveEndEventHandler = (event: NativeSyntheticEvent<SmoothMoveEndEvent>) => void;
95
+ export interface FitToCoordinatesTarget {
96
+ moveCamera(position: {
97
+ target?: LatLng;
98
+ zoom?: number;
99
+ bearing?: number;
100
+ tilt?: number;
101
+ }, duration?: number): Promise<void>;
102
+ getCameraPosition(): Promise<{
103
+ target?: LatLng;
104
+ zoom?: number;
105
+ bearing?: number;
106
+ tilt?: number;
107
+ }>;
108
+ }
109
+ export interface EdgePadding {
110
+ top?: number;
111
+ right?: number;
112
+ bottom?: number;
113
+ left?: number;
114
+ }
115
+ export interface CoordinateScreenProjector {
116
+ getLatLng(point: Point): Promise<LatLng>;
117
+ }
118
+ //# sourceMappingURL=route-playback.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-playback.types.d.ts","sourceRoot":"","sources":["../../src/types/route-playback.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=route-playback.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-playback.types.js","sourceRoot":"","sources":["../../src/types/route-playback.types.ts"],"names":[],"mappings":"","sourcesContent":["import type { NativeSyntheticEvent } from 'react-native';\n\nimport type { LatLng, LatLngBounds, LatLngPoint, Point } from './common.types';\nimport type { MarkerProps, PolygonProps, PolylineProps } from './overlays.types';\n\nexport interface RouteBounds {\n center: LatLng;\n bounds: {\n north: number;\n south: number;\n east: number;\n west: number;\n };\n span: {\n latitudeDelta: number;\n longitudeDelta: number;\n };\n recommendedZoom: number;\n}\n\nexport interface FitToCoordinatesOptions {\n duration?: number;\n paddingFactor?: number;\n minZoom?: number;\n maxZoom?: number;\n singlePointZoom?: number;\n bearing?: number;\n tilt?: number;\n preserveBearing?: boolean;\n preserveTilt?: boolean;\n}\n\nexport interface SmoothMoveProgressEvent {\n position: LatLng;\n angle: number;\n progress: number;\n distance: number;\n totalDistance: number;\n}\n\nexport interface SmoothMoveEndEvent {\n position: LatLng;\n angle: number;\n totalDistance: number;\n}\n\nexport interface RoutePlaybackOptions {\n durationSeconds?: number;\n minDurationSeconds?: number;\n speedMultiplier?: number;\n baseSpeedMps?: number;\n updateIntervalMs?: number;\n followCamera?: boolean;\n followZoom?: number;\n bearingSmoothing?: number;\n lookAheadDistanceMeters?: number;\n simplificationTolerance?: number;\n autoFit?: boolean;\n fitOptions?: FitToCoordinatesOptions;\n onProgress?: (state: RoutePlaybackState) => void;\n onComplete?: (state: RoutePlaybackState) => void;\n}\n\nexport interface RoutePlaybackState {\n isPlaying: boolean;\n isPaused: boolean;\n progress: number;\n currentPosition: LatLng | null;\n currentAngle: number;\n totalDistance: number;\n traveledDistance: number;\n durationSeconds: number;\n smoothMovePath?: LatLng[];\n smoothMoveDuration?: number;\n}\n\nexport interface RoutePlaybackController extends RoutePlaybackState {\n start(): void;\n pause(): void;\n resume(): void;\n stop(): void;\n seek(progress: number): void;\n setSpeedMultiplier(multiplier: number): void;\n}\n\nexport interface RouteOverlayProps {\n points: LatLngPoint[];\n showStartMarker?: boolean;\n showEndMarker?: boolean;\n polylineProps?: Omit<PolylineProps, 'points'>;\n startMarkerProps?: Omit<MarkerProps, 'position'>;\n endMarkerProps?: Omit<MarkerProps, 'position'>;\n}\n\nexport interface AreaMaskOverlayProps {\n rings: LatLngPoint[][] | string;\n polygonProps?: Omit<PolygonProps, 'points'>;\n}\n\nexport interface MultiRingPolyline {\n rings: LatLng[][];\n bounds: LatLngBounds | null;\n}\n\nexport type SmoothMoveProgressEventHandler = (\n event: NativeSyntheticEvent<SmoothMoveProgressEvent>\n) => void;\n\nexport type SmoothMoveEndEventHandler = (\n event: NativeSyntheticEvent<SmoothMoveEndEvent>\n) => void;\n\nexport interface FitToCoordinatesTarget {\n moveCamera(\n position: {\n target?: LatLng;\n zoom?: number;\n bearing?: number;\n tilt?: number;\n },\n duration?: number\n ): Promise<void>;\n getCameraPosition(): Promise<{\n target?: LatLng;\n zoom?: number;\n bearing?: number;\n tilt?: number;\n }>;\n}\n\nexport interface EdgePadding {\n top?: number;\n right?: number;\n bottom?: number;\n left?: number;\n}\n\nexport interface CoordinateScreenProjector {\n getLatLng(point: Point): Promise<LatLng>;\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import type { LatLngBounds, LatLngPoint } from '../types/common.types';
2
+ import type { FitToCoordinatesOptions, FitToCoordinatesTarget, MultiRingPolyline, RouteBounds } from '../types/route-playback.types';
3
+ export declare function estimateZoomLevel(latitudeDelta: number, longitudeDelta: number, options?: Pick<FitToCoordinatesOptions, 'minZoom' | 'maxZoom'>): number;
4
+ export declare function getRouteBounds(points: LatLngPoint[], options?: Pick<FitToCoordinatesOptions, 'paddingFactor' | 'minZoom' | 'maxZoom'>): RouteBounds | null;
5
+ export declare function parseMultiRingPolyline(polyline: string): MultiRingPolyline;
6
+ export declare function fitCameraToCoordinates(map: FitToCoordinatesTarget, points: LatLngPoint[], options?: FitToCoordinatesOptions): Promise<void>;
7
+ export declare function buildLatLngBounds(points: LatLngPoint[]): LatLngBounds | null;
8
+ //# sourceMappingURL=RouteUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteUtils.d.ts","sourceRoot":"","sources":["../../src/utils/RouteUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAU,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,KAAK,EACV,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACZ,MAAM,+BAA+B,CAAC;AAQvC,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,OAAO,GAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,GAAG,SAAS,CAAM,GACjE,MAAM,CAQR;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE,IAAI,CAAC,uBAAuB,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,CAAM,GACnF,WAAW,GAAG,IAAI,CAmCpB;AAyBD,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB,CA0B1E;AAED,wBAAsB,sBAAsB,CAC1C,GAAG,EAAE,sBAAsB,EAC3B,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,IAAI,CAAC,CAyCf;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,YAAY,GAAG,IAAI,CAgB5E"}
@@ -0,0 +1,140 @@
1
+ import { normalizeLatLng, normalizeLatLngList } from './GeoUtils';
2
+ const MIN_ZOOM = 3;
3
+ const MAX_ZOOM = 20;
4
+ const DEFAULT_SINGLE_POINT_ZOOM = 16;
5
+ const DEFAULT_PADDING_FACTOR = 1.2;
6
+ export function estimateZoomLevel(latitudeDelta, longitudeDelta, options = {}) {
7
+ // 使用经纬度跨度估算一个“足够看全路径”的缩放级别。
8
+ // 这是高层 TS 兜底逻辑,不依赖具体原生 SDK 的 fitBounds 能力。
9
+ const span = Math.max(latitudeDelta, longitudeDelta, 0.0001);
10
+ const rawZoom = Math.log2(360 / span);
11
+ const minZoom = options.minZoom ?? MIN_ZOOM;
12
+ const maxZoom = options.maxZoom ?? MAX_ZOOM;
13
+ return Math.max(minZoom, Math.min(maxZoom, Number(rawZoom.toFixed(2))));
14
+ }
15
+ export function getRouteBounds(points, options = {}) {
16
+ // 统一将路径点转换为对象坐标,再计算中心点、边界和推荐缩放。
17
+ const normalized = normalizeLatLngList(points);
18
+ if (normalized.length === 0) {
19
+ return null;
20
+ }
21
+ const latitudes = normalized.map((point) => point.latitude);
22
+ const longitudes = normalized.map((point) => point.longitude);
23
+ const north = Math.max(...latitudes);
24
+ const south = Math.min(...latitudes);
25
+ const east = Math.max(...longitudes);
26
+ const west = Math.min(...longitudes);
27
+ const paddingFactor = options.paddingFactor ?? DEFAULT_PADDING_FACTOR;
28
+ const latitudeDelta = Math.max((north - south) * paddingFactor, 0.0001);
29
+ const longitudeDelta = Math.max((east - west) * paddingFactor, 0.0001);
30
+ return {
31
+ center: {
32
+ latitude: (north + south) / 2,
33
+ longitude: (east + west) / 2,
34
+ },
35
+ bounds: {
36
+ north,
37
+ south,
38
+ east,
39
+ west,
40
+ },
41
+ span: {
42
+ latitudeDelta,
43
+ longitudeDelta,
44
+ },
45
+ recommendedZoom: estimateZoomLevel(latitudeDelta, longitudeDelta, options),
46
+ };
47
+ }
48
+ function parsePolylineRing(polyline) {
49
+ if (!polyline.trim()) {
50
+ return [];
51
+ }
52
+ return polyline
53
+ .split(';')
54
+ .map((segment) => segment.trim())
55
+ .filter(Boolean)
56
+ .map((segment) => {
57
+ const [longitude, latitude] = segment.split(',').map((value) => Number(value.trim()));
58
+ if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) {
59
+ return null;
60
+ }
61
+ return {
62
+ latitude,
63
+ longitude,
64
+ };
65
+ })
66
+ .filter((point) => point !== null);
67
+ }
68
+ export function parseMultiRingPolyline(polyline) {
69
+ // 高德 AOI / 多边形边界常见格式为 ring1|ring2,
70
+ // 这里按“外环/内环”统一拆成二维坐标数组。
71
+ const rings = polyline
72
+ .split('|')
73
+ .map((ring) => parsePolylineRing(ring))
74
+ .filter((ring) => ring.length > 0);
75
+ const flattened = rings.flat();
76
+ const bounds = flattened.length
77
+ ? {
78
+ southwest: {
79
+ latitude: Math.min(...flattened.map((point) => point.latitude)),
80
+ longitude: Math.min(...flattened.map((point) => point.longitude)),
81
+ },
82
+ northeast: {
83
+ latitude: Math.max(...flattened.map((point) => point.latitude)),
84
+ longitude: Math.max(...flattened.map((point) => point.longitude)),
85
+ },
86
+ }
87
+ : null;
88
+ return {
89
+ rings,
90
+ bounds,
91
+ };
92
+ }
93
+ export async function fitCameraToCoordinates(map, points, options = {}) {
94
+ // 高层相机适配:
95
+ // 1. 单点时直接移动到该点;
96
+ // 2. 多点时计算中心点与推荐缩放;
97
+ // 3. 尽量保留当前朝向和俯仰,避免突兀跳变。
98
+ const normalized = normalizeLatLngList(points);
99
+ if (normalized.length === 0) {
100
+ return;
101
+ }
102
+ const currentCamera = await map.getCameraPosition().catch(() => ({}));
103
+ if (normalized.length === 1) {
104
+ const single = normalizeLatLng(normalized[0]);
105
+ await map.moveCamera({
106
+ target: single,
107
+ zoom: options.singlePointZoom ?? currentCamera.zoom ?? DEFAULT_SINGLE_POINT_ZOOM,
108
+ bearing: options.preserveBearing === false ? options.bearing : currentCamera.bearing ?? options.bearing,
109
+ tilt: options.preserveTilt === false ? options.tilt : currentCamera.tilt ?? options.tilt,
110
+ }, options.duration ?? 0);
111
+ return;
112
+ }
113
+ const routeBounds = getRouteBounds(normalized, options);
114
+ if (!routeBounds) {
115
+ return;
116
+ }
117
+ await map.moveCamera({
118
+ target: routeBounds.center,
119
+ zoom: routeBounds.recommendedZoom,
120
+ bearing: options.preserveBearing === false ? options.bearing : currentCamera.bearing ?? options.bearing,
121
+ tilt: options.preserveTilt === false ? options.tilt : currentCamera.tilt ?? options.tilt,
122
+ }, options.duration ?? 0);
123
+ }
124
+ export function buildLatLngBounds(points) {
125
+ const routeBounds = getRouteBounds(points);
126
+ if (!routeBounds) {
127
+ return null;
128
+ }
129
+ return {
130
+ southwest: {
131
+ latitude: routeBounds.bounds.south,
132
+ longitude: routeBounds.bounds.west,
133
+ },
134
+ northeast: {
135
+ latitude: routeBounds.bounds.north,
136
+ longitude: routeBounds.bounds.east,
137
+ },
138
+ };
139
+ }
140
+ //# sourceMappingURL=RouteUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RouteUtils.js","sourceRoot":"","sources":["../../src/utils/RouteUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LatLng, LatLngBounds, LatLngPoint } from '../types/common.types';\nimport type {\n FitToCoordinatesOptions,\n FitToCoordinatesTarget,\n MultiRingPolyline,\n RouteBounds,\n} from '../types/route-playback.types';\nimport { normalizeLatLng, normalizeLatLngList } from './GeoUtils';\n\nconst MIN_ZOOM = 3;\nconst MAX_ZOOM = 20;\nconst DEFAULT_SINGLE_POINT_ZOOM = 16;\nconst DEFAULT_PADDING_FACTOR = 1.2;\n\nexport function estimateZoomLevel(\n latitudeDelta: number,\n longitudeDelta: number,\n options: Pick<FitToCoordinatesOptions, 'minZoom' | 'maxZoom'> = {}\n): number {\n // 使用经纬度跨度估算一个“足够看全路径”的缩放级别。\n // 这是高层 TS 兜底逻辑,不依赖具体原生 SDK 的 fitBounds 能力。\n const span = Math.max(latitudeDelta, longitudeDelta, 0.0001);\n const rawZoom = Math.log2(360 / span);\n const minZoom = options.minZoom ?? MIN_ZOOM;\n const maxZoom = options.maxZoom ?? MAX_ZOOM;\n return Math.max(minZoom, Math.min(maxZoom, Number(rawZoom.toFixed(2))));\n}\n\nexport function getRouteBounds(\n points: LatLngPoint[],\n options: Pick<FitToCoordinatesOptions, 'paddingFactor' | 'minZoom' | 'maxZoom'> = {}\n): RouteBounds | null {\n // 统一将路径点转换为对象坐标,再计算中心点、边界和推荐缩放。\n const normalized = normalizeLatLngList(points) as LatLng[];\n if (normalized.length === 0) {\n return null;\n }\n\n const latitudes = normalized.map((point) => point.latitude);\n const longitudes = normalized.map((point) => point.longitude);\n\n const north = Math.max(...latitudes);\n const south = Math.min(...latitudes);\n const east = Math.max(...longitudes);\n const west = Math.min(...longitudes);\n const paddingFactor = options.paddingFactor ?? DEFAULT_PADDING_FACTOR;\n const latitudeDelta = Math.max((north - south) * paddingFactor, 0.0001);\n const longitudeDelta = Math.max((east - west) * paddingFactor, 0.0001);\n\n return {\n center: {\n latitude: (north + south) / 2,\n longitude: (east + west) / 2,\n },\n bounds: {\n north,\n south,\n east,\n west,\n },\n span: {\n latitudeDelta,\n longitudeDelta,\n },\n recommendedZoom: estimateZoomLevel(latitudeDelta, longitudeDelta, options),\n };\n}\n\nfunction parsePolylineRing(polyline: string): LatLng[] {\n if (!polyline.trim()) {\n return [];\n }\n\n return polyline\n .split(';')\n .map((segment) => segment.trim())\n .filter(Boolean)\n .map((segment) => {\n const [longitude, latitude] = segment.split(',').map((value) => Number(value.trim()));\n if (!Number.isFinite(longitude) || !Number.isFinite(latitude)) {\n return null;\n }\n\n return {\n latitude,\n longitude,\n };\n })\n .filter((point): point is LatLng => point !== null);\n}\n\nexport function parseMultiRingPolyline(polyline: string): MultiRingPolyline {\n // 高德 AOI / 多边形边界常见格式为 ring1|ring2,\n // 这里按“外环/内环”统一拆成二维坐标数组。\n const rings = polyline\n .split('|')\n .map((ring) => parsePolylineRing(ring))\n .filter((ring) => ring.length > 0);\n\n const flattened = rings.flat();\n const bounds = flattened.length\n ? {\n southwest: {\n latitude: Math.min(...flattened.map((point) => point.latitude)),\n longitude: Math.min(...flattened.map((point) => point.longitude)),\n },\n northeast: {\n latitude: Math.max(...flattened.map((point) => point.latitude)),\n longitude: Math.max(...flattened.map((point) => point.longitude)),\n },\n }\n : null;\n\n return {\n rings,\n bounds,\n };\n}\n\nexport async function fitCameraToCoordinates(\n map: FitToCoordinatesTarget,\n points: LatLngPoint[],\n options: FitToCoordinatesOptions = {}\n): Promise<void> {\n // 高层相机适配:\n // 1. 单点时直接移动到该点;\n // 2. 多点时计算中心点与推荐缩放;\n // 3. 尽量保留当前朝向和俯仰,避免突兀跳变。\n const normalized = normalizeLatLngList(points) as LatLng[];\n if (normalized.length === 0) {\n return;\n }\n\n const currentCamera: Awaited<ReturnType<FitToCoordinatesTarget['getCameraPosition']>> =\n await map.getCameraPosition().catch(() => ({}));\n\n if (normalized.length === 1) {\n const single = normalizeLatLng(normalized[0]);\n await map.moveCamera(\n {\n target: single,\n zoom: options.singlePointZoom ?? currentCamera.zoom ?? DEFAULT_SINGLE_POINT_ZOOM,\n bearing: options.preserveBearing === false ? options.bearing : currentCamera.bearing ?? options.bearing,\n tilt: options.preserveTilt === false ? options.tilt : currentCamera.tilt ?? options.tilt,\n },\n options.duration ?? 0\n );\n return;\n }\n\n const routeBounds = getRouteBounds(normalized, options);\n if (!routeBounds) {\n return;\n }\n\n await map.moveCamera(\n {\n target: routeBounds.center,\n zoom: routeBounds.recommendedZoom,\n bearing: options.preserveBearing === false ? options.bearing : currentCamera.bearing ?? options.bearing,\n tilt: options.preserveTilt === false ? options.tilt : currentCamera.tilt ?? options.tilt,\n },\n options.duration ?? 0\n );\n}\n\nexport function buildLatLngBounds(points: LatLngPoint[]): LatLngBounds | null {\n const routeBounds = getRouteBounds(points);\n if (!routeBounds) {\n return null;\n }\n\n return {\n southwest: {\n latitude: routeBounds.bounds.south,\n longitude: routeBounds.bounds.west,\n },\n northeast: {\n latitude: routeBounds.bounds.north,\n longitude: routeBounds.bounds.east,\n },\n };\n}\n"]}
@@ -116,7 +116,7 @@ public class ExpoGaodeMapModule: Module {
116
116
  * 获取 SDK 版本号
117
117
  */
118
118
  Function("getVersion") {
119
- "iOS SDK Version"
119
+ MAMapKitVersion
120
120
  }
121
121
 
122
122
  /**
@@ -195,6 +195,7 @@ public class ExpoGaodeMapModule: Module {
195
195
  "longitude": location.coordinate.longitude,
196
196
  "accuracy": location.horizontalAccuracy,
197
197
  "altitude": location.altitude,
198
+ "heading": location.course,
198
199
  "bearing": location.course,
199
200
  "speed": location.speed,
200
201
  "timestamp": location.timestamp.timeIntervalSince1970 * 1000
@@ -578,7 +579,7 @@ public class ExpoGaodeMapModule: Module {
578
579
  }
579
580
 
580
581
  Function("setInterval") { (interval: Int) in
581
- self.getLocationManager().setDistanceFilter(Double(interval))
582
+ self.getLocationManager().setInterval(interval)
582
583
  }
583
584
 
584
585
  Function("setDistanceFilter") { (distance: Double) in
@@ -621,7 +622,7 @@ public class ExpoGaodeMapModule: Module {
621
622
  /**
622
623
  * 设置逆地理语言 (iOS 实现)
623
624
  */
624
- Function("setGeoLanguage") { (language: Int) in
625
+ Function("setGeoLanguage") { (language: String) in
625
626
  self.getLocationManager().setGeoLanguage(language)
626
627
  }
627
628
 
@@ -688,12 +689,7 @@ public class ExpoGaodeMapModule: Module {
688
689
  */
689
690
  AsyncFunction("checkLocationPermission") { (promise: Promise) in
690
691
  let status = self.currentAuthorizationStatus()
691
- let granted = status == .authorizedAlways || status == .authorizedWhenInUse
692
-
693
- promise.resolve([
694
- "granted": granted,
695
- "status": self.getAuthorizationStatusString(status)
696
- ])
692
+ promise.resolve(self.buildPermissionStatus(status))
697
693
  }
698
694
 
699
695
  /**
@@ -708,13 +704,7 @@ public class ExpoGaodeMapModule: Module {
708
704
  // 无论结果如何,都延迟后再次检查最终状态
709
705
  DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
710
706
  let finalStatus = self.currentAuthorizationStatus()
711
- let finalGranted = finalStatus == .authorizedAlways || finalStatus == .authorizedWhenInUse
712
- let finalStatusString = self.getAuthorizationStatusString(finalStatus)
713
-
714
- promise.resolve([
715
- "granted": finalGranted,
716
- "status": finalStatusString
717
- ])
707
+ promise.resolve(self.buildPermissionStatus(finalStatus))
718
708
  }
719
709
  }
720
710
  }
@@ -736,12 +726,14 @@ public class ExpoGaodeMapModule: Module {
736
726
  // 这里返回当前状态
737
727
  let hasBackground = status == .authorizedAlways
738
728
 
739
- promise.resolve([
740
- "granted": hasBackground,
741
- "backgroundLocation": hasBackground,
742
- "status": self.getAuthorizationStatusString(status),
743
- "message": hasBackground ? "已授予后台权限" : "需要在系统设置中手动授予'始终'权限"
744
- ])
729
+ promise.resolve(
730
+ self.buildPermissionStatus(
731
+ status,
732
+ grantedOverride: hasBackground,
733
+ backgroundLocationOverride: hasBackground,
734
+ message: hasBackground ? "已授予后台权限" : "需要在系统设置中手动授予'始终'权限"
735
+ )
736
+ )
745
737
  }
746
738
 
747
739
 
@@ -809,4 +801,31 @@ public class ExpoGaodeMapModule: Module {
809
801
  @unknown default: return "unknown"
810
802
  }
811
803
  }
804
+
805
+ private func buildPermissionStatus(
806
+ _ status: CLAuthorizationStatus,
807
+ grantedOverride: Bool? = nil,
808
+ backgroundLocationOverride: Bool? = nil,
809
+ message: String? = nil
810
+ ) -> [String: Any] {
811
+ let granted = grantedOverride ?? (status == .authorizedAlways || status == .authorizedWhenInUse)
812
+ let canAskAgain = status == .notDetermined
813
+ let isPermanentlyDenied = status == .denied || status == .restricted
814
+ let backgroundLocation = backgroundLocationOverride ?? (status == .authorizedAlways)
815
+
816
+ var result: [String: Any] = [
817
+ "granted": granted,
818
+ "status": self.getAuthorizationStatusString(status),
819
+ "canAskAgain": canAskAgain,
820
+ "backgroundLocation": backgroundLocation,
821
+ "isPermanentlyDenied": isPermanentlyDenied,
822
+ "shouldShowRationale": false
823
+ ]
824
+
825
+ if let message {
826
+ result["message"] = message
827
+ }
828
+
829
+ return result
830
+ }
812
831
  }