@maydon_tech/react-native-nitro-maps 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/NitroMap.podspec +1 -1
- package/README.md +82 -9
- package/android/CMakeLists.txt +4 -1
- package/android/gradle.properties +4 -4
- package/android/src/main/cpp/ClusterEngineJNI.cpp +198 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMap.kt +397 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapConfig.kt +53 -0
- package/android/src/main/{java → kotlin}/com/margelo/nitro/nitromap/NitroMapPackage.kt +4 -4
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/NitroMapView.kt +73 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/UserLocationManager.kt +295 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusterIconRenderer.kt +111 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/ClusteringManager.kt +104 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +166 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerIconFactory.kt +303 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/MarkerSelectionHandler.kt +72 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/markers/PriceMarkerRenderer.kt +159 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderFactory.kt +24 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +128 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapDelegate.kt +317 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Clustering.kt +524 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Markers.kt +358 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+Overlays.kt +272 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider+UserLocation.kt +296 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/GoogleMapProvider.kt +815 -0
- package/android/src/main/kotlin/com/margelo/nitro/nitromap/providers/google/MarkerTagData.kt +19 -0
- package/ios/Location/NitroLocationManager.swift +116 -0
- package/ios/MarkerRenderer/MarkerIconFactory.swift +1 -3
- package/ios/MarkerRenderer/PriceMarkerRenderer.swift +10 -6
- package/ios/NitroMap.swift +279 -13
- package/ios/NitroMapConfig/NitroMapConfig.swift +45 -0
- package/ios/Providers/{GoogleMapDelegate.swift → Google/GoogleMapDelegate.swift} +48 -23
- package/ios/Providers/Google/GoogleMapProvider+Camera.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider+Clustering.swift +541 -0
- package/ios/Providers/Google/GoogleMapProvider+Markers.swift +270 -0
- package/ios/Providers/Google/GoogleMapProvider+Overlays.swift +245 -0
- package/ios/Providers/Google/GoogleMapProvider+UserLocation.swift +180 -0
- package/ios/Providers/Google/GoogleMapProvider.swift +342 -0
- package/ios/Providers/MapProviderFactory.swift +17 -0
- package/ios/Providers/MapProviderProtocol.swift +48 -1
- package/ios/Shared/ClusterConfig+Factory.swift +2 -2
- package/ios/Shared/MapStyleProvider.swift +6 -4
- package/ios/Shared/MarkerSelectionHandler.swift +4 -1
- package/ios/Utils/ColorValueExtension.swift +46 -67
- package/lib/module/components/ImageMarker.js +39 -29
- package/lib/module/components/ImageMarker.js.map +1 -1
- package/lib/module/components/Marker.js +118 -0
- package/lib/module/components/Marker.js.map +1 -0
- package/lib/module/components/NitroCircle.js +92 -0
- package/lib/module/components/NitroCircle.js.map +1 -0
- package/lib/module/components/NitroMap.js +216 -76
- package/lib/module/components/NitroMap.js.map +1 -1
- package/lib/module/components/NitroPolygon.js +135 -0
- package/lib/module/components/NitroPolygon.js.map +1 -0
- package/lib/module/components/NitroPolyline.js +115 -0
- package/lib/module/components/NitroPolyline.js.map +1 -0
- package/lib/module/components/PriceMarker.js +16 -29
- package/lib/module/components/PriceMarker.js.map +1 -1
- package/lib/module/context/NitroMapContext.js.map +1 -1
- package/lib/module/hooks/useNitroCircle.js +18 -0
- package/lib/module/hooks/useNitroCircle.js.map +1 -0
- package/lib/module/hooks/useNitroMarker.js +26 -9
- package/lib/module/hooks/useNitroMarker.js.map +1 -1
- package/lib/module/hooks/useNitroOverlay.js +59 -0
- package/lib/module/hooks/useNitroOverlay.js.map +1 -0
- package/lib/module/hooks/useNitroPolygon.js +18 -0
- package/lib/module/hooks/useNitroPolygon.js.map +1 -0
- package/lib/module/hooks/useNitroPolyline.js +18 -0
- package/lib/module/hooks/useNitroPolyline.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/overlay.js +4 -0
- package/lib/module/types/overlay.js.map +1 -0
- package/lib/module/types/theme.js +4 -0
- package/lib/module/types/theme.js.map +1 -0
- package/lib/module/utils/colors.js +41 -13
- package/lib/module/utils/colors.js.map +1 -1
- package/lib/module/utils/validation.js +45 -0
- package/lib/module/utils/validation.js.map +1 -0
- package/lib/typescript/src/components/ImageMarker.d.ts.map +1 -1
- package/lib/typescript/src/components/Marker.d.ts +34 -0
- package/lib/typescript/src/components/Marker.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroCircle.d.ts +70 -0
- package/lib/typescript/src/components/NitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroMap.d.ts +60 -3
- package/lib/typescript/src/components/NitroMap.d.ts.map +1 -1
- package/lib/typescript/src/components/NitroPolygon.d.ts +86 -0
- package/lib/typescript/src/components/NitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts +84 -0
- package/lib/typescript/src/components/NitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/components/PriceMarker.d.ts +0 -5
- package/lib/typescript/src/components/PriceMarker.d.ts.map +1 -1
- package/lib/typescript/src/context/NitroMapContext.d.ts +2 -0
- package/lib/typescript/src/context/NitroMapContext.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroCircle.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroCircle.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts +20 -0
- package/lib/typescript/src/hooks/useNitroMarker.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts +26 -0
- package/lib/typescript/src/hooks/useNitroOverlay.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolygon.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts +7 -0
- package/lib/typescript/src/hooks/useNitroPolyline.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +15 -2
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts +248 -6
- package/lib/typescript/src/specs/NitroMap.nitro.d.ts.map +1 -1
- package/lib/typescript/src/types/map.d.ts +34 -4
- package/lib/typescript/src/types/map.d.ts.map +1 -1
- package/lib/typescript/src/types/marker.d.ts +24 -36
- package/lib/typescript/src/types/marker.d.ts.map +1 -1
- package/lib/typescript/src/types/overlay.d.ts +75 -0
- package/lib/typescript/src/types/overlay.d.ts.map +1 -0
- package/lib/typescript/src/types/theme.d.ts +93 -0
- package/lib/typescript/src/types/theme.d.ts.map +1 -0
- package/lib/typescript/src/utils/colors.d.ts +6 -8
- package/lib/typescript/src/utils/colors.d.ts.map +1 -1
- package/lib/typescript/src/utils/validation.d.ts +12 -0
- package/lib/typescript/src/utils/validation.d.ts.map +1 -0
- package/nitrogen/generated/android/c++/JCircleData.hpp +94 -0
- package/nitrogen/generated/android/c++/JClusterConfig.hpp +5 -7
- package/nitrogen/generated/android/c++/JFunc_void_UserLocationChangeEvent.hpp +79 -0
- package/nitrogen/generated/android/c++/JFunc_void_UserTrackingMode.hpp +77 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +76 -0
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.cpp +328 -21
- package/nitrogen/generated/android/c++/JHybridNitroMapSpec.hpp +53 -2
- package/nitrogen/generated/android/c++/JMarkerAnimation.hpp +3 -6
- package/nitrogen/generated/android/c++/JMarkerData.hpp +15 -3
- package/nitrogen/generated/android/c++/JPolygonData.hpp +149 -0
- package/nitrogen/generated/android/c++/JPolylineData.hpp +113 -0
- package/nitrogen/generated/android/c++/JUserLocationChangeEvent.hpp +70 -0
- package/nitrogen/generated/android/c++/JUserTrackingMode.hpp +62 -0
- package/nitrogen/generated/android/c++/views/JHybridNitroMapStateUpdater.cpp +72 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/CircleData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/ClusterConfig.kt +4 -4
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserLocationChangeEvent.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_UserTrackingMode.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/Func_void_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/HybridNitroMapSpec.kt +228 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerAnimation.kt +1 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/MarkerData.kt +12 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolygonData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/PolylineData.kt +62 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/UserLocationChangeEvent.kt +47 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitromap/{ClusterAnimationStyle.kt → UserTrackingMode.kt} +6 -8
- package/nitrogen/generated/android/nitromapOnLoad.cpp +6 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.cpp +24 -0
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Bridge.hpp +175 -17
- package/nitrogen/generated/ios/NitroMap-Swift-Cxx-Umbrella.hpp +15 -3
- package/nitrogen/generated/ios/c++/HybridNitroMapSpecSwift.hpp +249 -16
- package/nitrogen/generated/ios/c++/views/HybridNitroMapComponent.mm +90 -5
- package/nitrogen/generated/ios/swift/CircleData.swift +143 -0
- package/nitrogen/generated/ios/swift/ClusterConfig.swift +22 -15
- package/nitrogen/generated/ios/swift/Func_void_UserLocationChangeEvent.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_UserTrackingMode.swift +47 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec.swift +35 -1
- package/nitrogen/generated/ios/swift/HybridNitroMapSpec_cxx.swift +582 -8
- package/nitrogen/generated/ios/swift/MarkerAnimation.swift +4 -8
- package/nitrogen/generated/ios/swift/MarkerData.swift +54 -2
- package/nitrogen/generated/ios/swift/PolygonData.swift +179 -0
- package/nitrogen/generated/ios/swift/PolylineData.swift +155 -0
- package/nitrogen/generated/ios/swift/UserLocationChangeEvent.swift +69 -0
- package/nitrogen/generated/ios/swift/UserTrackingMode.swift +44 -0
- package/nitrogen/generated/shared/c++/CircleData.hpp +113 -0
- package/nitrogen/generated/shared/c++/ClusterConfig.hpp +5 -8
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.cpp +53 -2
- package/nitrogen/generated/shared/c++/HybridNitroMapSpec.hpp +75 -6
- package/nitrogen/generated/shared/c++/MarkerAnimation.hpp +4 -8
- package/nitrogen/generated/shared/c++/MarkerData.hpp +14 -2
- package/nitrogen/generated/shared/c++/PolygonData.hpp +114 -0
- package/nitrogen/generated/shared/c++/PolylineData.hpp +114 -0
- package/nitrogen/generated/shared/c++/UserLocationChangeEvent.hpp +88 -0
- package/nitrogen/generated/shared/c++/UserTrackingMode.hpp +80 -0
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.cpp +216 -12
- package/nitrogen/generated/shared/c++/views/HybridNitroMapComponent.hpp +23 -1
- package/nitrogen/generated/shared/json/NitroMapConfig.json +18 -1
- package/package.json +36 -5
- package/src/components/ImageMarker.tsx +58 -42
- package/src/components/Marker.tsx +161 -0
- package/src/components/NitroCircle.tsx +183 -0
- package/src/components/NitroMap.tsx +328 -78
- package/src/components/NitroPolygon.tsx +229 -0
- package/src/components/NitroPolyline.tsx +208 -0
- package/src/components/PriceMarker.tsx +23 -48
- package/src/context/NitroMapContext.tsx +4 -0
- package/src/hooks/useNitroCircle.ts +25 -0
- package/src/hooks/useNitroMarker.ts +49 -10
- package/src/hooks/useNitroOverlay.ts +68 -0
- package/src/hooks/useNitroPolygon.ts +25 -0
- package/src/hooks/useNitroPolyline.ts +25 -0
- package/src/index.tsx +23 -2
- package/src/specs/NitroMap.nitro.ts +294 -5
- package/src/types/map.ts +36 -4
- package/src/types/marker.ts +24 -44
- package/src/types/overlay.ts +77 -0
- package/src/types/theme.ts +101 -0
- package/src/utils/colors.ts +48 -16
- package/src/utils/validation.ts +69 -0
- package/android/src/main/java/com/margelo/nitro/nitromap/ClusterIconGenerator.kt +0 -108
- package/android/src/main/java/com/margelo/nitro/nitromap/ColorUtils.kt +0 -63
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMap.kt +0 -408
- package/android/src/main/java/com/margelo/nitro/nitromap/HybridNitroMapConfig.kt +0 -68
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconCache.kt +0 -176
- package/android/src/main/java/com/margelo/nitro/nitromap/MarkerIconFactory.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/NitroClusterEngine.kt +0 -252
- package/android/src/main/java/com/margelo/nitro/nitromap/clustering/QuadTree.kt +0 -195
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/GoogleMapProvider.kt +0 -912
- package/android/src/main/java/com/margelo/nitro/nitromap/providers/MapProviderInterface.kt +0 -70
- package/cpp/QuadTree.hpp +0 -246
- package/ios/NitroMapConfig/HybridNitroMapConfig.swift +0 -33
- package/ios/Providers/GoogleMapProvider+Camera.swift +0 -164
- package/ios/Providers/GoogleMapProvider.swift +0 -924
- package/nitrogen/generated/android/c++/JClusterAnimationStyle.hpp +0 -68
- package/nitrogen/generated/ios/swift/ClusterAnimationStyle.swift +0 -52
- package/nitrogen/generated/shared/c++/ClusterAnimationStyle.hpp +0 -88
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package com.margelo.nitro.nitromap.providers.google
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Type-safe marker tag data. Replaces loose `Any?` tag union
|
|
5
|
+
* (String | ClusterUserData | "__user_location__") with exhaustive
|
|
6
|
+
* sealed class for compile-time safety.
|
|
7
|
+
*
|
|
8
|
+
* Set on `Marker.tag` and matched with `when` in GoogleMapDelegate.
|
|
9
|
+
*/
|
|
10
|
+
sealed class MarkerTagData {
|
|
11
|
+
/** Regular user-added marker with its ID. */
|
|
12
|
+
data class Regular(val markerId: String) : MarkerTagData()
|
|
13
|
+
|
|
14
|
+
/** Cluster icon representing multiple markers. */
|
|
15
|
+
data class Cluster(val markerIds: List<String>, val count: Int) : MarkerTagData()
|
|
16
|
+
|
|
17
|
+
/** Custom user location marker. */
|
|
18
|
+
data object UserLocation : MarkerTagData()
|
|
19
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import CoreLocation
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
/// Provider-agnostic location manager that wraps CLLocationManager.
|
|
5
|
+
/// Lives at the NitroMap facade level, not tied to any specific map SDK.
|
|
6
|
+
/// Provides location updates + compass heading for custom user location markers.
|
|
7
|
+
class NitroLocationManager: NSObject, CLLocationManagerDelegate {
|
|
8
|
+
|
|
9
|
+
// MARK: - Properties
|
|
10
|
+
|
|
11
|
+
private let locationManager = CLLocationManager()
|
|
12
|
+
private var isRunning = false
|
|
13
|
+
|
|
14
|
+
var onLocationUpdate: ((_ location: CLLocation, _ heading: CLHeading?) -> Void)?
|
|
15
|
+
|
|
16
|
+
/// Called when location services fail
|
|
17
|
+
var onLocationError: ((_ code: String, _ message: String) -> Void)?
|
|
18
|
+
|
|
19
|
+
/// Latest heading (kept for marker rotation)
|
|
20
|
+
private(set) var latestHeading: CLHeading?
|
|
21
|
+
/// Latest location
|
|
22
|
+
private(set) var latestLocation: CLLocation?
|
|
23
|
+
|
|
24
|
+
// MARK: - Init
|
|
25
|
+
|
|
26
|
+
override init() {
|
|
27
|
+
super.init()
|
|
28
|
+
locationManager.delegate = self
|
|
29
|
+
locationManager.desiredAccuracy = kCLLocationAccuracyBest
|
|
30
|
+
locationManager.distanceFilter = 1 // Update every 1 meter
|
|
31
|
+
locationManager.headingFilter = 1 // Update every 1 degree
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// MARK: - Public API
|
|
35
|
+
|
|
36
|
+
func startUpdating() {
|
|
37
|
+
guard !isRunning else { return }
|
|
38
|
+
isRunning = true
|
|
39
|
+
|
|
40
|
+
// Request permission if not yet determined
|
|
41
|
+
let status = locationManager.authorizationStatus
|
|
42
|
+
if status == .notDetermined {
|
|
43
|
+
locationManager.requestWhenInUseAuthorization()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
locationManager.startUpdatingLocation()
|
|
47
|
+
locationManager.startUpdatingHeading()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func stopUpdating() {
|
|
51
|
+
guard isRunning else { return }
|
|
52
|
+
isRunning = false
|
|
53
|
+
locationManager.stopUpdatingLocation()
|
|
54
|
+
locationManager.stopUpdatingHeading()
|
|
55
|
+
latestLocation = nil
|
|
56
|
+
latestHeading = nil
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// MARK: - CLLocationManagerDelegate
|
|
60
|
+
|
|
61
|
+
func locationManager(
|
|
62
|
+
_ manager: CLLocationManager,
|
|
63
|
+
didUpdateLocations locations: [CLLocation]
|
|
64
|
+
) {
|
|
65
|
+
guard let location = locations.last else { return }
|
|
66
|
+
latestLocation = location
|
|
67
|
+
onLocationUpdate?(location, latestHeading)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func locationManager(
|
|
71
|
+
_ manager: CLLocationManager,
|
|
72
|
+
didUpdateHeading newHeading: CLHeading
|
|
73
|
+
) {
|
|
74
|
+
latestHeading = newHeading
|
|
75
|
+
// Fire update with latest location + new heading
|
|
76
|
+
if let location = latestLocation {
|
|
77
|
+
onLocationUpdate?(location, newHeading)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func locationManager(
|
|
82
|
+
_ manager: CLLocationManager,
|
|
83
|
+
didChangeAuthorization status: CLAuthorizationStatus
|
|
84
|
+
) {
|
|
85
|
+
// If permission just granted, start updating
|
|
86
|
+
if isRunning && (status == .authorizedWhenInUse || status == .authorizedAlways) {
|
|
87
|
+
locationManager.startUpdatingLocation()
|
|
88
|
+
locationManager.startUpdatingHeading()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
func locationManager(
|
|
93
|
+
_ manager: CLLocationManager,
|
|
94
|
+
didFailWithError error: Error
|
|
95
|
+
) {
|
|
96
|
+
let code: String
|
|
97
|
+
if let clError = error as? CLError {
|
|
98
|
+
switch clError.code {
|
|
99
|
+
case .denied:
|
|
100
|
+
code = "LOCATION_PERMISSION_DENIED"
|
|
101
|
+
case .locationUnknown:
|
|
102
|
+
code = "LOCATION_UNKNOWN"
|
|
103
|
+
case .network:
|
|
104
|
+
code = "LOCATION_NETWORK_ERROR"
|
|
105
|
+
default:
|
|
106
|
+
code = "LOCATION_ERROR"
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
code = "LOCATION_ERROR"
|
|
110
|
+
}
|
|
111
|
+
onLocationError?(code, error.localizedDescription)
|
|
112
|
+
#if DEBUG
|
|
113
|
+
NSLog("[NitroLocationManager] Error: %@", error.localizedDescription)
|
|
114
|
+
#endif
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -33,8 +33,6 @@ final class MarkerIconCache {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
@objc private func handleMemoryWarning() {
|
|
36
|
-
// Clear half the cache on memory warning instead of all
|
|
37
|
-
// This keeps frequently used icons while freeing memory
|
|
38
36
|
#if DEBUG
|
|
39
37
|
print("[MarkerIconCache] Memory warning received, clearing caches")
|
|
40
38
|
#endif
|
|
@@ -255,7 +253,7 @@ class MarkerIconFactory {
|
|
|
255
253
|
|
|
256
254
|
// Post notification for markers to refresh their icons
|
|
257
255
|
NotificationCenter.default.post(
|
|
258
|
-
name:
|
|
256
|
+
name: GoogleMapProvider.markerIconLoadedNotification,
|
|
259
257
|
object: nil,
|
|
260
258
|
userInfo: ["cacheKey": cacheKey, "icon": finalIcon]
|
|
261
259
|
)
|
|
@@ -33,16 +33,20 @@ class PriceMarkerRenderer {
|
|
|
33
33
|
)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
let bg = PriceMarkerRenderer.variantToUIColor(config.backgroundColor) ?? .white
|
|
37
|
+
let text = PriceMarkerRenderer.variantToUIColor(config.textColor)
|
|
38
|
+
?? UIColor(red: 51/255, green: 51/255, blue: 51/255, alpha: 1)
|
|
39
|
+
|
|
36
40
|
return Style(
|
|
37
41
|
price: config.price,
|
|
38
42
|
currency: config.currency,
|
|
39
43
|
selected: config.selected,
|
|
40
|
-
backgroundColor:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
selectedTextColor: PriceMarkerRenderer.variantToUIColor(config.selectedTextColor) ??
|
|
44
|
+
backgroundColor: bg,
|
|
45
|
+
// Fall back to normal colors when consumer doesn't provide selection colors.
|
|
46
|
+
// This way selectMarker() only shows the info window without changing the icon.
|
|
47
|
+
selectedBackgroundColor: PriceMarkerRenderer.variantToUIColor(config.selectedBackgroundColor) ?? bg,
|
|
48
|
+
textColor: text,
|
|
49
|
+
selectedTextColor: PriceMarkerRenderer.variantToUIColor(config.selectedTextColor) ?? text,
|
|
46
50
|
fontSize: CGFloat(config.fontSize ?? 10),
|
|
47
51
|
paddingHorizontal: CGFloat(config.paddingHorizontal ?? 8),
|
|
48
52
|
paddingVertical: CGFloat(config.paddingVertical ?? 6),
|
package/ios/NitroMap.swift
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import NitroModules
|
|
3
3
|
import UIKit
|
|
4
|
+
import CoreLocation
|
|
4
5
|
|
|
5
|
-
/// HybridNitroMap -
|
|
6
|
+
/// HybridNitroMap - Provider-agnostic map view facade.
|
|
6
7
|
///
|
|
7
8
|
/// Threading contract:
|
|
8
9
|
/// - All UI/SDK operations are dispatched to main thread HERE.
|
|
@@ -23,11 +24,11 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
23
24
|
/// The provider is created lazily on first `afterUpdate()` or first
|
|
24
25
|
/// imperative method call. This avoids premature init before the view
|
|
25
26
|
/// has valid bounds.
|
|
26
|
-
private var _provider:
|
|
27
|
+
private var _provider: MapProviderProtocol?
|
|
27
28
|
|
|
28
29
|
/// Returns the provider, initializing it if needed.
|
|
29
30
|
/// Must be called from the main thread.
|
|
30
|
-
private var mapProvider:
|
|
31
|
+
private var mapProvider: MapProviderProtocol {
|
|
31
32
|
if _provider == nil {
|
|
32
33
|
initializeProvider()
|
|
33
34
|
}
|
|
@@ -35,7 +36,7 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
private func initializeProvider() {
|
|
38
|
-
let provider =
|
|
39
|
+
let provider = MapProviderFactory.create(for: self.provider ?? .google)
|
|
39
40
|
provider.setup()
|
|
40
41
|
|
|
41
42
|
let providerView = provider.mapView
|
|
@@ -47,18 +48,34 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
47
48
|
applyCurrentSettings(to: provider)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
/// Returns `nil` when the region is the JS sentinel (negative deltas).
|
|
52
|
+
private func filterSentinel(_ r: Region?) -> Region? {
|
|
53
|
+
guard let r = r, r.latitudeDelta >= 0, r.longitudeDelta >= 0 else { return nil }
|
|
54
|
+
return r
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private func applyCurrentSettings(to provider: MapProviderProtocol) {
|
|
58
|
+
provider.initialRegion = filterSentinel(initialRegion)
|
|
59
|
+
provider.region = filterSentinel(region)
|
|
52
60
|
provider.showsUserLocation = showsUserLocation
|
|
53
61
|
provider.zoomEnabled = zoomEnabled
|
|
54
62
|
provider.scrollEnabled = scrollEnabled
|
|
55
63
|
provider.rotateEnabled = rotateEnabled
|
|
56
64
|
provider.pitchEnabled = pitchEnabled
|
|
57
65
|
provider.mapType = mapType
|
|
58
|
-
provider.showsMyLocationButton = showsMyLocationButton
|
|
59
66
|
provider.clusterConfig = clusterConfig
|
|
60
67
|
provider.customMapStyle = customMapStyle
|
|
61
68
|
provider.darkMode = darkMode
|
|
69
|
+
provider.mapPadding = mapPadding
|
|
70
|
+
provider.showsTraffic = showsTraffic
|
|
71
|
+
provider.showsBuildings = showsBuildings
|
|
72
|
+
provider.showsCompass = showsCompass
|
|
73
|
+
provider.minZoom = minZoom
|
|
74
|
+
provider.maxZoom = maxZoom
|
|
75
|
+
provider.userTrackingMode = userTrackingMode
|
|
76
|
+
provider.userLocationImage = userLocationImage
|
|
77
|
+
provider.userLocationSize = userLocationSize
|
|
78
|
+
provider.userLocationAnchor = userLocationAnchor
|
|
62
79
|
|
|
63
80
|
provider.onPress = onPress
|
|
64
81
|
provider.onLongPress = onLongPress
|
|
@@ -71,6 +88,55 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
71
88
|
provider.onMarkerDragEnd = onMarkerDragEnd
|
|
72
89
|
provider.onClusterPress = onClusterPress
|
|
73
90
|
provider.onError = onError
|
|
91
|
+
provider.onUserTrackingModeChange = onUserTrackingModeChange
|
|
92
|
+
provider.onMapIdle = onMapIdle
|
|
93
|
+
provider.onPolylinePress = onPolylinePress
|
|
94
|
+
provider.onPolygonPress = onPolygonPress
|
|
95
|
+
provider.onCirclePress = onCirclePress
|
|
96
|
+
|
|
97
|
+
// Start location manager if needed
|
|
98
|
+
if showsUserLocation == true {
|
|
99
|
+
startLocationManager()
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// MARK: - Location Manager
|
|
104
|
+
|
|
105
|
+
private lazy var locationManager: NitroLocationManager = {
|
|
106
|
+
let mgr = NitroLocationManager()
|
|
107
|
+
mgr.onLocationUpdate = { [weak self] location, heading in
|
|
108
|
+
self?.handleLocationUpdate(location, heading: heading)
|
|
109
|
+
}
|
|
110
|
+
mgr.onLocationError = { [weak self] code, message in
|
|
111
|
+
self?.onUserLocationError?(MapError(code: code, message: message))
|
|
112
|
+
}
|
|
113
|
+
return mgr
|
|
114
|
+
}()
|
|
115
|
+
|
|
116
|
+
private func startLocationManager() {
|
|
117
|
+
locationManager.startUpdating()
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private func stopLocationManager() {
|
|
121
|
+
locationManager.stopUpdating()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private func handleLocationUpdate(_ location: CLLocation, heading: CLHeading?) {
|
|
125
|
+
// Forward to provider for marker/camera management
|
|
126
|
+
_provider?.updateUserLocation(location, heading: heading)
|
|
127
|
+
|
|
128
|
+
// Fire JS callback
|
|
129
|
+
let headingValue = heading?.trueHeading ?? (location.course >= 0 ? location.course : -1)
|
|
130
|
+
let event = UserLocationChangeEvent(
|
|
131
|
+
coordinate: Coordinate(
|
|
132
|
+
latitude: location.coordinate.latitude,
|
|
133
|
+
longitude: location.coordinate.longitude
|
|
134
|
+
),
|
|
135
|
+
accuracy: location.horizontalAccuracy,
|
|
136
|
+
heading: headingValue,
|
|
137
|
+
speed: location.speed >= 0 ? location.speed : -1
|
|
138
|
+
)
|
|
139
|
+
onUserLocationChange?(event)
|
|
74
140
|
}
|
|
75
141
|
|
|
76
142
|
var view: UIView { return containerView }
|
|
@@ -88,11 +154,27 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
88
154
|
// are pushed in bulk via applyCurrentSettings when provider inits).
|
|
89
155
|
|
|
90
156
|
var initialRegion: Region? {
|
|
91
|
-
didSet {
|
|
157
|
+
didSet {
|
|
158
|
+
_provider?.initialRegion = filterSentinel(initialRegion)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
var region: Region? {
|
|
163
|
+
didSet {
|
|
164
|
+
// Sentinel → nil (cleared); real value → forwarded as-is
|
|
165
|
+
_provider?.region = filterSentinel(region)
|
|
166
|
+
}
|
|
92
167
|
}
|
|
93
168
|
|
|
94
169
|
var showsUserLocation: Bool? {
|
|
95
|
-
didSet {
|
|
170
|
+
didSet {
|
|
171
|
+
_provider?.showsUserLocation = showsUserLocation
|
|
172
|
+
if showsUserLocation == true {
|
|
173
|
+
startLocationManager()
|
|
174
|
+
} else {
|
|
175
|
+
stopLocationManager()
|
|
176
|
+
}
|
|
177
|
+
}
|
|
96
178
|
}
|
|
97
179
|
|
|
98
180
|
var zoomEnabled: Bool? {
|
|
@@ -115,10 +197,6 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
115
197
|
didSet { _provider?.mapType = mapType }
|
|
116
198
|
}
|
|
117
199
|
|
|
118
|
-
var showsMyLocationButton: Bool? {
|
|
119
|
-
didSet { _provider?.showsMyLocationButton = showsMyLocationButton }
|
|
120
|
-
}
|
|
121
|
-
|
|
122
200
|
var clusterConfig: ClusterConfig? {
|
|
123
201
|
didSet { _provider?.clusterConfig = clusterConfig }
|
|
124
202
|
}
|
|
@@ -131,6 +209,46 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
131
209
|
didSet { _provider?.darkMode = darkMode }
|
|
132
210
|
}
|
|
133
211
|
|
|
212
|
+
var mapPadding: EdgePadding = EdgePadding(top: 0, right: 0, bottom: 0, left: 0) {
|
|
213
|
+
didSet { _provider?.mapPadding = mapPadding }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
var showsTraffic: Bool? {
|
|
217
|
+
didSet { _provider?.showsTraffic = showsTraffic }
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
var showsBuildings: Bool? {
|
|
221
|
+
didSet { _provider?.showsBuildings = showsBuildings }
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
var showsCompass: Bool? {
|
|
225
|
+
didSet { _provider?.showsCompass = showsCompass }
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
var minZoom: Double = 1 {
|
|
229
|
+
didSet { _provider?.minZoom = minZoom }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
var maxZoom: Double = 22 {
|
|
233
|
+
didSet { _provider?.maxZoom = maxZoom }
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
var userTrackingMode: UserTrackingMode? {
|
|
237
|
+
didSet { _provider?.userTrackingMode = userTrackingMode }
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
var userLocationImage: String = "" {
|
|
241
|
+
didSet { _provider?.userLocationImage = userLocationImage }
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
var userLocationSize: Double = 40 {
|
|
245
|
+
didSet { _provider?.userLocationSize = userLocationSize }
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var userLocationAnchor: Point? {
|
|
249
|
+
didSet { _provider?.userLocationAnchor = userLocationAnchor }
|
|
250
|
+
}
|
|
251
|
+
|
|
134
252
|
// MARK: - Callbacks
|
|
135
253
|
|
|
136
254
|
var onPress: ((MapPressEvent) -> Void)? {
|
|
@@ -177,6 +295,30 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
177
295
|
didSet { _provider?.onError = onError }
|
|
178
296
|
}
|
|
179
297
|
|
|
298
|
+
var onUserLocationChange: ((_ event: UserLocationChangeEvent) -> Void)?
|
|
299
|
+
|
|
300
|
+
var onUserTrackingModeChange: ((_ mode: UserTrackingMode) -> Void)? {
|
|
301
|
+
didSet { _provider?.onUserTrackingModeChange = onUserTrackingModeChange }
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
var onMapIdle: (() -> Void)? {
|
|
305
|
+
didSet { _provider?.onMapIdle = onMapIdle }
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
var onPolylinePress: ((_ id: String) -> Void)? {
|
|
309
|
+
didSet { _provider?.onPolylinePress = onPolylinePress }
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
var onPolygonPress: ((_ id: String) -> Void)? {
|
|
313
|
+
didSet { _provider?.onPolygonPress = onPolygonPress }
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
var onCirclePress: ((_ id: String) -> Void)? {
|
|
317
|
+
didSet { _provider?.onCirclePress = onCirclePress }
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
var onUserLocationError: ((_ error: MapError) -> Void)?
|
|
321
|
+
|
|
180
322
|
// MARK: - Initialization
|
|
181
323
|
|
|
182
324
|
override init() {
|
|
@@ -216,6 +358,20 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
216
358
|
}
|
|
217
359
|
}
|
|
218
360
|
|
|
361
|
+
func fitToSuppliedMarkers(
|
|
362
|
+
markerIds: [String],
|
|
363
|
+
edgePadding: EdgePadding?,
|
|
364
|
+
animated: Bool?
|
|
365
|
+
) throws {
|
|
366
|
+
DispatchQueue.main.async { [weak self] in
|
|
367
|
+
self?.mapProvider.fitToSuppliedMarkers(
|
|
368
|
+
markerIds,
|
|
369
|
+
edgePadding: edgePadding,
|
|
370
|
+
animated: animated
|
|
371
|
+
)
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
219
375
|
func animateCamera(camera: Camera, duration: Double?) throws {
|
|
220
376
|
DispatchQueue.main.async { [weak self] in
|
|
221
377
|
self?.mapProvider.animateCamera(camera, duration: duration)
|
|
@@ -252,6 +408,32 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
252
408
|
return .resolved(withResult: boundaries)
|
|
253
409
|
}
|
|
254
410
|
|
|
411
|
+
func centerOnUserLocation() throws {
|
|
412
|
+
DispatchQueue.main.async { [weak self] in
|
|
413
|
+
self?._provider?.centerOnUserLocation()
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
func pointForCoordinate(coordinate: Coordinate) throws -> Point {
|
|
418
|
+
if Thread.isMainThread {
|
|
419
|
+
return mapProvider.pointForCoordinate(coordinate)
|
|
420
|
+
} else {
|
|
421
|
+
return DispatchQueue.main.sync {
|
|
422
|
+
return self.mapProvider.pointForCoordinate(coordinate)
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
func coordinateForPoint(point: Point) throws -> Coordinate {
|
|
428
|
+
if Thread.isMainThread {
|
|
429
|
+
return mapProvider.coordinateForPoint(point)
|
|
430
|
+
} else {
|
|
431
|
+
return DispatchQueue.main.sync {
|
|
432
|
+
return self.mapProvider.coordinateForPoint(point)
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
255
437
|
// MARK: - Marker Methods
|
|
256
438
|
|
|
257
439
|
func addMarker(marker: MarkerData) throws {
|
|
@@ -290,6 +472,12 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
290
472
|
}
|
|
291
473
|
}
|
|
292
474
|
|
|
475
|
+
func deselectMarker() {
|
|
476
|
+
DispatchQueue.main.async { [weak self] in
|
|
477
|
+
self?.mapProvider.deselectMarker()
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
293
481
|
// MARK: - Clustering
|
|
294
482
|
|
|
295
483
|
func setClusteringEnabled(enabled: Bool) throws {
|
|
@@ -329,4 +517,82 @@ class HybridNitroMap: HybridNitroMapSpec {
|
|
|
329
517
|
func getCurrentRegion() -> Region {
|
|
330
518
|
return mapProvider.getCurrentRegion()
|
|
331
519
|
}
|
|
520
|
+
|
|
521
|
+
// MARK: - Polyline Methods
|
|
522
|
+
|
|
523
|
+
func addPolyline(polyline: PolylineData) throws {
|
|
524
|
+
DispatchQueue.main.async { [weak self] in
|
|
525
|
+
self?.mapProvider.addPolyline(polyline)
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
func updatePolyline(polyline: PolylineData) throws {
|
|
530
|
+
DispatchQueue.main.async { [weak self] in
|
|
531
|
+
self?.mapProvider.updatePolyline(polyline)
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
func removePolyline(id: String) throws {
|
|
536
|
+
DispatchQueue.main.async { [weak self] in
|
|
537
|
+
self?.mapProvider.removePolyline(id)
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
func clearPolylines() throws {
|
|
542
|
+
DispatchQueue.main.async { [weak self] in
|
|
543
|
+
self?.mapProvider.clearPolylines()
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// MARK: - Polygon Methods
|
|
548
|
+
|
|
549
|
+
func addPolygon(polygon: PolygonData) throws {
|
|
550
|
+
DispatchQueue.main.async { [weak self] in
|
|
551
|
+
self?.mapProvider.addPolygon(polygon)
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
func updatePolygon(polygon: PolygonData) throws {
|
|
556
|
+
DispatchQueue.main.async { [weak self] in
|
|
557
|
+
self?.mapProvider.updatePolygon(polygon)
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
func removePolygon(id: String) throws {
|
|
562
|
+
DispatchQueue.main.async { [weak self] in
|
|
563
|
+
self?.mapProvider.removePolygon(id)
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
func clearPolygons() throws {
|
|
568
|
+
DispatchQueue.main.async { [weak self] in
|
|
569
|
+
self?.mapProvider.clearPolygons()
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// MARK: - Circle Methods
|
|
574
|
+
|
|
575
|
+
func addCircle(circle: CircleData) throws {
|
|
576
|
+
DispatchQueue.main.async { [weak self] in
|
|
577
|
+
self?.mapProvider.addCircle(circle)
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
func updateCircle(circle: CircleData) throws {
|
|
582
|
+
DispatchQueue.main.async { [weak self] in
|
|
583
|
+
self?.mapProvider.updateCircle(circle)
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
func removeCircle(id: String) throws {
|
|
588
|
+
DispatchQueue.main.async { [weak self] in
|
|
589
|
+
self?.mapProvider.removeCircle(id)
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
func clearCircles() throws {
|
|
594
|
+
DispatchQueue.main.async { [weak self] in
|
|
595
|
+
self?.mapProvider.clearCircles()
|
|
596
|
+
}
|
|
597
|
+
}
|
|
332
598
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import GoogleMaps
|
|
3
|
+
import NitroModules
|
|
4
|
+
|
|
5
|
+
class HybridNitroMapConfig: HybridNitroMapConfigSpec {
|
|
6
|
+
|
|
7
|
+
// Static flag to track initialization across all instances
|
|
8
|
+
private static var isInitialized = false
|
|
9
|
+
|
|
10
|
+
func NitroMapInitialize(apiKey: String, provider: MapProvider) {
|
|
11
|
+
// Use static flag to prevent duplicate initialization
|
|
12
|
+
guard !HybridNitroMapConfig.isInitialized else {
|
|
13
|
+
#if DEBUG
|
|
14
|
+
print("[NitroMap] Already initialized, skipping...")
|
|
15
|
+
#endif
|
|
16
|
+
return
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
switch provider {
|
|
20
|
+
case .google:
|
|
21
|
+
// Set initialized BEFORE async dispatch to prevent race conditions
|
|
22
|
+
HybridNitroMapConfig.isInitialized = true
|
|
23
|
+
DispatchQueue.main.async {
|
|
24
|
+
GMSServices.provideAPIKey(apiKey)
|
|
25
|
+
#if DEBUG
|
|
26
|
+
print("[NitroMap] Google Maps initialized")
|
|
27
|
+
#endif
|
|
28
|
+
}
|
|
29
|
+
case .apple:
|
|
30
|
+
// Apple Maps uses MapKit (built-in) — no SDK initialization needed
|
|
31
|
+
HybridNitroMapConfig.isInitialized = true
|
|
32
|
+
#if DEBUG
|
|
33
|
+
print("[NitroMap] Apple Maps ready (no SDK init needed)")
|
|
34
|
+
#endif
|
|
35
|
+
case .yandex:
|
|
36
|
+
#if DEBUG
|
|
37
|
+
print("[NitroMap] Yandex Maps is not yet implemented")
|
|
38
|
+
#endif
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func IsNitroMapInitialized() -> Bool {
|
|
43
|
+
return HybridNitroMapConfig.isInitialized
|
|
44
|
+
}
|
|
45
|
+
}
|