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

Support Map.Overlay for iOS #2022

Merged
merged 7 commits into from
Feb 20, 2018
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion docs/overlay.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ type LatLng {
latitude: Number,
longitude: Number,
}
```
```
8 changes: 4 additions & 4 deletions example/examples/ImageOverlayWithURL.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
const OVERLAY_TOP_LEFT_COORDINATE1 = [35.68184060244454, 139.76531982421875];
const OVERLAY_BOTTOM_RIGHT_COORDINATE1 = [35.679609609368576, 139.76806640625];
const IMAGE_URL1 = 'https://maps.gsi.go.jp/xyz/std/17/116423/51613.png';
// 116423, 51614, 17
const OVERLAY_TOP_LEFT_COORDINATE2 = [35.679609609368576, 139.76531982421875];
const OVERLAY_BOTTOM_RIGHT_COORDINATE2 = [35.67737855391474, 139.76806640625];
const IMAGE_URL2 = 'https://maps.gsi.go.jp/xyz/std/17/116423/51614.png';
// 116423, 51615, 17
const OVERLAY_TOP_LEFT_COORDINATE2 = [35.67737855391474, 139.76531982421875];
const OVERLAY_BOTTOM_RIGHT_COORDINATE2 = [35.67514743608467, 139.76806640625];
const IMAGE_URL2 = 'https://maps.gsi.go.jp/xyz/std/17/116423/51615.png';

export default class ImageOverlayWithURL extends Component {

Expand Down
1 change: 1 addition & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
@property (nonatomic, strong) NSMutableArray *polylines;
@property (nonatomic, strong) NSMutableArray *circles;
@property (nonatomic, strong) NSMutableArray *tiles;
@property (nonatomic, strong) NSMutableArray *overlays;

@property (nonatomic, assign) BOOL showsBuildings;
@property (nonatomic, assign) BOOL showsTraffic;
Expand Down
10 changes: 10 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMap.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import "AIRGoogleMapPolyline.h"
#import "AIRGoogleMapCircle.h"
#import "AIRGoogleMapUrlTile.h"
#import "AIRGoogleMapOverlay.h"
#import <GoogleMaps/GoogleMaps.h>
#import <MapKit/MapKit.h>
#import <React/UIView+React.h>
Expand Down Expand Up @@ -50,6 +51,7 @@ - (instancetype)init
_polylines = [NSMutableArray array];
_circles = [NSMutableArray array];
_tiles = [NSMutableArray array];
_overlays = [NSMutableArray array];
_initialRegion = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, 0.0), MKCoordinateSpanMake(0.0, 0.0));
_region = MKCoordinateRegionMake(CLLocationCoordinate2DMake(0.0, 0.0), MKCoordinateSpanMake(0.0, 0.0));
_initialRegionSetOnLoad = false;
Expand Down Expand Up @@ -99,6 +101,10 @@ - (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex
AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview;
tile.tileLayer.map = self;
[self.tiles addObject:tile];
} else if ([subview isKindOfClass:[AIRGoogleMapOverlay class]]) {
AIRGoogleMapOverlay *overlay = (AIRGoogleMapOverlay*)subview;
overlay.overlay.map = self;
[self.overlays addObject:overlay];
} else {
NSArray<id<RCTComponent>> *childSubviews = [subview reactSubviews];
for (int i = 0; i < childSubviews.count; i++) {
Expand Down Expand Up @@ -135,6 +141,10 @@ - (void)removeReactSubview:(id<RCTComponent>)subview {
AIRGoogleMapUrlTile *tile = (AIRGoogleMapUrlTile*)subview;
tile.tileLayer.map = nil;
[self.tiles removeObject:tile];
} else if ([subview isKindOfClass:[AIRGoogleMapOverlay class]]) {
AIRGoogleMapOverlay *overlay = (AIRGoogleMapOverlay*)subview;
overlay.overlay.map = nil;
[self.overlays removeObject:overlay];
} else {
NSArray<id<RCTComponent>> *childSubviews = [subview reactSubviews];
for (int i = 0; i < childSubviews.count; i++) {
Expand Down
23 changes: 23 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// AIRGoogleMapOverlay.h
//
// Created by Taro Matsuzawa on 5/3/17.
//

#import <Foundation/Foundation.h>
#import <GoogleMaps/GoogleMaps.h>
#import <React/RCTBridge.h>
#import "AIRMapCoordinate.h"
#import "AIRGoogleMap.h"

@interface AIRGoogleMapOverlay : UIView

@property (nonatomic, strong) GMSGroundOverlay *overlay;
@property (nonatomic, copy) NSString *imageSrc;
@property (nonatomic, strong, readonly) UIImage *overlayImage;
@property (nonatomic, copy) NSArray *boundsRect;
@property (nonatomic, readonly) GMSCoordinateBounds *overlayBounds;

@property (nonatomic, weak) RCTBridge *bridge;

@end
76 changes: 76 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMapOverlay.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// AIRGoogleMapOverlay.m
// Created by Nick Italiano on 3/5/17.
//

#import "AIRGoogleMapOverlay.h"

#import <React/RCTEventDispatcher.h>
#import <React/RCTImageLoader.h>
#import <React/RCTUtils.h>
#import <React/UIView+React.h>

@interface AIRGoogleMapOverlay()
@property (nonatomic, strong, readwrite) UIImage *overlayImage;
@property (nonatomic, readwrite) GMSCoordinateBounds *overlayBounds;
@end

@implementation AIRGoogleMapOverlay {
RCTImageLoaderCancellationBlock _reloadImageCancellationBlock;
CLLocationCoordinate2D _southWest;
CLLocationCoordinate2D _northEast;
}

- (instancetype)init
{
if ((self = [super init])) {
_overlay = [[GMSGroundOverlay alloc] init];
}
return self;
}

- (void)setImageSrc:(NSString *)imageSrc
{
NSLog(@">>> SET IMAGESRC: %@", imageSrc);
_imageSrc = imageSrc;

if (_reloadImageCancellationBlock) {
_reloadImageCancellationBlock();
_reloadImageCancellationBlock = nil;
}

__weak typeof(self) weakSelf = self;
_reloadImageCancellationBlock = [_bridge.imageLoader loadImageWithURLRequest:[RCTConvert NSURLRequest:_imageSrc]
size:weakSelf.bounds.size
scale:RCTScreenScale()
clipped:YES
resizeMode:RCTResizeModeCenter
progressBlock:nil
partialLoadBlock:nil
completionBlock:^(NSError *error, UIImage *image) {
if (error) {
NSLog(@"%@", error);
}
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@">>> IMAGE: %@", image);
weakSelf.overlayImage = image;
weakSelf.overlay.icon = image;
});
}];

}

- (void)setBoundsRect:(NSArray *)boundsRect
{
_boundsRect = boundsRect;

_southWest = CLLocationCoordinate2DMake([boundsRect[1][0] doubleValue], [boundsRect[0][1] doubleValue]);
_northEast = CLLocationCoordinate2DMake([boundsRect[0][0] doubleValue], [boundsRect[1][1] doubleValue]);

_overlayBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:_southWest
coordinate:_northEast];

_overlay.bounds = _overlayBounds;
}

@end
10 changes: 10 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//
// AIRGoogleMapOverlayManager.h
// Created by Taro Matsuzawa on 3/5/17.
//

#import <Foundation/Foundation.h>
#import <React/RCTViewManager.h>

@interface AIRGoogleMapOverlayManager : RCTViewManager
@end
22 changes: 22 additions & 0 deletions lib/ios/AirGoogleMaps/AIRGoogleMapOverlayManager.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#import "AIRGoogleMapOverlayManager.h"
#import "AIRGoogleMapOverlay.h"

@interface AIRGoogleMapOverlayManager()

@end

@implementation AIRGoogleMapOverlayManager

RCT_EXPORT_MODULE()

- (UIView *)view
{
AIRGoogleMapOverlay *overlay = [AIRGoogleMapOverlay new];
overlay.bridge = self.bridge;
return overlay;
}

RCT_REMAP_VIEW_PROPERTY(bounds, boundsRect, NSArray)
RCT_REMAP_VIEW_PROPERTY(image, imageSrc, NSString)

@end
18 changes: 18 additions & 0 deletions lib/ios/AirMaps.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */ = {isa = PBXBuildFile; fileRef = 1125B2F11C4AD445007D0023 /* SMCalloutView.m */; };
19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */; };
2163AA501FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 2163AA4F1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m */; };
53D31636202E723B00B55447 /* AIRMapOverlayManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D31635202E723B00B55447 /* AIRMapOverlayManager.m */; };
53D3163A202E72FC00B55447 /* AIRMapOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D31639202E72FC00B55447 /* AIRMapOverlay.m */; };
53D3163D202E734F00B55447 /* AIRMapOverlayRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = 53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */; };
628F81201FD16DF80058313A /* AIRMapLocalTile.m in Sources */ = {isa = PBXBuildFile; fileRef = 628F811F1FD16DF80058313A /* AIRMapLocalTile.m */; };
628F81231FD16EFA0058313A /* AIRMapLocalTileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 628F81221FD16EFA0058313A /* AIRMapLocalTileManager.m */; };
62AEC4D41FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m in Sources */ = {isa = PBXBuildFile; fileRef = 62AEC4D31FD5A0AA003225E0 /* AIRMapLocalTileOverlay.m */; };
Expand Down Expand Up @@ -76,6 +79,12 @@
19DABC7E1E7C9D3C00F41150 /* RCTConvert+AirMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+AirMap.m"; sourceTree = "<group>"; };
2163AA4E1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AIRMapPolylineRenderer.h; sourceTree = "<group>"; };
2163AA4F1FEAEDD100BBEC95 /* AIRMapPolylineRenderer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AIRMapPolylineRenderer.m; sourceTree = "<group>"; };
53D31635202E723B00B55447 /* AIRMapOverlayManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlayManager.m; sourceTree = "<group>"; };
53D31637202E725E00B55447 /* AIRMapOverlayManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlayManager.h; sourceTree = "<group>"; };
53D31638202E72D500B55447 /* AIRMapOverlay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlay.h; sourceTree = "<group>"; };
53D31639202E72FC00B55447 /* AIRMapOverlay.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlay.m; sourceTree = "<group>"; };
53D3163B202E732300B55447 /* AIRMapOverlayRenderer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapOverlayRenderer.h; sourceTree = "<group>"; };
53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapOverlayRenderer.m; sourceTree = "<group>"; };
628F811E1FD16D780058313A /* AIRMapLocalTile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapLocalTile.h; sourceTree = "<group>"; };
628F811F1FD16DF80058313A /* AIRMapLocalTile.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AIRMapLocalTile.m; sourceTree = "<group>"; };
628F81211FD16EAB0058313A /* AIRMapLocalTileManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AIRMapLocalTileManager.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -158,6 +167,12 @@
628F811F1FD16DF80058313A /* AIRMapLocalTile.m */,
628F81211FD16EAB0058313A /* AIRMapLocalTileManager.h */,
628F81221FD16EFA0058313A /* AIRMapLocalTileManager.m */,
53D31638202E72D500B55447 /* AIRMapOverlay.h */,
53D31639202E72FC00B55447 /* AIRMapOverlay.m */,
53D31637202E725E00B55447 /* AIRMapOverlayManager.h */,
53D31635202E723B00B55447 /* AIRMapOverlayManager.m */,
53D3163B202E732300B55447 /* AIRMapOverlayRenderer.h */,
53D3163C202E734F00B55447 /* AIRMapOverlayRenderer.m */,
);
path = AirMaps;
sourceTree = "<group>";
Expand Down Expand Up @@ -222,13 +237,16 @@
1125B2E31C4AD3DA007D0023 /* AIRMapPolygon.m in Sources */,
1125B2E41C4AD3DA007D0023 /* AIRMapPolygonManager.m in Sources */,
1125B2DB1C4AD3DA007D0023 /* AIRMapCallout.m in Sources */,
53D31636202E723B00B55447 /* AIRMapOverlayManager.m in Sources */,
1125B2E01C4AD3DA007D0023 /* AIRMapManager.m in Sources */,
1125B2E61C4AD3DA007D0023 /* AIRMapPolylineManager.m in Sources */,
1125B2DD1C4AD3DA007D0023 /* AIRMapCircle.m in Sources */,
19DABC7F1E7C9D3C00F41150 /* RCTConvert+AirMap.m in Sources */,
1125B2E51C4AD3DA007D0023 /* AIRMapPolyline.m in Sources */,
DA6C263E1C9E324A0035349F /* AIRMapUrlTileManager.m in Sources */,
53D3163A202E72FC00B55447 /* AIRMapOverlay.m in Sources */,
628F81201FD16DF80058313A /* AIRMapLocalTile.m in Sources */,
53D3163D202E734F00B55447 /* AIRMapOverlayRenderer.m in Sources */,
1125B2DA1C4AD3DA007D0023 /* AIRMap.m in Sources */,
1125B2DF1C4AD3DA007D0023 /* AIRMapCoordinate.m in Sources */,
1125B2F21C4AD445007D0023 /* SMCalloutView.m in Sources */,
Expand Down
6 changes: 6 additions & 0 deletions lib/ios/AirMaps/AIRMap.m
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#import <QuartzCore/QuartzCore.h>
#import "AIRMapUrlTile.h"
#import "AIRMapLocalTile.h"
#import "AIRMapOverlay.h"

const CLLocationDegrees AIRMapDefaultSpan = 0.005;
const NSTimeInterval AIRMapRegionChangeObserveInterval = 0.1;
Expand Down Expand Up @@ -122,6 +123,9 @@ - (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex
} else if ([subview isKindOfClass:[AIRMapLocalTile class]]) {
((AIRMapLocalTile *)subview).map = self;
[self addOverlay:(id<MKOverlay>)subview];
} else if ([subview isKindOfClass:[AIRMapOverlay class]]) {
((AIRMapOverlay *)subview).map = self;
[self addOverlay:(id<MKOverlay>)subview];
} else {
NSArray<id<RCTComponent>> *childSubviews = [subview reactSubviews];
for (int i = 0; i < childSubviews.count; i++) {
Expand Down Expand Up @@ -149,6 +153,8 @@ - (void)removeReactSubview:(id<RCTComponent>)subview {
[self removeOverlay:(id <MKOverlay>) subview];
} else if ([subview isKindOfClass:[AIRMapLocalTile class]]) {
[self removeOverlay:(id <MKOverlay>) subview];
} else if ([subview isKindOfClass:[AIRMapOverlay class]]) {
[self removeOverlay:(id <MKOverlay>) subview];
} else {
NSArray<id<RCTComponent>> *childSubviews = [subview reactSubviews];
for (int i = 0; i < childSubviews.count; i++) {
Expand Down
21 changes: 21 additions & 0 deletions lib/ios/AirMaps/AIRMapManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#import "AIRMapLocalTile.h"
#import "AIRMapSnapshot.h"
#import "RCTConvert+AirMap.h"
#import "AIRMapOverlay.h"

#import <MapKit/MapKit.h>

Expand Down Expand Up @@ -456,6 +457,24 @@ - (void)handleMapTap:(UITapGestureRecognizer *)recognizer {
}
}
}

if ([overlay isKindOfClass:[AIRMapOverlay class]]) {
AIRMapOverlay *imageOverlay = (AIRMapOverlay*) overlay;
if (MKMapRectContainsPoint(imageOverlay.boundingMapRect, mapPoint)) {
if (imageOverlay.onPress) {
id event = @{
@"action": @"image-overlay-press",
@"name": imageOverlay.name ?: @"unknown",
@"coordinate": @{
@"latitude": @(imageOverlay.coordinate.latitude),
@"longitude": @(imageOverlay.coordinate.longitude)
}
};
imageOverlay.onPress(event);
}
}
}

}

if (nearestDistance <= maxMeters) {
Expand Down Expand Up @@ -537,6 +556,8 @@ - (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id <MKOv
return ((AIRMapUrlTile *)overlay).renderer;
} else if ([overlay isKindOfClass:[AIRMapLocalTile class]]) {
return ((AIRMapLocalTile *)overlay).renderer;
} else if ([overlay isKindOfClass:[AIRMapOverlay class]]) {
return ((AIRMapOverlay *)overlay).renderer;
} else if([overlay isKindOfClass:[MKTileOverlay class]]) {
return [[MKTileOverlayRenderer alloc] initWithTileOverlay:overlay];
} else {
Expand Down
36 changes: 36 additions & 0 deletions lib/ios/AirMaps/AIRMapOverlay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#import "AIRMapCallout.h"

#import <MapKit/MapKit.h>
#import <UIKit/UIKit.h>

#import "RCTConvert+AirMap.h"
#import <React/RCTComponent.h>
#import "AIRMap.h"
#import "AIRMapOverlayRenderer.h"

@class RCTBridge;

@interface AIRMapOverlay : UIView <MKOverlay>

@property (nonatomic, strong) AIRMapOverlayRenderer *renderer;
@property (nonatomic, weak) AIRMap *map;
@property (nonatomic, weak) RCTBridge *bridge;

@property (nonatomic, strong) NSString *name;
@property (nonatomic, copy) NSString *imageSrc;
@property (nonatomic, strong, readonly) UIImage *overlayImage;
@property (nonatomic, copy) NSArray *boundsRect;
@property (nonatomic, assign) NSInteger rotation;
@property (nonatomic, assign) CGFloat transparency;
@property (nonatomic, assign) NSInteger zIndex;

@property (nonatomic, copy) RCTBubblingEventBlock onPress;

#pragma mark MKOverlay protocol

@property(nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property(nonatomic, readonly) MKMapRect boundingMapRect;
- (BOOL)intersectsMapRect:(MKMapRect)mapRect;
- (BOOL)canReplaceMapContent;

@end
Loading