react-native-google-maps-plus 0.1.0 → 1.0.1

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 (183) hide show
  1. package/GoogleMapsNitro.podspec +34 -0
  2. package/LICENSE +20 -0
  3. package/README.md +40 -0
  4. package/android/CMakeLists.txt +32 -0
  5. package/android/build.gradle +135 -0
  6. package/android/fix-prefab.gradle +51 -0
  7. package/android/gradle.properties +8 -0
  8. package/android/src/main/AndroidManifest.xml +2 -0
  9. package/android/src/main/cpp/cpp-adapter.cpp +6 -0
  10. package/android/src/main/java/com/googlemapsnitro/Color.kt +65 -0
  11. package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroPackage.kt +35 -0
  12. package/android/src/main/java/com/googlemapsnitro/GoogleMapsNitroViewImpl.kt +720 -0
  13. package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroModule.kt +22 -0
  14. package/android/src/main/java/com/googlemapsnitro/HybridGoogleMapsNitroView.kt +337 -0
  15. package/android/src/main/java/com/googlemapsnitro/LocationHandler.kt +205 -0
  16. package/android/src/main/java/com/googlemapsnitro/MapMarker.kt +145 -0
  17. package/android/src/main/java/com/googlemapsnitro/MapPolygon.kt +36 -0
  18. package/android/src/main/java/com/googlemapsnitro/MapPolyline.kt +59 -0
  19. package/android/src/main/java/com/googlemapsnitro/PermissionHandler.kt +116 -0
  20. package/android/src/main/java/com/googlemapsnitro/PlayServicesHandler.kt +25 -0
  21. package/ios/Color.swift +109 -0
  22. package/ios/GoogleMapNitroViewImpl.swift +590 -0
  23. package/ios/HybridGoogleMapsNitroModule.swift +27 -0
  24. package/ios/HybridGoogleMapsNitroView.swift +348 -0
  25. package/ios/LocationHandler.swift +205 -0
  26. package/ios/MapHelper.swift +18 -0
  27. package/ios/MapMarker.swift +207 -0
  28. package/ios/MapPolygon.swift +55 -0
  29. package/ios/MapPolyline.swift +83 -0
  30. package/ios/PermissionHandler.swift +73 -0
  31. package/lib/module/GoogleMapsNitroModule.nitro.js +4 -0
  32. package/lib/module/GoogleMapsNitroModule.nitro.js.map +1 -0
  33. package/lib/module/GoogleMapsNitroView.nitro.js +4 -0
  34. package/lib/module/GoogleMapsNitroView.nitro.js.map +1 -0
  35. package/lib/module/index.js +8 -0
  36. package/lib/module/index.js.map +1 -0
  37. package/lib/module/package.json +1 -0
  38. package/lib/module/types.js +78 -0
  39. package/lib/module/types.js.map +1 -0
  40. package/lib/typescript/package.json +1 -0
  41. package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts +12 -0
  42. package/lib/typescript/src/GoogleMapsNitroModule.nitro.d.ts.map +1 -0
  43. package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts +34 -0
  44. package/lib/typescript/src/GoogleMapsNitroView.nitro.d.ts.map +1 -0
  45. package/lib/typescript/src/index.d.ts +7 -0
  46. package/lib/typescript/src/index.d.ts.map +1 -0
  47. package/lib/typescript/src/types.d.ts +113 -0
  48. package/lib/typescript/src/types.d.ts.map +1 -0
  49. package/nitro.json +28 -0
  50. package/nitrogen/generated/.gitattributes +1 -0
  51. package/nitrogen/generated/android/GoogleMapsNitro+autolinking.cmake +85 -0
  52. package/nitrogen/generated/android/GoogleMapsNitro+autolinking.gradle +27 -0
  53. package/nitrogen/generated/android/GoogleMapsNitroOnLoad.cpp +70 -0
  54. package/nitrogen/generated/android/GoogleMapsNitroOnLoad.hpp +25 -0
  55. package/nitrogen/generated/android/c++/JFunc_void_RNLatLng.hpp +76 -0
  56. package/nitrogen/generated/android/c++/JFunc_void_RNLocation.hpp +78 -0
  57. package/nitrogen/generated/android/c++/JFunc_void_RNLocationErrorCode.hpp +76 -0
  58. package/nitrogen/generated/android/c++/JFunc_void_RNMapErrorCode.hpp +76 -0
  59. package/nitrogen/generated/android/c++/JFunc_void_RNRegion_RNCamera_bool.hpp +81 -0
  60. package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +74 -0
  61. package/nitrogen/generated/android/c++/JFunc_void_std__string.hpp +75 -0
  62. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroModuleSpec.cpp +83 -0
  63. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroModuleSpec.hpp +67 -0
  64. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroViewSpec.cpp +485 -0
  65. package/nitrogen/generated/android/c++/JHybridGoogleMapsNitroViewSpec.hpp +108 -0
  66. package/nitrogen/generated/android/c++/JRNAndroidLocationPermissionResult.hpp +62 -0
  67. package/nitrogen/generated/android/c++/JRNCamera.hpp +67 -0
  68. package/nitrogen/generated/android/c++/JRNIOSPermissionResult.hpp +59 -0
  69. package/nitrogen/generated/android/c++/JRNLatLng.hpp +57 -0
  70. package/nitrogen/generated/android/c++/JRNLineCapType.hpp +62 -0
  71. package/nitrogen/generated/android/c++/JRNLineJoinType.hpp +62 -0
  72. package/nitrogen/generated/android/c++/JRNLocation.hpp +58 -0
  73. package/nitrogen/generated/android/c++/JRNLocationErrorCode.hpp +71 -0
  74. package/nitrogen/generated/android/c++/JRNLocationPermissionResult.hpp +61 -0
  75. package/nitrogen/generated/android/c++/JRNMapErrorCode.hpp +74 -0
  76. package/nitrogen/generated/android/c++/JRNMapPadding.hpp +65 -0
  77. package/nitrogen/generated/android/c++/JRNMarker.hpp +82 -0
  78. package/nitrogen/generated/android/c++/JRNPolygon.hpp +94 -0
  79. package/nitrogen/generated/android/c++/JRNPolyline.hpp +102 -0
  80. package/nitrogen/generated/android/c++/JRNPosition.hpp +57 -0
  81. package/nitrogen/generated/android/c++/JRNRegion.hpp +62 -0
  82. package/nitrogen/generated/android/c++/JRNUserInterfaceStyle.hpp +62 -0
  83. package/nitrogen/generated/android/c++/views/JHybridGoogleMapsNitroViewStateUpdater.cpp +132 -0
  84. package/nitrogen/generated/android/c++/views/JHybridGoogleMapsNitroViewStateUpdater.hpp +49 -0
  85. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLatLng.kt +81 -0
  86. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLocation.kt +81 -0
  87. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNLocationErrorCode.kt +81 -0
  88. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNMapErrorCode.kt +81 -0
  89. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_RNRegion_RNCamera_bool.kt +81 -0
  90. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_bool.kt +81 -0
  91. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/Func_void_std__string.kt +81 -0
  92. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/GoogleMapsNitroOnLoad.kt +35 -0
  93. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/HybridGoogleMapsNitroModuleSpec.kt +64 -0
  94. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/HybridGoogleMapsNitroViewSpec.kt +263 -0
  95. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNAndroidLocationPermissionResult.kt +22 -0
  96. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNCamera.kt +38 -0
  97. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNIOSPermissionResult.kt +21 -0
  98. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLatLng.kt +32 -0
  99. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLineCapType.kt +22 -0
  100. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLineJoinType.kt +22 -0
  101. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocation.kt +32 -0
  102. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocationErrorCode.kt +25 -0
  103. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNLocationPermissionResult.kt +32 -0
  104. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMapErrorCode.kt +26 -0
  105. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMapPadding.kt +38 -0
  106. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNMarker.kt +47 -0
  107. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPolygon.kt +44 -0
  108. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPolyline.kt +47 -0
  109. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNPosition.kt +32 -0
  110. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNRegion.kt +35 -0
  111. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/RNUserInterfaceStyle.kt +22 -0
  112. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/views/HybridGoogleMapsNitroViewManager.kt +50 -0
  113. package/nitrogen/generated/android/kotlin/com/margelo/nitro/googlemapsnitro/views/HybridGoogleMapsNitroViewStateUpdater.kt +23 -0
  114. package/nitrogen/generated/ios/GoogleMapsNitro+autolinking.rb +60 -0
  115. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Bridge.cpp +121 -0
  116. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Bridge.hpp +649 -0
  117. package/nitrogen/generated/ios/GoogleMapsNitro-Swift-Cxx-Umbrella.hpp +104 -0
  118. package/nitrogen/generated/ios/GoogleMapsNitroAutolinking.mm +41 -0
  119. package/nitrogen/generated/ios/GoogleMapsNitroAutolinking.swift +40 -0
  120. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroModuleSpecSwift.cpp +11 -0
  121. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroModuleSpecSwift.hpp +102 -0
  122. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroViewSpecSwift.cpp +11 -0
  123. package/nitrogen/generated/ios/c++/HybridGoogleMapsNitroViewSpecSwift.hpp +294 -0
  124. package/nitrogen/generated/ios/c++/views/HybridGoogleMapsNitroViewComponent.mm +191 -0
  125. package/nitrogen/generated/ios/swift/Func_void_RNLatLng.swift +47 -0
  126. package/nitrogen/generated/ios/swift/Func_void_RNLocation.swift +47 -0
  127. package/nitrogen/generated/ios/swift/Func_void_RNLocationErrorCode.swift +47 -0
  128. package/nitrogen/generated/ios/swift/Func_void_RNLocationPermissionResult.swift +47 -0
  129. package/nitrogen/generated/ios/swift/Func_void_RNMapErrorCode.swift +47 -0
  130. package/nitrogen/generated/ios/swift/Func_void_RNRegion_RNCamera_bool.swift +47 -0
  131. package/nitrogen/generated/ios/swift/Func_void_bool.swift +47 -0
  132. package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +47 -0
  133. package/nitrogen/generated/ios/swift/Func_void_std__string.swift +47 -0
  134. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroModuleSpec.swift +52 -0
  135. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroModuleSpec_cxx.swift +164 -0
  136. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroViewSpec.swift +73 -0
  137. package/nitrogen/generated/ios/swift/HybridGoogleMapsNitroViewSpec_cxx.swift +630 -0
  138. package/nitrogen/generated/ios/swift/RNAndroidLocationPermissionResult.swift +44 -0
  139. package/nitrogen/generated/ios/swift/RNCamera.swift +123 -0
  140. package/nitrogen/generated/ios/swift/RNIOSPermissionResult.swift +40 -0
  141. package/nitrogen/generated/ios/swift/RNLatLng.swift +46 -0
  142. package/nitrogen/generated/ios/swift/RNLineCapType.swift +44 -0
  143. package/nitrogen/generated/ios/swift/RNLineJoinType.swift +44 -0
  144. package/nitrogen/generated/ios/swift/RNLocation.swift +46 -0
  145. package/nitrogen/generated/ios/swift/RNLocationErrorCode.swift +56 -0
  146. package/nitrogen/generated/ios/swift/RNLocationPermissionResult.swift +70 -0
  147. package/nitrogen/generated/ios/swift/RNMapErrorCode.swift +60 -0
  148. package/nitrogen/generated/ios/swift/RNMapPadding.swift +68 -0
  149. package/nitrogen/generated/ios/swift/RNMarker.swift +120 -0
  150. package/nitrogen/generated/ios/swift/RNPolygon.swift +152 -0
  151. package/nitrogen/generated/ios/swift/RNPolyline.swift +168 -0
  152. package/nitrogen/generated/ios/swift/RNPosition.swift +46 -0
  153. package/nitrogen/generated/ios/swift/RNRegion.swift +57 -0
  154. package/nitrogen/generated/ios/swift/RNUserInterfaceStyle.swift +44 -0
  155. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroModuleSpec.cpp +24 -0
  156. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroModuleSpec.hpp +67 -0
  157. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroViewSpec.cpp +66 -0
  158. package/nitrogen/generated/shared/c++/HybridGoogleMapsNitroViewSpec.hpp +145 -0
  159. package/nitrogen/generated/shared/c++/RNAndroidLocationPermissionResult.hpp +67 -0
  160. package/nitrogen/generated/shared/c++/RNCamera.hpp +81 -0
  161. package/nitrogen/generated/shared/c++/RNIOSPermissionResult.hpp +65 -0
  162. package/nitrogen/generated/shared/c++/RNLatLng.hpp +71 -0
  163. package/nitrogen/generated/shared/c++/RNLineCapType.hpp +80 -0
  164. package/nitrogen/generated/shared/c++/RNLineJoinType.hpp +80 -0
  165. package/nitrogen/generated/shared/c++/RNLocation.hpp +72 -0
  166. package/nitrogen/generated/shared/c++/RNLocationErrorCode.hpp +73 -0
  167. package/nitrogen/generated/shared/c++/RNLocationPermissionResult.hpp +76 -0
  168. package/nitrogen/generated/shared/c++/RNMapErrorCode.hpp +67 -0
  169. package/nitrogen/generated/shared/c++/RNMapPadding.hpp +79 -0
  170. package/nitrogen/generated/shared/c++/RNMarker.hpp +97 -0
  171. package/nitrogen/generated/shared/c++/RNPolygon.hpp +91 -0
  172. package/nitrogen/generated/shared/c++/RNPolyline.hpp +101 -0
  173. package/nitrogen/generated/shared/c++/RNPosition.hpp +71 -0
  174. package/nitrogen/generated/shared/c++/RNRegion.hpp +76 -0
  175. package/nitrogen/generated/shared/c++/RNUserInterfaceStyle.hpp +80 -0
  176. package/nitrogen/generated/shared/c++/views/HybridGoogleMapsNitroViewComponent.cpp +315 -0
  177. package/nitrogen/generated/shared/c++/views/HybridGoogleMapsNitroViewComponent.hpp +139 -0
  178. package/nitrogen/generated/shared/json/GoogleMapsNitroViewConfig.json +29 -0
  179. package/package.json +13 -3
  180. package/src/GoogleMapsNitroModule.nitro.ts +13 -0
  181. package/src/GoogleMapsNitroView.nitro.ts +78 -0
  182. package/src/index.tsx +24 -0
  183. package/src/types.ts +174 -0
@@ -0,0 +1,720 @@
1
+ package com.googlemapsnitro
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.location.Location
5
+ import com.facebook.react.bridge.LifecycleEventListener
6
+ import com.facebook.react.bridge.UiThreadUtil
7
+ import com.facebook.react.uimanager.PixelUtil.dpToPx
8
+ import com.facebook.react.uimanager.ThemedReactContext
9
+ import com.google.android.gms.common.ConnectionResult
10
+ import com.google.android.gms.maps.CameraUpdateFactory
11
+ import com.google.android.gms.maps.GoogleMap
12
+ import com.google.android.gms.maps.MapView
13
+ import com.google.android.gms.maps.OnMapReadyCallback
14
+ import com.google.android.gms.maps.model.CameraPosition
15
+ import com.google.android.gms.maps.model.LatLng
16
+ import com.google.android.gms.maps.model.LatLngBounds
17
+ import com.google.android.gms.maps.model.MapColorScheme
18
+ import com.google.android.gms.maps.model.MapStyleOptions
19
+ import com.google.android.gms.maps.model.Marker
20
+ import com.google.android.gms.maps.model.MarkerOptions
21
+ import com.google.android.gms.maps.model.Polygon
22
+ import com.google.android.gms.maps.model.PolygonOptions
23
+ import com.google.android.gms.maps.model.Polyline
24
+ import com.google.android.gms.maps.model.PolylineOptions
25
+
26
+ class GoogleMapsNitroViewImpl(
27
+ val reactContext: ThemedReactContext,
28
+ val locationHandler: LocationHandler,
29
+ val playServiceHandler: PlayServicesHandler,
30
+ val markerOptions: com.googlemapsnitro.MarkerOptions,
31
+ ) : MapView(reactContext),
32
+ GoogleMap.OnCameraMoveStartedListener,
33
+ GoogleMap.OnCameraMoveListener,
34
+ GoogleMap.OnCameraIdleListener,
35
+ GoogleMap.OnMapClickListener,
36
+ OnMapReadyCallback,
37
+ GoogleMap.OnMarkerClickListener,
38
+ LifecycleEventListener {
39
+ private var googleMap: GoogleMap? = null
40
+
41
+ private var pendingBuildingEnabled: Boolean = false
42
+ private var pendingTrafficEnabled: Boolean = false
43
+ private var pendingCustomMapStyle: MapStyleOptions? = null
44
+ private var pendingInitialCamera: CameraPosition =
45
+ CameraPosition
46
+ .builder()
47
+ .target(
48
+ LatLng(
49
+ 0.0,
50
+ 0.0,
51
+ ),
52
+ ).zoom(0f)
53
+ .bearing(0f)
54
+ .tilt(0f)
55
+ .build()
56
+ private var pendingUserInterfaceStyle: Int = MapColorScheme.FOLLOW_SYSTEM
57
+ private var pendingMinZoomLevel: Double = 0.0
58
+ private var pendingMaxZoomLevel: Double = 21.0
59
+ private var pendingMapPadding: RNMapPadding = RNMapPadding(0.0, 0.0, 0.0, 0.0)
60
+ private val pendingPolygons = mutableListOf<Pair<String, PolygonOptions>>()
61
+ private val pendingPolylines = mutableListOf<Pair<String, PolylineOptions>>()
62
+ private val pendingMarkers = mutableListOf<Pair<String, MarkerOptions>>()
63
+ private var cameraMoveReason = -1
64
+
65
+ private val polygonsById = mutableMapOf<String, Polygon>()
66
+ private val polylinesById = mutableMapOf<String, Polyline>()
67
+ private val markersById = mutableMapOf<String, Marker>()
68
+
69
+ private var lastSubmittedLocation: Location? = null
70
+ private var lastSubmittedCameraPosition: CameraPosition? = null
71
+
72
+ init {
73
+ reactContext.addLifecycleEventListener(this)
74
+ getMap()
75
+ }
76
+
77
+ private fun getMap() {
78
+ val result = playServiceHandler.playServicesAvailability()
79
+
80
+ when (result) {
81
+ ConnectionResult.SERVICE_MISSING -> {
82
+ onMapError?.invoke(RNMapErrorCode.PLAY_SERVICES_MISSING)
83
+ return
84
+ }
85
+
86
+ ConnectionResult.SERVICE_INVALID -> {
87
+ onMapError?.invoke(RNMapErrorCode.PLAY_SERVICES_INVALID)
88
+ return
89
+ }
90
+
91
+ ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED ->
92
+ onMapError?.invoke(RNMapErrorCode.PLAY_SERVICES_OUTDATED)
93
+
94
+ ConnectionResult.SERVICE_UPDATING ->
95
+ onMapError?.invoke(RNMapErrorCode.PLAY_SERVICE_UPDATING)
96
+
97
+ ConnectionResult.SERVICE_DISABLED ->
98
+ onMapError?.invoke(RNMapErrorCode.PLAY_SERVICES_DISABLED)
99
+
100
+ ConnectionResult.SUCCESS -> {}
101
+
102
+ else ->
103
+ onMapError?.invoke(RNMapErrorCode.UNKNOWN)
104
+ }
105
+
106
+ onCreate(null)
107
+ getMapAsync(this@GoogleMapsNitroViewImpl)
108
+ }
109
+
110
+ override fun onCameraMoveStarted(reason: Int) {
111
+ lastSubmittedCameraPosition = null
112
+ cameraMoveReason = reason
113
+ val bounds = googleMap?.projection?.visibleRegion?.latLngBounds
114
+ val cameraPosition = googleMap?.cameraPosition
115
+ if (bounds == null || cameraPosition == null) {
116
+ return
117
+ }
118
+ val isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == reason
119
+
120
+ val latDelta = bounds.northeast.latitude - bounds.southwest.latitude
121
+ val lngDelta = bounds.northeast.longitude - bounds.southwest.longitude
122
+
123
+ onCameraChangeStart?.invoke(
124
+ RNRegion(
125
+ center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
126
+ latitudeDelta = latDelta,
127
+ longitudeDelta = lngDelta,
128
+ ),
129
+ RNCamera(
130
+ center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
131
+ zoom = cameraPosition.zoom.toDouble(),
132
+ bearing = cameraPosition.bearing.toDouble(),
133
+ tilt = cameraPosition.tilt.toDouble(),
134
+ ),
135
+ isGesture,
136
+ )
137
+ }
138
+
139
+ override fun onCameraMove() {
140
+ val bounds = googleMap?.projection?.visibleRegion?.latLngBounds
141
+ val cameraPosition = googleMap?.cameraPosition
142
+ if (bounds == null || cameraPosition == null) {
143
+ return
144
+ }
145
+ if (cameraPosition == lastSubmittedCameraPosition) {
146
+ return
147
+ }
148
+ val isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason
149
+
150
+ val latDelta = bounds.northeast.latitude - bounds.southwest.latitude
151
+ val lngDelta = bounds.northeast.longitude - bounds.southwest.longitude
152
+
153
+ onCameraChange?.invoke(
154
+ RNRegion(
155
+ center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
156
+ latitudeDelta = latDelta,
157
+ longitudeDelta = lngDelta,
158
+ ),
159
+ RNCamera(
160
+ center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
161
+ zoom = cameraPosition.zoom.toDouble(),
162
+ bearing = cameraPosition.bearing.toDouble(),
163
+ tilt = cameraPosition.tilt.toDouble(),
164
+ ),
165
+ isGesture,
166
+ )
167
+ lastSubmittedCameraPosition = cameraPosition
168
+ }
169
+
170
+ override fun onCameraIdle() {
171
+ val bounds = googleMap?.projection?.visibleRegion?.latLngBounds
172
+ val cameraPosition = googleMap?.cameraPosition
173
+
174
+ if (bounds == null || cameraPosition == null) {
175
+ return
176
+ }
177
+ val isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason
178
+
179
+ val latDelta = bounds.northeast.latitude - bounds.southwest.latitude
180
+ val lngDelta = bounds.northeast.longitude - bounds.southwest.longitude
181
+
182
+ onCameraChangeComplete?.invoke(
183
+ RNRegion(
184
+ center = RNLatLng(bounds.center.latitude, bounds.center.longitude),
185
+ latitudeDelta = latDelta,
186
+ longitudeDelta = lngDelta,
187
+ ),
188
+ RNCamera(
189
+ center = RNLatLng(cameraPosition.target.latitude, cameraPosition.target.longitude),
190
+ zoom = cameraPosition.zoom.toDouble(),
191
+ bearing = cameraPosition.bearing.toDouble(),
192
+ tilt = cameraPosition.tilt.toDouble(),
193
+ ),
194
+ isGesture,
195
+ )
196
+ }
197
+
198
+ @SuppressLint("PotentialBehaviorOverride")
199
+ override fun onMapReady(map: GoogleMap) {
200
+ googleMap = map
201
+ googleMap?.setOnMapLoadedCallback {
202
+ googleMap?.setOnCameraMoveStartedListener(this)
203
+ googleMap?.setOnCameraMoveListener(this)
204
+ googleMap?.setOnCameraIdleListener(this)
205
+ googleMap?.setOnMarkerClickListener(this)
206
+ googleMap?.setOnMapClickListener(this)
207
+ }
208
+ initLocationCallbacks()
209
+ applyPending()
210
+
211
+ onMapReady?.invoke(true)
212
+ }
213
+
214
+ fun initLocationCallbacks() {
215
+ locationHandler.onUpdate = { location ->
216
+ // / only the coordinated are relevant right now
217
+ if (lastSubmittedLocation?.latitude != location.latitude || lastSubmittedLocation?.longitude != location.longitude ||
218
+ lastSubmittedLocation?.bearing != location.bearing
219
+ ) {
220
+ onLocationUpdate?.invoke(
221
+ RNLocation(
222
+ RNLatLng(location.latitude, location.longitude),
223
+ location.bearing.toDouble(),
224
+ ),
225
+ )
226
+ }
227
+ lastSubmittedLocation = location
228
+ }
229
+
230
+ locationHandler.onError = { error ->
231
+ onLocationError?.invoke(error)
232
+ }
233
+ locationHandler.start()
234
+ }
235
+
236
+ fun applyPending() {
237
+ onUi {
238
+ googleMap?.setPadding(
239
+ pendingMapPadding.left.dpToPx().toInt(),
240
+ pendingMapPadding.top.dpToPx().toInt(),
241
+ pendingMapPadding.right.dpToPx().toInt(),
242
+ pendingMapPadding.bottom.dpToPx().toInt(),
243
+ )
244
+
245
+ pendingInitialCamera.let {
246
+ googleMap?.moveCamera(
247
+ CameraUpdateFactory.newCameraPosition(
248
+ it,
249
+ ),
250
+ )
251
+ }
252
+
253
+ googleMap?.isBuildingsEnabled = pendingBuildingEnabled
254
+ googleMap?.isTrafficEnabled = pendingTrafficEnabled
255
+ googleMap?.setMapStyle(pendingCustomMapStyle)
256
+ googleMap?.mapColorScheme = pendingUserInterfaceStyle
257
+ googleMap?.setMinZoomPreference(pendingMinZoomLevel.toFloat())
258
+ googleMap?.setMaxZoomPreference(pendingMaxZoomLevel.toFloat())
259
+ }
260
+
261
+ if (pendingMarkers.isNotEmpty()) {
262
+ pendingMarkers.forEach { (id, opts) ->
263
+ internalAddMarker(id, opts)
264
+ }
265
+ pendingMarkers.clear()
266
+ }
267
+
268
+ if (pendingPolylines.isNotEmpty()) {
269
+ pendingPolylines.forEach { (id, opts) ->
270
+ internalAddPolyline(id, opts)
271
+ }
272
+ pendingPolylines.clear()
273
+ }
274
+
275
+ if (pendingPolygons.isNotEmpty()) {
276
+ pendingPolygons.forEach { (id, opts) ->
277
+ internalAddPolygon(id, opts)
278
+ }
279
+ pendingPolygons.clear()
280
+ }
281
+ }
282
+
283
+ var buildingEnabled: Boolean
284
+ get() = googleMap?.isBuildingsEnabled ?: pendingBuildingEnabled
285
+ set(value) {
286
+ pendingBuildingEnabled = value
287
+ onUi {
288
+ googleMap?.isBuildingsEnabled = value
289
+ }
290
+ }
291
+
292
+ var trafficEnabled: Boolean
293
+ get() = googleMap?.isTrafficEnabled ?: pendingTrafficEnabled
294
+ set(value) {
295
+ pendingTrafficEnabled = value
296
+ onUi {
297
+ googleMap?.isTrafficEnabled = value
298
+ }
299
+ }
300
+
301
+ var customMapStyle: MapStyleOptions?
302
+ get() = pendingCustomMapStyle
303
+ set(value) {
304
+ pendingCustomMapStyle = value
305
+ onUi {
306
+ googleMap?.setMapStyle(value)
307
+ }
308
+ }
309
+
310
+ var initialCamera: CameraPosition
311
+ get() = pendingInitialCamera
312
+ set(value) {
313
+ pendingInitialCamera = value
314
+ }
315
+
316
+ var userInterfaceStyle: Int
317
+ get() = pendingUserInterfaceStyle
318
+ set(value) {
319
+ pendingUserInterfaceStyle = value
320
+ onUi {
321
+ googleMap?.mapColorScheme = value
322
+ }
323
+ }
324
+
325
+ var minZoomLevel: Double
326
+ get() = pendingMinZoomLevel
327
+ set(value) {
328
+ pendingMinZoomLevel = value
329
+ onUi {
330
+ googleMap?.setMinZoomPreference(value.toFloat())
331
+ }
332
+ }
333
+
334
+ var maxZoomLevel: Double
335
+ get() = pendingMaxZoomLevel
336
+ set(value) {
337
+ pendingMaxZoomLevel = value
338
+ onUi {
339
+ googleMap?.setMaxZoomPreference(value.toFloat())
340
+ }
341
+ }
342
+
343
+ var mapPadding: RNMapPadding
344
+ get() = pendingMapPadding
345
+ set(value) {
346
+ pendingMapPadding = value
347
+ onUi {
348
+ googleMap?.setPadding(
349
+ value.left.dpToPx().toInt(),
350
+ value.top.dpToPx().toInt(),
351
+ value.right.dpToPx().toInt(),
352
+ value.bottom.dpToPx().toInt(),
353
+ )
354
+ }
355
+ }
356
+
357
+ var onMapError: ((RNMapErrorCode) -> Unit)? = null
358
+ var onMapReady: ((Boolean) -> Unit)? = null
359
+ var onLocationUpdate: ((RNLocation) -> Unit)? = null
360
+ var onLocationError: ((RNLocationErrorCode) -> Unit)? = null
361
+ var onMapPress: ((RNLatLng) -> Unit)? = null
362
+ var onMarkerPress: ((String) -> Unit)? = null
363
+ var onCameraChangeStart: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
364
+ var onCameraChange: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
365
+ var onCameraChangeComplete: ((RNRegion, RNCamera, Boolean) -> Unit)? = null
366
+
367
+ fun setCamera(
368
+ camera: RNCamera,
369
+ animated: Boolean,
370
+ durationMS: Int,
371
+ ) {
372
+ onUi {
373
+ val current = googleMap?.cameraPosition
374
+ if (current == null) {
375
+ return@onUi
376
+ }
377
+ val camPosBuilder =
378
+ CameraPosition.Builder(
379
+ current,
380
+ )
381
+
382
+ camera.center?.let {
383
+ camPosBuilder.target(
384
+ LatLng(
385
+ it.latitude,
386
+ it.longitude,
387
+ ),
388
+ )
389
+ }
390
+
391
+ camera.zoom?.let {
392
+ camPosBuilder.zoom(it.toFloat())
393
+ }
394
+ camera.bearing?.let {
395
+ camPosBuilder.bearing(it.toFloat())
396
+ }
397
+ camera.tilt?.let {
398
+ camPosBuilder.tilt(it.toFloat())
399
+ }
400
+
401
+ val camPos = camPosBuilder.build()
402
+
403
+ val update = CameraUpdateFactory.newCameraPosition(camPos)
404
+
405
+ if (animated) {
406
+ googleMap?.animateCamera(update, durationMS, null)
407
+ } else {
408
+ googleMap?.moveCamera(update)
409
+ }
410
+ }
411
+ }
412
+
413
+ fun setCameraToCoordinates(
414
+ coordinates: Array<RNLatLng>,
415
+ padding: RNMapPadding,
416
+ animated: Boolean,
417
+ durationMS: Int,
418
+ ) {
419
+ if (coordinates.isEmpty()) {
420
+ return
421
+ }
422
+ onUi {
423
+ val builder = LatLngBounds.Builder()
424
+ coordinates.forEach { coord ->
425
+ builder.include(LatLng(coord.latitude, coord.longitude))
426
+ }
427
+ val bounds = builder.build()
428
+
429
+ val latSpan = bounds.northeast.latitude - bounds.southwest.latitude
430
+ val lngSpan = bounds.northeast.longitude - bounds.southwest.longitude
431
+
432
+ val latPerPixel = latSpan / height
433
+ val lngPerPixel = lngSpan / width
434
+
435
+ builder.include(
436
+ LatLng(
437
+ bounds.northeast.latitude + (padding.top.dpToPx() * latPerPixel),
438
+ bounds.northeast.longitude,
439
+ ),
440
+ )
441
+ builder.include(
442
+ LatLng(
443
+ bounds.southwest.latitude - (padding.bottom.dpToPx() * latPerPixel),
444
+ bounds.southwest.longitude,
445
+ ),
446
+ )
447
+ builder.include(
448
+ LatLng(
449
+ bounds.northeast.latitude,
450
+ bounds.northeast.longitude + (padding.right.dpToPx() * lngPerPixel),
451
+ ),
452
+ )
453
+ builder.include(
454
+ LatLng(
455
+ bounds.southwest.latitude,
456
+ bounds.southwest.longitude - (padding.left.dpToPx() * lngPerPixel),
457
+ ),
458
+ )
459
+
460
+ val paddedBounds = builder.build()
461
+
462
+ val adjustedWidth = (width - padding.left.dpToPx() - padding.right.dpToPx()).toInt()
463
+ val adjustedHeight = (height - padding.top.dpToPx() - padding.bottom.dpToPx()).toInt()
464
+
465
+ val update =
466
+ CameraUpdateFactory.newLatLngBounds(
467
+ paddedBounds,
468
+ adjustedWidth,
469
+ adjustedHeight,
470
+ 0,
471
+ )
472
+ if (animated) {
473
+ googleMap?.animateCamera(update, durationMS, null)
474
+ } else {
475
+ googleMap?.moveCamera(update)
476
+ }
477
+ }
478
+ }
479
+
480
+ fun addMarker(
481
+ id: String,
482
+ opts: MarkerOptions,
483
+ ) {
484
+ if (googleMap == null) {
485
+ pendingMarkers.add(id to opts)
486
+ return
487
+ }
488
+
489
+ onUi {
490
+ markersById.remove(id)?.remove()
491
+ }
492
+ internalAddMarker(id, opts)
493
+ }
494
+
495
+ private fun internalAddMarker(
496
+ id: String,
497
+ opts: MarkerOptions,
498
+ ) {
499
+ onUi {
500
+ val marker =
501
+ googleMap?.addMarker(opts).also {
502
+ it?.tag = id
503
+ }
504
+ if (marker != null) {
505
+ markersById[id] = marker
506
+ }
507
+ }
508
+ }
509
+
510
+ fun updateMarker(
511
+ id: String,
512
+ block: (Marker) -> Unit,
513
+ ) {
514
+ val marker = markersById[id] ?: return
515
+ onUi {
516
+ block(marker)
517
+ }
518
+ }
519
+
520
+ fun removeMarker(id: String) {
521
+ onUi {
522
+ val marker = markersById.remove(id)
523
+ marker?.remove()
524
+ }
525
+ }
526
+
527
+ fun clearMarkers() {
528
+ onUi {
529
+ markersById.values.forEach { it.remove() }
530
+ }
531
+ markersById.clear()
532
+ pendingMarkers.clear()
533
+ }
534
+
535
+ fun addPolyline(
536
+ id: String,
537
+ opts: PolylineOptions,
538
+ ) {
539
+ if (googleMap == null) {
540
+ pendingPolylines.add(id to opts)
541
+ return
542
+ }
543
+ onUi {
544
+ polylinesById.remove(id)?.remove()
545
+ }
546
+ internalAddPolyline(id, opts)
547
+ }
548
+
549
+ private fun internalAddPolyline(
550
+ id: String,
551
+ opts: PolylineOptions,
552
+ ) {
553
+ onUi {
554
+ val polyline =
555
+ googleMap?.addPolyline(opts).also {
556
+ it?.tag = id
557
+ }
558
+ if (polyline != null) {
559
+ polylinesById[id] = polyline
560
+ }
561
+ }
562
+ }
563
+
564
+ fun updatePolyline(
565
+ id: String,
566
+ block: (Polyline) -> Unit,
567
+ ) {
568
+ val pl = polylinesById[id] ?: return
569
+ onUi {
570
+ block(pl)
571
+ }
572
+ }
573
+
574
+ fun removePolyline(id: String) {
575
+ onUi {
576
+ polylinesById.remove(id)?.remove()
577
+ }
578
+ }
579
+
580
+ fun clearPolylines() {
581
+ onUi {
582
+ polylinesById.values.forEach { it.remove() }
583
+ }
584
+ polylinesById.clear()
585
+ pendingPolylines.clear()
586
+ }
587
+
588
+ fun addPolygon(
589
+ id: String,
590
+ opts: PolygonOptions,
591
+ ) {
592
+ if (googleMap == null) {
593
+ pendingPolygons.add(id to opts)
594
+ return
595
+ }
596
+
597
+ onUi {
598
+ polygonsById.remove(id)?.remove()
599
+ }
600
+ internalAddPolygon(id, opts)
601
+ }
602
+
603
+ private fun internalAddPolygon(
604
+ id: String,
605
+ opts: PolygonOptions,
606
+ ) {
607
+ onUi {
608
+ val polygon =
609
+ googleMap?.addPolygon(opts).also {
610
+ it?.tag = id
611
+ }
612
+ if (polygon != null) {
613
+ polygonsById[id] = polygon
614
+ }
615
+ }
616
+ }
617
+
618
+ fun updatePolygon(
619
+ id: String,
620
+ block: (Polygon) -> Unit,
621
+ ) {
622
+ val polygon = polygonsById[id] ?: return
623
+ onUi {
624
+ block(polygon)
625
+ }
626
+ }
627
+
628
+ fun removePolygon(id: String) {
629
+ onUi {
630
+ polygonsById.remove(id)?.remove()
631
+ }
632
+ }
633
+
634
+ fun clearPolygons() {
635
+ onUi {
636
+ polygonsById.values.forEach { it.remove() }
637
+ }
638
+ polygonsById.clear()
639
+ pendingPolygons.clear()
640
+ }
641
+
642
+ fun clearAll() {
643
+ onUi {
644
+ markerOptions.cancelAllJobs()
645
+ clearMarkers()
646
+ clearPolylines()
647
+ clearPolygons()
648
+ locationHandler.stop()
649
+ googleMap?.apply {
650
+ setOnCameraMoveStartedListener(null)
651
+ setOnCameraMoveListener(null)
652
+ setOnCameraIdleListener(null)
653
+ setOnMarkerClickListener(null)
654
+ setOnMapClickListener(null)
655
+ }
656
+ this@GoogleMapsNitroViewImpl.onDestroy()
657
+ googleMap = null
658
+ reactContext.removeLifecycleEventListener(this)
659
+ }
660
+ }
661
+
662
+ override fun requestLayout() {
663
+ super.requestLayout()
664
+ // / setPadding issue
665
+ post {
666
+ measure(
667
+ MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
668
+ MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
669
+ )
670
+ layout(left, top, right, bottom)
671
+ }
672
+ }
673
+
674
+ override fun onAttachedToWindow() {
675
+ super.onAttachedToWindow()
676
+ locationHandler.start()
677
+ }
678
+
679
+ override fun onDetachedFromWindow() {
680
+ super.onDetachedFromWindow()
681
+ locationHandler.stop()
682
+ }
683
+
684
+ override fun onHostResume() {
685
+ onUi {
686
+ locationHandler.start()
687
+ this@GoogleMapsNitroViewImpl.onResume()
688
+ }
689
+ }
690
+
691
+ override fun onHostPause() {
692
+ onUi {
693
+ locationHandler.stop()
694
+ this@GoogleMapsNitroViewImpl.onPause()
695
+ }
696
+ }
697
+
698
+ override fun onHostDestroy() {
699
+ clearAll()
700
+ }
701
+
702
+ override fun onMarkerClick(marker: Marker): Boolean {
703
+ onMarkerPress?.invoke(marker.tag?.toString() ?: "unknown")
704
+ return true
705
+ }
706
+
707
+ override fun onMapClick(coordinates: LatLng) {
708
+ onMapPress?.invoke(
709
+ RNLatLng(coordinates.latitude, coordinates.longitude),
710
+ )
711
+ }
712
+ }
713
+
714
+ private inline fun onUi(crossinline block: () -> Unit) {
715
+ if (UiThreadUtil.isOnUiThread()) {
716
+ block()
717
+ } else {
718
+ UiThreadUtil.runOnUiThread { block() }
719
+ }
720
+ }