expo-gaode-map 2.2.24-next.1 → 2.2.24

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 (41) hide show
  1. package/README.md +37 -0
  2. package/android/build.gradle +25 -1
  3. package/android/src/main/cpp/cluster_jni.cpp +178 -0
  4. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapModule.kt +118 -0
  5. package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapOfflineModule.kt +46 -4
  6. package/android/src/main/java/expo/modules/gaodemap/utils/GeometryUtils.kt +116 -0
  7. package/build/ExpoGaodeMapModule.d.ts.map +1 -1
  8. package/build/ExpoGaodeMapModule.js +193 -60
  9. package/build/ExpoGaodeMapModule.js.map +1 -1
  10. package/build/ExpoGaodeMapView.js.map +1 -1
  11. package/build/components/FoldableMapView.d.ts +2 -2
  12. package/build/components/FoldableMapView.d.ts.map +1 -1
  13. package/build/components/FoldableMapView.js +12 -12
  14. package/build/components/FoldableMapView.js.map +1 -1
  15. package/build/components/MapUI.js.map +1 -1
  16. package/build/types/native-module.types.d.ts +65 -1
  17. package/build/types/native-module.types.d.ts.map +1 -1
  18. package/build/types/native-module.types.js.map +1 -1
  19. package/build/types/overlays.types.d.ts +2 -2
  20. package/build/types/overlays.types.d.ts.map +1 -1
  21. package/build/types/overlays.types.js.map +1 -1
  22. package/build/utils/ErrorHandler.d.ts +3 -3
  23. package/build/utils/ErrorHandler.d.ts.map +1 -1
  24. package/build/utils/ErrorHandler.js +1 -1
  25. package/build/utils/ErrorHandler.js.map +1 -1
  26. package/build/utils/GeoUtils.d.ts +3 -1
  27. package/build/utils/GeoUtils.d.ts.map +1 -1
  28. package/build/utils/GeoUtils.js +12 -12
  29. package/build/utils/GeoUtils.js.map +1 -1
  30. package/ios/ExpoGaodeMapModule.swift +90 -16
  31. package/ios/overlays/ClusterView.swift +1 -1
  32. package/ios/overlays/MarkerView.swift +5 -3
  33. package/ios/utils/ClusterNative.h +35 -15
  34. package/ios/utils/ClusterNative.mm +105 -4
  35. package/ios/utils/ColorParser.swift +1 -1
  36. package/ios/utils/GeometryUtils.swift +1 -1
  37. package/package.json +1 -1
  38. package/plugin/build/withGaodeMap.d.ts +5 -0
  39. package/plugin/build/withGaodeMap.js +40 -3
  40. package/shared/cpp/GeometryEngine.cpp +95 -0
  41. package/shared/cpp/GeometryEngine.hpp +65 -0
package/README.md CHANGED
@@ -162,9 +162,46 @@ try {
162
162
  }
163
163
  }
164
164
  ```
165
+ ### 5. 地图在模拟器上显示异常(可能会出现黑屏或闪退)
166
+
167
+ 建议:
168
+ - 确保在真机上测试,模拟器可能不支持地图功能
169
+ - 检查是否正确配置了 API Key
165
170
 
166
171
  **完整错误处理指南**:[ERROR_HANDLING_GUIDE.md](./ERROR_HANDLING_GUIDE.md)
167
172
 
173
+ ### 6. Google Play 版本支持
174
+
175
+ 如果你的应用需要上架 Google Play,需要使用高德地图 Google Play 版本的 SDK(通过了 Google Play 的合规审核)。
176
+
177
+ #### 步骤 1:下载 SDK
178
+ 前往 [高德开放平台](https://lbs.amap.com/api/android-sdk/download) 下载包含 Google Play 版本的 SDK(通常是合包,包含地图、搜索、定位功能)。
179
+
180
+ #### 步骤 2:放入项目
181
+ 将下载的 `.aar` 或 `.jar` 文件放入你的 Expo 项目根目录下的 `libs` 文件夹中(如果没有则创建),例如 `libs/AMap_3DMap_GooglePlay.aar`。
182
+
183
+ #### 步骤 3:配置插件
184
+ 在 `app.json` 中配置 `customMapSdkPath`:
185
+
186
+ ```json
187
+ {
188
+ "expo": {
189
+ "plugins": [
190
+ [
191
+ "expo-gaode-map",
192
+ {
193
+ "androidKey": "your-android-key",
194
+ "iosKey": "your-ios-key",
195
+ "customMapSdkPath": "./libs/AMap_3DMap_GooglePlay.aar"
196
+ }
197
+ ]
198
+ ]
199
+ }
200
+ }
201
+ ```
202
+
203
+ > **注意**:Google Play 版本的 SDK 通常是合包(包含地图+搜索+定位)。如果你的项目中引入了其他高德相关依赖(如 `expo-gaode-map-search`),可能会导致类冲突。插件会自动处理大部分冲突,但如果依然遇到 `Duplicate class` 错误,请检查是否引入了多余的依赖。
204
+
168
205
  支持的错误类型:
169
206
  - `SDK_NOT_INITIALIZED` - SDK 未初始化
170
207
  - `INVALID_API_KEY` - API Key 配置错误
@@ -54,5 +54,29 @@ android {
54
54
 
55
55
  dependencies {
56
56
  // 高德地图 3D SDK
57
- implementation ('com.amap.api:3dmap:latest.integration')
57
+ def customSdkPath = null
58
+ println "ExpoGaodeMap: Checking for custom SDK property in rootProject: ${rootProject.name}"
59
+ if (rootProject.hasProperty("EXPO_GAODE_MAP_CUSTOM_SDK_PATH")) {
60
+ customSdkPath = rootProject.property("EXPO_GAODE_MAP_CUSTOM_SDK_PATH")
61
+ println "ExpoGaodeMap: Found custom SDK path property: ${customSdkPath}"
62
+ } else {
63
+ println "ExpoGaodeMap: No custom SDK path property found."
64
+ }
65
+
66
+ if (customSdkPath) {
67
+ def sdkFile = rootProject.file(customSdkPath)
68
+ if (!sdkFile.exists()) {
69
+ // Try to find the file relative to the project root (parent of android folder)
70
+ sdkFile = new File(rootProject.projectDir.parentFile, customSdkPath)
71
+ }
72
+
73
+ if (sdkFile.exists()) {
74
+ println "ExpoGaodeMap: Using custom Map SDK from ${sdkFile.absolutePath}"
75
+ implementation files(sdkFile)
76
+ } else {
77
+ throw new FileNotFoundException("ExpoGaodeMap: Could not find custom SDK at ${customSdkPath}. Please check your customMapSdkPath configuration.")
78
+ }
79
+ } else {
80
+ implementation ('com.amap.api:3dmap:latest.integration')
81
+ }
58
82
  }
@@ -11,6 +11,7 @@ typedef void* jstring;
11
11
  typedef double jdouble;
12
12
  typedef int jint;
13
13
  typedef int jsize;
14
+ typedef void* jobjectArray;
14
15
  typedef unsigned char jboolean;
15
16
  #ifndef JNI_TRUE
16
17
  #define JNI_TRUE 1
@@ -232,6 +233,55 @@ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeIsPointInPolygon(
232
233
  #endif
233
234
  }
234
235
 
236
+ extern "C" JNIEXPORT jint JNICALL
237
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeFindPointInPolygons(
238
+ JNIEnv* env,
239
+ jclass,
240
+ jdouble pointLat,
241
+ jdouble pointLon,
242
+ jobjectArray polygonsLat,
243
+ jobjectArray polygonsLon
244
+ ) {
245
+ #if GAODE_HAVE_JNI
246
+ if (!polygonsLat || !polygonsLon) return -1;
247
+
248
+ const jsize polygonCount = env->GetArrayLength(polygonsLat);
249
+ if (polygonCount == 0) return -1;
250
+
251
+ std::vector<std::vector<gaodemap::GeoPoint>> polygons;
252
+ polygons.reserve(static_cast<size_t>(polygonCount));
253
+
254
+ for (jsize i = 0; i < polygonCount; ++i) {
255
+ jdoubleArray latArray = (jdoubleArray)env->GetObjectArrayElement(polygonsLat, i);
256
+ jdoubleArray lonArray = (jdoubleArray)env->GetObjectArrayElement(polygonsLon, i);
257
+
258
+ if (!latArray || !lonArray) continue;
259
+
260
+ const jsize pointCount = env->GetArrayLength(latArray);
261
+ jdouble* latValues = env->GetDoubleArrayElements(latArray, nullptr);
262
+ jdouble* lonValues = env->GetDoubleArrayElements(lonArray, nullptr);
263
+
264
+ std::vector<gaodemap::GeoPoint> polygon;
265
+ polygon.reserve(static_cast<size_t>(pointCount));
266
+ for (jsize j = 0; j < pointCount; ++j) {
267
+ polygon.push_back({latValues[j], lonValues[j]});
268
+ }
269
+
270
+ polygons.push_back(std::move(polygon));
271
+
272
+ env->ReleaseDoubleArrayElements(latArray, latValues, JNI_ABORT);
273
+ env->ReleaseDoubleArrayElements(lonArray, lonValues, JNI_ABORT);
274
+ env->DeleteLocalRef(latArray);
275
+ env->DeleteLocalRef(lonArray);
276
+ }
277
+
278
+ return gaodemap::findPointInPolygons(pointLat, pointLon, polygons);
279
+ #else
280
+ (void)env; (void)pointLat; (void)pointLon; (void)polygonsLat; (void)polygonsLon;
281
+ return -1;
282
+ #endif
283
+ }
284
+
235
285
  extern "C" JNIEXPORT jdouble JNICALL
236
286
  Java_expo_modules_gaodemap_utils_GeometryUtils_nativeCalculatePolygonArea(
237
287
  JNIEnv* env,
@@ -668,3 +718,131 @@ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeParsePolyline(
668
718
  return nullptr;
669
719
  #endif
670
720
  }
721
+
722
+ extern "C" JNIEXPORT jintArray JNICALL
723
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeLatLngToTile(
724
+ JNIEnv* env,
725
+ jclass,
726
+ jdouble lat,
727
+ jdouble lon,
728
+ jint zoom
729
+ ) {
730
+ #if GAODE_HAVE_JNI
731
+ gaodemap::TileResult result = gaodemap::latLngToTile(lat, lon, zoom);
732
+ jintArray array = env->NewIntArray(3);
733
+ jint buffer[3] = {result.x, result.y, result.z};
734
+ env->SetIntArrayRegion(array, 0, 3, buffer);
735
+ return array;
736
+ #else
737
+ (void)env; (void)lat; (void)lon; (void)zoom;
738
+ return nullptr;
739
+ #endif
740
+ }
741
+
742
+ extern "C" JNIEXPORT jdoubleArray JNICALL
743
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeTileToLatLng(
744
+ JNIEnv* env,
745
+ jclass,
746
+ jint x,
747
+ jint y,
748
+ jint zoom
749
+ ) {
750
+ #if GAODE_HAVE_JNI
751
+ gaodemap::GeoPoint result = gaodemap::tileToLatLng(x, y, zoom);
752
+ jdoubleArray array = env->NewDoubleArray(2);
753
+ jdouble buffer[2] = {result.lat, result.lon};
754
+ env->SetDoubleArrayRegion(array, 0, 2, buffer);
755
+ return array;
756
+ #else
757
+ (void)env; (void)x; (void)y; (void)zoom;
758
+ return nullptr;
759
+ #endif
760
+ }
761
+
762
+ extern "C" JNIEXPORT jdoubleArray JNICALL
763
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeLatLngToPixel(
764
+ JNIEnv* env,
765
+ jclass,
766
+ jdouble lat,
767
+ jdouble lon,
768
+ jint zoom
769
+ ) {
770
+ #if GAODE_HAVE_JNI
771
+ gaodemap::PixelResult result = gaodemap::latLngToPixel(lat, lon, zoom);
772
+ jdoubleArray array = env->NewDoubleArray(2);
773
+ jdouble buffer[2] = {result.x, result.y};
774
+ env->SetDoubleArrayRegion(array, 0, 2, buffer);
775
+ return array;
776
+ #else
777
+ (void)env; (void)lat; (void)lon; (void)zoom;
778
+ return nullptr;
779
+ #endif
780
+ }
781
+
782
+ extern "C" JNIEXPORT jdoubleArray JNICALL
783
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativePixelToLatLng(
784
+ JNIEnv* env,
785
+ jclass,
786
+ jdouble x,
787
+ jdouble y,
788
+ jint zoom
789
+ ) {
790
+ #if GAODE_HAVE_JNI
791
+ gaodemap::GeoPoint result = gaodemap::pixelToLatLng(x, y, zoom);
792
+ jdoubleArray array = env->NewDoubleArray(2);
793
+ jdouble buffer[2] = {result.lat, result.lon};
794
+ env->SetDoubleArrayRegion(array, 0, 2, buffer);
795
+ return array;
796
+ #else
797
+ (void)env; (void)x; (void)y; (void)zoom;
798
+ return nullptr;
799
+ #endif
800
+ }
801
+
802
+ extern "C" JNIEXPORT jdoubleArray JNICALL
803
+ Java_expo_modules_gaodemap_utils_GeometryUtils_nativeGenerateHeatmapGrid(
804
+ JNIEnv* env,
805
+ jclass,
806
+ jdoubleArray latitudes,
807
+ jdoubleArray longitudes,
808
+ jdoubleArray weights,
809
+ jdouble gridSizeMeters
810
+ ) {
811
+ #if GAODE_HAVE_JNI
812
+ if (!latitudes || !longitudes || !weights) return nullptr;
813
+ const jsize count = env->GetArrayLength(latitudes);
814
+ if (count == 0 || count != env->GetArrayLength(longitudes) || count != env->GetArrayLength(weights)) {
815
+ return nullptr;
816
+ }
817
+
818
+ jdouble* latVals = env->GetDoubleArrayElements(latitudes, nullptr);
819
+ jdouble* lonVals = env->GetDoubleArrayElements(longitudes, nullptr);
820
+ jdouble* weightVals = env->GetDoubleArrayElements(weights, nullptr);
821
+
822
+ std::vector<gaodemap::HeatmapPoint> points;
823
+ points.reserve(count);
824
+ for (jsize i = 0; i < count; ++i) {
825
+ points.push_back({latVals[i], lonVals[i], weightVals[i]});
826
+ }
827
+
828
+ env->ReleaseDoubleArrayElements(latitudes, latVals, JNI_ABORT);
829
+ env->ReleaseDoubleArrayElements(longitudes, lonVals, JNI_ABORT);
830
+ env->ReleaseDoubleArrayElements(weights, weightVals, JNI_ABORT);
831
+
832
+ auto cells = gaodemap::generateHeatmapGrid(points, gridSizeMeters);
833
+
834
+ jdoubleArray result = env->NewDoubleArray(static_cast<jsize>(cells.size() * 3));
835
+ std::vector<double> buffer;
836
+ buffer.reserve(cells.size() * 3);
837
+ for (const auto& c : cells) {
838
+ buffer.push_back(c.lat);
839
+ buffer.push_back(c.lon);
840
+ buffer.push_back(c.intensity);
841
+ }
842
+ env->SetDoubleArrayRegion(result, 0, static_cast<jsize>(buffer.size()), buffer.data());
843
+ return result;
844
+ #else
845
+ (void)env; (void)latitudes; (void)longitudes; (void)weights; (void)gridSizeMeters;
846
+ return nullptr;
847
+ #endif
848
+ }
@@ -79,6 +79,9 @@ class ExpoGaodeMapModule : Module() {
79
79
  SDKInitializer.initSDK(appContext.reactContext!!, androidKey)
80
80
  getLocationManager() // 初始化定位管理器
81
81
 
82
+ // 打印当前 SDK 版本信息,便于验证依赖来源
83
+ android.util.Log.i("ExpoGaodeMap", "✅ SDK 初始化完成 - Version: ${MapsInitializer.getVersion()}")
84
+
82
85
  // 初始化成功后自动触发一次预加载
83
86
  MapPreloadManager.startPreload(appContext.reactContext!!, poolSize = 1)
84
87
  } catch (e: SecurityException) {
@@ -451,6 +454,121 @@ class ExpoGaodeMapModule : Module() {
451
454
  }
452
455
  }
453
456
 
457
+ /**
458
+ * 经纬度转瓦片坐标
459
+ * @param coordinate 坐标
460
+ * @param zoom 缩放级别
461
+ * @return 瓦片坐标 [x, y]
462
+ */
463
+ Function("latLngToTile") { coordinate: Map<String, Any>?, zoom: Int ->
464
+ val latLng = LatLngParser.parseLatLng(coordinate)
465
+ if (latLng != null) {
466
+ val result = GeometryUtils.latLngToTile(latLng, zoom)
467
+ if (result != null && result.size >= 2) {
468
+ mapOf("x" to result[0], "y" to result[1])
469
+ } else {
470
+ null
471
+ }
472
+ } else {
473
+ null
474
+ }
475
+ }
476
+
477
+ /**
478
+ * 瓦片坐标转经纬度
479
+ * @param tile 瓦片坐标 {x, y, z}
480
+ * @return 坐标
481
+ */
482
+ Function("tileToLatLng") { tile: Map<String, Any>? ->
483
+ val x = (tile?.get("x") as? Number)?.toInt() ?: 0
484
+ val y = (tile?.get("y") as? Number)?.toInt() ?: 0
485
+ val zoom = (tile?.get("z") as? Number)?.toInt() ?: (tile?.get("zoom") as? Number)?.toInt() ?: 0
486
+ val result = GeometryUtils.tileToLatLng(x, y, zoom)
487
+ result?.let {
488
+ mapOf("latitude" to it.latitude, "longitude" to it.longitude)
489
+ }
490
+ }
491
+
492
+ /**
493
+ * 经纬度转像素坐标
494
+ * @param coordinate 坐标
495
+ * @param zoom 缩放级别
496
+ * @return 像素坐标 [x, y]
497
+ */
498
+ Function("latLngToPixel") { coordinate: Map<String, Any>?, zoom: Int ->
499
+ val latLng = LatLngParser.parseLatLng(coordinate)
500
+ if (latLng != null) {
501
+ val result = GeometryUtils.latLngToPixel(latLng, zoom)
502
+ if (result != null && result.size >= 2) {
503
+ mapOf("x" to result[0], "y" to result[1])
504
+ } else {
505
+ null
506
+ }
507
+ } else {
508
+ null
509
+ }
510
+ }
511
+
512
+ /**
513
+ * 像素坐标转经纬度
514
+ * @param pixel 像素坐标 {x, y}
515
+ * @param zoom 缩放级别
516
+ * @return 坐标
517
+ */
518
+ Function("pixelToLatLng") { pixel: Map<String, Any>?, zoom: Int ->
519
+ val x = (pixel?.get("x") as? Number)?.toDouble() ?: 0.0
520
+ val y = (pixel?.get("y") as? Number)?.toDouble() ?: 0.0
521
+ val result = GeometryUtils.pixelToLatLng(x, y, zoom)
522
+ result?.let {
523
+ mapOf("latitude" to it.latitude, "longitude" to it.longitude)
524
+ }
525
+ }
526
+
527
+ /**
528
+ * 批量判断点在哪个多边形内
529
+ * @param point 待判断点
530
+ * @param polygons 多边形列表
531
+ * @return 所在多边形的索引,不在任何多边形内返回 -1
532
+ */
533
+ Function("findPointInPolygons") { point: Map<String, Any>?, polygons: List<List<Any>>? ->
534
+ val pt = LatLngParser.parseLatLng(point)
535
+ val polys = polygons?.map { LatLngParser.parseLatLngList(it) }
536
+ if (pt != null && polys != null) {
537
+ GeometryUtils.findPointInPolygons(pt, polys)
538
+ } else {
539
+ -1
540
+ }
541
+ }
542
+
543
+ /**
544
+ * 生成网格聚合数据 (常用于展示网格聚合图或大规模点数据处理)
545
+ * @param points 包含经纬度和权重的点数组
546
+ * @param gridSizeMeters 网格大小(米)
547
+ */
548
+ Function("generateHeatmapGrid") { points: List<Map<String, Any>>?, gridSizeMeters: Double ->
549
+ if (points == null || points.isEmpty()) return@Function emptyList<Map<String, Any>>()
550
+
551
+ val count = points.size
552
+ val latitudes = DoubleArray(count)
553
+ val longitudes = DoubleArray(count)
554
+ val weights = DoubleArray(count)
555
+
556
+ points.forEachIndexed { index, map ->
557
+ latitudes[index] = (map["latitude"] as? Number)?.toDouble() ?: 0.0
558
+ longitudes[index] = (map["longitude"] as? Number)?.toDouble() ?: 0.0
559
+ weights[index] = (map["weight"] as? Number)?.toDouble() ?: 1.0
560
+ }
561
+
562
+ val result = GeometryUtils.generateHeatmapGrid(latitudes, longitudes, weights, gridSizeMeters)
563
+ result.map {
564
+ mapOf(
565
+ "latitude" to it.latitude,
566
+ "longitude" to it.longitude,
567
+ "intensity" to it.intensity
568
+ )
569
+ }
570
+ }
571
+
454
572
  // ==================== 定位配置 ====================
455
573
 
456
574
  /**
@@ -446,9 +446,9 @@ class ExpoGaodeMapOfflineModule : Module() {
446
446
  putString("cityName", city.city)
447
447
  putLong("size", city.size)
448
448
  putString("status", status)
449
- putInt("progress", city.getcompleteCode())
449
+ putInt("progress", getDownloadProgress(city))
450
450
  putString("version", city.version)
451
- putLong("downloadedSize", (city.size * city.getcompleteCode() / 100))
451
+ putLong("downloadedSize", (city.size * getDownloadProgress(city) / 100))
452
452
  }
453
453
  }
454
454
 
@@ -461,12 +461,54 @@ class ExpoGaodeMapOfflineModule : Module() {
461
461
  putString("cityName", province.provinceName)
462
462
  putLong("size", province.size)
463
463
  putString("status", getStatusString(province.state))
464
- putInt("progress", province.getcompleteCode())
464
+ putInt("progress", getDownloadProgress(province))
465
465
  putString("version", province.version)
466
466
  putString("provinceName", province.provinceName)
467
467
  putString("provinceCode", province.provinceCode)
468
468
  }
469
469
  }
470
+
471
+ /**
472
+ * 兼容获取 START_DOWNLOAD_FAILED 状态码
473
+ * 国内版拼写为 START_DOWNLOAD_FAILD,Google Play 版修正为 START_DOWNLOAD_FAILED
474
+ */
475
+ private val startDownloadFailedCode: Int by lazy {
476
+ try {
477
+ OfflineMapStatus::class.java.getField("START_DOWNLOAD_FAILED").getInt(null)
478
+ } catch (e: Exception) {
479
+ try {
480
+ OfflineMapStatus::class.java.getField("START_DOWNLOAD_FAILD").getInt(null)
481
+ } catch (e2: Exception) {
482
+ -1
483
+ }
484
+ }
485
+ }
486
+
487
+ /**
488
+ * 兼容获取下载进度
489
+ * Google Play 版本 SDK 可能修复了 getcompleteCode 的命名或使用了不同的 API
490
+ */
491
+ private fun getDownloadProgress(obj: Any): Int {
492
+ try {
493
+ // 尝试标准版的命名 (getcompleteCode)
494
+ val method = obj.javaClass.getMethod("getcompleteCode")
495
+ return method.invoke(obj) as Int
496
+ } catch (e: Exception) {
497
+ try {
498
+ // 尝试修正后的命名 (getCompleteCode) - Google Play 版本可能使用此命名
499
+ val method = obj.javaClass.getMethod("getCompleteCode")
500
+ return method.invoke(obj) as Int
501
+ } catch (e2: Exception) {
502
+ // 如果都失败了,尝试直接访问 completeCode 字段
503
+ try {
504
+ val field = obj.javaClass.getField("completeCode")
505
+ return field.getInt(obj)
506
+ } catch (e3: Exception) {
507
+ return 0
508
+ }
509
+ }
510
+ }
511
+ }
470
512
 
471
513
  /**
472
514
  * 获取状态字符串
@@ -484,7 +526,7 @@ class ExpoGaodeMapOfflineModule : Module() {
484
526
  OfflineMapStatus.EXCEPTION_NETWORK_LOADING -> "downloading" // 网络问题,可继续
485
527
  OfflineMapStatus.EXCEPTION_AMAP -> "failed" // 认证异常
486
528
  OfflineMapStatus.EXCEPTION_SDCARD -> "failed" // SD卡异常
487
- OfflineMapStatus.START_DOWNLOAD_FAILD -> "failed" // 开始下载失败
529
+ startDownloadFailedCode -> "failed" // 兼容两种拼写的开始下载失败
488
530
  OfflineMapStatus.CHECKUPDATES -> "not_downloaded"
489
531
  OfflineMapStatus.NEW_VERSION -> "not_downloaded"
490
532
  else -> "not_downloaded"
@@ -89,6 +89,44 @@ object GeometryUtils {
89
89
  precision: Int
90
90
  ): String
91
91
 
92
+ private external fun nativeLatLngToTile(
93
+ lat: Double,
94
+ lon: Double,
95
+ zoom: Int
96
+ ): IntArray
97
+
98
+ private external fun nativeTileToLatLng(
99
+ x: Int,
100
+ y: Int,
101
+ zoom: Int
102
+ ): DoubleArray
103
+
104
+ private external fun nativeLatLngToPixel(
105
+ lat: Double,
106
+ lon: Double,
107
+ zoom: Int
108
+ ): DoubleArray
109
+
110
+ private external fun nativePixelToLatLng(
111
+ x: Double,
112
+ y: Double,
113
+ zoom: Int
114
+ ): DoubleArray
115
+
116
+ private external fun nativeFindPointInPolygons(
117
+ pointLat: Double,
118
+ pointLon: Double,
119
+ polygons: Array<DoubleArray>,
120
+ polygonsLon: Array<DoubleArray>
121
+ ): Int
122
+
123
+ private external fun nativeGenerateHeatmapGrid(
124
+ latitudes: DoubleArray,
125
+ longitudes: DoubleArray,
126
+ weights: DoubleArray,
127
+ gridSizeMeters: Double
128
+ ): DoubleArray
129
+
92
130
  /**
93
131
  * 判断点是否在圆内
94
132
  * @param point 要判断的点
@@ -396,4 +434,82 @@ object GeometryUtils {
396
434
  private external fun nativeParsePolyline(
397
435
  polylineStr: String
398
436
  ): DoubleArray?
437
+
438
+ fun latLngToTile(latLng: LatLng, zoom: Int): IntArray? {
439
+ return try {
440
+ nativeLatLngToTile(latLng.latitude, latLng.longitude, zoom)
441
+ } catch (_: Throwable) {
442
+ null
443
+ }
444
+ }
445
+
446
+ fun tileToLatLng(x: Int, y: Int, zoom: Int): LatLng? {
447
+ return try {
448
+ val result = nativeTileToLatLng(x, y, zoom)
449
+ if (result != null && result.size >= 2) {
450
+ LatLng(result[0], result[1])
451
+ } else {
452
+ null
453
+ }
454
+ } catch (_: Throwable) {
455
+ null
456
+ }
457
+ }
458
+
459
+ fun latLngToPixel(latLng: LatLng, zoom: Int): DoubleArray? {
460
+ return try {
461
+ nativeLatLngToPixel(latLng.latitude, latLng.longitude, zoom)
462
+ } catch (_: Throwable) {
463
+ null
464
+ }
465
+ }
466
+
467
+ fun pixelToLatLng(x: Double, y: Double, zoom: Int): LatLng? {
468
+ return try {
469
+ val result = nativePixelToLatLng(x, y, zoom)
470
+ if (result != null && result.size >= 2) {
471
+ LatLng(result[0], result[1])
472
+ } else {
473
+ null
474
+ }
475
+ } catch (_: Throwable) {
476
+ null
477
+ }
478
+ }
479
+
480
+ fun findPointInPolygons(point: LatLng, polygons: List<List<LatLng>>): Int {
481
+ if (polygons.isEmpty()) return -1
482
+ return try {
483
+ val polygonsLat = Array(polygons.size) { i ->
484
+ DoubleArray(polygons[i].size) { j -> polygons[i][j].latitude }
485
+ }
486
+ val polygonsLon = Array(polygons.size) { i ->
487
+ DoubleArray(polygons[i].size) { j -> polygons[i][j].longitude }
488
+ }
489
+ nativeFindPointInPolygons(point.latitude, point.longitude, polygonsLat, polygonsLon)
490
+ } catch (_: Throwable) {
491
+ -1
492
+ }
493
+ }
494
+
495
+ data class HeatmapGridCell(val latitude: Double, val longitude: Double, val intensity: Double)
496
+
497
+ fun generateHeatmapGrid(
498
+ latitudes: DoubleArray,
499
+ longitudes: DoubleArray,
500
+ weights: DoubleArray,
501
+ gridSizeMeters: Double
502
+ ): List<HeatmapGridCell> {
503
+ if (latitudes.isEmpty() || latitudes.size != longitudes.size || latitudes.size != weights.size) return emptyList()
504
+ return try {
505
+ val result = nativeGenerateHeatmapGrid(latitudes, longitudes, weights, gridSizeMeters)
506
+ val cells = mutableListOf<HeatmapGridCell>()
507
+ for (i in result.indices step 3) {
508
+ cells.add(HeatmapGridCell(result[i], result[i+1], result[i+2]))
509
+ }
510
+ cells
511
+ } catch (_: Throwable) {
512
+ emptyList()
513
+ }
514
+ }
399
515
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAwhBnE;;EAEE;AACF,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED;;EAEE;AACF,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;wBAE0D,kBAAkB;AAA7E,wBAA8E"}
1
+ {"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAoB,MAAM,sBAAsB,CAAC;AAopBnE;;EAEE;AACF,wBAAgB,YAAY,IAAI,SAAS,GAAG,IAAI,CAE/C;AAED;;EAEE;AACF,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;wBAE0D,kBAAkB;AAA7E,wBAA8E"}