├── example ├── .ruby-version ├── app.json ├── .bundle │ └── config ├── android │ ├── app │ │ ├── debug.keystore │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.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 │ │ │ │ │ └── drawable │ │ │ │ │ │ └── rn_edit_text_material.xml │ │ │ │ ├── jni │ │ │ │ │ ├── MainApplicationModuleProvider.h │ │ │ │ │ ├── OnLoad.cpp │ │ │ │ │ ├── MainApplicationModuleProvider.cpp │ │ │ │ │ ├── MainComponentsRegistry.h │ │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.h │ │ │ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp │ │ │ │ │ ├── Android.mk │ │ │ │ │ └── MainComponentsRegistry.cpp │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ ├── newarchitecture │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ └── MainComponentsRegistry.java │ │ │ │ │ │ └── modules │ │ │ │ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ └── debug │ │ │ │ └── AndroidManifest.xml │ │ ├── proguard-rules.pro │ │ ├── build_defs.bzl │ │ └── _BUCK │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ ├── gradle.properties │ └── build.gradle ├── ios │ ├── example │ │ ├── Images.xcassets │ │ │ ├── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ ├── AppDelegate.h │ │ ├── main.m │ │ └── Info.plist │ ├── example.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── _xcode.env │ ├── exampleTests │ │ ├── Info.plist │ │ └── exampleTests.m │ └── Podfile ├── src │ └── examples │ │ ├── assets │ │ ├── car.png │ │ ├── flag-blue.png │ │ └── flag-pink.png │ │ ├── Geojson.tsx │ │ ├── CustomOverlayXMarksTheSpot.tsx │ │ ├── LiteMapView.tsx │ │ ├── CustomCallout.tsx │ │ ├── PriceMarker.tsx │ │ ├── MapKml.tsx │ │ ├── GradientPolylines.tsx │ │ ├── TestIdMarkers.tsx │ │ ├── OnPoiClick.tsx │ │ ├── CustomOverlay.tsx │ │ ├── IndoorMap.tsx │ │ ├── MapBoundaries.tsx │ │ ├── ImageOverlayWithAssets.tsx │ │ ├── AnimatedPriceMarker.tsx │ │ └── DraggableMarkers.tsx ├── .buckconfig ├── Gemfile ├── react-native.config.js ├── index.js ├── babel.config.js ├── package.json └── metro.config.js ├── .github ├── ISSUE_TEMPLATE │ └── config.yml ├── CODEOWNERS ├── workflows │ ├── stale.yml │ ├── push.yml │ └── pullRequest.yml └── PULL_REQUEST_TEMPLATE.md ├── src ├── sharedTypesInternal.ts ├── MapView.web.ts ├── ProviderConstants.ts ├── MapMarkerNativeComponent.ts ├── MapLocalTile.tsx ├── MapCalloutSubview.tsx ├── index.ts ├── sharedTypes.ts ├── MapCallout.tsx └── MapViewNativeComponent.ts ├── tsconfig.build.json ├── commitlint.config.js ├── .husky ├── commit-msg └── pre-commit ├── .eslintrc ├── babel.config.js ├── ios ├── AirMaps │ ├── AIRMapOverlayManager.h │ ├── AIRMapOverlayRenderer.h │ ├── AIRMapCoordinate.m │ ├── AIRMapCalloutManager.h │ ├── AIRMapCircleManager.h │ ├── AIRMapLocalTileOverlay.h │ ├── AIRMapPolygonManager.h │ ├── AIRMapPolylineManager.h │ ├── AIRMapCalloutSubviewManager.h │ ├── AIRMapWMSTileManager.h │ ├── AIRMapUrlTileManager.h │ ├── AIRMapLocalTileManager.h │ ├── AIRMapCalloutSubview.h │ ├── AIRMapCalloutSubview.m │ ├── AIRMapCoordinate.h │ ├── AIRMapUrlTileCachedOverlay.h │ ├── AIRMapSnapshot.h │ ├── AIRMapMarkerManager.h │ ├── AIRMapCallout.h │ ├── AIRMapCalloutSubviewManager.m │ ├── RCTConvert+AirMap.h │ ├── AIRWeakMapReference.m │ ├── AIRMapOverlayManager.m │ ├── AIRWeakTimerReference.h │ ├── AIRMapPolylineRenderer.h │ ├── AIRWeakMapReference.h │ ├── AIRMapLocalTileManager.m │ ├── AIRMapWMSTile.h │ ├── AIRMapCallout.m │ ├── AIRMapManager.h │ ├── AIRWeakTimerReference.m │ ├── AIRMapOverlayRenderer.m │ ├── AIRMapCalloutManager.m │ ├── AIRMapLocalTile.h │ ├── AIRMapOverlay.h │ ├── AIRMapLocalTileOverlay.m │ ├── AIRMapWMSTileManager.m │ ├── AIRMapUrlTileManager.m │ ├── AIRMapCircle.h │ ├── AIRMapPolylineManager.m │ ├── AIRMapPolygonManager.m │ ├── AIRMapPolyline.h │ ├── AIRMapPolygon.h │ ├── AIRMapUrlTile.h │ ├── AIRMapCircleManager.m │ ├── AIRMapLocalTile.m │ └── AIRMapMarker.h └── AirGoogleMaps │ ├── AIRGoogleMapHeatmapManager.h │ ├── AIRGMSMarker.m │ ├── AIRGMSPolygon.m │ ├── AIRGMSPolyline.m │ ├── AIRGoogleMapOverlayManager.h │ ├── AIRGoogleMapCircleManager.h │ ├── AIRGoogleMapPolygonManager.h │ ├── AIRGoogleMapPolylineManager.h │ ├── AIRGoogleMapMarkerManager.h │ ├── AIRGoogleMapCalloutManager.h │ ├── AIRGoogleMapUrlTileManager.h │ ├── AIRGoogleMapManager.h │ ├── AIRGoogleMapCalloutSubviewManager.h │ ├── AIRDummyView.h │ ├── AIRGoogleMapWMSTileManager.h │ ├── AIRGoogleMapCalloutSubview.h │ ├── AIRGoogleMapCalloutSubview.m │ ├── AIRDummyView.m │ ├── AIRGMSPolygon.h │ ├── RCTConvert+GMSMapViewType.h │ ├── AIRGMSPolyline.h │ ├── AIRGoogleMapCallout.h │ ├── AIRGoogleMapHeatmap.h │ ├── AIRGoogleMapUrlTile.h │ ├── AIRGMSMarker.h │ ├── AIRGoogleMapOverlayManager.m │ ├── AIRGoogleMapCalloutSubviewManager.m │ ├── AIRGoogleMapCalloutManager.m │ ├── AIRGoogleMapCircle.h │ ├── AIRGoogleMapURLTileManager.m │ ├── AIRGoogleMapHeatmapManager.m │ ├── AIRGoogleMapOverlay.h │ ├── AIRGoogleMapWMSTileManager.m │ ├── AIRGoogleMapCircleManager.m │ ├── AIRGoogleMapWMSTile.h │ ├── AIRGoogleMapPolygon.h │ ├── AIRGoogleMapCallout.m │ ├── AIRGoogleMapPolyline.h │ ├── AIRGoogleMapPolygonManager.m │ ├── AIRGoogleMapPolylineManager.m │ ├── AIRGoogleMapUrlTile.m │ ├── AIRGoogleMapCircle.m │ ├── AIRGoogleMapHeatmap.m │ └── AIRGoogleMapMarker.h ├── android ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── airbnb │ │ └── android │ │ └── react │ │ └── maps │ │ ├── ImageReadable.java │ │ ├── AirMapFeature.java │ │ ├── AirMapCallout.java │ │ ├── AirMapLiteManager.java │ │ ├── ViewAttacherGroup.java │ │ ├── ImageUtil.java │ │ ├── SizeReportingShadowNode.java │ │ ├── RegionChangeEvent.java │ │ ├── AirMapLocalTileManager.java │ │ ├── AirMapCalloutManager.java │ │ ├── LatLngBoundsUtils.java │ │ ├── ViewChangesTracker.java │ │ ├── FileUtil.java │ │ ├── AirMapOverlayManager.java │ │ └── AirMapCircleManager.java └── build.gradle ├── .prettierrc ├── .releaserc.json ├── SECURITY.md ├── docs ├── examples-setup.md ├── overlay.md ├── callout.md └── heatmap.md ├── tsconfig.json ├── react-native-maps.podspec ├── .gitignore ├── react-native-google-maps.podspec ├── LICENSE ├── CONTRIBUTING.md └── package.json /example/.ruby-version: -------------------------------------------------------------------------------- 1 | 2.7.5 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | -------------------------------------------------------------------------------- /example/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "displayName": "example" 4 | } -------------------------------------------------------------------------------- /src/sharedTypesInternal.ts: -------------------------------------------------------------------------------- 1 | export type Modify = Omit & R; 2 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "include": ["src"] 4 | } 5 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {extends: ['@commitlint/config-conventional']}; 2 | -------------------------------------------------------------------------------- /example/.bundle/config: -------------------------------------------------------------------------------- 1 | BUNDLE_PATH: "vendor/bundle" 2 | BUNDLE_FORCE_RUBY_PLATFORM: 1 3 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn commitlint --edit "$1" 5 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native-community", 3 | "ignorePatterns": "lib" // ts outdir 4 | } 5 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:metro-react-native-babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /src/MapView.web.ts: -------------------------------------------------------------------------------- 1 | //@ts-ignore 2 | export {default} from 'react-native-web/dist/modules/UnimplementedView'; 3 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint 5 | yarn tscheck 6 | yarn test 7 | -------------------------------------------------------------------------------- /src/ProviderConstants.ts: -------------------------------------------------------------------------------- 1 | export const PROVIDER_DEFAULT = undefined; 2 | export const PROVIDER_GOOGLE = 'google'; 3 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | /.github/workflows/ @Simon-TechForm @christopherdro 2 | /.github/CODEOWNERS @Simon-TechForm @christopherdro -------------------------------------------------------------------------------- /example/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/debug.keystore -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /example/src/examples/assets/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/src/examples/assets/car.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNMaps Example 3 | 4 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapOverlayManager.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AIRMapOverlayManager : RCTViewManager 4 | 5 | @end 6 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /example/src/examples/assets/flag-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/src/examples/assets/flag-blue.png -------------------------------------------------------------------------------- /example/src/examples/assets/flag-pink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/src/examples/assets/flag-pink.png -------------------------------------------------------------------------------- /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/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSameLine": true, 4 | "bracketSpacing": false, 5 | "singleQuote": true, 6 | "trailingComma": "all" 7 | } 8 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby '2.7.5' 5 | 6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2' 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rivafarabi/react-native-maps/master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /example/react-native.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | dependencies: { 5 | 'react-native-maps': { 6 | root: path.join(__dirname, '..'), 7 | }, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './src/App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapOverlayRenderer.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AIRMapOverlayRenderer : MKOverlayRenderer 4 | 5 | @property (nonatomic, assign) NSInteger rotation; 6 | @property (nonatomic, assign) CGFloat transparency; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /example/ios/example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : UIResponder 5 | 6 | @property (nonatomic, strong) UIWindow *window; 7 | 8 | @end 9 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCoordinate.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import "AIRMapCoordinate.h" 7 | 8 | 9 | @implementation AIRMapCoordinate { 10 | 11 | } 12 | @end -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface AIRMapCalloutManager : RCTViewManager 10 | @end -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCircleManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface AIRMapCircleManager : RCTViewManager 10 | @end -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTileOverlay.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTileOverlay.h 3 | // Pods 4 | // 5 | // Created by Peter Zavadsky on 04/12/2017. 6 | // 7 | 8 | #import 9 | 10 | @interface AIRMapLocalTileOverlay : MKTileOverlay 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolygonManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface AIRMapPolygonManager : RCTViewManager 10 | @end -------------------------------------------------------------------------------- /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/ios/example/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapHeatmapManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapHeatmapManager.h 3 | // 4 | // Created by David Cako on 29 April 2018. 5 | // 6 | 7 | #import 8 | 9 | @interface AIRGoogleMapHeatmapManager : RCTViewManager 10 | 11 | @end -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolylineManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | 9 | @interface AIRMapPolylineManager : RCTViewManager 10 | @end -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSMarker.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSMarker.m 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/5/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import "AIRGMSMarker.h" 11 | 12 | @implementation AIRGMSMarker 13 | 14 | @end 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSPolygon.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSPolygon.m 3 | // AirMaps 4 | // 5 | // Created by Gerardo Pacheco 02/05/2017. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import "AIRGMSPolygon.h" 11 | 12 | @implementation AIRGMSPolygon 13 | 14 | @end 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSPolyline.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSPolyline.m 3 | // AirMaps 4 | // 5 | // Created by Guilherme Pontes 04/05/2017. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import "AIRGMSPolyline.h" 11 | 12 | @implementation AIRGMSPolyline 13 | @end 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapOverlayManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapOverlayManager.h 3 | // Created by Taro Matsuzawa on 3/5/17. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | @interface AIRGoogleMapOverlayManager : RCTViewManager 10 | @end 11 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutSubviewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapCalloutSubviewManager.h 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface AIRMapCalloutSubviewManager : RCTViewManager 12 | 13 | @end 14 | 15 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapWMSTileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapWMSTileManager.h 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @interface AIRMapWMSTileManager : RCTViewManager 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapUrlTileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapUrlTileManager.h 3 | // AirMaps 4 | // 5 | // Created by cascadian on 3/19/16. 6 | // Copyright © 2016. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @interface AIRMapUrlTileManager : RCTViewManager 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCircleManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCircleManager.h 3 | // 4 | // Created by Nick Italiano on 10/24/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | 11 | @interface AIRGoogleMapCircleManager : RCTViewManager 12 | 13 | @end 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolygonManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolylgoneManager.h 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | 11 | @interface AIRGoogleMapPolygonManager : RCTViewManager 12 | 13 | @end 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolylineManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolylineManager.h 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | 11 | @interface AIRGoogleMapPolylineManager : RCTViewManager 12 | 13 | @end 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /example/ios/example.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapMarkerManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapMarkerManager.h 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/2/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | 12 | @interface AIRGoogleMapMarkerManager : RCTViewManager 13 | 14 | @end 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTileManager.h 3 | // AirMaps 4 | // 5 | // Created by Peter Zavadsky on 01/12/2017. 6 | // Copyright © 2017 Christopher. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AIRMapLocalTileManager : RCTViewManager 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutManager.h 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/6/16. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | 13 | @interface AIRGoogleMapCalloutManager : RCTViewManager 14 | 15 | @end 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapUrlTileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapURLTileManager.h 3 | // Created by Nick Italiano on 11/5/16. 4 | // 5 | 6 | #ifdef HAVE_GOOGLE_MAPS 7 | 8 | #import 9 | #import 10 | 11 | @interface AIRGoogleMapUrlTileManager : RCTViewManager 12 | @end 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutSubview.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapCalloutSubview.h 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface AIRMapCalloutSubview : UIView 13 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutSubview.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapCalloutSubview.m 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #import "AIRMapCalloutSubview.h" 10 | #import 11 | #import 12 | #import 13 | 14 | @implementation AIRMapCalloutSubview 15 | @end 16 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCoordinate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | @interface AIRMapCoordinate : NSObject 10 | 11 | @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 12 | 13 | @end -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapManager.h 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/1/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | 12 | @interface AIRGoogleMapManager : RCTViewManager 13 | @property (nonatomic) BOOL isGesture; 14 | 15 | @end 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutSubviewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutSubviewManager.h 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | 13 | @interface AIRGoogleMapCalloutSubviewManager : RCTViewManager 14 | 15 | @end 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRDummyView.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRDummyView.h 3 | // AirMapsExplorer 4 | // 5 | // Created by Gil Birman on 10/4/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | 12 | 13 | @interface AIRDummyView : UIView 14 | @property (nonatomic, weak) UIView *view; 15 | - (instancetype)initWithView:(UIView*)view; 16 | @end 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@semantic-release/commit-analyzer", 4 | "@semantic-release/release-notes-generator", 5 | [ 6 | "@semantic-release/changelog", 7 | { 8 | "changelogTitle": "# Changelog" 9 | } 10 | ], 11 | "@semantic-release/npm", 12 | "@semantic-release/git", 13 | "@semantic-release/github" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapWMSTileManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapWMSTileManager.h 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | #import 13 | 14 | @interface AIRGoogleMapWMSTileManager : RCTViewManager 15 | @end 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutSubview.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutSubview.h 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | #import 13 | 14 | @interface AIRGoogleMapCalloutSubview : UIView 15 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 16 | @end 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutSubview.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutSubview.m 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import "AIRGoogleMapCalloutSubview.h" 12 | #import 13 | #import 14 | #import 15 | 16 | @implementation AIRGoogleMapCalloutSubview 17 | @end 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ImageReadable.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | 4 | import android.graphics.Bitmap; 5 | 6 | import com.google.android.gms.maps.model.BitmapDescriptor; 7 | 8 | public interface ImageReadable { 9 | 10 | public void setIconBitmap(Bitmap bitmap); 11 | 12 | public void setIconBitmapDescriptor(BitmapDescriptor bitmapDescriptor); 13 | 14 | public void update(); 15 | } 16 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapUrlTileCachedOverlay.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapUrlTileCachedOverlay.h 3 | // Airmaps 4 | // 5 | // Created by Markus Suomi on 10/04/2021. 6 | // 7 | 8 | #import 9 | 10 | @interface AIRMapUrlTileCachedOverlay : MKTileOverlay 11 | 12 | @property NSInteger maximumNativeZ; 13 | @property (nonatomic, copy) NSURL *tileCachePath; 14 | @property NSInteger tileCacheMaxAge; 15 | @property BOOL offlineMode; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapSnapshot.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapSnapshot.h 3 | // AirMaps 4 | // 5 | // Created by Hein Rutjes on 26/09/16. 6 | // Copyright © 2016 Christopher. All rights reserved. 7 | // 8 | 9 | #ifndef AIRMapSnapshot_h 10 | #define AIRMapSnapshot_h 11 | 12 | @protocol AIRMapSnapshot 13 | @optional 14 | - (void) drawToSnapshot:(MKMapSnapshot *) snapshot context:(CGContextRef) context; 15 | @end 16 | 17 | #endif /* AIRMapSnapshot_h */ 18 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRDummyView.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRDummyView.m 3 | // AirMapsExplorer 4 | // 5 | // Created by Gil Birman on 10/4/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | #import "AIRDummyView.h" 12 | 13 | @implementation AIRDummyView 14 | - (instancetype)initWithView:(UIView*)view 15 | { 16 | if ((self = [super init])) { 17 | self.view = view; 18 | } 19 | return self; 20 | } 21 | @end 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSPolygon.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSPolygon.h 3 | // AirMaps 4 | // 5 | // Created by Gerardo Pacheco 02/05/2017. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | #import 12 | 13 | @class AIRGoogleMapPolygon; 14 | 15 | @interface AIRGMSPolygon : GMSPolygon 16 | @property (nonatomic, strong) NSString *identifier; 17 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/RCTConvert+GMSMapViewType.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTConvert+GMSMapViewType.h 3 | // 4 | // Created by Nick Italiano on 10/23/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface RCTConvert (GMSMapViewType) 14 | + (GMSCameraPosition*)GMSCameraPositionWithDefaults:(id)json existingCamera:(GMSCameraPosition*)existingCamera; 15 | @end 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapMarkerManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AIRMapMarkerManager : RCTViewManager 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSPolyline.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSPolyline.h 3 | // AirMaps 4 | // 5 | // Created by Guilherme Pontes 04/05/2017. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | #import 12 | 13 | @class AIRGoogleMapPolyline; 14 | 15 | @interface AIRGMSPolyline : GMSPolyline 16 | @property (nonatomic, strong) NSString *identifier; 17 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 18 | @end 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.x.x | :white_check_mark: | 8 | 9 | ## Reporting a Vulnerability 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** Instead, please report (suspected) security vulnerabilities to rnmapsci@gmail.com. If the issue is confirmed, we will release a patch as soon as possible depending on the complexity of the vulnerability. -------------------------------------------------------------------------------- /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 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCallout.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | 10 | @interface AIRMapCallout : RCTView 11 | 12 | @property (nonatomic, assign) BOOL tooltip; 13 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 14 | @property (nonatomic, assign) BOOL alphaHitTest; 15 | 16 | - (BOOL) isPointInside:(CGPoint)pointInCallout; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /docs/examples-setup.md: -------------------------------------------------------------------------------- 1 | # Examples Setup 2 | 3 | * Clone or download the repository. 4 | * From the root of the project run `yarn bootstrap` 5 | * `cd example` 6 | * `yarn android` or `yarn ios` 7 | 8 | **Please note that if you are trying out Android or using Google Maps on iOS, it's very likely that you will have to add your own API key for Google Maps to work. Check out the [Installation Instructions](./installation.md) to see how this is done, and make sure to run `yarn bootstrap` again after adding your personal API key.** 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCallout.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCallout.h 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/6/16. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | #import 13 | 14 | @interface AIRGoogleMapCallout : UIView 15 | @property (nonatomic, assign) BOOL tooltip; 16 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 17 | @property (nonatomic, assign) BOOL alphaHitTest; 18 | 19 | - (BOOL) isPointInside:(CGPoint)pointInCallout; 20 | 21 | @end 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapHeatmap.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapHeatmap.h 3 | // 4 | // Created by David Cako on 29 April 2018. 5 | // 6 | 7 | #import 8 | 9 | @interface AIRGoogleMapHeatmap : UIView 10 | 11 | @property (nonatomic, strong) GMUHeatmapTileLayer *heatmap; 12 | @property (nonatomic, strong) NSMutableArray *points; 13 | @property (nonatomic, assign) NSUInteger radius; 14 | @property (nonatomic, assign) float opacity; 15 | @property (nonatomic, assign) GMUGradient *gradient; 16 | 17 | @end -------------------------------------------------------------------------------- /example/babel.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const pak = require('../package.json'); 3 | 4 | module.exports = { 5 | presets: [ 6 | ['module:metro-react-native-babel-preset'], 7 | ['@babel/preset-typescript', {allowDeclareFields: true}], // to allow use of declare context 8 | ], 9 | plugins: [ 10 | [ 11 | 'module-resolver', 12 | { 13 | extensions: ['.tsx', '.ts', '.js', '.json'], 14 | alias: { 15 | [pak.name]: path.join(__dirname, '..', pak.source), 16 | }, 17 | }, 18 | ], 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/AirMapFeature.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.content.Context; 4 | 5 | import com.facebook.react.views.view.ReactViewGroup; 6 | import com.google.android.gms.maps.GoogleMap; 7 | 8 | public abstract class AirMapFeature extends ReactViewGroup { 9 | public AirMapFeature(Context context) { 10 | super(context); 11 | } 12 | 13 | public abstract void addToMap(GoogleMap map); 14 | 15 | public abstract void removeFromMap(GoogleMap map); 16 | 17 | public abstract Object getFeature(); 18 | } 19 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutSubviewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapCalloutSubviewManager.m 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #import "AIRMapCalloutSubviewManager.h" 10 | #import "AIRMapCalloutSubview.h" 11 | #import 12 | 13 | @implementation AIRMapCalloutSubviewManager 14 | RCT_EXPORT_MODULE() 15 | 16 | - (UIView *)view 17 | { 18 | AIRMapCalloutSubview *calloutSubview = [AIRMapCalloutSubview new]; 19 | return calloutSubview; 20 | } 21 | 22 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapUrlTile.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapURLTile.h 3 | // Created by Nick Italiano on 11/5/16. 4 | // 5 | 6 | #ifdef HAVE_GOOGLE_MAPS 7 | 8 | #import 9 | #import 10 | 11 | @interface AIRGoogleMapUrlTile : UIView 12 | 13 | @property (nonatomic, strong) GMSURLTileLayer *tileLayer; 14 | @property (nonatomic, assign) NSString *urlTemplate; 15 | @property (nonatomic, assign) int zIndex; 16 | @property NSInteger *maximumZ; 17 | @property NSInteger *minimumZ; 18 | @property BOOL flipY; 19 | 20 | @end 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /ios/AirMaps/RCTConvert+AirMap.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | #import 9 | 10 | @interface RCTConvert (AirMap) 11 | 12 | + (MKCoordinateSpan)MKCoordinateSpan:(id)json; 13 | + (MKCoordinateRegion)MKCoordinateRegion:(id)json; 14 | + (MKMapCamera*)MKMapCamera:(id)json; 15 | + (MKMapCamera*)MKMapCameraWithDefaults:(id)json existingCamera:(MKMapCamera*)camera; 16 | + (MKMapType)MKMapType:(id)json; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "react-native-maps": ["./src/index"] 6 | }, 7 | "allowJs": true, 8 | "allowSyntheticDefaultImports": true, 9 | "declaration": true, 10 | "esModuleInterop": true, 11 | "isolatedModules": true, 12 | "jsx": "react-native", 13 | "lib": ["es2017"], 14 | "module": "commonjs", 15 | "moduleResolution": "node", 16 | "outDir": "lib", 17 | "resolveJsonModule": true, 18 | "skipLibCheck": true, 19 | "strict": true, 20 | "target": "esnext" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/AirMapCallout.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.content.Context; 4 | 5 | import com.facebook.react.views.view.ReactViewGroup; 6 | 7 | public class AirMapCallout extends ReactViewGroup { 8 | private boolean tooltip = false; 9 | public int width; 10 | public int height; 11 | 12 | public AirMapCallout(Context context) { 13 | super(context); 14 | } 15 | 16 | public void setTooltip(boolean tooltip) { 17 | this.tooltip = tooltip; 18 | } 19 | 20 | public boolean getTooltip() { 21 | return this.tooltip; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/src/examples/Geojson.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import MapView, {Geojson} from 'react-native-maps'; 3 | import {StyleSheet} from 'react-native'; 4 | const myPlace: any = { 5 | type: 'FeatureCollection', 6 | features: [ 7 | { 8 | type: 'Feature', 9 | properties: {}, 10 | geometry: { 11 | type: 'Point', 12 | coordinates: [64.165329, 48.844287], 13 | }, 14 | }, 15 | ], 16 | }; 17 | 18 | const GeojsonMap = () => ( 19 | 20 | 21 | 22 | ); 23 | 24 | export default GeojsonMap; 25 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Run stale action' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/stale@v5 11 | with: 12 | stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' 13 | stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.' 14 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/AirMapLiteManager.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import com.facebook.react.bridge.ReactApplicationContext; 4 | import com.google.android.gms.maps.GoogleMapOptions; 5 | 6 | public class AirMapLiteManager extends AirMapManager { 7 | 8 | private static final String REACT_CLASS = "AIRMapLite"; 9 | 10 | @Override 11 | public String getName() { 12 | return REACT_CLASS; 13 | } 14 | 15 | public AirMapLiteManager(ReactApplicationContext context) { 16 | super(context); 17 | this.googleMapOptions = new GoogleMapOptions().liteMode(true); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGMSMarker.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGMSMarker.h 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/5/16. 6 | // 7 | 8 | #ifdef HAVE_GOOGLE_MAPS 9 | 10 | #import 11 | #import 12 | 13 | @class AIRGoogleMapMarker; 14 | 15 | @interface AIRGMSMarker : GMSMarker 16 | @property (nonatomic, strong) NSString *identifier; 17 | @property (nonatomic, weak) AIRGoogleMapMarker *fakeMarker; 18 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 19 | @end 20 | 21 | 22 | @protocol AIRGMSMarkerDelegate 23 | @required 24 | -(void)didTapMarker; 25 | @end 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "start": "react-native start", 9 | "test": "jest", 10 | "lint": "eslint ." 11 | }, 12 | "dependencies": { 13 | "react": "18.0.0", 14 | "react-native": "0.69.2" 15 | }, 16 | "devDependencies": { 17 | "@babel/core": "^7.12.9", 18 | "@babel/preset-typescript": "^7.18.6", 19 | "@babel/runtime": "^7.12.5", 20 | "babel-plugin-module-resolver": "^4.1.0", 21 | "metro-react-native-babel-preset": "^0.70.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRWeakMapReference.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRWeakMapReference.h" 11 | 12 | @implementation AIRWeakMapReference 13 | 14 | 15 | - (instancetype)initWithMapView:(AIRMap *)mapView { 16 | self = [super init]; 17 | if (self) { 18 | _mapView = mapView; 19 | } 20 | return self; 21 | } 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /react-native-maps.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 = "react-native-maps" 7 | s.version = package['version'] 8 | s.summary = package["description"] 9 | s.authors = package["author"] 10 | s.homepage = package["homepage"] 11 | s.license = package["license"] 12 | s.platform = :ios, "11.0" 13 | 14 | s.source = { :git => "https://github.com/react-native-maps/react-native-maps.git", :tag=> "v#{s.version}" } 15 | s.source_files = "ios/AirMaps/**/*.{h,m}" 16 | 17 | s.dependency 'React-Core' 18 | end 19 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapOverlayManager.m: -------------------------------------------------------------------------------- 1 | #import "AIRMapOverlayManager.h" 2 | 3 | #import 4 | #import 5 | #import 6 | #import "AIRMapOverlay.h" 7 | 8 | @interface AIRMapOverlayManager () 9 | 10 | @end 11 | 12 | @implementation AIRMapOverlayManager 13 | 14 | RCT_EXPORT_MODULE() 15 | 16 | - (UIView *)view 17 | { 18 | AIRMapOverlay *overlay = [AIRMapOverlay new]; 19 | overlay.bridge = self.bridge; 20 | return overlay; 21 | } 22 | 23 | RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray) 24 | RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString) 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRWeakTimerReference.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface AIRWeakTimerReference : NSObject 15 | 16 | - (instancetype)initWithTarget:(id)target andSelector:(SEL)selector; 17 | - (void)timerDidFire:(NSTimer *)timer; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapOverlayManager.m: -------------------------------------------------------------------------------- 1 | #import "AIRGoogleMapOverlayManager.h" 2 | #import "AIRGoogleMapOverlay.h" 3 | 4 | @interface AIRGoogleMapOverlayManager() 5 | 6 | @end 7 | 8 | @implementation AIRGoogleMapOverlayManager 9 | 10 | RCT_EXPORT_MODULE() 11 | 12 | - (UIView *)view 13 | { 14 | AIRGoogleMapOverlay *overlay = [AIRGoogleMapOverlay new]; 15 | overlay.bridge = self.bridge; 16 | return overlay; 17 | } 18 | 19 | RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray) 20 | RCT_REMAP_VIEW_PROPERTY(bearing, bearing, double) 21 | RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString) 22 | RCT_REMAP_VIEW_PROPERTY(opacity, opacity, CGFloat) 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'example' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings) 3 | include ':app' 4 | includeBuild('../node_modules/react-native-gradle-plugin') 5 | 6 | if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") { 7 | include(":ReactAndroid") 8 | project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid') 9 | include(":ReactAndroid:hermes-engine") 10 | project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine') 11 | } 12 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutSubviewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutSubviewManager.m 3 | // AirMaps 4 | // 5 | // Created by Denis Oblogin on 10/8/18. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import "AIRGoogleMapCalloutSubviewManager.h" 12 | #import "AIRGoogleMapCalloutSubview.h" 13 | #import 14 | 15 | @implementation AIRGoogleMapCalloutSubviewManager 16 | RCT_EXPORT_MODULE() 17 | 18 | - (UIView *)view 19 | { 20 | AIRGoogleMapCalloutSubview *calloutSubview = [AIRGoogleMapCalloutSubview new]; 21 | return calloutSubview; 22 | } 23 | 24 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 25 | 26 | @end 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolylineRenderer.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapPolylineRenderer.h 3 | // mapDemo 4 | // 5 | // Created by IjzerenHein on 13-11-21. 6 | // Copyright (c) 2017 IjzerenHein. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AIRMapPolylineRenderer : MKOverlayPathRenderer 12 | 13 | -(id)initWithOverlay:(id)overlay polyline:(MKPolyline*)polyline; 14 | -(id)initWithSnapshot:(MKMapSnapshot*)snapshot overlay:(id)overlay polyline:(MKPolyline*)polyline; 15 | -(void)drawWithZoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context; 16 | 17 | @property (nonatomic, strong) NSArray *strokeColors; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRWeakMapReference.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import "AIRMap.h" 12 | 13 | NS_ASSUME_NONNULL_BEGIN 14 | 15 | @interface AIRWeakMapReference : NSObject 16 | 17 | @property (nonatomic, weak) AIRMap *mapView; 18 | 19 | - (instancetype)initWithMapView:(AIRMap *)mapView; 20 | 21 | 22 | @end 23 | 24 | NS_ASSUME_NONNULL_END 25 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCalloutManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCalloutManager.m 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/6/16. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import "AIRGoogleMapCalloutManager.h" 12 | #import "AIRGoogleMapCallout.h" 13 | #import 14 | 15 | @implementation AIRGoogleMapCalloutManager 16 | RCT_EXPORT_MODULE() 17 | 18 | - (UIView *)view 19 | { 20 | AIRGoogleMapCallout *callout = [AIRGoogleMapCallout new]; 21 | return callout; 22 | } 23 | 24 | RCT_EXPORT_VIEW_PROPERTY(tooltip, BOOL) 25 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 26 | RCT_EXPORT_VIEW_PROPERTY(alphaHitTest, BOOL) 27 | 28 | @end 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCircle.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapsCircle.h 3 | // 4 | // Created by Nick Italiano on 10/24/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | #import "AIRMapCoordinate.h" 11 | 12 | @interface AIRGoogleMapCircle : UIView 13 | 14 | @property (nonatomic, strong) GMSCircle *circle; 15 | @property (nonatomic, assign) double radius; 16 | @property (nonatomic, assign) CLLocationCoordinate2D centerCoordinate; 17 | @property (nonatomic, strong) UIColor *strokeColor; 18 | @property (nonatomic, assign) double strokeWidth; 19 | @property (nonatomic, strong) UIColor *fillColor; 20 | @property (nonatomic, assign) int zIndex; 21 | 22 | @end 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /.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 | Pods/ 25 | AirMapsExplorer.xcworkspace/ 26 | 27 | # Android/IntelliJ 28 | # 29 | build/ 30 | .idea 31 | .gradle 32 | local.properties 33 | *.iml 34 | 35 | # node.js 36 | # 37 | node_modules/ 38 | npm-debug.log 39 | yarn-error.log 40 | 41 | # Bundle artifact 42 | *.jsbundle 43 | 44 | # VSCode workspace settings 45 | .vscode 46 | 47 | # ts outDir 48 | lib/ 49 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapURLTileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapURLTileManager.m 3 | // Created by Nick Italiano on 11/5/16. 4 | // 5 | 6 | #ifdef HAVE_GOOGLE_MAPS 7 | 8 | #import "AIRGoogleMapUrlTileManager.h" 9 | #import "AIRGoogleMapUrlTile.h" 10 | 11 | @interface AIRGoogleMapUrlTileManager() 12 | 13 | @end 14 | 15 | @implementation AIRGoogleMapUrlTileManager 16 | 17 | RCT_EXPORT_MODULE() 18 | 19 | - (UIView *)view 20 | { 21 | AIRGoogleMapUrlTile *tileLayer = [AIRGoogleMapUrlTile new]; 22 | return tileLayer; 23 | } 24 | 25 | RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) 26 | RCT_EXPORT_VIEW_PROPERTY(zIndex, int) 27 | RCT_EXPORT_VIEW_PROPERTY(maximumZ, NSInteger) 28 | RCT_EXPORT_VIEW_PROPERTY(minimumZ, NSInteger) 29 | RCT_EXPORT_VIEW_PROPERTY(flipY, BOOL) 30 | 31 | @end 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapHeatmapManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapHeatmapManager.m 3 | // 4 | // Created by David Cako on 29 April 2018. 5 | // 6 | 7 | #import "AIRGoogleMapHeatmapManager.h" 8 | #import "AIRGoogleMapHeatmap.h" 9 | #import "AIRGoogleMap.h" 10 | #import 11 | #import 12 | 13 | @interface AIRGoogleMapHeatmapManager() 14 | 15 | @end 16 | 17 | @implementation AIRGoogleMapHeatmapManager 18 | 19 | RCT_EXPORT_MODULE() 20 | 21 | - (UIView *)view 22 | { 23 | AIRGoogleMapHeatmap *heatmap = [AIRGoogleMapHeatmap new]; 24 | return heatmap; 25 | } 26 | 27 | RCT_EXPORT_VIEW_PROPERTY(points, NSArray) 28 | RCT_EXPORT_VIEW_PROPERTY(radius, NSUInteger) 29 | RCT_EXPORT_VIEW_PROPERTY(opacity, float) 30 | RCT_EXPORT_VIEW_PROPERTY(gradient, NSDictionary *) 31 | 32 | @end -------------------------------------------------------------------------------- /example/src/examples/CustomOverlayXMarksTheSpot.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View} from 'react-native'; 3 | import {Polygon, Polyline, Marker} from 'react-native-maps'; 4 | 5 | class XMarksTheSpot extends React.Component { 6 | render() { 7 | return ( 8 | 9 | 14 | 17 | 20 | 21 | 22 | ); 23 | } 24 | } 25 | 26 | export default XMarksTheSpot; 27 | -------------------------------------------------------------------------------- /example/ios/exampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | name: Push 2 | concurrency: 3 | group: push 4 | on: 5 | push: 6 | branches: 7 | - master 8 | - beta 9 | jobs: 10 | release: 11 | runs-on: ubuntu-latest 12 | env: 13 | HUSKY: 0 14 | steps: 15 | - name: Check out repository code 16 | uses: actions/checkout@v3 17 | with: 18 | persist-credentials: false 19 | 20 | - name: Setup node 21 | uses: actions/setup-node@v3 22 | with: 23 | node-version: 'lts/*' 24 | cache: yarn 25 | 26 | - name: Install dependencies 27 | run: yarn --frozen-lockfile 28 | 29 | - name: Build 30 | run: yarn build 31 | 32 | - name: Release 33 | env: 34 | GITHUB_TOKEN: ${{secrets.CI_GITHUB_TOKEN}} 35 | NPM_TOKEN: ${{secrets.NPM_TOKEN}} 36 | run: yarn release 37 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapOverlay.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapOverlay.h 3 | // 4 | // Created by Taro Matsuzawa on 5/3/17. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | #import 11 | #import 12 | #import "AIRMapCoordinate.h" 13 | #import "AIRGoogleMap.h" 14 | 15 | @interface AIRGoogleMapOverlay : UIView 16 | 17 | @property (nonatomic, strong) GMSGroundOverlay *overlay; 18 | @property (nonatomic, copy) NSString *imageSrc; 19 | @property (nonatomic, strong, readonly) UIImage *overlayImage; 20 | @property (nonatomic, copy) NSArray *boundsRect; 21 | @property (nonatomic, assign) CGFloat opacity; 22 | @property (nonatomic, readonly) GMSCoordinateBounds *overlayBounds; 23 | @property (nonatomic, readonly) double bearing; 24 | 25 | @property (nonatomic, weak) RCTBridge *bridge; 26 | 27 | @end 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ViewAttacherGroup.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.content.Context; 4 | import android.graphics.Rect; 5 | 6 | import com.facebook.react.views.view.ReactViewGroup; 7 | 8 | public class ViewAttacherGroup extends ReactViewGroup { 9 | 10 | public ViewAttacherGroup(Context context) { 11 | super(context); 12 | 13 | this.setWillNotDraw(true); 14 | this.setVisibility(VISIBLE); 15 | this.setAlpha(0.0f); 16 | this.setRemoveClippedSubviews(false); 17 | this.setClipBounds(new Rect(0, 0, 0, 0)); 18 | this.setOverflow("hidden"); // Change to ViewProps.HIDDEN until RN 0.57 is base 19 | } 20 | 21 | // This should make it more performant, avoid trying to hard to overlap layers with opacity. 22 | @Override 23 | public boolean hasOverlappingRendering() { 24 | return false; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapWMSTileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapWMSTileManager.m 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import "AIRGoogleMapWMSTileManager.h" 12 | #import "AIRGoogleMapWMSTile.h" 13 | 14 | @interface AIRGoogleMapWMSTileManager() 15 | 16 | @end 17 | 18 | @implementation AIRGoogleMapWMSTileManager 19 | 20 | RCT_EXPORT_MODULE() 21 | 22 | - (UIView *)view 23 | { 24 | AIRGoogleMapWMSTile *tileLayer = [AIRGoogleMapWMSTile new]; 25 | return tileLayer; 26 | } 27 | 28 | RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) 29 | RCT_EXPORT_VIEW_PROPERTY(zIndex, int) 30 | RCT_EXPORT_VIEW_PROPERTY(maximumZ, int) 31 | RCT_EXPORT_VIEW_PROPERTY(minimumZ, int) 32 | RCT_EXPORT_VIEW_PROPERTY(tileSize, int) 33 | RCT_EXPORT_VIEW_PROPERTY(opacity, float) 34 | 35 | @end 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTileManager.m 3 | // AirMaps 4 | // 5 | // Created by Peter Zavadsky on 01/12/2017. 6 | // Copyright © 2017 Christopher. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import "AIRMapMarker.h" 16 | #import "AIRMapLocalTile.h" 17 | 18 | #import "AIRMapLocalTileManager.h" 19 | 20 | @interface AIRMapLocalTileManager() 21 | 22 | @end 23 | 24 | @implementation AIRMapLocalTileManager 25 | 26 | 27 | RCT_EXPORT_MODULE() 28 | 29 | - (UIView *)view 30 | { 31 | AIRMapLocalTile *tile = [AIRMapLocalTile new]; 32 | return tile; 33 | } 34 | 35 | RCT_EXPORT_VIEW_PROPERTY(pathTemplate, NSString) 36 | RCT_EXPORT_VIEW_PROPERTY(tileSize, CGFloat) 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapWMSTile.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapWMSTile.h 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import 12 | #import 13 | 14 | #import 15 | #import 16 | #import "AIRMapCoordinate.h" 17 | #import "AIRMap.h" 18 | #import "RCTConvert+AirMap.h" 19 | #import "AIRMapUrlTile.h" 20 | #import "AIRMapUrlTileCachedOverlay.h" 21 | 22 | @interface AIRMapWMSTile : AIRMapUrlTile 23 | @end 24 | 25 | @interface AIRMapWMSTileOverlay : MKTileOverlay 26 | @end 27 | 28 | @interface AIRMapWMSTileCachedOverlay : AIRMapUrlTileCachedOverlay 29 | @end 30 | 31 | @interface AIRMapWMSTileHelper : NSObject 32 | 33 | + (NSURL *)URLForTilePath:(MKTileOverlayPath)path withURLTemplate:(NSString *)URLTemplate withTileSize:(NSInteger)tileSize; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ImageUtil.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | 4 | import android.graphics.Bitmap; 5 | import android.graphics.BitmapFactory; 6 | import android.util.Base64; 7 | 8 | import java.io.ByteArrayOutputStream; 9 | 10 | public class ImageUtil { 11 | public static Bitmap convert(String base64Str) throws IllegalArgumentException { 12 | byte[] decodedBytes = Base64.decode( 13 | base64Str.substring(base64Str.indexOf(",") + 1), 14 | Base64.DEFAULT 15 | ); 16 | 17 | return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length); 18 | } 19 | 20 | public static String convert(Bitmap bitmap) { 21 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 22 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); 23 | 24 | return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT); 25 | } 26 | 27 | } -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCircleManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCircleManager.m 3 | // 4 | // Created by Nick Italiano on 10/24/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import "AIRGoogleMapCircleManager.h" 10 | #import "AIRGoogleMapCircle.h" 11 | #import 12 | #import 13 | 14 | @interface AIRGoogleMapCircleManager() 15 | 16 | @end 17 | 18 | @implementation AIRGoogleMapCircleManager 19 | 20 | RCT_EXPORT_MODULE() 21 | 22 | - (UIView *)view 23 | { 24 | AIRGoogleMapCircle *circle = [AIRGoogleMapCircle new]; 25 | return circle; 26 | } 27 | 28 | RCT_EXPORT_VIEW_PROPERTY(radius, double) 29 | RCT_REMAP_VIEW_PROPERTY(center, centerCoordinate, CLLocationCoordinate2D) 30 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 31 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) 32 | RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) 33 | RCT_EXPORT_VIEW_PROPERTY(zIndex, int) 34 | 35 | @end 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCallout.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import "AIRMapCallout.h" 7 | 8 | 9 | @implementation AIRMapCallout 10 | 11 | - (BOOL) isPointInside:(CGPoint)pointInCallout { 12 | if (!self.alphaHitTest) 13 | return TRUE; 14 | CGFloat alpha = [self alphaOfPoint:pointInCallout]; 15 | return alpha >= 0.01; 16 | } 17 | 18 | - (CGFloat) alphaOfPoint:(CGPoint)point { 19 | unsigned char pixel[4] = {0}; 20 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 21 | CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast); 22 | CGContextTranslateCTM(context, -point.x, -point.y); 23 | [self.layer renderInContext:context]; 24 | CGContextRelease(context); 25 | CGColorSpaceRelease(colorSpace); 26 | return pixel[3]/255.0; 27 | } 28 | 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /.github/workflows/pullRequest.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened # default 7 | - reopened # default 8 | - synchronize # default 9 | - edited # used to check pr title 10 | branches: 11 | - master 12 | - beta 13 | 14 | jobs: 15 | lint-test: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Check out repository code 20 | uses: actions/checkout@v3 21 | 22 | - name: Setup node 23 | uses: actions/setup-node@v3 24 | with: 25 | node-version: 'lts/*' 26 | cache: yarn 27 | 28 | - name: Install dependencies 29 | run: yarn --frozen-lockfile 30 | 31 | - name: Lint PR title 32 | run: echo "${{ github.event.pull_request.title }}" | yarn commitlint 33 | 34 | - name: Lint 35 | run: yarn lint 36 | 37 | - name: TsCheck 38 | run: yarn tscheck 39 | 40 | - name: Test 41 | run: yarn test 42 | -------------------------------------------------------------------------------- /react-native-google-maps.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 = "react-native-google-maps" 7 | s.version = package['version'] 8 | s.summary = package["description"] 9 | s.authors = package["author"] 10 | s.homepage = package["homepage"] 11 | s.license = package["license"] 12 | s.platform = :ios, "13.0" 13 | 14 | s.source = { :git => "https://github.com/react-native-maps/react-native-maps.git", :tag=> "v#{s.version}" } 15 | s.source_files = "ios/AirGoogleMaps/**/*.{h,m}" 16 | s.compiler_flags = '-DHAVE_GOOGLE_MAPS=1', '-DHAVE_GOOGLE_MAPS_UTILS=1', '-fno-modules' 17 | s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "$(inherited) '$(PODS_ROOT)/Google-Maps-iOS-Utils/src/Heatmap' '$(PODS_ROOT)/Headers/Public/'" } 18 | 19 | s.dependency 'React-Core' 20 | s.dependency 'GoogleMaps', '7.0.0' 21 | s.dependency 'Google-Maps-iOS-Utils', '4.1.0' 22 | end 23 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapWMSTile.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapWMSTile.h 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import 12 | #import 13 | 14 | @interface WMSTileOverlay : GMSSyncTileLayer 15 | @property (nonatomic) double MapX,MapY,FULL; 16 | @property (nonatomic, strong) NSString *template; 17 | @property (nonatomic, assign) NSInteger maximumZ; 18 | @property (nonatomic, assign) NSInteger minimumZ; 19 | @end 20 | 21 | @interface AIRGoogleMapWMSTile : UIView 22 | @property (nonatomic, strong) WMSTileOverlay *tileLayer; 23 | @property (nonatomic, assign) NSString *urlTemplate; 24 | @property (nonatomic, assign) int zIndex; 25 | @property (nonatomic, assign) NSInteger maximumZ; 26 | @property (nonatomic, assign) NSInteger minimumZ; 27 | @property (nonatomic, assign) NSInteger tileSize; 28 | @property (nonatomic, assign) float opacity; 29 | @end 30 | 31 | #endif 32 | 33 | 34 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import "AIRMap.h" 12 | 13 | #define MERCATOR_RADIUS 85445659.44705395 14 | #define MERCATOR_OFFSET 268435456 15 | 16 | @interface AIRMapManager : RCTViewManager 17 | 18 | 19 | - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate 20 | zoomLevel:(double)zoomLevel 21 | animated:(BOOL)animated 22 | mapView:(AIRMap *)mapView; 23 | 24 | - (MKCoordinateRegion)coordinateRegionWithMapView:(AIRMap *)mapView 25 | centerCoordinate:(CLLocationCoordinate2D)centerCoordinate 26 | andZoomLevel:(double)zoomLevel; 27 | - (double) zoomLevel:(AIRMap *)mapView; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRWeakTimerReference.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRWeakTimerReference.h" 11 | 12 | @implementation AIRWeakTimerReference 13 | { 14 | __weak NSObject *_target; 15 | SEL _selector; 16 | } 17 | 18 | 19 | - (instancetype)initWithTarget:(id)target andSelector:(SEL)selector { 20 | self = [super init]; 21 | if (self) { 22 | _target = target; 23 | _selector = selector; 24 | } 25 | return self; 26 | } 27 | 28 | 29 | - (void)timerDidFire:(NSTimer *)timer 30 | { 31 | if(_target) 32 | { 33 | [_target performSelector:_selector withObject:timer]; 34 | } 35 | else 36 | { 37 | [timer invalidate]; 38 | } 39 | } 40 | 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapOverlayRenderer.m: -------------------------------------------------------------------------------- 1 | #import "AIRMapOverlayRenderer.h" 2 | #import "AIRMapOverlay.h" 3 | 4 | @implementation AIRMapOverlayRenderer 5 | 6 | - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { 7 | UIImage *image = [(AIRMapOverlay *)self.overlay overlayImage]; 8 | 9 | CGContextSaveGState(context); 10 | 11 | CGImageRef imageReference = image.CGImage; 12 | 13 | MKMapRect theMapRect = [self.overlay boundingMapRect]; 14 | CGRect theRect = [self rectForMapRect:theMapRect]; 15 | 16 | CGContextRotateCTM(context, M_PI); 17 | CGContextScaleCTM(context, -1.0, 1.0); 18 | CGContextTranslateCTM(context, 0.0, -theRect.size.height); 19 | CGContextAddRect(context, theRect); 20 | CGContextDrawImage(context, theRect, imageReference); 21 | 22 | CGContextRestoreGState(context); 23 | } 24 | 25 | - (BOOL)canDrawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale { 26 | return [(AIRMapOverlay *)self.overlay overlayImage] != nil; 27 | } 28 | 29 | @end 30 | 31 | -------------------------------------------------------------------------------- /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/example/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 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolygon.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolygon.h 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import 10 | #import 11 | #import "AIRGMSPolygon.h" 12 | #import "AIRMapCoordinate.h" 13 | 14 | @interface AIRGoogleMapPolygon : UIView 15 | 16 | @property (nonatomic, weak) RCTBridge *bridge; 17 | @property (nonatomic, strong) NSString *identifier; 18 | @property (nonatomic, strong) AIRGMSPolygon *polygon; 19 | @property (nonatomic, strong) NSArray *coordinates; 20 | @property (nonatomic, strong) NSArray *> *holes; 21 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 22 | 23 | @property (nonatomic, strong) UIColor *fillColor; 24 | @property (nonatomic, assign) double strokeWidth; 25 | @property (nonatomic, strong) UIColor *strokeColor; 26 | @property (nonatomic, assign) BOOL geodesic; 27 | @property (nonatomic, assign) int zIndex; 28 | @property (nonatomic, assign) BOOL tappable; 29 | 30 | @end 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCalloutManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRMapCalloutManager.h" 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import "AIRMapMarker.h" 19 | #import "AIRMapCallout.h" 20 | 21 | @interface AIRMapCalloutManager() 22 | 23 | @end 24 | 25 | @implementation AIRMapCalloutManager 26 | 27 | RCT_EXPORT_MODULE() 28 | 29 | - (UIView *)view 30 | { 31 | return [AIRMapCallout new]; 32 | } 33 | 34 | RCT_EXPORT_VIEW_PROPERTY(tooltip, BOOL) 35 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 36 | RCT_EXPORT_VIEW_PROPERTY(alphaHitTest, BOOL) 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /docs/overlay.md: -------------------------------------------------------------------------------- 1 | # `` Component API 2 | 3 | ## Props 4 | 5 | | Prop | Type | Default | Note | 6 | |---|---|---|---| 7 | | `image` | `ImageSource` | A custom image to be used as the overlay. Only required local image resources and uri (as for images located in the net) are allowed to be used. 8 | | `bounds` | `Array` | | The coordinates for the image (bottom-left corner, top-right corner). ie.```[[lat, long], [lat, long]]``` 9 | | `bearing` | `Number ` | `0` | `Google Maps API only` The bearing in degrees clockwise from north. Values outside the range [0, 360) will be normalized. 10 | | `tappable` | `Bool` | `false` | `Android only` Boolean to allow an overlay to be tappable and use the onPress function. 11 | | `opacity` | `Number` | `1.0` | `Google maps only` The opacity of the overlay. 12 | 13 | ## Events 14 | 15 | | Event Name | Returns | Notes 16 | |---|---|---| 17 | | `onPress` | | `Android only` Callback that is called when the user presses on the overlay 18 | 19 | ## Types 20 | 21 | ``` 22 | type LatLng = [ 23 | latitude: Number, 24 | longitude: Number, 25 | ] 26 | ``` 27 | 28 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTile.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTile.h 3 | // AirMaps 4 | // 5 | // Created by Peter Zavadsky on 01/12/2017. 6 | // Copyright © 2017 Christopher. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | #import "AIRMapCoordinate.h" 16 | #import "AIRMap.h" 17 | #import "RCTConvert+AirMap.h" 18 | 19 | @interface AIRMapLocalTile : MKAnnotationView 20 | 21 | @property (nonatomic, weak) AIRMap *map; 22 | 23 | @property (nonatomic, strong) MKTileOverlay *tileOverlay; 24 | @property (nonatomic, strong) MKTileOverlayRenderer *renderer; 25 | 26 | @property (nonatomic, copy) NSString *pathTemplate; 27 | @property (nonatomic, assign) CGFloat tileSize; 28 | 29 | #pragma mark MKOverlay protocol 30 | 31 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 32 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 33 | //- (BOOL)intersectsMapRect:(MKMapRect)mapRect; 34 | - (BOOL)canReplaceMapContent; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCallout.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapCallout.m 3 | // AirMaps 4 | // 5 | // Created by Gil Birman on 9/6/16. 6 | // 7 | // 8 | 9 | #ifdef HAVE_GOOGLE_MAPS 10 | 11 | #import "AIRGoogleMapCallout.h" 12 | #import 13 | #import 14 | #import 15 | 16 | @implementation AIRGoogleMapCallout 17 | 18 | - (BOOL) isPointInside:(CGPoint)pointInCallout { 19 | if (!self.alphaHitTest) 20 | return TRUE; 21 | CGFloat alpha = [self alphaOfPoint:pointInCallout]; 22 | return alpha >= 0.01; 23 | } 24 | 25 | - (CGFloat) alphaOfPoint:(CGPoint)point { 26 | unsigned char pixel[4] = {0}; 27 | CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 28 | CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 4, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast); 29 | CGContextTranslateCTM(context, -point.x, -point.y); 30 | [self.layer renderInContext:context]; 31 | CGContextRelease(context); 32 | CGColorSpaceRelease(colorSpace); 33 | return pixel[3]/255.0; 34 | } 35 | 36 | 37 | @end 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /example/ios/example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Airbnb 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /example/metro.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const escape = require('escape-string-regexp'); 3 | const exclusionList = require('metro-config/src/defaults/exclusionList'); 4 | const pak = require('../package.json'); 5 | 6 | const root = path.resolve(__dirname, '..'); 7 | 8 | const modules = Object.keys({ 9 | ...pak.peerDependencies, 10 | }); 11 | 12 | module.exports = { 13 | projectRoot: __dirname, 14 | watchFolders: [root], 15 | 16 | // We need to make sure that only one version is loaded for peerDependencies 17 | // So we block them at the root, and alias them to the versions in example's node_modules 18 | resolver: { 19 | blacklistRE: exclusionList( 20 | modules.map( 21 | m => new RegExp(`^${escape(path.join(root, 'node_modules', m))}\\/.*$`), 22 | ), 23 | ), 24 | 25 | extraNodeModules: modules.reduce((acc, name) => { 26 | acc[name] = path.join(__dirname, 'node_modules', name); 27 | return acc; 28 | }, {}), 29 | }, 30 | 31 | transformer: { 32 | getTransformOptions: async () => ({ 33 | transform: { 34 | experimentalImportSupport: false, 35 | inlineRequires: true, 36 | }, 37 | }), 38 | }, 39 | }; 40 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapOverlay.h: -------------------------------------------------------------------------------- 1 | #import "AIRMapCallout.h" 2 | 3 | #import 4 | #import 5 | 6 | #import "RCTConvert+AirMap.h" 7 | #import 8 | #import "AIRMap.h" 9 | #import "AIRMapOverlayRenderer.h" 10 | 11 | @class RCTBridge; 12 | 13 | @interface AIRMapOverlay : UIView 14 | 15 | @property (nonatomic, strong) AIRMapOverlayRenderer *renderer; 16 | @property (nonatomic, weak) AIRMap *map; 17 | @property (nonatomic, weak) RCTBridge *bridge; 18 | 19 | @property (nonatomic, strong) NSString *name; 20 | @property (nonatomic, copy) NSString *imageSrc; 21 | @property (nonatomic, strong, readonly) UIImage *overlayImage; 22 | @property (nonatomic, copy) NSArray *boundsRect; 23 | @property (nonatomic, assign) NSInteger rotation; 24 | @property (nonatomic, assign) CGFloat transparency; 25 | @property (nonatomic, assign) NSInteger zIndex; 26 | 27 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 28 | 29 | #pragma mark MKOverlay protocol 30 | 31 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 32 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 33 | - (BOOL)intersectsMapRect:(MKMapRect)mapRect; 34 | - (BOOL)canReplaceMapContent; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /example/src/examples/LiteMapView.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Dimensions, ScrollView} from 'react-native'; 3 | 4 | import MapView from 'react-native-maps'; 5 | 6 | const {width, height} = Dimensions.get('window'); 7 | 8 | const ASPECT_RATIO = width / height; 9 | const LATITUDE = 37.78825; 10 | const LONGITUDE = -122.4324; 11 | const LATITUDE_DELTA = 0.0922; 12 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 13 | 14 | const SAMPLE_REGION = { 15 | latitude: LATITUDE, 16 | longitude: LONGITUDE, 17 | latitudeDelta: LATITUDE_DELTA, 18 | longitudeDelta: LONGITUDE_DELTA, 19 | }; 20 | 21 | class LiteMapView extends React.Component { 22 | render() { 23 | const maps = []; 24 | for (let i = 0; i < 10; i++) { 25 | maps.push( 26 | , 32 | ); 33 | } 34 | return ( 35 | {maps} 36 | ); 37 | } 38 | } 39 | 40 | const styles = StyleSheet.create({ 41 | map: { 42 | height: 200, 43 | marginVertical: 50, 44 | }, 45 | }); 46 | 47 | export default LiteMapView; 48 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolyline.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolyline.h 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | #import 9 | #import 10 | #import 11 | #import "AIRGMSPolyline.h" 12 | #import "AIRMapCoordinate.h" 13 | #import "AIRGoogleMapMarker.h" 14 | 15 | @interface AIRGoogleMapPolyline : UIView 16 | 17 | @property (nonatomic, weak) RCTBridge *bridge; 18 | @property (nonatomic, strong) NSString *identifier; 19 | @property (nonatomic, strong) AIRGMSPolyline *polyline; 20 | @property (nonatomic, strong) NSArray *coordinates; 21 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 22 | 23 | @property (nonatomic, strong) UIColor *strokeColor; 24 | @property (nonatomic, strong) NSArray *strokeColors; 25 | @property (nonatomic, assign) double strokeWidth; 26 | @property (nonatomic, assign) UIColor *fillColor; 27 | @property (nonatomic, strong) NSArray *lineDashPattern; 28 | @property (nonatomic, assign) BOOL geodesic; 29 | @property (nonatomic, assign) NSString *title; 30 | @property (nonatomic, assign) int zIndex; 31 | @property (nonatomic, assign) BOOL tappable; 32 | 33 | @end 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTileOverlay.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTileOverlay.m 3 | // Pods-AirMapsExplorer 4 | // 5 | // Created by Peter Zavadsky on 04/12/2017. 6 | // 7 | 8 | #import "AIRMapLocalTileOverlay.h" 9 | 10 | @interface AIRMapLocalTileOverlay () 11 | 12 | @end 13 | 14 | @implementation AIRMapLocalTileOverlay 15 | 16 | 17 | -(void)loadTileAtPath:(MKTileOverlayPath)path result:(void (^)(NSData *, NSError *))result { 18 | NSMutableString *tileFilePath = [self.URLTemplate mutableCopy]; 19 | [tileFilePath replaceOccurrencesOfString: @"{x}" withString:[NSString stringWithFormat:@"%li", (long)path.x] options:0 range:NSMakeRange(0, tileFilePath.length)]; 20 | [tileFilePath replaceOccurrencesOfString:@"{y}" withString:[NSString stringWithFormat:@"%li", (long)path.y] options:0 range:NSMakeRange(0, tileFilePath.length)]; 21 | [tileFilePath replaceOccurrencesOfString:@"{z}" withString:[NSString stringWithFormat:@"%li", (long)path.z] options:0 range:NSMakeRange(0, tileFilePath.length)]; 22 | if ([[NSFileManager defaultManager] fileExistsAtPath:tileFilePath]) { 23 | NSData* tile = [NSData dataWithContentsOfFile:tileFilePath]; 24 | result(tile,nil); 25 | } else { 26 | result(nil, nil); 27 | } 28 | } 29 | 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/SizeReportingShadowNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * This source code is licensed under the BSD-style license found in the 5 | * LICENSE file in the root directory of this source tree. An additional grant 6 | * of patent rights can be found in the PATENTS file in the same directory. 7 | */ 8 | 9 | package com.airbnb.android.react.maps; 10 | 11 | import com.facebook.react.uimanager.LayoutShadowNode; 12 | import com.facebook.react.uimanager.UIViewOperationQueue; 13 | 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | // Custom LayoutShadowNode implementation used in conjunction with the AirMapManager 18 | // which sends the width/height of the view after layout occurs. 19 | public class SizeReportingShadowNode extends LayoutShadowNode { 20 | 21 | @Override 22 | public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { 23 | super.onCollectExtraUpdates(uiViewOperationQueue); 24 | 25 | Map data = new HashMap<>(); 26 | data.put("width", getLayoutWidth()); 27 | data.put("height", getLayoutHeight()); 28 | 29 | uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), data); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapWMSTileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapWMSTileManager.m 3 | // AirMaps 4 | // 5 | // Created by nizam on 10/28/18. 6 | // Copyright © 2018. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import "AIRMapMarker.h" 17 | #import "AIRMapWMSTile.h" 18 | 19 | #import "AIRMapWMSTileManager.h" 20 | 21 | @interface AIRMapWMSTileManager() 22 | 23 | @end 24 | 25 | @implementation AIRMapWMSTileManager 26 | 27 | 28 | RCT_EXPORT_MODULE() 29 | 30 | - (UIView *)view 31 | { 32 | AIRMapWMSTile *tile = [AIRMapWMSTile new]; 33 | return tile; 34 | } 35 | 36 | RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) 37 | RCT_EXPORT_VIEW_PROPERTY(maximumZ, NSInteger) 38 | RCT_EXPORT_VIEW_PROPERTY(maximumNativeZ, NSInteger) 39 | RCT_EXPORT_VIEW_PROPERTY(minimumZ, NSInteger) 40 | RCT_EXPORT_VIEW_PROPERTY(shouldReplaceMapContent, BOOL) 41 | RCT_EXPORT_VIEW_PROPERTY(tileSize, NSInteger) 42 | RCT_EXPORT_VIEW_PROPERTY(tileCachePath, NSString) 43 | RCT_EXPORT_VIEW_PROPERTY(tileCacheMaxAge, NSInteger) 44 | RCT_EXPORT_VIEW_PROPERTY(offlineMode, BOOL) 45 | RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat) 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | require_relative '../node_modules/react-native/scripts/react_native_pods' 2 | require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' 3 | 4 | platform :ios, '13.0' 5 | install! 'cocoapods', :deterministic_uuids => false 6 | 7 | production = ENV["PRODUCTION"] == "1" 8 | 9 | target 'example' do 10 | config = use_native_modules! 11 | 12 | # Flags change depending on the env values. 13 | flags = get_default_flags() 14 | 15 | use_react_native!( 16 | :path => config[:reactNativePath], 17 | # to enable hermes on iOS, change `false` to `true` and then install pods 18 | :production => production, 19 | :hermes_enabled => flags[:hermes_enabled], 20 | :fabric_enabled => flags[:fabric_enabled], 21 | :flipper_configuration => FlipperConfiguration.disabled, 22 | # An absolute path to your application root. 23 | :app_path => "#{Pod::Config.instance.installation_root}/.." 24 | ) 25 | 26 | rn_maps_path = '../../' 27 | pod 'react-native-google-maps', :path => rn_maps_path 28 | 29 | target 'exampleTests' do 30 | inherit! :complete 31 | # Pods for testing 32 | end 33 | 34 | post_install do |installer| 35 | react_native_post_install(installer) 36 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolygonManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolylgoneManager.m 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | #import "AIRGoogleMapPolygonManager.h" 9 | 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import "RCTConvert+AirMap.h" 17 | #import "AIRGoogleMapPolygon.h" 18 | 19 | @interface AIRGoogleMapPolygonManager() 20 | 21 | @end 22 | 23 | @implementation AIRGoogleMapPolygonManager 24 | 25 | RCT_EXPORT_MODULE() 26 | 27 | - (UIView *)view 28 | { 29 | AIRGoogleMapPolygon *polygon = [AIRGoogleMapPolygon new]; 30 | polygon.bridge = self.bridge; 31 | return polygon; 32 | } 33 | 34 | RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) 35 | RCT_EXPORT_VIEW_PROPERTY(holes, AIRMapCoordinateArrayArray) 36 | RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) 37 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) 38 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 39 | RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) 40 | RCT_EXPORT_VIEW_PROPERTY(zIndex, int) 41 | RCT_EXPORT_VIEW_PROPERTY(tappable, BOOL) 42 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 43 | 44 | @end 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /docs/callout.md: -------------------------------------------------------------------------------- 1 | # `` Component API 2 | 3 | ## Props 4 | 5 | | Prop | Type | Default | Note | 6 | |---|---|---|---| 7 | | `tooltip` | `Boolean` | `false` | If `false`, a default "tooltip" bubble window will be drawn around this callouts children. If `true`, the child views can fully customize their appearance, including any "bubble" like styles. 8 | | `alphaHitTest` | `Boolean` | `false` | If `true`, clicks on transparent areas in callout will be passed to map. **Note**: iOS only. 9 | 10 | ## Events 11 | 12 | | Event Name | Returns | Notes 13 | |---|---|---| 14 | | `onPress` | | Callback that is called when the user presses on the callout 15 | 16 | 17 | 18 | --- 19 | 20 | 21 | 22 | # `` Component API 23 | 24 | **Note**: Supported on iOS only. 25 | Use to handle press on specific subview of callout. 26 | Put this component inside ``. 27 | 28 | ## Events 29 | 30 | | Event Name | Returns | Notes 31 | |---|---|---| 32 | | `onPress` | | Callback that is called when the user presses on this subview inside callout 33 | 34 | ## Notes 35 | Native press event has property `action`, which is: 36 | - `callout-press` (or `marker-overlay-press` for GoogleMaps on iOS) for press on `` 37 | - `callout-inside-press` (or `marker-inside-overlay-press` for GoogleMaps on iOS) for press on `` 38 | 39 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapUrlTileManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapUrlTileManager.m 3 | // AirMaps 4 | // 5 | // Created by cascadian on 3/19/16. 6 | // Copyright © 2016. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import "AIRMapMarker.h" 16 | #import "AIRMapUrlTile.h" 17 | 18 | #import "AIRMapUrlTileManager.h" 19 | 20 | @interface AIRMapUrlTileManager() 21 | 22 | @end 23 | 24 | @implementation AIRMapUrlTileManager 25 | 26 | 27 | RCT_EXPORT_MODULE() 28 | 29 | - (UIView *)view 30 | { 31 | AIRMapUrlTile *tile = [AIRMapUrlTile new]; 32 | return tile; 33 | } 34 | 35 | RCT_EXPORT_VIEW_PROPERTY(urlTemplate, NSString) 36 | RCT_EXPORT_VIEW_PROPERTY(maximumZ, NSInteger) 37 | RCT_EXPORT_VIEW_PROPERTY(maximumNativeZ, NSInteger) 38 | RCT_EXPORT_VIEW_PROPERTY(minimumZ, NSInteger) 39 | RCT_EXPORT_VIEW_PROPERTY(flipY, BOOL) 40 | RCT_EXPORT_VIEW_PROPERTY(shouldReplaceMapContent, BOOL) 41 | RCT_EXPORT_VIEW_PROPERTY(tileSize, NSInteger) 42 | RCT_EXPORT_VIEW_PROPERTY(tileCachePath, NSString) 43 | RCT_EXPORT_VIEW_PROPERTY(tileCacheMaxAge, NSInteger) 44 | RCT_EXPORT_VIEW_PROPERTY(offlineMode, BOOL) 45 | RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat) 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /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/example/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 | -------------------------------------------------------------------------------- /docs/heatmap.md: -------------------------------------------------------------------------------- 1 | # `` Component API 2 | 3 | **Note**: Supported on Google Maps only. 4 | 5 | ## Props 6 | 7 | | Prop | Type | Default | Note | 8 | |---|---|---|---| 9 | | `points` | `Array` | | Array of heatmap entries to apply towards density. 10 | | `radius` | `Number` | `20` | The radius of the heatmap points in pixels, between 10 and 50. 11 | | `opacity` | `Number` | `0.7` | The opacity of the heatmap. 12 | | `gradient` | `Object` | | Heatmap gradient configuration (See below for *Gradient Config*). 13 | 14 | 15 | ## Gradient Config 16 | 17 | [Android Doc](https://developers.google.com/maps/documentation/android-sdk/utility/heatmap#custom) | [iOS Doc](https://developers.google.com/maps/documentation/ios-sdk/utility/heatmap#customize) 18 | 19 | | Prop | Type | Default | Note | 20 | |---|---|---|---| 21 | | `colors` | `Array` | | Colors (one or more) to use for gradient. 22 | | `startPoints` | `Array` | | Array of floating point values from 0 to 1 representing where each color starts. Array length must be equal to `colors` array length. 23 | | `colorMapSize` | `Number` | `256` | Resolution of color map -- number corresponding to the number of steps colors are interpolated into. 24 | 25 | 26 | ## Types 27 | 28 | ``` 29 | type WeightedLatLng = { 30 | latitude: Number; 31 | longitude: Number; 32 | weight?: Number; 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/newarchitecture/components/MainComponentsRegistry.java: -------------------------------------------------------------------------------- 1 | package com.example.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 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapPolylineManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapPolylineManager.m 3 | // 4 | // Created by Nick Italiano on 10/22/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | 9 | #import "AIRGoogleMapPolylineManager.h" 10 | 11 | #import 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import "RCTConvert+AirMap.h" 18 | #import "AIRGoogleMapPolyline.h" 19 | 20 | @interface AIRGoogleMapPolylineManager() 21 | 22 | @end 23 | 24 | @implementation AIRGoogleMapPolylineManager 25 | 26 | RCT_EXPORT_MODULE() 27 | 28 | - (UIView *)view 29 | { 30 | AIRGoogleMapPolyline *polyline = [AIRGoogleMapPolyline new]; 31 | polyline.bridge = self.bridge; 32 | return polyline; 33 | } 34 | 35 | RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) 36 | RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) 37 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 38 | RCT_EXPORT_VIEW_PROPERTY(strokeColors, UIColorArray) 39 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, double) 40 | RCT_EXPORT_VIEW_PROPERTY(lineDashPattern, NSArray) 41 | RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) 42 | RCT_EXPORT_VIEW_PROPERTY(zIndex, int) 43 | RCT_EXPORT_VIEW_PROPERTY(tappable, BOOL) 44 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 45 | 46 | @end 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/MapMarkerNativeComponent.ts: -------------------------------------------------------------------------------- 1 | import type {HostComponent} from 'react-native'; 2 | import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands'; 3 | import {NativeProps} from './MapMarker'; 4 | import {LatLng} from './sharedTypes'; 5 | 6 | export type MapMarkerNativeComponentType = HostComponent; 7 | 8 | interface NativeCommands { 9 | showCallout: ( 10 | viewRef: NonNullable< 11 | React.RefObject['current'] 12 | >, 13 | ) => void; 14 | hideCallout: ( 15 | viewRef: NonNullable< 16 | React.RefObject['current'] 17 | >, 18 | ) => void; 19 | redrawCallout: ( 20 | viewRef: NonNullable< 21 | React.RefObject['current'] 22 | >, 23 | ) => void; 24 | animateMarkerToCoordinate: ( 25 | viewRef: NonNullable< 26 | React.RefObject['current'] 27 | >, 28 | coordinate: LatLng, 29 | duration: number, 30 | ) => void; 31 | redraw: ( 32 | viewRef: NonNullable< 33 | React.RefObject['current'] 34 | >, 35 | ) => void; 36 | } 37 | 38 | export const Commands: NativeCommands = codegenNativeCommands({ 39 | supportedCommands: [ 40 | 'showCallout', 41 | 'hideCallout', 42 | 'redrawCallout', 43 | 'animateMarkerToCoordinate', 44 | 'redraw', 45 | ], 46 | }); 47 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 22 | 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /example/src/examples/CustomCallout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import {StyleSheet, View} from 'react-native'; 4 | 5 | class CustomCallout extends React.Component { 6 | render() { 7 | return ( 8 | 9 | 10 | {this.props.children} 11 | 12 | 13 | 14 | 15 | ); 16 | } 17 | } 18 | 19 | const styles = StyleSheet.create({ 20 | container: { 21 | flexDirection: 'column', 22 | alignSelf: 'flex-start', 23 | }, 24 | bubble: { 25 | width: 140, 26 | flexDirection: 'row', 27 | alignSelf: 'flex-start', 28 | backgroundColor: '#4da2ab', 29 | paddingHorizontal: 20, 30 | paddingVertical: 12, 31 | borderRadius: 6, 32 | borderColor: '#007a87', 33 | borderWidth: 0.5, 34 | }, 35 | amount: { 36 | flex: 1, 37 | }, 38 | arrow: { 39 | backgroundColor: 'transparent', 40 | borderWidth: 16, 41 | borderColor: 'transparent', 42 | borderTopColor: '#4da2ab', 43 | alignSelf: 'center', 44 | marginTop: -32, 45 | }, 46 | arrowBorder: { 47 | backgroundColor: 'transparent', 48 | borderWidth: 16, 49 | borderColor: 'transparent', 50 | borderTopColor: '#007a87', 51 | alignSelf: 'center', 52 | marginTop: -0.5, 53 | }, 54 | }); 55 | 56 | export default CustomCallout; 57 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCircle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | 14 | #import "AIRMapCoordinate.h" 15 | #import "AIRMap.h" 16 | #import "RCTConvert+AirMap.h" 17 | 18 | @interface AIRMapCircle: MKAnnotationView 19 | 20 | @property (nonatomic, weak) AIRMap *map; 21 | 22 | @property (nonatomic, strong) MKCircle *circle; 23 | @property (nonatomic, strong) MKCircleRenderer *renderer; 24 | 25 | @property (nonatomic, assign) CLLocationCoordinate2D centerCoordinate; 26 | @property (nonatomic, assign) CLLocationDistance radius; 27 | 28 | @property (nonatomic, strong) UIColor *fillColor; 29 | @property (nonatomic, strong) UIColor *strokeColor; 30 | @property (nonatomic, assign) CGFloat strokeWidth; 31 | @property (nonatomic, assign) CGFloat miterLimit; 32 | @property (nonatomic, assign) CGLineCap lineCap; 33 | @property (nonatomic, assign) CGLineJoin lineJoin; 34 | @property (nonatomic, assign) CGFloat lineDashPhase; 35 | @property (nonatomic, strong) NSArray *lineDashPattern; 36 | 37 | #pragma mark MKOverlay protocol 38 | 39 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 40 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 41 | - (BOOL)intersectsMapRect:(MKMapRect)mapRect; 42 | - (BOOL)canReplaceMapContent; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /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.example", 39 | ) 40 | 41 | android_resource( 42 | name = "res", 43 | package = "com.example", 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 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolylineManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRMapPolylineManager.h" 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import "RCTConvert+AirMap.h" 19 | #import "AIRMapMarker.h" 20 | #import "AIRMapPolyline.h" 21 | 22 | @interface AIRMapPolylineManager() 23 | 24 | @end 25 | 26 | @implementation AIRMapPolylineManager 27 | 28 | RCT_EXPORT_MODULE() 29 | 30 | - (UIView *)view 31 | { 32 | AIRMapPolyline *polyline = [AIRMapPolyline new]; 33 | return polyline; 34 | } 35 | 36 | RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) 37 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 38 | RCT_EXPORT_VIEW_PROPERTY(strokeColors, UIColorArray) 39 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat) 40 | RCT_EXPORT_VIEW_PROPERTY(lineCap, CGLineCap) 41 | RCT_EXPORT_VIEW_PROPERTY(lineJoin, CGLineJoin) 42 | RCT_EXPORT_VIEW_PROPERTY(miterLimit, CGFloat) 43 | RCT_EXPORT_VIEW_PROPERTY(lineDashPhase, CGFloat) 44 | RCT_EXPORT_VIEW_PROPERTY(lineDashPattern, NSArray) 45 | RCT_EXPORT_VIEW_PROPERTY(geodesic, BOOL) 46 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolygonManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRMapPolygonManager.h" 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import "RCTConvert+AirMap.h" 19 | #import "AIRMapMarker.h" 20 | #import "AIRMapPolygon.h" 21 | 22 | @interface AIRMapPolygonManager() 23 | 24 | @end 25 | 26 | @implementation AIRMapPolygonManager 27 | 28 | RCT_EXPORT_MODULE() 29 | 30 | - (UIView *)view 31 | { 32 | AIRMapPolygon *polygon = [AIRMapPolygon new]; 33 | return polygon; 34 | } 35 | 36 | RCT_EXPORT_VIEW_PROPERTY(coordinates, AIRMapCoordinateArray) 37 | RCT_EXPORT_VIEW_PROPERTY(holes, AIRMapCoordinateArrayArray) 38 | RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) 39 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 40 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat) 41 | RCT_EXPORT_VIEW_PROPERTY(lineCap, CGLineCap) 42 | RCT_EXPORT_VIEW_PROPERTY(lineJoin, CGLineJoin) 43 | RCT_EXPORT_VIEW_PROPERTY(miterLimit, CGFloat) 44 | RCT_EXPORT_VIEW_PROPERTY(lineDashPhase, CGFloat) 45 | RCT_EXPORT_VIEW_PROPERTY(lineDashPattern, NSArray) 46 | RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 47 | 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /example/src/examples/PriceMarker.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Text} from 'react-native'; 3 | 4 | class PriceMarker extends React.Component { 5 | render() { 6 | const {fontSize, amount} = this.props; 7 | return ( 8 | 9 | 10 | $ 11 | {amount} 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | } 19 | 20 | const styles = StyleSheet.create({ 21 | container: { 22 | flexDirection: 'column', 23 | alignSelf: 'flex-start', 24 | }, 25 | bubble: { 26 | flex: 0, 27 | flexDirection: 'row', 28 | alignSelf: 'flex-start', 29 | backgroundColor: '#FF5A5F', 30 | padding: 2, 31 | borderRadius: 3, 32 | borderColor: '#D23F44', 33 | borderWidth: 0.5, 34 | }, 35 | dollar: { 36 | color: '#FFFFFF', 37 | fontSize: 10, 38 | }, 39 | amount: { 40 | color: '#FFFFFF', 41 | fontSize: 13, 42 | }, 43 | arrow: { 44 | backgroundColor: 'transparent', 45 | borderWidth: 4, 46 | borderColor: 'transparent', 47 | borderTopColor: '#FF5A5F', 48 | alignSelf: 'center', 49 | marginTop: -9, 50 | }, 51 | arrowBorder: { 52 | backgroundColor: 'transparent', 53 | borderWidth: 4, 54 | borderColor: 'transparent', 55 | borderTopColor: '#D23F44', 56 | alignSelf: 'center', 57 | marginTop: -0.5, 58 | }, 59 | }); 60 | 61 | export default PriceMarker; 62 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolyline.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | #import "AIRMapCoordinate.h" 14 | #import "AIRMap.h" 15 | #import "RCTConvert+AirMap.h" 16 | 17 | 18 | @interface AIRMapPolyline: MKAnnotationView 19 | 20 | @property (nonatomic, weak) AIRMap *map; 21 | 22 | @property (nonatomic, strong) MKPolyline *polyline; 23 | @property (nonatomic, strong) MKOverlayPathRenderer *renderer; 24 | 25 | @property (nonatomic, strong) NSArray *coordinates; 26 | @property (nonatomic, strong) UIColor *fillColor; 27 | @property (nonatomic, strong) UIColor *strokeColor; 28 | @property (nonatomic, strong) NSArray *strokeColors; 29 | @property (nonatomic, assign) CGFloat strokeWidth; 30 | @property (nonatomic, assign) CGFloat miterLimit; 31 | @property (nonatomic, assign) CGLineCap lineCap; 32 | @property (nonatomic, assign) CGLineJoin lineJoin; 33 | @property (nonatomic, assign) CGFloat lineDashPhase; 34 | @property (nonatomic, strong) NSArray *lineDashPattern; 35 | @property (nonatomic, assign) BOOL geodesic; 36 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 37 | 38 | #pragma mark MKOverlay protocol 39 | 40 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 41 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 42 | - (BOOL)intersectsMapRect:(MKMapRect)mapRect; 43 | - (BOOL)canReplaceMapContent; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapPolygon.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Leland Richardson on 12/27/15. 3 | // Copyright (c) 2015 Facebook. All rights reserved. 4 | // 5 | 6 | #import 7 | 8 | #import 9 | #import 10 | 11 | #import 12 | #import 13 | #import "AIRMapCoordinate.h" 14 | #import "AIRMap.h" 15 | #import "RCTConvert+AirMap.h" 16 | 17 | 18 | 19 | @interface AIRMapPolygon: MKAnnotationView 20 | 21 | @property (nonatomic, weak) AIRMap *map; 22 | 23 | @property (nonatomic, strong) MKPolygon *polygon; 24 | @property (nonatomic, strong) MKPolygonRenderer *renderer; 25 | @property (nonatomic, strong) NSArray *interiorPolygons; 26 | 27 | @property (nonatomic, strong) NSArray *coordinates; 28 | @property (nonatomic, strong) NSArray *> *holes; 29 | @property (nonatomic, strong) UIColor *fillColor; 30 | @property (nonatomic, strong) UIColor *strokeColor; 31 | @property (nonatomic, assign) CGFloat strokeWidth; 32 | @property (nonatomic, assign) CGFloat miterLimit; 33 | @property (nonatomic, assign) CGLineCap lineCap; 34 | @property (nonatomic, assign) CGLineJoin lineJoin; 35 | @property (nonatomic, assign) CGFloat lineDashPhase; 36 | @property (nonatomic, strong) NSArray *lineDashPattern; 37 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 38 | 39 | #pragma mark MKOverlay protocol 40 | 41 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 42 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 43 | - (BOOL)intersectsMapRect:(MKMapRect)mapRect; 44 | - (BOOL)canReplaceMapContent; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapUrlTile.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapURLTile.m 3 | // Created by Nick Italiano on 11/5/16. 4 | // 5 | 6 | #ifdef HAVE_GOOGLE_MAPS 7 | 8 | #import "AIRGoogleMapUrlTile.h" 9 | 10 | @implementation AIRGoogleMapUrlTile 11 | 12 | - (void)setZIndex:(int)zIndex 13 | { 14 | _zIndex = zIndex; 15 | _tileLayer.zIndex = zIndex; 16 | } 17 | 18 | - (void)setUrlTemplate:(NSString *)urlTemplate 19 | { 20 | _urlTemplate = urlTemplate; 21 | _tileLayer = [GMSURLTileLayer tileLayerWithURLConstructor:[self _getTileURLConstructor]]; 22 | _tileLayer.tileSize = [[UIScreen mainScreen] scale] * 256; 23 | } 24 | 25 | - (GMSTileURLConstructor)_getTileURLConstructor 26 | { 27 | NSString *urlTemplate = self.urlTemplate; 28 | NSInteger *maximumZ = self.maximumZ; 29 | NSInteger *minimumZ = self.minimumZ; 30 | GMSTileURLConstructor urls = ^NSURL* _Nullable (NSUInteger x, NSUInteger y, NSUInteger zoom) { 31 | 32 | if (self.flipY == YES) { 33 | y = (1 << zoom) - y - 1; 34 | } 35 | 36 | NSString *url = urlTemplate; 37 | url = [url stringByReplacingOccurrencesOfString:@"{x}" withString:[NSString stringWithFormat: @"%ld", (long)x]]; 38 | url = [url stringByReplacingOccurrencesOfString:@"{y}" withString:[NSString stringWithFormat: @"%ld", (long)y]]; 39 | url = [url stringByReplacingOccurrencesOfString:@"{z}" withString:[NSString stringWithFormat: @"%ld", (long)zoom]]; 40 | 41 | if(maximumZ && (long)zoom > (long)maximumZ) { 42 | return nil; 43 | } 44 | 45 | if(minimumZ && (long)zoom < (long)minimumZ) { 46 | return nil; 47 | } 48 | 49 | return [NSURL URLWithString:url]; 50 | }; 51 | return urls; 52 | } 53 | 54 | @end 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/MapLocalTile.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {ViewProps} from 'react-native'; 3 | 4 | import decorateMapComponent, { 5 | USES_DEFAULT_IMPLEMENTATION, 6 | SUPPORTED, 7 | ProviderContext, 8 | NativeComponent, 9 | MapManagerCommand, 10 | UIManagerCommand, 11 | } from './decorateMapComponent'; 12 | 13 | export type MapLocalTileProps = ViewProps & { 14 | /** 15 | * @platform iOS: Apple Maps only 16 | * @platform Android: Supported 17 | */ 18 | pathTemplate: string; 19 | 20 | /** 21 | * @platform iOS: Apple Maps only 22 | * @platform Android: Supported 23 | */ 24 | tileSize?: number; 25 | 26 | /** 27 | * Set to true to use pathTemplate to open files from Android's AssetManager. The default is false. 28 | * @platform android 29 | */ 30 | useAssets?: boolean; 31 | 32 | /** 33 | * @platform iOS: Not supported 34 | * @platform Android: Supported 35 | */ 36 | zIndex?: number; 37 | }; 38 | 39 | type NativeProps = MapLocalTileProps; 40 | 41 | export class MapLocalTile extends React.Component { 42 | // declaration only, as they are set through decorateMap 43 | declare context: React.ContextType; 44 | getNativeComponent!: () => NativeComponent; 45 | getMapManagerCommand!: (name: string) => MapManagerCommand; 46 | getUIManagerCommand!: (name: string) => UIManagerCommand; 47 | 48 | render() { 49 | const AIRMapLocalTile = this.getNativeComponent(); 50 | return ; 51 | } 52 | } 53 | 54 | export default decorateMapComponent(MapLocalTile, 'LocalTile', { 55 | google: { 56 | ios: SUPPORTED, 57 | android: USES_DEFAULT_IMPLEMENTATION, 58 | }, 59 | }); 60 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapUrlTile.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIRUrlTileOverlay.h 3 | // AirMaps 4 | // 5 | // Created by cascadian on 3/19/16. 6 | // Copyright © 2016. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | #import 14 | #import 15 | #import "AIRMapCoordinate.h" 16 | #import "AIRMap.h" 17 | #import "RCTConvert+AirMap.h" 18 | #import "AIRMapUrlTileCachedOverlay.h" 19 | 20 | @interface AIRMapUrlTile : MKAnnotationView { 21 | BOOL _urlTemplateSet; 22 | BOOL _tileSizeSet; 23 | BOOL _flipYSet; 24 | BOOL _tileCachePathSet; 25 | BOOL _tileCacheMaxAgeSet; 26 | BOOL _maximumNativeZSet; 27 | BOOL _cachedOverlayCreated; 28 | BOOL _opacitySet; 29 | } 30 | 31 | @property (nonatomic, weak) AIRMap *map; 32 | 33 | @property (nonatomic, strong) AIRMapUrlTileCachedOverlay *tileOverlay; 34 | @property (nonatomic, strong) MKTileOverlayRenderer *renderer; 35 | @property (nonatomic, copy) NSString *urlTemplate; 36 | @property NSInteger maximumZ; 37 | @property NSInteger maximumNativeZ; 38 | @property NSInteger minimumZ; 39 | @property BOOL flipY; 40 | @property BOOL shouldReplaceMapContent; 41 | @property NSInteger tileSize; 42 | @property (nonatomic, copy) NSString *tileCachePath; 43 | @property NSInteger tileCacheMaxAge; 44 | @property BOOL offlineMode; 45 | @property CGFloat opacity; 46 | 47 | - (void)updateProperties; 48 | - (void)update; 49 | 50 | #pragma mark MKOverlay protocol 51 | 52 | @property(nonatomic, readonly) CLLocationCoordinate2D coordinate; 53 | @property(nonatomic, readonly) MKMapRect boundingMapRect; 54 | //- (BOOL)intersectsMapRect:(MKMapRect)mapRect; 55 | - (BOOL)canReplaceMapContent; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapCircleManager.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRMapCircleManager.h" 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | #import 17 | #import 18 | #import "AIRMapMarker.h" 19 | #import "AIRMapCircle.h" 20 | 21 | @interface AIRMapCircleManager() 22 | 23 | @end 24 | 25 | @implementation AIRMapCircleManager 26 | 27 | RCT_EXPORT_MODULE() 28 | 29 | - (UIView *)view 30 | { 31 | AIRMapCircle *circle = [AIRMapCircle new]; 32 | return circle; 33 | } 34 | 35 | RCT_REMAP_VIEW_PROPERTY(center, centerCoordinate, CLLocationCoordinate2D) 36 | RCT_EXPORT_VIEW_PROPERTY(radius, CLLocationDistance) 37 | RCT_EXPORT_VIEW_PROPERTY(fillColor, UIColor) 38 | RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor) 39 | RCT_EXPORT_VIEW_PROPERTY(strokeWidth, CGFloat) 40 | RCT_EXPORT_VIEW_PROPERTY(lineCap, CGLineCap) 41 | RCT_EXPORT_VIEW_PROPERTY(lineJoin, CGLineJoin) 42 | RCT_EXPORT_VIEW_PROPERTY(miterLimit, CGFloat) 43 | RCT_EXPORT_VIEW_PROPERTY(lineDashPhase, CGFloat) 44 | RCT_EXPORT_VIEW_PROPERTY(lineDashPattern, NSArray) 45 | 46 | // NOTE(lmr): 47 | // for now, onPress events for overlays will be left unimplemented. Seems it is possible with some work, but 48 | // it is difficult to achieve in both ios and android so I decided to leave it out. 49 | //RCT_EXPORT_VIEW_PROPERTY(onPress, RCTBubblingEventBlock) 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /example/ios/example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNMaps Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | NSExceptionDomains 30 | 31 | localhost 32 | 33 | NSExceptionAllowsInsecureHTTPLoads 34 | 35 | 36 | 37 | 38 | NSLocationWhenInUseUsageDescription 39 | 40 | UILaunchStoryboardName 41 | LaunchScreen 42 | UIRequiredDeviceCapabilities 43 | 44 | armv7 45 | 46 | UISupportedInterfaceOrientations 47 | 48 | UIInterfaceOrientationPortrait 49 | UIInterfaceOrientationLandscapeLeft 50 | UIInterfaceOrientationLandscapeRight 51 | 52 | UIViewControllerBasedStatusBarAppearance 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/RegionChangeEvent.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import com.facebook.react.bridge.WritableMap; 4 | import com.facebook.react.bridge.WritableNativeMap; 5 | import com.facebook.react.uimanager.events.Event; 6 | import com.facebook.react.uimanager.events.RCTEventEmitter; 7 | import com.google.android.gms.maps.model.LatLng; 8 | import com.google.android.gms.maps.model.LatLngBounds; 9 | 10 | public class RegionChangeEvent extends Event { 11 | private final LatLngBounds bounds; 12 | private final boolean continuous; 13 | private final boolean isGesture; 14 | 15 | public RegionChangeEvent(int id, LatLngBounds bounds, boolean continuous, boolean isGesture) { 16 | super(id); 17 | this.bounds = bounds; 18 | this.continuous = continuous; 19 | this.isGesture = isGesture; 20 | } 21 | 22 | @Override 23 | public String getEventName() { 24 | return "topChange"; 25 | } 26 | 27 | @Override 28 | public boolean canCoalesce() { 29 | return false; 30 | } 31 | 32 | @Override 33 | public void dispatch(RCTEventEmitter rctEventEmitter) { 34 | WritableMap event = new WritableNativeMap(); 35 | event.putBoolean("continuous", continuous); 36 | 37 | WritableMap region = new WritableNativeMap(); 38 | LatLng center = bounds.getCenter(); 39 | region.putDouble("latitude", center.latitude); 40 | region.putDouble("longitude", center.longitude); 41 | region.putDouble("latitudeDelta", bounds.northeast.latitude - bounds.southwest.latitude); 42 | region.putDouble("longitudeDelta", bounds.northeast.longitude - bounds.southwest.longitude); 43 | event.putMap("region", region); 44 | event.putBoolean("isGesture", isGesture); 45 | 46 | rctEventEmitter.receiveEvent(getViewTag(), getEventName(), event); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapLocalTile.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRMapLocalTile.m 3 | // AirMaps 4 | // 5 | // Created by Peter Zavadsky on 01/12/2017. 6 | // Copyright © 2017 Christopher. All rights reserved. 7 | // 8 | 9 | #import "AIRMapLocalTile.h" 10 | #import 11 | #import "AIRMapLocalTileOverlay.h" 12 | 13 | @implementation AIRMapLocalTile { 14 | BOOL _pathTemplateSet; 15 | BOOL _tileSizeSet; 16 | } 17 | 18 | 19 | - (void)setPathTemplate:(NSString *)pathTemplate{ 20 | _pathTemplate = pathTemplate; 21 | _pathTemplateSet = YES; 22 | [self createTileOverlayAndRendererIfPossible]; 23 | [self update]; 24 | } 25 | 26 | - (void)setTileSize:(CGFloat)tileSize{ 27 | _tileSize = tileSize; 28 | _tileSizeSet = YES; 29 | [self createTileOverlayAndRendererIfPossible]; 30 | [self update]; 31 | } 32 | 33 | - (void) createTileOverlayAndRendererIfPossible 34 | { 35 | if (!_pathTemplateSet || !_tileSizeSet) return; 36 | self.tileOverlay = [[AIRMapLocalTileOverlay alloc] initWithURLTemplate:self.pathTemplate]; 37 | self.tileOverlay.canReplaceMapContent = YES; 38 | self.tileOverlay.tileSize = CGSizeMake(_tileSize, _tileSize); 39 | self.renderer = [[MKTileOverlayRenderer alloc] initWithTileOverlay:self.tileOverlay]; 40 | } 41 | 42 | - (void) update 43 | { 44 | if (!_renderer) return; 45 | 46 | if (_map == nil) return; 47 | [_map removeOverlay:self]; 48 | [_map addOverlay:self level:MKOverlayLevelAboveLabels]; 49 | } 50 | 51 | #pragma mark MKOverlay implementation 52 | 53 | - (CLLocationCoordinate2D) coordinate 54 | { 55 | return self.tileOverlay.coordinate; 56 | } 57 | 58 | - (MKMapRect) boundingMapRect 59 | { 60 | return self.tileOverlay.boundingMapRect; 61 | } 62 | 63 | - (BOOL)canReplaceMapContent 64 | { 65 | return self.tileOverlay.canReplaceMapContent; 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.facebook.react.ReactActivityDelegate; 5 | import com.facebook.react.ReactRootView; 6 | 7 | public class MainActivity extends ReactActivity { 8 | 9 | /** 10 | * Returns the name of the main component registered from JavaScript. This is used to schedule 11 | * rendering of the component. 12 | */ 13 | @Override 14 | protected String getMainComponentName() { 15 | return "example"; 16 | } 17 | 18 | /** 19 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and 20 | * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer 21 | * (Paper). 22 | */ 23 | @Override 24 | protected ReactActivityDelegate createReactActivityDelegate() { 25 | return new MainActivityDelegate(this, getMainComponentName()); 26 | } 27 | 28 | public static class MainActivityDelegate extends ReactActivityDelegate { 29 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) { 30 | super(activity, mainComponentName); 31 | } 32 | 33 | @Override 34 | protected ReactRootView createRootView() { 35 | ReactRootView reactRootView = new ReactRootView(getContext()); 36 | // If you opted-in for the New Architecture, we enable the Fabric Renderer. 37 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); 38 | return reactRootView; 39 | } 40 | 41 | @Override 42 | protected boolean isConcurrentRootEnabled() { 43 | // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18). 44 | // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html 45 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | def safeExtGet(prop, fallback) { 2 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 3 | } 4 | 5 | buildscript { 6 | // The Android Gradle plugin is only required when opening the android folder stand-alone. 7 | // This avoids unnecessary downloads and potential conflicts when the library is included as a 8 | // module dependency in an application project. 9 | if (project == rootProject) { 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle:4.2.2") 16 | } 17 | } 18 | } 19 | 20 | apply plugin: 'com.android.library' 21 | 22 | android { 23 | compileSdkVersion safeExtGet('compileSdkVersion', 30) 24 | 25 | defaultConfig { 26 | minSdkVersion safeExtGet('minSdkVersion', 21) 27 | targetSdkVersion safeExtGet('targetSdkVersion', 30) 28 | } 29 | } 30 | 31 | repositories { 32 | mavenLocal() 33 | mavenCentral() 34 | maven { 35 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 36 | url "$rootDir/../node_modules/react-native/android" 37 | } 38 | maven { 39 | // Android JSC is installed from npm 40 | url "$rootDir/../node_modules/jsc-android/dist" 41 | } 42 | google() 43 | } 44 | 45 | dependencies { 46 | def work_version = safeExtGet('targetSdkVersion', 27) < 31 ? "2.5.0" : "2.7.1" 47 | implementation 'com.facebook.react:react-native:+' 48 | implementation "com.google.android.gms:play-services-base:${safeExtGet('playServicesVersion', '18.1.0')}" 49 | implementation "com.google.android.gms:play-services-maps:${safeExtGet('playServicesVersion', '18.0.2')}" 50 | implementation "com.google.android.gms:play-services-location:20.0.0" 51 | implementation 'com.google.maps.android:android-maps-utils:0.5' 52 | implementation "androidx.work:work-runtime:$work_version" 53 | } 54 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapCircle.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapsCircle.m 3 | // 4 | // Created by Nick Italiano on 10/24/16. 5 | // 6 | 7 | #ifdef HAVE_GOOGLE_MAPS 8 | #import 9 | #import "AIRGoogleMapCircle.h" 10 | #import 11 | #import 12 | 13 | @implementation AIRGoogleMapCircle 14 | { 15 | BOOL _didMoveToWindow; 16 | } 17 | 18 | - (instancetype)init 19 | { 20 | if (self = [super init]) { 21 | _didMoveToWindow = false; 22 | _circle = [[GMSCircle alloc] init]; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)didMoveToWindow { 28 | [super didMoveToWindow]; 29 | if(_didMoveToWindow) return; 30 | _didMoveToWindow = true; 31 | if(_fillColor) { 32 | _circle.fillColor = _fillColor; 33 | } 34 | if(_strokeColor) { 35 | _circle.strokeColor = _strokeColor; 36 | } 37 | if(_strokeWidth) { 38 | _circle.strokeWidth = _strokeWidth; 39 | } 40 | } 41 | 42 | - (void)setRadius:(double)radius 43 | { 44 | _radius = radius; 45 | _circle.radius = radius; 46 | } 47 | 48 | - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate 49 | { 50 | _centerCoordinate = centerCoordinate; 51 | _circle.position = centerCoordinate; 52 | } 53 | 54 | -(void)setStrokeColor:(UIColor *)strokeColor 55 | { 56 | _strokeColor = strokeColor; 57 | if(_didMoveToWindow) { 58 | _circle.strokeColor = strokeColor; 59 | } 60 | } 61 | 62 | -(void)setStrokeWidth:(double)strokeWidth 63 | { 64 | _strokeWidth = strokeWidth; 65 | if(_didMoveToWindow) { 66 | _circle.strokeWidth = strokeWidth; 67 | } 68 | } 69 | 70 | -(void)setFillColor:(UIColor *)fillColor 71 | { 72 | _fillColor = fillColor; 73 | if(_didMoveToWindow) { 74 | _circle.fillColor = fillColor; 75 | } 76 | } 77 | 78 | -(void)setZIndex:(int)zIndex 79 | { 80 | _zIndex = zIndex; 81 | _circle.zIndex = zIndex; 82 | } 83 | 84 | @end 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 12 | 13 | ### Does any other open PR do the same thing? 14 | 15 | 26 | 27 | (please answer here) 28 | 29 | ### What issue is this PR fixing? 30 | 31 | (please link the issue here) 32 | 33 | ### How did you test this PR? 34 | 35 | 48 | 49 | (please answer here) 50 | 51 | 54 | -------------------------------------------------------------------------------- /example/src/examples/MapKml.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Dimensions} from 'react-native'; 3 | import MapView, {Marker} from 'react-native-maps'; 4 | 5 | const {width, height} = Dimensions.get('window'); 6 | 7 | const ASPECT_RATIO = width / height; 8 | const LATITUDE = -18.9193508; 9 | const LONGITUDE = -48.2830592; 10 | const LATITUDE_DELTA = 0.0922; 11 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 12 | const KML_FILE = 'https://pastebin.com/raw/jAzGpq1F'; 13 | 14 | export default class MapKml extends React.Component { 15 | map: any; 16 | constructor(props: any) { 17 | super(props); 18 | 19 | this.state = { 20 | region: { 21 | latitude: LATITUDE, 22 | longitude: LONGITUDE, 23 | latitudeDelta: LATITUDE_DELTA, 24 | longitudeDelta: LONGITUDE_DELTA, 25 | }, 26 | }; 27 | 28 | this.onKmlReady = this.onKmlReady.bind(this); 29 | } 30 | 31 | onKmlReady() { 32 | this.map.fitToElements({animated: true}); 33 | } 34 | 35 | render() { 36 | return ( 37 | 38 | { 40 | this.map = ref; 41 | }} 42 | provider={this.props.provider} 43 | style={styles.map} 44 | initialRegion={this.state.region} 45 | kmlSrc={KML_FILE} 46 | onKmlReady={this.onKmlReady}> 47 | 52 | 53 | 54 | ); 55 | } 56 | } 57 | 58 | const styles = StyleSheet.create({ 59 | container: { 60 | justifyContent: 'flex-end', 61 | alignItems: 'center', 62 | }, 63 | scrollview: { 64 | alignItems: 'center', 65 | paddingVertical: 40, 66 | }, 67 | map: { 68 | width, 69 | height, 70 | }, 71 | }); 72 | -------------------------------------------------------------------------------- /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 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Version of flipper SDK to use with React Native 28 | FLIPPER_VERSION=0.125.0 29 | 30 | # Use this property to specify which architecture you want to build. 31 | # You can also override it from the CLI using 32 | # ./gradlew -PreactNativeArchitectures=x86_64 33 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 34 | 35 | # Use this property to enable support to the new architecture. 36 | # This will allow you to use TurboModules and the Fabric render in 37 | # your application. You should enable this flag either if you want 38 | # to write custom TurboModules/Fabric components OR use libraries that 39 | # are providing them. 40 | newArchEnabled=false 41 | -------------------------------------------------------------------------------- /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 = "31.0.0" 8 | minSdkVersion = 21 9 | compileSdkVersion = 31 10 | targetSdkVersion = 31 11 | 12 | if (System.properties['os.arch'] == "aarch64") { 13 | // For M1 Users we need to use the NDK 24 which added support for aarch64 14 | ndkVersion = "24.0.8215888" 15 | } else { 16 | // Otherwise we default to the side-by-side NDK version from AGP. 17 | ndkVersion = "21.4.7075529" 18 | } 19 | } 20 | repositories { 21 | google() 22 | mavenCentral() 23 | } 24 | dependencies { 25 | classpath("com.android.tools.build:gradle:7.1.1") 26 | classpath("com.facebook.react:react-native-gradle-plugin") 27 | classpath("de.undercouch:gradle-download-task:5.0.1") 28 | // NOTE: Do not place your application dependencies here; they belong 29 | // in the individual module build.gradle files 30 | } 31 | } 32 | 33 | allprojects { 34 | repositories { 35 | maven { 36 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 37 | url("$rootDir/../node_modules/react-native/android") 38 | } 39 | maven { 40 | // Android JSC is installed from npm 41 | url("$rootDir/../node_modules/jsc-android/dist") 42 | } 43 | mavenCentral { 44 | // We don't want to fetch react-native from Maven Central as there are 45 | // older versions over there. 46 | content { 47 | excludeGroup "com.facebook.react" 48 | } 49 | } 50 | google() 51 | maven { url 'https://www.jitpack.io' } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /example/src/examples/GradientPolylines.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, Dimensions} from 'react-native'; 3 | 4 | import MapView, {Polyline} from 'react-native-maps'; 5 | 6 | const {width, height} = Dimensions.get('window'); 7 | 8 | const ASPECT_RATIO = width / height; 9 | const LATITUDE = 37.78825; 10 | const LONGITUDE = -122.4324; 11 | const LATITUDE_DELTA = 0.0922; 12 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 13 | 14 | const COORDINATES = [ 15 | {latitude: 37.8025259, longitude: -122.4351431}, 16 | {latitude: 37.7896386, longitude: -122.421646}, 17 | {latitude: 37.7665248, longitude: -122.4161628}, 18 | {latitude: 37.7734153, longitude: -122.4577787}, 19 | {latitude: 37.7948605, longitude: -122.4596065}, 20 | {latitude: 37.8025259, longitude: -122.4351431}, 21 | ]; 22 | 23 | const COLORS = [ 24 | '#7F0000', 25 | '#00000000', // no color, creates a "long" gradient between the previous and next coordinate 26 | '#B24112', 27 | '#E5845C', 28 | '#238C23', 29 | '#7F0000', 30 | ]; 31 | 32 | class GradientPolylines extends React.Component { 33 | constructor(props: any) { 34 | super(props); 35 | 36 | this.state = { 37 | region: { 38 | latitude: LATITUDE, 39 | longitude: LONGITUDE, 40 | latitudeDelta: LATITUDE_DELTA, 41 | longitudeDelta: LONGITUDE_DELTA, 42 | }, 43 | }; 44 | } 45 | 46 | render() { 47 | return ( 48 | 52 | 58 | 59 | ); 60 | } 61 | } 62 | 63 | const styles = StyleSheet.create({ 64 | container: { 65 | ...StyleSheet.absoluteFillObject, 66 | }, 67 | }); 68 | 69 | export default GradientPolylines; 70 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/AirMapLocalTileManager.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | import android.view.WindowManager; 6 | 7 | import com.facebook.react.bridge.ReactApplicationContext; 8 | import com.facebook.react.uimanager.ThemedReactContext; 9 | import com.facebook.react.uimanager.ViewGroupManager; 10 | import com.facebook.react.uimanager.annotations.ReactProp; 11 | 12 | /** 13 | * Created by zavadpe on 30/11/2017. 14 | */ 15 | public class AirMapLocalTileManager extends ViewGroupManager { 16 | 17 | public AirMapLocalTileManager(ReactApplicationContext reactContext) { 18 | super(); 19 | DisplayMetrics metrics = new DisplayMetrics(); 20 | ((WindowManager) reactContext.getSystemService(Context.WINDOW_SERVICE)) 21 | .getDefaultDisplay() 22 | .getRealMetrics(metrics); 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "AIRMapLocalTile"; 28 | } 29 | 30 | @Override 31 | public AirMapLocalTile createViewInstance(ThemedReactContext context) { 32 | return new AirMapLocalTile(context); 33 | } 34 | 35 | @ReactProp(name = "pathTemplate") 36 | public void setPathTemplate(AirMapLocalTile view, String pathTemplate) { 37 | view.setPathTemplate(pathTemplate); 38 | } 39 | 40 | @ReactProp(name = "tileSize", defaultFloat = 256f) 41 | public void setTileSize(AirMapLocalTile view, float tileSize) { 42 | view.setTileSize(tileSize); 43 | } 44 | 45 | @ReactProp(name = "zIndex", defaultFloat = -1.0f) 46 | public void setZIndex(AirMapLocalTile view, float zIndex) { 47 | view.setZIndex(zIndex); 48 | } 49 | 50 | @ReactProp(name = "useAssets", defaultBoolean = false) 51 | public void setUseAssets(AirMapLocalTile view, boolean useAssets) { 52 | view.setUseAssets(useAssets); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /example/src/examples/TestIdMarkers.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Dimensions} from 'react-native'; 3 | 4 | import MapView, {Marker} from 'react-native-maps'; 5 | 6 | const {width, height} = Dimensions.get('window'); 7 | 8 | const ASPECT_RATIO = width / height; 9 | const LATITUDE = 37.78825; 10 | const LONGITUDE = -122.4324; 11 | const LATITUDE_DELTA = 0.0922; 12 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 13 | const SPACE = 0.01; 14 | 15 | function log(eventName: any, e: any) { 16 | console.log(eventName, e.nativeEvent); 17 | } 18 | 19 | export default class MarkerTypes extends React.Component { 20 | constructor(props: any) { 21 | super(props); 22 | 23 | this.state = { 24 | a: { 25 | latitude: LATITUDE + SPACE, 26 | longitude: LONGITUDE + SPACE, 27 | }, 28 | }; 29 | } 30 | 31 | render() { 32 | return ( 33 | 34 | 43 | log('onSelect', e)} 47 | onDrag={e => log('onDrag', e)} 48 | onDragStart={e => log('onDragStart', e)} 49 | onDragEnd={e => log('onDragEnd', e)} 50 | onPress={e => log('onPress', e)} 51 | draggable 52 | /> 53 | 54 | 55 | ); 56 | } 57 | } 58 | 59 | const styles = StyleSheet.create({ 60 | container: { 61 | ...StyleSheet.absoluteFillObject, 62 | justifyContent: 'flex-end', 63 | alignItems: 'center', 64 | }, 65 | map: { 66 | ...StyleSheet.absoluteFillObject, 67 | }, 68 | }); 69 | -------------------------------------------------------------------------------- /src/MapCalloutSubview.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import {NativeSyntheticEvent, StyleSheet, ViewProps} from 'react-native'; 3 | import decorateMapComponent, { 4 | SUPPORTED, 5 | NOT_SUPPORTED, 6 | ProviderContext, 7 | NativeComponent, 8 | MapManagerCommand, 9 | UIManagerCommand, 10 | } from './decorateMapComponent'; 11 | import {Frame, Point} from './sharedTypes'; 12 | 13 | export type MapCalloutSubviewProps = ViewProps & { 14 | /** 15 | * Callback that is called when the user presses on this subview inside callout 16 | * 17 | * @platform iOS: Supported 18 | * @platform Android: Not supported 19 | */ 20 | onPress?: (event: CalloutSubviewPressEvent) => void; 21 | }; 22 | 23 | type NativeProps = MapCalloutSubviewProps; 24 | 25 | export class MapCalloutSubview extends React.Component { 26 | // declaration only, as they are set through decorateMap 27 | declare context: React.ContextType; 28 | getNativeComponent!: () => NativeComponent; 29 | getMapManagerCommand!: (name: string) => MapManagerCommand; 30 | getUIManagerCommand!: (name: string) => UIManagerCommand; 31 | render() { 32 | const AIRMapCalloutSubview = this.getNativeComponent(); 33 | return ( 34 | 38 | ); 39 | } 40 | } 41 | 42 | const styles = StyleSheet.create({ 43 | calloutSubview: {}, 44 | }); 45 | 46 | export default decorateMapComponent(MapCalloutSubview, 'CalloutSubview', { 47 | google: { 48 | ios: SUPPORTED, 49 | android: NOT_SUPPORTED, 50 | }, 51 | }); 52 | 53 | type CalloutSubviewPressEvent = NativeSyntheticEvent<{ 54 | /** 55 | * Apple Maps: `callout-inside-press` 56 | * 57 | * Google Maps: `marker-inside-overlay-press` 58 | */ 59 | action: 'callout-inside-press' | 'marker-inside-overlay-press'; 60 | frame: Frame; 61 | id: string; 62 | point: Point; 63 | }>; 64 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/AirMapCalloutManager.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import com.facebook.react.common.MapBuilder; 6 | import com.facebook.react.uimanager.LayoutShadowNode; 7 | import com.facebook.react.uimanager.ThemedReactContext; 8 | import com.facebook.react.uimanager.ViewGroupManager; 9 | import com.facebook.react.uimanager.annotations.ReactProp; 10 | 11 | import java.util.Map; 12 | 13 | public class AirMapCalloutManager extends ViewGroupManager { 14 | 15 | @Override 16 | public String getName() { 17 | return "AIRMapCallout"; 18 | } 19 | 20 | @Override 21 | public AirMapCallout createViewInstance(ThemedReactContext context) { 22 | return new AirMapCallout(context); 23 | } 24 | 25 | @ReactProp(name = "tooltip", defaultBoolean = false) 26 | public void setTooltip(AirMapCallout view, boolean tooltip) { 27 | view.setTooltip(tooltip); 28 | } 29 | 30 | @Override 31 | @Nullable 32 | public Map getExportedCustomDirectEventTypeConstants() { 33 | return MapBuilder.of("onPress", MapBuilder.of("registrationName", "onPress")); 34 | } 35 | 36 | @Override 37 | public LayoutShadowNode createShadowNodeInstance() { 38 | // we use a custom shadow node that emits the width/height of the view 39 | // after layout with the updateExtraData method. Without this, we can't generate 40 | // a bitmap of the appropriate width/height of the rendered view. 41 | return new SizeReportingShadowNode(); 42 | } 43 | 44 | @Override 45 | public void updateExtraData(AirMapCallout view, Object extraData) { 46 | // This method is called from the shadow node with the width/height of the rendered 47 | // marker view. 48 | //noinspection unchecked 49 | Map data = (Map) extraData; 50 | float width = data.get("width"); 51 | float height = data.get("height"); 52 | view.width = (int) width; 53 | view.height = (int) height; 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/LatLngBoundsUtils.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import com.google.android.gms.maps.model.LatLng; 4 | import com.google.android.gms.maps.model.LatLngBounds; 5 | 6 | public class LatLngBoundsUtils { 7 | public static boolean BoundsAreDifferent(LatLngBounds a, LatLngBounds b) { 8 | LatLng centerA = a.getCenter(); 9 | double latA = centerA.latitude; 10 | double lngA = centerA.longitude; 11 | double latDeltaA = a.northeast.latitude - a.southwest.latitude; 12 | double lngDeltaA = a.northeast.longitude - a.southwest.longitude; 13 | 14 | LatLng centerB = b.getCenter(); 15 | double latB = centerB.latitude; 16 | double lngB = centerB.longitude; 17 | double latDeltaB = b.northeast.latitude - b.southwest.latitude; 18 | double lngDeltaB = b.northeast.longitude - b.southwest.longitude; 19 | 20 | double latEps = LatitudeEpsilon(a, b); 21 | double lngEps = LongitudeEpsilon(a, b); 22 | 23 | return 24 | different(latA, latB, latEps) || 25 | different(lngA, lngB, lngEps) || 26 | different(latDeltaA, latDeltaB, latEps) || 27 | different(lngDeltaA, lngDeltaB, lngEps); 28 | } 29 | 30 | private static boolean different(double a, double b, double epsilon) { 31 | return Math.abs(a - b) > epsilon; 32 | } 33 | 34 | private static double LatitudeEpsilon(LatLngBounds a, LatLngBounds b) { 35 | double sizeA = a.northeast.latitude - a.southwest.latitude; // something mod 180? 36 | double sizeB = b.northeast.latitude - b.southwest.latitude; // something mod 180? 37 | double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); 38 | return size / 2560; 39 | } 40 | 41 | private static double LongitudeEpsilon(LatLngBounds a, LatLngBounds b) { 42 | double sizeA = a.northeast.longitude - a.southwest.longitude; 43 | double sizeB = b.northeast.longitude - b.southwest.longitude; 44 | double size = Math.min(Math.abs(sizeA), Math.abs(sizeB)); 45 | return size / 2560; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/src/examples/OnPoiClick.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Text, Dimensions} from 'react-native'; 3 | 4 | import MapView, {Callout, Marker} from 'react-native-maps'; 5 | 6 | const {width, height} = Dimensions.get('window'); 7 | 8 | const ASPECT_RATIO = width / height; 9 | const LATITUDE = 37.78825; 10 | const LONGITUDE = -122.4324; 11 | const LATITUDE_DELTA = 0.0922; 12 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 13 | 14 | class OnPoiClick extends React.Component { 15 | constructor(props: any) { 16 | super(props); 17 | 18 | this.state = { 19 | region: { 20 | latitude: LATITUDE, 21 | longitude: LONGITUDE, 22 | latitudeDelta: LATITUDE_DELTA, 23 | longitudeDelta: LONGITUDE_DELTA, 24 | }, 25 | poi: null, 26 | }; 27 | 28 | this.onPoiClick = this.onPoiClick.bind(this); 29 | } 30 | 31 | onPoiClick(e: any) { 32 | const poi = e.nativeEvent; 33 | 34 | this.setState({ 35 | poi, 36 | }); 37 | } 38 | 39 | render() { 40 | return ( 41 | 42 | 47 | {this.state.poi && ( 48 | 49 | 50 | 51 | Place Id: {this.state.poi.placeId} 52 | Name: {this.state.poi.name} 53 | 54 | 55 | 56 | )} 57 | 58 | 59 | ); 60 | } 61 | } 62 | 63 | const styles = StyleSheet.create({ 64 | container: { 65 | ...StyleSheet.absoluteFillObject, 66 | justifyContent: 'flex-end', 67 | alignItems: 'center', 68 | }, 69 | map: { 70 | ...StyleSheet.absoluteFillObject, 71 | }, 72 | }); 73 | 74 | export default OnPoiClick; 75 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for helping this project become a better library :) 4 | 5 | - [Triage](#triage) 6 | - [Reporting Bugs](#reporting-bugs) 7 | - [Providing a feature request](#providing-a-feature-request) 8 | - [Pull requests](#pull-requests) 9 | 10 | ## Triage 11 | 12 | This is one of the easiest and most effective ways of helping out. If you see an open issue, try and reproduce the bug yourself, and comment with the result. If the issue is lacking any information to reproduce the bug, let the author know. 13 | 14 | ## Reporting Bugs 15 | 16 | Open an issue, making sure to follow the bug report template. 17 | 18 | ## Providing a feature request 19 | 20 | Open an issue, making sure to follow the Feature request template. 21 | 22 | ## Pull requests 23 | 24 | ### Getting started 25 | 26 | - If there isn't one already, open an issue describing the bug or feature request that you are going to solve in your pull request. 27 | - Create a fork of react-native-maps 28 | - If you already have a fork, make sure it is up to date 29 | - Git clone your fork and run `yarn` in the base of the cloned repo to setup your local development environment. 30 | - Create a branch from the master branch to start working on your changes. 31 | 32 | ### Committing 33 | 34 | - When you made your changes, run `yarn lint` & `yarn test` to make sure the code you introduced doesn't cause any obvious issues. 35 | - When you are ready to commit your changes, use the [Angular conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/#summary) convention for you commit messages, as we use your commits when releasing new versions. 36 | - Use present tense: "add awesome component" not "added awesome component" 37 | - Limit the first line of the commit message to 100 characters 38 | - Reference issues and pull requests before committing 39 | 40 | ### Creating the pull request 41 | 42 | - The title of the PR needs to follow the same conventions as your commit messages, as it might be used in case of a squash merge. 43 | - Create the pull request against the beta branch. 44 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java: -------------------------------------------------------------------------------- 1 | package com.example.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/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import MapView, { 2 | AnimatedMapView as Animated, 3 | MAP_TYPES, 4 | enableLatestRenderer, 5 | MapViewProps, 6 | } from './MapView'; 7 | 8 | import Marker from './MapMarker'; 9 | export {MapMarker} from './MapMarker'; 10 | export type {MapMarkerProps} from './MapMarker'; 11 | 12 | import Overlay from './MapOverlay'; 13 | export {MapOverlay} from './MapOverlay'; 14 | export type {MapOverlayProps} from './MapOverlay'; 15 | 16 | export {default as Polyline, MapPolyline} from './MapPolyline'; 17 | export type {MapPolylineProps} from './MapPolyline'; 18 | export {default as Heatmap, MapHeatmap} from './MapHeatmap'; 19 | export type {MapHeatmapProps} from './MapHeatmap'; 20 | export {default as Polygon, MapPolygon} from './MapPolygon'; 21 | export type {MapPolygonProps} from './MapPolygon'; 22 | export {default as Circle, MapCircle} from './MapCircle'; 23 | export type {MapCircleProps} from './MapCircle'; 24 | export {default as UrlTile, MapUrlTile} from './MapUrlTile'; 25 | export type {MapUrlTileProps} from './MapUrlTile'; 26 | export {default as WMSTile, MapWMSTile} from './MapWMSTile'; 27 | export type {MapWMSTileProps} from './MapWMSTile'; 28 | export {default as LocalTile, MapLocalTile} from './MapLocalTile'; 29 | export type {MapLocalTileProps} from './MapLocalTile'; 30 | export {default as Callout, MapCallout} from './MapCallout'; 31 | export type {MapCalloutProps} from './MapCallout'; 32 | export { 33 | default as CalloutSubview, 34 | MapCalloutSubview, 35 | } from './MapCalloutSubview'; 36 | export type {MapCalloutSubviewProps} from './MapCalloutSubview'; 37 | export {default as AnimatedRegion} from './AnimatedRegion'; 38 | export {default as Geojson} from './Geojson'; 39 | export type {GeojsonProps} from './Geojson'; 40 | 41 | export {Marker, Overlay}; 42 | export type {MapViewProps}; 43 | export {Animated, MAP_TYPES, enableLatestRenderer}; 44 | 45 | export * from './ProviderConstants'; 46 | export * from './MapView.types'; 47 | export * from './sharedTypes'; 48 | 49 | export const MarkerAnimated = Marker.Animated; 50 | export const OverlayAnimated = Overlay.Animated; 51 | 52 | export default MapView; 53 | -------------------------------------------------------------------------------- /example/src/examples/CustomOverlay.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Dimensions} from 'react-native'; 3 | 4 | import MapView from 'react-native-maps'; 5 | import XMarksTheSpot from './CustomOverlayXMarksTheSpot'; 6 | 7 | const {width, height} = Dimensions.get('window'); 8 | const ASPECT_RATIO = width / height; 9 | const LATITUDE = 37.78825; 10 | const LONGITUDE = -122.4324; 11 | const LATITUDE_DELTA = 0.0922; 12 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 13 | 14 | class CustomOverlay extends React.Component { 15 | constructor(props: any) { 16 | super(props); 17 | 18 | this.state = { 19 | region: { 20 | latitude: LATITUDE, 21 | longitude: LONGITUDE, 22 | latitudeDelta: LATITUDE_DELTA, 23 | longitudeDelta: LONGITUDE_DELTA, 24 | }, 25 | coordinates: [ 26 | { 27 | longitude: -122.442753, 28 | latitude: 37.79879, 29 | }, 30 | { 31 | longitude: -122.424728, 32 | latitude: 37.801232, 33 | }, 34 | { 35 | longitude: -122.422497, 36 | latitude: 37.790651, 37 | }, 38 | { 39 | longitude: -122.440693, 40 | latitude: 37.788209, 41 | }, 42 | ], 43 | center: { 44 | longitude: -122.4326648935676, 45 | latitude: 37.79418561114521, 46 | }, 47 | }; 48 | } 49 | 50 | render() { 51 | const {coordinates, center, region} = this.state; 52 | return ( 53 | 54 | 58 | 59 | 60 | 61 | ); 62 | } 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | container: { 67 | ...StyleSheet.absoluteFillObject, 68 | justifyContent: 'flex-end', 69 | alignItems: 'center', 70 | }, 71 | map: { 72 | ...StyleSheet.absoluteFillObject, 73 | }, 74 | }); 75 | 76 | export default CustomOverlay; 77 | -------------------------------------------------------------------------------- /android/src/main/java/com/airbnb/android/react/maps/ViewChangesTracker.java: -------------------------------------------------------------------------------- 1 | package com.airbnb.android.react.maps; 2 | 3 | import android.os.Handler; 4 | import android.os.Looper; 5 | 6 | import java.util.LinkedList; 7 | 8 | public class ViewChangesTracker { 9 | 10 | private static ViewChangesTracker instance; 11 | private final Handler handler; 12 | private final LinkedList markers = new LinkedList<>(); 13 | private boolean hasScheduledFrame = false; 14 | private final Runnable updateRunnable; 15 | private final long fps = 40; 16 | 17 | private ViewChangesTracker() { 18 | handler = new Handler(Looper.myLooper()); 19 | updateRunnable = new Runnable() { 20 | @Override 21 | public void run() { 22 | hasScheduledFrame = false; 23 | update(); 24 | 25 | if (markers.size() > 0) { 26 | handler.postDelayed(updateRunnable, fps); 27 | } 28 | } 29 | }; 30 | } 31 | 32 | static ViewChangesTracker getInstance() { 33 | if (instance == null) { 34 | synchronized (ViewChangesTracker.class) { 35 | instance = new ViewChangesTracker(); 36 | } 37 | } 38 | 39 | return instance; 40 | } 41 | 42 | public void addMarker(AirMapMarker marker) { 43 | markers.add(marker); 44 | 45 | if (!hasScheduledFrame) { 46 | hasScheduledFrame = true; 47 | handler.postDelayed(updateRunnable, fps); 48 | } 49 | } 50 | 51 | public void removeMarker(AirMapMarker marker) { 52 | markers.remove(marker); 53 | } 54 | 55 | public boolean containsMarker(AirMapMarker marker) { 56 | return markers.contains(marker); 57 | } 58 | 59 | private final LinkedList markersToRemove = new LinkedList<>(); 60 | 61 | public void update() { 62 | for (AirMapMarker marker : markers) { 63 | if (!marker.updateCustomForTracking()) { 64 | markersToRemove.add(marker); 65 | } 66 | } 67 | 68 | // Remove markers that are not active anymore 69 | if (markersToRemove.size() > 0) { 70 | markers.removeAll(markersToRemove); 71 | markersToRemove.clear(); 72 | } 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /ios/AirGoogleMaps/AIRGoogleMapHeatmap.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIRGoogleMapHeatmap.m 3 | // 4 | // Created by David Cako on 29 April 2018. 5 | // 6 | #import 7 | #import "AIRGoogleMapHeatmap.h" 8 | #import 9 | #import 10 | #import 11 | 12 | @implementation AIRGoogleMapHeatmap 13 | 14 | - (instancetype)init 15 | { 16 | if (self = [super init]) { 17 | _heatmap = [[GMUHeatmapTileLayer alloc] init]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)setPoints:(NSArray *)points 23 | { 24 | NSMutableArray *w = [NSMutableArray arrayWithCapacity:points.count]; 25 | for (int i = 0; i < points.count; i++) { 26 | CLLocationCoordinate2D coord = [RCTConvert CLLocationCoordinate2D:points[i]]; 27 | float intensity = 1.0; 28 | if (points[i][@"weight"] != nil) { 29 | intensity = [RCTConvert float:points[i][@"weight"]]; 30 | } 31 | [w addObject:[[GMUWeightedLatLng alloc] initWithCoordinate:coord intensity:intensity]]; 32 | } 33 | _points = w; 34 | [self.heatmap setWeightedData:w]; 35 | [self.heatmap clearTileCache]; 36 | [self.heatmap setMap:self.heatmap.map]; 37 | } 38 | 39 | - (void)setRadius:(NSUInteger)radius 40 | { 41 | _radius = radius; 42 | [self.heatmap setRadius:radius]; 43 | } 44 | 45 | - (void)setOpacity:(float)opacity 46 | { 47 | _opacity = opacity; 48 | [self.heatmap setOpacity:opacity]; 49 | } 50 | 51 | - (void)setGradient:(NSDictionary *)gradient 52 | { 53 | NSArray *colors = [RCTConvert UIColorArray:gradient[@"colors"]]; 54 | NSArray *colorStartPoints = [RCTConvert NSNumberArray:gradient[@"startPoints"]]; 55 | NSUInteger colorMapSize = [RCTConvert NSUInteger:gradient[@"colorMapSize"]]; 56 | 57 | GMUGradient *gmuGradient = [[GMUGradient alloc] initWithColors:colors 58 | startPoints:colorStartPoints 59 | colorMapSize:colorMapSize]; 60 | _gradient = gmuGradient; 61 | [self.heatmap setGradient:gmuGradient]; 62 | } 63 | 64 | @end -------------------------------------------------------------------------------- /ios/AirMaps/AIRMapMarker.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AIRMapMarker.h" 11 | #import "AIRMapCallout.h" 12 | 13 | #import 14 | #import 15 | 16 | #import 17 | #import "AIRMap.h" 18 | #import "SMCalloutView.h" 19 | #import "RCTConvert+AirMap.h" 20 | 21 | @class RCTBridge; 22 | 23 | @interface AIRMapMarker : MKAnnotationView 24 | 25 | @property (nonatomic, strong) AIRMapCallout *calloutView; 26 | @property (nonatomic, weak) AIRMap *map; 27 | @property (nonatomic, weak) RCTBridge *bridge; 28 | 29 | @property (nonatomic, strong) NSString *identifier; 30 | @property (nonatomic, copy) NSString *imageSrc; 31 | @property (nonatomic, copy) NSString *title; 32 | @property (nonatomic, copy) NSString *subtitle; 33 | @property (nonatomic, assign) CLLocationCoordinate2D coordinate; 34 | @property (nonatomic, strong) UIColor *pinColor; 35 | @property (nonatomic, assign) NSInteger zIndex; 36 | @property (nonatomic, assign) double opacity; 37 | @property (nonatomic, assign) BOOL isPreselected; 38 | 39 | @property (nonatomic, copy) RCTBubblingEventBlock onPress; 40 | @property (nonatomic, copy) RCTDirectEventBlock onSelect; 41 | @property (nonatomic, copy) RCTDirectEventBlock onDeselect; 42 | @property (nonatomic, copy) RCTDirectEventBlock onCalloutPress; 43 | @property (nonatomic, copy) RCTDirectEventBlock onDragStart; 44 | @property (nonatomic, copy) RCTDirectEventBlock onDrag; 45 | @property (nonatomic, copy) RCTDirectEventBlock onDragEnd; 46 | 47 | 48 | - (MKAnnotationView *)getAnnotationView; 49 | - (void)fillCalloutView:(SMCalloutView *)calloutView; 50 | - (BOOL)shouldShowCalloutView; 51 | - (void)showCalloutView; 52 | - (void)hideCalloutView; 53 | - (void)addTapGestureRecognizer; 54 | 55 | @end 56 | 57 | 58 | @interface AIREmptyCalloutBackgroundView : SMCalloutBackgroundView 59 | @end 60 | -------------------------------------------------------------------------------- /src/sharedTypes.ts: -------------------------------------------------------------------------------- 1 | import {NativeSyntheticEvent} from 'react-native'; 2 | 3 | export type Provider = 'google' | undefined; 4 | 5 | export type LatLng = { 6 | latitude: number; 7 | longitude: number; 8 | }; 9 | 10 | export type Point = { 11 | x: number; 12 | y: number; 13 | }; 14 | 15 | export type Region = LatLng & { 16 | latitudeDelta: number; 17 | longitudeDelta: number; 18 | }; 19 | 20 | export type Frame = Point & {height: number; width: number}; 21 | 22 | export type CalloutPressEvent = NativeSyntheticEvent<{ 23 | action: 'callout-press'; 24 | 25 | /** 26 | * @platform iOS 27 | */ 28 | frame?: Frame; 29 | 30 | /** 31 | * @platform iOS 32 | */ 33 | id?: string; 34 | 35 | /** 36 | * @platform iOS 37 | */ 38 | point?: Point; 39 | 40 | /** 41 | * @platform Android 42 | */ 43 | coordinate?: LatLng; 44 | 45 | /** 46 | * @platform Android 47 | */ 48 | position?: Point; 49 | }>; 50 | 51 | export type LineCapType = 'butt' | 'round' | 'square'; 52 | export type LineJoinType = 'miter' | 'round' | 'bevel'; 53 | 54 | export type ClickEvent = NativeSyntheticEvent< 55 | {coordinate: LatLng; position: Point} & T 56 | >; 57 | 58 | export type MarkerDeselectEvent = Omit< 59 | ClickEvent<{ 60 | action: 'marker-deselect'; 61 | id: string; 62 | }>, 63 | 'position' 64 | >; 65 | 66 | export type MarkerSelectEvent = Omit< 67 | ClickEvent<{id: string; action: 'marker-select'}>, 68 | 'position' 69 | >; 70 | 71 | export type MarkerDragEvent = ClickEvent<{ 72 | /** 73 | * @platform iOS 74 | */ 75 | id?: string; 76 | }>; 77 | 78 | export type MarkerDragStartEndEvent = NativeSyntheticEvent<{ 79 | coordinate: LatLng; 80 | 81 | /** 82 | * @platform iOS 83 | */ 84 | id?: string; 85 | 86 | /** 87 | * @platform Android 88 | */ 89 | position?: Point; 90 | }>; 91 | 92 | export type MarkerPressEvent = NativeSyntheticEvent<{ 93 | id: string; 94 | action: 'marker-press'; 95 | coordinate: LatLng; 96 | 97 | /** 98 | * @platform Android 99 | */ 100 | position?: Point; 101 | }>; 102 | -------------------------------------------------------------------------------- /example/ios/exampleTests/exampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface exampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation exampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-native-maps", 3 | "description": "React Native Mapview component for iOS + Android", 4 | "source": "src/index", 5 | "main": "lib/index.js", 6 | "author": "Leland Richardson ", 7 | "homepage": "https://github.com/react-native-maps/react-native-maps#readme", 8 | "version": "1.3.2", 9 | "license": "MIT", 10 | "scripts": { 11 | "lint": "eslint . --max-warnings 0", 12 | "tscheck": "tsc --noEmit", 13 | "build": "tsc --project tsconfig.build.json", 14 | "test": "jest", 15 | "prepare": "husky install", 16 | "release": "semantic-release", 17 | "bootstrap": "yarn --cwd example && yarn && (cd example && cd ios && pod install)" 18 | }, 19 | "files": [ 20 | "lib", 21 | "android", 22 | "ios", 23 | "react-native-google-maps.podspec", 24 | "react-native-maps.podspec", 25 | "!android/build", 26 | "!ios/build", 27 | "!**/__tests__", 28 | "!**/__fixtures__", 29 | "!**/__mocks__" 30 | ], 31 | "repository": { 32 | "type": "git", 33 | "url": "https://github.com/react-native-maps/react-native-maps" 34 | }, 35 | "keywords": [ 36 | "react", 37 | "react-native", 38 | "react-component", 39 | "map", 40 | "mapview", 41 | "google-maps", 42 | "mapkit" 43 | ], 44 | "peerDependencies": { 45 | "react": ">= 17.0.1", 46 | "react-native": ">= 0.64.3", 47 | "react-native-web": ">= 0.11" 48 | }, 49 | "peerDependenciesMeta": { 50 | "react-native-web": { 51 | "optional": true 52 | } 53 | }, 54 | "devDependencies": { 55 | "@commitlint/cli": "17.1.2", 56 | "@commitlint/config-conventional": "17.1.0", 57 | "@react-native-community/eslint-config": "3.1.0", 58 | "@semantic-release/changelog": "6.0.1", 59 | "@semantic-release/git": "10.0.1", 60 | "@types/react-native": "0.70.3", 61 | "babel-jest": "29.0.3", 62 | "eslint": "8.23.1", 63 | "husky": "8.0.1", 64 | "jest": "29.0.3", 65 | "prettier": "2.7.1", 66 | "react": "18.1.0", 67 | "react-native": "0.70.1", 68 | "semantic-release": "19.0.5", 69 | "typescript": "4.8.3" 70 | }, 71 | "dependencies": { 72 | "@types/geojson": "^7946.0.8" 73 | }, 74 | "jest": { 75 | "preset": "react-native" 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /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/src/examples/IndoorMap.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet, View, Dimensions, Button, Alert} from 'react-native'; 3 | import MapView from 'react-native-maps'; 4 | 5 | const {width, height} = Dimensions.get('window'); 6 | const ASPECT_RATIO = width / height; 7 | const LATITUDE = 1.3039991; 8 | const LONGITUDE = 103.8316911; 9 | const LATITUDE_DELTA = 0.003; 10 | const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; 11 | 12 | export default class IndoorMap extends React.Component { 13 | map: any; 14 | constructor(props: any) { 15 | super(props); 16 | this.setIndoorLevel = this.setIndoorLevel.bind(this); 17 | } 18 | 19 | handleIndoorFocus(event: any) { 20 | const {indoorBuilding} = event.nativeEvent; 21 | const {defaultLevelIndex, levels} = indoorBuilding; 22 | const levelNames = levels.map((lv: any) => lv.name || ''); 23 | const msg = `Default Level: ${defaultLevelIndex}\nLevels: ${levelNames.toString()}`; 24 | Alert.alert('Indoor building focused', msg); 25 | } 26 | 27 | setIndoorLevel(level: any) { 28 | this.map.setIndoorActiveLevelIndex(level); 29 | } 30 | 31 | render() { 32 | return ( 33 | 34 | { 47 | this.map = map; 48 | }} 49 | /> 50 |