From 6fd2483cb2a9405f4346a26415e46ad3507fb8f9 Mon Sep 17 00:00:00 2001 From: "ITONE\\bussakorn.wonghom" <> Date: Wed, 22 Aug 2018 15:46:01 +0700 Subject: [PATCH 01/28] Add indoor events support for Android/iOS --- docs/mapview.md | 19 +++++ example/App.js | 2 + example/examples/IndoorMap.js | 72 ++++++++++++++++ .../android/react/maps/AirMapManager.java | 14 ++- .../airbnb/android/react/maps/AirMapView.java | 74 +++++++++++++++- lib/components/MapView.js | 13 +++ lib/ios/AirGoogleMaps/AIRGoogleMap.h | 3 + lib/ios/AirGoogleMaps/AIRGoogleMap.m | 8 ++ lib/ios/AirGoogleMaps/AIRGoogleMapManager.h | 2 + lib/ios/AirGoogleMaps/AIRGoogleMapManager.m | 85 ++++++++++++++++++- 10 files changed, 287 insertions(+), 5 deletions(-) create mode 100644 example/examples/IndoorMap.js diff --git a/docs/mapview.md b/docs/mapview.md index edbe23a850..4f055da7a1 100644 --- a/docs/mapview.md +++ b/docs/mapview.md @@ -62,6 +62,8 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | `onMarkerDragStart` | `{ coordinate: LatLng, position: Point }` | Callback that is called when the user initiates a drag on a marker (if it is draggable) | `onMarkerDrag` | `{ coordinate: LatLng, position: Point }` | Callback called continuously as a marker is dragged | `onMarkerDragEnd` | `{ coordinate: LatLng, position: Point }` | Callback that is called when a drag on a marker finishes. This is usually the point you will want to setState on the marker's coordinate again +| `onIndoorLevelActivated` | `IndoorLevel` | Callback that is called when a level on indoor building is activated +| `onIndoorBuildingFocused` | `IndoorBuilding` | Callback that is called when a indoor building is focused/unfocused @@ -75,6 +77,7 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres | `animateToBearing` | `bearing: Number`, `duration: Number` | | `animateToViewingAngle` | `angle: Number`, `duration: Number` | | `setMapBoundaries` | `northEast: LatLng`, `southWest: LatLng` | `GoogleMaps only` +| `setIndoorActiveLevelIndex` | `levelIndex: Number` | | `fitToElements` | `animated: Boolean` | | `fitToSuppliedMarkers` | `markerIDs: String[]`, `animated: Boolean` | If you need to use this in `ComponentDidMount`, make sure you put it in a timeout or it will cause performance problems. | `fitToCoordinates` | `coordinates: Array, options: { edgePadding: EdgePadding, animated: Boolean }` | If called in `ComponentDidMount` in android, it will cause an exception. It is recommended to call it from the MapView `onLayout` event. @@ -161,3 +164,19 @@ type KmlContainer { markers: [Marker] } ``` + +``` +type IndoorBuilding { + underground: boolean, + activeLevelIndex: Number, + levels: Array, +} +``` + +``` +type IndoorLevel { + activeLevelIndex: Number, + name: String, + shortName: String, +} +``` diff --git a/example/App.js b/example/App.js index 7b6231e61d..9c000ddc95 100644 --- a/example/App.js +++ b/example/App.js @@ -42,6 +42,7 @@ import ImageOverlayWithAssets from './examples/ImageOverlayWithAssets'; import ImageOverlayWithURL from './examples/ImageOverlayWithURL'; import AnimatedNavigation from './examples/AnimatedNavigation'; import OnPoiClick from './examples/OnPoiClick'; +import IndoorMap from './examples/IndoorMap'; const IOS = Platform.OS === 'ios'; const ANDROID = Platform.OS === 'android'; @@ -162,6 +163,7 @@ class App extends React.Component { [ImageOverlayWithURL, 'Image Overlay Component with URL', true], [AnimatedNavigation, 'Animated Map Navigation', true], [OnPoiClick, 'On Poi Click', true], + [IndoorMap, 'Indoor Map', true], ] // Filter out examples that are not yet supported for Google Maps on iOS. .filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps))) diff --git a/example/examples/IndoorMap.js b/example/examples/IndoorMap.js new file mode 100644 index 0000000000..bcb6290bfc --- /dev/null +++ b/example/examples/IndoorMap.js @@ -0,0 +1,72 @@ +import React from 'react'; +import { + StyleSheet, + View, + Dimensions, + Button, + Alert, +} from 'react-native'; + import MapView from 'react-native-maps'; + const { width, height } = Dimensions.get('window'); + const ASPECT_RATIO = width / height; +const LATITUDE = 1.3039991; +const LONGITUDE = 103.8316911; +// const LATITUDE = 37.6167451; +// const LONGITUDE = -122.3876189; +const LATITUDE_DELTA = 0.003; +const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO; + class IndoorMap extends React.Component { + constructor(props) { + super(props); + this.setIndoorLevel = this.setIndoorLevel.bind(this); + } + handleIndoorFocus(event) { + const { indoorBuilding } = event.nativeEvent; + const { defaultLevelIndex, levels } = indoorBuilding; + const levelNames = levels.map(lv => lv.name || ''); + const msg = `Default Level: ${defaultLevelIndex}\nLevels: ${levelNames.toString()}`; + Alert.alert( + 'Indoor building focused', + msg + ); + } + setIndoorLevel(level) { + this.map.setIndoorActiveLevelIndex(level); + } + render() { + return ( + + { this.map = map; }} + /> +