-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathJFViewController.m
More file actions
121 lines (90 loc) · 3.66 KB
/
JFViewController.m
File metadata and controls
121 lines (90 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// JFViewController.m
// JFMapViewExample
//
// Created by Jonathan Field on 15/09/2013.
// Copyright (c) 2013 Jonathan Field. All rights reserved.
//
#import "JFViewController.h"
@interface JFViewController ()
@end
@implementation JFViewController
/*
Establish MapView delegate
Add the Gesture Recogniser to the Map
*/
- (void)viewDidLoad
{
[super viewDidLoad];
[self.mapView setDelegate:self];
[self addGestureRecogniserToMapView];
}
/*
Add a Gesture Recogniser that determines when the user has pressed the map for more than 0.5 seconds
When that action is detected, call a function to add a pin at that location
*/
- (void)addGestureRecogniserToMapView{
UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(addPinToMap:)];
lpgr.minimumPressDuration = 0.5; //
[self.mapView addGestureRecognizer:lpgr];
}
/*
Called from LongPress Gesture Recogniser, convert Screen X+Y to Longitude and Latitude then add a standard Pin at that Location.
The pin has its Title and SubTitle set to Placeholder text, you can modify this as you wish, a good idea would be to run a Geocoding block and put the street address in the SubTitle.
*/
- (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
return;
CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];
JFMapAnnotation *toAdd = [[JFMapAnnotation alloc]init];
toAdd.coordinate = touchMapCoordinate;
toAdd.subtitle = @"Subtitle";
toAdd.title = @"Title";
[self.mapView addAnnotation:toAdd];
}
/*
On the background thread, retrieve the Array of Annotations from the JSON from the next function.
On the main thread, add the annotations to the map.
*/
- (IBAction)addCitiesToMap:(id)sender{
__block NSArray *annoations;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
annoations = [self parseJSONCities];
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.mapView addAnnotations:annoations];
});
});
}
/*
Convert raw JSON to Objective-C Foundation Objects
Iterate over each returned object and create a JFMapAnnotationObject from it
Add each new Annotation to an Array and then return it.
*/
- (NSMutableArray *)parseJSONCities{
NSMutableArray *retval = [[NSMutableArray alloc]init];
NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"capitals"
ofType:@"json"];
NSData *data = [NSData dataWithContentsOfFile:jsonPath];
NSError *error = nil;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
for (JFMapAnnotation *record in json) {
JFMapAnnotation *temp = [[JFMapAnnotation alloc]init];
[temp setTitle:[record valueForKey:@"Capital"]];
[temp setSubtitle:[record valueForKey:@"Country"]];
[temp setCoordinate:CLLocationCoordinate2DMake([[record valueForKey:@"Latitude"]floatValue], [[record valueForKey:@"Longitude"]floatValue])];
[retval addObject:temp];
}
return retval;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end