├── .gitignore ├── .prettierrc.json ├── example ├── .buckconfig ├── .gitignore ├── App.tsx ├── __tests__ │ └── App.js ├── android │ ├── .gitignore │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── build_defs.bzl │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ ├── AndroidManifest.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── expo │ │ │ │ └── expo │ │ │ │ └── maps │ │ │ │ └── ReactNativeFlipper.java │ │ │ └── main │ │ │ ├── java │ │ │ └── com │ │ │ │ └── expo │ │ │ │ └── expo │ │ │ │ └── maps │ │ │ │ ├── MainActivity.java │ │ │ │ ├── MainApplication.java │ │ │ │ └── newarchitecture │ │ │ │ ├── MainApplicationReactNativeHost.java │ │ │ │ ├── components │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ └── modules │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ ├── jni │ │ │ ├── Android.mk │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ ├── MainApplicationModuleProvider.h │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ ├── MainComponentsRegistry.cpp │ │ │ ├── MainComponentsRegistry.h │ │ │ └── OnLoad.cpp │ │ │ └── res │ │ │ ├── drawable │ │ │ ├── rn_edit_text_material.xml │ │ │ └── splashscreen.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── values-night │ │ │ └── colors.xml │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── assets │ ├── building.png │ ├── exampleMapStyle.json │ ├── newark_nj_1922.jpeg │ ├── points.json │ ├── pointsWithData.json │ ├── sample.geo.json │ └── sample.kml ├── babel.config.js ├── components │ ├── ExamplesListItem.tsx │ └── SwitchContainer.tsx ├── constants │ └── ConcreteExampleScreens.ts ├── context │ └── ProviderContext.ts ├── expo-maps.plugin.android.js ├── expo-maps.plugin.ios.js ├── google-maps-api-keys.json.example ├── index.js ├── ios │ ├── .gitignore │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── Podfile.properties.json │ ├── example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── example.xcscheme │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ └── example │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── SplashScreenBackground.imageset │ │ │ ├── Contents.json │ │ │ └── image.png │ │ ├── SplashScreen.storyboard │ │ ├── Supporting │ │ └── Expo.plist │ │ ├── example.entitlements │ │ ├── main.m │ │ └── noop-file.swift ├── metro.config.js ├── navigators │ └── MainNavigator.tsx ├── package.json ├── screens │ ├── CallbacksExample.tsx │ ├── CirclesExample.tsx │ ├── ControlsExample.tsx │ ├── ExamplesListScreen.tsx │ ├── GeoJsonExample.tsx │ ├── GesturesExample.tsx │ ├── GoogleMapsStylingExample.tsx │ ├── HeatmapsExample.tsx │ ├── KMLExample.tsx │ ├── MapMoveExample.tsx │ ├── MapTypesExample.tsx │ ├── MarkersExample.tsx │ ├── OverlaysExample.tsx │ ├── POIExample.tsx │ ├── PolygonsExample.tsx │ ├── PolylinesExample.tsx │ └── TrafficExample.tsx └── tsconfig.json ├── expo-maps ├── .eslintrc.js ├── .prettierrc ├── CHANGELOG.md ├── README.md ├── android │ ├── .gitignore │ ├── build.gradle │ └── src │ │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── expo │ │ └── modules │ │ └── maps │ │ ├── ExpoGoogleMapsModule.kt │ │ ├── MapViewLifecycleEventListener.kt │ │ ├── PropsData.kt │ │ ├── googleMaps │ │ ├── GoogleMapsCallbacks.kt │ │ ├── GoogleMapsCameraAnimations.kt │ │ ├── GoogleMapsCircles.kt │ │ ├── GoogleMapsClusters.kt │ │ ├── GoogleMapsControls.kt │ │ ├── GoogleMapsGeoJsons.kt │ │ ├── GoogleMapsGestures.kt │ │ ├── GoogleMapsHeatmaps.kt │ │ ├── GoogleMapsKMLs.kt │ │ ├── GoogleMapsMarkers.kt │ │ ├── GoogleMapsOverlays.kt │ │ ├── GoogleMapsPlaces.kt │ │ ├── GoogleMapsPolygons.kt │ │ ├── GoogleMapsPolylines.kt │ │ ├── GoogleMapsUtils.kt │ │ ├── GoogleMapsView.kt │ │ └── placesUtils │ │ │ ├── GoogleMapsPlacesSearchCompleter.kt │ │ │ ├── GoogleMapsPlacesTokenUtils.kt │ │ │ └── GooglePlacesFetchPlace.kt │ │ ├── interfaces │ │ ├── Circles.kt │ │ ├── Clusters.kt │ │ ├── Controls.kt │ │ ├── ExpoMapView.kt │ │ ├── GeoJsons.kt │ │ ├── Gestures.kt │ │ ├── Heatmaps.kt │ │ ├── KMLs.kt │ │ ├── Markers.kt │ │ ├── Overlays.kt │ │ ├── Polygons.kt │ │ └── Polylines.kt │ │ └── records │ │ ├── CameraMoveRecord.kt │ │ ├── CameraPositionRecord.kt │ │ ├── ClusterRecord.kt │ │ ├── LatLngDeltaRecord.kt │ │ ├── LatLngRecord.kt │ │ ├── MarkerRecord.kt │ │ ├── PointOfInterestRecord.kt │ │ └── UserLocationRecord.kt ├── babel.config.js ├── build │ ├── Circle.d.ts │ ├── Circle.js │ ├── Circle.js.map │ ├── Cluster.d.ts │ ├── Cluster.js │ ├── Cluster.js.map │ ├── Common.types.d.ts │ ├── Common.types.js │ ├── Common.types.js.map │ ├── Events.d.ts │ ├── Events.js │ ├── Events.js.map │ ├── ExpoMaps.d.ts │ ├── ExpoMaps.js │ ├── ExpoMaps.js.map │ ├── ExpoMaps.web.d.ts │ ├── ExpoMaps.web.js │ ├── ExpoMaps.web.js.map │ ├── GeoJson.d.ts │ ├── GeoJson.js │ ├── GeoJson.js.map │ ├── Heatmap.d.ts │ ├── Heatmap.js │ ├── Heatmap.js.map │ ├── KML.d.ts │ ├── KML.js │ ├── KML.js.map │ ├── Map.d.ts │ ├── Map.js │ ├── Map.js.map │ ├── Map.types.d.ts │ ├── Map.types.js │ ├── Map.types.js.map │ ├── Marker.d.ts │ ├── Marker.js │ ├── Marker.js.map │ ├── NativeExpoMapView.d.ts │ ├── NativeExpoMapView.js │ ├── NativeExpoMapView.js.map │ ├── Overlay.d.ts │ ├── Overlay.js │ ├── Overlay.js.map │ ├── Polygon.d.ts │ ├── Polygon.js │ ├── Polygon.js.map │ ├── Polyline.d.ts │ ├── Polyline.js │ ├── Polyline.js.map │ ├── Utils.d.ts │ ├── Utils.js │ └── Utils.js.map ├── expo-module.config.json ├── ios │ ├── ExpoMaps.podspec │ └── ExpoMaps │ │ ├── AppleMaps │ │ ├── AppleMapsCameraAnimations.swift │ │ ├── AppleMapsCircles.swift │ │ ├── AppleMapsClusters.swift │ │ ├── AppleMapsControls.swift │ │ ├── AppleMapsDelegate.swift │ │ ├── AppleMapsGeoJsons.swift │ │ ├── AppleMapsGestures.swift │ │ ├── AppleMapsKMLs.swift │ │ ├── AppleMapsMarkers.swift │ │ ├── AppleMapsMarkersManager.swift │ │ ├── AppleMapsPOI.swift │ │ ├── AppleMapsPolygons.swift │ │ ├── AppleMapsPolylines.swift │ │ ├── AppleMapsUtils.swift │ │ ├── AppleMapsView.swift │ │ ├── ArrayExtension.swift │ │ ├── CustomTypes │ │ │ ├── ExpoMKAnnotation.swift │ │ │ ├── ExpoMKAnnotationView.swift │ │ │ ├── ExpoMKCircle.swift │ │ │ ├── ExpoMKClusterAnnotation.swift │ │ │ ├── ExpoMKClusterAnnotationView.swift │ │ │ ├── ExpoMKPolygon.swift │ │ │ └── ExpoMKPolyline.swift │ │ ├── KMLTags.swift │ │ ├── POIUtils │ │ │ ├── AppleMapsPOISearch.swift │ │ │ ├── AppleMapsPOISearchCompleter.swift │ │ │ ├── AppleMapsPOISearchController.swift │ │ │ └── AppleMapsPOISearchResultsView.swift │ │ └── UIColorExtension.swift │ │ ├── ExpoAppleMapsModule.swift │ │ ├── ExpoGoogleMapsModule.swift │ │ ├── GoogleMaps │ │ ├── CustomTypes │ │ │ └── ExpoGoogleMapsPolyline.swift │ │ ├── GoogleMapsCameraAnimations.swift │ │ ├── GoogleMapsCircles.swift │ │ ├── GoogleMapsClusterManagerDelegate.swift │ │ ├── GoogleMapsClusters.swift │ │ ├── GoogleMapsControls.swift │ │ ├── GoogleMapsGeoJSONs.swift │ │ ├── GoogleMapsGestures.swift │ │ ├── GoogleMapsHeatmaps.swift │ │ ├── GoogleMapsKMLs.swift │ │ ├── GoogleMapsMarkers.swift │ │ ├── GoogleMapsMarkersManager.swift │ │ ├── GoogleMapsOverlays.swift │ │ ├── GoogleMapsPlaces.swift │ │ ├── GoogleMapsPolygons.swift │ │ ├── GoogleMapsPolylines.swift │ │ ├── GoogleMapsUtils.swift │ │ ├── GoogleMapsView.swift │ │ ├── GoogleMapsViewDelegate.swift │ │ └── PlacesUtils │ │ │ ├── GoogleMapsPlacesSearchCompleter.swift │ │ │ ├── GoogleMapsPlacesTokenUtils.swift │ │ │ └── GooglePlacesFetchPlace.swift │ │ ├── MapEventsNames.swift │ │ ├── PropsData.swift │ │ ├── Protocols │ │ ├── Circles.swift │ │ ├── Clusters.swift │ │ ├── Controls.swift │ │ ├── ExpoMapView.swift │ │ ├── GeoJsons.swift │ │ ├── Gestures.swift │ │ ├── Heatmaps.swift │ │ ├── KMLs.swift │ │ ├── Markers.swift │ │ ├── Overlays.swift │ │ ├── PointsOfInterests.swift │ │ ├── Polygons.swift │ │ ├── Polylines.swift │ │ └── SearchCompleter.swift │ │ └── Records │ │ ├── CameraMoveRecord.swift │ │ ├── CameraPositionRecord.swift │ │ ├── ClusterRecord.swift │ │ ├── LatLngDeltaRecord.swift │ │ ├── LatLngRecord.swift │ │ ├── MarkerRecord.swift │ │ ├── PointOfInterestRecord.swift │ │ └── UserLocationRecord.swift ├── package.json ├── src │ ├── Circle.ts │ ├── Cluster.ts │ ├── Common.types.ts │ ├── Events.ts │ ├── ExpoMaps.ts │ ├── ExpoMaps.web.ts │ ├── GeoJson.ts │ ├── Heatmap.ts │ ├── KML.ts │ ├── Map.tsx │ ├── Map.types.ts │ ├── Marker.ts │ ├── NativeExpoMapView.tsx │ ├── Overlay.ts │ ├── Polygon.ts │ ├── Polyline.ts │ ├── Utils.ts │ └── __tests__ │ │ └── Maps-test.ts └── tsconfig.json ├── package.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Expo 2 | .expo 3 | __generated__ 4 | web-build 5 | 6 | # macOS 7 | .DS_Store 8 | 9 | # Node 10 | node_modules 11 | npm-debug.log 12 | yarn-error.log 13 | # Env 14 | .envrc.local 15 | 16 | # Emacs 17 | *~ 18 | 19 | # Vim 20 | .*.swp 21 | .*.swo 22 | .*.swn 23 | .*.swm 24 | 25 | # Sublime Text 26 | *.sublime-project 27 | *.sublime-workspace 28 | 29 | # Xcode 30 | *.pbxuser 31 | !default.pbxuser 32 | *.xccheckout 33 | *.xcscmblueprint 34 | xcuserdata 35 | 36 | # IDEA / Android Studio 37 | *.iml 38 | .gradle 39 | .idea 40 | 41 | # Eclipse 42 | .project 43 | .settings 44 | 45 | # VSCode 46 | .history/ 47 | 48 | git-crypt-key 49 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | 34 | # node.js 35 | # 36 | node_modules/ 37 | npm-debug.log 38 | yarn-error.log 39 | 40 | # BUCK 41 | buck-out/ 42 | \.buckd/ 43 | *.keystore 44 | !debug.keystore 45 | 46 | # Bundle artifacts 47 | *.jsbundle 48 | 49 | # CocoaPods 50 | /ios/Pods/ 51 | 52 | # Expo 53 | .expo/ 54 | web-build/ 55 | dist/ 56 | 57 | # @generated expo-cli sync-e7dcf75f4e856f7b6f3239b3f3a7dd614ee755a8 58 | # The following patterns were generated by expo-cli 59 | 60 | # OSX 61 | # 62 | .DS_Store 63 | 64 | # Xcode 65 | # 66 | build/ 67 | *.pbxuser 68 | !default.pbxuser 69 | *.mode1v3 70 | !default.mode1v3 71 | *.mode2v3 72 | !default.mode2v3 73 | *.perspectivev3 74 | !default.perspectivev3 75 | xcuserdata 76 | *.xccheckout 77 | *.moved-aside 78 | DerivedData 79 | *.hmap 80 | *.ipa 81 | *.xcuserstate 82 | project.xcworkspace 83 | 84 | # Android/IntelliJ 85 | # 86 | build/ 87 | .idea 88 | .gradle 89 | local.properties 90 | *.iml 91 | *.hprof 92 | 93 | # node.js 94 | # 95 | node_modules/ 96 | npm-debug.log 97 | yarn-error.log 98 | 99 | # BUCK 100 | buck-out/ 101 | \.buckd/ 102 | *.keystore 103 | !debug.keystore 104 | 105 | # Bundle artifacts 106 | *.jsbundle 107 | 108 | # CocoaPods 109 | /ios/Pods/ 110 | 111 | # Expo 112 | .expo/ 113 | web-build/ 114 | dist/ 115 | 116 | # @end expo-cli 117 | 118 | # google api keys file 119 | google-maps-api-keys.json 120 | 121 | # Info.plist 122 | /ios/example/Info.plist 123 | 124 | # AndroidManifest.xml 125 | /android/app/src/main/AndroidManifest.xml 126 | -------------------------------------------------------------------------------- /example/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import { NavigationContainer } from '@react-navigation/native'; 3 | import MainNavigator from './navigators/MainNavigator'; 4 | import { Platform } from 'react-native'; 5 | import { Providers } from 'expo-maps/build/Map.types'; 6 | import SwitchContainer from './components/SwitchContainer'; 7 | import ProviderContext from './context/ProviderContext'; 8 | import { View } from 'react-native'; 9 | import * as Location from 'expo-location'; 10 | 11 | export default function App() { 12 | const [provider, setProvider] = useState('google'); 13 | 14 | // it should be done as a part of library, just for now in example app 15 | const getLocationPermissions = async () => { 16 | await Location.requestForegroundPermissionsAsync(); 17 | }; 18 | 19 | useEffect(() => { 20 | getLocationPermissions(); 21 | }, []); 22 | 23 | return ( 24 | 25 | 26 | 27 | {Platform.OS === 'ios' && ( 28 | 29 | 33 | setProvider(provider === 'google' ? 'apple' : 'google') 34 | } 35 | /> 36 | 37 | )} 38 | 39 | 40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /example/__tests__/App.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import App from '../App'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | renderer.create(); 10 | }); 11 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Android/IntelliJ 6 | # 7 | build/ 8 | .idea 9 | .gradle 10 | local.properties 11 | *.iml 12 | *.hprof 13 | 14 | # BUCK 15 | buck-out/ 16 | \.buckd/ 17 | *.keystore 18 | !debug.keystore 19 | 20 | # Bundle artifacts 21 | *.jsbundle 22 | -------------------------------------------------------------------------------- /example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | # To learn about Buck see [Docs](https://buckbuild.com/). 2 | # To run your application with Buck: 3 | # - install Buck 4 | # - `npm start` - to start the packager 5 | # - `cd android` 6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 8 | # - `buck install -r android/app` - compile, install and run application 9 | # 10 | 11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") 12 | 13 | lib_deps = [] 14 | 15 | create_aar_targets(glob(["libs/*.aar"])) 16 | 17 | create_jar_targets(glob(["libs/*.jar"])) 18 | 19 | android_library( 20 | name = "all-libs", 21 | exported_deps = lib_deps, 22 | ) 23 | 24 | android_library( 25 | name = "app-code", 26 | srcs = glob([ 27 | "src/main/java/**/*.java", 28 | ]), 29 | deps = [ 30 | ":all-libs", 31 | ":build_config", 32 | ":res", 33 | ], 34 | ) 35 | 36 | android_build_config( 37 | name = "build_config", 38 | package = "com.expo.expo.maps", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.expo.expo.maps", 44 | res = "src/main/res", 45 | ) 46 | 47 | android_binary( 48 | name = "app", 49 | keystore = "//android/keystores:debug", 50 | manifest = "src/main/AndroidManifest.xml", 51 | package_type = "debug", 52 | deps = [ 53 | ":app-code", 54 | ], 55 | ) 56 | -------------------------------------------------------------------------------- /example/android/app/build_defs.bzl: -------------------------------------------------------------------------------- 1 | """Helper definitions to glob .aar and .jar targets""" 2 | 3 | def create_aar_targets(aarfiles): 4 | for aarfile in aarfiles: 5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] 6 | lib_deps.append(":" + name) 7 | android_prebuilt_aar( 8 | name = name, 9 | aar = aarfile, 10 | ) 11 | 12 | def create_jar_targets(jarfiles): 13 | for jarfile in jarfiles: 14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] 15 | lib_deps.append(":" + name) 16 | prebuilt_jar( 17 | name = name, 18 | binary_jar = jarfile, 19 | ) 20 | -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # react-native-reanimated 11 | -keep class com.swmansion.reanimated.** { *; } 12 | -keep class com.facebook.react.turbomodule.** { *; } 13 | 14 | # Add any project specific keep options here: 15 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/expo/expo/maps/newarchitecture/components/MainComponentsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.expo.expo.maps.newarchitecture.components; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.proguard.annotations.DoNotStrip; 5 | import com.facebook.react.fabric.ComponentFactory; 6 | import com.facebook.soloader.SoLoader; 7 | 8 | /** 9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a 10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 11 | * folder for you). 12 | * 13 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 14 | * `newArchEnabled` property). Is ignored otherwise. 15 | */ 16 | @DoNotStrip 17 | public class MainComponentsRegistry { 18 | static { 19 | SoLoader.loadLibrary("fabricjni"); 20 | } 21 | 22 | @DoNotStrip private final HybridData mHybridData; 23 | 24 | @DoNotStrip 25 | private native HybridData initHybrid(ComponentFactory componentFactory); 26 | 27 | @DoNotStrip 28 | private MainComponentsRegistry(ComponentFactory componentFactory) { 29 | mHybridData = initHybrid(componentFactory); 30 | } 31 | 32 | @DoNotStrip 33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) { 34 | return new MainComponentsRegistry(componentFactory); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/expo/expo/maps/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java: -------------------------------------------------------------------------------- 1 | package com.expo.expo.maps.newarchitecture.modules; 2 | 3 | import com.facebook.jni.HybridData; 4 | import com.facebook.react.ReactPackage; 5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.soloader.SoLoader; 8 | import java.util.List; 9 | 10 | /** 11 | * Class responsible to load the TurboModules. This class has native methods and needs a 12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ 13 | * folder for you). 14 | * 15 | *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the 16 | * `newArchEnabled` property). Is ignored otherwise. 17 | */ 18 | public class MainApplicationTurboModuleManagerDelegate 19 | extends ReactPackageTurboModuleManagerDelegate { 20 | 21 | private static volatile boolean sIsSoLibraryLoaded; 22 | 23 | protected MainApplicationTurboModuleManagerDelegate( 24 | ReactApplicationContext reactApplicationContext, List packages) { 25 | super(reactApplicationContext, packages); 26 | } 27 | 28 | protected native HybridData initHybrid(); 29 | 30 | native boolean canCreateTurboModule(String moduleName); 31 | 32 | public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { 33 | protected MainApplicationTurboModuleManagerDelegate build( 34 | ReactApplicationContext context, List packages) { 35 | return new MainApplicationTurboModuleManagerDelegate(context, packages); 36 | } 37 | } 38 | 39 | @Override 40 | protected synchronized void maybeLoadOtherSoLibraries() { 41 | if (!sIsSoLibraryLoaded) { 42 | // If you change the name of your application .so file in the Android.mk file, 43 | // make sure you update the name here as well. 44 | SoLoader.loadLibrary("example_appmodules"); 45 | sIsSoLibraryLoaded = true; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/Android.mk: -------------------------------------------------------------------------------- 1 | THIS_DIR := $(call my-dir) 2 | 3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk 4 | 5 | # If you wish to add a custom TurboModule or Fabric component in your app you 6 | # will have to include the following autogenerated makefile. 7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk 8 | include $(CLEAR_VARS) 9 | 10 | LOCAL_PATH := $(THIS_DIR) 11 | 12 | # You can customize the name of your application .so file here. 13 | LOCAL_MODULE := example_appmodules 14 | 15 | LOCAL_C_INCLUDES := $(LOCAL_PATH) 16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) 17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) 18 | 19 | # If you wish to add a custom TurboModule or Fabric component in your app you 20 | # will have to uncomment those lines to include the generated source 21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) 22 | # 23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) 25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni 26 | 27 | # Here you should add any native library you wish to depend on. 28 | LOCAL_SHARED_LIBRARIES := \ 29 | libfabricjni \ 30 | libfbjni \ 31 | libfolly_runtime \ 32 | libglog \ 33 | libjsi \ 34 | libreact_codegen_rncore \ 35 | libreact_debug \ 36 | libreact_nativemodule_core \ 37 | libreact_render_componentregistry \ 38 | libreact_render_core \ 39 | libreact_render_debug \ 40 | libreact_render_graphics \ 41 | librrc_view \ 42 | libruntimeexecutor \ 43 | libturbomodulejsijni \ 44 | libyoga 45 | 46 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall 47 | 48 | include $(BUILD_SHARED_LIBRARY) 49 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationModuleProvider.h" 2 | 3 | #include 4 | 5 | namespace facebook { 6 | namespace react { 7 | 8 | std::shared_ptr MainApplicationModuleProvider( 9 | const std::string moduleName, 10 | const JavaTurboModule::InitParams ¶ms) { 11 | // Here you can provide your own module provider for TurboModules coming from 12 | // either your application or from external libraries. The approach to follow 13 | // is similar to the following (for a library called `samplelibrary`: 14 | // 15 | // auto module = samplelibrary_ModuleProvider(moduleName, params); 16 | // if (module != nullptr) { 17 | // return module; 18 | // } 19 | // return rncore_ModuleProvider(moduleName, params); 20 | return rncore_ModuleProvider(moduleName, params); 21 | } 22 | 23 | } // namespace react 24 | } // namespace facebook 25 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationModuleProvider.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | std::shared_ptr MainApplicationModuleProvider( 12 | const std::string moduleName, 13 | const JavaTurboModule::InitParams ¶ms); 14 | 15 | } // namespace react 16 | } // namespace facebook 17 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "MainApplicationTurboModuleManagerDelegate.h" 2 | #include "MainApplicationModuleProvider.h" 3 | 4 | namespace facebook { 5 | namespace react { 6 | 7 | jni::local_ref 8 | MainApplicationTurboModuleManagerDelegate::initHybrid( 9 | jni::alias_ref) { 10 | return makeCxxInstance(); 11 | } 12 | 13 | void MainApplicationTurboModuleManagerDelegate::registerNatives() { 14 | registerHybrid({ 15 | makeNativeMethod( 16 | "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), 17 | makeNativeMethod( 18 | "canCreateTurboModule", 19 | MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), 20 | }); 21 | } 22 | 23 | std::shared_ptr 24 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 25 | const std::string name, 26 | const std::shared_ptr jsInvoker) { 27 | // Not implemented yet: provide pure-C++ NativeModules here. 28 | return nullptr; 29 | } 30 | 31 | std::shared_ptr 32 | MainApplicationTurboModuleManagerDelegate::getTurboModule( 33 | const std::string name, 34 | const JavaTurboModule::InitParams ¶ms) { 35 | return MainApplicationModuleProvider(name, params); 36 | } 37 | 38 | bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( 39 | std::string name) { 40 | return getTurboModule(name, nullptr) != nullptr || 41 | getTurboModule(name, {.moduleName = name}) != nullptr; 42 | } 43 | 44 | } // namespace react 45 | } // namespace facebook 46 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | namespace facebook { 8 | namespace react { 9 | 10 | class MainApplicationTurboModuleManagerDelegate 11 | : public jni::HybridClass< 12 | MainApplicationTurboModuleManagerDelegate, 13 | TurboModuleManagerDelegate> { 14 | public: 15 | // Adapt it to the package you used for your Java class. 16 | static constexpr auto kJavaDescriptor = 17 | "Lcom/expo/expo/maps/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; 18 | 19 | static jni::local_ref initHybrid(jni::alias_ref); 20 | 21 | static void registerNatives(); 22 | 23 | std::shared_ptr getTurboModule( 24 | const std::string name, 25 | const std::shared_ptr jsInvoker) override; 26 | std::shared_ptr getTurboModule( 27 | const std::string name, 28 | const JavaTurboModule::InitParams ¶ms) override; 29 | 30 | /** 31 | * Test-only method. Allows user to verify whether a TurboModule can be 32 | * created by instances of this class. 33 | */ 34 | bool canCreateTurboModule(std::string name); 35 | }; 36 | 37 | } // namespace react 38 | } // namespace facebook 39 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.cpp: -------------------------------------------------------------------------------- 1 | #include "MainComponentsRegistry.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} 12 | 13 | std::shared_ptr 14 | MainComponentsRegistry::sharedProviderRegistry() { 15 | auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); 16 | 17 | // Custom Fabric Components go here. You can register custom 18 | // components coming from your App or from 3rd party libraries here. 19 | // 20 | // providerRegistry->add(concreteComponentDescriptorProvider< 21 | // AocViewerComponentDescriptor>()); 22 | return providerRegistry; 23 | } 24 | 25 | jni::local_ref 26 | MainComponentsRegistry::initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate) { 29 | auto instance = makeCxxInstance(delegate); 30 | 31 | auto buildRegistryFunction = 32 | [](EventDispatcher::Weak const &eventDispatcher, 33 | ContextContainer::Shared const &contextContainer) 34 | -> ComponentDescriptorRegistry::Shared { 35 | auto registry = MainComponentsRegistry::sharedProviderRegistry() 36 | ->createComponentDescriptorRegistry( 37 | {eventDispatcher, contextContainer}); 38 | 39 | auto mutableRegistry = 40 | std::const_pointer_cast(registry); 41 | 42 | mutableRegistry->setFallbackComponentDescriptor( 43 | std::make_shared( 44 | ComponentDescriptorParameters{ 45 | eventDispatcher, contextContainer, nullptr})); 46 | 47 | return registry; 48 | }; 49 | 50 | delegate->buildRegistryFunction = buildRegistryFunction; 51 | return instance; 52 | } 53 | 54 | void MainComponentsRegistry::registerNatives() { 55 | registerHybrid({ 56 | makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), 57 | }); 58 | } 59 | 60 | } // namespace react 61 | } // namespace facebook 62 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/MainComponentsRegistry.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace facebook { 9 | namespace react { 10 | 11 | class MainComponentsRegistry 12 | : public facebook::jni::HybridClass { 13 | public: 14 | // Adapt it to the package you used for your Java class. 15 | constexpr static auto kJavaDescriptor = 16 | "Lcom/expo/expo/maps/newarchitecture/components/MainComponentsRegistry;"; 17 | 18 | static void registerNatives(); 19 | 20 | MainComponentsRegistry(ComponentFactory *delegate); 21 | 22 | private: 23 | static std::shared_ptr 24 | sharedProviderRegistry(); 25 | 26 | static jni::local_ref initHybrid( 27 | jni::alias_ref, 28 | ComponentFactory *delegate); 29 | }; 30 | 31 | } // namespace react 32 | } // namespace facebook 33 | -------------------------------------------------------------------------------- /example/android/app/src/main/jni/OnLoad.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "MainApplicationTurboModuleManagerDelegate.h" 3 | #include "MainComponentsRegistry.h" 4 | 5 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { 6 | return facebook::jni::initialize(vm, [] { 7 | facebook::react::MainApplicationTurboModuleManagerDelegate:: 8 | registerNatives(); 9 | facebook::react::MainComponentsRegistry::registerNatives(); 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/splashscreen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/colors.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | #023c69 3 | #ffffff 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | example 3 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 14 | 17 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.taskdefs.condition.Os 2 | 3 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 4 | 5 | buildscript { 6 | ext { 7 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '31.0.0' 8 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '21') 9 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '31') 10 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '31') 11 | if (findProperty('android.kotlinVersion')) { 12 | kotlinVersion = findProperty('android.kotlinVersion') 13 | } 14 | frescoVersion = findProperty('expo.frescoVersion') ?: '2.5.0' 15 | 16 | if (System.properties['os.arch'] == 'aarch64') { 17 | // For M1 Users we need to use the NDK 24 which added support for aarch64 18 | ndkVersion = '24.0.8215888' 19 | } else { 20 | // Otherwise we default to the side-by-side NDK version from AGP. 21 | ndkVersion = '21.4.7075529' 22 | } 23 | } 24 | repositories { 25 | google() 26 | mavenCentral() 27 | } 28 | dependencies { 29 | classpath('com.android.tools.build:gradle:7.1.1') 30 | classpath('com.facebook.react:react-native-gradle-plugin') 31 | classpath('de.undercouch:gradle-download-task:5.0.1') 32 | // NOTE: Do not place your application dependencies here; they belong 33 | // in the individual module build.gradle files 34 | } 35 | } 36 | 37 | allprojects { 38 | repositories { 39 | mavenLocal() 40 | maven { 41 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 42 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android')) 43 | } 44 | maven { 45 | // Android JSC is installed from npm 46 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), '../dist')) 47 | } 48 | 49 | google() 50 | mavenCentral { 51 | // We don't want to fetch react-native from Maven Central as there are 52 | // older versions over there. 53 | content { 54 | excludeGroup 'com.facebook.react' 55 | } 56 | } 57 | maven { url 'https://www.jitpack.io' } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | 25 | # Automatically convert third-party libraries to use AndroidX 26 | android.enableJetifier=true 27 | 28 | # Version of flipper SDK to use with React Native 29 | FLIPPER_VERSION=0.125.0 30 | 31 | # Use this property to specify which architecture you want to build. 32 | # You can also override it from the CLI using 33 | # ./gradlew -PreactNativeArchitectures=x86_64 34 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 35 | 36 | # Use this property to enable support to the new architecture. 37 | # This will allow you to use TurboModules and the Fabric render in 38 | # your application. You should enable this flag either if you want 39 | # to write custom TurboModules/Fabric components OR use libraries that 40 | # are providing them. 41 | newArchEnabled=false 42 | 43 | # The hosted JavaScript engine 44 | # Supported values: expo.jsEngine = "hermes" | "jsc" 45 | expo.jsEngine=jsc 46 | 47 | # Enable GIF support in React Native images (~200 B increase) 48 | expo.gif.enabled=true 49 | # Enable webp support in React Native images (~85 KB increase) 50 | expo.webp.enabled=true 51 | # Enable animated webp support (~3.4 MB increase) 52 | # Disabled by default because iOS doesn't support animated webp 53 | expo.webp.animated=false 54 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | 3 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle"); 4 | useExpoModules() 5 | 6 | apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle"); 7 | applyNativeModulesSettingsGradle(settings) 8 | 9 | include ':app' 10 | includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile()) 11 | 12 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 13 | include(":ReactAndroid") 14 | project(":ReactAndroid").projectDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../ReactAndroid"); 15 | include(":ReactAndroid:hermes-engine") 16 | project(":ReactAndroid:hermes-engine").projectDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), "../ReactAndroid/hermes-engine"); 17 | } 18 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "example", 4 | "slug": "example", 5 | "version": "1.0.0", 6 | "assetBundlePatterns": ["**/*"], 7 | "android": { 8 | "package": "com.expo.expo.maps" 9 | }, 10 | "ios": { 11 | "bundleIdentifier": "com.expo.expo.maps" 12 | }, 13 | "plugins": ["./expo-maps.plugin.ios", "./expo-maps.plugin.android"] 14 | }, 15 | "name": "example" 16 | } 17 | -------------------------------------------------------------------------------- /example/assets/building.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/assets/building.png -------------------------------------------------------------------------------- /example/assets/newark_nj_1922.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/assets/newark_nj_1922.jpeg -------------------------------------------------------------------------------- /example/assets/sample.geo.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "FeatureCollection", 3 | "features": [ 4 | { 5 | "type": "Feature", 6 | "geometry": { "type": "Point", "coordinates": [102.0, 0.5] }, 7 | "properties": { 8 | "color": "blue", 9 | "title": "Marker", 10 | "snippet": "This is marker from GeoJSON" 11 | } 12 | }, 13 | { 14 | "type": "Feature", 15 | "geometry": { 16 | "type": "LineString", 17 | "coordinates": [ 18 | [1.75, 47.69], 19 | [21.89, 42.79], 20 | [43.65, 53.22], 21 | [58.58, 48.58] 22 | ] 23 | }, 24 | "properties": { 25 | "color": "magenta", 26 | "pattern": [ 27 | { "type": "stroke", "length": 10 }, 28 | { "type": "stroke", "length": 0 }, 29 | { "type": "stroke", "length": 10 }, 30 | { "type": "gap", "length": 10 }, 31 | { "type": "stroke", "length": 0 }, 32 | { "type": "gap", "length": 10 } 33 | ] 34 | } 35 | }, 36 | { 37 | "type": "Feature", 38 | "geometry": { 39 | "type": "Polygon", 40 | "coordinates": [ 41 | [ 42 | [15.73, 53.84], 43 | [16.31, 51.11], 44 | [50.14, 22.07], 45 | [53.18, 22.11] 46 | ] 47 | ] 48 | }, 49 | "properties": { 50 | "fillColor": "blue", 51 | "strokeColor": "#000000", 52 | "strokeWidth": 10, 53 | "strokeJointType": "bevel", 54 | "strokePattern": [ 55 | { "type": "stroke", "length": 10 }, 56 | { "type": "stroke", "length": 0 }, 57 | { "type": "stroke", "length": 10 }, 58 | { "type": "gap", "length": 10 }, 59 | { "type": "stroke", "length": 0 }, 60 | { "type": "gap", "length": 10 } 61 | ] 62 | } 63 | }, 64 | { 65 | "type": "Feature", 66 | "geometry": { 67 | "type": "Polygon", 68 | "coordinates": [ 69 | [ 70 | [11.73, 52.84], 71 | [13.31, 50.11], 72 | [50.14, 22.07] 73 | ] 74 | ] 75 | }, 76 | "properties": { 77 | "strokeColor": "#000000", 78 | "strokeWidth": 10, 79 | "strokeJointType": "bevel", 80 | "strokePattern": [ 81 | { "type": "stroke", "length": 10 }, 82 | { "type": "stroke", "length": 0 }, 83 | { "type": "stroke", "length": 10 }, 84 | { "type": "gap", "length": 10 }, 85 | { "type": "stroke", "length": 0 }, 86 | { "type": "gap", "length": 10 } 87 | ] 88 | } 89 | } 90 | ] 91 | } 92 | -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: [["babel-preset-expo", { jsxRuntime: "automatic" }]], 5 | plugins: ["react-native-reanimated/plugin"], 6 | }; 7 | }; 8 | -------------------------------------------------------------------------------- /example/components/ExamplesListItem.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Text, TouchableOpacity } from 'react-native'; 3 | 4 | interface ExampleListItem { 5 | onExampleSelect: () => void; 6 | name: string; 7 | } 8 | 9 | export default function ExampleListItem({ 10 | onExampleSelect, 11 | name, 12 | }: ExampleListItem) { 13 | return ( 14 | 15 | {name} 16 | 17 | ); 18 | } 19 | 20 | const styles = StyleSheet.create({ 21 | exampleListItem: { 22 | flex: 1, 23 | height: 80, 24 | alignItems: 'center', 25 | justifyContent: 'center', 26 | marginVertical: 10, 27 | marginHorizontal: 30, 28 | borderRadius: 10, 29 | shadowOpacity: 0.1, 30 | shadowRadius: 5, 31 | elevation: 8, 32 | shadowColor: 'rgba(0,0,0,0.56)', 33 | backgroundColor: 'white', 34 | }, 35 | nameText: { 36 | fontSize: 16, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /example/components/SwitchContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Switch, View, StyleSheet, Text } from 'react-native'; 3 | 4 | interface SwitchContainerProps { 5 | title: string; 6 | onValueChange: () => void; 7 | value: boolean; 8 | enabled?: boolean; 9 | } 10 | 11 | export default function SwitchContainer({ 12 | title, 13 | onValueChange, 14 | value, 15 | enabled = true, 16 | }: SwitchContainerProps) { 17 | return enabled ? ( 18 | 19 | {title} 20 | onValueChange()} 23 | trackColor={{ true: 'green', false: 'red' }} 24 | /> 25 | 26 | ) : null; 27 | } 28 | 29 | const styles = StyleSheet.create({ 30 | switchContainer: { 31 | margin: 5, 32 | flexDirection: 'row', 33 | justifyContent: 'space-between', 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /example/context/ProviderContext.ts: -------------------------------------------------------------------------------- 1 | import { Providers } from 'expo-maps/build/Map.types'; 2 | import { createContext } from 'react'; 3 | 4 | const ProviderContext = createContext('google'); 5 | 6 | export default ProviderContext; 7 | -------------------------------------------------------------------------------- /example/expo-maps.plugin.android.js: -------------------------------------------------------------------------------- 1 | const { withAndroidManifest, AndroidConfig } = require('@expo/config-plugins'); 2 | 3 | const { addMetaDataItemToMainApplication, getMainApplicationOrThrow } = 4 | AndroidConfig.Manifest; 5 | 6 | module.exports = function withExpoMaps(config) { 7 | return withAndroidManifest(config, async (config) => { 8 | config.modResults = await setCustomConfigAsync(config, config.modResults); 9 | return config; 10 | }); 11 | }; 12 | 13 | async function setCustomConfigAsync(config, androidManifest) { 14 | const googleApiKeys = require('./google-maps-api-keys.json'); 15 | const mainApplication = getMainApplicationOrThrow(androidManifest); 16 | 17 | addMetaDataItemToMainApplication( 18 | mainApplication, 19 | // value for `android:name` 20 | 'com.google.android.geo.API_KEY', 21 | // value for `android:value` 22 | googleApiKeys.googleMapsApiKey 23 | ); 24 | 25 | return androidManifest; 26 | } 27 | -------------------------------------------------------------------------------- /example/expo-maps.plugin.ios.js: -------------------------------------------------------------------------------- 1 | const { withInfoPlist } = require('@expo/config-plugins'); 2 | 3 | module.exports = function withExpoMaps(config) { 4 | const googleApiKeys = require('./google-maps-api-keys.json'); 5 | return withInfoPlist(config, (config) => { 6 | config.modResults.GoogleMapsApiKey = googleApiKeys.googleMapsApiKey; 7 | return config; 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /example/google-maps-api-keys.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "googleMapsApiKey": "AIzaSyDbgaRNTr3PhYdj_PL7jY_o9u3R08Gf8Ao" 3 | } 4 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import 'react-native-gesture-handler'; 2 | import { registerRootComponent } from 'expo'; 3 | 4 | import App from './App'; 5 | 6 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App); 7 | // It also ensures that whether you load the app in Expo Go or in a native build, 8 | // the environment is set up appropriately 9 | registerRootComponent(App); 10 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /example/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") 2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") 3 | require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules") 4 | 5 | require 'json' 6 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} 7 | 8 | platform :ios, podfile_properties['ios.deploymentTarget'] || '12.4' 9 | install! 'cocoapods', 10 | :deterministic_uuids => false 11 | 12 | target 'example' do 13 | use_expo_modules! 14 | config = use_native_modules! 15 | 16 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] 17 | 18 | # Flags change depending on the env values. 19 | flags = get_default_flags() 20 | 21 | use_react_native!( 22 | :path => config[:reactNativePath], 23 | :hermes_enabled => flags[:hermes_enabled] || podfile_properties['expo.jsEngine'] == 'hermes', 24 | :fabric_enabled => flags[:fabric_enabled], 25 | # An absolute path to your application root. 26 | :app_path => "#{Dir.pwd}/.." 27 | ) 28 | 29 | # Uncomment to opt-in to using Flipper 30 | # Note that if you have use_frameworks! enabled, Flipper will not work 31 | # 32 | # if !ENV['CI'] 33 | # use_flipper!() 34 | # end 35 | 36 | post_install do |installer| 37 | react_native_post_install(installer) 38 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 39 | end 40 | 41 | post_integrate do |installer| 42 | begin 43 | expo_patch_react_imports!(installer) 44 | rescue => e 45 | Pod::UI.warn e 46 | end 47 | end 48 | 49 | end 50 | -------------------------------------------------------------------------------- /example/ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "jsc" 3 | } 4 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | #import 6 | 7 | @interface AppDelegate : EXAppDelegateWrapper 8 | 9 | @end 10 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "expo" 37 | } 38 | } -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/SplashScreenBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/SplashScreenBackground.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/software-mansion-labs/expo-maps/1ebe9d50a02afca60d6926f2dcdcee65ec9bd141/example/ios/example/Images.xcassets/SplashScreenBackground.imageset/image.png -------------------------------------------------------------------------------- /example/ios/example/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | EXUpdatesSDKVersion 12 | 46.0.0 13 | EXUpdatesURL 14 | https://exp.host/@anonymous/example 15 | 16 | -------------------------------------------------------------------------------- /example/ios/example/example.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | -------------------------------------------------------------------------------- /example/ios/example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /example/ios/example/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // 5 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const { getDefaultConfig } = require('expo/metro-config'); 2 | const path = require('path'); 3 | 4 | const projectRoot = __dirname; 5 | const workspaceRoot = path.resolve(__dirname, '..'); 6 | 7 | const config = getDefaultConfig(__dirname); 8 | 9 | config.watchFolders = [workspaceRoot]; 10 | config.resolver.nodeModulesPath = [ 11 | path.resolve(projectRoot, 'node_modules'), 12 | path.resolve(workspaceRoot, 'node_modules'), 13 | ]; 14 | 15 | config.resolver.assetExts.push('kml'); 16 | 17 | module.exports = config; 18 | -------------------------------------------------------------------------------- /example/navigators/MainNavigator.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStackNavigator } from '@react-navigation/stack'; 3 | import ExamplesListScreen from '../screens/ExamplesListScreen'; 4 | import { CONCRETE_EXAMPLE_SCREENS } from '../constants/ConcreteExampleScreens'; 5 | import { Providers } from 'expo-maps/build/Map.types'; 6 | 7 | // TODO: definetly type this better! 8 | interface ProviderProp { 9 | provider: Providers; 10 | } 11 | 12 | export type ExamplesStackNavigatorProps = { 13 | ExamplesListScreen: undefined; 14 | Markers: undefined; 15 | Polygons: undefined; 16 | Polylines: undefined; 17 | Circles: undefined; 18 | Controls: undefined; 19 | 'Google Maps Styling': undefined; 20 | Gestures: undefined; 21 | 'Map Types': undefined; 22 | 'Camera Position': undefined; 23 | Traffic: undefined; 24 | KML: undefined; 25 | GeoJson: undefined; 26 | Callbacks: undefined; 27 | POI: undefined; 28 | Overlays: undefined; 29 | Heatmaps: undefined; 30 | 'Map Move': undefined; 31 | }; 32 | 33 | const ExamplesStackNavigator = 34 | createStackNavigator(); 35 | 36 | export default function MainNavigator() { 37 | return ( 38 | 39 | 44 | {CONCRETE_EXAMPLE_SCREENS.map(({ name, screen }) => ( 45 | 53 | ))} 54 | 55 | ); 56 | } 57 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "private": true, 6 | "scripts": { 7 | "android": "expo run:android", 8 | "ios": "expo run:ios", 9 | "web": "expo start --web", 10 | "start": "expo start --dev-client" 11 | }, 12 | "dependencies": { 13 | "@babel/runtime": "^7.14.0", 14 | "@react-navigation/bottom-tabs": "^6.2.0", 15 | "@react-navigation/native": "^6.0.8", 16 | "@react-navigation/stack": "^6.1.1", 17 | "expo": "^46.0.1", 18 | "expo-error-recovery": "~3.2.0", 19 | "expo-maps": "*", 20 | "expo-modules-core": "~0.11.3", 21 | "expo-splash-screen": "~0.16.1", 22 | "expo-status-bar": "~1.4.0", 23 | "react": "18.0.0", 24 | "react-dom": "18.0.0", 25 | "react-native": "0.69.3", 26 | "react-native-dropdown-picker": "^5.3.0", 27 | "react-native-gesture-handler": "~2.5.0", 28 | "react-native-paper": "4.12.1", 29 | "react-native-reanimated": "~2.9.1", 30 | "react-native-safe-area-context": "4.3.1", 31 | "react-native-screens": "~3.15.0", 32 | "react-native-web": "~0.18.7" 33 | }, 34 | "devDependencies": { 35 | "@babel/core": "^7.12.9", 36 | "@types/react": "~17.0.21", 37 | "@types/react-native": "~0.67.6", 38 | "prettier": "2.7.1" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /example/screens/CirclesExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | import ProviderContext from '../context/ProviderContext'; 4 | 5 | import * as Maps from 'expo-maps'; 6 | 7 | export default function PolylinesExample() { 8 | const provider = useContext(ProviderContext); 9 | return ( 10 | 11 | 12 | 19 | 20 | 21 | ); 22 | } 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | flex: 1, 27 | }, 28 | }); 29 | -------------------------------------------------------------------------------- /example/screens/ControlsExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import SwitchContainer from '../components/SwitchContainer'; 6 | import ProviderContext from '../context/ProviderContext'; 7 | import { Platform } from 'expo-modules-core'; 8 | 9 | export default function ControlsExample() { 10 | const provider = useContext(ProviderContext); 11 | 12 | const [showZoomControls, setShowZoomControls] = useState(false); 13 | const [showCompass, setShowCompass] = useState(false); 14 | const [showMyLocationButton, setShowMyLocationButton] = 15 | useState(false); 16 | const [showLevelPicker, setShowLevelPicker] = useState(false); 17 | const [showMapToolbar, setShowMapToolbar] = useState(false); 18 | 19 | return ( 20 | 21 | 31 | 32 | {Platform.OS == 'android' && ( 33 | setShowZoomControls(!showZoomControls)} 37 | /> 38 | )} 39 | setShowCompass(!showCompass)} 43 | /> 44 | setShowMyLocationButton(!showMyLocationButton)} 48 | /> 49 | setShowLevelPicker(!showLevelPicker)} 53 | /> 54 | {Platform.OS == 'android' && ( 55 | setShowMapToolbar(!showMapToolbar)} 59 | /> 60 | )} 61 | 62 | 63 | ); 64 | } 65 | 66 | const styles = StyleSheet.create({ 67 | mapContainer: { 68 | flex: 1, 69 | }, 70 | }); 71 | -------------------------------------------------------------------------------- /example/screens/ExamplesListScreen.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { FlatList } from 'react-native'; 3 | import { View } from 'react-native'; 4 | import type { StackScreenProps } from '@react-navigation/stack'; 5 | import ExamplesListItem from '../components/ExamplesListItem'; 6 | import { ExamplesStackNavigatorProps } from '../navigators/MainNavigator'; 7 | import { CONCRETE_EXAMPLE_SCREENS } from '../constants/ConcreteExampleScreens'; 8 | 9 | type ExamplesListScreenProps = StackScreenProps< 10 | ExamplesStackNavigatorProps, 11 | 'ExamplesListScreen' 12 | >; 13 | 14 | export default function ExamplesListScreen({ 15 | navigation, 16 | }: ExamplesListScreenProps) { 17 | return ( 18 | 19 | ( 22 | { 26 | navigation.navigate(item.name); 27 | }} 28 | /> 29 | )} 30 | contentContainerStyle={{ paddingVertical: 15 }} 31 | /> 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /example/screens/GeoJsonExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | import * as Maps from 'expo-maps'; 4 | import ProviderContext from '../context/ProviderContext'; 5 | 6 | export default function GeoJsonExample() { 7 | const provider = useContext(ProviderContext); 8 | 9 | return ( 10 | 11 | 12 | 29 | 30 | 31 | ); 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /example/screens/GesturesExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import SwitchContainer from '../components/SwitchContainer'; 6 | import ProviderContext from '../context/ProviderContext'; 7 | 8 | export default function GesturesExample() { 9 | const provider = useContext(ProviderContext); 10 | 11 | const [enableRotateGestures, setEnableRotateGestures] = 12 | useState(false); 13 | const [enableScrollGestures, setEnableScrollGestures] = 14 | useState(false); 15 | const [enableTiltGestures, setEnableTiltGestures] = useState(false); 16 | const [enableZoomGestures, setEnableZoomGestures] = useState(false); 17 | 18 | return ( 19 | 20 | 28 | 29 | setEnableRotateGestures(!enableRotateGestures)} 33 | /> 34 | setEnableScrollGestures(!enableScrollGestures)} 38 | /> 39 | setEnableTiltGestures(!enableTiltGestures)} 43 | /> 44 | setEnableZoomGestures(!enableZoomGestures)} 48 | /> 49 | 50 | 51 | ); 52 | } 53 | 54 | const styles = StyleSheet.create({ 55 | container: { 56 | flex: 1, 57 | }, 58 | switchContainer: { 59 | margin: 5, 60 | flexDirection: 'row', 61 | justifyContent: 'space-between', 62 | }, 63 | }); 64 | -------------------------------------------------------------------------------- /example/screens/GoogleMapsStylingExample.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | 6 | export default function GoogleMapsStylingExample() { 7 | return ( 8 | 9 | 16 | 17 | ); 18 | } 19 | 20 | const styles = StyleSheet.create({ 21 | container: { 22 | flex: 1, 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /example/screens/HeatmapsExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | 7 | import * as points from '../assets/points.json'; 8 | import * as pointsWithData from '../assets/pointsWithData.json'; 9 | 10 | export default function HeatmapExample() { 11 | const provider = useContext(ProviderContext); 12 | 13 | return ( 14 | 15 | 16 | 21 | 25 | 26 | 27 | ); 28 | } 29 | 30 | const styles = StyleSheet.create({ 31 | container: { 32 | flex: 1, 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /example/screens/KMLExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | 7 | export default function KMLExample() { 8 | const provider = useContext(ProviderContext); 9 | 10 | return ( 11 | 12 | 23 | 24 | 25 | 26 | ); 27 | } 28 | 29 | const styles = StyleSheet.create({ 30 | container: { 31 | flex: 1, 32 | }, 33 | }); 34 | -------------------------------------------------------------------------------- /example/screens/MapTypesExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | import { MapTypes } from 'expo-maps/build/Map.types'; 7 | import DropDownPicker from 'react-native-dropdown-picker'; 8 | 9 | export default function MapTypesExample() { 10 | const provider = useContext(ProviderContext); 11 | 12 | const [mapType, setMapType] = useState('normal'); 13 | const [open, setOpen] = useState(false); 14 | return ( 15 | 16 | 21 | 22 | setMapType(value as MapTypes)} 31 | multiple={false} 32 | open={open} 33 | setOpen={() => setOpen(!open)} 34 | placeholder={mapType} 35 | /> 36 | 37 | 38 | ); 39 | } 40 | 41 | const styles = StyleSheet.create({ 42 | container: { 43 | flex: 1, 44 | }, 45 | }); 46 | -------------------------------------------------------------------------------- /example/screens/MarkersExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | 7 | export default function MarkerExample() { 8 | const provider = useContext(ProviderContext); 9 | 10 | return ( 11 | 12 | 13 | 20 | 27 | 35 | 42 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ); 58 | } 59 | 60 | const styles = StyleSheet.create({ 61 | container: { 62 | flex: 1, 63 | }, 64 | }); 65 | -------------------------------------------------------------------------------- /example/screens/OverlaysExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | 7 | export default function OverlaysExample() { 8 | const provider = useContext(ProviderContext); 9 | return ( 10 | 11 | 22 | 29 | 30 | 31 | ); 32 | } 33 | 34 | const styles = StyleSheet.create({ 35 | container: { 36 | flex: 1, 37 | }, 38 | map: { 39 | flex: 1, 40 | width: '100%', 41 | }, 42 | }); 43 | -------------------------------------------------------------------------------- /example/screens/PolygonsExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import ProviderContext from '../context/ProviderContext'; 6 | 7 | export default function PolygonsExample() { 8 | const provider = useContext(ProviderContext); 9 | return ( 10 | 11 | 12 | 20 | 30 | 41 | 42 | 43 | ); 44 | } 45 | 46 | const styles = StyleSheet.create({ 47 | container: { 48 | flex: 1, 49 | }, 50 | }); 51 | -------------------------------------------------------------------------------- /example/screens/PolylinesExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | import ProviderContext from '../context/ProviderContext'; 4 | 5 | import * as Maps from 'expo-maps'; 6 | 7 | export default function PolylinesExample() { 8 | const provider = useContext(ProviderContext); 9 | return ( 10 | 11 | 12 | 32 | 33 | 34 | ); 35 | } 36 | 37 | const styles = StyleSheet.create({ 38 | container: { 39 | flex: 1, 40 | }, 41 | }); 42 | -------------------------------------------------------------------------------- /example/screens/TrafficExample.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState } from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | 4 | import * as Maps from 'expo-maps'; 5 | import SwitchContainer from '../components/SwitchContainer'; 6 | import ProviderContext from '../context/ProviderContext'; 7 | 8 | export default function TrafficExample() { 9 | const provider = useContext(ProviderContext); 10 | 11 | const [showTraffic, setShowTraffic] = useState(false); 12 | 13 | return ( 14 | 15 | 20 | 21 | setShowTraffic(!showTraffic)} 25 | /> 26 | 27 | 28 | ); 29 | } 30 | 31 | const styles = StyleSheet.create({ 32 | mapContainer: { 33 | flex: 1, 34 | }, 35 | switchContainer: { 36 | padding: 20, 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "strict": true 5 | } 6 | } -------------------------------------------------------------------------------- /expo-maps/.eslintrc.js: -------------------------------------------------------------------------------- 1 | // @generated by expo-module-scripts 2 | module.exports = require('expo-module-scripts/eslintrc.base.js'); 3 | -------------------------------------------------------------------------------- /expo-maps/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": true 6 | } 7 | -------------------------------------------------------------------------------- /expo-maps/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## Unpublished 4 | 5 | ### 🛠 Breaking changes 6 | 7 | ### 🎉 New features 8 | 9 | ### 🐛 Bug fixes 10 | 11 | ### 💡 Others 12 | -------------------------------------------------------------------------------- /expo-maps/README.md: -------------------------------------------------------------------------------- 1 | # expo-maps 2 | 3 | Describe your module and why it's important in a few sentences. 4 | 5 | ## API documentation 6 | 7 | ## Installation in managed Expo projects 8 | 9 | ## Installation in bare React Native projects 10 | 11 | ## Contributing 12 | 13 | Contributions are very welcome! Please refer to guidelines described in the [contributing guide](https://github.com/expo/expo#contributing). 14 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/MapViewLifecycleEventListener.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps 2 | 3 | import com.google.android.gms.maps.MapView 4 | import expo.modules.core.interfaces.LifecycleEventListener 5 | 6 | class MapViewLifecycleEventListener(private val mapView: MapView) : LifecycleEventListener { 7 | 8 | override fun onHostResume() { 9 | mapView.onResume() 10 | } 11 | 12 | override fun onHostPause() { 13 | mapView.onPause() 14 | } 15 | 16 | override fun onHostDestroy() { 17 | mapView.onDestroy() 18 | } 19 | } -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsControls.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import com.google.android.gms.maps.GoogleMap 4 | import expo.modules.maps.interfaces.Controls 5 | 6 | class GoogleMapsControls(private val map: GoogleMap): Controls { 7 | 8 | override fun setShowZoomControl(enable: Boolean) { 9 | map.uiSettings.isZoomControlsEnabled = enable 10 | } 11 | 12 | override fun setShowCompass(enable: Boolean) { 13 | // the compass will only ever appear when the camera is oriented such that 14 | // it has a non-zero bearing or non-zero tilt. When the user clicks on the compass, 15 | // the camera animates back to the default orientation and the compass fades away shortly afterwards 16 | map.uiSettings.isCompassEnabled = enable 17 | } 18 | 19 | override fun setShowMapToolbar(enable: Boolean) { 20 | // the toolbar slides in when the user taps a marker 21 | // and slides out again when the marker is no longer in focus 22 | map.uiSettings.isMapToolbarEnabled = enable 23 | } 24 | 25 | override fun setShowMyLocationButton(enable: Boolean) { 26 | // the My Location button appears in the top right corner of 27 | // the screen only when the My Location layer is enabled 28 | @SuppressWarnings("MissingPermission") 29 | map.isMyLocationEnabled = true 30 | map.uiSettings.isMyLocationButtonEnabled = enable 31 | } 32 | 33 | override fun setShowLevelPicker(enable: Boolean) { 34 | // appears only when the user is viewing an indoor map 35 | map.uiSettings.isIndoorLevelPickerEnabled = enable 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsGestures.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import com.google.android.gms.maps.GoogleMap 4 | import expo.modules.maps.interfaces.Gestures 5 | 6 | class GoogleMapsGestures(private val googleMap: GoogleMap) : Gestures { 7 | 8 | override fun setEnabledRotateGesture(enabled: Boolean) { 9 | googleMap.uiSettings.isRotateGesturesEnabled = enabled 10 | } 11 | 12 | override fun setEnabledScrollGesture(enabled: Boolean) { 13 | googleMap.uiSettings.isScrollGesturesEnabled = enabled 14 | } 15 | 16 | override fun setEnabledTiltGesture(enabled: Boolean) { 17 | googleMap.uiSettings.isTiltGesturesEnabled = enabled 18 | } 19 | 20 | override fun setEnabledZoomGesture(enabled: Boolean) { 21 | googleMap.uiSettings.isZoomGesturesEnabled = enabled 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsHeatmaps.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import android.content.Context 4 | import android.graphics.Color 5 | import com.google.android.gms.maps.GoogleMap 6 | import com.google.android.gms.maps.model.LatLng 7 | import com.google.android.gms.maps.model.TileOverlay 8 | import com.google.android.gms.maps.model.TileOverlayOptions 9 | import com.google.maps.android.data.kml.KmlLayer 10 | import com.google.maps.android.heatmaps.Gradient 11 | import com.google.maps.android.heatmaps.HeatmapTileProvider 12 | import com.google.maps.android.heatmaps.WeightedLatLng 13 | import expo.modules.maps.HeatmapObject 14 | import expo.modules.maps.interfaces.Heatmaps 15 | 16 | class GoogleMapsHeatmaps(private val map: GoogleMap) : Heatmaps { 17 | 18 | private val heatmapOverlays = mutableListOf() 19 | 20 | override fun setHeatmaps(heatmapObjects: Array) { 21 | heatmapOverlays.forEach { it.remove() } 22 | heatmapOverlays.clear() 23 | 24 | for (heatmapObject in heatmapObjects) { 25 | var builder = HeatmapTileProvider.Builder() 26 | .weightedData(heatmapObject.points.map { 27 | WeightedLatLng(LatLng(it.latitude, it.longitude), it.data ?: 1.0) 28 | }) 29 | heatmapObject.gradient?.let { 30 | builder = builder.gradient( 31 | Gradient( 32 | it.colors.map { colorHexStringToInt(it) }.toIntArray(), 33 | it.locations)) 34 | } 35 | heatmapObject.radius.let { 36 | builder = builder.radius(it ?: 20) 37 | } 38 | heatmapObject.opacity.let { 39 | builder = builder.opacity(it ?: 1.0) 40 | } 41 | var provider = builder.build() 42 | val tileOverlay = map.addTileOverlay(TileOverlayOptions().tileProvider(provider)) 43 | tileOverlay?.let { heatmapOverlays.add(it) } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsKMLs.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import android.content.Context 4 | import android.net.Uri 5 | import com.google.android.gms.maps.GoogleMap 6 | import com.google.maps.android.data.kml.KmlLayer 7 | import expo.modules.maps.KMLObject 8 | import expo.modules.maps.interfaces.KMLs 9 | import java.io.File 10 | 11 | class GoogleMapsKMLs(private val context: Context, private val map: GoogleMap) : KMLs { 12 | 13 | private val layers = mutableListOf() 14 | 15 | override fun setKMLs(kmlObjects: Array) { 16 | deleteKMLs() 17 | 18 | kmlObjects.forEach { 19 | val path = File(Uri.parse(it.filePath).path!!) 20 | val layer = KmlLayer(map, path.inputStream(), context) 21 | layer.addLayerToMap() 22 | layers.add(layer) 23 | } 24 | } 25 | 26 | private fun deleteKMLs() { 27 | layers.forEach { it.removeLayerFromMap() } 28 | layers.clear() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsOverlays.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import android.net.Uri 4 | import com.google.android.gms.maps.GoogleMap 5 | import com.google.android.gms.maps.model.GroundOverlay 6 | import com.google.android.gms.maps.model.LatLng 7 | import com.google.android.gms.maps.model.LatLngBounds 8 | import com.google.android.gms.maps.model.GroundOverlayOptions 9 | import com.google.android.gms.maps.model.BitmapDescriptorFactory 10 | import expo.modules.maps.OverlayObject 11 | import expo.modules.maps.interfaces.Overlays 12 | 13 | class GoogleMapsOverlays(private val map: GoogleMap): Overlays { 14 | 15 | private val overlays = mutableListOf() 16 | 17 | override fun setOverlays(overlayObjects: Array) { 18 | detachAndDeleteOverlays() 19 | 20 | overlayObjects.forEach { overlayObject -> 21 | val localUri = Uri.parse(overlayObject.icon).path!! 22 | val southWest = LatLng(overlayObject.bounds.southWest.latitude, overlayObject.bounds.southWest.longitude) 23 | val northEast = LatLng(overlayObject.bounds.northEast.latitude, overlayObject.bounds.northEast.longitude) 24 | val bounds = LatLngBounds(southWest, northEast) 25 | val groundOverlayOptions = GroundOverlayOptions().image(BitmapDescriptorFactory.fromPath(localUri)).positionFromBounds(bounds) 26 | map.addGroundOverlay(groundOverlayOptions)?.let { overlays.add(it) } 27 | } 28 | } 29 | 30 | override fun detachAndDeleteOverlays() { 31 | overlays.forEach { it.remove() } 32 | overlays.clear() 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsPolygons.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import com.google.android.gms.maps.GoogleMap 4 | import com.google.android.gms.maps.model.* 5 | import expo.modules.maps.* 6 | import expo.modules.maps.interfaces.Polygons 7 | 8 | class GoogleMapsPolygons(private val map: GoogleMap) : Polygons { 9 | private val polygons = mutableListOf() 10 | 11 | override fun setPolygons(polygonObjects: Array) { 12 | detachAndDeletePolygons() 13 | for (polygonObject in polygonObjects) { 14 | val polygonOptions = PolygonOptions() 15 | for (point in polygonObject.points) { 16 | polygonOptions.add(LatLng(point.latitude, point.longitude)) 17 | } 18 | 19 | polygonObject.fillColor?.let { polygonOptions.fillColor(colorStringToARGBInt(it)) } 20 | polygonObject.strokeColor?.let { polygonOptions.strokeColor(colorStringToARGBInt(it)) } 21 | polygonObject.strokeWidth?.let { polygonOptions.strokeWidth(it) } 22 | polygonObject.strokePattern?.let { 23 | polygonOptions.strokePattern(it.map(::patternItemToNative)) 24 | } 25 | polygonObject.jointType?.let { polygonOptions.strokeJointType(it) } 26 | 27 | val polygon = map.addPolygon(polygonOptions) 28 | polygons.add(polygon) 29 | } 30 | } 31 | 32 | override fun detachAndDeletePolygons() { 33 | for (polygon in polygons) { 34 | polygon.remove() 35 | } 36 | polygons.clear() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/GoogleMapsPolylines.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps 2 | 3 | import com.google.android.gms.maps.GoogleMap 4 | import com.google.android.gms.maps.model.* 5 | import expo.modules.maps.* 6 | import expo.modules.maps.interfaces.Polylines 7 | 8 | class GoogleMapsPolylines(private val map: GoogleMap) : Polylines { 9 | private val polylines = mutableListOf() 10 | 11 | override fun setPolylines(polylineObjects: Array) { 12 | detachAndDeletePolylines() 13 | for (polylineObject in polylineObjects) { 14 | val polylineOptions = PolylineOptions() 15 | for (point in polylineObject.points) { 16 | polylineOptions.add(LatLng(point.latitude, point.longitude)) 17 | } 18 | 19 | polylineObject.color?.let { polylineOptions.color(colorStringToARGBInt(it)) } 20 | polylineObject.width?.let { polylineOptions.width(it) } 21 | polylineObject.pattern?.let { polylineOptions.pattern(it.map(::patternItemToNative)) } 22 | polylineObject.jointType?.let { polylineOptions.jointType(jointToNative(it)) } 23 | polylineObject.capType?.let { 24 | polylineOptions.startCap(capToNative(it)) 25 | polylineOptions.endCap(capToNative(it)) 26 | } 27 | 28 | val polyline = map.addPolyline(polylineOptions) 29 | polylines.add(polyline) 30 | } 31 | } 32 | 33 | override fun detachAndDeletePolylines() { 34 | for (polyline in polylines) { 35 | polyline.remove() 36 | } 37 | polylines.clear() 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/placesUtils/GoogleMapsPlacesSearchCompleter.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps.placesUtils 2 | 3 | import com.google.android.gms.maps.GoogleMap 4 | import com.google.android.libraries.places.api.model.AutocompletePrediction 5 | import com.google.android.libraries.places.api.model.AutocompleteSessionToken 6 | import com.google.android.libraries.places.api.model.RectangularBounds 7 | import com.google.android.libraries.places.api.model.TypeFilter 8 | import com.google.android.libraries.places.api.net.* 9 | import expo.modules.kotlin.Promise 10 | import expo.modules.kotlin.exception.CodedException 11 | 12 | class GoogleMapsPlacesSearchCompleter( 13 | private val placesClient: PlacesClient, 14 | private val tokenUtils: GoogleMapsPlacesTokenUtils, 15 | private val map: GoogleMap 16 | ) { 17 | 18 | private var searchCompleterResults = listOf() 19 | 20 | fun autoComplete(searchQueryFragment: String, searchCompletionsPromise: Promise) { 21 | val request = buildAutocompleteRequest(searchQueryFragment) 22 | placesClient.findAutocompletePredictions(request) 23 | .addOnSuccessListener { response -> 24 | searchCompleterResults = response.autocompletePredictions 25 | resolveSearchCompletionsPromise(searchCompletionsPromise) 26 | } 27 | .addOnFailureListener { exception -> 28 | val errorMessage = "Fetching AutocompletePredictions error, ${exception.message}" 29 | searchCompletionsPromise.reject(SearchCompleterException(errorMessage)) 30 | } 31 | } 32 | 33 | private fun buildAutocompleteRequest(query: String): FindAutocompletePredictionsRequest { 34 | return FindAutocompletePredictionsRequest.builder() 35 | .setLocationBias(getSearchCompletionRegion()) 36 | .setTypeFilter(TypeFilter.ESTABLISHMENT) 37 | .setSessionToken(getToken()) 38 | .setQuery(query) 39 | .build() 40 | } 41 | 42 | private fun getSearchCompletionRegion(): RectangularBounds { 43 | val visibleRegion = map.projection.visibleRegion.latLngBounds 44 | return RectangularBounds.newInstance(visibleRegion.southwest, visibleRegion.northeast) 45 | } 46 | 47 | private fun getToken(): AutocompleteSessionToken? { 48 | return tokenUtils.getToken() 49 | } 50 | 51 | private fun resolveSearchCompletionsPromise(searchCompletionsPromise: Promise) { 52 | val results = mapSearchCompletions(searchCompleterResults) 53 | searchCompletionsPromise.resolve(results) 54 | } 55 | 56 | private fun mapSearchCompletions(completions: List) = 57 | completions.map { "${it.getFullText(null)};${it.placeId}" } 58 | } 59 | 60 | private class SearchCompleterException(detailMessage: String) : CodedException(detailMessage) 61 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/placesUtils/GoogleMapsPlacesTokenUtils.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps.placesUtils 2 | 3 | import com.google.android.libraries.places.api.model.AutocompleteSessionToken 4 | 5 | class GoogleMapsPlacesTokenUtils { 6 | 7 | private var token = AutocompleteSessionToken.newInstance() 8 | 9 | fun setNewSessionToken() { 10 | token = AutocompleteSessionToken.newInstance() 11 | } 12 | 13 | fun getToken(): AutocompleteSessionToken? { 14 | return token 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/googleMaps/placesUtils/GooglePlacesFetchPlace.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.googleMaps.placesUtils 2 | 3 | import com.google.android.gms.maps.CameraUpdateFactory 4 | import com.google.android.gms.maps.GoogleMap 5 | import com.google.android.gms.maps.model.LatLng 6 | import com.google.android.libraries.places.api.model.Place 7 | import com.google.android.libraries.places.api.net.FetchPlaceRequest 8 | import com.google.android.libraries.places.api.net.FetchPlaceResponse 9 | import com.google.android.libraries.places.api.net.PlacesClient 10 | import expo.modules.maps.MarkerObject 11 | import expo.modules.maps.googleMaps.GoogleMapsMarkers 12 | 13 | class GooglePlacesFetchPlace( 14 | private val placesClient: PlacesClient, 15 | private val tokenUtils: GoogleMapsPlacesTokenUtils, 16 | private val markers: GoogleMapsMarkers, 17 | private val map: GoogleMap 18 | ) { 19 | 20 | private var fetchedPlace: Place? = null 21 | set(newValue) { 22 | field = newValue 23 | displayMarker() 24 | } 25 | 26 | fun search(placeId: String) { 27 | val placeFields = listOf(Place.Field.LAT_LNG, Place.Field.NAME, Place.Field.ADDRESS) 28 | val request = FetchPlaceRequest.newInstance(placeId, placeFields) 29 | 30 | placesClient.fetchPlace(request) 31 | .addOnSuccessListener { response: FetchPlaceResponse -> 32 | fetchedPlace = response.place 33 | } 34 | .addOnFailureListener { exception: Exception -> 35 | println("FetchPlace error, ${exception.message}") 36 | } 37 | 38 | tokenUtils.setNewSessionToken() 39 | } 40 | 41 | private fun displayMarker() { 42 | val marker = getMarkerToDisplay() ?: return 43 | markers.setPOIMarkers(arrayOf(marker)) 44 | val update = CameraUpdateFactory.newLatLng(LatLng(marker.latitude, marker.longitude)) 45 | map.moveCamera(update) 46 | } 47 | 48 | private fun getMarkerToDisplay(): MarkerObject? { 49 | val place = fetchedPlace ?: return null 50 | val latitude = place.latLng?.latitude ?: return null 51 | val longitude = place.latLng?.longitude ?: return null 52 | return MarkerObject( 53 | null, 54 | latitude, 55 | longitude, 56 | place.name ?: "", 57 | place.address ?: "", 58 | null, 59 | "red", 60 | false, 61 | null, 62 | null, 63 | 1.0 64 | ) 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Circles.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.CircleObject 4 | 5 | interface Circles { 6 | fun setCircles(circleObjects: Array) 7 | fun detachAndDeleteCircles() 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Clusters.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.ClusterObject 4 | 5 | interface Clusters { 6 | fun setClusters(clusterObjects: Array) 7 | } 8 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Controls.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | interface Controls { 4 | fun setShowZoomControl(enable: Boolean) 5 | fun setShowCompass(enable: Boolean) 6 | fun setShowMapToolbar(enable: Boolean) 7 | fun setShowMyLocationButton(enable: Boolean) 8 | fun setShowLevelPicker(enable: Boolean) 9 | } 10 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/ExpoMapView.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.kotlin.Promise 4 | import expo.modules.maps.* 5 | import expo.modules.maps.records.CameraMoveRecord 6 | 7 | interface ExpoMapView { 8 | fun setMapType(mapType: MapType) 9 | fun setMarkers(markerObjects: Array) 10 | fun setPolygons(polygonObjects: Array) 11 | fun setPolylines(polylineObjects: Array) 12 | fun setCircles(circleObjects: Array) 13 | fun setClusters(clusterObjects: Array) 14 | fun setEnabledTraffic(enableTraffic: Boolean) 15 | fun setKMLs(kmlObjects: Array) 16 | fun setGeoJsons(geoJsonObjects: Array) 17 | fun setInitialCameraPosition(initialCameraPosition: CameraMoveRecord) 18 | fun moveCamera(cameraMove: CameraMoveRecord, promise: Promise?) 19 | fun setOverlays(overlayObjects: Array) 20 | fun setHeatmaps(heatmapObjects: Array) 21 | } 22 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/GeoJsons.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.GeoJsonObject 4 | 5 | interface GeoJsons { 6 | fun setGeoJsons(geoJsonObjects: Array) 7 | } 8 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Gestures.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | interface Gestures { 4 | fun setEnabledRotateGesture(enabled: Boolean) 5 | fun setEnabledScrollGesture(enabled: Boolean) 6 | fun setEnabledTiltGesture(enabled: Boolean) 7 | fun setEnabledZoomGesture(enabled: Boolean) 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Heatmaps.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.HeatmapObject 4 | 5 | interface Heatmaps { 6 | fun setHeatmaps(heatmapObjects: Array) 7 | } 8 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/KMLs.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.KMLObject 4 | 5 | interface KMLs { 6 | fun setKMLs(kmlObjects: Array) 7 | } 8 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Markers.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.MarkerObject 4 | 5 | interface Markers { 6 | fun setMarkers(markerObjects: Array) 7 | fun detachAndDeleteMarkers() 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Overlays.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.OverlayObject 4 | 5 | interface Overlays { 6 | fun setOverlays(overlayObjects: Array) 7 | fun detachAndDeleteOverlays() 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Polygons.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.PolygonObject 4 | 5 | interface Polygons { 6 | fun setPolygons(polygonObjects: Array) 7 | fun detachAndDeletePolygons() 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/interfaces/Polylines.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.interfaces 2 | 3 | import expo.modules.maps.PolylineObject 4 | 5 | interface Polylines { 6 | fun setPolylines(polylineObjects: Array) 7 | fun detachAndDeletePolylines() 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/CameraMoveRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import expo.modules.kotlin.records.Field 4 | import expo.modules.kotlin.records.Record 5 | 6 | class CameraMoveRecord: Record { 7 | @Field 8 | var target: LatLngRecord? = null 9 | 10 | @Field 11 | var zoom: Float? = null 12 | 13 | @Field 14 | var bearing: Float? = null 15 | 16 | @Field 17 | var tilt: Float? = null 18 | 19 | @Field 20 | var latLngDelta: LatLngDeltaRecord? = null 21 | 22 | @Field 23 | var animate: Boolean = true 24 | 25 | @Field 26 | var duration: Int = 1000 27 | } 28 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/CameraPositionRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.android.gms.maps.model.CameraPosition 4 | import com.google.android.gms.maps.model.LatLng 5 | import expo.modules.kotlin.records.Field 6 | import expo.modules.kotlin.records.Record 7 | 8 | class CameraPositionRecord(cameraPosition: CameraPosition) : Record { 9 | @Field 10 | var target: LatLngRecord = LatLngRecord(cameraPosition.target) 11 | 12 | @Field 13 | var zoom: Float = cameraPosition.zoom 14 | 15 | @Field 16 | var bearing: Float = cameraPosition.bearing 17 | 18 | @Field 19 | var tilt: Float = cameraPosition.tilt 20 | } 21 | 22 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/ClusterRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.maps.android.clustering.Cluster 4 | import expo.modules.kotlin.records.Field 5 | import expo.modules.kotlin.records.Record 6 | import expo.modules.maps.MarkerObject 7 | 8 | class ClusterRecord(@Field var id: String?, cluster: Cluster) : Record { 9 | @Field 10 | var position: LatLngRecord = LatLngRecord(cluster.position) 11 | } 12 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/LatLngDeltaRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.android.gms.maps.model.LatLng 4 | import expo.modules.kotlin.records.Field 5 | import expo.modules.kotlin.records.Record 6 | 7 | class LatLngDeltaRecord(latLng: LatLng): Record { 8 | @Field 9 | var longitudeDelta: Double = 0.0 10 | 11 | @Field 12 | var latitudeDelta: Double = 0.0 13 | } 14 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/LatLngRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.android.gms.maps.model.LatLng 4 | import expo.modules.kotlin.records.Field 5 | import expo.modules.kotlin.records.Record 6 | 7 | class LatLngRecord(latLng: LatLng) : Record { 8 | @Field 9 | var longitude: Double = latLng.longitude 10 | 11 | @Field 12 | var latitude: Double = latLng.latitude 13 | } 14 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/MarkerRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.android.gms.maps.model.Marker 4 | import expo.modules.kotlin.records.Field 5 | import expo.modules.kotlin.records.Record 6 | import expo.modules.maps.MarkerObject 7 | 8 | class MarkerRecord(): Record { 9 | 10 | @Field 11 | lateinit var id: String 12 | 13 | @Field 14 | lateinit var position: LatLngRecord 15 | 16 | constructor(marker: Marker): this() { 17 | this.id = marker.id 18 | this.position = LatLngRecord(marker.position) 19 | } 20 | 21 | constructor(markerObject: MarkerObject): this() { 22 | this.id = markerObject.id.toString() 23 | this.position = LatLngRecord(markerObject.position) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/PointOfInterestRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import com.google.android.gms.maps.model.PointOfInterest 4 | import expo.modules.kotlin.records.Field 5 | import expo.modules.kotlin.records.Record 6 | 7 | class PointOfInterestRecord(pointOfInterest: PointOfInterest) : Record { 8 | @Field 9 | var position: LatLngRecord = LatLngRecord(pointOfInterest.latLng) 10 | 11 | @Field 12 | var name: String = pointOfInterest.name 13 | 14 | @Field 15 | var placeId: String = pointOfInterest.placeId 16 | } 17 | 18 | -------------------------------------------------------------------------------- /expo-maps/android/src/main/java/expo/modules/maps/records/UserLocationRecord.kt: -------------------------------------------------------------------------------- 1 | package expo.modules.maps.records 2 | 3 | import android.location.Location 4 | import android.os.Build 5 | import androidx.annotation.RequiresApi 6 | import com.google.android.gms.maps.model.LatLng 7 | import expo.modules.kotlin.records.Field 8 | import expo.modules.kotlin.records.Record 9 | 10 | class UserLocationRecord(location: Location) : Record { 11 | @Field 12 | var position: LatLngRecord = LatLngRecord(LatLng(location.latitude, location.longitude)) 13 | 14 | @Field 15 | var altitude: Double = location.altitude 16 | 17 | @Field 18 | var accuracy: Float = location.accuracy 19 | 20 | @RequiresApi(Build.VERSION_CODES.O) 21 | @Field 22 | var verticalAccuracy: Float = location.verticalAccuracyMeters 23 | 24 | @Field 25 | var speed: Float = location.speed 26 | 27 | @RequiresApi(Build.VERSION_CODES.O) 28 | @Field 29 | var speedAccuracy = location.speedAccuracyMetersPerSecond 30 | 31 | @Field 32 | var heading: Float = location.bearing 33 | 34 | @Field 35 | var timestamp: Long = location.time 36 | } 37 | -------------------------------------------------------------------------------- /expo-maps/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /expo-maps/build/Circle.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Point } from './Common.types'; 3 | /** 4 | * Props of Circle component of Expo Maps library. 5 | */ 6 | export declare type CircleProps = { 7 | /** 8 | * The center position of the circle. 9 | * @required 10 | */ 11 | center: Point; 12 | /** 13 | * The radius of the circle in meters. 14 | * @required 15 | */ 16 | radius: number; 17 | /** 18 | /** 19 | * Color of the circle's edge line (optional). 20 | * 21 | * Accepted formats: 22 | * * `'#RRGGBB'` 23 | * * `'#RRGGBBAA'` 24 | * * `'#RGB'` 25 | * * `'#RGBA'` 26 | * @default default for given map provider 27 | */ 28 | strokeColor?: string; 29 | /** 30 | * Circle edge's width in pixels. (optional) 31 | * 32 | * @default default for given map provider 33 | */ 34 | strokeWidth?: number; 35 | /** 36 | * Circle fill color in hex format (optional). 37 | 38 | * Accepted formats: 39 | * * `'#RRGGBB'` 40 | * * `'#RRGGBBAA'` 41 | * * `'#RGB'` 42 | * * `'#RGBA'` 43 | * @default '#00000000' 44 | */ 45 | fillColor?: string; 46 | }; 47 | /** 48 | * Internal JSON object for representing circles in Expo Maps library. 49 | * 50 | * See {@link CircleProps} for more detail. 51 | */ 52 | export declare type CircleObject = { 53 | type: 'circle'; 54 | center: Point; 55 | radius: number; 56 | strokeColor?: string; 57 | strokeWidth?: number; 58 | fillColor?: string; 59 | }; 60 | /** 61 | * Circle component of Expo Maps library. 62 | * 63 | * Draws customizable flat circle on ExpoMap. 64 | * Drawn circle does not follow curvature of the Earth. 65 | * 66 | * This component should be ExpoMap component child to work properly. 67 | * 68 | * See {@link CircleProps} to learn more about props. 69 | */ 70 | export declare class Circle extends React.Component { 71 | render(): null; 72 | } 73 | -------------------------------------------------------------------------------- /expo-maps/build/Circle.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Circle component of Expo Maps library. 4 | * 5 | * Draws customizable flat circle on ExpoMap. 6 | * Drawn circle does not follow curvature of the Earth. 7 | * 8 | * This component should be ExpoMap component child to work properly. 9 | * 10 | * See {@link CircleProps} to learn more about props. 11 | */ 12 | export class Circle extends React.Component { 13 | render() { 14 | return null; 15 | } 16 | } 17 | //# sourceMappingURL=Circle.js.map -------------------------------------------------------------------------------- /expo-maps/build/Circle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Circle.js","sourceRoot":"","sources":["../src/Circle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA+D1B;;;;;;;;;GASG;AACH,MAAM,OAAO,MAAO,SAAQ,KAAK,CAAC,SAAsB;IACtD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\r\nimport { Point } from './Common.types';\r\n\r\n/**\r\n * Props of Circle component of Expo Maps library.\r\n */\r\nexport type CircleProps = {\r\n /**\r\n * The center position of the circle.\r\n * @required\r\n */\r\n center: Point;\r\n /**\r\n * The radius of the circle in meters.\r\n * @required\r\n */\r\n radius: number;\r\n /**\r\n /**\r\n * Color of the circle's edge line (optional).\r\n * \r\n * Accepted formats:\r\n * * `'#RRGGBB'`\r\n * * `'#RRGGBBAA'`\r\n * * `'#RGB'`\r\n * * `'#RGBA'`\r\n * @default default for given map provider\r\n */\r\n strokeColor?: string;\r\n /**\r\n * Circle edge's width in pixels. (optional)\r\n * \r\n * @default default for given map provider\r\n */\r\n strokeWidth?: number;\r\n /**\r\n * Circle fill color in hex format (optional).\r\n\r\n * Accepted formats:\r\n * * `'#RRGGBB'`\r\n * * `'#RRGGBBAA'`\r\n * * `'#RGB'`\r\n * * `'#RGBA'`\r\n * @default '#00000000'\r\n */\r\n fillColor?: string;\r\n};\r\n\r\n\r\n/**\r\n * Internal JSON object for representing circles in Expo Maps library.\r\n *\r\n * See {@link CircleProps} for more detail.\r\n */\r\nexport type CircleObject = {\r\n type: 'circle';\r\n center: Point;\r\n radius: number;\r\n strokeColor?: string;\r\n strokeWidth?: number;\r\n fillColor?: string;\r\n};\r\n\r\n/**\r\n * Circle component of Expo Maps library.\r\n *\r\n * Draws customizable flat circle on ExpoMap.\r\n * Drawn circle does not follow curvature of the Earth.\r\n *\r\n * This component should be ExpoMap component child to work properly.\r\n *\r\n * See {@link CircleProps} to learn more about props.\r\n */\r\nexport class Circle extends React.Component {\r\n render() {\r\n return null;\r\n }\r\n}\r\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Cluster.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PropsWithChildren } from 'react'; 3 | import { BaseMarkerOptions, MarkerObject } from './Marker'; 4 | /** 5 | * Props of Cluster component of Expo Maps library. 6 | */ 7 | export declare type ClusterProps = PropsWithChildren<{ 8 | /** 9 | * Cluster name 10 | * 11 | * @required 12 | */ 13 | name: String; 14 | /** 15 | * Minimal number of markers to form the cluster 16 | * 17 | * @default 4 18 | */ 19 | minimumClusterSize?: number; 20 | } & BaseMarkerOptions>; 21 | /** 22 | * Internal JSON object for representing marker clusters in Expo Maps library. 23 | * 24 | * See {@link ClusterProps} for more detail. 25 | */ 26 | export declare type ClusterObject = { 27 | type: 'cluster'; 28 | markers: MarkerObject[]; 29 | name: String; 30 | minimumClusterSize: number; 31 | } & BaseMarkerOptions; 32 | /** 33 | * Cluster component of Expo Maps library. 34 | * 35 | * Gathers {@link Marker}s passed as this component children in cluster. 36 | * 37 | * This component should be ExpoMap component child to work properly. 38 | * 39 | * See {@link ClusterProps} to learn more about props. 40 | */ 41 | export declare class Cluster extends React.Component { 42 | render(): null; 43 | } 44 | -------------------------------------------------------------------------------- /expo-maps/build/Cluster.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Cluster component of Expo Maps library. 4 | * 5 | * Gathers {@link Marker}s passed as this component children in cluster. 6 | * 7 | * This component should be ExpoMap component child to work properly. 8 | * 9 | * See {@link ClusterProps} to learn more about props. 10 | */ 11 | export class Cluster extends React.Component { 12 | render() { 13 | return null; 14 | } 15 | } 16 | //# sourceMappingURL=Cluster.js.map -------------------------------------------------------------------------------- /expo-maps/build/Cluster.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Cluster.js","sourceRoot":"","sources":["../src/Cluster.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAoC1B;;;;;;;;GAQG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK,CAAC,SAAuB;IACxD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\nimport { PropsWithChildren } from 'react';\nimport { BaseMarkerOptions, MarkerObject, Marker } from './Marker';\n\n/**\n * Props of Cluster component of Expo Maps library.\n */\nexport type ClusterProps = PropsWithChildren<\n {\n /**\n * Cluster name\n *\n * @required\n */\n name: String;\n /**\n * Minimal number of markers to form the cluster\n *\n * @default 4\n */\n minimumClusterSize?: number;\n } & BaseMarkerOptions\n>;\n\n/**\n * Internal JSON object for representing marker clusters in Expo Maps library.\n *\n * See {@link ClusterProps} for more detail.\n */\nexport type ClusterObject = {\n type: 'cluster';\n markers: MarkerObject[];\n name: String;\n minimumClusterSize: number;\n} & BaseMarkerOptions;\n\n/**\n * Cluster component of Expo Maps library.\n *\n * Gathers {@link Marker}s passed as this component children in cluster.\n *\n * This component should be ExpoMap component child to work properly.\n *\n * See {@link ClusterProps} to learn more about props.\n */\nexport class Cluster extends React.Component {\n render() {\n return null;\n }\n}\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Common.types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Possible power priorities for OnLocationChange event 3 | */ 4 | export var LocationChangePriority; 5 | (function (LocationChangePriority) { 6 | /** 7 | * Best accuracy that the device can acquire. Will consume more power. 8 | */ 9 | LocationChangePriority[LocationChangePriority["PRIORITY_HIGH_ACCURACY"] = 100] = "PRIORITY_HIGH_ACCURACY"; 10 | /** 11 | * Bock level accuracy. Block level accuracy is considered to be about 100 meter accuracy. 12 | */ 13 | LocationChangePriority[LocationChangePriority["PRIORITY_BALANCED_POWER_ACCURACY"] = 102] = "PRIORITY_BALANCED_POWER_ACCURACY"; 14 | /** 15 | * City level accuracy. City level accuracy is considered to be about 10km accuracy. 16 | * Using a coarse accuracy such as this often consumes less power 17 | */ 18 | LocationChangePriority[LocationChangePriority["PRIORITY_LOW_POWER"] = 104] = "PRIORITY_LOW_POWER"; 19 | /** 20 | * No locations will be returned unless a different client has requested location updates in which case 21 | * this request will act as a passive listener to those locations. Will use no additional power 22 | */ 23 | LocationChangePriority[LocationChangePriority["PRIORITY_NO_POWER"] = 105] = "PRIORITY_NO_POWER"; 24 | })(LocationChangePriority || (LocationChangePriority = {})); 25 | //# sourceMappingURL=Common.types.js.map -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.d.ts: -------------------------------------------------------------------------------- 1 | export declare const NativeExpoAppleMapsModule: import("expo-modules-core").ProxyNativeModule; 2 | export declare const NativeExpoGoogleMapsModule: import("expo-modules-core").ProxyNativeModule; 3 | -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.js: -------------------------------------------------------------------------------- 1 | import { NativeModulesProxy } from 'expo-modules-core'; 2 | export const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps; 3 | export const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps; 4 | //# sourceMappingURL=ExpoMaps.js.map -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ExpoMaps.js","sourceRoot":"","sources":["../src/ExpoMaps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC,aAAa,CAAC;AAC1E,MAAM,CAAC,MAAM,0BAA0B,GAAG,kBAAkB,CAAC,cAAc,CAAC","sourcesContent":["import { NativeModulesProxy } from 'expo-modules-core';\n\nexport const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps;\nexport const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps;\n"]} -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.web.d.ts: -------------------------------------------------------------------------------- 1 | declare const _default: { 2 | readonly name: string; 3 | }; 4 | export default _default; 5 | -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.web.js: -------------------------------------------------------------------------------- 1 | export default { 2 | get name() { 3 | return 'ExpoMaps'; 4 | }, 5 | }; 6 | //# sourceMappingURL=ExpoMaps.web.js.map -------------------------------------------------------------------------------- /expo-maps/build/ExpoMaps.web.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"ExpoMaps.web.js","sourceRoot":"","sources":["../src/ExpoMaps.web.ts"],"names":[],"mappings":"AAAA,eAAe;IACb,IAAI,IAAI;QACN,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC","sourcesContent":["export default {\n get name(): string {\n return 'ExpoMaps';\n },\n};\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Heatmap.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PointWithData } from './Common.types'; 3 | import { ExpoLinearGradient } from 'expo-module-scripts'; 4 | /** 5 | * Props of Heatmap component of Expo Maps library. 6 | */ 7 | export declare type HeatmapProps = { 8 | points: PointWithData[]; 9 | } & HeatmapOptions; 10 | /** 11 | * Configuration options for the heatmap. 12 | */ 13 | export declare type HeatmapOptions = { 14 | /** 15 | * The radius of Gaussian blur applied to the points in pixels (optional). 16 | * @default 20 17 | */ 18 | radius?: number; 19 | /** 20 | * Defines the color theme of the heatmap (optianal). 21 | * 22 | * Color locations will correspond to colors for particular values on the heatmap scaled between 0 and 1. 23 | * 24 | * @default provider default 25 | */ 26 | gradient?: ExpoLinearGradient; 27 | /** 28 | * Opacity of the heatmap (optional). 29 | * @default 1 30 | */ 31 | opacity?: number; 32 | }; 33 | /** 34 | * Internal JSON object for representing marker clusters in Expo Maps library. 35 | * 36 | * See {@link ClusterProps} for more detail. 37 | */ 38 | export declare type HeatmapObject = { 39 | type: 'heatmap'; 40 | points: PointWithData[]; 41 | radius?: number; 42 | opacity?: number; 43 | } & HeatmapProps; 44 | /** 45 | * Heatmap component of Expo Maps library. 46 | * 47 | * Displays multiple {@link PointWithData} objects as a heatmap. 48 | * Providing data with each point is optional; if no data is provided, 49 | * heatmap will represent density of points on the map. 50 | * 51 | * This component should be ExpoMap component child to work properly. 52 | * 53 | * See {@link HeatmapProps} to learn more about props. 54 | */ 55 | export declare class Heatmap extends React.Component { 56 | render(): null; 57 | } 58 | -------------------------------------------------------------------------------- /expo-maps/build/Heatmap.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Heatmap component of Expo Maps library. 4 | * 5 | * Displays multiple {@link PointWithData} objects as a heatmap. 6 | * Providing data with each point is optional; if no data is provided, 7 | * heatmap will represent density of points on the map. 8 | * 9 | * This component should be ExpoMap component child to work properly. 10 | * 11 | * See {@link HeatmapProps} to learn more about props. 12 | */ 13 | export class Heatmap extends React.Component { 14 | render() { 15 | return null; 16 | } 17 | } 18 | //# sourceMappingURL=Heatmap.js.map -------------------------------------------------------------------------------- /expo-maps/build/Heatmap.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Heatmap.js","sourceRoot":"","sources":["../src/Heatmap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA+C1B;;;;;;;;;;GAUG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK,CAAC,SAAuB;IACxD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\nimport { PointWithData } from './Common.types';\nimport { ExpoLinearGradient } from 'expo-module-scripts';\n\n/**\n * Props of Heatmap component of Expo Maps library.\n */\nexport type HeatmapProps = {\n points: PointWithData[];\n} & HeatmapOptions;\n\n/**\n * Configuration options for the heatmap.\n */\nexport type HeatmapOptions = {\n /**\n * The radius of Gaussian blur applied to the points in pixels (optional).\n * @default 20\n */\n radius?: number;\n /**\n * Defines the color theme of the heatmap (optianal).\n * \n * Color locations will correspond to colors for particular values on the heatmap scaled between 0 and 1.\n * \n * @default provider default\n */\n gradient?: ExpoLinearGradient;\n /**\n * Opacity of the heatmap (optional).\n * @default 1\n */\n opacity?: number;\n};\n\n/**\n * Internal JSON object for representing marker clusters in Expo Maps library.\n *\n * See {@link ClusterProps} for more detail.\n */\nexport type HeatmapObject = {\n type: 'heatmap';\n points: PointWithData[];\n radius?: number;\n opacity?: number;\n} & HeatmapProps;\n\n/**\n * Heatmap component of Expo Maps library.\n *\n * Displays multiple {@link PointWithData} objects as a heatmap.\n * Providing data with each point is optional; if no data is provided,\n * heatmap will represent density of points on the map.\n *\n * This component should be ExpoMap component child to work properly.\n *\n * See {@link HeatmapProps} to learn more about props.\n */\nexport class Heatmap extends React.Component {\n render() {\n return null;\n }\n}\n"]} -------------------------------------------------------------------------------- /expo-maps/build/KML.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * KML specific props. 4 | */ 5 | export declare type KMLProps = { 6 | /** 7 | * The value of require('path/to/file.kml') for the .kml asset 8 | */ 9 | filePath: string; 10 | }; 11 | /** 12 | * Internal JSON object for representing marker KMLs in Expo Maps library. 13 | * 14 | * See {@link KMLProps} for more detail. 15 | */ 16 | export declare type KMLObject = { 17 | type: 'kml'; 18 | } & KMLProps; 19 | /** 20 | * KML component of Expo Maps library. 21 | * 22 | * Displays data provided in .kml file. 23 | * This component should be ExpoMap component child to work properly. 24 | * 25 | * See {@link KMLProps} for more details. 26 | */ 27 | export declare class KML extends React.Component { 28 | render(): null; 29 | } 30 | -------------------------------------------------------------------------------- /expo-maps/build/KML.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * KML component of Expo Maps library. 4 | * 5 | * Displays data provided in .kml file. 6 | * This component should be ExpoMap component child to work properly. 7 | * 8 | * See {@link KMLProps} for more details. 9 | */ 10 | export class KML extends React.Component { 11 | render() { 12 | return null; 13 | } 14 | } 15 | //# sourceMappingURL=KML.js.map -------------------------------------------------------------------------------- /expo-maps/build/KML.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"KML.js","sourceRoot":"","sources":["../src/KML.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAqB1B;;;;;;;GAOG;AACH,MAAM,OAAO,GAAI,SAAQ,KAAK,CAAC,SAAmB;IAChD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\n\n/**\n * KML specific props.\n */\nexport type KMLProps = {\n /**\n * The value of require('path/to/file.kml') for the .kml asset\n */\n filePath: string;\n};\n\n/**\n * Internal JSON object for representing marker KMLs in Expo Maps library.\n *\n * See {@link KMLProps} for more detail.\n */\nexport type KMLObject = {\n type: 'kml';\n} & KMLProps;\n\n/**\n * KML component of Expo Maps library.\n *\n * Displays data provided in .kml file.\n * This component should be ExpoMap component child to work properly.\n *\n * See {@link KMLProps} for more details.\n */\nexport class KML extends React.Component {\n render() {\n return null;\n }\n}\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Map.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { ExpoMapState, ExpoMapViewProps } from './Map.types'; 3 | import { CameraMove } from './Common.types'; 4 | export { Marker } from './Marker'; 5 | export { Polygon } from './Polygon'; 6 | export { Polyline } from './Polyline'; 7 | export { Circle } from './Circle'; 8 | export { Cluster } from './Cluster'; 9 | export { KML } from './KML'; 10 | export { GeoJson } from './GeoJson'; 11 | export { Overlay } from './Overlay'; 12 | export { ExpoMapRef } from './Map.types'; 13 | export { POICategoryType } from './Map.types'; 14 | export { Heatmap } from './Heatmap'; 15 | export * from './Events'; 16 | /** 17 | * Main map component of Expo Maps library. 18 | * 19 | * See {@link ExpoMapViewProps} to learn more about props. 20 | */ 21 | export declare class ExpoMap extends React.Component { 22 | state: ExpoMapState; 23 | _ismounted: boolean; 24 | mapView: React.RefObject; 25 | getSearchCompletions(queryFragment: string): void; 26 | moveCamera(cameraMove: CameraMove): Promise; 27 | componentDidMount(): void; 28 | componentWillUnmount(): void; 29 | componentDidUpdate(_: any, prevState: ExpoMapState): void; 30 | private mapChildren; 31 | render(): JSX.Element; 32 | } 33 | -------------------------------------------------------------------------------- /expo-maps/build/Map.types.js: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=Map.types.js.map -------------------------------------------------------------------------------- /expo-maps/build/Marker.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Marker component of Expo Maps library. 4 | * 5 | * Draws customizable marker on ExpoMap. 6 | * This component should be ExpoMap component child to work properly. 7 | * 8 | * See {@link MarkerProps} for more details. 9 | */ 10 | export class Marker extends React.Component { 11 | render() { 12 | return null; 13 | } 14 | } 15 | //# sourceMappingURL=Marker.js.map -------------------------------------------------------------------------------- /expo-maps/build/Marker.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Marker.js","sourceRoot":"","sources":["../src/Marker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA+F1B;;;;;;;GAOG;AACH,MAAM,OAAO,MAAO,SAAQ,KAAK,CAAC,SAAsB;IACtD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\nimport { Point } from './Common.types';\n\n/**\n * Marker specific props.\n */\nexport type BaseMarkerOptions = {\n /**\n * Id of the marker or cluster, should be unique.\n * If no id is specified then marker-related events won't fire for that particular marker or cluster.\n */\n id?: string;\n /**\n * Title of the marker, avaliable in annotation box.\n */\n markerTitle?: string;\n /**\n * Short description of the marker, avaliable in annotation box.\n */\n markerSnippet?: string;\n /**\n * Custom marker icon.\n */\n icon?: string;\n /**\n * Color of a marker when icon is not provided.\n *\n * Accepted formats:\n * * `'#RRGGBB'`\n * * `'#RRGGBBAA'`\n * * `'#RGB'`\n * * `'#RGBA'`\n * * 'red'\n * * 'blue'\n * * 'green'\n * * 'black'\n * * 'white'\n * * 'gray'\n * * 'cyan'\n * * 'magenta'\n * * 'yellow'\n * * 'lightgray'\n * * 'darkgray'\n * * 'grey'\n * * 'aqua'\n * * 'fuchsia'\n * * 'lime'\n * * 'maroon'\n * * 'navy'\n * * 'olive'\n * * 'purple'\n * * 'silver'\n * * 'teal'\n * @default 'red'\n */\n color?: string;\n /**\n * Opacity of a marker's icon, applied both to asset based icon\n * as well as to default marker's icon.\n */\n opacity?: number;\n};\n\nexport type MarkerOptions = {\n /**\n * If 'true' marker is draggable, clustered markers can't be dragged.\n *\n * @default false\n */\n draggable?: boolean;\n /**\n * Translation of latitude coordinate.\n */\n anchorU?: number;\n /**\n * Translation of longitude coordinate.\n */\n anchorV?: number;\n} & BaseMarkerOptions;\n\n/**\n * Props of Marker component of Expo Maps library.\n */\nexport type MarkerProps = MarkerOptions & Point;\n\n/**\n * Internal JSON object for representing markers in Expo Maps library.\n *\n * See {@link MarkerProps} for more details.\n */\nexport type MarkerObject = {\n type: 'marker';\n} & MarkerOptions &\n Point;\n\n/**\n * Marker component of Expo Maps library.\n *\n * Draws customizable marker on ExpoMap.\n * This component should be ExpoMap component child to work properly.\n *\n * See {@link MarkerProps} for more details.\n */\nexport class Marker extends React.Component {\n render() {\n return null;\n }\n}\n"]} -------------------------------------------------------------------------------- /expo-maps/build/NativeExpoMapView.d.ts: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { NativeExpoGoogleMapsViewProps, NativeExpoAppleMapsViewProps } from './Map.types'; 3 | export declare const NativeExpoGoogleMapsView: React.ComponentType; 4 | export declare const NativeExpoAppleMapsView: React.ComponentType; 5 | export declare const NativeExpoAppleMapsModule: import("expo-modules-core").ProxyNativeModule; 6 | export declare const NativeExpoGoogleMapsModule: import("expo-modules-core").ProxyNativeModule; 7 | -------------------------------------------------------------------------------- /expo-maps/build/NativeExpoMapView.js: -------------------------------------------------------------------------------- 1 | import { requireNativeViewManager } from 'expo-modules-core'; 2 | import { NativeModulesProxy } from 'expo-modules-core'; 3 | export const NativeExpoGoogleMapsView = requireNativeViewManager('ExpoGoogleMaps'); 4 | export const NativeExpoAppleMapsView = requireNativeViewManager('ExpoAppleMaps'); 5 | export const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps; 6 | export const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps; 7 | //# sourceMappingURL=NativeExpoMapView.js.map -------------------------------------------------------------------------------- /expo-maps/build/NativeExpoMapView.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"NativeExpoMapView.js","sourceRoot":"","sources":["../src/NativeExpoMapView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAQvD,MAAM,CAAC,MAAM,wBAAwB,GAAG,wBAAwB,CAC9D,gBAAgB,CACqC,CAAC;AAExD,MAAM,CAAC,MAAM,uBAAuB,GAAG,wBAAwB,CAC7D,eAAe,CACqC,CAAC;AAEvD,MAAM,CAAC,MAAM,yBAAyB,GAAG,kBAAkB,CAAC,aAAa,CAAC;AAC1E,MAAM,CAAC,MAAM,0BAA0B,GAAG,kBAAkB,CAAC,cAAc,CAAC","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core';\nimport { NativeModulesProxy } from 'expo-modules-core';\nimport * as React from 'react';\n\nimport {\n NativeExpoGoogleMapsViewProps,\n NativeExpoAppleMapsViewProps,\n} from './Map.types';\n\nexport const NativeExpoGoogleMapsView = requireNativeViewManager(\n 'ExpoGoogleMaps'\n) as React.ComponentType;\n\nexport const NativeExpoAppleMapsView = requireNativeViewManager(\n 'ExpoAppleMaps'\n) as React.ComponentType;\n\nexport const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps;\nexport const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps;\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Overlay.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Point } from './Common.types'; 3 | /** 4 | * Overlay specific props. 5 | */ 6 | export declare type OverlayProps = { 7 | /** 8 | * South west, and north east corners of the image. 9 | */ 10 | bounds: { 11 | /** 12 | * South west corner coordinates. 13 | */ 14 | southWest: Point; 15 | /** 16 | * North east corner coordinates. 17 | */ 18 | northEast: Point; 19 | }; 20 | /** 21 | * Custom overlay graphic 22 | */ 23 | icon: string; 24 | }; 25 | export declare type OverlayObject = { 26 | type: 'overlay'; 27 | } & OverlayProps; 28 | /** 29 | * Ground Overlay component of Expo Maps library. 30 | * 31 | * Draws custom ground overlays on ExpoMap. 32 | * This component should be ExpoMap component child to work properly. 33 | * 34 | * See {@link OverlayProps} for more details. 35 | */ 36 | export declare class Overlay extends React.Component { 37 | render(): null; 38 | } 39 | -------------------------------------------------------------------------------- /expo-maps/build/Overlay.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Ground Overlay component of Expo Maps library. 4 | * 5 | * Draws custom ground overlays on ExpoMap. 6 | * This component should be ExpoMap component child to work properly. 7 | * 8 | * See {@link OverlayProps} for more details. 9 | */ 10 | export class Overlay extends React.Component { 11 | render() { 12 | return null; 13 | } 14 | } 15 | //# sourceMappingURL=Overlay.js.map -------------------------------------------------------------------------------- /expo-maps/build/Overlay.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"Overlay.js","sourceRoot":"","sources":["../src/Overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8B1B;;;;;;;GAOG;AACH,MAAM,OAAO,OAAQ,SAAQ,KAAK,CAAC,SAAuB;IACxD,MAAM;QACJ,OAAO,IAAI,CAAC;IACd,CAAC;CACF","sourcesContent":["import React from 'react';\nimport { Point } from './Common.types';\n\n/**\n * Overlay specific props.\n */\nexport type OverlayProps = {\n /**\n * South west, and north east corners of the image.\n */\n bounds: {\n /**\n * South west corner coordinates.\n */\n southWest: Point;\n /**\n * North east corner coordinates.\n */\n northEast: Point;\n };\n /**\n * Custom overlay graphic\n */\n icon: string;\n};\n\nexport type OverlayObject = {\n type: 'overlay';\n} & OverlayProps;\n\n/**\n * Ground Overlay component of Expo Maps library.\n *\n * Draws custom ground overlays on ExpoMap.\n * This component should be ExpoMap component child to work properly.\n *\n * See {@link OverlayProps} for more details.\n */\nexport class Overlay extends React.Component {\n render() {\n return null;\n }\n}\n"]} -------------------------------------------------------------------------------- /expo-maps/build/Polygon.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Polygon component of Expo Maps library. 4 | * 5 | * Draws customizable polygon on ExpoMap. 6 | * This component should be ExpoMap component child to work properly. 7 | * 8 | * See {@link PolygonProps} to learn more about props. 9 | */ 10 | export class Polygon extends React.Component { 11 | render() { 12 | return null; 13 | } 14 | } 15 | //# sourceMappingURL=Polygon.js.map -------------------------------------------------------------------------------- /expo-maps/build/Polyline.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | /** 3 | * Represents a polyline on the map. 4 | */ 5 | export class Polyline extends React.Component { 6 | render() { 7 | return null; 8 | } 9 | } 10 | //# sourceMappingURL=Polyline.js.map -------------------------------------------------------------------------------- /expo-maps/build/Utils.d.ts: -------------------------------------------------------------------------------- 1 | import { Cluster, ClusterObject } from './Cluster'; 2 | import { Color } from './Common.types'; 3 | import { Marker, MarkerObject } from './Marker'; 4 | import { Polygon, PolygonObject } from './Polygon'; 5 | import { Polyline, PolylineObject } from './Polyline'; 6 | import { Circle, CircleObject } from './Circle'; 7 | import { KML, KMLObject } from './KML'; 8 | import { GeoJson, GeoJsonObject } from './GeoJson'; 9 | import { Overlay, OverlayObject } from './Overlay'; 10 | import { Heatmap, HeatmapObject } from './Heatmap'; 11 | export declare function isSimpleType(child: any): boolean; 12 | export declare function isPolygon(child: any): child is Polygon; 13 | export declare function isPolyline(child: any): child is Polyline; 14 | export declare function isOverlay(child: any): child is Overlay; 15 | export declare function isCircle(child: any): child is Circle; 16 | export declare function isMarker(child: any): child is Marker; 17 | export declare function isCluster(child: any): child is Cluster; 18 | export declare function isKML(child: any): child is KML; 19 | export declare function isGeoJson(child: any): child is GeoJson; 20 | export declare function isHeatmap(child: any): child is Heatmap; 21 | export declare function isHexColor(color: any): color is Color; 22 | export declare function mapColorToHexColor(color: Color, defaultColor?: string): string; 23 | export declare function warnIfChildIsIncompatible(child: any): void; 24 | export declare function buildGeoJsonObject(child: GeoJson): GeoJsonObject; 25 | export declare function buildMarkerObject(child: Marker): Promise; 26 | export declare function buildOverlayObject(child: Overlay): Promise; 27 | export declare function buildPolygonObject(child: Polygon): PolygonObject; 28 | export declare function buildPolylineObject(child: Polyline): PolylineObject; 29 | export declare function buildCircleObject(child: Circle): CircleObject; 30 | export declare function buildKMLObject(child: KML): Promise; 31 | export declare function buildClusterObject(child: Cluster): Promise; 32 | export declare function buildHeatmapObject(child: Heatmap): HeatmapObject; 33 | -------------------------------------------------------------------------------- /expo-maps/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-maps", 3 | "platforms": ["ios", "android"], 4 | "ios": { 5 | "modulesClassNames": ["ExpoGoogleMapsModule", "ExpoAppleMapsModule"] 6 | }, 7 | "android": { 8 | "modulesClassNames": ["expo.modules.maps.ExpoGoogleMapsModule"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, '..', 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = 'ExpoMaps' 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.description = package['description'] 10 | s.license = package['license'] 11 | s.author = package['author'] 12 | s.homepage = package['homepage'] 13 | s.platform = :ios, '12.0' 14 | s.source = { git: 'https://github.com/expo/expo.git' } 15 | s.static_framework = true 16 | s.source_files = 'ExpoMaps/**/*.{h,m,swift}' 17 | s.preserve_paths = 'ExpoMaps/**/*.{h,m,swift}' 18 | s.requires_arc = true 19 | 20 | s.dependency 'ExpoModulesCore' 21 | s.dependency 'GoogleMaps', '6.0.0' 22 | s.dependency 'Google-Maps-iOS-Utils', '~> 4.1.0' 23 | s.dependency 'GooglePlaces', '6.2.1' 24 | end 25 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsCircles.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsCircles: Circles { 4 | private let mapView: MKMapView 5 | private var circles: [MKCircle] = [] 6 | 7 | init(mapView: MKMapView) { 8 | self.mapView = mapView 9 | } 10 | 11 | func setCircles(circleObjects: [CircleObject]) { 12 | detachAndDeleteCircles() 13 | for circleObject in circleObjects { 14 | let circle = ExpoMKCircle( 15 | center: CLLocationCoordinate2D( 16 | latitude: circleObject.center.latitude, longitude: circleObject.center.longitude), 17 | radius: circleObject.radius 18 | ) 19 | if circleObject.fillColor != nil {circle.fillColor = circleObject.fillColor!} 20 | if circleObject.strokeColor != nil {circle.strokeColor = circleObject.strokeColor!} 21 | if circleObject.strokeWidth != nil {circle.strokeWidth = circleObject.strokeWidth!} 22 | mapView.addOverlay(circle) 23 | circles.append(circle) 24 | } 25 | } 26 | 27 | internal func detachAndDeleteCircles() { 28 | for circle in circles { 29 | self.mapView.removeOverlay(circle) 30 | } 31 | circles = [] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsClusters.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsClusters : Clusters { 4 | 5 | private let mapView: MKMapView 6 | private let markersManager: AppleMapsMarkersManager 7 | 8 | /* 9 | Two custer classes, which are used to display clusters on a map, are here registered in order to reuse their instances 10 | when user scrolls a map. 11 | */ 12 | init(mapView: MKMapView, markersManager: AppleMapsMarkersManager) { 13 | self.mapView = mapView 14 | self.markersManager = markersManager 15 | mapView.register(ExpoMKClusterImageAnnotationView.self, forAnnotationViewWithReuseIdentifier: "image_cluster") 16 | mapView.register(ExpoMKClusterColorAnnotationView.self, forAnnotationViewWithReuseIdentifier: "color_cluster") 17 | } 18 | 19 | func setClusters(clusterObjects: [ClusterObject]) { 20 | mapView.removeAnnotations(markersManager.getClustersItems()) 21 | 22 | for clusterObject in clusterObjects { 23 | for markerObject in clusterObject.markers { 24 | let marker = createAppleMarker(markerObject: markerObject, includeDragging: true) 25 | 26 | if (clusterObject.markers.count >= clusterObject.minimumClusterSize) { 27 | marker.clusterName = clusterObject.name 28 | } 29 | 30 | mapView.addAnnotation(marker) 31 | markersManager.appendClustersItem(clusterItem: marker) 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsControls.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsControls: Controls { 4 | private let mapView: MKMapView 5 | 6 | init(mapView: MKMapView) { 7 | self.mapView = mapView 8 | } 9 | 10 | func setShowCompass(enable: Bool) { 11 | mapView.showsCompass = enable 12 | } 13 | 14 | func setShowMyLocationButton(enable: Bool) { 15 | if (enable == true) { 16 | enableMyLocationButton() 17 | } 18 | } 19 | 20 | func setShowLevelPicker(enable: Bool) { 21 | //TODO: enable floor picker 22 | } 23 | 24 | private func enableMyLocationButton() { 25 | mapView.showsUserLocation = true 26 | let myLocationButton = MKUserTrackingButton(mapView: mapView) 27 | myLocationButton.layer.backgroundColor = UIColor(white: 1, alpha: 0.5).cgColor 28 | myLocationButton.layer.borderColor = UIColor.white.cgColor 29 | myLocationButton.layer.borderWidth = 1 30 | myLocationButton.layer.cornerRadius = 5 31 | myLocationButton.translatesAutoresizingMaskIntoConstraints = false 32 | mapView.addSubview(myLocationButton) 33 | 34 | NSLayoutConstraint.activate([ 35 | myLocationButton.topAnchor.constraint(equalTo: mapView.topAnchor, 36 | constant: 100), 37 | myLocationButton.trailingAnchor.constraint(equalTo: 38 | mapView.trailingAnchor, constant: -10) 39 | ]) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsGestures.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | final class AppleMapsGestures: Gestures { 4 | 5 | private let mapView: MKMapView 6 | 7 | init(mapView: MKMapView) { 8 | self.mapView = mapView 9 | } 10 | 11 | init?(coder: NSCoder) { 12 | fatalError("init(coder:) has not been implemented") 13 | } 14 | 15 | func setEnabledRotateGesture(enabled: Bool) { 16 | mapView.isRotateEnabled = enabled 17 | } 18 | 19 | func setEnabledScrollGesture(enabled: Bool) { 20 | mapView.isScrollEnabled = enabled 21 | } 22 | 23 | func setEnabledTiltGesture(enabled: Bool) { 24 | mapView.isPitchEnabled = enabled 25 | } 26 | 27 | func setEnabledZoomGesture(enabled: Bool) { 28 | mapView.isZoomEnabled = enabled 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsMarkers.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsMarkers: NSObject, Markers { 4 | 5 | private let mapView: MKMapView 6 | private let markersManager: AppleMapsMarkersManager 7 | private var kmlMarkers: [ExpoMKAnnotation] = [] 8 | private var poiMarkers: [ExpoMKAnnotation] = [] 9 | 10 | /* 11 | Two marker classes, which are used to display markers on a map, are here registered in order to reuse their instances 12 | when user scrolls a map. 13 | */ 14 | init(mapView: MKMapView, markersManager: AppleMapsMarkersManager) { 15 | self.mapView = mapView 16 | self.markersManager = markersManager 17 | mapView.register(ExpoMKImageAnnotationView.self, forAnnotationViewWithReuseIdentifier: "image_marker") 18 | mapView.register(ExpoMKColorAnnotationView.self, forAnnotationViewWithReuseIdentifier: "color_marker") 19 | } 20 | 21 | func setMarkers(markerObjects: [MarkerObject]) { 22 | detachAndDeleteMarkers() 23 | 24 | for markerObject in markerObjects { 25 | let marker = createAppleMarker(markerObject: markerObject, includeDragging: true) 26 | 27 | mapView.addAnnotation(marker) 28 | markersManager.appendMarker(marker: marker) 29 | } 30 | } 31 | 32 | func setKMLMarkers(markerObjects: [MarkerObject]) { 33 | detachAndDeleteKMLMarkers() 34 | 35 | for markerObject in markerObjects { 36 | let marker = createAppleMarker(markerObject: markerObject, includeDragging: false) 37 | 38 | mapView.addAnnotation(marker) 39 | kmlMarkers.append(marker) 40 | } 41 | } 42 | 43 | func setPOIMarkers(markerObjects: [MarkerObject]) { 44 | detachAndDeletePOIMarkers() 45 | 46 | for markerObject in markerObjects { 47 | let marker = createAppleMarker(markerObject: markerObject, includeDragging: false) 48 | 49 | mapView.addAnnotation(marker) 50 | poiMarkers.append(marker) 51 | } 52 | } 53 | 54 | internal func detachAndDeleteMarkers() { 55 | mapView.removeAnnotations(markersManager.getMarkers()) 56 | markersManager.clearMarkers() 57 | } 58 | 59 | private func detachAndDeleteKMLMarkers() { 60 | mapView.removeAnnotations(kmlMarkers) 61 | kmlMarkers = [] 62 | } 63 | 64 | func detachAndDeletePOIMarkers() { 65 | mapView.removeAnnotations(poiMarkers) 66 | poiMarkers = [] 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsMarkersManager.swift: -------------------------------------------------------------------------------- 1 | class AppleMapsMarkersManager { 2 | 3 | private var markersMap: [ExpoMKAnnotation : String?] = [:] 4 | private var clustersItemsMap: [ExpoMKAnnotation : String?] = [:] 5 | 6 | func appendMarker(marker: ExpoMKAnnotation) { 7 | markersMap[marker] = marker.id 8 | } 9 | 10 | func clearMarkers() { 11 | markersMap.removeAll() 12 | } 13 | 14 | func getMarkerId(marker: ExpoMKAnnotation) -> String? { 15 | return markersMap[marker] ?? nil 16 | } 17 | 18 | func getMarkers() -> [ExpoMKAnnotation] { 19 | return Array(markersMap.keys) 20 | } 21 | 22 | func appendClustersItem(clusterItem: ExpoMKAnnotation) { 23 | clustersItemsMap[clusterItem] = clusterItem.id 24 | } 25 | 26 | func clearClustersItems() { 27 | clustersItemsMap.removeAll() 28 | } 29 | 30 | func getClusterItemId(clusterItem: ExpoMKAnnotation) -> String? { 31 | return clustersItemsMap[clusterItem] ?? nil 32 | } 33 | 34 | func getClustersItems() -> [ExpoMKAnnotation] { 35 | return Array(clustersItemsMap.keys) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsPolygons.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsPolygons: Polygons { 4 | 5 | private let mapView: MKMapView 6 | private var polygons: [MKPolygon] = [] 7 | private var kmlPolygons: [MKPolygon] = [] 8 | 9 | init(mapView: MKMapView) { 10 | self.mapView = mapView 11 | } 12 | 13 | func setPolygons(polygonObjects: [PolygonObject]) { 14 | detachAndDeletePolygons() 15 | for polygonObject in polygonObjects { 16 | let polygon = createPolygon(polygonObject: polygonObject) 17 | mapView.addOverlay(polygon) 18 | polygons.append(polygon) 19 | } 20 | } 21 | 22 | func setKMLPolygons(polygonObjects: [PolygonObject]) { 23 | detachAndDeleteKMLPolygons() 24 | for polygonObject in polygonObjects { 25 | let polygon = createPolygon(polygonObject: polygonObject) 26 | mapView.addOverlay(polygon) 27 | kmlPolygons.append(polygon) 28 | } 29 | } 30 | 31 | internal func detachAndDeletePolygons() { 32 | mapView.removeOverlays(polygons) 33 | polygons = [] 34 | } 35 | 36 | private func detachAndDeleteKMLPolygons() { 37 | mapView.removeOverlays(kmlPolygons) 38 | kmlPolygons = [] 39 | } 40 | 41 | private func createPolygon(polygonObject: PolygonObject) -> MKPolygon { 42 | var overlayPoints: [CLLocationCoordinate2D] = [] 43 | for point in polygonObject.points { 44 | overlayPoints.append( 45 | CLLocationCoordinate2D(latitude: point.latitude, longitude: point.longitude)) 46 | } 47 | let polygon = ExpoMKPolygon(coordinates: &overlayPoints, count: overlayPoints.count) 48 | if polygonObject.fillColor != nil { polygon.fillColor = polygonObject.fillColor! } 49 | if polygonObject.strokeColor != nil { polygon.strokeColor = polygonObject.strokeColor! } 50 | if polygonObject.strokeWidth != nil { polygon.strokeWidth = polygonObject.strokeWidth! } 51 | if polygonObject.strokePattern != nil { 52 | polygon.strokePattern = strokePatternToLineDashPatternPolygon( 53 | pattern: polygonObject.strokePattern, width: polygon.strokeWidth) 54 | if polygonObject.strokeWidth == nil {polygon.strokeWidth = 1.0} 55 | } 56 | polygon.jointType = jointToCGLineJoin(polygonObject.jointType) 57 | 58 | return polygon 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/AppleMapsPolylines.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class AppleMapsPolylines: Polylines { 4 | 5 | private let mapView: MKMapView 6 | private var polylines: [MKPolyline] = [] 7 | private var kmlPolylines: [MKPolyline] = [] 8 | 9 | init(mapView: MKMapView) { 10 | self.mapView = mapView 11 | } 12 | 13 | func setPolylines(polylineObjects: [PolylineObject]) { 14 | detachAndDeletePolylines() 15 | for polylineObject in polylineObjects { 16 | let polyline = createPolyline(polylineObject: polylineObject) 17 | mapView.addOverlay(polyline) 18 | polylines.append(polyline) 19 | } 20 | } 21 | 22 | func setKMLPolylines(polylineObjects: [PolylineObject]) { 23 | detachAndDeleteKMLPolylines() 24 | for polylineObject in polylineObjects { 25 | let polyline = createPolyline(polylineObject: polylineObject) 26 | mapView.addOverlay(polyline) 27 | kmlPolylines.append(polyline) 28 | } 29 | } 30 | 31 | internal func detachAndDeletePolylines() { 32 | mapView.removeOverlays(polylines) 33 | polylines = [] 34 | } 35 | 36 | private func detachAndDeleteKMLPolylines() { 37 | mapView.removeOverlays(kmlPolylines) 38 | kmlPolylines = [] 39 | } 40 | 41 | private func createPolyline(polylineObject: PolylineObject) -> MKPolyline { 42 | var overlayPoints: [CLLocationCoordinate2D] = [] 43 | for point in polylineObject.points { 44 | overlayPoints.append( 45 | CLLocationCoordinate2D(latitude: point.latitude, longitude: point.longitude)) 46 | } 47 | let polyline = ExpoMKPolyline(coordinates: &overlayPoints, count: overlayPoints.count) 48 | if polylineObject.color != nil { polyline.color = polylineObject.color! } 49 | if polylineObject.width != nil { polyline.width = polylineObject.width! } 50 | let dotLength = polylineObject.capType == .butt ? polyline.width : 0 51 | polyline.pattern = strokePatternToLineDashPatternPolyline( 52 | pattern: polylineObject.pattern, dotLength: dotLength) 53 | polyline.jointType = jointToCGLineJoin(polylineObject.jointType) 54 | polyline.capType = capToCGLineCap(polylineObject.capType) 55 | 56 | return polyline 57 | } 58 | 59 | private func capToCGLineCap(_ capType: Cap?) -> CGLineCap { 60 | switch capType { 61 | case .round: 62 | return .round 63 | case .butt: 64 | return .butt 65 | case .square: 66 | return .square 67 | default: 68 | return .round 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/ArrayExtension.swift: -------------------------------------------------------------------------------- 1 | extension Array { 2 | func penultimate() -> Element? { 3 | if count < 2 { 4 | return nil 5 | } 6 | let index = count - 2 7 | return self[index] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKAnnotation.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | open class ExpoMKAnnotation : NSObject, MKAnnotation { 4 | 5 | // This property must be key-value observable, which the `@objc dynamic` attributes provide. 6 | @objc public dynamic var coordinate: CLLocationCoordinate2D 7 | 8 | public var title: String? = nil 9 | 10 | public var subtitle: String? = nil 11 | 12 | var id: String? = nil 13 | 14 | var isDraggable: Bool = false 15 | 16 | var centerOffsetX: Double = 0 17 | 18 | var centerOffsetY: Double = 0 19 | 20 | var alpha: Double = 1 21 | 22 | var clusterName: String? = nil 23 | 24 | init(coordinate: CLLocationCoordinate2D) { 25 | self.coordinate = coordinate 26 | super.init() 27 | } 28 | } 29 | 30 | class ExpoMKImageAnnotation : ExpoMKAnnotation { 31 | 32 | var icon: String = "" 33 | } 34 | 35 | class ExpoMKColorAnnotation : ExpoMKAnnotation { 36 | 37 | var color: Double = 0 38 | } 39 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKAnnotationView.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class ExpoMKColorAnnotationView : MKMarkerAnnotationView, UIGestureRecognizerDelegate { 4 | 5 | override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 6 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 7 | 8 | // Set in order to display annotation even if user zooms out 9 | displayPriority = .required 10 | } 11 | 12 | init(annotation: ExpoMKColorAnnotation, reuseIdentifier: String?) { 13 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 14 | 15 | // Set in order to display annotation even if user zooms out 16 | displayPriority = .required 17 | isDraggable = annotation.isDraggable 18 | centerOffset = CGPoint(x: annotation.centerOffsetX, y: annotation.centerOffsetY) 19 | alpha = annotation.alpha 20 | markerTintColor = UIColor(hue: annotation.color, saturation: 1, brightness: 1, alpha: 1) 21 | clusteringIdentifier = annotation.clusterName 22 | } 23 | 24 | required init?(coder aDecoder: NSCoder) { 25 | fatalError("init(coder:) has not been implemented") 26 | } 27 | } 28 | 29 | class ExpoMKImageAnnotationView : MKAnnotationView { 30 | 31 | override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 32 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 33 | 34 | // Set in order to display annotation even if user zooms out 35 | displayPriority = .required 36 | // For displaying data in a infoWindow when annotation is clicked 37 | canShowCallout = true 38 | isEnabled = true 39 | } 40 | 41 | init(annotation: ExpoMKImageAnnotation, reuseIdentifier: String?) { 42 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 43 | 44 | // Set in order to display annotation even if user zooms out 45 | displayPriority = .required 46 | // For displaying data in a infoWindow when annotation is clicked 47 | canShowCallout = true 48 | isEnabled = true 49 | isDraggable = annotation.isDraggable 50 | centerOffset = CGPoint(x: annotation.centerOffsetX, y: annotation.centerOffsetY) 51 | alpha = annotation.alpha 52 | image = UIImage(contentsOfFile: annotation.icon) 53 | clusteringIdentifier = annotation.clusterName 54 | } 55 | 56 | required init?(coder aDecoder: NSCoder) { 57 | fatalError("init(coder:) has not been implemented") 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKCircle.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class ExpoMKCircle: MKCircle { 4 | var fillColor: UIColor = UIColor.clear 5 | var strokeColor: UIColor = UIColor.black 6 | var strokeWidth: Float = 1.0 7 | } 8 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKClusterAnnotation.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | open class ExpoMKClusterAnnotation : MKClusterAnnotation { 4 | 5 | var id: String? = nil 6 | 7 | var minimumClusterSize: Int = 4 8 | 9 | var alpha: Double = 1 10 | } 11 | 12 | class ExpoMKClusterColorAnnotation : ExpoMKClusterAnnotation { 13 | 14 | var color: Double = 0 15 | } 16 | 17 | class ExpoMKClusterImageAnnotation : ExpoMKClusterAnnotation { 18 | 19 | var icon: String = "" 20 | } 21 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKClusterAnnotationView.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class ExpoMKClusterColorAnnotationView : MKMarkerAnnotationView { 4 | 5 | override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 6 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 7 | 8 | // Set in order to display annotation even if user zooms out 9 | displayPriority = .required 10 | } 11 | 12 | init(annotation: ExpoMKClusterColorAnnotation, reuseIdentifier: String?) { 13 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 14 | 15 | // Set in order to display annotation even if user zooms out 16 | displayPriority = .required 17 | markerTintColor = UIColor(hue: annotation.color, saturation: 1, brightness: 1, alpha: 1) 18 | alpha = annotation.alpha 19 | } 20 | 21 | required init?(coder aDecoder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | } 25 | 26 | class ExpoMKClusterImageAnnotationView : MKAnnotationView { 27 | 28 | override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 29 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 30 | 31 | // Set in order to display annotation even if user zooms out 32 | displayPriority = .required 33 | // For displaying data in a infoWindow when annotation is clicked 34 | canShowCallout = true 35 | isEnabled = true 36 | } 37 | 38 | init(annotation: ExpoMKClusterImageAnnotation, reuseIdentifier: String?) { 39 | super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 40 | 41 | // Set in order to display annotation even if user zooms out 42 | displayPriority = .required 43 | // For displaying data in a infoWindow when annotation is clicked 44 | canShowCallout = true 45 | isEnabled = true 46 | image = UIImage(contentsOfFile: annotation.icon) 47 | alpha = annotation.alpha 48 | } 49 | 50 | required init?(coder aDecoder: NSCoder) { 51 | fatalError("init(coder:) has not been implemented") 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKPolygon.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class ExpoMKPolygon: MKPolygon { 4 | var fillColor: UIColor = UIColor.blue.withAlphaComponent(0.25) 5 | var strokeColor: UIColor = UIColor.blue 6 | var strokeWidth: Float = 0.0001 7 | var strokePattern: [NSNumber]? = nil 8 | var jointType: CGLineJoin = CGLineJoin.miter 9 | } 10 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/CustomTypes/ExpoMKPolyline.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | 3 | class ExpoMKPolyline: MKPolyline { 4 | var color: UIColor = UIColor.blue 5 | var width: Float = 1.0 6 | var pattern: [NSNumber]? = nil 7 | var jointType: CGLineJoin = CGLineJoin.miter 8 | var capType: CGLineCap = CGLineCap.round 9 | } 10 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/POIUtils/AppleMapsPOISearchCompleter.swift: -------------------------------------------------------------------------------- 1 | import MapKit 2 | import ExpoModulesCore 3 | 4 | class AppleMapsPOISearchCompleter: NSObject, SearchCompleter { 5 | 6 | private var searchCompleter = MKLocalSearchCompleter() 7 | private var searchCompleterResults: [MKLocalSearchCompletion]? 8 | private var searchCompletionsPromise: Promise? 9 | 10 | init(delegate: MKLocalSearchCompleterDelegate?) { 11 | super.init() 12 | let delegate = delegate ?? self 13 | searchCompleter.delegate = delegate 14 | } 15 | 16 | func autoComplete(searchQueryFragment: String) { 17 | searchCompleter.queryFragment = searchQueryFragment 18 | } 19 | 20 | func autoComplete(searchQueryFragment: String, promise: Promise) { 21 | searchCompletionsPromise = promise 22 | searchCompleter.queryFragment = searchQueryFragment 23 | } 24 | 25 | func getSearchCompletions() -> [String] { 26 | if let results = searchCompleterResults { 27 | return mapSearchCompletions(completions: results) 28 | } 29 | return [] 30 | } 31 | 32 | func setSearchCompleterRegion(region: MKCoordinateRegion) { 33 | searchCompleter.region = region 34 | } 35 | 36 | @available(iOS 13.0, *) 37 | func setSearchCompleterFilters(filter: MKPointOfInterestFilter?) { 38 | searchCompleter.resultTypes = .pointOfInterest 39 | guard let filter = filter else { 40 | searchCompleter.pointOfInterestFilter = nil 41 | return 42 | } 43 | searchCompleter.pointOfInterestFilter = filter 44 | } 45 | 46 | private func resolveSearchCompletionsPromise() { 47 | guard searchCompletionsPromise != nil else { 48 | return 49 | } 50 | 51 | if let results = searchCompleterResults { 52 | let searchCompletions = mapSearchCompletions(completions: results) 53 | searchCompletionsPromise?.resolve(searchCompletions) 54 | } else { 55 | let errorMessage = "Error while fetching search completions." 56 | searchCompletionsPromise?.reject("", errorMessage) 57 | } 58 | searchCompletionsPromise = nil 59 | } 60 | 61 | func mapSearchCompletions(completions: [MKLocalSearchCompletion]) -> [String] { 62 | var stringCompletions: [String] = [] 63 | for completion in completions { 64 | stringCompletions.append(completion.title + ";" + completion.subtitle) 65 | } 66 | return stringCompletions 67 | } 68 | 69 | } 70 | 71 | extension AppleMapsPOISearchCompleter: MKLocalSearchCompleterDelegate { 72 | 73 | func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) { 74 | searchCompleterResults = completer.results 75 | resolveSearchCompletionsPromise() 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/AppleMaps/UIColorExtension.swift: -------------------------------------------------------------------------------- 1 | extension UIColor { 2 | public convenience init(hexString: String) { 3 | let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) 4 | var int = UInt64() 5 | Scanner(string: hex).scanHexInt64(&int) 6 | let a, r, g, b: UInt64 7 | switch hex.count { 8 | case 3: // RGB (12-bit) 9 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) 10 | case 6: // RGB (24-bit) 11 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) 12 | case 8: // ARGB (32-bit) 13 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) 14 | default: 15 | (a, r, g, b) = (255, 0, 0, 0) 16 | } 17 | self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/CustomTypes/ExpoGoogleMapsPolyline.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class ExpoGoogleMapsPolyline: GMSPolyline { 4 | var pattern: [PatternItem]? = nil 5 | } 6 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsCircles.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsCircles: Circles { 4 | private let mapView: GMSMapView 5 | private var circles: [GMSCircle] = [] 6 | 7 | init(mapView: GMSMapView) { 8 | self.mapView = mapView 9 | } 10 | 11 | func setCircles(circleObjects: [CircleObject]) { 12 | detachAndDeleteCircles() 13 | for circleObject in circleObjects { 14 | let circle = GMSCircle( 15 | position: CLLocationCoordinate2D( 16 | latitude: circleObject.center.latitude, longitude: circleObject.center.longitude), 17 | radius: circleObject.radius) 18 | circle.fillColor = circleObject.fillColor ?? circle.fillColor 19 | circle.strokeWidth = CGFloat(circleObject.strokeWidth ?? Float(circle.strokeWidth)) 20 | circle.strokeColor = circleObject.strokeColor ?? circle.strokeColor 21 | circle.map = mapView 22 | circles.append(circle) 23 | } 24 | } 25 | 26 | internal func detachAndDeleteCircles() { 27 | for circle in circles { 28 | circle.map = nil 29 | } 30 | circles = [] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsClusterManagerDelegate.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | import GoogleMapsUtils 3 | import ExpoModulesCore 4 | 5 | class GoogleMapsClusterManagerDelegate: NSObject, GMUClusterManagerDelegate { 6 | private var onClusterPress: Callback<[String: Any?]>? 7 | private let googleMapsMarkersManager: GoogleMapsMarkersManager 8 | 9 | init(googleMapsMarkersManager: GoogleMapsMarkersManager) { 10 | self.googleMapsMarkersManager = googleMapsMarkersManager 11 | super.init() 12 | } 13 | 14 | func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool { 15 | if let id = googleMapsMarkersManager.getClusterId(cluster: clusterManager) { 16 | onClusterPress?(ClusterRecord(id: id, cluster: cluster).toDictionary()) 17 | } 18 | return false 19 | } 20 | 21 | func setOnClusterPress(onClusterPress: Callback<[String: Any?]>){ 22 | self.onClusterPress = onClusterPress 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsControls.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsControls: Controls { 4 | 5 | private let mapView: GMSMapView 6 | 7 | init(mapView: GMSMapView) { 8 | self.mapView = mapView 9 | } 10 | 11 | func setShowCompass(enable: Bool) { 12 | mapView.settings.compassButton = enable 13 | } 14 | 15 | func setShowMyLocationButton(enable: Bool) { 16 | if (enable == true) { 17 | mapView.isMyLocationEnabled = true 18 | } 19 | mapView.settings.myLocationButton = enable 20 | } 21 | 22 | func setShowLevelPicker(enable: Bool) { 23 | //appears whenever an indoor map is featured prominently 24 | mapView.settings.indoorPicker = enable 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsGeoJSONs.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | import GoogleMapsUtils 3 | 4 | class GoogleMapsGeoJsons: GeoJsons { 5 | 6 | private let mapView: GMSMapView 7 | private var renderers: [GMUGeometryRenderer] = [] 8 | 9 | init(mapView: GMSMapView) { 10 | self.mapView = mapView 11 | } 12 | 13 | func setGeoJsons(geoJsonObjects: [GeoJsonObject]) { 14 | deleteGeoJsons() 15 | for geoJsonObject in geoJsonObjects { 16 | let geoJsonParser = GMUGeoJSONParser(data: geoJsonObject.geoJsonString.data(using: .utf8)!) 17 | geoJsonParser.parse() 18 | 19 | for feature in geoJsonParser.features { 20 | if (feature.geometry.type == "Polygon") { 21 | feature.style = GMUStyle( 22 | styleID: "defaultExpoMapsStyle", 23 | stroke: geoJsonObject.defaultStyle?.polygon?.strokeColor, 24 | fill: geoJsonObject.defaultStyle?.polygon?.fillColor, 25 | width: geoJsonObject.defaultStyle?.polygon?.strokeWidth != nil ? CGFloat(geoJsonObject.defaultStyle!.polygon!.strokeWidth!) : CGFloat(), 26 | scale: CGFloat(), 27 | heading: CGFloat(), 28 | anchor: CGPoint(), 29 | iconUrl: nil, 30 | title: nil, 31 | hasFill: geoJsonObject.defaultStyle?.polygon?.fillColor != nil, 32 | hasStroke: geoJsonObject.defaultStyle?.polygon?.strokeColor != nil 33 | ) 34 | } else if (feature.geometry.type == "LineString") { 35 | feature.style = GMUStyle( 36 | styleID: "defaultExpoMapsStyle", 37 | stroke: geoJsonObject.defaultStyle?.polyline?.color, 38 | fill: nil, 39 | width: geoJsonObject.defaultStyle?.polyline?.width != nil ? CGFloat(geoJsonObject.defaultStyle!.polyline!.width!) : CGFloat(), 40 | scale: CGFloat(), 41 | heading: CGFloat(), 42 | anchor: CGPoint(), 43 | iconUrl: nil, 44 | title: nil, 45 | hasFill: false, 46 | hasStroke: geoJsonObject.defaultStyle?.polyline?.color != nil 47 | ) 48 | } 49 | } 50 | 51 | let renderer = GMUGeometryRenderer( 52 | map: mapView, 53 | geometries: geoJsonParser.features 54 | ) 55 | 56 | renderer.render() 57 | renderers.append(renderer) 58 | } 59 | } 60 | 61 | private func deleteGeoJsons() { 62 | for renderer in renderers { 63 | renderer.clear() 64 | } 65 | renderers = [] 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsGestures.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsGestures : Gestures { 4 | 5 | private let mapView: GMSMapView 6 | 7 | init(mapView: GMSMapView) { 8 | self.mapView = mapView 9 | } 10 | 11 | func setEnabledRotateGesture(enabled: Bool) { 12 | mapView.settings.rotateGestures = enabled 13 | } 14 | 15 | func setEnabledScrollGesture(enabled: Bool) { 16 | mapView.settings.scrollGestures = enabled 17 | } 18 | 19 | func setEnabledTiltGesture(enabled: Bool) { 20 | mapView.settings.tiltGestures = enabled 21 | } 22 | 23 | func setEnabledZoomGesture(enabled: Bool) { 24 | mapView.settings.zoomGestures = enabled 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsHeatmaps.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | import GoogleMapsUtils 3 | import CoreLocation 4 | 5 | class GoogleMapsHeatmaps: Heatmaps { 6 | 7 | private let mapView: GMSMapView 8 | private var heatmaps: [GMUHeatmapTileLayer] = [] 9 | 10 | init(mapView: GMSMapView) { 11 | self.mapView = mapView 12 | } 13 | 14 | func setHeatmaps(heatmapObjects: [HeatmapObject]) { 15 | detachAndDeleteHeatmaps() 16 | for heatmapObject in heatmapObjects { 17 | let heatmap: GMUHeatmapTileLayer = GMUHeatmapTileLayer() 18 | if let gradient = heatmapObject.gradient { 19 | heatmap.gradient = GMUGradient( 20 | colors: gradient.colors, 21 | startPoints:gradient.locations.map({NSNumber(value: $0)}), 22 | colorMapSize: 256) 23 | } 24 | if let radius = heatmapObject.radius {heatmap.radius = radius} 25 | if let opacity = heatmapObject.opacity {heatmap.opacity = opacity} 26 | heatmap.weightedData = heatmapObject.points.map({ 27 | GMUWeightedLatLng( 28 | coordinate: CLLocationCoordinate2D(latitude: $0.latitude, longitude: $0.longitude), 29 | intensity: $0.data ?? 1.0) 30 | }) 31 | 32 | heatmap.map = mapView 33 | heatmaps.append(heatmap) 34 | } 35 | } 36 | 37 | internal func detachAndDeleteHeatmaps() { 38 | for heatmap in heatmaps { 39 | heatmap.map = nil 40 | } 41 | heatmaps = [] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsKMLs.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | import GoogleMapsUtils 3 | 4 | class GoogleMapsKMLs: KMLs { 5 | 6 | private let mapView: GMSMapView 7 | private var renderers: [GMUGeometryRenderer] = [] 8 | 9 | init(mapView: GMSMapView) { 10 | self.mapView = mapView 11 | } 12 | 13 | func setKMLs(kmlObjects: [KMLObject]) { 14 | deleteKMLs() 15 | 16 | for kmlObject in kmlObjects { 17 | let url = URL(fileURLWithPath: kmlObject.filePath) 18 | let kmlParser = GMUKMLParser(url: url.standardized) 19 | kmlParser.parse() 20 | 21 | let renderer = GMUGeometryRenderer( 22 | map: mapView, 23 | geometries: kmlParser.placemarks, 24 | styles: kmlParser.styles 25 | ) 26 | 27 | renderer.render() 28 | renderers.append(renderer) 29 | } 30 | } 31 | 32 | private func deleteKMLs() { 33 | for renderer in renderers { 34 | renderer.clear() 35 | } 36 | renderers = [] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsMarkers.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsMarkers: Markers { 4 | 5 | private let mapView: GMSMapView 6 | private let googleMapsMarkersManager: GoogleMapsMarkersManager 7 | private var poiMarkers: [GMSMarker] = [] 8 | 9 | init(mapView: GMSMapView, googleMapsMarkersManager: GoogleMapsMarkersManager) { 10 | self.mapView = mapView 11 | self.googleMapsMarkersManager = googleMapsMarkersManager 12 | } 13 | 14 | func setMarkers(markerObjects: [MarkerObject]) { 15 | detachAndDeleteMarkers() 16 | for markerObject in markerObjects { 17 | let marker: GMSMarker = createGoogleMarker(markerObject: markerObject, includeDragging: true) 18 | 19 | marker.map = mapView 20 | googleMapsMarkersManager.appendMarker(marker: marker, id: markerObject.id) 21 | } 22 | } 23 | 24 | func setPOIMarkers(markerObjects: [MarkerObject]) { 25 | detachAndDeletePOIMarkers() 26 | for markerObject in markerObjects { 27 | let marker: GMSMarker = createGoogleMarker(markerObject: markerObject, includeDragging: false) 28 | 29 | marker.map = mapView 30 | poiMarkers.append(marker) 31 | } 32 | } 33 | 34 | internal func detachAndDeleteMarkers() { 35 | googleMapsMarkersManager.clearMarkers() 36 | } 37 | 38 | func detachAndDeletePOIMarkers() { 39 | for marker in poiMarkers { 40 | marker.map = nil 41 | } 42 | poiMarkers = [] 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsMarkersManager.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | import GoogleMapsUtils 3 | 4 | class GoogleMapsMarkersManager { 5 | 6 | private var markersMap: [GMSMarker : String?] = [:] 7 | private var clustersMap: [GMUClusterManager : String?] = [:] 8 | private var clustersItemsMap: [GMSMarker : String?] = [:] 9 | 10 | func clearMarkers() { 11 | for marker in markersMap.keys { 12 | marker.map = nil 13 | } 14 | markersMap.removeAll() 15 | } 16 | 17 | func appendMarker(marker: GMSMarker, id: String?) { 18 | markersMap[marker] = id 19 | } 20 | 21 | func getMarkerId(marker: GMSMarker) -> String? { 22 | return markersMap[marker] ?? nil 23 | } 24 | 25 | func clearClusters() { 26 | for clusterItem in clustersItemsMap.keys { 27 | clusterItem.map = nil 28 | } 29 | clustersItemsMap.removeAll() 30 | 31 | for cluster in clustersMap.keys { 32 | cluster.clearItems() 33 | cluster.cluster() 34 | } 35 | clustersMap.removeAll() 36 | } 37 | 38 | func appendCluster(cluster: GMUClusterManager, id: String?) { 39 | clustersMap[cluster] = id 40 | } 41 | 42 | func appendClusterItem(clusterItem: GMSMarker, id: String?) { 43 | clustersItemsMap[clusterItem] = id 44 | } 45 | 46 | func getClusterId(cluster: GMUClusterManager) -> String? { 47 | return clustersMap[cluster] ?? nil 48 | } 49 | 50 | func getClusterItemId(clusterItem: GMSMarker) -> String? { 51 | return clustersItemsMap[clusterItem] ?? nil 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsOverlays.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsOverlays: Overlays { 4 | 5 | private let mapView: GMSMapView 6 | private var overlays: [GMSGroundOverlay] = [] 7 | 8 | init(mapView: GMSMapView) { 9 | self.mapView = mapView 10 | } 11 | 12 | func setOverlays(overlayObjects: [OverlayObject]) { 13 | detachAndDeleteOverlays() 14 | for overlayObject in overlayObjects { 15 | let southWest = CLLocationCoordinate2D(latitude: overlayObject.bounds.southWest.latitude, longitude: overlayObject.bounds.southWest.longitude) 16 | let northEast = CLLocationCoordinate2D(latitude: overlayObject.bounds.northEast.latitude, longitude: overlayObject.bounds.northEast.longitude) 17 | let overlayBounds = GMSCoordinateBounds(coordinate: southWest, coordinate: northEast) 18 | let iconURL = URL(fileURLWithPath: overlayObject.icon) 19 | let icon = UIImage(contentsOfFile: iconURL.standardized.path) 20 | let overlay = GMSGroundOverlay(bounds: overlayBounds, icon: icon) 21 | overlay.bearing = 0 22 | overlay.map = mapView 23 | overlays.append(overlay) 24 | } 25 | } 26 | 27 | internal func detachAndDeleteOverlays() { 28 | for overlay in overlays { 29 | overlay.map = nil 30 | } 31 | overlays = [] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsPlaces.swift: -------------------------------------------------------------------------------- 1 | import GooglePlaces 2 | import GoogleMaps 3 | import ExpoModulesCore 4 | 5 | class GoogleMapsPlaces: PointsOfInterests { 6 | 7 | private let mapView: GMSMapView 8 | private var markers: GoogleMapsMarkers 9 | private let placesClient: GMSPlacesClient 10 | private var tokenUtils: GoogleMapsPlacesTokenUtils 11 | private var placesSearchCompleter: GoogleMapsPlacesSearchCompleter 12 | private var placesFetcher: GooglePlacesFetchPlace 13 | 14 | init(mapView: GMSMapView, markers: GoogleMapsMarkers) { 15 | self.mapView = mapView 16 | self.markers = markers 17 | placesClient = GMSPlacesClient() 18 | tokenUtils = GoogleMapsPlacesTokenUtils() 19 | 20 | placesSearchCompleter = GoogleMapsPlacesSearchCompleter(placesClient: placesClient, tokenUtils: tokenUtils) 21 | placesFetcher = GooglePlacesFetchPlace(placesClient: placesClient, tokenUtils: tokenUtils, markers: markers, mapView: mapView) 22 | } 23 | 24 | func fetchSearchCompletions(searchQueryFragment: String, promise: Promise) { 25 | placesSearchCompleter.setSearchCompleterRegion(mapView: mapView) 26 | placesSearchCompleter.autoComplete(searchQueryFragment: searchQueryFragment, promise: promise) 27 | } 28 | 29 | func createSearchRequest(place: String) { 30 | guard !place.isEmpty, let placeId = getPlaceIdFromCompletion(place: place) else { 31 | markers.detachAndDeletePOIMarkers() 32 | return 33 | } 34 | placesFetcher.search(placeId: placeId) 35 | } 36 | 37 | private func getPlaceIdFromCompletion(place: String) -> String? { 38 | let tmpStr = place.components(separatedBy: ";") 39 | return tmpStr[1] 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsPolylines.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | class GoogleMapsPolylines: Polylines { 4 | 5 | private let mapView: GMSMapView 6 | private var polylines: [ExpoGoogleMapsPolyline] = [] 7 | 8 | init(mapView: GMSMapView) { 9 | self.mapView = mapView 10 | } 11 | 12 | func setPolylines(polylineObjects: [PolylineObject]) { 13 | detachAndDeletePolylines() 14 | for polylineObject in polylineObjects { 15 | let path = GMSMutablePath() 16 | for point in polylineObject.points { 17 | path.add(CLLocationCoordinate2D(latitude: point.latitude, longitude: point.longitude)) 18 | } 19 | let polyline = ExpoGoogleMapsPolyline(path: path) 20 | polyline.strokeWidth = CGFloat(polylineObject.width ?? Float(polyline.strokeWidth)) 21 | polyline.strokeColor = polylineObject.color ?? polyline.strokeColor 22 | if polylineObject.pattern != nil { 23 | polyline.pattern = polylineObject.pattern 24 | polyline.spans = strokePatternToStyles( 25 | path: polyline.path!, strokePattern: polyline.pattern!, color: polyline.strokeColor, 26 | width: Float(polyline.strokeWidth)) 27 | } 28 | polyline.map = mapView 29 | polylines.append(polyline) 30 | } 31 | } 32 | 33 | internal func detachAndDeletePolylines() { 34 | for polyline in polylines { 35 | polyline.map = nil 36 | } 37 | polylines = [] 38 | } 39 | 40 | private func strokePatternToStyles( 41 | path: GMSPath, strokePattern: [PatternItem], color: UIColor = .blue, width: Float = 2 42 | ) -> [GMSStyleSpan] { 43 | let col = GMSStrokeStyle.solidColor(color) 44 | let trans = GMSStrokeStyle.solidColor(.clear) 45 | let styles = strokePattern.map({ (patIt: PatternItem) -> GMSStrokeStyle in 46 | switch patIt.type { 47 | case .stroke: 48 | return col 49 | case .gap: 50 | return trans 51 | } 52 | }) 53 | let scale: Float = Float( 54 | 1.0 / mapView.projection.points(forMeters: 1, at: mapView.camera.target)) 55 | let lengths = strokePattern.map({ 56 | $0.length == 0 && $0.type == .stroke 57 | ? NSNumber(value: scale * width) : NSNumber(value: scale * $0.length) 58 | }) 59 | return GMSStyleSpans(path, styles, lengths, GMSLengthKind.rhumb) 60 | } 61 | 62 | func updateStrokePatterns() { 63 | for polyline in polylines { 64 | if polyline.pattern != nil { 65 | polyline.spans = strokePatternToStyles( 66 | path: polyline.path!, strokePattern: polyline.pattern!, color: polyline.strokeColor, 67 | width: Float(polyline.strokeWidth)) 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/GoogleMapsUtils.swift: -------------------------------------------------------------------------------- 1 | import GoogleMaps 2 | 3 | /* 4 | Returns asset based marker icon when markerObject.icon is not null, otherwise returns default marker with provided color. 5 | */ 6 | func createGoogleMarker(markerObject: MarkerObject, includeDragging: Bool) -> GMSMarker { 7 | let position = CLLocationCoordinate2D(latitude: markerObject.latitude, longitude: markerObject.longitude) 8 | let marker = GMSMarker(position: position) 9 | let iconURL = (markerObject.icon != nil) ? URL(fileURLWithPath: markerObject.icon!) : nil 10 | marker.title = markerObject.markerTitle 11 | marker.snippet = markerObject.markerSnippet 12 | 13 | if (includeDragging) { 14 | marker.isDraggable = markerObject.draggable 15 | } 16 | 17 | marker.groundAnchor = CGPoint(x: markerObject.anchorU ?? 0.5, y: markerObject.anchorV ?? 1) 18 | marker.opacity = Float(markerObject.opacity) 19 | 20 | if (iconURL != nil) { 21 | marker.icon = UIImage(contentsOfFile: iconURL!.standardized.path) 22 | } else { 23 | marker.icon = GMSMarker.markerImage(with: markerObject.color) 24 | } 25 | 26 | return marker 27 | } 28 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/PlacesUtils/GoogleMapsPlacesSearchCompleter.swift: -------------------------------------------------------------------------------- 1 | import GooglePlaces 2 | import GoogleMaps 3 | import ExpoModulesCore 4 | 5 | class GoogleMapsPlacesSearchCompleter: SearchCompleter { 6 | 7 | private var placesClient: GMSPlacesClient 8 | private var tokenUtils: GoogleMapsPlacesTokenUtils 9 | private var searchCompleterResults: [GMSAutocompletePrediction]? 10 | private var filter = GMSAutocompleteFilter() 11 | 12 | init(placesClient: GMSPlacesClient, tokenUtils: GoogleMapsPlacesTokenUtils) { 13 | self.placesClient = placesClient 14 | self.tokenUtils = tokenUtils 15 | } 16 | 17 | func autoComplete(searchQueryFragment: String) { 18 | autoComplete(searchQueryFragment: searchQueryFragment, promise: nil) 19 | } 20 | 21 | func autoComplete(searchQueryFragment: String, promise: Promise?) { 22 | guard let token = tokenUtils.getToken() else { 23 | let errorMessage = "No token provided for auto complete request!" 24 | promise?.reject("", errorMessage) 25 | return 26 | } 27 | 28 | placesClient.findAutocompletePredictions(fromQuery: searchQueryFragment, filter: filter, sessionToken: token, callback: {(results, error) in 29 | if let error = error { 30 | let errorMessage = "Autocomplete error: \(error)" 31 | promise?.reject("", errorMessage) 32 | return 33 | } 34 | if let results = results { 35 | self.searchCompleterResults = results 36 | } 37 | } 38 | ) 39 | 40 | if let promise = promise { 41 | resolveSearchCompletionsPromise(searchCompletionsPromise: promise) 42 | } 43 | } 44 | 45 | func getSearchCompletions() -> [String] { 46 | if let results = searchCompleterResults { 47 | return mapSearchCompletions(completions: results) 48 | } 49 | return [] 50 | } 51 | 52 | func mapSearchCompletions(completions: [GMSAutocompletePrediction]) -> [String] { 53 | return completions.map { $0.attributedFullText.string + ";" + $0.placeID } 54 | } 55 | 56 | func setSearchCompleterFilters(filter: GMSAutocompleteFilter) { 57 | filter.type = .establishment 58 | } 59 | 60 | func setSearchCompleterRegion(mapView: GMSMapView) { 61 | let visibleRegion = mapView.projection.visibleRegion() 62 | let bounds = GMSCoordinateBounds(region: visibleRegion) 63 | let region = GMSPlaceRectangularLocationOption(bounds.northEast, bounds.southWest) 64 | filter.locationBias = region 65 | } 66 | 67 | private func resolveSearchCompletionsPromise(searchCompletionsPromise: Promise) { 68 | let results = getSearchCompletions() 69 | searchCompletionsPromise.resolve(results) 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/PlacesUtils/GoogleMapsPlacesTokenUtils.swift: -------------------------------------------------------------------------------- 1 | import GooglePlaces 2 | 3 | class GoogleMapsPlacesTokenUtils { 4 | 5 | private var token: GMSAutocompleteSessionToken? 6 | 7 | init() { 8 | token = GMSAutocompleteSessionToken.init() 9 | } 10 | 11 | func setNewSessionToken() { 12 | token = GMSAutocompleteSessionToken.init() 13 | } 14 | 15 | func deleteToken() { 16 | token = nil 17 | } 18 | 19 | func getToken() -> GMSAutocompleteSessionToken? { 20 | if let token = token { 21 | return token 22 | } 23 | print("GMSAutocompleteSessionToken was not set") 24 | return nil 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/GoogleMaps/PlacesUtils/GooglePlacesFetchPlace.swift: -------------------------------------------------------------------------------- 1 | import GooglePlaces 2 | import GoogleMaps 3 | 4 | class GooglePlacesFetchPlace { 5 | 6 | private var placesClient: GMSPlacesClient 7 | private var tokenUtils: GoogleMapsPlacesTokenUtils 8 | private var markers: GoogleMapsMarkers 9 | private var mapView: GMSMapView 10 | private var fetchedPlace: GMSPlace? { 11 | didSet { 12 | displayMarker() 13 | } 14 | } 15 | 16 | init(placesClient: GMSPlacesClient, tokenUtils: GoogleMapsPlacesTokenUtils, markers: GoogleMapsMarkers, mapView: GMSMapView) { 17 | self.placesClient = placesClient 18 | self.tokenUtils = tokenUtils 19 | self.markers = markers 20 | self.mapView = mapView 21 | } 22 | 23 | func search(placeId: String) { 24 | guard let token = tokenUtils.getToken() else { 25 | print("No token provided for auto complete request!") 26 | return 27 | } 28 | 29 | let fields = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) 30 | | UInt(GMSPlaceField.coordinate.rawValue)) 31 | 32 | 33 | placesClient.fetchPlace(fromPlaceID: placeId, placeFields: fields, sessionToken: token, callback: { (place, error) in 34 | if let error = error { 35 | print("An error occurred: \(error.localizedDescription)") 36 | } 37 | if let place = place { 38 | self.fetchedPlace = place 39 | } 40 | }) 41 | 42 | tokenUtils.setNewSessionToken() 43 | } 44 | 45 | } 46 | 47 | extension GooglePlacesFetchPlace { 48 | 49 | private func displayMarker() { 50 | if let marker = getMarkerToDisplay() { 51 | markers.setPOIMarkers(markerObjects: [marker]) 52 | var bounds = GMSCoordinateBounds() 53 | let coordinate = CLLocationCoordinate2D(latitude: marker.latitude, longitude: marker.longitude) 54 | bounds = bounds.includingCoordinate(coordinate) 55 | let update = GMSCameraUpdate.fit(bounds) 56 | mapView.moveCamera(update) 57 | } 58 | } 59 | 60 | private func getMarkerToDisplay() -> MarkerObject? { 61 | guard let place = fetchedPlace else { return nil } 62 | let marker = MarkerObject() 63 | marker.latitude = place.coordinate.latitude 64 | marker.longitude = place.coordinate.longitude 65 | marker.markerTitle = place.name 66 | marker.opacity = 1 67 | marker.color = UIColor.clear 68 | marker.draggable = false 69 | return marker 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/MapEventsNames.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import GoogleMapsUtils 3 | import GoogleMaps 4 | 5 | enum MapEventsNames: String { 6 | case ON_CAMERA_MOVE_STARTED_EVENT = "onCameraMoveStarted" 7 | case ON_CAMERA_MOVE_ENDED_EVENT = "onCameraMoveEnded" 8 | case ON_MARKER_CLICK_EVENT = "onMarkerClick" 9 | case ON_MARKER_DRAG_STARTED_EVENT = "onMarkerDragStarted" 10 | case ON_MARKER_DRAG_ENDED_EVENT = "onMarkerDragEnded" 11 | } 12 | 13 | func createCameraEventContent(latitude: Double, longitude: Double) -> [String : Any?] { 14 | return ["latitude" : latitude, "longitude" : longitude] 15 | } 16 | 17 | func createMarkerClickEventContent(id: String) -> [String : Any?] { 18 | return ["id" : id] 19 | } 20 | 21 | func createMarkerDragStartedEventContent(id: String) -> [String : Any?] { 22 | return ["id" : id] 23 | } 24 | 25 | func createMarkerDragEndedEventContent(id: String, latitude: Double, longitude: Double) -> [String : Any?] { 26 | return ["id" : id, "latitude" : latitude, "longitude" : longitude] 27 | } 28 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Circles.swift: -------------------------------------------------------------------------------- 1 | protocol Circles { 2 | func detachAndDeleteCircles() 3 | func setCircles(circleObjects: [CircleObject]) 4 | } 5 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Clusters.swift: -------------------------------------------------------------------------------- 1 | protocol Clusters { 2 | func setClusters(clusterObjects: [ClusterObject]) 3 | } 4 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Controls.swift: -------------------------------------------------------------------------------- 1 | protocol Controls { 2 | func setShowCompass(enable: Bool) 3 | func setShowMyLocationButton(enable: Bool) 4 | func setShowLevelPicker(enable: Bool) 5 | } 6 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/ExpoMapView.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | protocol ExpoMapView: UIView { 4 | init(sendEvent: @escaping (String, [String: Any?]) -> Void) 5 | init?(coder: NSCoder) 6 | 7 | func setMapType(mapType: MapType) 8 | func setMarkers(markerObjects: [MarkerObject]) 9 | func setPolygons(polygonObjects: [PolygonObject]) 10 | func setPolylines(polylineObjects: [PolylineObject]) 11 | func setInitialCameraPosition(initialCameraPosition: CameraMoveRecord) 12 | func moveCamera(cameraMove: CameraMoveRecord, promise: Promise?) 13 | func setEnabledTraffic(enableTraffic: Bool) 14 | func setKMLs(kmlObjects: [KMLObject]) 15 | func setGeoJsons(geoJsonObjects: [GeoJsonObject]) 16 | func setOverlays(overlayObjects: [OverlayObject]) 17 | } 18 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/GeoJsons.swift: -------------------------------------------------------------------------------- 1 | protocol GeoJsons { 2 | func setGeoJsons(geoJsonObjects: [GeoJsonObject]) 3 | } 4 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Gestures.swift: -------------------------------------------------------------------------------- 1 | protocol Gestures { 2 | func setEnabledRotateGesture(enabled: Bool) 3 | func setEnabledScrollGesture(enabled: Bool) 4 | func setEnabledTiltGesture(enabled: Bool) 5 | func setEnabledZoomGesture(enabled: Bool) 6 | } 7 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Heatmaps.swift: -------------------------------------------------------------------------------- 1 | protocol Heatmaps { 2 | func setHeatmaps(heatmapObjects: [HeatmapObject]) 3 | } 4 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/KMLs.swift: -------------------------------------------------------------------------------- 1 | protocol KMLs { 2 | func setKMLs(kmlObjects: [KMLObject]) 3 | } 4 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Markers.swift: -------------------------------------------------------------------------------- 1 | protocol Markers { 2 | func detachAndDeleteMarkers() 3 | func setMarkers(markerObjects: [MarkerObject]) 4 | } 5 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Overlays.swift: -------------------------------------------------------------------------------- 1 | protocol Overlays { 2 | func detachAndDeleteOverlays() 3 | func setOverlays(overlayObjects: [OverlayObject]) 4 | } 5 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/PointsOfInterests.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | protocol PointsOfInterests { 4 | func fetchSearchCompletions(searchQueryFragment: String, promise: Promise) 5 | func createSearchRequest(place: String) 6 | } 7 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Polygons.swift: -------------------------------------------------------------------------------- 1 | protocol Polygons { 2 | func detachAndDeletePolygons() 3 | func setPolygons(polygonObjects: [PolygonObject]) 4 | } 5 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/Polylines.swift: -------------------------------------------------------------------------------- 1 | protocol Polylines { 2 | func detachAndDeletePolylines() 3 | func setPolylines(polylineObjects: [PolylineObject]) 4 | } 5 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Protocols/SearchCompleter.swift: -------------------------------------------------------------------------------- 1 | protocol SearchCompleter { 2 | associatedtype T 3 | func autoComplete(searchQueryFragment: String) 4 | func getSearchCompletions() -> [String] 5 | func mapSearchCompletions(completions: [T]) -> [String] 6 | } 7 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/CameraMoveRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import GoogleMaps 3 | import MapKit 4 | 5 | struct CameraMoveRecord: Record { 6 | init() {} 7 | 8 | @Field var target: [String: Any?] 9 | @Field var zoom: Float? 10 | @Field var bearing: Double? 11 | @Field var tilt: Double? 12 | @Field var latLngDelta: [String: Any?]? 13 | @Field var duration: Int = 1000 14 | @Field var animate: Bool = true 15 | } 16 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/CameraPositionRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import GoogleMaps 3 | import MapKit 4 | 5 | struct CameraPositionRecord: Record { 6 | init() {} 7 | 8 | @Field var target: [String: Any?] 9 | @Field var zoom: Float? 10 | @Field var bearing: Double? 11 | @Field var tilt: Double? 12 | @Field var latitudeDelta: Double? 13 | @Field var longitudeDelta: Double? 14 | 15 | init(cameraPosition: GMSCameraPosition, visibleRegion: GMSVisibleRegion?) { 16 | target = LatLngRecord(coordinate: cameraPosition.target).toDictionary(); 17 | zoom = cameraPosition.zoom 18 | bearing = cameraPosition.bearing; 19 | tilt = cameraPosition.viewingAngle; 20 | if let visibleRegion = visibleRegion { 21 | latitudeDelta = abs(visibleRegion.nearLeft.latitude - visibleRegion.farRight.latitude) 22 | longitudeDelta = abs(visibleRegion.nearLeft.longitude - visibleRegion.farRight.longitude) 23 | } 24 | } 25 | 26 | init(camera: MKMapCamera, coordinateSpan: MKCoordinateSpan) { 27 | target = LatLngRecord(coordinate: camera.centerCoordinate).toDictionary() 28 | bearing = camera.heading 29 | tilt = camera.pitch 30 | latitudeDelta = coordinateSpan.latitudeDelta 31 | longitudeDelta = coordinateSpan.longitudeDelta 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/ClusterRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import GoogleMaps 3 | import MapKit 4 | import GoogleMapsUtils 5 | 6 | struct ClusterRecord: Record { 7 | init() {} 8 | 9 | @Field var id: String? 10 | @Field var position: [String: Any?] 11 | 12 | init(id: String, cluster: GMUCluster) { 13 | self.id = id 14 | position = LatLngRecord(coordinate: cluster.position).toDictionary() 15 | } 16 | 17 | init(cluster: ExpoMKClusterAnnotation) { 18 | id = cluster.id 19 | position = LatLngRecord(coordinate: cluster.coordinate).toDictionary() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/LatLngDeltaRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | struct LatLngDeltaRecord: Record { 4 | init() {} 5 | 6 | @Field var latitudeDelta: Double = 0 7 | @Field var longitudeDelta: Double = 0 8 | } 9 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/LatLngRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | struct LatLngRecord: Record { 4 | init() {} 5 | 6 | @Field var latitude: Double? 7 | @Field var longitude: Double? 8 | 9 | init(coordinate: CLLocationCoordinate2D) { 10 | latitude = coordinate.latitude 11 | longitude = coordinate.longitude 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/MarkerRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import GoogleMaps 3 | import MapKit 4 | 5 | struct MarkerRecord: Record { 6 | init() {} 7 | 8 | @Field var id: String? 9 | @Field var position: [String: Any?] 10 | 11 | init(id: String?, marker: GMSMarker) { 12 | self.id = id 13 | position = LatLngRecord(coordinate: marker.position).toDictionary() 14 | } 15 | 16 | init(marker: ExpoMKAnnotation) { 17 | id = marker.id 18 | position = LatLngRecord(coordinate: marker.coordinate).toDictionary() 19 | } 20 | 21 | init(marker: ExpoMKClusterAnnotation) { 22 | id = marker.id 23 | position = LatLngRecord(coordinate: marker.coordinate).toDictionary() 24 | } 25 | 26 | init(id: String, position: CLLocationCoordinate2D) { 27 | self.id = id 28 | self.position = LatLngRecord(coordinate: position).toDictionary() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/PointOfInterestRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | 3 | struct PointOfInterestRecord: Record { 4 | init() {} 5 | 6 | @Field var position: [String: Any?]? 7 | @Field var name: String? 8 | @Field var placeId: String? 9 | 10 | init(placeId: String, name: String, location: CLLocationCoordinate2D) { 11 | position = LatLngRecord(coordinate: location).toDictionary() 12 | self.placeId = placeId 13 | self.name = name 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /expo-maps/ios/ExpoMaps/Records/UserLocationRecord.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import MapKit 3 | 4 | struct UserLocationRecord: Record { 5 | init() {} 6 | 7 | @Field var position: [String: Any?] 8 | @Field var altitude: Double? 9 | @Field var accuracy: Double? 10 | @Field var verticalAccuracy: Double? 11 | @Field var speed: Double? 12 | @Field var speedAccuracy: Double? 13 | @Field var heading: Double? 14 | @Field var timestamp: Double? 15 | 16 | init(location: CLLocation) { 17 | position = LatLngRecord(coordinate: location.coordinate).toDictionary() 18 | altitude = location.altitude 19 | accuracy = location.horizontalAccuracy 20 | verticalAccuracy = location.verticalAccuracy 21 | speed = location.speed 22 | speedAccuracy = location.speedAccuracy 23 | heading = location.course 24 | timestamp = location.timestamp.timeIntervalSinceReferenceDate * 1000 25 | } 26 | 27 | init(location: MKUserLocation) { 28 | position = LatLngRecord(coordinate: location.coordinate).toDictionary() 29 | altitude = location.location?.altitude 30 | accuracy = location.location?.horizontalAccuracy 31 | verticalAccuracy = location.location?.verticalAccuracy 32 | speed = location.location?.speed 33 | speedAccuracy = location.location?.speedAccuracy 34 | heading = location.heading?.trueHeading 35 | timestamp = (location.location?.timestamp.timeIntervalSinceReferenceDate ?? -1) * 1000 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /expo-maps/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-maps", 3 | "version": "1.0.0", 4 | "description": "ExpoMaps standalone module", 5 | "main": "build/Map.js", 6 | "types": "build/Map.d.ts", 7 | "scripts": { 8 | "build": "expo-module build", 9 | "clean": "expo-module clean", 10 | "lint": "expo-module lint", 11 | "test": "expo-module test", 12 | "prepare": "expo-module prepare", 13 | "prepublishOnly": "expo-module prepublishOnly", 14 | "expo-module": "expo-module" 15 | }, 16 | "keywords": [ 17 | "react-native", 18 | "expo", 19 | "expo-maps" 20 | ], 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/expo/expo.git", 24 | "directory": "packages/expo-maps" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/expo/expo/issues" 28 | }, 29 | "author": "650 Industries, Inc.", 30 | "license": "MIT", 31 | "homepage": "https://docs.expo.dev/versions/latest/sdk/module-template", 32 | "dependencies": { 33 | "expo-asset": "^8.4.6", 34 | "expo-location": "^14.0.2", 35 | "expo-module-scripts": "^2.0.0" 36 | }, 37 | "peerDependencies": { 38 | "expo": "*" 39 | }, 40 | "jest": { 41 | "preset": "expo-module-scripts/ios" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /expo-maps/src/Circle.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Point } from './Common.types'; 3 | 4 | /** 5 | * Props of Circle component of Expo Maps library. 6 | */ 7 | export type CircleProps = { 8 | /** 9 | * The center position of the circle. 10 | * @required 11 | */ 12 | center: Point; 13 | /** 14 | * The radius of the circle in meters. 15 | * @required 16 | */ 17 | radius: number; 18 | /** 19 | /** 20 | * Color of the circle's edge line (optional). 21 | * 22 | * Accepted formats: 23 | * * `'#RRGGBB'` 24 | * * `'#RRGGBBAA'` 25 | * * `'#RGB'` 26 | * * `'#RGBA'` 27 | * @default default for given map provider 28 | */ 29 | strokeColor?: string; 30 | /** 31 | * Circle edge's width in pixels. (optional) 32 | * 33 | * @default default for given map provider 34 | */ 35 | strokeWidth?: number; 36 | /** 37 | * Circle fill color in hex format (optional). 38 | 39 | * Accepted formats: 40 | * * `'#RRGGBB'` 41 | * * `'#RRGGBBAA'` 42 | * * `'#RGB'` 43 | * * `'#RGBA'` 44 | * @default '#00000000' 45 | */ 46 | fillColor?: string; 47 | }; 48 | 49 | 50 | /** 51 | * Internal JSON object for representing circles in Expo Maps library. 52 | * 53 | * See {@link CircleProps} for more detail. 54 | */ 55 | export type CircleObject = { 56 | type: 'circle'; 57 | center: Point; 58 | radius: number; 59 | strokeColor?: string; 60 | strokeWidth?: number; 61 | fillColor?: string; 62 | }; 63 | 64 | /** 65 | * Circle component of Expo Maps library. 66 | * 67 | * Draws customizable flat circle on ExpoMap. 68 | * Drawn circle does not follow curvature of the Earth. 69 | * 70 | * This component should be ExpoMap component child to work properly. 71 | * 72 | * See {@link CircleProps} to learn more about props. 73 | */ 74 | export class Circle extends React.Component { 75 | render() { 76 | return null; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /expo-maps/src/Cluster.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PropsWithChildren } from 'react'; 3 | import { BaseMarkerOptions, MarkerObject, Marker } from './Marker'; 4 | 5 | /** 6 | * Props of Cluster component of Expo Maps library. 7 | */ 8 | export type ClusterProps = PropsWithChildren< 9 | { 10 | /** 11 | * Cluster name 12 | * 13 | * @required 14 | */ 15 | name: String; 16 | /** 17 | * Minimal number of markers to form the cluster 18 | * 19 | * @default 4 20 | */ 21 | minimumClusterSize?: number; 22 | } & BaseMarkerOptions 23 | >; 24 | 25 | /** 26 | * Internal JSON object for representing marker clusters in Expo Maps library. 27 | * 28 | * See {@link ClusterProps} for more detail. 29 | */ 30 | export type ClusterObject = { 31 | type: 'cluster'; 32 | markers: MarkerObject[]; 33 | name: String; 34 | minimumClusterSize: number; 35 | } & BaseMarkerOptions; 36 | 37 | /** 38 | * Cluster component of Expo Maps library. 39 | * 40 | * Gathers {@link Marker}s passed as this component children in cluster. 41 | * 42 | * This component should be ExpoMap component child to work properly. 43 | * 44 | * See {@link ClusterProps} to learn more about props. 45 | */ 46 | export class Cluster extends React.Component { 47 | render() { 48 | return null; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /expo-maps/src/ExpoMaps.ts: -------------------------------------------------------------------------------- 1 | import { NativeModulesProxy } from 'expo-modules-core'; 2 | 3 | export const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps; 4 | export const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps; 5 | -------------------------------------------------------------------------------- /expo-maps/src/ExpoMaps.web.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | get name(): string { 3 | return 'ExpoMaps'; 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /expo-maps/src/Heatmap.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { PointWithData } from './Common.types'; 3 | import { ExpoLinearGradient } from 'expo-module-scripts'; 4 | 5 | /** 6 | * Props of Heatmap component of Expo Maps library. 7 | */ 8 | export type HeatmapProps = { 9 | points: PointWithData[]; 10 | } & HeatmapOptions; 11 | 12 | /** 13 | * Configuration options for the heatmap. 14 | */ 15 | export type HeatmapOptions = { 16 | /** 17 | * The radius of Gaussian blur applied to the points in pixels (optional). 18 | * @default 20 19 | */ 20 | radius?: number; 21 | /** 22 | * Defines the color theme of the heatmap (optianal). 23 | * 24 | * Color locations will correspond to colors for particular values on the heatmap scaled between 0 and 1. 25 | * 26 | * @default provider default 27 | */ 28 | gradient?: ExpoLinearGradient; 29 | /** 30 | * Opacity of the heatmap (optional). 31 | * @default 1 32 | */ 33 | opacity?: number; 34 | }; 35 | 36 | /** 37 | * Internal JSON object for representing marker clusters in Expo Maps library. 38 | * 39 | * See {@link ClusterProps} for more detail. 40 | */ 41 | export type HeatmapObject = { 42 | type: 'heatmap'; 43 | points: PointWithData[]; 44 | radius?: number; 45 | opacity?: number; 46 | } & HeatmapProps; 47 | 48 | /** 49 | * Heatmap component of Expo Maps library. 50 | * 51 | * Displays multiple {@link PointWithData} objects as a heatmap. 52 | * Providing data with each point is optional; if no data is provided, 53 | * heatmap will represent density of points on the map. 54 | * 55 | * This component should be ExpoMap component child to work properly. 56 | * 57 | * See {@link HeatmapProps} to learn more about props. 58 | */ 59 | export class Heatmap extends React.Component { 60 | render() { 61 | return null; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /expo-maps/src/KML.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | /** 4 | * KML specific props. 5 | */ 6 | export type KMLProps = { 7 | /** 8 | * The value of require('path/to/file.kml') for the .kml asset 9 | */ 10 | filePath: string; 11 | }; 12 | 13 | /** 14 | * Internal JSON object for representing marker KMLs in Expo Maps library. 15 | * 16 | * See {@link KMLProps} for more detail. 17 | */ 18 | export type KMLObject = { 19 | type: 'kml'; 20 | } & KMLProps; 21 | 22 | /** 23 | * KML component of Expo Maps library. 24 | * 25 | * Displays data provided in .kml file. 26 | * This component should be ExpoMap component child to work properly. 27 | * 28 | * See {@link KMLProps} for more details. 29 | */ 30 | export class KML extends React.Component { 31 | render() { 32 | return null; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /expo-maps/src/Marker.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Point } from './Common.types'; 3 | 4 | /** 5 | * Marker specific props. 6 | */ 7 | export type BaseMarkerOptions = { 8 | /** 9 | * Id of the marker or cluster, should be unique. 10 | * If no id is specified then marker-related events won't fire for that particular marker or cluster. 11 | */ 12 | id?: string; 13 | /** 14 | * Title of the marker, avaliable in annotation box. 15 | */ 16 | markerTitle?: string; 17 | /** 18 | * Short description of the marker, avaliable in annotation box. 19 | */ 20 | markerSnippet?: string; 21 | /** 22 | * Custom marker icon. 23 | */ 24 | icon?: string; 25 | /** 26 | * Color of a marker when icon is not provided. 27 | * 28 | * Accepted formats: 29 | * * `'#RRGGBB'` 30 | * * `'#RRGGBBAA'` 31 | * * `'#RGB'` 32 | * * `'#RGBA'` 33 | * * 'red' 34 | * * 'blue' 35 | * * 'green' 36 | * * 'black' 37 | * * 'white' 38 | * * 'gray' 39 | * * 'cyan' 40 | * * 'magenta' 41 | * * 'yellow' 42 | * * 'lightgray' 43 | * * 'darkgray' 44 | * * 'grey' 45 | * * 'aqua' 46 | * * 'fuchsia' 47 | * * 'lime' 48 | * * 'maroon' 49 | * * 'navy' 50 | * * 'olive' 51 | * * 'purple' 52 | * * 'silver' 53 | * * 'teal' 54 | * @default 'red' 55 | */ 56 | color?: string; 57 | /** 58 | * Opacity of a marker's icon, applied both to asset based icon 59 | * as well as to default marker's icon. 60 | */ 61 | opacity?: number; 62 | }; 63 | 64 | export type MarkerOptions = { 65 | /** 66 | * If 'true' marker is draggable, clustered markers can't be dragged. 67 | * 68 | * @default false 69 | */ 70 | draggable?: boolean; 71 | /** 72 | * Translation of latitude coordinate. 73 | */ 74 | anchorU?: number; 75 | /** 76 | * Translation of longitude coordinate. 77 | */ 78 | anchorV?: number; 79 | } & BaseMarkerOptions; 80 | 81 | /** 82 | * Props of Marker component of Expo Maps library. 83 | */ 84 | export type MarkerProps = MarkerOptions & Point; 85 | 86 | /** 87 | * Internal JSON object for representing markers in Expo Maps library. 88 | * 89 | * See {@link MarkerProps} for more details. 90 | */ 91 | export type MarkerObject = { 92 | type: 'marker'; 93 | } & MarkerOptions & 94 | Point; 95 | 96 | /** 97 | * Marker component of Expo Maps library. 98 | * 99 | * Draws customizable marker on ExpoMap. 100 | * This component should be ExpoMap component child to work properly. 101 | * 102 | * See {@link MarkerProps} for more details. 103 | */ 104 | export class Marker extends React.Component { 105 | render() { 106 | return null; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /expo-maps/src/NativeExpoMapView.tsx: -------------------------------------------------------------------------------- 1 | import { requireNativeViewManager } from 'expo-modules-core'; 2 | import { NativeModulesProxy } from 'expo-modules-core'; 3 | import * as React from 'react'; 4 | 5 | import { 6 | NativeExpoGoogleMapsViewProps, 7 | NativeExpoAppleMapsViewProps, 8 | } from './Map.types'; 9 | 10 | export const NativeExpoGoogleMapsView = requireNativeViewManager( 11 | 'ExpoGoogleMaps' 12 | ) as React.ComponentType; 13 | 14 | export const NativeExpoAppleMapsView = requireNativeViewManager( 15 | 'ExpoAppleMaps' 16 | ) as React.ComponentType; 17 | 18 | export const NativeExpoAppleMapsModule = NativeModulesProxy.ExpoAppleMaps; 19 | export const NativeExpoGoogleMapsModule = NativeModulesProxy.ExpoGoogleMaps; 20 | -------------------------------------------------------------------------------- /expo-maps/src/Overlay.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Point } from './Common.types'; 3 | 4 | /** 5 | * Overlay specific props. 6 | */ 7 | export type OverlayProps = { 8 | /** 9 | * South west, and north east corners of the image. 10 | */ 11 | bounds: { 12 | /** 13 | * South west corner coordinates. 14 | */ 15 | southWest: Point; 16 | /** 17 | * North east corner coordinates. 18 | */ 19 | northEast: Point; 20 | }; 21 | /** 22 | * Custom overlay graphic 23 | */ 24 | icon: string; 25 | }; 26 | 27 | export type OverlayObject = { 28 | type: 'overlay'; 29 | } & OverlayProps; 30 | 31 | /** 32 | * Ground Overlay component of Expo Maps library. 33 | * 34 | * Draws custom ground overlays on ExpoMap. 35 | * This component should be ExpoMap component child to work properly. 36 | * 37 | * See {@link OverlayProps} for more details. 38 | */ 39 | export class Overlay extends React.Component { 40 | render() { 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /expo-maps/src/__tests__/Maps-test.ts: -------------------------------------------------------------------------------- 1 | import * as Maps from '../Maps'; 2 | 3 | describe('Maps', () => { 4 | it('someGreatMethodAsync is defined', async () => { 5 | expect(Maps.someGreatMethodAsync).toBeDefined(); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /expo-maps/tsconfig.json: -------------------------------------------------------------------------------- 1 | // @generated by expo-module-scripts 2 | { 3 | "extends": "expo-module-scripts/tsconfig.base", 4 | "compilerOptions": { 5 | "outDir": "./build" 6 | }, 7 | "include": ["./src"], 8 | "exclude": ["**/__mocks__/*", "**/__tests__/*"] 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@expo/expo-maps", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": "Expo", 6 | "license": "MIT", 7 | "workspaces": { 8 | "packages": [ 9 | "example", 10 | "expo-maps" 11 | ] 12 | }, 13 | "scripts": { 14 | "clean-install": "rm -rf node_modules yarn.lock; cd expo-maps && rm -rf node_modules build android/build; cd ../example && rm -rf node_modules android/build android/.gradle ios/Pods ios/Podfile.lock ios/build && cd .. && yarn install && cd example/ios && pod install" 15 | }, 16 | "resolutions": { 17 | "expo-modules-core": "~0.11.3" 18 | } 19 | } 20 | --------------------------------------------------------------------------------