i want to draw polyline using googleMap Api on MKMapView.
i am doing this way. Here is Code for it.
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager.requestSerializer setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
NSString *urlString =#"https://maps.googleapis.com/maps/api/directions/json";
NSString *origin = #"23.0061,72.5647";
NSString *dstinatin = #"23.03293,72.6284";
MKPointAnnotation *annotationEnd = [[MKPointAnnotation alloc] init];
[annotationEnd setCoordinate:CLLocationCoordinate2DMake(23.0293, 72.6284)];
[annotationEnd setTitle:#"Ending"]; //You can set the subtitle too
[self.mkMapView addAnnotation:annotationEnd];
NSDictionary *dictParameters = #{#"origin" : [NSString stringWithFormat:#"%#",origin], #"destination" : [NSString stringWithFormat:#"%#",dstinatin], #"mode" : #"driving", #"sensor" : #"true"};
[manager GET:urlString parameters:dictParameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSArray *routesArray = [responseObject objectForKey:#"routes"];
if ([routesArray count] > 0)
{
NSDictionary *routeDict = [routesArray objectAtIndex:0];
NSDictionary *routeOverviewPolyline = [routeDict objectForKey:#"overview_polyline"];
NSString *points = [routeOverviewPolyline objectForKey:#"points"];
MKPolyline *line = [self polylineWithEncodedString:points];
[mkMapView addOverlay:line];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
my decoding method is :
-(MKPolyline *)polylineWithEncodedString:(NSString *)encodedString
{
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);
return polyline;
}
i think my coding is ok but i am not getting proper polyline. i am getting it as seen in screen shot. polyline's last end should be on my MKPointAnnotation. Sorry for my english. please help me.
The destination of the route:
23.03293,72.6284
//____^
isn't equal to the marker-position:
23.0293,72.6284
Related
I create a polyline in map. and successfully create polyline in map view.
My problem is, This code run only simulator. do not work on device. I tried to many times but do not work on device.
Genrate the IPA and install in my device and crash my app. why? and simply run in simulator, why?
I follow this link
Why is this happining? please help
Thankyou
my code
-(void) centerMapForCoordinateArray:(CLLocationCoordinate2D *)routes andCount:(int)count{
MKCoordinateRegion region;
CLLocationDegrees maxLat = -90;
CLLocationDegrees maxLon = -180;
CLLocationDegrees minLat = 90;
CLLocationDegrees minLon = 180;
for(int idx = 0; idx <count; idx++)
{
CLLocationCoordinate2D currentLocation = routes[idx];
if(currentLocation.latitude > maxLat)
maxLat = currentLocation.latitude;
if(currentLocation.latitude < minLat)
minLat = currentLocation.latitude;
if(currentLocation.longitude > maxLon)
maxLon = currentLocation.longitude;
if(currentLocation.longitude < minLon)
minLon = currentLocation.longitude;
}
region.center.latitude = (maxLat + minLat) / 2;
region.center.longitude = (maxLon + minLon) / 2;
region.span.latitudeDelta = maxLat - minLat;
region.span.longitudeDelta = maxLon - minLon;
[self.mapView setRegion:region animated:YES];
}
- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);
return polyline;
}
- (void)getDirections {
//Cross country
//37.705553,-122.372074 to 25.883937,-80.223026
//Home to work
//37.7577,-122.4376 to 37.764473,-122.399639
CLLocation *newLocation = [[CLLocation alloc] initWithLatitude:22.7001469 longitude:75.8758194];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude);
annotation.title = #"You";
[self.mapView addAnnotation:annotation];
CLLocation *keyPlace = [[CLLocation alloc] initWithLatitude:22.6924483 longitude:75.8653895];
MKPointAnnotation *endannotation = [[MKPointAnnotation alloc] init];
endannotation.coordinate = CLLocationCoordinate2DMake(keyPlace.coordinate.latitude, keyPlace.coordinate.longitude);
endannotation.title = #"School";
[self.mapView addAnnotation:endannotation];
CLLocationCoordinate2D endCoordinate;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false&mode=driving", newLocation.coordinate.latitude, newLocation.coordinate.longitude, keyPlace.coordinate.latitude, keyPlace.coordinate.longitude]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!error) {
NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&error];
NSLog(#"response == %#",responseDict);
if ([[responseDict valueForKey:#"status"] isEqualToString:#"ZERO_RESULTS"]) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not route path from your current location"
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles:nil, nil] show];
return;
}
int points_count = 0;
if ([[responseDict objectForKey:#"routes"] count])
points_count = [[[[[[responseDict objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"] count];
if (!points_count) {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"Could not route path from your current location"
delegate:nil
cancelButtonTitle:#"Close"
otherButtonTitles:nil, nil] show];
return;
}
CLLocationCoordinate2D points[points_count];
NSLog(#"routes %#", [[[[responseDict objectForKey:#"routes"] objectAtIndex:0]objectForKey:#"overview_polyline"] objectForKey:#"points"]
);
MKPolyline *polyline = [self polylineWithEncodedString:[[[[responseDict objectForKey:#"routes"] objectAtIndex:0]objectForKey:#"overview_polyline"] objectForKey:#"points"]];
[self.mapView addOverlay:polyline];
int j = 0;
NSArray *steps = nil;
if (points_count && [[[[responseDict objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] count])
steps = [[[[[responseDict objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"];
for (int i = 0; i < points_count; i++) {
double st_lat = [[[[steps objectAtIndex:i] objectForKey:#"start_location"] valueForKey:#"lat"] doubleValue];
double st_lon = [[[[steps objectAtIndex:i] objectForKey:#"start_location"] valueForKey:#"lng"] doubleValue];
//NSLog(#"lat lon: %f %f", st_lat, st_lon);
if (st_lat > 0.0f && st_lon > 0.0f) {
points[j] = CLLocationCoordinate2DMake(st_lat, st_lon);
j++;
}
double end_lat = [[[[steps objectAtIndex:i] objectForKey:#"end_location"] valueForKey:#"lat"] doubleValue];
double end_lon = [[[[steps objectAtIndex:i] objectForKey:#"end_location"] valueForKey:#"lng"] doubleValue];
//NSLog(#"lat %f lng %f",end_lat,end_lon);
//if (end_lat > 0.0f && end_lon > 0.0f) {
points[j] = CLLocationCoordinate2DMake(end_lat, end_lon);
endCoordinate = CLLocationCoordinate2DMake(end_lat, end_lon);
j++;
//}
}
NSLog(#"points Count %d",points_count);
// MKPolyline *polyline = [MKPolyline polylineWithCoordinates:points count:points_count];
// [self.mapView addOverlay:polyline];
[self centerMapForCoordinateArray:points andCount:points_count];
}
}
#pragma mark - MapKit
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKPinAnnotationView *annView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"currentloc"];
annView.canShowCallout = YES;
annView.animatesDrop = YES;
return annView;
}
- (MKOverlayView *)mapView:(MKMapView *)mapView
viewForOverlay:(id<MKOverlay>)overlay {
MKPolylineView *overlayView = [[MKPolylineView alloc] initWithOverlay:overlay];
overlayView.lineWidth = 5;
overlayView.strokeColor = [UIColor purpleColor];
overlayView.fillColor = [[UIColor purpleColor] colorWithAlphaComponent:0.5f];
return overlayView;
}
I go through your code and run in simulator, it will show warning CFNetwork SSLHandshake failed (-9824) NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824), so i think you miss the NSAppTransportSecurity key in your plist.
Problem seems with certificate try by setting development certificates and check provisioning profile.
Set the proper certificates and provisioning profile in build setting/target then check.
More detail read:
https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppStoreDistributionTutorial/LaunchingYourApponDevices/LaunchingYourApponDevices.html
Try to Run in iphone4s or 5 Simulator, if it crash in simulator than change
points[j] = CLLocationCoordinate2DMake(end_lat, end_lon);
endCoordinate = CLLocationCoordinate2DMake(end_lat, end_lon);
j++;
With
if (j<=points_count) {
points[j] = CLLocationCoordinate2DMake(end_lat, end_lon);
endCoordinate = CLLocationCoordinate2DMake(end_lat, end_lon);
j++;
}
Why? Because
we declare CLLocationCoordinate2D points[points_count];
So max Coordinate2D is points_count
but some latitude longitude j value is higher than the points_count so we have to put if condition for j
Check it and let me know it it solve your problem or not.
I have create a PolyLine in MapView. I tried to many times but did not draw. Ones a draw polyLine but that case run only simulator, I run in device and crash my app. and I already post my question here
I tried to many times and using lots of tutorials, please suggest any other tutorial.
I want to create a PolyLine in MapView using google direction URL. Starting point is my device location and end point is any lat long. so both points in centre draw a polyLine. That means create a root map starting point to end point draw a PolyLine.
Please help, Thank you
you can use google api for this
http://maps.googleapis.com/maps/api/directions/json?origin
in this api you have to pass lat log of your locations like this methode
-(NSArray*) calculateRoutes
{
NSString *baseUrl = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=true",currentlatitude,currentlongitude,destination lat,destination log];
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:baseUrl]];
if (data) {
NSDictionary *direction_dictionary=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
if (direction_dictionary) {
if ([[direction_dictionary valueForKey:#"status"] isEqualToString:#"OK"]) {
NSArray *routes_array=[direction_dictionary valueForKey:#"routes"];
if (routes_array) {
NSString *poinstEncoded_String=[[[routes_array firstObject] valueForKey:#"overview_polyline"] valueForKey:#"points"];
routes = [self decodePolyLine:[poinstEncoded_String mutableCopy]];
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];
dispatch_async(dispatch_get_main_queue(), ^{
[self.MapVw addOverlay:polyLine];
// add polyline here to your mapview
});
}
}
}
}
}
-(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];
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
After getting response (Full example http://way2ios.com/development/ios-development-2/iphone-2/draw-polygon-mkmapview-stylus/):
– (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id )overlay
{
MKPolygonView *polygonView = [[MKPolygonView alloc] initWithPolygon:overlay];
polygonView.lineWidth = 5;
polygonView.strokeColor = [UIColor redColor];
polygonView.fillColor = [UIColor colorWithRed:0 green:191 blue:255 alpha:0.5];
mapView.userInteractionEnabled = YES;
return polygonView;
}
Check these also :
https://github.com/kadirpekel/MapWithRoutes and https://github.com/versluis/MapViewLines
I'm trying to draw route on my map using Google Maps SDK.
This is the URL that i'm calling and I parse the JSON response to array of coordinates:
id jsonResponse = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
int points_count = 0;
points_count = [[[[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"] count];
NSArray *steps = nil;
if (points_count && [[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] count])
{
steps = [[[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"];
}
NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:points_count];
for (int i = 0; i < points_count; i++)
{
NSDictionary *start;
NSDictionary *finish;
double st_lat = [[[[steps objectAtIndex:i] objectForKey:#"start_location"] valueForKey:#"lat"] doubleValue];
double st_lon = [[[[steps objectAtIndex:i] objectForKey:#"start_location"] valueForKey:#"lng"] doubleValue];
if (st_lat > 0.0f && st_lon > 0.0f)
{
start = #{ #"latitude" : [NSNumber numberWithDouble:st_lat], #"longitude" : [NSNumber numberWithDouble:st_lon] };
}
double end_lat = [[[[steps objectAtIndex:i] objectForKey:#"end_location"] valueForKey:#"lat"] doubleValue];
double end_lon = [[[[steps objectAtIndex:i] objectForKey:#"end_location"] valueForKey:#"lng"] doubleValue];
if (end_lat > 0.0f && end_lon > 0.0f)
{
finish = #{ #"latitude" : [NSNumber numberWithDouble:end_lat], #"longitude" : [NSNumber numberWithDouble:end_lon] };
}
[coordinates addObject:#{ #"start" : start, #"finish" : finish }];
}
And than drawing on the map view with this method:
GMSMutablePath *path = [GMSMutablePath path];
for (NSDictionary *d in directions)
{
NSDictionary *start = d[#"start"];
NSDictionary *finish = d[#"finish"];
CLLocationCoordinate2D c_start = CLLocationCoordinate2DMake([start[#"latitude"] doubleValue], [start[#"longitude"] doubleValue]);
CLLocationCoordinate2D c_finish = CLLocationCoordinate2DMake([finish[#"latitude"] doubleValue], [finish[#"longitude"] doubleValue]);
[path addCoordinate:c_start];
[path addCoordinate:c_finish];
}
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.strokeColor = [UIColor redColor];
line.strokeWidth = 2.0f;
line.map = self.mapView;
Why it is drawing like that and not going into the street it self?
What am I doing wrong here?
Try this it draws exact path like in driving mode - StreetMode, Here's my code :
iOS GSMPolyLine
So the problem was that I used the start_location and end_location instead of the polyline -> points. Fixed my code into this:
Request URL for example: https://maps.googleapis.com/maps/api/directions/json?origin=40.716072,-74.008836&destination=40.697545,-73.983892&sensor=false&waypoints=optimize:true&mode=driving
id jsonResponse = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
int points_count = 0;
points_count = [[[[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"] count];
NSArray *steps = nil;
if (points_count && [[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] count])
{
steps = [[[[[jsonResponse objectForKey:#"routes"] objectAtIndex:0] objectForKey:#"legs"] objectAtIndex:0] objectForKey:#"steps"];
}
NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:points_count];
for (int i = 0; i < points_count; i++)
{
NSString *toDecode = [[[steps objectAtIndex:i] objectForKey:#"polyline"] valueForKey:#"points"];
NSArray *locations = [AppUtils decodePolylineWithString:toDecode];
for (int i = 0 ; i < locations.count ; i++)
{
if (i != locations.count - 1) {
CLLocation *start = [locations objectAtIndex:i];
CLLocation *finish = [locations objectAtIndex:i + 1];
[coordinates addObject:#{ #"start" : start, #"finish" : finish }];
}
}
}
GMSMutablePath *path = [GMSMutablePath path];
for (NSDictionary *d in directions)
{
CLLocation *start = d[#"start"];
CLLocation *finish = d[#"finish"];
[path addCoordinate:start.coordinate];
[path addCoordinate:finish.coordinate];
}
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.strokeColor = [UIColor redColor];
line.strokeWidth = 2.0f;
line.map = self.mapView;
+ (NSArray*)decodePolylineWithString:(NSString *)encodedString
{
NSMutableArray *coordinates = [NSMutableArray array];
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
CLLocation *location = [[CLLocation alloc] initWithLatitude:finalLat longitude:finalLon];
[coordinates addObject:location];
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
free(coords);
return coordinates;
}
I know it's a little bit dirty, but that's work and it works great.
Enjoy.
I am creating a Navigation iPhone app that creates a polyline between the user location and the destination the user wants to go.
I am able to create the polyline. But what i need to do is as the user proceeds on the polyline, the polyline need to gradually decrease showing the user is on track. And i also need to detect if the user has strayed from the path.
For example, if the user has to go left but he doesn't, how will i detect that?
Any help will be appreciated. Thanks.
EDIT :
I have used the following code to draw the polyline for
-(void)drawPolyline{
//Draw polyline via the selected route
NSMutableArray *polys = [NSMutableArray array];
GMSMutablePath *path = [GMSMutablePath path];
NSDictionary *route=[routes objectAtIndex:0];
//self.strPolyPoints is a string
self.strPolyPoints=[[route objectForKey:#"overview_polyline"] objectForKey:#"points"];
NSArray *arrPoints=[self decodePolyLine];
for(CLLocation *location in arrPoints){
CLLocationCoordinate2D coordinate=location.coordinate;
[path addCoordinate:coordinate];
}
_lengths = #[#([path lengthOfKind:kGMSLengthGeodesic] / 40)];
GMSPolyline *polyline = [[GMSPolyline alloc] init];
polyline.path = path;
polyline.strokeColor = [UIColor blueColor];
polyline.geodesic = NO;
polyline.strokeWidth = 5;
polyline.map = mapView_;
[polys addObject:polyline];
_polys = polys;
[self tick];
}
- (void)tick {
//Create steps for polyline(dotted polylines)
for (GMSPolyline *poly in _polys) {
poly.spans =
GMSStyleSpans(poly.path, _styles, _lengths, kGMSLengthGeodesic, _pos);
}
_pos -= _step;
//Animate the polyline like moving from source to destination
if (kAnimate) {
__weak id weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC / 5),
dispatch_get_main_queue(),
^{ [weakSelf tick]; });
}
}
-(NSMutableArray *)decodePolyLine {
NSMutableString *encoded = [[NSMutableString alloc] initWithCapacity:[self.strPolyPoints length]];
[encoded appendString:self.strPolyPoints];
[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;
}
I think you have to draw the polyline from the user's location to the destination, on location change of the device remove the existing polyline and draw a new one with the user's current location. You could share some code that you have tried already so that I can help you in a better way.
There are CLLocation2D points, MKMapPoints, MKCoordinates, and convertCoordinate:toPointInView: which all give you points in one form or another. I am drawing a custom route in:
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context {
Whats the proper point to use for drawing?
routeView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, mapView.frame.size.width, mapView.frame.size.height)];
routeView.userInteractionEnabled = NO;
[mapView addSubview:routeView];
And
-(void) updateRouteView {
CGContextRef context = CGBitmapContextCreate(nil,
routeView.frame.size.width,
routeView.frame.size.height,
8,
4 * routeView.frame.size.width,
CGColorSpaceCreateDeviceRGB(),
kCGImageAlphaPremultipliedLast);
CGContextSetStrokeColorWithColor(context, lineColor.CGColor);
CGContextSetRGBFillColor(context, 0.0, 0.0, 1.0, 1.0);
CGContextSetLineWidth(context, 4.0);
for(int i = 0; i < self.routes.count; i++) {
CLLocation* location = [self.routes objectAtIndex:i];
CGPoint point = [mapView convertCoordinate:location.coordinate toPointToView:routeView];
if(i == 0) {
CGContextMoveToPoint(context, point.x, routeView.frame.size.height - point.y);
} else {
CGContextAddLineToPoint(context, point.x, routeView.frame.size.height - point.y);
}
}
CGContextStrokePath(context);
CGImageRef image = CGBitmapContextCreateImage(context);
UIImage* img = [UIImage imageWithCGImage:image];
routeView.image = img;
CGContextRelease(context);
}
You can use google api like-
Define approirate variable in .h-
NSArray *arrRoutePoints;
MKPolygon *objpolygon;
MKPolyline *objpolyline;
Call function like where you want -
self.arrRoutePoints=[self getRoutePointFrom:newSource to:newDestination];
[self drawRoute];
Function Code :
- (NSArray*)getRoutePointFrom:(MKPointAnnotation *)origin to:(MKPointAnnotation *)destination
{
NSString *saddress=[NSString stringWithFormat:#"%f,%f",origin.coordinate.latitude,origin.coordinate.longitude];
NSString *daddress=[NSString stringWithFormat:#"%f,%f",destination.coordinate.latitude,destination.coordinate.longitude];
NSString *apiUrlString=[NSString stringWithFormat:#"http://maps.google.com/maps?output=dragdir&saddr=%#&daddr=%#", saddress, daddress];
NSURL *apiUrl=[NSURL URLWithString:apiUrlString];
NSError *error;
NSString *apiResponse=[NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error];
NSRange range;
range=[apiResponse rangeOfString:#"points:\\\"([^\\\"]*)\\\"" options:NSRegularExpressionSearch];
NSString *encodedPoint=[apiResponse substringWithRange:range];
NSLog(#"Encode lentgh %d",[encodedPoint length]);
encodedPoint=[encodedPoint stringByReplacingOccurrencesOfString:#"points:\"" withString:#""];
encodedPoint=[encodedPoint stringByReplacingOccurrencesOfString:#"\"" withString:#""];
return [self decodePolyLine:[encodedPoint mutableCopy]];
}
- (NSMutableArray *)decodePolyLine:(NSMutableString *)encodedString
{
[encodedString replaceOccurrencesOfString:#"\\\\" withString:#"\\"
options:NSLiteralSearch
range:NSMakeRange(0, [encodedString length])];
NSInteger len = [encodedString 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 = [encodedString 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 {
if(index<len)
{
b = [encodedString characterAtIndex:index++] - 63;
result |= (b & 0x1f) << shift;
shift += 5;
}
else
{
break;
}
} 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("\n[%f,", [latitude doubleValue]);
printf("%f]", [longitude doubleValue]);
CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]];
[array addObject:loc];
}
return array;
}
- (void)drawRoute
{
int numPoints=[arrRoutePoints count];
if(numPoints >1)
{
CLLocationCoordinate2D *coord=malloc(numPoints *sizeof(CLLocationCoordinate2D));
for(int i=0;i<numPoints;i++)
{
CLLocation *current=[arrRoutePoints objectAtIndex:i];
NSLog(#"%#",[arrRoutePoints objectAtIndex:i]);
NSLog(#"Current \n[%g",current.coordinate.latitude);
NSLog(#"%g]",current.coordinate.longitude);
coord[i]=current.coordinate;
NSLog(#"\n[%g",coord[i].latitude);
NSLog(#"%g]",coord[i].longitude);
}
self.objpolyline=[MKPolyline polylineWithCoordinates:coord count:numPoints];
free(coord);
[mapView addOverlay:objpolyline];
[mapView setNeedsDisplay];
}
}