Skip to content

Commit

Permalink
Add search & forwardGeocode
Browse files Browse the repository at this point in the history
  • Loading branch information
designbymind authored Sep 24, 2023
1 parent b011480 commit 4871a3e
Showing 1 changed file with 141 additions and 4 deletions.
145 changes: 141 additions & 4 deletions ios/Classes/TiMapModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import "TiBlob.h"
#import "TiMapCameraProxy.h"
#import "TiMapConstants.h"
#import "TiMapUtils.h"
#import "TiMapViewProxy.h"

@implementation TiMapModule
Expand Down Expand Up @@ -89,16 +90,12 @@ - (void)openLookAroundDialog:(id)args
return;
}

KrollCallback *callback = (KrollCallback *)args[@"callback"];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake([TiUtils doubleValue:args[@"latitude"]], [TiUtils doubleValue:args[@"longitude"]]);

MKLookAroundSceneRequest *request = [[MKLookAroundSceneRequest alloc] initWithCoordinate:coordinate];

[request getSceneWithCompletionHandler:^(MKLookAroundScene *_Nullable_result scene, NSError *_Nullable error) {
if (error != nil) {
[callback call:@[ @{@"success" : @(NO),
@"error" : error.localizedDescription} ]
thisObject:self];
return;
}

Expand All @@ -120,6 +117,142 @@ - (void)lookAroundViewControllerDidPresentFullScreen:(MKLookAroundViewController

#endif

- (MKLocalSearchCompleter *)searchCompleter
{
if (_searchCompleter == nil) {
_searchCompleter = [[MKLocalSearchCompleter alloc] init];
_searchCompleter.delegate = self;
}

return _searchCompleter;
}

- (void)search:(id)args
{
ENSURE_UI_THREAD(search, args);

NSString *value = [TiUtils stringValue:args[0]];

// Require a search value
if (!value) {
[self throwException:@"Missing required search value" subreason:@"Please provide the value as a String" location:CODELOCATION];
return;
}

// Pass additional options like search region
if ([args count] > 1) {
NSDictionary *options = (NSDictionary *)args[1];
if (options == nil) {
[self throwException:@"Options have to be called within an Object" subreason:@"Please provide the value as an Object" location:CODELOCATION];
}

// Handle search region
if (options[@"region"]) {
NSDictionary<NSString *, NSNumber *> *region = options[@"region"];
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake([TiUtils doubleValue:region[@"latitude"]], [TiUtils doubleValue:region[@"longitude"]]);
MKCoordinateSpan span = MKCoordinateSpanMake([TiUtils doubleValue:region[@"latitudeDelta"]], [TiUtils doubleValue:region[@"longitudeDelta"]]);

if (CLLocationCoordinate2DIsValid(coordinate)) {
[[self searchCompleter] setRegion:MKCoordinateRegionMake(coordinate, span)];
}
}

// Handle filter types
if ([TiUtils isIOSVersionOrGreater:@"13.0"] && options[@"resultTypes"]) {
if (@available(iOS 13.0, *)) {
_searchCompleter.resultTypes = [TiMapUtils mappedResultTypes:options[@"resultTypes"]];
} else {
NSLog(@"[ERROR] The \"resultTypes\" options are only available on iOS 13+");
}
}
}

[[self searchCompleter] setQueryFragment:value];
}

- (void)geocodeAddress:(id)args
{
NSString *address = (NSString *)args[0];
KrollCallback *callback = (KrollCallback *)args[1];

CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:address
completionHandler:^(NSArray<CLPlacemark *> *_Nullable placemarks, NSError *_Nullable error) {
if (placemarks.count == 0 || error != nil) {
[callback call:@[ @{@"success" : @(NO),
@"error" : error.localizedDescription ?: @"Unknown error"} ]
thisObject:self];
return;
}

CLPlacemark *place = placemarks[0];

NSDictionary<NSString *, id> *proxyPlace = @{
@"name": NULL_IF_NIL(place.name),
@"street": NULL_IF_NIL([self formattedStreetNameFromPlace:place]),
@"thoroughfare": NULL_IF_NIL(place.thoroughfare),
@"subThoroughfare": NULL_IF_NIL(place.subThoroughfare),
@"postalCode": NULL_IF_NIL(place.postalCode),
@"city": NULL_IF_NIL(place.locality),
@"subLocality": NULL_IF_NIL(place.subLocality),
@"country": NULL_IF_NIL(place.country),
@"state": NULL_IF_NIL(place.administrativeArea),
@"subAdministrativeArea": NULL_IF_NIL(place.subAdministrativeArea),
@"latitude": @(place.location.coordinate.latitude),
@"longitude": @(place.location.coordinate.longitude),
};

[callback call:@[ @{@"success" : @(YES),
@"place" : proxyPlace} ]
thisObject:self];
}];
}

- (NSString *)formattedStreetNameFromPlace:(CLPlacemark *)place
{
if (place.thoroughfare == nil) {
return nil;
} else if (place.subThoroughfare == nil) {
return place.thoroughfare;
}

return [NSString stringWithFormat:@"%@ %@", place.thoroughfare, place.subThoroughfare];
}

- (void)completer:(MKLocalSearchCompleter *)completer didFailWithError:(NSError *)error
{
[self fireEvent:@"didUpdateResults" withObject:@{ @"results" : @[], @"error" : error.localizedDescription }];
}

- (void)completerDidUpdateResults:(MKLocalSearchCompleter *)completer
{
NSMutableArray<NSDictionary<NSString *, id> *> *proxyResults = [NSMutableArray arrayWithCapacity:completer.results.count];

[completer.results enumerateObjectsUsingBlock:^(MKLocalSearchCompletion *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
NSMutableArray<NSDictionary<NSString *, NSNumber *> *> *titleHighlightRanges = [NSMutableArray arrayWithCapacity:obj.titleHighlightRanges.count];
NSMutableArray<NSDictionary<NSString *, NSNumber *> *> *subtitleHighlightRanges = [NSMutableArray arrayWithCapacity:obj.subtitleHighlightRanges.count];

[obj.titleHighlightRanges enumerateObjectsUsingBlock:^(NSValue *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
[titleHighlightRanges addObject:@{@"offset" : @(obj.rangeValue.location),
@"length" : @(obj.rangeValue.length)}];
}];

[obj.subtitleHighlightRanges enumerateObjectsUsingBlock:^(NSValue *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) {
[subtitleHighlightRanges addObject:@{@"offset" : @(obj.rangeValue.location),
@"length" : @(obj.rangeValue.length)}];
}];

[proxyResults addObject:@{
@"title" : obj.title,
@"subtitle" : obj.subtitle,
@"titleHighlightRanges" : titleHighlightRanges,
@"subtitleHighlightRanges" : subtitleHighlightRanges
}];
}];

[self fireEvent:@"didUpdateResults" withObject:@{ @"results" : proxyResults }];
}

MAKE_SYSTEM_PROP(STANDARD_TYPE, MKMapTypeStandard);
MAKE_SYSTEM_PROP(NORMAL_TYPE, MKMapTypeStandard); // For parity with Android
MAKE_SYSTEM_PROP(SATELLITE_TYPE, MKMapTypeSatellite);
Expand Down Expand Up @@ -168,4 +301,8 @@ - (void)lookAroundViewControllerDidPresentFullScreen:(MKLookAroundViewController
MAKE_SYSTEM_PROP(FEATURE_POINT_OF_INTEREST, MKMapFeatureOptionPointsOfInterest);
#endif

MAKE_SYSTEM_PROP(SEARCH_RESULT_TYPE_ADDRESS, MKLocalSearchCompleterResultTypeAddress);
MAKE_SYSTEM_PROP(SEARCH_RESULT_TYPE_POINT_OF_INTEREST, MKLocalSearchCompleterResultTypePointOfInterest);
MAKE_SYSTEM_PROP(SEARCH_RESULT_TYPE_QUERY, MKLocalSearchCompleterResultTypeQuery);

@end

0 comments on commit 4871a3e

Please sign in to comment.