NSArrayM was mutated while being enumerated - iphone

App crashes with error:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x21481c10> was mutated while being enumerated.'
This happen only if I move over mapview when my annotations is loading. If I doesn't touch map, no error occurred.
- (void) startloading
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
[self loadPList];
});
}
my code is:
- (void) loadPList
{
#autoreleasepool {
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"test.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSMutableArray * annotationsToRemove = [ mapView.annotations mutableCopy ] ;
[ annotationsToRemove removeObject:mapView.userLocation ] ;
[ mapView removeAnnotations:annotationsToRemove ] ;
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"blackKey"])
{
NSArray *ann = [dict objectForKey:#"Black"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:#"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:#"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:#"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:#"Icon"];
[mapView addAnnotation:myAnnotation]; // SIGNAL SIGABRT
[annotations addObject:myAnnotation];
}
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"blueyellowKey"])
{
NSArray *ann = [dict objectForKey:#"BlueYellow"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:#"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:#"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:#"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:#"Icon"];
[mapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
}
}
}
}

I think you should change your loadPlist method to this, and then just call [self loadPlist] to invoke it:
- (void) loadPList
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"test.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
//ALL THIS CODE FROM HERE ON OUT IS NOT THREAD SAFE! YOU ARE ACCESSING THE UI AND MUST PERFORM IT ON THE MAIN THREAD!
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *annotations = [[NSMutableArray alloc]init];
NSMutableArray * annotationsToRemove = [ mapView.annotations mutableCopy ] ;
[ annotationsToRemove removeObject:mapView.userLocation ] ;
[ mapView removeAnnotations:annotationsToRemove ] ;
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"blackKey"])
{
NSArray *ann = [dict objectForKey:#"Black"];
for(int i = 0; i < [ann count]; i++) {
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:#"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:#"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:#"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:#"Icon"];
[mapView addAnnotation:myAnnotation]; // SIGNAL SIGABRT
[annotations addObject:myAnnotation];
}
}
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"blueyellowKey"])
{
NSArray *ann = [dict objectForKey:#"BlueYellow"];
for(int i = 0; i < [ann count]; i++)
{
NSString *coordinates = [[ann objectAtIndex:i] objectForKey:#"Coordinates"];
double realLatitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:1] doubleValue];
double realLongitude = [[[coordinates componentsSeparatedByString:#","] objectAtIndex:0] doubleValue];
MyAnnotation *myAnnotation = [[MyAnnotation alloc] init];
CLLocationCoordinate2D theCoordinate;
theCoordinate.latitude = realLatitude;
theCoordinate.longitude = realLongitude;
myAnnotation.coordinate=CLLocationCoordinate2DMake(realLatitude,realLongitude);
myAnnotation.title = [[ann objectAtIndex:i] objectForKey:#"Name"];
myAnnotation.subtitle = [[ann objectAtIndex:i] objectForKey:#"Address"];
myAnnotation.icon = [[ann objectAtIndex:0] objectForKey:#"Icon"];
[mapView addAnnotation:myAnnotation];
[annotations addObject:myAnnotation];
}
}
}
});
}
This performs the IO work of reading in the annotations in the background, and then passes off the UI work back to the main thread. Hope this helps!

Related

Draw Map Path among multiple location

I am new in iphone development, i want to draw path between 5 location how i can draw path in google map.
I want path from location1 to location2 , location2 to location3, location3 to location4 and location4 to location5.
here is my code
- (void)viewDidLoad {
[super viewDidLoad];
NSDictionary *d1,*d2,*d3,*d4,*d5;
d1=[NSDictionary dictionaryWithObjectsAndKeys:#"location1",#"comments",#"1",#"id",#"23.02941395",#"latitude",#"72.54620655",#"longitude",nil];
d2=[NSDictionary dictionaryWithObjectsAndKeys:#"location2",#"comments",#"2",#"id",#"23.028359049999995",#"latitude",#"72.54537318333334",#"longitude",nil];
d3=[NSDictionary dictionaryWithObjectsAndKeys:#"location3",#"comments",#"3",#"id",#"23.029545",#"latitude",#"72.546036",#"longitude",nil];
d4=[NSDictionary dictionaryWithObjectsAndKeys:#"location4",#"comments",#"4",#"id",#"23.030050",#"latitude",#"72.546226",#"longitude",nil];
d5=[NSDictionary dictionaryWithObjectsAndKeys:#"location5",#"comments",#"5",#"id",#"23.030050",#"latitude",#"72.546022",#"longitude",nil];
self.reports=[NSArray arrayWithObjects:d1,d2,d3,d4,d5,nil];
for (NSDictionary *d in self.reports) {
float latitude=[[d valueForKey:#"latitude"] floatValue];
float longitude=[[d valueForKey:#"longitude"] floatValue];
Place* home = [[[Place alloc] init] autorelease];
home.name = [d valueForKey:#"comments"];
home.latitude = latitude;
home.longitude = longitude;
PlaceMark *from = [[[PlaceMark alloc] initWithPlace:home] autorelease];
[mapView addAnnotation:from];
}
[self centerMap];
}
-(void) centerMap
{
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90;
CLLocationDegrees maxLon = -180;
CLLocationDegrees minLat = 120;
CLLocationDegrees minLon = 150;
NSMutableArray *temp=[NSArray arrayWithArray:self.reports];
NSLog(#"%#",temp);
for (int i=0; i<[temp count];i++) {
Place* home = [[[Place alloc] init] autorelease];
home.latitude = [[[temp objectAtIndex:i] valueForKey:#"latitude"]floatValue];
home.longitude =[[[temp objectAtIndex:i] valueForKey:#"longitude"]floatValue];
PlaceMark* from = [[[PlaceMark alloc] initWithPlace:home] autorelease];
CLLocation* currentLocation = (CLLocation*)from ;
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
region.center.latitude = (maxLat + minLat) / 2;
region.center.longitude = (maxLon + minLon) / 2;
region.span.latitudeDelta = maxLat - minLat;
region.span.longitudeDelta = maxLon - minLon;
}
[mapView setRegion:region animated:YES];
}
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if (annotation == mapView.userLocation)
return nil;
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: #"asdf"];
if (pin == nil)
pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier: #"asdf"] autorelease];
else
pin.annotation = annotation;
pin.userInteractionEnabled = YES;
UIButton *disclosureButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[disclosureButton setFrame:CGRectMake(0, 0, 30, 30)];
pin.rightCalloutAccessoryView = disclosureButton;
pin.pinColor = MKPinAnnotationColorRed;
//pin.animatesDrop = YES;
[pin setEnabled:YES];
[pin setCanShowCallout:YES];
return pin;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSString *strTitle = [NSString stringWithFormat:#"%#",[view.annotation title]];
NSMutableDictionary *d;
NSMutableArray *temp=[NSArray arrayWithArray:self.reports];
for (int i = 0; i<[temp count]; i++)
{
d = (NSMutableDictionary*)[temp objectAtIndex:i];
NSString *strAddress = [NSString stringWithFormat:#"%#",[d valueForKey:#"comments"]];
if([strAddress isEqualToString:strTitle]) {
[self presentModalViewController:self.nxtDetailsVCtr animated:YES];
[self.nxtDetailsVCtr.lblDetail setText:strAddress];
break;
}
}
}
You can use NVPlolineAnnotation to draw line inside the map. Here is the Source Code.
Frameworks needed
QuartzCore.framework
CoreLocation.framework
MapKit.framework
Files Needed
JSONKit.h
JSONKit.m
Set -fno-objc-arc in compile source for JSON in case of ARC.
In header File
__block IBOutlet MKMapView *__mapView;
NSArray* routes;
MKPointAnnotation *startLocation;
MKPointAnnotation *endLocation;
MKPolyline *polyLine;
Implementation piece of code...
- (void)viewDidLoad
{
// [__mapView setShowsUserLocation:YES];
[__mapView setZoomEnabled:YES];
[__mapView setScrollEnabled:YES];
[__mapView setMapType:MKMapTypeStandard];
[__mapView setDelegate:self];
routes=[[NSArray alloc] init];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)drawPath:(id)sender {
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
[self showRouteFrom:startLocation to:endLocation];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
if (polyLine) {
[__mapView setVisibleMapRect:[polyLine boundingMapRect]];
[__mapView addOverlay:polyLine];
[self centerMap];
}
NSLog(#"drawing path completed");
});
});
}
-(void) showRouteFrom: (id<MKAnnotation>)source to:(id<MKAnnotation>)destination;
{
if(routes)
{
[__mapView removeAnnotations:[__mapView annotations]];
}
[__mapView addAnnotation:source];
[__mapView addAnnotation:destination];
NSLog(#"source title is %#",source.title);
NSLog(#"destination title is %#",destination.title);
routes = [self calculateRoutesFrom:source.coordinate to:destination.coordinate];
NSLog(#"routes are %#",routes);
NSInteger numberOfSteps = routes.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [routes objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
NSLog(#"poly line to be added as ovelay is %#",polyLine);
}
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t
{
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false&avoid=highways&mode=",saddr,daddr];
NSLog(#"Fired API %#",apiUrlStr);
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSDictionary *dic=[apiResponse objectFromJSONString];
if (dic!=nil) {
NSArray *routPoints=[[NSArray alloc] initWithArray:[dic valueForKey:#"routes"]];
NSDictionary *polylineOverview=[[routPoints objectAtIndex:0] valueForKey:#"overview_polyline"];
NSString *polylinePoints = [polylineOverview objectForKey:#"points"];
return [self decodePolyLine:[polylinePoints mutableCopy]];
}
return nil;
}
- (NSMutableArray *)decodePolyLine: (NSMutableString *)encoded
{
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\" options:NSLiteralSearch range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len)
{
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
//printf("[%f,", [latitude doubleValue]);
//printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
#pragma mark- MKMapView delegate method
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor purpleColor];
polylineView.lineWidth = 5.0;
NSLog(#"polyline in viewFor overlay: %#",polylineView);
return polylineView;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"did update user location called ");
MKCoordinateRegion region;
region.span.latitudeDelta = .005;
region.span.longitudeDelta = .005;
region.center = userLocation.coordinate;
[mapView setRegion:region animated:YES];
}
-(void) centerMap
{
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90.0;
CLLocationDegrees maxLon = -180.0;
CLLocationDegrees minLat = 90.0;
CLLocationDegrees minLon = 180.0;
for(int idx = 0; idx < routes.count; idx++)
{
CLLocation* currentLocation = [routes objectAtIndex:idx];
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
}
region.center.latitude = (maxLat + minLat) / 2.0;
region.center.longitude = (maxLon + minLon) / 2.0;
region.span.latitudeDelta = 0.01;
region.span.longitudeDelta = 0.01;
region.span.latitudeDelta = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat);
region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon);
[__mapView setRegion:region animated:YES];
}
#pragma mark- UITextField delegate method
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[self.view bringSubviewToFront:textField];
CGRect rect=textField.frame;
[[NSUserDefaults standardUserDefaults] setValue:NSStringFromCGRect(rect) forKey:#"textFieldRect"];
rect.origin.y=self.view.frame.size.height-260;
[UIView animateWithDuration:0.3 animations:^{
[textField setFrame:rect];
}];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
NSString *rectStr=[[NSUserDefaults standardUserDefaults] valueForKey:#"textFieldRect"];
NSArray *rectArray=[rectStr componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"{,} "]];
CGRect rect;
rect.origin.x=[[rectArray objectAtIndex:2] floatValue];
rect.origin.y=[[rectArray objectAtIndex:4] floatValue];
rect.size.width=[[rectArray objectAtIndex:8] floatValue];
rect.size.height=[[rectArray objectAtIndex:10] floatValue];
[UIView animateWithDuration:0.3 animations:^{
[textField setFrame:rect];
}];
[textField resignFirstResponder];
return YES;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
NSDictionary *locationDic=[self getLatLongOfPlace:[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSDictionary *latLongDic=[[[[[locationDic valueForKey:#"results"] objectAtIndex:0] valueForKey:#"geometry"]valueForKey:#"viewport"] valueForKey:#"northeast"];
if (textField.tag==0) {
startLocation=[[MKPointAnnotation alloc] init];
[startLocation setCoordinate:CLLocationCoordinate2DMake([[latLongDic valueForKey:#"lat"] floatValue], [[latLongDic valueForKey:#"lng"] floatValue])];
startLocation.title=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}else{
endLocation=[[MKPointAnnotation alloc] init];
[endLocation setCoordinate:CLLocationCoordinate2DMake([[latLongDic valueForKey:#"lat"] floatValue], [[latLongDic valueForKey:#"lng"] floatValue])];
endLocation.title=[textField.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}
NSLog(#"object at index is viewport %#",[[[[[locationDic valueForKey:#"results"] objectAtIndex:0] valueForKey:#"geometry"]valueForKey:#"viewport"] valueForKey:#"northeast"]);
}
#pragma mark Getting lat long from place name.
-(NSDictionary*)getLatLongOfPlace:(NSString*)place
{
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=true",place];
NSLog(#"Fired URL:- %#",apiUrlStr);
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSDictionary *dic=[apiResponse objectFromJSONString];
return dic;
}
Here is SampleCode I made
NOTE:--- In case if sample doesn't work for u jsut this line in viewDidLoad Method
// [__mapView setShowsUserLocation:YES];
Screenshot
#import "ViewController.h"
#import "JSONKit.h"
#interface ViewController ()
#end
#implementation ViewController
NSMutableArray *locationarry ;
NSMutableDictionary * citywiselatlong ;
- (void)viewDidLoad
{
locationarry = [[NSMutableArray alloc]initWithObjects:#"Ahmedabad",#"Rajkot",#"Baroda",#"Surat", nil];
citywiselatlong = [[NSMutableDictionary alloc]init];
[self locationfind];
NSMutableString* TotalXMLString = [[NSMutableString alloc]init];
[TotalXMLString appendFormat:#"http://maps.googleapis.com/maps/api/distancematrix/json?origins="];
[TotalXMLString appendFormat:#"%#,%#&destinations=",[[citywiselatlong valueForKey:[locationarry objectAtIndex:0]] valueForKey:#"lat"] ,[[citywiselatlong valueForKey:[locationarry objectAtIndex:0]] valueForKey:#"lng"]];
for (int i = 1; i < [locationarry count]; i++) {
[TotalXMLString appendFormat:#"%#,%#",[[citywiselatlong valueForKey:[locationarry objectAtIndex:i]] valueForKey:#"lat"] ,[[citywiselatlong valueForKey:[locationarry objectAtIndex:i]] valueForKey:#"lng"]];
if (i != [locationarry count] -1 ) {
[TotalXMLString appendFormat:#"|"];
}
else
{
[TotalXMLString appendFormat:#"&mode=driving&sensor=false"];
}
}
NSURL* apiUrl = [NSURL URLWithString:[TotalXMLString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSDictionary *dic=[apiResponse objectFromJSONString];
NSLog(#"%#",dic);
NSMutableArray * distance = [[NSMutableArray alloc]initWithArray:[[[[dic valueForKey:#"rows"] objectAtIndex:0] valueForKey:#"elements"]valueForKey:#"distance"]];
for (int j= 0 ; j < [distance count]; j++) {
NSMutableDictionary *data = [[NSMutableDictionary alloc]initWithDictionary:[distance objectAtIndex:j]];
}
NSLog(#"%#",distance);
[__mapView setShowsUserLocation:YES];
[__mapView setZoomEnabled:YES];
[__mapView setScrollEnabled:YES];
[__mapView setMapType:MKMapTypeHybrid];
[__mapView setDelegate:self];
routes=[[NSArray alloc] init];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark- MKMapView delegate method
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor purpleColor];
polylineView.lineWidth = 5.0;
NSLog(#"polyline in viewFor overlay: %#",polylineView);
return polylineView;
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(#"did update user location called ");
MKCoordinateRegion region;
region.span.latitudeDelta = .005;
region.span.longitudeDelta = .005;
region.center = userLocation.coordinate;
[mapView setRegion:region animated:YES];
}
- (NSMutableArray *)decodePolyLine: (NSMutableString *)encoded
{
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\" options:NSLiteralSearch range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len)
{
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
//printf("[%f,", [latitude doubleValue]);
//printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t
{
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false&avoid=highways&mode=",saddr,daddr];
NSLog(#"Fired API %#",apiUrlStr);
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSDictionary *dic=[apiResponse objectFromJSONString];
if (dic!=nil) {
NSArray *routPoints=[[NSArray alloc] initWithArray:[dic valueForKey:#"routes"]];
NSDictionary *polylineOverview=[[routPoints objectAtIndex:0] valueForKey:#"overview_polyline"];
NSString *polylinePoints = [polylineOverview objectForKey:#"points"];
return [self decodePolyLine:[polylinePoints mutableCopy]];
}
return nil;
}
- (IBAction)drawPath:(id)sender {
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
[self showRouteFrom:startLocation to:endLocation];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
if (polyLine) {
[__mapView setVisibleMapRect:[polyLine boundingMapRect]];
[__mapView addOverlay:polyLine];
}
NSLog(#"drawing path completed");
});
});
}
-(void) showRouteFrom: (id<MKAnnotation>)source to:(id<MKAnnotation>)destination;
{
routes = [self calculateRoutesFrom:source.coordinate to:destination.coordinate];
NSLog(#"routes are %#",routes);
NSInteger numberOfSteps = routes.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [routes objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[polyLineArray addObject:polyLine];
}
- (IBAction)drawMultiple:(id)sender
{
polyLineArray=[[NSMutableArray alloc] init];
MKPointAnnotation *start=[[MKPointAnnotation alloc] init];
MKPointAnnotation *end=[[MKPointAnnotation alloc] init];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
for (int i=0;i<locationarry.count-1;i++)
{
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i] componentsSeparatedByString:#","]];
NSDictionary *dic=[citywiselatlong objectForKey:[part objectAtIndex:0]];
[start setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"lat"] floatValue], [[dic valueForKey:#"lng"] floatValue])];
part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i +1 ] componentsSeparatedByString:#","]];
dic=[citywiselatlong objectForKey:[part objectAtIndex:0]];
[end setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"lat"] floatValue], [[dic valueForKey:#"lng"] floatValue])];
[self showRouteFrom:start to:end];
}
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:0] componentsSeparatedByString:#","]];
NSDictionary *tempDic=[[NSDictionary alloc] initWithDictionary:[citywiselatlong objectForKey:[part objectAtIndex:0]]];
[start setCoordinate:CLLocationCoordinate2DMake([[tempDic valueForKey:#"lat"] floatValue], [[tempDic valueForKey:#"lng"] floatValue])];
if (polyLine) {
[__mapView setVisibleMapRect:[polyLine boundingMapRect]];
for (MKPolyline *pLine in polyLineArray) {
[__mapView addOverlay:pLine];
}
}
for (int i =0 ; i< [locationarry count]; i ++)
{
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i] componentsSeparatedByString:#","]];
NSDictionary *dic=[citywiselatlong objectForKey:[part objectAtIndex:0]];
MKPointAnnotation *first=[[MKPointAnnotation alloc] init];
MKPointAnnotation *second=[[MKPointAnnotation alloc] init];
[first setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"lat"] floatValue], [[dic valueForKey:#"lng"] floatValue])];
if(i+1<[locationarry count])
{
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i + 1] componentsSeparatedByString:#","]];
dic=[citywiselatlong objectForKey:[part objectAtIndex:0]];
[second setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"lat"] floatValue], [[dic valueForKey:#"lng"] floatValue])];
}
else
{
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i] componentsSeparatedByString:#","]];
dic=[citywiselatlong objectForKey:[part objectAtIndex:0]];;
[second setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"lat"] floatValue], [[dic valueForKey:#"lng"] floatValue])];
}
if (i==0)
{
[__mapView addAnnotation:first];
[__mapView addAnnotation:second];
}
else
{
[__mapView addAnnotation:second];
}
}
NSLog(#"drawing path completed");
});
});
}
-(void) centerMap
{
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90.0;
CLLocationDegrees maxLon = -180.0;
CLLocationDegrees minLat = 90.0;
CLLocationDegrees minLon = 180.0;
for(int idx = 0; idx < routes.count; idx++)
{
CLLocation* currentLocation = [routes objectAtIndex:idx];
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
}
region.center.latitude = (maxLat + minLat) / 2.0;
region.center.longitude = (maxLon + minLon) / 2.0;
region.span.latitudeDelta = 0.01;
region.span.longitudeDelta = 0.01;
region.span.latitudeDelta = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat);
region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon);
[__mapView setRegion:region animated:YES];
}
#pragma mark- UITextField delegate method
-(void)locationfind
{
for (int i = 0; i < [locationarry count]; i++) {
NSDictionary *locationDic=[self getLatLongOfPlace:[[locationarry objectAtIndex:i] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSDictionary *latLongDic=[[[[locationDic valueForKey:#"results"] objectAtIndex:0] valueForKey:#"geometry"]valueForKey:#"location"];
NSArray *part = [[NSArray alloc]initWithArray:[[locationarry objectAtIndex:i] componentsSeparatedByString:#","]];
[citywiselatlong setObject:latLongDic forKey:[part objectAtIndex:0]];
NSLog(#"%#",citywiselatlong);
}
}
#pragma mark Getting lat long from place name.
-(NSDictionary*)getLatLongOfPlace:(NSString*)place
{
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/geocode/json?address=%#&sensor=true",place];
NSLog(#"Fired URL:- %#",apiUrlStr);
NSURL* apiUrl = [NSURL URLWithString:[apiUrlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSDictionary *dic=[apiResponse objectFromJSONString];
return dic;
}
#end
For drawing multiple points you can use it as
need to declare mutable array in header file
NSMutableArray *polyLineArray;
Implementation file need minor changes as ===
-(void) showRouteFrom: (id<MKAnnotation>)source to:(id<MKAnnotation>)destination;
{
NSLog(#"source title is %#",source.title);
NSLog(#"destination title is %#",destination.title);
routes = [self calculateRoutesFrom:source.coordinate to:destination.coordinate];
NSLog(#"routes are %#",routes);
NSInteger numberOfSteps = routes.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [routes objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[polyLineArray addObject:polyLine];
// NSLog(#"poly line to be added as ovelay is %#",polyLine);
}
- (IBAction)drawMultiple:(id)sender
{
polyLineArray=[[NSMutableArray alloc] init];
NSDictionary *kolkata,*delhi,*chennai,*mumbai,*pune;
kolkata=[NSDictionary dictionaryWithObjectsAndKeys:#"location1",#"comments",#"1",#"id",#"23.0083321",#"latitude",#"88.54276659999",#"longitude",nil];
delhi=[NSDictionary dictionaryWithObjectsAndKeys:#"location2",#"comments",#"2",#"id",#"28.889816",#"latitude",#"77.3418147",#"longitude",nil];
chennai=[NSDictionary dictionaryWithObjectsAndKeys:#"location3",#"comments",#"3",#"id",#"13.23339843",#"latitude",#"80.3322912",#"longitude",nil];
mumbai=[NSDictionary dictionaryWithObjectsAndKeys:#"location4",#"comments",#"4",#"id",#"19.2716339",#"latitude",#"72.9864994",#"longitude",nil];
pune=[NSDictionary dictionaryWithObjectsAndKeys:#"location5",#"comments",#"5",#"id",#"18.6346965",#"latitude",#"73.9894867",#"longitude",nil];
NSArray *arrayOfLocations=[[NSArray alloc] initWithObjects:kolkata,delhi,chennai,mumbai,pune,nil];
MKPointAnnotation *start=[[MKPointAnnotation alloc] init];
MKPointAnnotation *end=[[MKPointAnnotation alloc] init];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
for (int i=0;i<arrayOfLocations.count-1;i++)
{
NSDictionary *dic=[arrayOfLocations objectAtIndex:i];
[start setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"latitude"] floatValue], [[dic valueForKey:#"longitude"] floatValue])];
dic=[arrayOfLocations objectAtIndex:i+1];
[end setCoordinate:CLLocationCoordinate2DMake([[dic valueForKey:#"latitude"] floatValue], [[dic valueForKey:#"longitude"] floatValue])];
[self showRouteFrom:start to:end];
}
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
NSDictionary *tempDic=[[NSDictionary alloc] initWithDictionary:[arrayOfLocations objectAtIndex:0]];
[start setCoordinate:CLLocationCoordinate2DMake([[tempDic valueForKey:#"latitude"] floatValue], [[tempDic valueForKey:#"longitude"] floatValue])];
[__mapView addAnnotation:start];
[__mapView addAnnotation:end];
if (polyLine) {
[__mapView setVisibleMapRect:[polyLine boundingMapRect]];
for (MKPolyline *pLine in polyLineArray) {
[__mapView addOverlay:pLine];
}
}
NSLog(#"drawing path completed");
});
});
}
If u need sample code here it is
Output is --------
Use BreadCrumbs here is the sample code ..it is very useful ...u can customize the code according to ur requirement
https://developer.apple.com/library/ios/samplecode/Breadcrumb/Introduction/Intro.html

Drawing a route on Apple map (iOS 6+)

I was looking for many code samples of how to draw a polyline on MKMapView like the second answer (from above) in this link. However, will that solution work on iOS 6 Apple maps? If not, can you provide a link to a sample code that draws the route on Apple maps?
Yes, it'll work.
Google maps and apple maps are different a little bit, could be some little inaccuracies.
All the API's are almost same.
P.S. I use google routes in my app since iOS5 and haven't got any problems when updated app for iOS6.
-(void)load_mapView{
Place* home = [[[Place alloc] init] autorelease];
home.name = strAdd;
CLLocationCoordinate2D loc=[self geoCodeUsingAddress:strAdd Status:1];
home.latitude =loc.latitude;
home.longitude =loc.longitude;
Place* office = [[[Place alloc] init] autorelease];
office.name = endAdd;
CLLocationCoordinate2D loc2=[self geoCodeUsingAddress:endAdd Status:2];;
office.latitude = loc2.latitude;
office.longitude = loc2.longitude;
//*******
routeView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, mapView.frame.size.width, mapView.frame.size.height)];
routeView.userInteractionEnabled = NO;
[mapView addSubview:routeView];
lineColor = [UIColor colorWithWhite:0.2 alpha:0.5];
[self showRouteFrom:home to:office];
[activityIndicator stopAnimating];
}
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address Status:(NSInteger )sts
{
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude = latitude;
center.longitude = longitude;
return center;
}
-(NSMutableArray *)decodePolyLine: (NSMutableString *)encoded {
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\"
options:NSLiteralSearch
range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[[NSMutableArray alloc] init] autorelease];
NSInteger lat=0;
NSInteger lng=0;
while (index < len) {
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[[NSNumber alloc] initWithFloat:lat * 1e-5] autorelease];
NSNumber *longitude = [[[NSNumber alloc] initWithFloat:lng * 1e-5] autorelease];
// printf("[%f,", [latitude doubleValue]);
// printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]] autorelease];
[array addObject:loc];
}
return array;
}
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable){
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.google.com/maps?output=dragdir&saddr=%#&daddr=%#", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
// NSLog(#"api url: %#", apiUrl);
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl];
NSString* encodedPoints = [apiResponse stringByMatching:#"points:\\\"([^\\\"]*)\\\"" capture:1L];
// NSLog(#"encodedPoints.....%#",encodedPoints);
// NSLog(#"self decodePolyLine:[encodedPoints mutableCopy].....%#",[self decodePolyLine:[encodedPoints mutableCopy]]);
NSLog(#"return %# ",[encodedPoints mutableCopy]);
return [self decodePolyLine:[encodedPoints mutableCopy]];
}else{
[activityIndicator stopAnimating];
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Oops!" message:#"Railway server is either busy or not responding at the moment. Try again later." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
return 0;
}
}
-(void) centerMap {
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90;
CLLocationDegrees maxLon = -180;
CLLocationDegrees minLat = 90;
CLLocationDegrees minLon = 180;
for(int idx = 0; idx < routes.count; idx++)
{
CLLocation* currentLocation = [routes objectAtIndex:idx];
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
}
region.center.latitude = (maxLat + minLat) / 2;
region.center.longitude = (maxLon + minLon) / 2;
region.span.latitudeDelta = maxLat - minLat;
region.span.longitudeDelta = maxLon - minLon;
[mapView setRegion:region animated:YES];
}
-(void) showRouteFrom: (Place*) f to:(Place*) t {
if(routes) {
[mapView removeAnnotations:[mapView annotations]];
[routes release];
}
PlaceMark* from = [[[PlaceMark alloc] initWithPlace:f] autorelease];
PlaceMark* to = [[[PlaceMark alloc] initWithPlace:t] autorelease];
[mapView addAnnotation:from];
[mapView addAnnotation:to];
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus internetStatus = [reachability currentReachabilityStatus];
if (internetStatus != NotReachable){
routes = [[self calculateRoutesFrom:from.coordinate to:to.coordinate] retain];
[self drawRoute];
[self centerMap];
}else{
[activityIndicator stopAnimating];
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Oops!" message:#"Railway server is either busy or not responding at the moment. Try again later." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
- (void)drawRoute
{
int numPoints = [routes count];
if (numPoints > 1)
{
CLLocationCoordinate2D* coords = malloc(numPoints * sizeof(CLLocationCoordinate2D));
for (int i = 0; i < numPoints; i++)
{
CLLocation* current = [routes objectAtIndex:i];
coords[i] = current.coordinate;
}
objPolyline = [MKPolyline polylineWithCoordinates:coords count:numPoints];
free(coords);
[mapView addOverlay:objPolyline];
[mapView setNeedsDisplay];
}
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *thePolylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
thePolylineView.strokeColor = [UIColor colorWithRed:((float) 204.0 / 255.0f)green:((float) 7.0 / 255.0f)blue:((float) 40.0 / 255.0f)alpha:1.0f]; // <-- So important stuff here
thePolylineView.lineWidth = 5.0;
return thePolylineView;
}

Finding Path/Route Between two points on MapKit in iPhone

I am trying to find the path between two locations on Mapkit. All I have is two locations. Now I have to find the exact path between these points and draw a line between these points using MapKit. I have gone through several examples in which they are using .csv files. In that .csv file they have stored the latitude and longitude values of the full path and drawing line based on those values.
But here I am trying to draw a line without knowing the path. So is there any way to find the path dynamically and draw a line?
Below is the code to finds path & draws line between two locations.
To implement below class:
_mapRecord = [[PSMapDirection alloc] initWithFrame:CGRectMake(0.0, 49.0, 320.0, 411.0)];
[self.view addSubview:_mapRecord];
MapDirection.h
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import "RegexKitLite.h"
#interface MapDirection : UIView<MKMapViewDelegate>
{
MKMapView* mapView;
NSArray* routes;
BOOL isUpdatingRoutes;
}
-(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t;
#end
MapDirection.m
#import "MapDirection.h"
#interface MapDirection()
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) from to: (CLLocationCoordinate2D) to;
-(void) centerMap;
#end
- (id) initWithFrame:(CGRect) frame
{
self = [super initWithFrame:frame];
if (self != nil)
{
mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
mapView.showsUserLocation = NO;
[mapView setDelegate:self];
[self addSubview:mapView];
}
return self;
}
- (NSMutableArray *)decodePolyLine: (NSMutableString *)encoded
{
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\" options:NSLiteralSearch range:NSMakeRange(0, [encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len)
{
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
//printf("[%f,", [latitude doubleValue]);
//printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t
{
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.google.com/maps?output=dragdir&saddr=%#&daddr=%#", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
//NSLog(#"api url: %#", apiUrl);
NSError* error = nil;
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSASCIIStringEncoding error:&error];
NSString *encodedPoints = [apiResponse stringByMatching:#"points:\\\"([^\\\"]*)\\\"" capture:1L];
return [self decodePolyLine:[encodedPoints mutableCopy]];
}
-(void) centerMap
{
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90.0;
CLLocationDegrees maxLon = -180.0;
CLLocationDegrees minLat = 90.0;
CLLocationDegrees minLon = 180.0;
for(int idx = 0; idx < routes.count; idx++)
{
CLLocation* currentLocation = [routes objectAtIndex:idx];
if(currentLocation.coordinate.latitude > maxLat)
maxLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.latitude < minLat)
minLat = currentLocation.coordinate.latitude;
if(currentLocation.coordinate.longitude > maxLon)
maxLon = currentLocation.coordinate.longitude;
if(currentLocation.coordinate.longitude < minLon)
minLon = currentLocation.coordinate.longitude;
}
region.center.latitude = (maxLat + minLat) / 2.0;
region.center.longitude = (maxLon + minLon) / 2.0;
region.span.latitudeDelta = 0.01;
region.span.longitudeDelta = 0.01;
region.span.latitudeDelta = ((maxLat - minLat)<0.0)?100.0:(maxLat - minLat);
region.span.longitudeDelta = ((maxLon - minLon)<0.0)?100.0:(maxLon - minLon);
[mapView setRegion:region animated:YES];
}
-(void) showRouteFrom: (MKAnnotation*) f to:(MKAnnotation*) t
{
if(routes)
{
[mapView removeAnnotations:[mapView annotations]];
}
[mapView addAnnotation:f];
[mapView addAnnotation:t];
routes = [self calculateRoutesFrom:f.coordinate to:t.coordinate];
NSInteger numberOfSteps = routes.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [routes objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[mapView addOverlay:polyLine];
[self centerMap];
}
#pragma mark MKPolyline delegate functions
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor purpleColor];
polylineView.lineWidth = 5.0;
return polylineView;
}
#end
Sample Map Route for starting points - "41.967659,-87.627869" and destination points - "41.574361,-91.083069"
Here The way in which I am able to draw direction between two points(Location).
First of all download GoogleMap sdk from this link and integrate into your application.
Now API key required and you can create as par given guidelines on this link.
Below are Code that draw direction on google map between two location.
-(NSArray*) calculateRoutesFrom:(CLLocationCoordinate2D) f to: (CLLocationCoordinate2D) t {
NSString* saddr = [NSString stringWithFormat:#"%f,%f", f.latitude, f.longitude];
NSString* daddr = [NSString stringWithFormat:#"%f,%f", t.latitude, t.longitude];
NSURL *url=[NSURL URLWithString:[NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false&avoid=highways&mode=driving",saddr,daddr]];
NSError *error=nil;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init] ;
[request setURL:url];
[request setHTTPMethod:#"POST"];
NSURLResponse *response = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error: &error];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONWritingPrettyPrinted error:nil];
return [self decodePolyLine:[self parseResponse:dic]];
}
- (NSString *)parseResponse:(NSDictionary *)response {
NSArray *routes = [response objectForKey:#"routes"];
NSDictionary *route = [routes lastObject];
if (route) {
NSString *overviewPolyline = [[route objectForKey:
#"overview_polyline"] objectForKey:#"points"];
return overviewPolyline;
}
return #"";
}
-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {
NSMutableString *encoded = [[NSMutableString alloc]
initWithCapacity:[encodedStr length]];
[encoded appendString:encodedStr];
[encoded replaceOccurrencesOfString:#"\\\\" withString:#"\\"
options:NSLiteralSearch
range:NSMakeRange(0,
[encoded length])];
NSInteger len = [encoded length];
NSInteger index = 0;
NSMutableArray *array = [[NSMutableArray alloc] init];
NSInteger lat=0;
NSInteger lng=0;
while (index < len) {
NSInteger b;
NSInteger shift = 0;
NSInteger result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlat = ((result & 1) ? ~(result >> 1)
: (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = [encoded characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
NSInteger dlng = ((result & 1) ? ~(result >> 1)
: (result >> 1));
lng += dlng;
NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5];
NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
CLLocation *location = [[CLLocation alloc] initWithLatitude:
[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:location];
}
return array;
}
- (void)loadMapViewWithDirection {
float lat = 23.050671;
float lng = 72.541351;
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:lat
longitude:lng
zoom:10];
GMSMapView * mapView = [GMSMapView mapWithFrame:CGRectMake(0, 75, 320, self.view.frame.size.height-kHeaderRect.size.height) camera:camera];
self.mapView.myLocationEnabled = YES;
float sourceLatitude = 23.050671;
float sourceLongitude = 72.541351;
float destLatitude = 23.036138;
float destLongitude = 72.603836;
GMSMarker *sourceMarker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude);
marker.map = self.mapView;
GMSMarker *destMarker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(destLatitude, destLongitude);
marker.map = self.mapView;
self.mapView.delegate = self;
[self drawDirection:CLLocationCoordinate2DMake(sourceLatitude, sourceLongitude) and:CLLocationCoordinate2DMake(destLatitude, destLongitude)];
[self.view addSubview:self.mapView];
}
- (void) drawDirection:(CLLocationCoordinate2D)source and:(CLLocationCoordinate2D) dest {
GMSPolyline *polyline = [[GMSPolyline alloc] init];
GMSMutablePath *path = [GMSMutablePath path];
NSArray * points = [self calculateRoutesFrom:source to:dest];
NSInteger numberOfSteps = points.count;
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [points objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
[path addCoordinate:coordinate];
}
polyline.path = path;
polyline.strokeColor = [UIColor redColor];
polyline.strokeWidth = 2.f;
polyline.map = self.mapView;
// Copy the previous polyline, change its color, and mark it as geodesic.
polyline = [polyline copy];
polyline.strokeColor = [UIColor greenColor];
polyline.geodesic = YES;
polyline.map = self.mapView;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadMapViewWithDirection];
}
You can refer this code, it does exactly what you want.EDIT: and this also
I don't think you can do this locally. Implementing an algoritm for finding a path between two gps points requires a lot of input data (data from the maps) and you don't have this. Only a map provider can afford to implement such algoritm and expose an API for using it. I think Google have routing API, but I haven't played around with it...
https://developers.google.com/maps/documentation/directions/
Note that the TOS say that you have to display the results on a Google map, so you'll have to disable the functionality on the next iOS release

iphone+UIscrollview or to use uitableview to display image in matrix format

I want to display the image(which comes from webservice) the format such that the output in the screen appears like below image:-
Now the logic i had implemented is,i had added the image in uiscrollview.
with the below logic:-
for (int j=0;j<9;j++) {
for (int i=0; i<[mainRestaurantArray count];i++) {
if ([[[mainRestaurantArray objectAtIndex:i] valueForKey:#"Image"] isKindOfClass:[UIImage class]]) {
[CombineArray addObject:[mainRestaurantArray objectAtIndex:i]];
//NSLog(#"cnt=>%d array==>%#",cnt,[CombineArray objectAtIndex:cnt]);
UIButton* btn = [[UIButton alloc]init];
btn.tag = cnt;
btn.frame = CGRectMake(15+(cnt%5)*60, 15+(cnt/5)*60,Width,Height);
btn.backgroundColor = [UIColor greenColor];
[btn setBackgroundImage:[[CombineArray objectAtIndex:cnt] valueForKey:#"Image"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(Buttonclick:) forControlEvents:UIControlEventTouchUpInside];
[ScrlPhotos addSubview:btn];
[btn release];
cnt++;
}
}
[mainRestaurantArray release];
counter++;
[self urlcalled];//The function which calls the webservice
}
//}
ScrlPhotos.contentSize = CGSizeMake(320, ([CombineArray count]/5.0)*60+25);
The function which does the webservice is below:-
-(void)urlcalled{
#try
{
if (rangeDistance == nil) {
rangeDistance =#"100";
}
urlstring[0]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Gym&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[1]=[NSString stringWithFormat:#"http://www.google.com/maps?q=resort&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[2]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Tourist place&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[3]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Hotels&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[4]=[NSString stringWithFormat:#"http://www.google.com/maps?q=shopping Mall&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[5]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Industries&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[6]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Shopping_mall&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[7]=[NSString stringWithFormat:#"http://www.google.com/maps?q=garden&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[8]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Religious Place&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
urlstring[9]=[NSString stringWithFormat:#"http://www.google.com/maps?q=Restaurants&sll=%#,%#&radius=200000&output=json",AppDel.Latitude,AppDel.Longitude];
NSLog(#"conte==>%d urlstring[counter]==>%#",counter,urlstring[counter]);
NSString *str = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlstring[counter]]];
str1 = [str substringFromIndex:9];
//NSLog(#"===>%#",str1);
NSArray *array = [str1 componentsSeparatedByString:#"overlays:"];
NSString *str2 = [array objectAtIndex:1];
NSString *finalUpperStr = [str2 substringFromIndex:21];
array1 = [finalUpperStr componentsSeparatedByString:#"},panel:"];
NSString *strF = [array1 objectAtIndex:0];
NSArray *arrayF = [strF componentsSeparatedByString:#"{id:"];
///////....................this object will change as require in for loop .............................//
mainRestaurantArray = [[NSMutableArray alloc] init];
for (int i=1; i<[arrayF count]-5; i++) {
NSString *strF12 = [arrayF objectAtIndex:i];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
NSArray *aryF23 = [strF12 componentsSeparatedByString:#"latlng:{"];
//NSLog(#"%#",[aryF23 objectAtIndex:1]);
NSString *strF23 = [aryF23 objectAtIndex:1];
NSArray *ar = [strF23 componentsSeparatedByString:#"},image:"];
//NSLog(#"%#",[ar objectAtIndex:0]);
NSString *strLat = [ar objectAtIndex:0];
NSArray *arrayLat = [strLat componentsSeparatedByString:#","];
NSString *strFLat = [[arrayLat objectAtIndex:0] substringFromIndex:4];
NSString *strLong = [[arrayLat objectAtIndex:1] substringFromIndex:4];
//NSLog(#"Lati = %# Longi = %#" , strFLat , strLong);
[dic setValue:strFLat forKey:#"Latitude"];
[dic setValue:strLong forKey:#"Longitude"];
NSString *strLAdd = [ar objectAtIndex:1];
NSArray *arrayLAdd = [strLAdd componentsSeparatedByString:#"laddr:"];
//NSLog(#"%#",[arrayLAdd objectAtIndex:1]);
NSString *strLAdd1 = [arrayLAdd objectAtIndex:1];
NSArray *arrayLAdd1 = [strLAdd1 componentsSeparatedByString:#"geocode:"];
// NSLog(#"%#",[arrayLAdd1 objectAtIndex:0]);
NSString *strAddres = [[arrayLAdd1 objectAtIndex:0] stringByReplacingOccurrencesOfString:#"\"" withString:#""];
//NSLog(#"%#",strAddres);
[dic setValue:strAddres forKey:#"Address"];
NSString *strName = [arrayLAdd1 objectAtIndex:1];
NSArray *arrayName = [strName componentsSeparatedByString:#"name:"];
NSString *strName1 = [[arrayName objectAtIndex:1]stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *arrayName1 = [strName1 componentsSeparatedByString:#"infoWindow:"];
[dic setValue:[arrayName1 objectAtIndex:0] forKey:#"Name"];
// for image load .. 07Dec..
NSString *strImage= [arrayF objectAtIndex:i];
NSRange range = [strImage rangeOfString:#"photoUrl"];
if(range.location == NSNotFound){
NSLog(#"Not found");
[dic setValue:#"" forKey:#"Image"];
}else{
NSArray *arrayImage = [strImage componentsSeparatedByString:#"photoUrl:"];
NSString *strImage1 = [arrayImage objectAtIndex:1];
NSArray *arrayImage1 = [strImage1 componentsSeparatedByString:#",photoType:"];
NSString *strfindImage = [[arrayImage1 objectAtIndex:0] stringByReplacingOccurrencesOfString:#"\"" withString:#""];
myImage = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strfindImage]]];
[dic setValue:myImage forKey:#"Image"];
}
[mainRestaurantArray addObject:dic];
if (i==20) {
break;
}
}
}
#catch (NSException * e)
{
NSLog(#"NSException==>%#",e);
}
}
But the problem i am facing is the image is displayed after completing the loop at 10 times.
I want to display the image parallely as it comes from webservice,so that time taken should be less..
Is there any way out..
Please help me.
Use UIImageView+cacheWeb.. it makes lazy loading a lot easier
http://hackemist.com/SDWebImage/doc/Categories/UIImageView+WebCache.html

Issue in Displaying Multiple annonations view in MkMapKit

I need to display multiple annonation views in MKMapKit..I use this code..
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib
[mapView setMapType:MKMapTypeStandard];
[mapView setZoomEnabled:YES];
[mapView setScrollEnabled:YES];
DisplayMap *ann = [[DisplayMap alloc] init];
//NSLog(#"xapp.arrplacename:%d",[xapp.arrplacename count]);
for (i=0;i<=[arrplacename count]-1;i++)
{
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
//arrplacename contains the address of the locations
NSString *straddress=[arrplacename objectAtIndex:i];
NSString *strregion=#"";
NSString *strs=[straddress stringByAppendingString: strregion];
// lbladdress.text=strs;
// NSString add=strs;
// here you define the url setting your address
NSString *urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",[strs stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSLog(#"US: %#",urlString);
// then you get the response string here
NSString *locationString = [[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]] autorelease];
NSLog(#"loaction strings%#",locationString);
// now you can create an array splitting the response values using the ","
//[listItems addObject:locationString];
listItems = [locationString componentsSeparatedByString:#","];
NSLog(#"A: %#",[xapp.listItems objectAtIndex:2]);
// define latitude and longitude variables
double latitude = 0.0;
double longitude = 0.0;
NSString *strlatitude;
NSString *strlongitude;
strlatitude=[xapp.listItems objectAtIndex:2];
strlongitude=[xapp.listItems objectAtIndex:3];
float stringFloat = [strlatitude floatValue];
float string1Float = [strlongitude floatValue];
// if your array has inside the sctructure you aspect (4 values as described in my previous post) and the first value is like "200" (OK result)
if([xapp.listItems count] >= 4 && [[xapp.listItems objectAtIndex:0] isEqualToString:#"200"])
{
// not sure if you need the accurancy parameter
//accurancy = [[listItems objectAtIndex:1] intValue];
// here you can get your values
// latitude = [[listItems objectAtIndex:2] doubleValue];
//longitude = [[listItems objectAtIndex:3] doubleValue];
latitude = stringFloat;
longitude = string1Float;
}
else {
NSLog(#"Error on map");
}
region.center.latitude = latitude;
region.center.longitude = longitude;
NSLog(#"latitude:%g",region.center.latitude);
// region.center.latitude = 42.7157850;
// region.center.longitude = 27.56470180;
region.span.longitudeDelta = 0.01f;
region.span.latitudeDelta = 0.01f;
[mapView setRegion:region animated:YES];
[mapView setDelegate:self];
ann.title = [xapp.arrplacename objectAtIndex:i];
ann.subtitle = [xapp.arrplacename objectAtIndex:i];
ann.coordinate = region.center;
[mapView addAnnotation:ann];
}
}
I do have some problems in this code....all the coordnates are not added to the listitems array..I can see only the objects that are added atlast....
This is the delegates I add for displaying the annonation in my map..
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address{
NSLog(#"ssssss");
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\":" intoString:nil] && [scanner scanString:#"\"lat\":" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\":" intoString:nil] && [scanner scanString:#"\"lng\":" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude = latitude;
center.longitude = longitude;
return center;
}
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:
(id <MKAnnotation>)annotation {
MKPinAnnotationView *pinView = nil;
NSLog(#"pinnview before release %d",[pinView retainCount]);
if (pinView !=nil) {
pinView =nil;
[pinView release];
}
NSLog(#"pinnview after release %d",[pinView retainCount]);
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if(annotation != mapView.userLocation)
{
static NSString *defaultPinID = #"your-pin";
pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( counting < [mapView.annotations count])
{
counting++;
pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
/* for(DisplayMap* a in mapView.annotations)
{
if (annotation == a){
pinView.image =
[UIImage imageWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:a.image ofType:nil]];
}
}*/
pinView.centerOffset= CGPointMake(0,-10);
pinView.canShowCallout = YES;
}
}
// return pinView;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views
{
NSLog(#"enter");
[mapView selectAnnotation:[[mapView annotations] lastObject] animated:YES];
}
Delegates are called only once eventhough I'm using [mapView addAnnotation:ann]; inside the for loop...And it shows pin only for the last item tatz added in the array...How can I overcome this????
You are allocating and initializing 'ann' only once before the for loop starts, and you are altering the same and adding it again and again into Map. Thats why you are getting only one annotation.
Move this line inside for loop and try,
DisplayMap *ann = [[DisplayMap alloc] init];