react-native-maps 0.31.0 → 1.0.0-alpha.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 (301) hide show
  1. package/android/build.gradle +89 -33
  2. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  3. package/android/gradle/wrapper/gradle-wrapper.properties +5 -0
  4. package/android/gradlew +251 -0
  5. package/android/gradlew.bat +94 -0
  6. package/android/src/main/AndroidManifest.xml +1 -5
  7. package/android/src/main/RCTAppDependencyProvider.h +25 -0
  8. package/android/src/main/RCTAppDependencyProvider.mm +55 -0
  9. package/android/src/main/RCTModulesConformingToProtocolsProvider.h +18 -0
  10. package/android/src/main/RCTModulesConformingToProtocolsProvider.mm +33 -0
  11. package/android/src/main/RCTThirdPartyComponentsProvider.h +16 -0
  12. package/android/src/main/RCTThirdPartyComponentsProvider.mm +28 -0
  13. package/android/src/main/ReactAppDependencyProvider.podspec +34 -0
  14. package/android/src/main/java/com/facebook/fbreact/specs/NativeAirMapsModuleSpec.java +63 -0
  15. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsCalloutManagerDelegate.java +35 -0
  16. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsCalloutManagerInterface.java +17 -0
  17. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsCircleManagerDelegate.java +49 -0
  18. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsCircleManagerInterface.java +23 -0
  19. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsGooglePolygonManagerDelegate.java +49 -0
  20. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsGooglePolygonManagerInterface.java +23 -0
  21. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerDelegate.java +209 -0
  22. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsMapViewManagerInterface.java +74 -0
  23. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerDelegate.java +104 -0
  24. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsMarkerManagerInterface.java +39 -0
  25. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsOverlayManagerDelegate.java +45 -0
  26. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsOverlayManagerInterface.java +22 -0
  27. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsPolylineManagerDelegate.java +58 -0
  28. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsPolylineManagerInterface.java +26 -0
  29. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsUrlTileManagerDelegate.java +62 -0
  30. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsUrlTileManagerInterface.java +27 -0
  31. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsWMSTileManagerDelegate.java +56 -0
  32. package/android/src/main/java/com/facebook/react/viewmanagers/RNMapsWMSTileManagerInterface.java +25 -0
  33. package/android/src/main/java/com/rnmaps/fabric/CalloutManager.java +77 -0
  34. package/android/src/main/java/com/rnmaps/fabric/CircleManager.java +94 -0
  35. package/android/src/main/java/com/rnmaps/fabric/JSONUtil.java +86 -0
  36. package/android/src/main/java/com/rnmaps/fabric/MapViewManager.java +623 -0
  37. package/android/src/main/java/com/rnmaps/fabric/MarkerManager.java +258 -0
  38. package/android/src/main/java/com/rnmaps/fabric/NativeAirMapsModule.java +284 -0
  39. package/android/src/main/java/com/rnmaps/fabric/OverlayManager.java +101 -0
  40. package/android/src/main/java/com/rnmaps/fabric/PolygonManager.java +89 -0
  41. package/android/src/main/java/com/rnmaps/fabric/PolylineManager.java +121 -0
  42. package/android/src/main/java/com/rnmaps/fabric/UrlTileManager.java +124 -0
  43. package/android/src/main/java/com/rnmaps/fabric/WMSTileManager.java +114 -0
  44. package/android/src/main/java/com/rnmaps/fabric/event/OnCalloutPressEvent.java +25 -0
  45. package/android/src/main/java/com/rnmaps/fabric/event/OnDeselectEvent.java +28 -0
  46. package/android/src/main/java/com/rnmaps/fabric/event/OnDoublePressEvent.java +27 -0
  47. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEndEvent.java +28 -0
  48. package/android/src/main/java/com/rnmaps/fabric/event/OnDragEvent.java +28 -0
  49. package/android/src/main/java/com/rnmaps/fabric/event/OnDragStartEvent.java +28 -0
  50. package/android/src/main/java/com/rnmaps/fabric/event/OnIndoorBuildingFocusedEvent.java +28 -0
  51. package/android/src/main/java/com/rnmaps/fabric/event/OnIndoorLevelActivatedEvent.java +28 -0
  52. package/android/src/main/java/com/rnmaps/fabric/event/OnKmlReadyEvent.java +28 -0
  53. package/android/src/main/java/com/rnmaps/fabric/event/OnLongPressEvent.java +28 -0
  54. package/android/src/main/java/com/rnmaps/fabric/event/OnMapLoadedEvent.java +29 -0
  55. package/android/src/main/java/com/rnmaps/fabric/event/OnMapReadyEvent.java +29 -0
  56. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDeselectEvent.java +28 -0
  57. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEndEvent.java +28 -0
  58. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragEvent.java +28 -0
  59. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerDragStartEvent.java +28 -0
  60. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerPressEvent.java +28 -0
  61. package/android/src/main/java/com/rnmaps/fabric/event/OnMarkerSelectEvent.java +28 -0
  62. package/android/src/main/java/com/rnmaps/fabric/event/OnPanDragEvent.java +28 -0
  63. package/android/src/main/java/com/rnmaps/fabric/event/OnPoiClickEvent.java +27 -0
  64. package/android/src/main/java/com/rnmaps/fabric/event/OnPressEvent.java +27 -0
  65. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeCompleteEvent.java +30 -0
  66. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeEvent.java +48 -0
  67. package/android/src/main/java/com/rnmaps/fabric/event/OnRegionChangeStartEvent.java +33 -0
  68. package/android/src/main/java/com/rnmaps/fabric/event/OnSelectEvent.java +28 -0
  69. package/android/src/main/java/com/rnmaps/fabric/event/OnUserLocationChangeEvent.java +28 -0
  70. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/FileUtil.java +3 -6
  71. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/FusedLocationSource.java +5 -2
  72. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/ImageReadable.java +1 -1
  73. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/ImageReader.java +5 -7
  74. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/ImageUtil.java +1 -2
  75. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/LatLngBoundsUtils.java +1 -1
  76. package/android/src/main/java/com/rnmaps/maps/MapAirModulePackage.java +98 -0
  77. package/android/src/main/java/com/rnmaps/maps/MapCallout.java +41 -0
  78. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapCalloutManager.java → rnmaps/maps/MapCalloutManager.java} +6 -6
  79. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapCircle.java → rnmaps/maps/MapCircle.java} +34 -8
  80. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapCircleManager.java → rnmaps/maps/MapCircleManager.java} +15 -20
  81. package/android/src/main/java/com/rnmaps/maps/MapFeature.java +17 -0
  82. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapGradientPolyline.java → rnmaps/maps/MapGradientPolyline.java} +9 -12
  83. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapGradientPolylineManager.java → rnmaps/maps/MapGradientPolylineManager.java} +13 -18
  84. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapHeatmap.java → rnmaps/maps/MapHeatmap.java} +8 -9
  85. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapHeatmapManager.java → rnmaps/maps/MapHeatmapManager.java} +8 -8
  86. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapLocalTile.java → rnmaps/maps/MapLocalTile.java} +19 -16
  87. package/android/src/main/java/com/rnmaps/maps/MapLocalTileManager.java +54 -0
  88. package/android/src/main/java/com/rnmaps/maps/MapManager.java +504 -0
  89. package/android/src/main/java/com/rnmaps/maps/MapMarker.java +706 -0
  90. package/android/src/main/java/com/rnmaps/maps/MapMarkerManager.java +368 -0
  91. package/android/src/main/java/com/rnmaps/maps/MapModule.java +283 -0
  92. package/android/src/main/java/com/rnmaps/maps/MapOverlay.java +262 -0
  93. package/android/src/main/java/com/rnmaps/maps/MapOverlayManager.java +97 -0
  94. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapPolygon.java → rnmaps/maps/MapPolygon.java} +73 -9
  95. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapPolygonManager.java → rnmaps/maps/MapPolygonManager.java} +22 -22
  96. package/android/src/main/java/com/rnmaps/maps/MapPolyline.java +230 -0
  97. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapPolylineManager.java → rnmaps/maps/MapPolylineManager.java} +18 -38
  98. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapTileProvider.java → rnmaps/maps/MapTileProvider.java} +55 -76
  99. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapTileWorker.java → rnmaps/maps/MapTileWorker.java} +7 -14
  100. package/android/src/main/java/com/rnmaps/maps/MapUIBlock.java +64 -0
  101. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapUrlTile.java → rnmaps/maps/MapUrlTile.java} +29 -29
  102. package/android/src/main/java/com/rnmaps/maps/MapUrlTileManager.java +87 -0
  103. package/android/src/main/java/com/rnmaps/maps/MapView.java +1844 -0
  104. package/android/src/main/java/com/{airbnb/android/react/maps/AirMapWMSTile.java → rnmaps/maps/MapWMSTile.java} +11 -17
  105. package/android/src/main/java/com/rnmaps/maps/MapWMSTileManager.java +81 -0
  106. package/android/src/main/java/com/rnmaps/maps/MapsPackage.java +45 -0
  107. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/RegionChangeEvent.java +1 -1
  108. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/SizeReportingShadowNode.java +1 -1
  109. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/ViewAttacherGroup.java +2 -7
  110. package/android/src/main/java/com/{airbnb/android/react → rnmaps}/maps/ViewChangesTracker.java +12 -11
  111. package/android/src/main/jni/CMakeLists.txt +36 -0
  112. package/android/src/main/jni/RNMapsSpecs-generated.cpp +68 -0
  113. package/android/src/main/jni/RNMapsSpecs.h +31 -0
  114. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.cpp +31 -0
  115. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/ComponentDescriptors.h +33 -0
  116. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/EventEmitters.cpp +979 -0
  117. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/EventEmitters.h +860 -0
  118. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/Props.cpp +227 -0
  119. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/Props.h +1297 -0
  120. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI-generated.cpp +74 -0
  121. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/RNMapsSpecsJSI.h +268 -0
  122. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.cpp +26 -0
  123. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/ShadowNodes.h +131 -0
  124. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/States.cpp +16 -0
  125. package/android/src/main/jni/react/renderer/components/RNMapsSpecs/States.h +137 -0
  126. package/app.plugin.js +1 -0
  127. package/ios/AirGoogleMaps/AIRGMSMarker.h +2 -0
  128. package/ios/AirGoogleMaps/AIRGoogleMap.h +22 -12
  129. package/ios/AirGoogleMaps/{AIRGoogleMap.m → AIRGoogleMap.mm} +407 -130
  130. package/ios/AirGoogleMaps/AIRGoogleMapCircle.h +2 -3
  131. package/ios/AirGoogleMaps/AIRGoogleMapCircle.m +42 -3
  132. package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.h +13 -0
  133. package/ios/AirGoogleMaps/AIRGoogleMapCoordinate.m +10 -0
  134. package/ios/AirGoogleMaps/AIRGoogleMapHeatmap.h +1 -1
  135. package/ios/AirGoogleMaps/AIRGoogleMapManager.h +11 -0
  136. package/ios/AirGoogleMaps/AIRGoogleMapManager.mm +543 -0
  137. package/ios/AirGoogleMaps/AIRGoogleMapMarker.h +4 -0
  138. package/ios/AirGoogleMaps/AIRGoogleMapMarker.m +369 -237
  139. package/ios/AirGoogleMaps/AIRGoogleMapMarkerManager.m +3 -2
  140. package/ios/AirGoogleMaps/AIRGoogleMapOverlay.h +0 -1
  141. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.h +7 -6
  142. package/ios/AirGoogleMaps/AIRGoogleMapPolygon.m +62 -5
  143. package/ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m +3 -3
  144. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.h +4 -3
  145. package/ios/AirGoogleMaps/AIRGoogleMapPolyline.m +9 -9
  146. package/ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m +2 -2
  147. package/ios/AirGoogleMaps/AIRGoogleMapUrlTile.m +2 -2
  148. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.h +1 -1
  149. package/ios/AirGoogleMaps/AIRGoogleMapWMSTile.m +4 -4
  150. package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h +3 -0
  151. package/ios/AirGoogleMaps/RCTConvert+GMSMapViewType.m +18 -0
  152. package/ios/AirGoogleMaps/RNMapsGoogleMapView.h +29 -0
  153. package/ios/AirGoogleMaps/RNMapsGoogleMapView.mm +678 -0
  154. package/ios/AirGoogleMaps/RNMapsGoogleMapViewManager.mm +40 -0
  155. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.h +26 -0
  156. package/ios/AirGoogleMaps/RNMapsGooglePolygonView.mm +226 -0
  157. package/ios/AirGoogleMaps/RNMapsGooglePolygonViewManager.mm +26 -0
  158. package/ios/AirGoogleMaps/Resources/GoogleMapsPrivacy.bundle/PrivacyInfo.xcprivacy +110 -0
  159. package/ios/AirMaps/AIRMap.h +19 -14
  160. package/ios/AirMaps/{AIRMap.m → AIRMap.mm} +333 -120
  161. package/ios/AirMaps/AIRMapCircle.m +1 -53
  162. package/ios/AirMaps/AIRMapCoordinate.m +2 -4
  163. package/ios/AirMaps/AIRMapManager.m +64 -218
  164. package/ios/AirMaps/AIRMapMarker.h +5 -0
  165. package/ios/AirMaps/AIRMapMarker.m +180 -69
  166. package/ios/AirMaps/AIRMapMarkerManager.m +3 -0
  167. package/ios/AirMaps/AIRMapOverlay.m +2 -2
  168. package/ios/AirMaps/AIRMapPolygon.m +0 -52
  169. package/ios/AirMaps/AIRMapPolyline.m +3 -2
  170. package/ios/AirMaps/AIRMapWMSTile.m +8 -8
  171. package/ios/AirMaps/Callout/SMCalloutView.m +1 -1
  172. package/ios/AirMaps/FabricPlaceholders/PlaceHolderGoogleMapView.h +25 -0
  173. package/ios/AirMaps/FabricPlaceholders/PlaceHolderGoogleMapView.mm +77 -0
  174. package/ios/AirMaps/FabricPlaceholders/PlaceHolderPolygonView.h +25 -0
  175. package/ios/AirMaps/FabricPlaceholders/PlaceHolderPolygonView.mm +52 -0
  176. package/ios/AirMaps/RCTComponentData+Maps.h +13 -0
  177. package/ios/AirMaps/RCTComponentData+Maps.m +55 -0
  178. package/ios/AirMaps/RCTConvert+AirMap.h +6 -1
  179. package/ios/AirMaps/RCTConvert+AirMap.m +18 -0
  180. package/ios/AirMaps/RNMapsAirModule.h +15 -0
  181. package/ios/AirMaps/RNMapsAirModule.mm +164 -0
  182. package/ios/AirMaps/RNMapsDefines.h +1 -0
  183. package/ios/AirMaps/RNMapsMapView.h +27 -0
  184. package/ios/AirMaps/RNMapsMapView.mm +577 -0
  185. package/ios/AirMaps/RNMapsMapViewManager.mm +42 -0
  186. package/ios/AirMaps/RNMapsMarkerView.h +24 -0
  187. package/ios/AirMaps/RNMapsMarkerView.mm +439 -0
  188. package/ios/AirMaps/RNMapsMarkerViewManager.mm +28 -0
  189. package/ios/AirMaps/UIView+AirMap.h +11 -0
  190. package/ios/AirMaps/UIView+AirMap.m +20 -0
  191. package/ios/AirMaps/module.modulemap +6 -0
  192. package/ios/AirMaps.xcodeproj/project.pbxproj +44 -4
  193. package/ios/PrivacyInfo.xcprivacy +37 -0
  194. package/ios/generated/RCTAppDependencyProvider.h +25 -0
  195. package/ios/generated/RCTAppDependencyProvider.mm +55 -0
  196. package/ios/generated/RCTModulesConformingToProtocolsProvider.h +18 -0
  197. package/ios/generated/RCTModulesConformingToProtocolsProvider.mm +33 -0
  198. package/ios/generated/RCTThirdPartyComponentsProvider.h +16 -0
  199. package/ios/generated/RCTThirdPartyComponentsProvider.mm +26 -0
  200. package/ios/generated/RNMapsAirModuleDelegate.h +24 -0
  201. package/ios/generated/RNMapsHostVewDelegate.h +17 -0
  202. package/ios/generated/RNMapsSpecs/ComponentDescriptors.cpp +29 -0
  203. package/ios/generated/RNMapsSpecs/ComponentDescriptors.h +31 -0
  204. package/ios/generated/RNMapsSpecs/EventEmitters.cpp +977 -0
  205. package/ios/generated/RNMapsSpecs/EventEmitters.h +846 -0
  206. package/ios/generated/RNMapsSpecs/Props.cpp +194 -0
  207. package/ios/generated/RNMapsSpecs/Props.h +1224 -0
  208. package/ios/generated/RNMapsSpecs/RCTComponentViewHelpers.h +591 -0
  209. package/ios/generated/RNMapsSpecs/RNMapsSpecs-generated.mm +92 -0
  210. package/ios/generated/RNMapsSpecs/RNMapsSpecs.h +137 -0
  211. package/ios/generated/RNMapsSpecs/ShadowNodes.cpp +24 -0
  212. package/ios/generated/RNMapsSpecs/ShadowNodes.h +109 -0
  213. package/ios/generated/RNMapsSpecs/States.cpp +16 -0
  214. package/ios/generated/RNMapsSpecs/States.h +113 -0
  215. package/ios/generated/RNMapsSpecsJSI-generated.cpp +74 -0
  216. package/ios/generated/RNMapsSpecsJSI.h +268 -0
  217. package/ios/generated/ReactAppDependencyProvider.podspec +34 -0
  218. package/ios/generated/module.modulemap +15 -0
  219. package/package.json +57 -34
  220. package/plugin/build/android.js +58 -0
  221. package/plugin/build/index.js +10 -0
  222. package/plugin/build/ios.js +176 -0
  223. package/plugin/build/types.js +2 -0
  224. package/react-native-maps.podspec +114 -11
  225. package/react-native.config.js +15 -0
  226. package/src/{AnimatedRegion.js → AnimatedRegion.ts} +26 -21
  227. package/src/Geojson.tsx +541 -0
  228. package/src/MapCallout.tsx +77 -0
  229. package/src/MapCalloutSubview.tsx +64 -0
  230. package/src/MapCircle.tsx +162 -0
  231. package/src/MapHeatmap.tsx +125 -0
  232. package/src/MapLocalTile.tsx +60 -0
  233. package/src/MapMarker.tsx +531 -0
  234. package/src/MapMarkerNativeComponent.ts +51 -0
  235. package/src/MapOverlay.tsx +178 -0
  236. package/src/MapPolygon.tsx +188 -0
  237. package/src/MapPolygon.types.ts +25 -0
  238. package/src/MapPolyline.tsx +215 -0
  239. package/src/MapUrlTile.tsx +169 -0
  240. package/src/MapView.tsx +1235 -0
  241. package/src/MapView.types.ts +212 -0
  242. package/src/MapView.web.ts +2 -0
  243. package/src/MapViewNativeComponent.ts +86 -0
  244. package/src/MapWMSTile.tsx +148 -0
  245. package/src/ProviderConstants.ts +2 -0
  246. package/src/createFabricMap.tsx +253 -0
  247. package/src/decorateMapComponent.ts +230 -0
  248. package/src/fixImageProp.ts +17 -0
  249. package/src/index.ts +52 -0
  250. package/src/sharedTypes.ts +101 -0
  251. package/src/sharedTypesInternal.ts +1 -0
  252. package/src/specs/NativeAirMapsModule.ts +36 -0
  253. package/src/specs/NativeComponentCallout.ts +63 -0
  254. package/src/specs/NativeComponentCircle.ts +93 -0
  255. package/src/specs/NativeComponentGoogleMapView.ts +922 -0
  256. package/src/specs/NativeComponentGooglePolygon.ts +94 -0
  257. package/src/specs/NativeComponentMapView.ts +1100 -0
  258. package/src/specs/NativeComponentMarker.ts +326 -0
  259. package/src/specs/NativeComponentOverlay.ts +98 -0
  260. package/src/specs/NativeComponentPolyline.ts +124 -0
  261. package/src/specs/NativeComponentUrlTile.ts +128 -0
  262. package/src/specs/NativeComponentWMSTile.ts +107 -0
  263. package/LICENSE +0 -21
  264. package/README.md +0 -652
  265. package/android/src/main/assets/ula.kml +0 -1214
  266. package/android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java +0 -23
  267. package/android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java +0 -18
  268. package/android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java +0 -20
  269. package/android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTileManager.java +0 -56
  270. package/android/src/main/java/com/airbnb/android/react/maps/AirMapManager.java +0 -500
  271. package/android/src/main/java/com/airbnb/android/react/maps/AirMapMarker.java +0 -630
  272. package/android/src/main/java/com/airbnb/android/react/maps/AirMapMarkerManager.java +0 -370
  273. package/android/src/main/java/com/airbnb/android/react/maps/AirMapModule.java +0 -380
  274. package/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlay.java +0 -169
  275. package/android/src/main/java/com/airbnb/android/react/maps/AirMapOverlayManager.java +0 -81
  276. package/android/src/main/java/com/airbnb/android/react/maps/AirMapPolyline.java +0 -162
  277. package/android/src/main/java/com/airbnb/android/react/maps/AirMapUrlTileManager.java +0 -97
  278. package/android/src/main/java/com/airbnb/android/react/maps/AirMapView.java +0 -1384
  279. package/android/src/main/java/com/airbnb/android/react/maps/AirMapWMSTileManager.java +0 -87
  280. package/android/src/main/java/com/airbnb/android/react/maps/MapsPackage.java +0 -65
  281. package/index.d.ts +0 -637
  282. package/ios/AirGoogleMaps/AIRGoogleMapManager.m +0 -690
  283. package/ios/User.xcconfig +0 -0
  284. package/react-native-google-maps.podspec +0 -22
  285. package/src/Geojson.js +0 -334
  286. package/src/MapCallout.js +0 -51
  287. package/src/MapCalloutSubview.js +0 -44
  288. package/src/MapCircle.js +0 -150
  289. package/src/MapHeatmap.js +0 -99
  290. package/src/MapLocalTile.js +0 -52
  291. package/src/MapMarker.js +0 -377
  292. package/src/MapOverlay.js +0 -86
  293. package/src/MapPolygon.js +0 -202
  294. package/src/MapPolyline.js +0 -168
  295. package/src/MapUrlTile.js +0 -131
  296. package/src/MapView.js +0 -1160
  297. package/src/MapView.web.js +0 -1
  298. package/src/MapWMSTile.js +0 -122
  299. package/src/ProviderConstants.js +0 -2
  300. package/src/decorateMapComponent.js +0 -112
  301. package/src/index.js +0 -31
@@ -0,0 +1,1844 @@
1
+ package com.rnmaps.maps;
2
+
3
+ import static androidx.core.content.PermissionChecker.checkSelfPermission;
4
+
5
+ import android.app.Activity;
6
+ import android.content.Context;
7
+ import android.content.res.ColorStateList;
8
+ import android.graphics.Bitmap;
9
+ import android.graphics.Color;
10
+ import android.graphics.Point;
11
+ import android.location.Location;
12
+
13
+ import androidx.lifecycle.DefaultLifecycleObserver;
14
+ import androidx.lifecycle.LifecycleOwner;
15
+
16
+ import android.view.GestureDetector;
17
+ import android.view.MotionEvent;
18
+ import android.view.View;
19
+ import android.view.ViewGroup;
20
+ import android.widget.ImageView;
21
+ import android.widget.ProgressBar;
22
+ import android.widget.RelativeLayout;
23
+
24
+ import androidx.annotation.NonNull;
25
+ import androidx.annotation.Nullable;
26
+ import androidx.core.content.PermissionChecker;
27
+ import androidx.core.view.GestureDetectorCompat;
28
+ import androidx.core.view.MotionEventCompat;
29
+
30
+ import com.facebook.react.common.MapBuilder;
31
+
32
+ import com.facebook.react.bridge.Arguments;
33
+ import com.facebook.react.bridge.ReactApplicationContext;
34
+ import com.facebook.react.bridge.ReactContext;
35
+ import com.facebook.react.bridge.ReadableArray;
36
+ import com.facebook.react.bridge.ReadableMap;
37
+ import com.facebook.react.bridge.WritableArray;
38
+ import com.facebook.react.bridge.WritableMap;
39
+ import com.facebook.react.bridge.WritableNativeArray;
40
+ import com.facebook.react.bridge.WritableNativeMap;
41
+ import com.facebook.react.uimanager.ThemedReactContext;
42
+ import com.facebook.react.uimanager.UIManagerHelper;
43
+ import com.facebook.react.uimanager.events.Event;
44
+ import com.facebook.react.uimanager.events.EventDispatcher;
45
+ import com.google.android.gms.maps.CameraUpdate;
46
+ import com.google.android.gms.maps.CameraUpdateFactory;
47
+ import com.google.android.gms.maps.GoogleMap;
48
+ import com.google.android.gms.maps.GoogleMapOptions;
49
+ import com.google.android.gms.maps.OnMapReadyCallback;
50
+ import com.google.android.gms.maps.Projection;
51
+ import com.google.android.gms.maps.model.BitmapDescriptorFactory;
52
+ import com.google.android.gms.maps.model.CameraPosition;
53
+ import com.google.android.gms.maps.model.GroundOverlay;
54
+ import com.google.android.gms.maps.model.IndoorBuilding;
55
+ import com.google.android.gms.maps.model.IndoorLevel;
56
+ import com.google.android.gms.maps.model.LatLng;
57
+ import com.google.android.gms.maps.model.LatLngBounds;
58
+ import com.google.android.gms.maps.model.MapStyleOptions;
59
+ import com.google.android.gms.maps.model.Marker;
60
+ import com.google.android.gms.maps.model.MarkerOptions;
61
+ import com.google.android.gms.maps.model.PointOfInterest;
62
+ import com.google.android.gms.maps.model.Polygon;
63
+ import com.google.android.gms.maps.model.Polyline;
64
+ import com.google.android.gms.maps.model.TileOverlay;
65
+ import com.google.maps.android.collections.CircleManager;
66
+ import com.google.maps.android.collections.GroundOverlayManager;
67
+ import com.google.maps.android.collections.MarkerManager;
68
+ import com.google.maps.android.collections.PolygonManager;
69
+ import com.google.maps.android.collections.PolylineManager;
70
+ import com.google.maps.android.data.kml.KmlContainer;
71
+ import com.google.maps.android.data.kml.KmlLayer;
72
+ import com.google.maps.android.data.kml.KmlPlacemark;
73
+
74
+ import org.json.JSONException;
75
+ import org.json.JSONObject;
76
+ import org.xmlpull.v1.XmlPullParserException;
77
+
78
+ import java.io.IOException;
79
+ import java.io.InputStream;
80
+ import java.util.ArrayList;
81
+ import java.util.Arrays;
82
+ import java.util.HashMap;
83
+ import java.util.Iterator;
84
+ import java.util.List;
85
+ import java.util.Map;
86
+ import java.util.concurrent.ExecutionException;
87
+
88
+ import com.rnmaps.fabric.event.*;
89
+
90
+ public class MapView extends com.google.android.gms.maps.MapView implements GoogleMap.InfoWindowAdapter,
91
+ GoogleMap.OnMarkerDragListener, OnMapReadyCallback, GoogleMap.OnPoiClickListener, GoogleMap.OnIndoorStateChangeListener, DefaultLifecycleObserver {
92
+ public GoogleMap map;
93
+ private MarkerManager markerManager;
94
+ private MarkerManager.Collection markerCollection;
95
+ private PolylineManager polylineManager;
96
+ private PolylineManager.Collection polylineCollection;
97
+ private PolygonManager polygonManager;
98
+ private PolygonManager.Collection polygonCollection;
99
+ private CircleManager.Collection circleCollection;
100
+ private GroundOverlayManager groundOverlayManager;
101
+ private GroundOverlayManager.Collection groundOverlayCollection;
102
+ private ProgressBar mapLoadingProgressBar;
103
+ private RelativeLayout mapLoadingLayout;
104
+ private ImageView cacheImageView;
105
+ private Boolean isMapLoaded = false;
106
+
107
+ private Boolean isMapReady = false;
108
+
109
+ private Integer loadingBackgroundColor = null;
110
+ private Integer loadingIndicatorColor = null;
111
+
112
+ private LatLngBounds boundsToMove;
113
+ private CameraUpdate cameraToSet;
114
+ private boolean setPaddingDeferred = false;
115
+ private boolean showUserLocation = false;
116
+
117
+ private boolean showsTraffic = false;
118
+
119
+ private boolean handlePanDrag = false;
120
+ private boolean moveOnMarkerPress = true;
121
+ private boolean cacheEnabled = false;
122
+ private boolean poiClickEnabled = true;
123
+
124
+ private ReadableMap initialRegion;
125
+ private ReadableMap region;
126
+ private ReadableMap initialCamera;
127
+ private ReadableMap camera;
128
+ private String customMapStyleString;
129
+ private boolean initialRegionSet = false;
130
+ private boolean initialCameraSet = false;
131
+ private LatLngBounds cameraLastIdleBounds;
132
+ private int cameraMoveReason = 0;
133
+ private MapMarker selectedMarker;
134
+
135
+ private static final String[] PERMISSIONS = new String[]{
136
+ "android.permission.ACCESS_FINE_LOCATION", "android.permission.ACCESS_COARSE_LOCATION"};
137
+
138
+ private final List<MapFeature> features = new ArrayList<>();
139
+ private final Map<Marker, MapMarker> markerMap = new HashMap<>();
140
+ private final Map<Polyline, MapPolyline> polylineMap = new HashMap<>();
141
+ private final Map<Polygon, MapPolygon> polygonMap = new HashMap<>();
142
+ private final Map<GroundOverlay, MapOverlay> overlayMap = new HashMap<>();
143
+ private final Map<TileOverlay, MapHeatmap> heatmapMap = new HashMap<>();
144
+ private final Map<TileOverlay, MapGradientPolyline> gradientPolylineMap = new HashMap<>();
145
+ private final GestureDetectorCompat gestureDetector;
146
+ private boolean paused = false;
147
+ private boolean destroyed = false;
148
+ private final ThemedReactContext context;
149
+ private final FusedLocationSource fusedLocationSource;
150
+
151
+ private final ViewAttacherGroup attacherGroup;
152
+ private LatLng tapLocation;
153
+ private Float maxZoomLevel;
154
+ private Float minZoomLevel;
155
+ private Boolean pitchEnabled;
156
+ private Boolean showsCompass;
157
+ private Boolean rotateEnabled;
158
+ private Boolean zoomEnabled;
159
+ private Boolean zoomControlEnabled;
160
+ private Boolean setShowBuildings;
161
+ private Boolean showsIndoorLevelPicker;
162
+ private Boolean showIndoors;
163
+ private Boolean scrollEnabled;
164
+ private Boolean scrollDuringRotateOrZoomEnabled;
165
+ private String kmlSrc = null;
166
+
167
+ private static boolean contextHasBug(Context context) {
168
+ return context == null ||
169
+ context.getResources() == null ||
170
+ context.getResources().getConfiguration() == null;
171
+ }
172
+
173
+ // We do this to fix this bug:
174
+ // https://github.com/react-native-maps/react-native-maps/issues/271
175
+ //
176
+ // which conflicts with another bug regarding the passed in context:
177
+ // https://github.com/react-native-maps/react-native-maps/issues/1147
178
+ //
179
+ // Doing this allows us to avoid both bugs.
180
+ private static Context getNonBuggyContext(ThemedReactContext reactContext,
181
+ ReactApplicationContext appContext) {
182
+ Context superContext = reactContext;
183
+ if (!contextHasBug(appContext.getCurrentActivity())) {
184
+ superContext = appContext.getCurrentActivity();
185
+ } else if (contextHasBug(superContext)) {
186
+ // we have the bug! let's try to find a better context to use
187
+ if (!contextHasBug(reactContext.getCurrentActivity())) {
188
+ superContext = reactContext.getCurrentActivity();
189
+ } else if (!contextHasBug(reactContext.getApplicationContext())) {
190
+ superContext = reactContext.getApplicationContext();
191
+ }
192
+
193
+ }
194
+ return superContext;
195
+ }
196
+
197
+
198
+ @Override
199
+ public void onCreate(LifecycleOwner owner) {
200
+ super.onCreate(null);
201
+ }
202
+
203
+ @Override
204
+ public void onStart(LifecycleOwner owner) {
205
+ super.onStart();
206
+ }
207
+
208
+ @Override
209
+ public void onResume(LifecycleOwner owner) {
210
+ if (hasPermissions() && map != null) {
211
+ //noinspection MissingPermission
212
+ map.setMyLocationEnabled(showUserLocation);
213
+ map.setLocationSource(fusedLocationSource);
214
+ }
215
+ synchronized (MapView.this) {
216
+ if (!destroyed) {
217
+ MapView.this.onResume();
218
+ }
219
+ paused = false;
220
+ }
221
+ }
222
+
223
+
224
+ @Override
225
+ public void onPause(LifecycleOwner owner) {
226
+ super.onPause();
227
+ if (hasPermissions() && map != null) {
228
+ //noinspection MissingPermission
229
+ map.setMyLocationEnabled(false);
230
+ }
231
+ synchronized (MapView.this) {
232
+ if (!destroyed) {
233
+ MapView.this.onPause();
234
+ }
235
+ paused = true;
236
+ }
237
+ }
238
+
239
+ @Override
240
+ public void onStop(LifecycleOwner owner) {
241
+ super.onStop();
242
+ }
243
+
244
+ @Override
245
+ public void onDestroy(LifecycleOwner owner) {
246
+ MapView.this.doDestroy();
247
+ }
248
+
249
+ public MapView(ThemedReactContext context,
250
+ GoogleMapOptions googleMapOptions) {
251
+ super(context, googleMapOptions);
252
+ this.context = context;
253
+ Activity activity = context.getCurrentActivity();
254
+ if (activity instanceof LifecycleOwner) {
255
+ ((LifecycleOwner) activity).getLifecycle().addObserver(this);
256
+ }
257
+ super.getMapAsync(this);
258
+
259
+ final MapView view = this;
260
+
261
+ fusedLocationSource = new FusedLocationSource(context);
262
+
263
+ gestureDetector =
264
+ new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {
265
+
266
+ @Override
267
+ public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
268
+ float distanceY) {
269
+ if (handlePanDrag) {
270
+ onPanDrag(e2);
271
+ }
272
+ return false;
273
+ }
274
+
275
+ @Override
276
+ public boolean onDoubleTap(MotionEvent ev) {
277
+ onDoublePress(ev);
278
+ return false;
279
+ }
280
+ });
281
+
282
+ this.addOnLayoutChangeListener(new OnLayoutChangeListener() {
283
+ @Override
284
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
285
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
286
+ if (!paused) {
287
+ MapView.this.cacheView();
288
+ }
289
+ }
290
+ });
291
+
292
+
293
+ // Set up a parent view for triggering visibility in subviews that depend on it.
294
+ // Mainly ReactImageView depends on Fresco which depends on onVisibilityChanged() event
295
+ attacherGroup = new ViewAttacherGroup(context);
296
+ LayoutParams attacherLayoutParams = new LayoutParams(0, 0);
297
+ attacherLayoutParams.width = 0;
298
+ attacherLayoutParams.height = 0;
299
+ attacherLayoutParams.leftMargin = 99999999;
300
+ attacherLayoutParams.topMargin = 99999999;
301
+ attacherGroup.setLayoutParams(attacherLayoutParams);
302
+ addView(attacherGroup);
303
+ }
304
+
305
+ public MapView(ThemedReactContext reactContext, ReactApplicationContext appContext,
306
+ MapManager manager,
307
+ GoogleMapOptions googleMapOptions) {
308
+ this(null, googleMapOptions);
309
+
310
+ }
311
+
312
+ public double[][] getMarkersFrames(boolean onlyVisible) {
313
+
314
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
315
+ boolean addedPosition = false;
316
+ LatLngBounds mapBounds = map.getProjection().getVisibleRegion().latLngBounds;
317
+ for (MapFeature feature : features) {
318
+ if (feature instanceof MapMarker) {
319
+ Marker marker = (Marker) feature.getFeature();
320
+ if (!onlyVisible ||
321
+ mapBounds.contains(marker.getPosition())) {
322
+ builder.include(marker.getPosition());
323
+ addedPosition = true;
324
+ }
325
+ }
326
+ }
327
+ if (addedPosition) {
328
+
329
+ LatLngBounds bounds = builder.build();
330
+ LatLng northEast = bounds.northeast;
331
+ LatLng southWest = bounds.southwest;
332
+
333
+ return new double[][]{
334
+ {northEast.longitude, northEast.latitude},
335
+ {southWest.longitude, southWest.latitude}
336
+ };
337
+ }
338
+ return null;
339
+ }
340
+
341
+ public void setShowsTraffic(boolean value) {
342
+ showsTraffic = value;
343
+ if (map != null) {
344
+ map.setTrafficEnabled(value);
345
+ }
346
+ }
347
+
348
+
349
+ @FunctionalInterface
350
+ public interface EventCreator<T extends Event> {
351
+ T create(int surfaceId, int viewId, WritableMap payload);
352
+ }
353
+
354
+ private <T extends Event> void dispatchEvent(WritableMap payload, EventCreator<T> creator) {
355
+ dispatchEvent(payload, creator, getId(), context);
356
+ }
357
+
358
+ public static <T extends Event> void dispatchEvent(WritableMap payload, EventCreator<T> creator, int viewId, ReactContext context) {
359
+ // Cast context to ReactContext
360
+ ReactContext reactContext = context;
361
+
362
+ // Get the event dispatcher
363
+ EventDispatcher eventDispatcher = UIManagerHelper.getEventDispatcherForReactTag(reactContext, viewId);
364
+
365
+ // If there is a dispatcher, create and dispatch the event
366
+ if (eventDispatcher != null) {
367
+ int surfaceId = UIManagerHelper.getSurfaceId(reactContext);
368
+ T event = creator.create(surfaceId, viewId, payload);
369
+ eventDispatcher.dispatchEvent(event);
370
+ }
371
+ }
372
+
373
+ @Override
374
+ public void onMapReady(@NonNull final GoogleMap map) {
375
+ if (destroyed) {
376
+ return;
377
+ }
378
+ this.map = map;
379
+ if (maxZoomLevel != null) {
380
+ setMaxZoomLevel(maxZoomLevel);
381
+ }
382
+ if (minZoomLevel != null) {
383
+ setMinZoomLevel(minZoomLevel);
384
+ }
385
+ if (pitchEnabled != null) {
386
+ setPitchEnabled(pitchEnabled);
387
+ }
388
+ if (showsCompass != null) {
389
+ setShowsCompass(showsCompass);
390
+ }
391
+ if (rotateEnabled != null) {
392
+ setRotateEnabled(rotateEnabled);
393
+ }
394
+ if (zoomEnabled != null) {
395
+ setZoomEnabled(zoomEnabled);
396
+ }
397
+ if (zoomControlEnabled != null) {
398
+ setZoomControlEnabled(zoomControlEnabled);
399
+ }
400
+ if (setShowBuildings != null) {
401
+ setShowBuildings(setShowBuildings);
402
+ }
403
+ if (showsIndoorLevelPicker != null) {
404
+ setShowsIndoorLevelPicker(showsIndoorLevelPicker);
405
+ }
406
+ if (showIndoors != null) {
407
+ setShowIndoors(showIndoors);
408
+ }
409
+ if (scrollEnabled != null) {
410
+ setScrollEnabled(scrollEnabled);
411
+ }
412
+ if (scrollDuringRotateOrZoomEnabled != null) {
413
+ setScrollDuringRotateOrZoomEnabled(scrollDuringRotateOrZoomEnabled);
414
+ }
415
+
416
+ markerManager = new MarkerManager(map);
417
+ markerCollection = markerManager.newCollection();
418
+ polylineManager = new PolylineManager(map);
419
+ polylineCollection = polylineManager.newCollection();
420
+ polygonManager = new PolygonManager(map);
421
+ polygonCollection = polygonManager.newCollection();
422
+ CircleManager circleManager = new CircleManager(map);
423
+ circleCollection = circleManager.newCollection();
424
+ groundOverlayManager = new GroundOverlayManager(map);
425
+ groundOverlayCollection = groundOverlayManager.newCollection();
426
+
427
+ markerCollection.setInfoWindowAdapter(this);
428
+ markerCollection.setOnMarkerDragListener(this);
429
+ this.map.setOnIndoorStateChangeListener(this);
430
+
431
+ applyBridgedProps();
432
+ dispatchEvent(new WritableNativeMap(), OnMapReadyEvent::new);
433
+
434
+ final MapView view = this;
435
+
436
+ map.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
437
+ @Override
438
+ public void onMyLocationChange(Location location) {
439
+ WritableMap event = new WritableNativeMap();
440
+
441
+ WritableMap coordinate = new WritableNativeMap();
442
+ coordinate.putDouble("latitude", location.getLatitude());
443
+ coordinate.putDouble("longitude", location.getLongitude());
444
+ coordinate.putDouble("altitude", location.getAltitude());
445
+ coordinate.putDouble("timestamp", location.getTime());
446
+ coordinate.putDouble("accuracy", location.getAccuracy());
447
+ coordinate.putDouble("speed", location.getSpeed());
448
+ coordinate.putDouble("heading", location.getBearing());
449
+ coordinate.putBoolean("isFromMockProvider", location.isFromMockProvider());
450
+
451
+ event.putMap("coordinate", coordinate);
452
+ dispatchEvent(event, OnUserLocationChangeEvent::new);
453
+ }
454
+ });
455
+
456
+ markerCollection.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
457
+ @Override
458
+ public boolean onMarkerClick(@NonNull Marker marker) {
459
+ MapMarker airMapMarker = getMarkerMap(marker);
460
+
461
+ WritableMap eventData = makeClickEventData(marker.getPosition());
462
+ eventData.putString("action", "press");
463
+ eventData.putString("id", airMapMarker.getIdentifier());
464
+ airMapMarker.dispatchEvent(eventData, OnPressEvent::new);
465
+
466
+ WritableMap mapEventData = makeClickEventData(marker.getPosition());
467
+ mapEventData.putString("action", "marker-press");
468
+ mapEventData.putString("id", airMapMarker.getIdentifier());
469
+
470
+ dispatchEvent(mapEventData, OnMarkerPressEvent::new);
471
+
472
+
473
+ handleMarkerSelection(airMapMarker);
474
+
475
+ // Return false to open the callout info window and center on the marker
476
+ // https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap
477
+ // .OnMarkerClickListener
478
+ if (view.moveOnMarkerPress) {
479
+ return false;
480
+ } else {
481
+ marker.showInfoWindow();
482
+ return true;
483
+ }
484
+ }
485
+ });
486
+
487
+ polygonCollection.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
488
+ @Override
489
+ public void onPolygonClick(@NonNull Polygon polygon) {
490
+ WritableMap event = makeClickEventData(tapLocation);
491
+ event.putString("action", "polygon-press");
492
+ MapPolygon mapPolygon = polygonMap.get(polygon);
493
+ mapPolygon.dispatchEvent(event, OnPressEvent::new, context);
494
+ event = makeClickEventData(tapLocation);
495
+ event.putString("action", "polygon-press");
496
+ event.putString("id", String.valueOf(mapPolygon.getId()));
497
+ dispatchEvent(event, OnPressEvent::new);
498
+ }
499
+ });
500
+
501
+ polylineCollection.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
502
+ @Override
503
+ public void onPolylineClick(@NonNull Polyline polyline) {
504
+ WritableMap event = makeClickEventData(tapLocation);
505
+ event.putString("action", "polyline-press");
506
+ dispatchEvent(event, OnPressEvent::new);
507
+ event = makeClickEventData(tapLocation);
508
+ dispatchEvent(event, OnPressEvent::new, polylineMap.get(polyline).getId(), context);
509
+
510
+ }
511
+ });
512
+
513
+ markerCollection.setOnInfoWindowClickListener(marker -> {
514
+ WritableMap event = makeClickEventData(marker.getPosition());
515
+ event.putString("action", "callout-press");
516
+ dispatchEvent(event, OnCalloutPressEvent::new);
517
+
518
+
519
+ event = makeClickEventData(marker.getPosition());
520
+ event.putString("action", "callout-press");
521
+ MapMarker markerView = getMarkerMap(marker);
522
+ dispatchEvent(event, OnCalloutPressEvent::new, markerView.getId(), context);
523
+
524
+ MapCallout infoWindow = markerView.getCalloutView();
525
+ if (infoWindow != null) {
526
+ event = makeClickEventData(marker.getPosition());
527
+ event.putString("action", "callout-press");
528
+ dispatchEvent(event, OnPressEvent::new, infoWindow.getId(), context);
529
+ }
530
+ });
531
+
532
+ map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
533
+ @Override
534
+ public void onMapClick(@NonNull LatLng point) {
535
+ WritableMap event = makeClickEventData(point);
536
+ event.putString("action", "press");
537
+ dispatchEvent(event, OnPressEvent::new);
538
+
539
+ handleMarkerSelection(null);
540
+ }
541
+ });
542
+
543
+ map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
544
+ @Override
545
+ public void onMapLongClick(@NonNull LatLng point) {
546
+ WritableMap event = makeClickEventData(point);
547
+ event.putString("action", "long-press");
548
+ dispatchEvent(event, OnLongPressEvent::new);
549
+ }
550
+ });
551
+
552
+ groundOverlayCollection.setOnGroundOverlayClickListener(new GoogleMap.OnGroundOverlayClickListener() {
553
+ @Override
554
+ public void onGroundOverlayClick(@NonNull GroundOverlay groundOverlay) {
555
+ WritableMap event = makeClickEventData(groundOverlay.getPosition());
556
+ event.putString("action", "overlay-press");
557
+
558
+ dispatchEvent(event, OnPressEvent::new);
559
+ event = makeClickEventData(groundOverlay.getPosition());
560
+ dispatchEvent(event, OnPressEvent::new, overlayMap.get(groundOverlay).getId(), context);
561
+ }
562
+ });
563
+
564
+ map.setOnCameraMoveStartedListener(reason -> {
565
+ cameraMoveReason = reason;
566
+ boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == reason;
567
+ WritableMap event = new WritableNativeMap();
568
+ event.putBoolean("isGesture", isGesture);
569
+ dispatchEvent(event, OnRegionChangeStartEvent::new);
570
+ });
571
+
572
+ map.setOnCameraMoveListener(() -> {
573
+ LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
574
+ cameraLastIdleBounds = null;
575
+ boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason;
576
+ WritableMap payload = OnRegionChangeEvent.payLoadFor(bounds, false, isGesture);
577
+ dispatchEvent(payload, OnRegionChangeStartEvent::new);
578
+ });
579
+
580
+ map.setOnCameraIdleListener(() -> {
581
+ LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
582
+ if ((cameraMoveReason != 0) &&
583
+ ((cameraLastIdleBounds == null) ||
584
+ LatLngBoundsUtils.BoundsAreDifferent(bounds, cameraLastIdleBounds))) {
585
+
586
+ cameraLastIdleBounds = bounds;
587
+ boolean isGesture = GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE == cameraMoveReason;
588
+ WritableMap payload = OnRegionChangeEvent.payLoadFor(bounds, false, isGesture);
589
+ dispatchEvent(payload, OnRegionChangeCompleteEvent::new);
590
+ }
591
+ });
592
+
593
+ map.setOnMapLoadedCallback(() -> {
594
+ isMapLoaded = true;
595
+ dispatchEvent(new WritableNativeMap(), OnMapLoadedEvent::new);
596
+ MapView.this.cacheView();
597
+ });
598
+
599
+
600
+ map.setTrafficEnabled(showsTraffic);
601
+
602
+
603
+ isMapReady = true;
604
+ if (kmlSrc != null) {
605
+ setKmlSrc(kmlSrc);
606
+ kmlSrc = null;
607
+ }
608
+ }
609
+
610
+ private synchronized void handleMarkerSelection(MapMarker target) {
611
+ if (selectedMarker == target) {
612
+ return;
613
+ }
614
+
615
+ WritableMap event;
616
+
617
+ if (selectedMarker != null) {
618
+ event = makeClickEventData(selectedMarker.getPosition());
619
+ event.putString("action", "marker-deselect");
620
+ event.putString("id", selectedMarker.getIdentifier());
621
+ selectedMarker.dispatchEvent(event, OnDeselectEvent::new);
622
+
623
+ event = makeClickEventData(selectedMarker.getPosition());
624
+ event.putString("action", "marker-deselect");
625
+ event.putString("id", selectedMarker.getIdentifier());
626
+ dispatchEvent(event, OnMarkerDeselectEvent::new);
627
+ }
628
+
629
+ if (target != null) {
630
+ event = makeClickEventData(target.getPosition());
631
+ event.putString("action", "marker-select");
632
+ event.putString("id", target.getIdentifier());
633
+ target.dispatchEvent(event, OnSelectEvent::new);
634
+
635
+ event = makeClickEventData(target.getPosition());
636
+ event.putString("action", "marker-select");
637
+ event.putString("id", target.getIdentifier());
638
+ dispatchEvent(event, OnMarkerSelectEvent::new);
639
+ }
640
+
641
+ selectedMarker = target;
642
+ }
643
+
644
+ private boolean hasPermissions() {
645
+ return checkSelfPermission(getContext(), PERMISSIONS[0]) == PermissionChecker.PERMISSION_GRANTED ||
646
+ checkSelfPermission(getContext(), PERMISSIONS[1]) == PermissionChecker.PERMISSION_GRANTED;
647
+ }
648
+
649
+
650
+ public static Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
651
+ MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
652
+ builder.put(OnPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPressEvent.EVENT_NAME));
653
+ builder.put(OnLongPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnLongPressEvent.EVENT_NAME));
654
+ return builder.build();
655
+ }
656
+
657
+ // , ,
658
+ public static Map<String, Object> getExportedCustomDirectEventTypeConstants() {
659
+ MapBuilder.Builder<String, Object> builder = MapBuilder.builder();
660
+ builder.put(OnMarkerPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerPressEvent.EVENT_NAME));
661
+ builder.put(OnCalloutPressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnCalloutPressEvent.EVENT_NAME));
662
+ builder.put(OnMarkerDragEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEvent.EVENT_NAME));
663
+ builder.put(OnMarkerDragStartEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragStartEvent.EVENT_NAME));
664
+ builder.put(OnMarkerDragEndEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDragEndEvent.EVENT_NAME));
665
+ builder.put(OnPoiClickEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPoiClickEvent.EVENT_NAME));
666
+ builder.put(OnDoublePressEvent.EVENT_NAME, MapBuilder.of("registrationName", OnDoublePressEvent.EVENT_NAME));
667
+ builder.put(OnPanDragEvent.EVENT_NAME, MapBuilder.of("registrationName", OnPanDragEvent.EVENT_NAME));
668
+ builder.put(OnMarkerSelectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerSelectEvent.EVENT_NAME));
669
+ builder.put(OnMarkerDeselectEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMarkerDeselectEvent.EVENT_NAME));
670
+ builder.put(OnMapLoadedEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMapLoadedEvent.EVENT_NAME));
671
+ builder.put(OnMapReadyEvent.EVENT_NAME, MapBuilder.of("registrationName", OnMapReadyEvent.EVENT_NAME));
672
+ builder.put(OnUserLocationChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnUserLocationChangeEvent.EVENT_NAME));
673
+ builder.put(OnRegionChangeEvent.EVENT_NAME, MapBuilder.of("registrationName", OnRegionChangeEvent.EVENT_NAME));
674
+ builder.put(OnRegionChangeStartEvent.EVENT_NAME, MapBuilder.of("registrationName", OnRegionChangeStartEvent.EVENT_NAME));
675
+ builder.put(OnRegionChangeCompleteEvent.EVENT_NAME, MapBuilder.of("registrationName", OnRegionChangeCompleteEvent.EVENT_NAME));
676
+ builder.put(OnIndoorBuildingFocusedEvent.EVENT_NAME, MapBuilder.of("registrationName", OnIndoorBuildingFocusedEvent.EVENT_NAME));
677
+ builder.put(OnIndoorLevelActivatedEvent.EVENT_NAME, MapBuilder.of("registrationName", OnIndoorLevelActivatedEvent.EVENT_NAME));
678
+ builder.put(OnKmlReadyEvent.EVENT_NAME, MapBuilder.of("registrationName", OnKmlReadyEvent.EVENT_NAME));
679
+ return builder.build();
680
+ }
681
+
682
+
683
+ /*
684
+ onDestroy is final method so I can't override it.
685
+ */
686
+ public synchronized void doDestroy() {
687
+ if (destroyed) {
688
+ return;
689
+ }
690
+ destroyed = true;
691
+
692
+ Activity activity = context.getCurrentActivity();
693
+ if (activity instanceof LifecycleOwner) {
694
+ ((LifecycleOwner) activity).getLifecycle().removeObserver(this);
695
+ }
696
+ if (!paused) {
697
+ onPause();
698
+ paused = true;
699
+ }
700
+ onDestroy();
701
+ }
702
+
703
+ public void setInitialCameraSet(boolean initialCameraSet) {
704
+ this.initialCameraSet = initialCameraSet;
705
+ }
706
+
707
+ public void setInitialRegion(ReadableMap initialRegion) {
708
+ this.initialRegion = initialRegion;
709
+ // Theoretically onMapReady might be called before setInitialRegion
710
+ // In that case, trigger moveToRegion manually
711
+ if (!initialRegionSet && map != null) {
712
+ moveToRegion(initialRegion);
713
+ initialRegionSet = true;
714
+ }
715
+ }
716
+
717
+ public void setInitialCamera(ReadableMap initialCamera) {
718
+ this.initialCamera = initialCamera;
719
+ if (!initialCameraSet && map != null) {
720
+ moveToCamera(initialCamera);
721
+ initialCameraSet = true;
722
+ }
723
+ }
724
+
725
+ private void applyBridgedProps() {
726
+ if (initialRegion != null) {
727
+ moveToRegion(initialRegion);
728
+ initialRegionSet = true;
729
+ } else if (region != null) {
730
+ moveToRegion(region);
731
+ } else if (initialCamera != null) {
732
+ moveToCamera(initialCamera);
733
+ initialCameraSet = true;
734
+ } else if (camera != null) {
735
+ moveToCamera(camera);
736
+ }
737
+ if (customMapStyleString != null) {
738
+ map.setMapStyle(new MapStyleOptions(customMapStyleString));
739
+ }
740
+ this.setPoiClickEnabled(poiClickEnabled);
741
+ if (setPaddingDeferred &&
742
+ (baseLeftMapPadding != 0 ||
743
+ baseTopMapPadding != 0 ||
744
+ baseRightMapPadding != 0 ||
745
+ baseBottomMapPadding != 0)) {
746
+ applyBaseMapPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
747
+ }
748
+ }
749
+
750
+ public static LatLngBounds latLngBoundsFromRegion(ReadableMap region) {
751
+ if (region == null) return null;
752
+
753
+ double lng = region.getDouble("longitude");
754
+ double lat = region.getDouble("latitude");
755
+ double lngDelta = region.getDouble("longitudeDelta");
756
+ double latDelta = region.getDouble("latitudeDelta");
757
+ return new LatLngBounds(
758
+ new LatLng(lat - latDelta / 2, lng - lngDelta / 2), // southwest
759
+ new LatLng(lat + latDelta / 2, lng + lngDelta / 2) // northeast
760
+ );
761
+ }
762
+
763
+ private void moveToRegion(ReadableMap region) {
764
+ LatLngBounds bounds = latLngBoundsFromRegion(region);
765
+ if (bounds == null) return;
766
+ double lng = region.getDouble("longitude");
767
+ double lat = region.getDouble("latitude");
768
+ if (super.getHeight() <= 0 || super.getWidth() <= 0) {
769
+ // in this case, our map has not been laid out yet, so we save the bounds in a local
770
+ // variable, and make a guess of zoomLevel 10. Not to worry, though: as soon as layout
771
+ // occurs, we will move the camera to the saved bounds. Note that if we tried to move
772
+ // to the bounds now, it would trigger an exception.
773
+ map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(lat, lng), 10));
774
+ boundsToMove = bounds;
775
+ } else {
776
+ map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
777
+ boundsToMove = null;
778
+ }
779
+ }
780
+
781
+ public void setRegion(ReadableMap region) {
782
+ this.region = region;
783
+ if (region != null && map != null) {
784
+ moveToRegion(region);
785
+ }
786
+ }
787
+
788
+ public void setCamera(ReadableMap camera) {
789
+ this.camera = camera;
790
+ if (camera != null && map != null) {
791
+ moveToCamera(camera);
792
+ }
793
+ }
794
+
795
+ public static CameraPosition cameraPositionFromMap(ReadableMap camera) {
796
+ if (camera == null) return null;
797
+
798
+ CameraPosition.Builder builder = new CameraPosition.Builder();
799
+
800
+ ReadableMap center = camera.getMap("center");
801
+ if (center != null) {
802
+ double lng = center.getDouble("longitude");
803
+ double lat = center.getDouble("latitude");
804
+ builder.target(new LatLng(lat, lng));
805
+ }
806
+
807
+ builder.tilt((float) camera.getDouble("pitch"));
808
+ builder.bearing((float) camera.getDouble("heading"));
809
+ builder.zoom((float) camera.getDouble("zoom"));
810
+
811
+ return builder.build();
812
+ }
813
+
814
+ public CameraPosition cameraPositionFromJSON(JSONObject camera) throws JSONException {
815
+ if (camera == null) return null;
816
+ if (map == null) return null;
817
+
818
+ CameraPosition.Builder builder = new CameraPosition.Builder();
819
+
820
+ if (camera.has("center")) {
821
+ JSONObject center = camera.getJSONObject("center");
822
+ if (center != null) {
823
+ double lng = center.getDouble("longitude");
824
+ double lat = center.getDouble("latitude");
825
+ builder.target(new LatLng(lat, lng));
826
+ }
827
+ } else {
828
+ builder.target(map.getCameraPosition().target);
829
+ }
830
+
831
+ if (camera.has("pitch")) {
832
+ builder.tilt((float) camera.getDouble("pitch"));
833
+ } else {
834
+ builder.tilt(map.getCameraPosition().tilt);
835
+ }
836
+ if (camera.has("heading")) {
837
+ builder.bearing((float) camera.getDouble("heading"));
838
+ } else {
839
+ builder.bearing(map.getCameraPosition().bearing);
840
+ }
841
+ if (camera.has("zoom")) {
842
+ builder.zoom((float) camera.getDouble("zoom"));
843
+ } else {
844
+ builder.zoom(map.getCameraPosition().zoom);
845
+ }
846
+
847
+ return builder.build();
848
+ }
849
+
850
+ public void moveToCamera(ReadableMap cameraMap) {
851
+ moveToCamera(cameraPositionFromMap(cameraMap));
852
+ }
853
+
854
+ public void moveToCamera(CameraPosition camera) {
855
+ if (camera == null) return;
856
+ CameraUpdate update = CameraUpdateFactory.newCameraPosition(camera);
857
+
858
+ if (super.getHeight() <= 0 || super.getWidth() <= 0) {
859
+ // in this case, our map has not been laid out yet, so we save the camera update in a
860
+ // local variable. As soon as layout occurs, we will move the camera to the saved update.
861
+ // Note that if we tried to move to the camera now, it would trigger an exception.
862
+ cameraToSet = update;
863
+ } else {
864
+ map.moveCamera(update);
865
+ cameraToSet = null;
866
+ }
867
+ }
868
+
869
+ public void setMapStyle(@Nullable String customMapStyleString) {
870
+ this.customMapStyleString = customMapStyleString;
871
+ if (map != null && customMapStyleString != null) {
872
+ map.setMapStyle(new MapStyleOptions(customMapStyleString));
873
+ }
874
+ }
875
+
876
+ public void setShowsUserLocation(boolean showUserLocation) {
877
+ this.showUserLocation = showUserLocation; // hold onto this for lifecycle handling
878
+ if (hasPermissions() && map != null) {
879
+ map.setLocationSource(fusedLocationSource);
880
+ //noinspection MissingPermission
881
+ map.setMyLocationEnabled(showUserLocation);
882
+ }
883
+ }
884
+
885
+ public void setUserLocationPriority(int priority) {
886
+ fusedLocationSource.setPriority(priority);
887
+ }
888
+
889
+ public void setUserLocationUpdateInterval(int interval) {
890
+ fusedLocationSource.setInterval(interval);
891
+ }
892
+
893
+ public void setUserLocationFastestInterval(int interval) {
894
+ fusedLocationSource.setFastestInterval(interval);
895
+ }
896
+
897
+ public void setShowsMyLocationButton(boolean showMyLocationButton) {
898
+ if (map != null) {
899
+ if (hasPermissions() || !showMyLocationButton) {
900
+ map.getUiSettings().setMyLocationButtonEnabled(showMyLocationButton);
901
+ }
902
+ }
903
+ }
904
+
905
+ public void setToolbarEnabled(boolean toolbarEnabled) {
906
+ if (map != null) {
907
+ if (hasPermissions() || !toolbarEnabled) {
908
+ map.getUiSettings().setMapToolbarEnabled(toolbarEnabled);
909
+ }
910
+ }
911
+ }
912
+
913
+ public void setMapType(int mapType) {
914
+ if (map != null) {
915
+ map.setMapType(mapType);
916
+ }
917
+ }
918
+
919
+ public void setCacheEnabled(boolean cacheEnabled) {
920
+ this.cacheEnabled = cacheEnabled;
921
+ this.cacheView();
922
+ }
923
+
924
+ public void setPoiClickEnabled(boolean poiClickEnabled) {
925
+ this.poiClickEnabled = poiClickEnabled;
926
+ if (map != null) {
927
+ map.setOnPoiClickListener(poiClickEnabled ? this : null);
928
+ }
929
+ }
930
+
931
+ public void setLoadingEnabled(boolean loadingEnabled) {
932
+ if (loadingEnabled && !this.isMapLoaded) {
933
+ this.getMapLoadingLayoutView().setVisibility(View.VISIBLE);
934
+ }
935
+ }
936
+
937
+ public void setMoveOnMarkerPress(boolean moveOnPress) {
938
+ this.moveOnMarkerPress = moveOnPress;
939
+ }
940
+
941
+ public void setMaxZoomLevel(float maxZoomLevel) {
942
+ this.maxZoomLevel = maxZoomLevel;
943
+ if (map != null) {
944
+ map.setMaxZoomPreference(maxZoomLevel);
945
+ }
946
+ }
947
+
948
+ public void setMinZoomLevel(float minZoomLevel) {
949
+ this.minZoomLevel = minZoomLevel;
950
+ if (map != null) {
951
+ map.setMinZoomPreference(minZoomLevel);
952
+ }
953
+ }
954
+
955
+ public void setPitchEnabled(boolean pitchEnabled) {
956
+ this.pitchEnabled = pitchEnabled;
957
+ if (map != null) {
958
+ map.getUiSettings().setTiltGesturesEnabled(pitchEnabled);
959
+ }
960
+ }
961
+
962
+ public void setShowsCompass(boolean showsCompass) {
963
+ this.showsCompass = showsCompass;
964
+ if (map != null) {
965
+ map.getUiSettings().setCompassEnabled(showsCompass);
966
+ }
967
+ }
968
+
969
+ public void setRotateEnabled(boolean rotateEnabled) {
970
+ this.rotateEnabled = rotateEnabled;
971
+ if (map != null) {
972
+ map.getUiSettings().setRotateGesturesEnabled(rotateEnabled);
973
+ }
974
+ }
975
+
976
+ public void setZoomEnabled(boolean zoomEnabled) {
977
+ this.zoomEnabled = zoomEnabled;
978
+ if (map != null) {
979
+ map.getUiSettings().setZoomGesturesEnabled(zoomEnabled);
980
+ }
981
+ }
982
+
983
+ public void setZoomControlEnabled(boolean zoomControlEnabled) {
984
+ this.zoomControlEnabled = zoomControlEnabled;
985
+ if (map != null) {
986
+ map.getUiSettings().setZoomControlsEnabled(zoomControlEnabled);
987
+ }
988
+ }
989
+
990
+ public void setScrollDuringRotateOrZoomEnabled(boolean scrollDuringRotateOrZoomEnabled) {
991
+ this.scrollDuringRotateOrZoomEnabled = scrollDuringRotateOrZoomEnabled;
992
+ if (map != null) {
993
+ map.getUiSettings().setScrollGesturesEnabledDuringRotateOrZoom(scrollDuringRotateOrZoomEnabled);
994
+ }
995
+ }
996
+
997
+ public void setScrollEnabled(boolean scrollEnabled) {
998
+ this.scrollEnabled = scrollEnabled;
999
+ if (map != null) {
1000
+ map.getUiSettings().setScrollGesturesEnabled(scrollEnabled);
1001
+ }
1002
+ }
1003
+
1004
+ public void setShowIndoors(boolean showIndoors) {
1005
+ this.showIndoors = showIndoors;
1006
+ if (map != null) {
1007
+ map.setIndoorEnabled(showIndoors);
1008
+ }
1009
+ }
1010
+
1011
+ public void setShowsIndoorLevelPicker(boolean showsIndoorLevelPicker) {
1012
+ this.showsIndoorLevelPicker = showsIndoorLevelPicker;
1013
+ if (map != null) {
1014
+ map.getUiSettings().setIndoorLevelPickerEnabled(showsIndoorLevelPicker);
1015
+ }
1016
+ }
1017
+
1018
+ public void setShowBuildings(boolean showBuildings) {
1019
+ this.setShowBuildings = showBuildings;
1020
+ if (map != null) {
1021
+ map.setBuildingsEnabled(showBuildings);
1022
+ }
1023
+ }
1024
+
1025
+
1026
+ public void setLoadingBackgroundColor(Integer loadingBackgroundColor) {
1027
+ this.loadingBackgroundColor = loadingBackgroundColor;
1028
+
1029
+ if (this.mapLoadingLayout != null) {
1030
+ if (loadingBackgroundColor == null) {
1031
+ this.mapLoadingLayout.setBackgroundColor(Color.WHITE);
1032
+ } else {
1033
+ this.mapLoadingLayout.setBackgroundColor(this.loadingBackgroundColor);
1034
+ }
1035
+ }
1036
+ }
1037
+
1038
+ public void setLoadingIndicatorColor(Integer loadingIndicatorColor) {
1039
+ this.loadingIndicatorColor = loadingIndicatorColor;
1040
+ if (this.mapLoadingProgressBar != null) {
1041
+ Integer color = loadingIndicatorColor;
1042
+ if (color == null) {
1043
+ color = Color.parseColor("#606060");
1044
+ }
1045
+
1046
+ ColorStateList progressTintList = ColorStateList.valueOf(loadingIndicatorColor);
1047
+ ColorStateList secondaryProgressTintList = ColorStateList.valueOf(loadingIndicatorColor);
1048
+ ColorStateList indeterminateTintList = ColorStateList.valueOf(loadingIndicatorColor);
1049
+
1050
+ this.mapLoadingProgressBar.setProgressTintList(progressTintList);
1051
+ this.mapLoadingProgressBar.setSecondaryProgressTintList(secondaryProgressTintList);
1052
+ this.mapLoadingProgressBar.setIndeterminateTintList(indeterminateTintList);
1053
+ }
1054
+ }
1055
+
1056
+ public void setHandlePanDrag(boolean handlePanDrag) {
1057
+ this.handlePanDrag = handlePanDrag;
1058
+ }
1059
+
1060
+ public void addFeature(View child, int index) {
1061
+ // Our desired API is to pass up annotations/overlays as children to the mapview component.
1062
+ // This is where we intercept them and do the appropriate underlying mapview action.
1063
+ if (child instanceof MapMarker) {
1064
+ MapMarker annotation = (MapMarker) child;
1065
+ annotation.addToMap(markerCollection);
1066
+ features.add(index, annotation);
1067
+
1068
+ // Allow visibility event to be triggered later
1069
+ int visibility = annotation.getVisibility();
1070
+ annotation.setVisibility(INVISIBLE);
1071
+
1072
+ // Remove from a view group if already present, prevent "specified child
1073
+ // already had a parent" error.
1074
+ ViewGroup annotationParent = (ViewGroup) annotation.getParent();
1075
+ if (annotationParent != null) {
1076
+ annotationParent.removeView(annotation);
1077
+ }
1078
+
1079
+ // Add to the parent group
1080
+ attacherGroup.addView(annotation);
1081
+
1082
+ // Trigger visibility event if necessary.
1083
+ // With some testing, seems like it is not always
1084
+ // triggered just by being added to a parent view.
1085
+ annotation.setVisibility(visibility);
1086
+
1087
+ Marker marker = (Marker) annotation.getFeature();
1088
+ markerMap.put(marker, annotation);
1089
+ } else if (child instanceof MapPolyline) {
1090
+ MapPolyline polylineView = (MapPolyline) child;
1091
+ polylineView.addToMap(polylineCollection);
1092
+ features.add(index, polylineView);
1093
+ Polyline polyline = (Polyline) polylineView.getFeature();
1094
+ polylineMap.put(polyline, polylineView);
1095
+ } else if (child instanceof MapGradientPolyline) {
1096
+ MapGradientPolyline polylineView = (MapGradientPolyline) child;
1097
+ polylineView.addToMap(map);
1098
+ features.add(index, polylineView);
1099
+ TileOverlay tileOverlay = (TileOverlay) polylineView.getFeature();
1100
+ gradientPolylineMap.put(tileOverlay, polylineView);
1101
+ } else if (child instanceof MapPolygon) {
1102
+ MapPolygon polygonView = (MapPolygon) child;
1103
+ polygonView.addToMap(polygonCollection);
1104
+ features.add(index, polygonView);
1105
+ Polygon polygon = (Polygon) polygonView.getFeature();
1106
+ polygonMap.put(polygon, polygonView);
1107
+ } else if (child instanceof MapCircle) {
1108
+ MapCircle circleView = (MapCircle) child;
1109
+ circleView.addToMap(circleCollection);
1110
+ features.add(index, circleView);
1111
+ } else if (child instanceof MapUrlTile) {
1112
+ MapUrlTile urlTileView = (MapUrlTile) child;
1113
+ urlTileView.addToMap(map);
1114
+ features.add(index, urlTileView);
1115
+ } else if (child instanceof MapWMSTile) {
1116
+ MapWMSTile urlTileView = (MapWMSTile) child;
1117
+ urlTileView.addToMap(map);
1118
+ features.add(index, urlTileView);
1119
+ } else if (child instanceof MapLocalTile) {
1120
+ MapLocalTile localTileView = (MapLocalTile) child;
1121
+ localTileView.addToMap(map);
1122
+ features.add(index, localTileView);
1123
+ } else if (child instanceof MapOverlay) {
1124
+ MapOverlay overlayView = (MapOverlay) child;
1125
+ overlayView.addToMap(groundOverlayCollection);
1126
+ features.add(index, overlayView);
1127
+ GroundOverlay overlay = (GroundOverlay) overlayView.getFeature();
1128
+ overlayMap.put(overlay, overlayView);
1129
+ } else if (child instanceof MapHeatmap) {
1130
+ MapHeatmap heatmapView = (MapHeatmap) child;
1131
+ heatmapView.addToMap(map);
1132
+ features.add(index, heatmapView);
1133
+ TileOverlay heatmap = (TileOverlay) heatmapView.getFeature();
1134
+ heatmapMap.put(heatmap, heatmapView);
1135
+ } else if (child instanceof ViewGroup) {
1136
+ ViewGroup children = (ViewGroup) child;
1137
+ for (int i = 0; i < children.getChildCount(); i++) {
1138
+ addFeature(children.getChildAt(i), index);
1139
+ }
1140
+ } else {
1141
+ addView(child, index);
1142
+ }
1143
+ }
1144
+
1145
+ public int getFeatureCount() {
1146
+ return features.size();
1147
+ }
1148
+
1149
+ public View getFeatureAt(int index) {
1150
+ return features.get(index);
1151
+ }
1152
+
1153
+ public void removeFeatureAt(int index) {
1154
+ MapFeature feature = features.remove(index);
1155
+ if (feature instanceof MapMarker) {
1156
+ markerMap.remove(feature.getFeature());
1157
+ feature.removeFromMap(markerCollection);
1158
+ attacherGroup.removeView(feature);
1159
+ } else if (feature instanceof MapHeatmap) {
1160
+ heatmapMap.remove(feature.getFeature());
1161
+ feature.removeFromMap(map);
1162
+ } else if (feature instanceof MapCircle) {
1163
+ feature.removeFromMap(circleCollection);
1164
+ } else if (feature instanceof MapOverlay) {
1165
+ feature.removeFromMap(groundOverlayCollection);
1166
+ } else if (feature instanceof MapPolygon) {
1167
+ feature.removeFromMap(polygonCollection);
1168
+ } else if (feature instanceof MapPolyline) {
1169
+ feature.removeFromMap(polylineCollection);
1170
+ } else {
1171
+ feature.removeFromMap(map);
1172
+ }
1173
+ }
1174
+
1175
+ public WritableMap makeClickEventData(LatLng point) {
1176
+ WritableMap event = new WritableNativeMap();
1177
+
1178
+ WritableMap coordinate = new WritableNativeMap();
1179
+ coordinate.putDouble("latitude", point.latitude);
1180
+ coordinate.putDouble("longitude", point.longitude);
1181
+ event.putMap("coordinate", coordinate);
1182
+
1183
+ Projection projection = map.getProjection();
1184
+ Point screenPoint = projection.toScreenLocation(point);
1185
+
1186
+ WritableMap position = new WritableNativeMap();
1187
+ position.putDouble("x", screenPoint.x);
1188
+ position.putDouble("y", screenPoint.y);
1189
+ event.putMap("position", position);
1190
+
1191
+ return event;
1192
+ }
1193
+
1194
+ public void updateExtraData(Object extraData) {
1195
+ if (setPaddingDeferred && super.getHeight() > 0 && super.getWidth() > 0) {
1196
+ CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
1197
+
1198
+ map.setPadding(edgeLeftPadding + baseLeftMapPadding,
1199
+ edgeTopPadding + baseTopMapPadding,
1200
+ edgeRightPadding + baseRightMapPadding,
1201
+ edgeBottomPadding + baseBottomMapPadding);
1202
+ map.moveCamera(cu);
1203
+
1204
+ // Move the google logo to the default base padding value.
1205
+ map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
1206
+
1207
+ setPaddingDeferred = false;
1208
+ }
1209
+
1210
+ // if boundsToMove is not null, we now have the MapView's width/height, so we can apply
1211
+ // a proper camera move
1212
+ if (boundsToMove != null) {
1213
+ HashMap<String, Float> data = (HashMap<String, Float>) extraData;
1214
+ int width = data.get("width") == null ? 0 : data.get("width").intValue();
1215
+ int height = data.get("height") == null ? 0 : data.get("height").intValue();
1216
+
1217
+ //fix for https://github.com/react-native-maps/react-native-maps/issues/245,
1218
+ //it's not guaranteed the passed-in height and width would be greater than 0.
1219
+ if (width <= 0 || height <= 0) {
1220
+ map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, 0));
1221
+ } else {
1222
+ map.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsToMove, width, height, 0));
1223
+ }
1224
+
1225
+ boundsToMove = null;
1226
+ cameraToSet = null;
1227
+ } else if (cameraToSet != null) {
1228
+ map.moveCamera(cameraToSet);
1229
+ cameraToSet = null;
1230
+ }
1231
+ }
1232
+
1233
+ public void animateToCamera(CameraPosition position, int duration) {
1234
+ if (map == null) return;
1235
+ CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
1236
+ if (duration <= 0) {
1237
+ map.moveCamera(update);
1238
+ } else {
1239
+ map.animateCamera(update, duration, null);
1240
+ }
1241
+ }
1242
+
1243
+ public void animateToCamera(ReadableMap camera, int duration) {
1244
+ if (map == null) return;
1245
+ CameraPosition.Builder builder = new CameraPosition.Builder(map.getCameraPosition());
1246
+ if (camera.hasKey("zoom")) {
1247
+ builder.zoom((float) camera.getDouble("zoom"));
1248
+ }
1249
+ if (camera.hasKey("heading")) {
1250
+ builder.bearing((float) camera.getDouble("heading"));
1251
+ }
1252
+ if (camera.hasKey("pitch")) {
1253
+ builder.tilt((float) camera.getDouble("pitch"));
1254
+ }
1255
+ if (camera.hasKey("center")) {
1256
+ ReadableMap center = camera.getMap("center");
1257
+ builder.target(new LatLng(center.getDouble("latitude"), center.getDouble("longitude")));
1258
+ }
1259
+ animateToCamera(builder.build(), duration);
1260
+ }
1261
+
1262
+ public void animateToRegion(LatLngBounds bounds, int duration) {
1263
+ if (map == null) return;
1264
+ if (duration <= 0) {
1265
+ map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0));
1266
+ } else {
1267
+ map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 0), duration, null);
1268
+ }
1269
+ }
1270
+
1271
+ public void fitToElements(ReadableMap edgePadding, boolean animated) {
1272
+ if (map == null) return;
1273
+
1274
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
1275
+
1276
+ boolean addedPosition = false;
1277
+ if (features.size() > 0) {
1278
+ for (MapFeature feature : features) {
1279
+ if (feature instanceof MapMarker) {
1280
+ Marker marker = (Marker) feature.getFeature();
1281
+ builder.include(marker.getPosition());
1282
+ addedPosition = true;
1283
+ }
1284
+ // TODO(lmr): may want to include shapes / etc.
1285
+ }
1286
+ }
1287
+ if (addedPosition) {
1288
+ LatLngBounds bounds = builder.build();
1289
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
1290
+
1291
+ if (edgePadding != null) {
1292
+ appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
1293
+ edgePadding.getInt("right"), edgePadding.getInt("bottom"));
1294
+ }
1295
+
1296
+ if (animated) {
1297
+ map.animateCamera(cu);
1298
+ } else {
1299
+ map.moveCamera(cu);
1300
+ }
1301
+ // Move the google logo to the default base padding value.
1302
+ map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
1303
+ }
1304
+ }
1305
+
1306
+ public void fitToSuppliedMarkers(ReadableArray markerIDsArray, ReadableMap edgePadding, boolean animated) {
1307
+ if (map == null) return;
1308
+
1309
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
1310
+
1311
+ String[] markerIDs = new String[markerIDsArray.size()];
1312
+ for (int i = 0; i < markerIDsArray.size(); i++) {
1313
+ markerIDs[i] = markerIDsArray.getString(i);
1314
+ }
1315
+
1316
+ boolean addedPosition = false;
1317
+
1318
+ List<String> markerIDList = Arrays.asList(markerIDs);
1319
+
1320
+ for (MapFeature feature : features) {
1321
+ if (feature instanceof MapMarker) {
1322
+ String identifier = ((MapMarker) feature).getIdentifier();
1323
+ Marker marker = (Marker) feature.getFeature();
1324
+ if (markerIDList.contains(identifier)) {
1325
+ builder.include(marker.getPosition());
1326
+ addedPosition = true;
1327
+ }
1328
+ }
1329
+ }
1330
+
1331
+ if (addedPosition) {
1332
+ LatLngBounds bounds = builder.build();
1333
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
1334
+
1335
+ if (edgePadding != null) {
1336
+ appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"),
1337
+ edgePadding.getInt("right"), edgePadding.getInt("bottom"));
1338
+ }
1339
+
1340
+ if (animated) {
1341
+ map.animateCamera(cu);
1342
+ } else {
1343
+ map.moveCamera(cu);
1344
+ }
1345
+ // Move the google logo to the default base padding value.
1346
+ map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
1347
+ }
1348
+ }
1349
+
1350
+ // padding configured by 'mapPadding' property
1351
+ int baseLeftMapPadding;
1352
+ int baseRightMapPadding;
1353
+ int baseTopMapPadding;
1354
+ int baseBottomMapPadding;
1355
+ // extra padding specified by 'edgePadding' option of fitToElements/fitToSuppliedMarkers/fitToCoordinates
1356
+ int edgeLeftPadding;
1357
+ int edgeRightPadding;
1358
+ int edgeTopPadding;
1359
+ int edgeBottomPadding;
1360
+
1361
+ public void applyBaseMapPadding(int left, int top, int right, int bottom) {
1362
+ if (super.getHeight() <= 0 || super.getWidth() <= 0) {
1363
+ // the map is not laid out yet and calling setPadding() now has no effect
1364
+ baseLeftMapPadding = left;
1365
+ baseRightMapPadding = right;
1366
+ baseTopMapPadding = top;
1367
+ baseBottomMapPadding = bottom;
1368
+ setPaddingDeferred = true;
1369
+ return;
1370
+ }
1371
+
1372
+ // retrieve current camera with current edge paddings configured
1373
+ map.setPadding(edgeLeftPadding + baseLeftMapPadding,
1374
+ edgeTopPadding + baseTopMapPadding,
1375
+ edgeRightPadding + baseRightMapPadding,
1376
+ edgeBottomPadding + baseBottomMapPadding);
1377
+ CameraUpdate cu = CameraUpdateFactory.newCameraPosition(map.getCameraPosition());
1378
+
1379
+ baseLeftMapPadding = left;
1380
+ baseRightMapPadding = right;
1381
+ baseTopMapPadding = top;
1382
+ baseBottomMapPadding = bottom;
1383
+
1384
+ // apply base paddings and restore center position of the map
1385
+ map.setPadding(edgeLeftPadding + left,
1386
+ edgeTopPadding + top,
1387
+ edgeRightPadding + right,
1388
+ edgeBottomPadding + bottom);
1389
+ map.moveCamera(cu);
1390
+
1391
+ // Move the google logo to the default base padding value.
1392
+ map.setPadding(left, top, right, bottom);
1393
+ setPaddingDeferred = false;
1394
+ }
1395
+
1396
+ public void fitToCoordinates(ReadableArray coordinatesArray, ReadableMap edgePadding,
1397
+ boolean animated) {
1398
+ if (map == null) return;
1399
+
1400
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
1401
+
1402
+ for (int i = 0; i < coordinatesArray.size(); i++) {
1403
+ ReadableMap latLng = coordinatesArray.getMap(i);
1404
+ double lat = latLng.getDouble("latitude");
1405
+ double lng = latLng.getDouble("longitude");
1406
+ builder.include(new LatLng(lat, lng));
1407
+ }
1408
+
1409
+ LatLngBounds bounds = builder.build();
1410
+ CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
1411
+
1412
+ if (edgePadding != null) {
1413
+ appendMapPadding(edgePadding.getInt("left"), edgePadding.getInt("top"), edgePadding.getInt("right"), edgePadding.getInt("bottom"));
1414
+ }
1415
+
1416
+ if (animated) {
1417
+ map.animateCamera(cu);
1418
+ } else {
1419
+ map.moveCamera(cu);
1420
+ }
1421
+ // Move the google logo to the default base padding value.
1422
+ map.setPadding(baseLeftMapPadding, baseTopMapPadding, baseRightMapPadding, baseBottomMapPadding);
1423
+ }
1424
+
1425
+ private void appendMapPadding(int iLeft, int iTop, int iRight, int iBottom) {
1426
+ double density = getResources().getDisplayMetrics().density;
1427
+
1428
+ edgeLeftPadding = (int) (iLeft * density);
1429
+ edgeTopPadding = (int) (iTop * density);
1430
+ edgeRightPadding = (int) (iRight * density);
1431
+ edgeBottomPadding = (int) (iBottom * density);
1432
+
1433
+ map.setPadding(edgeLeftPadding + baseLeftMapPadding,
1434
+ edgeTopPadding + baseTopMapPadding,
1435
+ edgeRightPadding + baseRightMapPadding,
1436
+ edgeBottomPadding + baseBottomMapPadding);
1437
+ }
1438
+
1439
+ public double[][] getMapBoundaries() {
1440
+ LatLngBounds bounds = map.getProjection().getVisibleRegion().latLngBounds;
1441
+ LatLng northEast = bounds.northeast;
1442
+ LatLng southWest = bounds.southwest;
1443
+
1444
+ return new double[][]{
1445
+ {northEast.longitude, northEast.latitude},
1446
+ {southWest.longitude, southWest.latitude}
1447
+ };
1448
+ }
1449
+
1450
+ public void setMapBoundaries(ReadableMap northEast, ReadableMap southWest) {
1451
+ if (map == null) return;
1452
+
1453
+ LatLngBounds.Builder builder = new LatLngBounds.Builder();
1454
+
1455
+ double latNE = northEast.getDouble("latitude");
1456
+ double lngNE = northEast.getDouble("longitude");
1457
+ builder.include(new LatLng(latNE, lngNE));
1458
+
1459
+ double latSW = southWest.getDouble("latitude");
1460
+ double lngSW = southWest.getDouble("longitude");
1461
+ builder.include(new LatLng(latSW, lngSW));
1462
+
1463
+ LatLngBounds bounds = builder.build();
1464
+
1465
+ map.setLatLngBoundsForCameraTarget(bounds);
1466
+ }
1467
+
1468
+ // InfoWindowAdapter interface
1469
+
1470
+ @Override
1471
+ public View getInfoWindow(Marker marker) {
1472
+ MapMarker markerView = getMarkerMap(marker);
1473
+ return markerView.getCallout();
1474
+ }
1475
+
1476
+ @Override
1477
+ public View getInfoContents(Marker marker) {
1478
+ MapMarker markerView = getMarkerMap(marker);
1479
+ return markerView.getInfoContents();
1480
+ }
1481
+
1482
+ @Override
1483
+ public boolean dispatchTouchEvent(MotionEvent ev) {
1484
+ gestureDetector.onTouchEvent(ev);
1485
+
1486
+ int X = (int) ev.getX();
1487
+ int Y = (int) ev.getY();
1488
+ if (map != null) {
1489
+ tapLocation = map.getProjection().fromScreenLocation(new Point(X, Y));
1490
+ }
1491
+
1492
+ int action = MotionEventCompat.getActionMasked(ev);
1493
+
1494
+ switch (action) {
1495
+ case (MotionEvent.ACTION_DOWN):
1496
+ this.getParent().requestDisallowInterceptTouchEvent(
1497
+ map != null && map.getUiSettings().isScrollGesturesEnabled());
1498
+ break;
1499
+ case (MotionEvent.ACTION_UP):
1500
+ // Clear this regardless, since isScrollGesturesEnabled() may have been updated
1501
+ this.getParent().requestDisallowInterceptTouchEvent(false);
1502
+ break;
1503
+ }
1504
+ super.dispatchTouchEvent(ev);
1505
+ return true;
1506
+ }
1507
+
1508
+ @Override
1509
+ public void onMarkerDragStart(Marker marker) {
1510
+ WritableMap event = makeClickEventData(marker.getPosition());
1511
+ dispatchEvent(event, OnMarkerDragStartEvent::new);
1512
+
1513
+ MapMarker markerView = getMarkerMap(marker);
1514
+ event = makeClickEventData(marker.getPosition());
1515
+ dispatchEvent(event, OnMarkerDragStartEvent::new, markerView.getId(), context);
1516
+ }
1517
+
1518
+ @Override
1519
+ public void onMarkerDrag(Marker marker) {
1520
+ WritableMap event = makeClickEventData(marker.getPosition());
1521
+ dispatchEvent(event, OnMarkerDragEvent::new);
1522
+
1523
+ MapMarker markerView = getMarkerMap(marker);
1524
+ event = makeClickEventData(marker.getPosition());
1525
+ dispatchEvent(event, OnMarkerDragEvent::new, markerView.getId(), context);
1526
+ }
1527
+
1528
+ @Override
1529
+ public void onMarkerDragEnd(Marker marker) {
1530
+ WritableMap event = makeClickEventData(marker.getPosition());
1531
+ dispatchEvent(event, OnMarkerDragEndEvent::new);
1532
+ MapMarker markerView = getMarkerMap(marker);
1533
+ event = makeClickEventData(marker.getPosition());
1534
+ dispatchEvent(event, OnMarkerDragEndEvent::new, markerView.getId(), context);
1535
+ }
1536
+
1537
+ @Override
1538
+ public void onPoiClick(PointOfInterest poi) {
1539
+ WritableMap event = makeClickEventData(poi.latLng);
1540
+
1541
+ event.putString("placeId", poi.placeId);
1542
+ event.putString("name", poi.name);
1543
+ dispatchEvent(event, OnPoiClickEvent::new);
1544
+ }
1545
+
1546
+ private ProgressBar getMapLoadingProgressBar() {
1547
+ if (this.mapLoadingProgressBar == null) {
1548
+ this.mapLoadingProgressBar = new ProgressBar(getContext());
1549
+ this.mapLoadingProgressBar.setIndeterminate(true);
1550
+ }
1551
+ if (this.loadingIndicatorColor != null) {
1552
+ this.setLoadingIndicatorColor(this.loadingIndicatorColor);
1553
+ }
1554
+ return this.mapLoadingProgressBar;
1555
+ }
1556
+
1557
+ private RelativeLayout getMapLoadingLayoutView() {
1558
+ if (this.mapLoadingLayout == null) {
1559
+ this.mapLoadingLayout = new RelativeLayout(getContext());
1560
+ this.mapLoadingLayout.setBackgroundColor(Color.LTGRAY);
1561
+ this.addView(this.mapLoadingLayout,
1562
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1563
+ ViewGroup.LayoutParams.MATCH_PARENT));
1564
+
1565
+ RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
1566
+ RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
1567
+ params.addRule(RelativeLayout.CENTER_IN_PARENT);
1568
+ this.mapLoadingLayout.addView(this.getMapLoadingProgressBar(), params);
1569
+
1570
+ this.mapLoadingLayout.setVisibility(View.INVISIBLE);
1571
+ }
1572
+ this.setLoadingBackgroundColor(this.loadingBackgroundColor);
1573
+ return this.mapLoadingLayout;
1574
+ }
1575
+
1576
+ private ImageView getCacheImageView() {
1577
+ if (this.cacheImageView == null) {
1578
+ this.cacheImageView = new ImageView(getContext());
1579
+ this.addView(this.cacheImageView,
1580
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
1581
+ ViewGroup.LayoutParams.MATCH_PARENT));
1582
+ this.cacheImageView.setVisibility(View.INVISIBLE);
1583
+ }
1584
+ return this.cacheImageView;
1585
+ }
1586
+
1587
+ private void removeCacheImageView() {
1588
+ if (this.cacheImageView != null) {
1589
+ ((ViewGroup) this.cacheImageView.getParent()).removeView(this.cacheImageView);
1590
+ this.cacheImageView = null;
1591
+ }
1592
+ }
1593
+
1594
+ private void removeMapLoadingProgressBar() {
1595
+ if (this.mapLoadingProgressBar != null) {
1596
+ ((ViewGroup) this.mapLoadingProgressBar.getParent()).removeView(this.mapLoadingProgressBar);
1597
+ this.mapLoadingProgressBar = null;
1598
+ }
1599
+ }
1600
+
1601
+ private void removeMapLoadingLayoutView() {
1602
+ this.removeMapLoadingProgressBar();
1603
+ if (this.mapLoadingLayout != null) {
1604
+ ((ViewGroup) this.mapLoadingLayout.getParent()).removeView(this.mapLoadingLayout);
1605
+ this.mapLoadingLayout = null;
1606
+ }
1607
+ }
1608
+
1609
+ private void cacheView() {
1610
+ if (this.cacheEnabled) {
1611
+ final ImageView cacheImageView = this.getCacheImageView();
1612
+ final RelativeLayout mapLoadingLayout = this.getMapLoadingLayoutView();
1613
+ cacheImageView.setVisibility(View.INVISIBLE);
1614
+ mapLoadingLayout.setVisibility(View.VISIBLE);
1615
+ if (this.isMapLoaded) {
1616
+ this.map.snapshot(new GoogleMap.SnapshotReadyCallback() {
1617
+ @Override
1618
+ public void onSnapshotReady(Bitmap bitmap) {
1619
+ cacheImageView.setImageBitmap(bitmap);
1620
+ cacheImageView.setVisibility(View.VISIBLE);
1621
+ mapLoadingLayout.setVisibility(View.INVISIBLE);
1622
+ }
1623
+ });
1624
+ }
1625
+ } else {
1626
+ this.removeCacheImageView();
1627
+ if (this.isMapLoaded) {
1628
+ this.removeMapLoadingLayoutView();
1629
+ }
1630
+ }
1631
+ }
1632
+
1633
+ public void onPanDrag(MotionEvent ev) {
1634
+ Point point = new Point((int) ev.getX(), (int) ev.getY());
1635
+ LatLng coords = this.map.getProjection().fromScreenLocation(point);
1636
+ WritableMap event = makeClickEventData(coords);
1637
+ dispatchEvent(event, OnPanDragEvent::new);
1638
+ }
1639
+
1640
+ public void onDoublePress(MotionEvent ev) {
1641
+ if (this.map == null) return;
1642
+ Point point = new Point((int) ev.getX(), (int) ev.getY());
1643
+ LatLng coords = this.map.getProjection().fromScreenLocation(point);
1644
+ WritableMap event = makeClickEventData(coords);
1645
+ dispatchEvent(event, OnDoublePressEvent::new);
1646
+
1647
+ }
1648
+
1649
+ public void setKmlSrc(String kmlSrc) {
1650
+ if (isMapReady) {
1651
+ try {
1652
+ InputStream kmlStream = new FileUtil(context).execute(kmlSrc).get();
1653
+
1654
+ if (kmlStream == null) {
1655
+ return;
1656
+ }
1657
+
1658
+ KmlLayer kmlLayer = new KmlLayer(map, kmlStream, context, markerManager, polygonManager, polylineManager, groundOverlayManager, null);
1659
+
1660
+ kmlLayer.addLayerToMap();
1661
+
1662
+ WritableMap pointers = new WritableNativeMap();
1663
+ WritableArray markers = new WritableNativeArray();
1664
+
1665
+ if (kmlLayer.getContainers() == null) {
1666
+ dispatchEvent(pointers, OnKmlReadyEvent::new);
1667
+ return;
1668
+ }
1669
+
1670
+ //Retrieve a nested container within the first container
1671
+ KmlContainer container = kmlLayer.getContainers().iterator().next();
1672
+ if (container == null || container.getContainers() == null) {
1673
+ dispatchEvent(pointers, OnKmlReadyEvent::new);
1674
+ return;
1675
+ }
1676
+
1677
+
1678
+ if (container.getContainers().iterator().hasNext()) {
1679
+ container = container.getContainers().iterator().next();
1680
+ }
1681
+
1682
+ int index = 0;
1683
+ for (KmlPlacemark placemark : container.getPlacemarks()) {
1684
+ MarkerOptions options = new MarkerOptions();
1685
+
1686
+ if (placemark.getInlineStyle() != null) {
1687
+ options = placemark.getMarkerOptions();
1688
+ } else {
1689
+ options.icon(BitmapDescriptorFactory.defaultMarker());
1690
+ }
1691
+
1692
+ LatLng latLng = ((LatLng) placemark.getGeometry().getGeometryObject());
1693
+ String title = "";
1694
+ String snippet = "";
1695
+
1696
+ if (placemark.hasProperty("name")) {
1697
+ title = placemark.getProperty("name");
1698
+ }
1699
+
1700
+ if (placemark.hasProperty("description")) {
1701
+ snippet = placemark.getProperty("description");
1702
+ }
1703
+
1704
+ options.position(latLng);
1705
+ options.title(title);
1706
+ options.snippet(snippet);
1707
+ // FIXME: get markerManager from somewhere
1708
+ /*
1709
+ MapMarker marker = new MapMarker(context, options, this.manager.getMarkerManager());
1710
+
1711
+ if (placemark.getInlineStyle() != null
1712
+ && placemark.getInlineStyle().getIconUrl() != null) {
1713
+ marker.setImage(placemark.getInlineStyle().getIconUrl());
1714
+ } else if (container.getStyle(placemark.getStyleId()) != null) {
1715
+ KmlStyle style = container.getStyle(placemark.getStyleId());
1716
+ marker.setImage(style.getIconUrl());
1717
+ }
1718
+
1719
+ String identifier = title + " - " + index;
1720
+
1721
+ marker.setIdentifier(identifier);
1722
+
1723
+ addFeature(marker, index++);
1724
+
1725
+
1726
+ WritableMap loadedMarker = makeClickEventData(latLng);
1727
+ loadedMarker.putString("id", identifier);
1728
+ loadedMarker.putString("title", title);
1729
+ loadedMarker.putString("description", snippet);
1730
+
1731
+ markers.pushMap(loadedMarker);
1732
+ */
1733
+ }
1734
+
1735
+ pointers.putArray("markers", markers);
1736
+ dispatchEvent(new WritableNativeMap(), OnKmlReadyEvent::new);
1737
+
1738
+ } catch (XmlPullParserException | IOException | InterruptedException |
1739
+ ExecutionException e) {
1740
+ e.printStackTrace();
1741
+ }
1742
+ } else {
1743
+ this.kmlSrc = kmlSrc;
1744
+ }
1745
+ }
1746
+
1747
+ @Override
1748
+ public void onIndoorBuildingFocused() {
1749
+ IndoorBuilding building = this.map.getFocusedBuilding();
1750
+ if (building != null) {
1751
+ List<IndoorLevel> levels = building.getLevels();
1752
+ int index = 0;
1753
+ WritableArray levelsArray = Arguments.createArray();
1754
+ for (IndoorLevel level : levels) {
1755
+ WritableMap levelMap = Arguments.createMap();
1756
+ levelMap.putInt("index", index);
1757
+ levelMap.putString("name", level.getName());
1758
+ levelMap.putString("shortName", level.getShortName());
1759
+ levelsArray.pushMap(levelMap);
1760
+ index++;
1761
+ }
1762
+ WritableMap indoorBuilding = Arguments.createMap();
1763
+ indoorBuilding.putArray("levels", levelsArray);
1764
+ indoorBuilding.putInt("activeLevelIndex", building.getActiveLevelIndex());
1765
+ indoorBuilding.putBoolean("underground", building.isUnderground());
1766
+
1767
+ dispatchEvent(indoorBuilding, OnIndoorBuildingFocusedEvent::new);
1768
+ } else {
1769
+ WritableArray levelsArray = Arguments.createArray();
1770
+ WritableMap indoorBuilding = Arguments.createMap();
1771
+ indoorBuilding.putArray("levels", levelsArray);
1772
+ indoorBuilding.putInt("activeLevelIndex", 0);
1773
+ indoorBuilding.putBoolean("underground", false);
1774
+
1775
+ dispatchEvent(indoorBuilding, OnIndoorBuildingFocusedEvent::new);
1776
+ }
1777
+ }
1778
+
1779
+ @Override
1780
+ public void onIndoorLevelActivated(IndoorBuilding building) {
1781
+ if (building == null) {
1782
+ return;
1783
+ }
1784
+ int activeLevelIndex = building.getActiveLevelIndex();
1785
+ if (activeLevelIndex < 0 || activeLevelIndex >= building.getLevels().size()) {
1786
+ return;
1787
+ }
1788
+ IndoorLevel level = building.getLevels().get(activeLevelIndex);
1789
+
1790
+ WritableMap indoorlevel = Arguments.createMap();
1791
+
1792
+ indoorlevel.putInt("activeLevelIndex", activeLevelIndex);
1793
+ indoorlevel.putString("name", level.getName());
1794
+ indoorlevel.putString("shortName", level.getShortName());
1795
+
1796
+ dispatchEvent(indoorlevel, OnIndoorLevelActivatedEvent::new);
1797
+ }
1798
+
1799
+ public void setIndoorActiveLevelIndex(int activeLevelIndex) {
1800
+ IndoorBuilding building = this.map.getFocusedBuilding();
1801
+ if (building != null) {
1802
+ if (activeLevelIndex >= 0 && activeLevelIndex < building.getLevels().size()) {
1803
+ IndoorLevel level = building.getLevels().get(activeLevelIndex);
1804
+ if (level != null) {
1805
+ level.activate();
1806
+ }
1807
+ }
1808
+ }
1809
+ }
1810
+
1811
+ private MapMarker getMarkerMap(Marker marker) {
1812
+ MapMarker airMarker = markerMap.get(marker);
1813
+
1814
+ if (airMarker != null) {
1815
+ return airMarker;
1816
+ }
1817
+
1818
+ for (Map.Entry<Marker, MapMarker> entryMarker : markerMap.entrySet()) {
1819
+ if (entryMarker.getKey().getPosition().equals(marker.getPosition())
1820
+ && entryMarker.getKey().getTitle().equals(marker.getTitle())) {
1821
+ airMarker = entryMarker.getValue();
1822
+ break;
1823
+ }
1824
+ }
1825
+
1826
+ return airMarker;
1827
+ }
1828
+
1829
+ @Override
1830
+ public void requestLayout() {
1831
+ super.requestLayout();
1832
+ post(measureAndLayout);
1833
+ }
1834
+
1835
+ private final Runnable measureAndLayout = new Runnable() {
1836
+ @Override
1837
+ public void run() {
1838
+ measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
1839
+ MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.EXACTLY));
1840
+ layout(getLeft(), getTop(), getRight(), getBottom());
1841
+ }
1842
+ };
1843
+
1844
+ }