expo-gaode-map-navigation 1.1.5 → 1.1.7

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 (146) hide show
  1. package/README.md +213 -73
  2. package/android/build.gradle +10 -0
  3. package/android/src/main/cpp/CMakeLists.txt +24 -0
  4. package/android/src/main/cpp/cluster_jni.cpp +848 -0
  5. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +616 -92
  6. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapOfflineModule.kt +493 -0
  7. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +230 -14
  8. package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapViewModule.kt +37 -27
  9. package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +494 -0
  10. package/android/src/main/java/expo/modules/gaodemap/map/companion/BitmapDescriptorCache.kt +30 -0
  11. package/android/src/main/java/expo/modules/gaodemap/map/companion/IconBitmapCache.kt +37 -0
  12. package/android/src/main/java/expo/modules/gaodemap/map/managers/UIManager.kt +76 -0
  13. package/android/src/main/java/expo/modules/gaodemap/map/modules/LocationManager.kt +15 -3
  14. package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +4 -59
  15. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleView.kt +9 -12
  16. package/android/src/main/java/expo/modules/gaodemap/map/overlays/CircleViewModule.kt +5 -6
  17. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterView.kt +539 -66
  18. package/android/src/main/java/expo/modules/gaodemap/map/overlays/ClusterViewModule.kt +17 -1
  19. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapView.kt +165 -33
  20. package/android/src/main/java/expo/modules/gaodemap/map/overlays/HeatMapViewModule.kt +15 -3
  21. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerView.kt +1249 -672
  22. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MarkerViewModule.kt +40 -17
  23. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointView.kt +177 -22
  24. package/android/src/main/java/expo/modules/gaodemap/map/overlays/MultiPointViewModule.kt +11 -3
  25. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonView.kt +57 -14
  26. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolygonViewModule.kt +9 -5
  27. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineView.kt +90 -63
  28. package/android/src/main/java/expo/modules/gaodemap/map/overlays/PolylineViewModule.kt +7 -3
  29. package/android/src/main/java/expo/modules/gaodemap/map/services/LocationForegroundService.kt +3 -2
  30. package/android/src/main/java/expo/modules/gaodemap/map/utils/BitmapDescriptorCache.kt +20 -0
  31. package/android/src/main/java/expo/modules/gaodemap/map/utils/ClusterNative.kt +13 -0
  32. package/android/src/main/java/expo/modules/gaodemap/map/utils/ColorParser.kt +20 -0
  33. package/android/src/main/java/expo/modules/gaodemap/map/utils/GeometryUtils.kt +515 -0
  34. package/android/src/main/java/expo/modules/gaodemap/map/utils/LatLngParser.kt +91 -0
  35. package/android/src/main/java/expo/modules/gaodemap/map/utils/PermissionHelper.kt +248 -0
  36. package/build/ExpoGaodeMapNaviView.d.ts +7 -7
  37. package/build/ExpoGaodeMapNaviView.js +10 -11
  38. package/build/ExpoGaodeMapNavigationModule.d.ts +2 -1
  39. package/build/index.d.ts +35 -33
  40. package/build/index.js +70 -106
  41. package/build/map/ExpoGaodeMapModule.d.ts +2 -201
  42. package/build/map/ExpoGaodeMapModule.js +586 -18
  43. package/build/map/ExpoGaodeMapOfflineModule.d.ts +139 -0
  44. package/build/map/ExpoGaodeMapOfflineModule.js +8 -0
  45. package/build/map/ExpoGaodeMapView.js +66 -58
  46. package/build/map/components/FoldableMapView.d.ts +38 -0
  47. package/build/map/components/FoldableMapView.js +209 -0
  48. package/build/map/components/MapContext.d.ts +12 -0
  49. package/build/map/components/MapContext.js +54 -0
  50. package/build/map/components/MapUI.d.ts +18 -0
  51. package/build/map/components/MapUI.js +29 -0
  52. package/build/map/components/overlays/Circle.js +34 -3
  53. package/build/map/components/overlays/Cluster.d.ts +3 -1
  54. package/build/map/components/overlays/Cluster.js +31 -2
  55. package/build/map/components/overlays/HeatMap.d.ts +3 -1
  56. package/build/map/components/overlays/HeatMap.js +33 -3
  57. package/build/map/components/overlays/Marker.d.ts +1 -1
  58. package/build/map/components/overlays/Marker.js +37 -32
  59. package/build/map/components/overlays/MultiPoint.js +1 -1
  60. package/build/map/components/overlays/Polygon.js +30 -3
  61. package/build/map/components/overlays/Polyline.js +36 -3
  62. package/build/map/index.d.ts +25 -5
  63. package/build/map/index.js +59 -18
  64. package/build/map/types/common.types.d.ts +40 -0
  65. package/build/map/types/common.types.js +0 -4
  66. package/build/map/types/index.d.ts +3 -2
  67. package/build/map/types/map-view.types.d.ts +108 -3
  68. package/build/map/types/native-module.types.d.ts +363 -0
  69. package/build/map/types/native-module.types.js +5 -0
  70. package/build/map/types/offline.types.d.ts +132 -0
  71. package/build/map/types/offline.types.js +5 -0
  72. package/build/map/types/overlays.types.d.ts +137 -24
  73. package/build/map/utils/ErrorHandler.d.ts +110 -0
  74. package/build/map/utils/ErrorHandler.js +421 -0
  75. package/build/map/utils/GeoUtils.d.ts +20 -0
  76. package/build/map/utils/GeoUtils.js +76 -0
  77. package/build/map/utils/OfflineMapManager.d.ts +148 -0
  78. package/build/map/utils/OfflineMapManager.js +217 -0
  79. package/build/map/utils/PermissionUtils.d.ts +91 -0
  80. package/build/map/utils/PermissionUtils.js +255 -0
  81. package/build/map/utils/PlatformDetector.d.ts +102 -0
  82. package/build/map/utils/PlatformDetector.js +186 -0
  83. package/build/types/index.d.ts +1 -0
  84. package/build/types/index.js +1 -0
  85. package/build/types/native-module.types.d.ts +69 -0
  86. package/build/types/native-module.types.js +2 -0
  87. package/build/types/naviview.types.d.ts +1 -1
  88. package/expo-module.config.json +12 -10
  89. package/ios/ExpoGaodeMapNavigation.podspec +9 -0
  90. package/ios/map/ExpoGaodeMapModule.swift +485 -75
  91. package/ios/map/ExpoGaodeMapOfflineModule.swift +479 -0
  92. package/ios/map/ExpoGaodeMapView.swift +611 -62
  93. package/ios/map/ExpoGaodeMapViewModule.swift +48 -26
  94. package/ios/map/MapPreloadManager.swift +348 -0
  95. package/ios/map/cpp/ClusterEngine.cpp +110 -0
  96. package/ios/map/cpp/ClusterEngine.hpp +20 -0
  97. package/ios/map/cpp/ColorParser.cpp +135 -0
  98. package/ios/map/cpp/ColorParser.hpp +14 -0
  99. package/ios/map/cpp/GeometryEngine.cpp +574 -0
  100. package/ios/map/cpp/GeometryEngine.hpp +159 -0
  101. package/ios/map/cpp/QuadTree.cpp +92 -0
  102. package/ios/map/cpp/QuadTree.hpp +42 -0
  103. package/ios/map/cpp/README.md +55 -0
  104. package/ios/map/managers/UIManager.swift +72 -1
  105. package/ios/map/modules/LocationManager.swift +123 -166
  106. package/ios/map/overlays/CircleView.swift +16 -32
  107. package/ios/map/overlays/CircleViewModule.swift +12 -12
  108. package/ios/map/overlays/ClusterAnnotation.swift +32 -0
  109. package/ios/map/overlays/ClusterView.swift +331 -45
  110. package/ios/map/overlays/ClusterViewModule.swift +20 -6
  111. package/ios/map/overlays/HeatMapView.swift +135 -32
  112. package/ios/map/overlays/HeatMapViewModule.swift +20 -8
  113. package/ios/map/overlays/MarkerView.swift +613 -130
  114. package/ios/map/overlays/MarkerViewModule.swift +38 -18
  115. package/ios/map/overlays/MultiPointView.swift +168 -10
  116. package/ios/map/overlays/MultiPointViewModule.swift +27 -5
  117. package/ios/map/overlays/PolygonView.swift +62 -23
  118. package/ios/map/overlays/PolygonViewModule.swift +18 -12
  119. package/ios/map/overlays/PolylineView.swift +21 -13
  120. package/ios/map/overlays/PolylineViewModule.swift +18 -12
  121. package/ios/map/utils/ClusterNative.h +96 -0
  122. package/ios/map/utils/ClusterNative.mm +377 -0
  123. package/ios/map/utils/ColorParser.swift +12 -1
  124. package/ios/map/utils/CppBridging.mm +13 -0
  125. package/ios/map/utils/GeometryUtils.swift +34 -0
  126. package/ios/map/utils/LatLngParser.swift +87 -0
  127. package/ios/map/utils/PermissionManager.swift +135 -6
  128. package/package.json +3 -2
  129. package/shared/cpp/ClusterEngine.cpp +110 -0
  130. package/shared/cpp/ClusterEngine.hpp +20 -0
  131. package/shared/cpp/ColorParser.cpp +135 -0
  132. package/shared/cpp/ColorParser.hpp +14 -0
  133. package/shared/cpp/GeometryEngine.cpp +574 -0
  134. package/shared/cpp/GeometryEngine.hpp +159 -0
  135. package/shared/cpp/QuadTree.cpp +92 -0
  136. package/shared/cpp/QuadTree.hpp +42 -0
  137. package/shared/cpp/README.md +55 -0
  138. package/shared/cpp/tests/benchmark_js.js +41 -0
  139. package/shared/cpp/tests/run.sh +17 -0
  140. package/shared/cpp/tests/test_main.cpp +276 -0
  141. package/build/map/ExpoGaodeMap.types.d.ts +0 -41
  142. package/build/map/ExpoGaodeMap.types.js +0 -24
  143. package/build/map/utils/EventManager.d.ts +0 -10
  144. package/build/map/utils/EventManager.js +0 -26
  145. package/build/map/utils/ModuleLoader.d.ts +0 -73
  146. package/build/map/utils/ModuleLoader.js +0 -112
@@ -0,0 +1,848 @@
1
+ #if __has_include(<jni.h>)
2
+ #include <jni.h>
3
+ #define GAODE_HAVE_JNI 1
4
+ #else
5
+ #define GAODE_HAVE_JNI 0
6
+ typedef void JNIEnv;
7
+ typedef void* jclass;
8
+ typedef void* jdoubleArray;
9
+ typedef void* jintArray;
10
+ typedef void* jstring;
11
+ typedef double jdouble;
12
+ typedef int jint;
13
+ typedef int jsize;
14
+ typedef void* jobjectArray;
15
+ typedef unsigned char jboolean;
16
+ #ifndef JNI_TRUE
17
+ #define JNI_TRUE 1
18
+ #endif
19
+ #ifndef JNI_FALSE
20
+ #define JNI_FALSE 0
21
+ #endif
22
+ #define JNIEXPORT
23
+ #define JNICALL
24
+ #endif
25
+
26
+ #include <vector>
27
+ #include <string>
28
+
29
+ #include "../../../../shared/cpp/ClusterEngine.hpp"
30
+ #include "../../../../shared/cpp/GeometryEngine.hpp"
31
+ #include "../../../../shared/cpp/ColorParser.hpp"
32
+
33
+ extern "C" JNIEXPORT jintArray JNICALL
34
+ Java_expo_modules_gaodemap_map_utils_ClusterNative_clusterPoints(
35
+ JNIEnv* env,
36
+ jclass,
37
+ jdoubleArray latitudes,
38
+ jdoubleArray longitudes,
39
+ jdouble radiusMeters
40
+ ) {
41
+ #if GAODE_HAVE_JNI
42
+ if (!latitudes || !longitudes) {
43
+ jintArray empty = env->NewIntArray(1);
44
+ jint zero = 0;
45
+ env->SetIntArrayRegion(empty, 0, 1, &zero);
46
+ return empty;
47
+ }
48
+
49
+ const jsize countLat = env->GetArrayLength(latitudes);
50
+ const jsize countLon = env->GetArrayLength(longitudes);
51
+ if (countLat == 0 || countLat != countLon) {
52
+ jintArray empty = env->NewIntArray(1);
53
+ jint zero = 0;
54
+ env->SetIntArrayRegion(empty, 0, 1, &zero);
55
+ return empty;
56
+ }
57
+
58
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
59
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
60
+
61
+ std::vector<gaodemap::ClusterPoint> points;
62
+ points.reserve(static_cast<size_t>(countLat));
63
+
64
+ for (jsize i = 0; i < countLat; ++i) {
65
+ gaodemap::ClusterPoint point;
66
+ point.lat = latValues[i];
67
+ point.lon = lonValues[i];
68
+ point.index = static_cast<int>(i);
69
+ points.push_back(point);
70
+ }
71
+
72
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
73
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
74
+
75
+ const auto clusters = gaodemap::clusterPoints(points, static_cast<double>(radiusMeters));
76
+
77
+ size_t totalSize = 1;
78
+ for (const auto& cluster : clusters) {
79
+ totalSize += 2 + cluster.indices.size();
80
+ }
81
+
82
+ std::vector<jint> result;
83
+ result.reserve(totalSize);
84
+ result.push_back(static_cast<jint>(clusters.size()));
85
+
86
+ for (const auto& cluster : clusters) {
87
+ result.push_back(static_cast<jint>(cluster.centerIndex));
88
+ result.push_back(static_cast<jint>(cluster.indices.size()));
89
+ for (int idx : cluster.indices) {
90
+ result.push_back(static_cast<jint>(idx));
91
+ }
92
+ }
93
+
94
+ jintArray array = env->NewIntArray(static_cast<jsize>(result.size()));
95
+ env->SetIntArrayRegion(array, 0, static_cast<jsize>(result.size()), result.data());
96
+ return array;
97
+ #else
98
+ (void)env;
99
+ (void)latitudes;
100
+ (void)longitudes;
101
+ (void)radiusMeters;
102
+ return nullptr;
103
+ #endif
104
+ }
105
+
106
+ extern "C" JNIEXPORT jdoubleArray JNICALL
107
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeGetNearestPointOnPath(
108
+ JNIEnv* env,
109
+ jclass,
110
+ jdoubleArray latitudes,
111
+ jdoubleArray longitudes,
112
+ jdouble targetLat,
113
+ jdouble targetLon
114
+ ) {
115
+ #if GAODE_HAVE_JNI
116
+ if (!latitudes || !longitudes) {
117
+ return nullptr;
118
+ }
119
+
120
+ const jsize countLat = env->GetArrayLength(latitudes);
121
+ const jsize countLon = env->GetArrayLength(longitudes);
122
+ if (countLat < 2 || countLat != countLon) {
123
+ return nullptr;
124
+ }
125
+
126
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
127
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
128
+
129
+ std::vector<gaodemap::GeoPoint> points;
130
+ points.reserve(static_cast<size_t>(countLat));
131
+
132
+ for (jsize i = 0; i < countLat; ++i) {
133
+ points.push_back({latValues[i], lonValues[i]});
134
+ }
135
+
136
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
137
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
138
+
139
+ gaodemap::GeoPoint target = {static_cast<double>(targetLat), static_cast<double>(targetLon)};
140
+ gaodemap::NearestPointResult result = gaodemap::getNearestPointOnPath(points, target);
141
+
142
+ jdoubleArray resultArray = env->NewDoubleArray(4);
143
+ if (resultArray == nullptr) return nullptr;
144
+
145
+ jdouble buffer[4] = {result.latitude, result.longitude, static_cast<jdouble>(result.index), result.distanceMeters};
146
+ env->SetDoubleArrayRegion(resultArray, 0, 4, buffer);
147
+ return resultArray;
148
+ #else
149
+ (void)env;
150
+ (void)latitudes;
151
+ (void)longitudes;
152
+ (void)targetLat;
153
+ (void)targetLon;
154
+ return nullptr;
155
+ #endif
156
+ }
157
+
158
+ extern "C" JNIEXPORT jboolean JNICALL
159
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeIsPointInCircle(
160
+ JNIEnv* env,
161
+ jclass,
162
+ jdouble pointLat,
163
+ jdouble pointLon,
164
+ jdouble centerLat,
165
+ jdouble centerLon,
166
+ jdouble radiusMeters
167
+ ) {
168
+ #if GAODE_HAVE_JNI
169
+ (void)env;
170
+ return gaodemap::isPointInCircle(
171
+ static_cast<double>(pointLat),
172
+ static_cast<double>(pointLon),
173
+ static_cast<double>(centerLat),
174
+ static_cast<double>(centerLon),
175
+ static_cast<double>(radiusMeters)
176
+ ) ? JNI_TRUE : JNI_FALSE;
177
+ #else
178
+ (void)env;
179
+ (void)pointLat;
180
+ (void)pointLon;
181
+ (void)centerLat;
182
+ (void)centerLon;
183
+ (void)radiusMeters;
184
+ return JNI_FALSE;
185
+ #endif
186
+ }
187
+
188
+ extern "C" JNIEXPORT jboolean JNICALL
189
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeIsPointInPolygon(
190
+ JNIEnv* env,
191
+ jclass,
192
+ jdouble pointLat,
193
+ jdouble pointLon,
194
+ jdoubleArray latitudes,
195
+ jdoubleArray longitudes
196
+ ) {
197
+ #if GAODE_HAVE_JNI
198
+ if (!latitudes || !longitudes) {
199
+ return JNI_FALSE;
200
+ }
201
+
202
+ const jsize countLat = env->GetArrayLength(latitudes);
203
+ const jsize countLon = env->GetArrayLength(longitudes);
204
+ if (countLat < 3 || countLat != countLon) {
205
+ return JNI_FALSE;
206
+ }
207
+
208
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
209
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
210
+
211
+ std::vector<gaodemap::GeoPoint> polygon;
212
+ polygon.reserve(static_cast<size_t>(countLat));
213
+
214
+ for (jsize i = 0; i < countLat; ++i) {
215
+ polygon.push_back({latValues[i], lonValues[i]});
216
+ }
217
+
218
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
219
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
220
+
221
+ return gaodemap::isPointInPolygon(
222
+ static_cast<double>(pointLat),
223
+ static_cast<double>(pointLon),
224
+ polygon
225
+ ) ? JNI_TRUE : JNI_FALSE;
226
+ #else
227
+ (void)env;
228
+ (void)pointLat;
229
+ (void)pointLon;
230
+ (void)latitudes;
231
+ (void)longitudes;
232
+ return JNI_FALSE;
233
+ #endif
234
+ }
235
+
236
+ extern "C" JNIEXPORT jint JNICALL
237
+ Java_expo_modules_gaodemap_map_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
+
285
+ extern "C" JNIEXPORT jdouble JNICALL
286
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculatePolygonArea(
287
+ JNIEnv* env,
288
+ jclass,
289
+ jdoubleArray latitudes,
290
+ jdoubleArray longitudes
291
+ ) {
292
+ #if GAODE_HAVE_JNI
293
+ if (!latitudes || !longitudes) {
294
+ return 0.0;
295
+ }
296
+
297
+ const jsize countLat = env->GetArrayLength(latitudes);
298
+ const jsize countLon = env->GetArrayLength(longitudes);
299
+ if (countLat < 3 || countLat != countLon) {
300
+ return 0.0;
301
+ }
302
+
303
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
304
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
305
+
306
+ std::vector<gaodemap::GeoPoint> polygon;
307
+ polygon.reserve(static_cast<size_t>(countLat));
308
+
309
+ for (jsize i = 0; i < countLat; ++i) {
310
+ polygon.push_back({latValues[i], lonValues[i]});
311
+ }
312
+
313
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
314
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
315
+
316
+ return static_cast<jdouble>(gaodemap::calculatePolygonArea(polygon));
317
+ #else
318
+ (void)env;
319
+ (void)latitudes;
320
+ (void)longitudes;
321
+ return 0.0;
322
+ #endif
323
+ }
324
+
325
+ extern "C" JNIEXPORT jdouble JNICALL
326
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculateRectangleArea(
327
+ JNIEnv* env,
328
+ jclass,
329
+ jdouble swLat,
330
+ jdouble swLon,
331
+ jdouble neLat,
332
+ jdouble neLon
333
+ ) {
334
+ #if GAODE_HAVE_JNI
335
+ (void)env;
336
+ return static_cast<jdouble>(gaodemap::calculateRectangleArea(
337
+ static_cast<double>(swLat),
338
+ static_cast<double>(swLon),
339
+ static_cast<double>(neLat),
340
+ static_cast<double>(neLon)
341
+ ));
342
+ #else
343
+ (void)env;
344
+ (void)swLat;
345
+ (void)swLon;
346
+ (void)neLat;
347
+ (void)neLon;
348
+ return 0.0;
349
+ #endif
350
+ }
351
+
352
+ extern "C" JNIEXPORT jdouble JNICALL
353
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculateDistance(
354
+ JNIEnv* env,
355
+ jclass,
356
+ jdouble lat1,
357
+ jdouble lon1,
358
+ jdouble lat2,
359
+ jdouble lon2
360
+ ) {
361
+ #if GAODE_HAVE_JNI
362
+ (void)env;
363
+ return static_cast<jdouble>(gaodemap::calculateDistance(
364
+ static_cast<double>(lat1),
365
+ static_cast<double>(lon1),
366
+ static_cast<double>(lat2),
367
+ static_cast<double>(lon2)
368
+ ));
369
+ #else
370
+ (void)env;
371
+ (void)lat1;
372
+ (void)lon1;
373
+ (void)lat2;
374
+ (void)lon2;
375
+ return 0.0;
376
+ #endif
377
+ }
378
+
379
+ extern "C" JNIEXPORT jint JNICALL
380
+ Java_expo_modules_gaodemap_map_utils_ColorParser_nativeParseColor(
381
+ JNIEnv* env,
382
+ jclass,
383
+ jstring colorString
384
+ ) {
385
+ #if GAODE_HAVE_JNI
386
+ if (!colorString) {
387
+ return 0; // Black or 0
388
+ }
389
+ const char* nativeString = env->GetStringUTFChars(colorString, nullptr);
390
+ if (!nativeString) {
391
+ return 0;
392
+ }
393
+ std::string str(nativeString);
394
+ env->ReleaseStringUTFChars(colorString, nativeString);
395
+
396
+ return static_cast<jint>(gaodemap::parseColor(str));
397
+ #else
398
+ (void)env;
399
+ (void)colorString;
400
+ return 0;
401
+ #endif
402
+ }
403
+
404
+ extern "C" JNIEXPORT jdoubleArray JNICALL
405
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeSimplifyPolyline(
406
+ JNIEnv* env,
407
+ jclass,
408
+ jdoubleArray latitudes,
409
+ jdoubleArray longitudes,
410
+ jdouble toleranceMeters
411
+ ) {
412
+ #if GAODE_HAVE_JNI
413
+ if (!latitudes || !longitudes) {
414
+ return env->NewDoubleArray(0);
415
+ }
416
+
417
+ const jsize countLat = env->GetArrayLength(latitudes);
418
+ const jsize countLon = env->GetArrayLength(longitudes);
419
+ if (countLat != countLon) {
420
+ return env->NewDoubleArray(0);
421
+ }
422
+
423
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
424
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
425
+
426
+ std::vector<gaodemap::GeoPoint> points;
427
+ points.reserve(static_cast<size_t>(countLat));
428
+
429
+ for (jsize i = 0; i < countLat; ++i) {
430
+ points.push_back({latValues[i], lonValues[i]});
431
+ }
432
+
433
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
434
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
435
+
436
+ const auto simplified = gaodemap::simplifyPolyline(points, static_cast<double>(toleranceMeters));
437
+
438
+ jdoubleArray result = env->NewDoubleArray(static_cast<jsize>(simplified.size() * 2));
439
+ if (result == nullptr) {
440
+ return nullptr;
441
+ }
442
+
443
+ std::vector<jdouble> resultBuffer;
444
+ resultBuffer.reserve(simplified.size() * 2);
445
+ for (const auto& p : simplified) {
446
+ resultBuffer.push_back(p.lat);
447
+ resultBuffer.push_back(p.lon);
448
+ }
449
+
450
+ env->SetDoubleArrayRegion(result, 0, static_cast<jsize>(resultBuffer.size()), resultBuffer.data());
451
+ return result;
452
+ #else
453
+ (void)env;
454
+ (void)latitudes;
455
+ (void)longitudes;
456
+ (void)toleranceMeters;
457
+ return nullptr;
458
+ #endif
459
+ }
460
+
461
+ extern "C" JNIEXPORT jdouble JNICALL
462
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculatePathLength(
463
+ JNIEnv* env,
464
+ jclass,
465
+ jdoubleArray latitudes,
466
+ jdoubleArray longitudes
467
+ ) {
468
+ #if GAODE_HAVE_JNI
469
+ if (!latitudes || !longitudes) {
470
+ return 0.0;
471
+ }
472
+
473
+ const jsize countLat = env->GetArrayLength(latitudes);
474
+ const jsize countLon = env->GetArrayLength(longitudes);
475
+ if (countLat < 2 || countLat != countLon) {
476
+ return 0.0;
477
+ }
478
+
479
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
480
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
481
+
482
+ std::vector<gaodemap::GeoPoint> points;
483
+ points.reserve(static_cast<size_t>(countLat));
484
+
485
+ for (jsize i = 0; i < countLat; ++i) {
486
+ points.push_back({latValues[i], lonValues[i]});
487
+ }
488
+
489
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
490
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
491
+
492
+ return static_cast<jdouble>(gaodemap::calculatePathLength(points));
493
+ #else
494
+ (void)env;
495
+ (void)latitudes;
496
+ (void)longitudes;
497
+ return 0.0;
498
+ #endif
499
+ }
500
+
501
+ extern "C" JNIEXPORT jdoubleArray JNICALL
502
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeGetPointAtDistance(
503
+ JNIEnv* env,
504
+ jclass,
505
+ jdoubleArray latitudes,
506
+ jdoubleArray longitudes,
507
+ jdouble distanceMeters
508
+ ) {
509
+ #if GAODE_HAVE_JNI
510
+ if (!latitudes || !longitudes) {
511
+ return nullptr;
512
+ }
513
+
514
+ const jsize countLat = env->GetArrayLength(latitudes);
515
+ const jsize countLon = env->GetArrayLength(longitudes);
516
+ if (countLat < 2 || countLat != countLon) {
517
+ return nullptr;
518
+ }
519
+
520
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
521
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
522
+
523
+ std::vector<gaodemap::GeoPoint> points;
524
+ points.reserve(static_cast<size_t>(countLat));
525
+
526
+ for (jsize i = 0; i < countLat; ++i) {
527
+ points.push_back({latValues[i], lonValues[i]});
528
+ }
529
+
530
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
531
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
532
+
533
+ double outLat, outLon, outAngle;
534
+ bool success = gaodemap::getPointAtDistance(points, static_cast<double>(distanceMeters), &outLat, &outLon, &outAngle);
535
+
536
+ if (success) {
537
+ jdoubleArray result = env->NewDoubleArray(3);
538
+ if (result == nullptr) return nullptr;
539
+
540
+ jdouble buffer[3] = {outLat, outLon, outAngle};
541
+ env->SetDoubleArrayRegion(result, 0, 3, buffer);
542
+ return result;
543
+ } else {
544
+ return nullptr;
545
+ }
546
+ #else
547
+ (void)env;
548
+ (void)latitudes;
549
+ (void)longitudes;
550
+ (void)distanceMeters;
551
+ return nullptr;
552
+ #endif
553
+ }
554
+
555
+ extern "C" JNIEXPORT jdoubleArray JNICALL
556
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculatePathBounds(
557
+ JNIEnv* env,
558
+ jclass,
559
+ jdoubleArray latitudes,
560
+ jdoubleArray longitudes
561
+ ) {
562
+ #if GAODE_HAVE_JNI
563
+ if (!latitudes || !longitudes) {
564
+ return nullptr;
565
+ }
566
+
567
+ const jsize countLat = env->GetArrayLength(latitudes);
568
+ const jsize countLon = env->GetArrayLength(longitudes);
569
+ if (countLat == 0 || countLat != countLon) {
570
+ return nullptr;
571
+ }
572
+
573
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
574
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
575
+
576
+ std::vector<gaodemap::GeoPoint> points;
577
+ points.reserve(static_cast<size_t>(countLat));
578
+
579
+ for (jsize i = 0; i < countLat; ++i) {
580
+ points.push_back({latValues[i], lonValues[i]});
581
+ }
582
+
583
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
584
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
585
+
586
+ gaodemap::PathBounds bounds = gaodemap::calculatePathBounds(points);
587
+
588
+ jdoubleArray resultArray = env->NewDoubleArray(6);
589
+ if (resultArray == nullptr) return nullptr;
590
+
591
+ jdouble buffer[6] = {
592
+ bounds.north,
593
+ bounds.south,
594
+ bounds.east,
595
+ bounds.west,
596
+ bounds.centerLat,
597
+ bounds.centerLon
598
+ };
599
+ env->SetDoubleArrayRegion(resultArray, 0, 6, buffer);
600
+ return resultArray;
601
+ #else
602
+ (void)env;
603
+ (void)latitudes;
604
+ (void)longitudes;
605
+ return nullptr;
606
+ #endif
607
+ }
608
+
609
+ extern "C" JNIEXPORT jdoubleArray JNICALL
610
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeCalculateCentroid(
611
+ JNIEnv* env,
612
+ jclass,
613
+ jdoubleArray latitudes,
614
+ jdoubleArray longitudes
615
+ ) {
616
+ #if GAODE_HAVE_JNI
617
+ if (!latitudes || !longitudes) {
618
+ return nullptr;
619
+ }
620
+
621
+ const jsize countLat = env->GetArrayLength(latitudes);
622
+ const jsize countLon = env->GetArrayLength(longitudes);
623
+ if (countLat < 3 || countLat != countLon) {
624
+ return nullptr;
625
+ }
626
+
627
+ jdouble* latValues = env->GetDoubleArrayElements(latitudes, nullptr);
628
+ jdouble* lonValues = env->GetDoubleArrayElements(longitudes, nullptr);
629
+
630
+ std::vector<gaodemap::GeoPoint> polygon;
631
+ polygon.reserve(static_cast<size_t>(countLat));
632
+
633
+ for (jsize i = 0; i < countLat; ++i) {
634
+ polygon.push_back({latValues[i], lonValues[i]});
635
+ }
636
+
637
+ env->ReleaseDoubleArrayElements(latitudes, latValues, JNI_ABORT);
638
+ env->ReleaseDoubleArrayElements(longitudes, lonValues, JNI_ABORT);
639
+
640
+ gaodemap::GeoPoint centroid = gaodemap::calculateCentroid(polygon);
641
+
642
+ jdoubleArray result = env->NewDoubleArray(2);
643
+ if (result == nullptr) return nullptr;
644
+
645
+ jdouble buffer[2] = {centroid.lat, centroid.lon};
646
+ env->SetDoubleArrayRegion(result, 0, 2, buffer);
647
+ return result;
648
+ #else
649
+ (void)env;
650
+ (void)latitudes;
651
+ (void)longitudes;
652
+ return nullptr;
653
+ #endif
654
+ }
655
+
656
+ extern "C" JNIEXPORT jstring JNICALL
657
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeEncodeGeoHash(
658
+ JNIEnv* env,
659
+ jclass,
660
+ jdouble lat,
661
+ jdouble lon,
662
+ jint precision
663
+ ) {
664
+ #if GAODE_HAVE_JNI
665
+ std::string hash = gaodemap::encodeGeoHash(
666
+ static_cast<double>(lat),
667
+ static_cast<double>(lon),
668
+ static_cast<int>(precision)
669
+ );
670
+ return env->NewStringUTF(hash.c_str());
671
+ #else
672
+ (void)env;
673
+ (void)lat;
674
+ (void)lon;
675
+ (void)precision;
676
+ return nullptr;
677
+ #endif
678
+ }
679
+
680
+ extern "C" JNIEXPORT jdoubleArray JNICALL
681
+ Java_expo_modules_gaodemap_map_utils_GeometryUtils_nativeParsePolyline(
682
+ JNIEnv* env,
683
+ jclass,
684
+ jstring polylineStr
685
+ ) {
686
+ #if GAODE_HAVE_JNI
687
+ if (!polylineStr) {
688
+ return nullptr;
689
+ }
690
+
691
+ const char* nativeString = env->GetStringUTFChars(polylineStr, nullptr);
692
+ if (!nativeString) return nullptr;
693
+
694
+ std::string cppPolylineStr(nativeString);
695
+ env->ReleaseStringUTFChars(polylineStr, nativeString);
696
+
697
+ std::vector<gaodemap::GeoPoint> points = gaodemap::parsePolyline(cppPolylineStr);
698
+
699
+ if (points.empty()) {
700
+ return env->NewDoubleArray(0);
701
+ }
702
+
703
+ jdoubleArray result = env->NewDoubleArray(static_cast<jsize>(points.size() * 2));
704
+ if (result == nullptr) return nullptr;
705
+
706
+ std::vector<double> flatBuffer;
707
+ flatBuffer.reserve(points.size() * 2);
708
+ for (const auto& p : points) {
709
+ flatBuffer.push_back(p.lat);
710
+ flatBuffer.push_back(p.lon);
711
+ }
712
+
713
+ env->SetDoubleArrayRegion(result, 0, static_cast<jsize>(flatBuffer.size()), flatBuffer.data());
714
+ return result;
715
+ #else
716
+ (void)env;
717
+ (void)polylineStr;
718
+ return nullptr;
719
+ #endif
720
+ }
721
+
722
+ extern "C" JNIEXPORT jintArray JNICALL
723
+ Java_expo_modules_gaodemap_map_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_map_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_map_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_map_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_map_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
+ }