Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Android support for onPoiClick #2050

Merged
merged 6 commits into from
Mar 10, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ To run examples:

```bash
npm i
npm start
npm start

#Android
npm run run:android
Expand Down Expand Up @@ -397,6 +397,12 @@ Enable lite mode on Android with `liteMode` prop. Ideal when having multiple map

![](http://i.giphy.com/qZ2lAf18s89na.gif)

### On Poi Click (Google Maps Only)

Poi are clickable, you can catch the event to get its information (usually to get the full detail from Google Place using the placeId).

![](https://media.giphy.com/media/3480VsCKnHr31uCLU3/giphy.gif)

### Animated Region

The MapView can accept an `AnimatedRegion` value as its `region` prop. This allows you to utilize the Animated API to control the map's center and zoom.
Expand Down
1 change: 1 addition & 0 deletions docs/mapview.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ To access event data, you will need to use `e.nativeEvent`. For example, `onPres
| `onRegionChangeComplete` | `Region` | Callback that is called once when the region changes, such as when the user is done moving the map.
| `onPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user taps on the map.
| `onPanDrag` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user presses and drags the map. **NOTE**: for iOS `scrollEnabled` should be set to false to trigger the event
| `onPoiClick` | `{ coordinate: LatLng, position: Point, placeId: string, name: string }` | Callback that is called when user click on a POI. **NOTE**: Android only (IOS soon)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have iOS now, right? So the soon line can be removed

| `onLongPress` | `{ coordinate: LatLng, position: Point }` | Callback that is called when user makes a "long press" somewhere on the map.
| `onMarkerPress` | | Callback that is called when a marker on the map is tapped by the user.
| `onMarkerSelect` | | Callback that is called when a marker on the map becomes selected. This will be called when the callout for that marker is about to be shown. **Note**: iOS only.
Expand Down
2 changes: 2 additions & 0 deletions example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import MapKml from './examples/MapKml';
import BugMarkerWontUpdate from './examples/BugMarkerWontUpdate';
import ImageOverlayWithAssets from './examples/ImageOverlayWithAssets';
import ImageOverlayWithURL from './examples/ImageOverlayWithURL';
import OnPoiClick from './examples/OnPoiClick';

const IOS = Platform.OS === 'ios';
const ANDROID = Platform.OS === 'android';
Expand Down Expand Up @@ -158,6 +159,7 @@ class App extends React.Component {
[BugMarkerWontUpdate, 'BUG: Marker Won\'t Update (Android)', true],
[ImageOverlayWithAssets, 'Image Overlay Component with Assets', true],
[ImageOverlayWithURL, 'Image Overlay Component with URL', true],
[OnPoiClick, 'On Poi Click', true],
]
// Filter out examples that are not yet supported for Google Maps on iOS.
.filter(example => ANDROID || (IOS && (example[2] || !this.state.useGoogleMaps)))
Expand Down
86 changes: 86 additions & 0 deletions example/examples/OnPoiClick.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React from 'react';
import {
StyleSheet,
View,
Text,
Dimensions,
} from 'react-native';

import MapView, { Callout, Marker, ProviderPropType } from 'react-native-maps';

const { width, height } = Dimensions.get('window');

const ASPECT_RATIO = width / height;
const LATITUDE = 37.78825;
const LONGITUDE = -122.4324;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;

class OnPoiClick extends React.Component {
constructor(props) {
super(props);

this.state = {
region: {
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA,
},
poi: null,
};

this.onPoiClick = this.onPoiClick.bind(this);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use an arrow function the bind is not needed, but it's up to you :)

}

onPoiClick(e) {
const poi = e.nativeEvent;

this.setState({
poi,
});
}

render() {
return (
<View style={styles.container}>
<MapView
provider={this.props.provider}
style={styles.map}
initialRegion={this.state.region}
onPoiClick={this.onPoiClick}
>
{this.state.poi && (
<Marker
coordinate={this.state.poi.coordinate}
>
<Callout>
<View>
<Text>Place Id: { this.state.poi.placeId }</Text>
<Text>Name: { this.state.poi.name }</Text>
</View>
</Callout>
</Marker>
)}
</MapView>
</View>
);
}
}

OnPoiClick.propTypes = {
provider: ProviderPropType,
};

const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
justifyContent: 'flex-end',
alignItems: 'center',
},
map: {
...StyleSheet.absoluteFillObject,
},
});

export default OnPoiClick;
1 change: 1 addition & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ declare module "react-native-maps" {
onMarkerDragStart?: (value: { coordinate: LatLng, position: Point }) => void;
onMarkerDrag?: (value: { coordinate: LatLng, position: Point }) => void;
onMarkerDragEnd?: (value: { coordinate: LatLng, position: Point }) => void;
onPoiClick?: (value: {coordinate: LatLng, position: Point, placeId: string, name: string }) => void;
minZoomLevel?: number;
maxZoomLevel?: number;
kmlSrc?: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,8 @@ public Map getExportedCustomDirectEventTypeConstants() {
"onMarkerDrag", MapBuilder.of("registrationName", "onMarkerDrag"),
"onMarkerDragEnd", MapBuilder.of("registrationName", "onMarkerDragEnd"),
"onPanDrag", MapBuilder.of("registrationName", "onPanDrag"),
"onKmlReady", MapBuilder.of("registrationName", "onKmlReady")
"onKmlReady", MapBuilder.of("registrationName", "onKmlReady"),
"onPoiClick", MapBuilder.of("registrationName", "onPoiClick")
));

return map;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PointOfInterest;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.Polyline;
import com.google.maps.android.data.kml.KmlContainer;
Expand All @@ -63,7 +64,7 @@
import static android.support.v4.content.PermissionChecker.checkSelfPermission;

public class AirMapView extends MapView implements GoogleMap.InfoWindowAdapter,
GoogleMap.OnMarkerDragListener, OnMapReadyCallback {
GoogleMap.OnMarkerDragListener, OnMapReadyCallback, GoogleMap.OnPoiClickListener {
public GoogleMap map;
private KmlLayer kmlLayer;
private ProgressBar mapLoadingProgressBar;
Expand Down Expand Up @@ -177,6 +178,7 @@ public void onMapReady(final GoogleMap map) {
this.map = map;
this.map.setInfoWindowAdapter(this);
this.map.setOnMarkerDragListener(this);
this.map.setOnPoiClickListener(this);

manager.pushEvent(context, this, "onMapReady", new WritableNativeMap());

Expand Down Expand Up @@ -788,6 +790,16 @@ public void onMarkerDragEnd(Marker marker) {
manager.pushEvent(context, markerView, "onDragEnd", event);
}

@Override
public void onPoiClick(PointOfInterest poi) {
WritableMap event = makeClickEventData(poi.latLng);

event.putString("placeId", poi.placeId);
event.putString("name", poi.name);

manager.pushEvent(context, this, "onPoiClick", event);
}

private ProgressBar getMapLoadingProgressBar() {
if (this.mapLoadingProgressBar == null) {
this.mapLoadingProgressBar = new ProgressBar(getContext());
Expand Down
5 changes: 5 additions & 0 deletions lib/components/MapView.js
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,11 @@ const propTypes = {
*/
onPanDrag: PropTypes.func,

/**
* Callback that is called when user click on a POI
*/
onPoiClick: PropTypes.func,

/**
* Callback that is called when a marker on the map is tapped by the user.
*/
Expand Down
2 changes: 2 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
@property (nonatomic, copy) RCTBubblingEventBlock onLongPress;
@property (nonatomic, copy) RCTBubblingEventBlock onMarkerPress;
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
@property (nonatomic, copy) RCTBubblingEventBlock onPoiClick;
@property (nonatomic, copy) RCTDirectEventBlock onRegionChange;
@property (nonatomic, copy) RCTDirectEventBlock onRegionChangeComplete;
@property (nonatomic, strong) NSMutableArray *markers;
Expand Down Expand Up @@ -56,6 +57,7 @@
- (void)didLongPressAtCoordinate:(CLLocationCoordinate2D)coordinate;
- (void)didChangeCameraPosition:(GMSCameraPosition *)position;
- (void)idleAtCameraPosition:(GMSCameraPosition *)position;
- (void)didTapPOIWithPlaceID:(NSString *)placeID name:(NSString *) name location:(CLLocationCoordinate2D) location;

+ (MKCoordinateRegion)makeGMSCameraPositionFromMap:(GMSMapView *)map andGMSCameraPosition:(GMSCameraPosition *)position;
+ (GMSCameraPosition*)makeGMSCameraPositionFromMap:(GMSMapView *)map andMKCoordinateRegion:(MKCoordinateRegion)region;
Expand Down
36 changes: 25 additions & 11 deletions lib/ios/AirGoogleMaps/AIRGoogleMap.m
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,20 @@ - (void)didChangeCameraPosition:(GMSCameraPosition *)position {
if (self.onChange) self.onChange(event);
}

- (void)didTapPOIWithPlaceID:(NSString *)placeID
name:(NSString *)name
location:(CLLocationCoordinate2D)location {
id event = @{@"placeId": placeID,
@"name": name,
@"coordinate": @{
@"latitude": @(location.latitude),
@"longitude": @(location.longitude)
}
};

if (self.onPoiClick) self.onPoiClick(event);
}

- (void)idleAtCameraPosition:(GMSCameraPosition *)position {
id event = @{@"continuous": @NO,
@"region": regionAsJSON([AIRGoogleMap makeGMSCameraPositionFromMap:self andGMSCameraPosition:position]),
Expand Down Expand Up @@ -417,7 +431,7 @@ + (NSString *)GetIconUrl:(GMUPlacemark *) marker parser:(GMUKMLParser *) parser
}
}
}

return marker.style.iconUrl;
}

Expand All @@ -426,28 +440,28 @@ - (NSString *)KmlSrc {
}

- (void)setKmlSrc:(NSString *)kmlUrl {

_kmlSrc = kmlUrl;

NSURL *url = [NSURL URLWithString:kmlUrl];
NSData *urlData = nil;

if ([url isFileURL]) {
urlData = [NSData dataWithContentsOfURL:url];
} else {
urlData = [[NSFileManager defaultManager] contentsAtPath:kmlUrl];
}

GMUKMLParser *parser = [[GMUKMLParser alloc] initWithData:urlData];
[parser parse];

NSUInteger index = 0;
NSMutableArray *markers = [[NSMutableArray alloc]init];

for (GMUPlacemark *place in parser.placemarks) {

CLLocationCoordinate2D location =((GMUPoint *) place.geometry).coordinate;

AIRGoogleMapMarker *marker = (AIRGoogleMapMarker *)[[AIRGoogleMapMarkerManager alloc] view];
if (!marker.bridge) {
marker.bridge = _bridge;
Expand All @@ -460,9 +474,9 @@ - (void)setKmlSrc:(NSString *)kmlUrl {
marker.imageSrc = [AIRGoogleMap GetIconUrl:place parser:parser];
marker.layer.backgroundColor = [UIColor clearColor].CGColor;
marker.layer.position = CGPointZero;

[self insertReactSubview:(UIView *) marker atIndex:index];

[markers addObject:@{@"id": marker.identifier,
@"title": marker.title,
@"description": marker.subtitle,
Expand All @@ -474,7 +488,7 @@ - (void)setKmlSrc:(NSString *)kmlUrl {

index++;
}

id event = @{@"markers": markers};
if (self.onKmlReady) self.onKmlReady(event);
}
Expand Down
21 changes: 15 additions & 6 deletions lib/ios/AirGoogleMaps/AIRGoogleMapManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(onMarkerPress, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onRegionChange, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onRegionChangeComplete, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(onPoiClick, RCTDirectEventBlock)
RCT_EXPORT_VIEW_PROPERTY(mapType, GMSMapViewType)
RCT_EXPORT_VIEW_PROPERTY(minZoomLevel, CGFloat)
RCT_EXPORT_VIEW_PROPERTY(maxZoomLevel, CGFloat)
Expand Down Expand Up @@ -303,16 +304,16 @@ - (UIView *)view
[coordinate[@"latitude"] doubleValue],
[coordinate[@"longitude"] doubleValue]
);

[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
id view = viewRegistry[reactTag];
if (![view isKindOfClass:[AIRGoogleMap class]]) {
RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
} else {
AIRGoogleMap *mapView = (AIRGoogleMap *)view;

CGPoint touchPoint = [mapView.projection pointForCoordinate:coord];

callback(@[[NSNull null], @{
@"x": @(touchPoint.x),
@"y": @(touchPoint.y),
Expand All @@ -329,16 +330,16 @@ - (UIView *)view
[point[@"x"] doubleValue],
[point[@"y"] doubleValue]
);

[self.bridge.uiManager addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
id view = viewRegistry[reactTag];
if (![view isKindOfClass:[AIRGoogleMap class]]) {
RCTLogError(@"Invalid view returned from registry, expecting AIRMap, got: %@", view);
} else {
AIRGoogleMap *mapView = (AIRGoogleMap *)view;

CLLocationCoordinate2D coordinate = [mapView.projection coordinateForPoint:pt];

callback(@[[NSNull null], @{
@"latitude": @(coordinate.latitude),
@"longitude": @(coordinate.longitude),
Expand Down Expand Up @@ -436,4 +437,12 @@ - (void)mapView:(GMSMapView *)mapView didDragMarker:(GMSMarker *)marker {
AIRGMSMarker *aMarker = (AIRGMSMarker *)marker;
[aMarker.fakeMarker didDragMarker:aMarker];
}

- (void)mapView:(GMSMapView *)mapView
didTapPOIWithPlaceID:(NSString *)placeID
name:(NSString *)name
location:(CLLocationCoordinate2D)location {
AIRGoogleMap *googleMapView = (AIRGoogleMap *)mapView;
[googleMapView didTapPOIWithPlaceID:placeID name:name location:location];
}
@end