expo-gaode-map-navigation 2.0.11 → 2.0.12

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 (71) hide show
  1. package/android/src/main/cpp/cluster_jni.cpp +56 -0
  2. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +45 -6
  3. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +23 -17
  4. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +37 -25
  5. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +6 -6
  6. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +103 -0
  7. package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviView.kt +1 -1
  8. package/build/index.d.ts +10 -1
  9. package/build/index.d.ts.map +1 -1
  10. package/build/index.js +6 -3
  11. package/build/index.js.map +1 -1
  12. package/build/map/ExpoGaodeMapModule.d.ts +15 -13
  13. package/build/map/ExpoGaodeMapModule.d.ts.map +1 -1
  14. package/build/map/ExpoGaodeMapModule.js +31 -39
  15. package/build/map/ExpoGaodeMapModule.js.map +1 -1
  16. package/build/map/ExpoGaodeMapView.d.ts +3 -4
  17. package/build/map/ExpoGaodeMapView.d.ts.map +1 -1
  18. package/build/map/ExpoGaodeMapView.js +28 -25
  19. package/build/map/ExpoGaodeMapView.js.map +1 -1
  20. package/build/map/components/overlays/Circle.d.ts.map +1 -1
  21. package/build/map/components/overlays/Circle.js +1 -30
  22. package/build/map/components/overlays/Circle.js.map +1 -1
  23. package/build/map/components/overlays/Cluster.d.ts.map +1 -1
  24. package/build/map/components/overlays/Cluster.js +1 -42
  25. package/build/map/components/overlays/Cluster.js.map +1 -1
  26. package/build/map/components/overlays/HeatMap.d.ts.map +1 -1
  27. package/build/map/components/overlays/HeatMap.js +1 -20
  28. package/build/map/components/overlays/HeatMap.js.map +1 -1
  29. package/build/map/components/overlays/Marker.d.ts.map +1 -1
  30. package/build/map/components/overlays/Marker.js +76 -80
  31. package/build/map/components/overlays/Marker.js.map +1 -1
  32. package/build/map/components/overlays/Polygon.d.ts.map +1 -1
  33. package/build/map/components/overlays/Polygon.js +1 -25
  34. package/build/map/components/overlays/Polygon.js.map +1 -1
  35. package/build/map/components/overlays/Polyline.d.ts.map +1 -1
  36. package/build/map/components/overlays/Polyline.js +1 -31
  37. package/build/map/components/overlays/Polyline.js.map +1 -1
  38. package/build/map/index.d.ts +6 -2
  39. package/build/map/index.d.ts.map +1 -1
  40. package/build/map/index.js +6 -2
  41. package/build/map/index.js.map +1 -1
  42. package/build/map/types/index.d.ts +2 -2
  43. package/build/map/types/index.d.ts.map +1 -1
  44. package/build/map/types/index.js.map +1 -1
  45. package/build/map/types/native-module.types.d.ts +11 -12
  46. package/build/map/types/native-module.types.d.ts.map +1 -1
  47. package/build/map/types/native-module.types.js.map +1 -1
  48. package/build/map/types/overlays.types.d.ts +9 -14
  49. package/build/map/types/overlays.types.d.ts.map +1 -1
  50. package/build/map/types/overlays.types.js.map +1 -1
  51. package/build/map/types/route-playback.types.d.ts +16 -0
  52. package/build/map/types/route-playback.types.d.ts.map +1 -1
  53. package/build/map/types/route-playback.types.js.map +1 -1
  54. package/build/types/coordinates.types.d.ts +3 -0
  55. package/build/types/coordinates.types.d.ts.map +1 -1
  56. package/build/types/coordinates.types.js.map +1 -1
  57. package/ios/ExpoGaodeMapNaviView.swift +31 -2
  58. package/ios/map/ExpoGaodeMapModule.swift +38 -6
  59. package/ios/map/ExpoGaodeMapView.swift +10 -3
  60. package/ios/map/GaodeMapPrivacyManager.swift +26 -18
  61. package/ios/map/cpp/GeometryEngine.cpp +112 -0
  62. package/ios/map/cpp/GeometryEngine.hpp +21 -0
  63. package/ios/map/modules/LocationManager.swift +1 -1
  64. package/ios/map/overlays/MarkerView.swift +11 -11
  65. package/ios/map/overlays/MarkerViewModule.swift +4 -4
  66. package/ios/map/utils/ClusterNative.h +8 -0
  67. package/ios/map/utils/ClusterNative.mm +27 -0
  68. package/package.json +6 -4
  69. package/scripts/check-expo-modules.js +68 -0
  70. package/shared/cpp/GeometryEngine.cpp +112 -0
  71. package/shared/cpp/GeometryEngine.hpp +21 -0
@@ -41,12 +41,12 @@ public class MarkerViewModule: Module {
41
41
  view.iconHeight = height
42
42
  }
43
43
 
44
- Prop("customViewWidth") { (view: MarkerView, width: Double) in
45
- view.customViewWidth = width
44
+ Prop("contentWidth") { (view: MarkerView, width: Double) in
45
+ view.setContentWidth(width)
46
46
  }
47
47
 
48
- Prop("customViewHeight") { (view: MarkerView, height: Double) in
49
- view.customViewHeight = height
48
+ Prop("contentHeight") { (view: MarkerView, height: Double) in
49
+ view.setContentHeight(height)
50
50
  }
51
51
 
52
52
  Prop("centerOffset") { (view: MarkerView, offset: [String: Double]) in
@@ -55,6 +55,14 @@ NS_ASSUME_NONNULL_BEGIN
55
55
  + (NSDictionary * _Nullable)calculatePathBoundsWithLatitudes:(NSArray<NSNumber *> *)latitudes
56
56
  longitudes:(NSArray<NSNumber *> *)longitudes NS_SWIFT_NAME(calculatePathBounds(latitudes:longitudes:));
57
57
 
58
+ + (double)calculateFitZoomWithLatitudes:(NSArray<NSNumber *> *)latitudes
59
+ longitudes:(NSArray<NSNumber *> *)longitudes
60
+ viewportWidthPx:(double)viewportWidthPx
61
+ viewportHeightPx:(double)viewportHeightPx
62
+ paddingPx:(double)paddingPx
63
+ minZoom:(int)minZoom
64
+ maxZoom:(int)maxZoom NS_SWIFT_NAME(calculateFitZoom(latitudes:longitudes:viewportWidthPx:viewportHeightPx:paddingPx:minZoom:maxZoom:));
65
+
58
66
  + (NSString *)encodeGeoHashWithLat:(double)lat
59
67
  lon:(double)lon
60
68
  precision:(int)precision NS_SWIFT_NAME(encodeGeoHash(lat:lon:precision:));
@@ -242,6 +242,33 @@
242
242
  };
243
243
  }
244
244
 
245
+ + (double)calculateFitZoomWithLatitudes:(NSArray<NSNumber *> *)latitudes
246
+ longitudes:(NSArray<NSNumber *> *)longitudes
247
+ viewportWidthPx:(double)viewportWidthPx
248
+ viewportHeightPx:(double)viewportHeightPx
249
+ paddingPx:(double)paddingPx
250
+ minZoom:(int)minZoom
251
+ maxZoom:(int)maxZoom {
252
+ if (latitudes.count == 0 || latitudes.count != longitudes.count) {
253
+ return (double)minZoom;
254
+ }
255
+
256
+ std::vector<gaodemap::GeoPoint> points;
257
+ points.reserve(latitudes.count);
258
+ for (NSUInteger i = 0; i < latitudes.count; i++) {
259
+ points.push_back({[latitudes[i] doubleValue], [longitudes[i] doubleValue]});
260
+ }
261
+
262
+ return gaodemap::calculateFitZoomForPoints(
263
+ points,
264
+ viewportWidthPx,
265
+ viewportHeightPx,
266
+ paddingPx,
267
+ minZoom,
268
+ maxZoom
269
+ );
270
+ }
271
+
245
272
  + (NSString *)encodeGeoHashWithLat:(double)lat
246
273
  lon:(double)lon
247
274
  precision:(int)precision {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-gaode-map-navigation",
3
- "version": "2.0.11",
3
+ "version": "2.0.12",
4
4
  "description": "React Native AMap (Gaode Map) navigation module for Expo: route planning and turn-by-turn navigation, includes full map features.",
5
5
  "author": "TomWq <582752848@qq.com> (https://github.com/TomWq)",
6
6
  "repository": {
@@ -17,6 +17,7 @@
17
17
  "lint": "expo-module lint",
18
18
  "test": "expo-module test",
19
19
  "prepare": "expo-module prepare && yarn build:plugin",
20
+ "postinstall": "node scripts/check-expo-modules.js",
20
21
  "prepublishOnly": "echo 'Skipping proofread check' && exit 0",
21
22
  "expo-module": "expo-module",
22
23
  "android": "expo run:android",
@@ -25,9 +26,9 @@
25
26
  "devDependencies": {
26
27
  "@expo/vector-icons": "^15.0.3",
27
28
  "@types/react": "~19.1.0",
28
- "expo": "^54.0.31",
29
- "expo-module-scripts": "^5.0.8",
30
- "react-native": "0.81.5",
29
+ "expo": "^55.0.8",
30
+ "expo-module-scripts": "^55.0.2",
31
+ "react-native": "0.83.2",
31
32
  "typescript": "^5.9.3"
32
33
  },
33
34
  "peerDependencies": {
@@ -51,6 +52,7 @@
51
52
  "ios",
52
53
  "widget-template",
53
54
  "shared",
55
+ "scripts",
54
56
  "app.plugin.js",
55
57
  "expo-module.config.json",
56
58
  "plugin/build"
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+
6
+ function resolveProjectRoot() {
7
+ return process.env.INIT_CWD || process.env.npm_config_local_prefix || process.cwd();
8
+ }
9
+
10
+ function hasPackage(pkgName, projectRoot) {
11
+ try {
12
+ require.resolve(`${pkgName}/package.json`, { paths: [projectRoot] });
13
+ return true;
14
+ } catch {
15
+ return false;
16
+ }
17
+ }
18
+
19
+ function printWarning(lines) {
20
+ const prefix = '[expo-gaode-map-navigation]';
21
+ console.warn(`${prefix} WARNING: Expo Modules infrastructure was not detected in this React Native project.`);
22
+ for (const line of lines) {
23
+ console.warn(`${prefix} ${line}`);
24
+ }
25
+ }
26
+
27
+ function main() {
28
+ const projectRoot = resolveProjectRoot();
29
+
30
+ // Skip non-React Native consumers.
31
+ if (!hasPackage('react-native', projectRoot)) {
32
+ return;
33
+ }
34
+
35
+ const hasExpo = hasPackage('expo', projectRoot);
36
+ const hasExpoModulesCore = hasPackage('expo-modules-core', projectRoot);
37
+ const podfilePath = path.join(projectRoot, 'ios', 'Podfile');
38
+ const hasPodfile = fs.existsSync(podfilePath);
39
+ const hasUseExpoModules = hasPodfile
40
+ ? /\buse_expo_modules!\b/m.test(fs.readFileSync(podfilePath, 'utf8'))
41
+ : true;
42
+
43
+ if (hasExpo && hasExpoModulesCore && hasUseExpoModules) {
44
+ return;
45
+ }
46
+
47
+ const details = [];
48
+ if (!hasExpo) {
49
+ details.push('Missing dependency: expo');
50
+ }
51
+ if (!hasExpoModulesCore) {
52
+ details.push('Missing dependency: expo-modules-core');
53
+ }
54
+ if (!hasUseExpoModules) {
55
+ details.push('iOS Podfile does not contain use_expo_modules!');
56
+ }
57
+
58
+ printWarning([
59
+ ...details,
60
+ 'This package requires Expo Modules infrastructure even in bare React Native apps.',
61
+ 'Suggested fix:',
62
+ ' npx install-expo-modules@latest',
63
+ hasPodfile ? ' (then) cd ios && pod install' : null,
64
+ 'Docs: https://docs.expo.dev/bare/installing-expo-modules/',
65
+ ].filter(Boolean));
66
+ }
67
+
68
+ main();
@@ -3,6 +3,7 @@
3
3
  #include <cmath>
4
4
  #include <map>
5
5
  #include <algorithm>
6
+ #include <limits>
6
7
 
7
8
  namespace gaodemap {
8
9
 
@@ -19,6 +20,54 @@ static inline double geo_toDegrees(double radians) {
19
20
  return radians * kRadiansToDegrees;
20
21
  }
21
22
 
23
+ static inline double clampMercatorLatitude(double lat) {
24
+ static constexpr double kMaxMercatorLatitude = 85.05112878;
25
+ if (lat > kMaxMercatorLatitude) return kMaxMercatorLatitude;
26
+ if (lat < -kMaxMercatorLatitude) return -kMaxMercatorLatitude;
27
+ return lat;
28
+ }
29
+
30
+ static inline double mercatorX01(double lon) {
31
+ double wrapped = std::fmod(lon + 180.0, 360.0);
32
+ if (wrapped < 0.0) {
33
+ wrapped += 360.0;
34
+ }
35
+ return wrapped / 360.0;
36
+ }
37
+
38
+ static inline double mercatorY01(double lat) {
39
+ const double clampedLat = clampMercatorLatitude(lat);
40
+ const double latRad = geo_toRadians(clampedLat);
41
+ const double y = (1.0 - std::asinh(std::tan(latRad)) / kPi) * 0.5;
42
+ if (y < 0.0) return 0.0;
43
+ if (y > 1.0) return 1.0;
44
+ return y;
45
+ }
46
+
47
+ static double wrappedSpan01(std::vector<double> xs) {
48
+ if (xs.size() <= 1) {
49
+ return 0.0;
50
+ }
51
+
52
+ std::sort(xs.begin(), xs.end());
53
+ double maxGap = 0.0;
54
+
55
+ for (size_t i = 0; i + 1 < xs.size(); ++i) {
56
+ const double gap = xs[i + 1] - xs[i];
57
+ if (gap > maxGap) {
58
+ maxGap = gap;
59
+ }
60
+ }
61
+
62
+ const double endGap = xs.front() + 1.0 - xs.back();
63
+ if (endGap > maxGap) {
64
+ maxGap = endGap;
65
+ }
66
+
67
+ const double span = 1.0 - maxGap;
68
+ return span < 0.0 ? 0.0 : span;
69
+ }
70
+
22
71
  double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
23
72
  const double radLat1 = geo_toRadians(lat1);
24
73
  const double radLat2 = geo_toRadians(lat2);
@@ -512,6 +561,69 @@ GeoPoint pixelToLatLng(double x, double y, int zoom) {
512
561
  return {lat, lon};
513
562
  }
514
563
 
564
+ double calculateFitZoomForPoints(
565
+ const std::vector<GeoPoint>& points,
566
+ double viewportWidthPx,
567
+ double viewportHeightPx,
568
+ double paddingPx,
569
+ int minZoom,
570
+ int maxZoom
571
+ ) {
572
+ if (minZoom > maxZoom) {
573
+ std::swap(minZoom, maxZoom);
574
+ }
575
+ if (points.empty()) {
576
+ return static_cast<double>(minZoom);
577
+ }
578
+ if (points.size() == 1) {
579
+ return static_cast<double>(maxZoom);
580
+ }
581
+
582
+ const double safeViewportWidth = viewportWidthPx > 1.0 ? viewportWidthPx : 390.0;
583
+ const double safeViewportHeight = viewportHeightPx > 1.0 ? viewportHeightPx : 844.0;
584
+ const double safePadding = std::max(0.0, paddingPx);
585
+ const double availableWidth = std::max(1.0, safeViewportWidth - safePadding * 2.0);
586
+ const double availableHeight = std::max(1.0, safeViewportHeight - safePadding * 2.0);
587
+
588
+ std::vector<double> projectedXs;
589
+ projectedXs.reserve(points.size());
590
+
591
+ double minY = std::numeric_limits<double>::max();
592
+ double maxY = -std::numeric_limits<double>::max();
593
+
594
+ for (const auto& p : points) {
595
+ projectedXs.push_back(mercatorX01(p.lon));
596
+ const double y = mercatorY01(p.lat);
597
+ if (y < minY) minY = y;
598
+ if (y > maxY) maxY = y;
599
+ }
600
+
601
+ const double spanX = wrappedSpan01(projectedXs);
602
+ const double spanY = std::max(0.0, maxY - minY);
603
+ static constexpr double kTileSize = 256.0;
604
+ static constexpr double kSpanEpsilon = 1e-12;
605
+
606
+ const double zoomX = spanX <= kSpanEpsilon
607
+ ? static_cast<double>(maxZoom)
608
+ : std::log2(availableWidth / (kTileSize * spanX));
609
+ const double zoomY = spanY <= kSpanEpsilon
610
+ ? static_cast<double>(maxZoom)
611
+ : std::log2(availableHeight / (kTileSize * spanY));
612
+
613
+ double fitZoom = std::min(zoomX, zoomY);
614
+ if (!std::isfinite(fitZoom)) {
615
+ fitZoom = static_cast<double>(minZoom);
616
+ }
617
+
618
+ if (fitZoom < static_cast<double>(minZoom)) {
619
+ fitZoom = static_cast<double>(minZoom);
620
+ } else if (fitZoom > static_cast<double>(maxZoom)) {
621
+ fitZoom = static_cast<double>(maxZoom);
622
+ }
623
+
624
+ return fitZoom;
625
+ }
626
+
515
627
  // --- 批量地理围栏与热力图 ---
516
628
 
517
629
  int findPointInPolygons(double pointLat, double pointLon, const std::vector<std::vector<GeoPoint>>& polygons) {
@@ -125,6 +125,27 @@ PixelResult latLngToPixel(double lat, double lon, int zoom);
125
125
  */
126
126
  GeoPoint pixelToLatLng(double x, double y, int zoom);
127
127
 
128
+ /**
129
+ * 根据一组坐标点和视口尺寸计算“可同时看到所有点”的推荐缩放级别。
130
+ * 使用 Web Mercator 投影,在跨经线场景下会自动取更小经度跨度。
131
+ *
132
+ * @param points 坐标点集合,至少 1 个
133
+ * @param viewportWidthPx 视口宽度(像素)
134
+ * @param viewportHeightPx 视口高度(像素)
135
+ * @param paddingPx 四周预留的内边距(像素)
136
+ * @param minZoom 最小缩放级别
137
+ * @param maxZoom 最大缩放级别
138
+ * @return 推荐 zoom(已在 [minZoom, maxZoom] 范围内)
139
+ */
140
+ double calculateFitZoomForPoints(
141
+ const std::vector<GeoPoint>& points,
142
+ double viewportWidthPx,
143
+ double viewportHeightPx,
144
+ double paddingPx,
145
+ int minZoom,
146
+ int maxZoom
147
+ );
148
+
128
149
  // --- 批量地理围栏与热力图 ---
129
150
 
130
151
  /**