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