Google maps polyline not rendering perfectly - ios

I am drawing polyline using latest google maps API for iOS. I am constructing polyline point by point but it is not rendering properly as when i zoom out the polyline vanishes(not in literal terms) from the map and when i zoom in it simply shows the line.
This is how polyline appears when zoomed in
This is how it appears when zoomed out
here is my function for drawing polyline
RCPolyline *polyline = [[RCPolyline alloc] init];
[polyline drawPolylineFromPoint:self.selectedEmployee.location toPoint:location];
i have override init: for RCPolyline to be something like this
- (instancetype)init {
self = [super init];
if (self) {
self.strokeWidth = 5.0f;
self.strokeColor = UIColor.redColor;
self.geodesic = YES;
self.map = [RCMapView sharedMapView];
}
return self;}
and drawPolylineFromPoint:toPoint: does this
- (void)drawPolylineFromPoint:(CLLocation *)pointX toPoint:(CLLocation *)pointY {
GMSMutablePath *path = [GMSMutablePath path];
[path addCoordinate:pointX.coordinate];
[path addCoordinate:pointY.coordinate];
self.path = path;}

I found the glitch, i was making local instance of RCPolyline class and was calling the method for constructing polyline from that what i wanted was to have a global object for RCPolyline instance and update the GMSPath for the RCPolyline class instance
something like this:
- (instancetype)initWithMap:(GMSMapView *)mapView {
self = [super init];
if (self) {
self.strokeWidth = 4.0f;
self.strokeColor = [UIColor redColor];
self.geodesic = YES;
self.map = mapView;
self.mutablePath = [GMSMutablePath path];
}
return self;}
and now i am calling this method from that same instance.
- (void)appendPolylineWithCoordinate:(CLLocation *)location {
[self.mutablePath addCoordinate:location.coordinate];
self.path = self.mutablePath;}
PS: RCPolyline is subclass of GMSPolyline

Try this code.
- (void)fetchPolylineWithOrigin:(CLLocation *)origin destination:(CLLocation *)destination {
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:lat longitude:longg zoom:12];
GMSMapView *mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView.myLocationEnabled = YES;
self.view = mapView;
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(-33.86, 151.20);
marker.map = mapView;
NSString *originString = [NSString stringWithFormat:#"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude];
NSString *destinationString = [NSString stringWithFormat:#"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude];
NSString *directionsAPI = #"https://maps.googleapis.com/maps/api/directions/json?";
NSString *directionsUrlString = [NSString stringWithFormat:#"%#&origin=%#&destination=%#&mode=driving&key=%#&alternatives=true", directionsAPI, originString, destinationString,#"YOUR API KEY"];
NSURL *directionsUrl = [NSURL URLWithString:directionsUrlString];
NSURLSessionDataTask *fetchDirectionsTask = [[NSURLSession sharedSession] dataTaskWithURL:directionsUrl completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error)
{
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if(error)
{
return;
}
NSArray *routesArray = [json objectForKey:#"routes"];
GMSPolyline *polyline = nil;
int i=1;
for (id route in routesArray)
{
NSDictionary *routeDict = [route valueForKey:#"overview_polyline"];
NSString *points = [routeDict objectForKey:#"points"];
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
GMSPath *path = [GMSPath pathFromEncodedPath:points];
polyline = [GMSPolyline polylineWithPath:path];
polyline.strokeWidth = 3;
if(i==1)
{
polyline.strokeColor = [UIColor greenColor];
}else if(i==2)
{
polyline.strokeColor = [UIColor redColor];
}else{
polyline.strokeColor = [UIColor blueColor];
}
i = i+1;
bounds = [bounds includingCoordinate:marker.position];
polyline.map=mapView;
}
}];
[fetchDirectionsTask resume];
}

Related

How to iterate over the path from Google Directions API?

I am trying to move the marker along two selected markers with their coordinates set.
I am getting the path from this code:
GMSPath *path1 =[GMSPath pathFromEncodedPath:self.dataReceive[#"routes"][0][#"overview_polyline"][#"points"]];
When i am using the for loop to move first marker to the position of second marker. It is taking a straight path but it should move along the path coordinates that has been fetched from the google directions API.
for (int i = 0; i< path1.count; i++) {
CLLocationCoordinate2D position = [path1 coordinateAtIndex:i];
[CATransaction begin];
[CATransaction setAnimationDuration:50];
self.marker.position = position;
self.marker.map = self.mapView;
[CATransaction commit];
}
Thanks.
Try this code Objective C.
- (void)showPathFromCurrentLocationForCoordinate:(CLLocationCoordinate2D)coord{
CLLocationCoordinate2D destination = coord;
NSMutableString *urlString = [[NSMutableString alloc] initWithString:#"https://maps.googleapis.com/maps/api/directions/json?"];
[urlString appendString:[NSString stringWithFormat:#"origin=%f,%f&destination=%f,%f&sensor=true",self.deviceLocation.latitude,self.deviceLocation.longitude,destination.latitude,destination.longitude]];
[RestApi getPath:urlString withParameter:nil withHandler:^(id responseObject, NSError *error, NSURLResponse *response) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error == nil) {
NSDictionary *json = responseObject;
NSArray *routes = [json objectForKey:#"routes"];
if (routes != nil && routes.count > 0) {
NSDictionary *route = [routes objectAtIndex:0];
long distance = 0;
NSArray *legs = [route objectForKey:#"legs"];
for (NSDictionary *leg in legs) {
long dist = [leg[#"distance"][#"value"] longValue];
distance = distance + dist;
}
GMSPath *path =[GMSPath pathFromEncodedPath:route[#"overview_polyline"][#"points"]];
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.strokeColor = PATH_STROKE_COLOR;
line.strokeWidth = PATH_STROKE_WIDTH;
line.map = mapView;
GMSMutablePath *markerpath = [GMSMutablePath path];
[markerpath addCoordinate: self.deviceLocation];
[markerpath addCoordinate: marker.position];
GMSCoordinateBounds *bonds = [[GMSCoordinateBounds alloc] initWithPath:markerpath];
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat: 1.0] forKey:kCATransactionAnimationDuration];
[mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bonds withPadding:MAP_BOUNDS_OFFSET_PADDING]];
[CATransaction commit];
}
else{
NSLog(#"Google direction API failed.");
}
}
else if (error != nil){
NSLog(#"%#",error.localizedDescription);
}
});
}];
}

Adding a marker image to Google Maps on IOS Objective-C app

I have a map to show directions. I am able to tap on a direction to view an annotation with the instructions but what I am trying to do is add a marker to the directions coordinates. Here is the code I am currently using:
-(void) getDirectionsFromStart: (CLLocation*) start toEnd: (CLLocation*) end
{
NSString *mapDir = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%f,%f&destination=%f,%f&sensor=false", start.coordinate.latitude, start.coordinate.longitude, end.coordinate.latitude, end.coordinate.longitude];
if ([self.directionsArray count] == 0) {
//parse the string response and then draw the points on a map
NSError *error;
NSString *response = [NSString stringWithContentsOfURL:[NSURL URLWithString:mapDir] encoding:NSUTF8StringEncoding error:&error];
if (response == nil) {
NSLog(#"Google Maps error: %#", [error localizedDescription]);
NSLog(#"Google Maps recovery: %#", [error localizedRecoverySuggestion]);
//[self getDirectionsFromStart:nil toEnd:nil];
}
self.directionsArray = [gMapsJsonDirectionsParser parseJsonToMapDirections:response];
}
for (gMapsJourneyLeg *leg in self.directionsArray) {
#autoreleasepool {
self.directionsHeader.text = [NSString stringWithFormat:#"To %# Taking: %#", leg.end_address, leg.duration.text];
for (gMapsStep *step in leg.steps ) {
MKPolyline *polyLine = [gMapsJsonDirectionsParser polylineWithEncodedString:step.polyLine];
MKPolylineView *line = [[MKPolylineView alloc] initWithPolyline: polyLine];
line.fillColor = [UIColor blueColor];
line.strokeColor = [UIColor blueColor];
line.lineWidth = 5;
[self.mapView addOverlay:polyLine];
//[self.mapView setVisibleMapRect:polyLine.boundingMapRect];
//map point code
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = step.end_location.coordinate;
point.title = step.htmlInstructions;
[[self.mapView viewForAnnotation:point] setTag:1];
UIImage *image = [UIImage imageNamed:#"marker_red.png"];
[[self.mapView viewForAnnotation:point] setImage:image];
[self.mapView addAnnotation:point];
}
}
}
[self.tableView reloadData];
}
To be clear, the annotations and polyline are both fine it's just the marker is never shown.
Base on the code in the Google Docs for Markers:
Here is the sample code for adding markers with custom image.
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127);
GMSMarker *london = [GMSMarker markerWithPosition:position];
london.title = #"London";
london.icon = [UIImage imageNamed:#"house"];
london.map = mapView_;
May be you have not set the GMSMarker *london = [GMSMarker markerWithPosition:position]; that is why your marker is not visible.
Kindly check the marker without a custom image if it will show up, if not try adding the markerPosition property.

how to draw line between x number of moving annotations?

Hai am new to xcode am developing an iOS app for vehicle tracking using mkmap I need to draw lines between the annotations for every 5 seconds based on the vehicle moving, My prob is it draw the line for the first time only and from the second refresh interval it it won't works my code is below,
- (void)viewDidLoad
{
[super viewDidLoad];
aTimer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(timerFired:)
userInfo:nil
repeats:YES];
}
-(void)timerFired:(NSTimer *) theTimer
{
NSArray *existingpoints = MapViewC.annotations;
if ([existingpoints count])
[MapViewC removeAnnotations:existingpoints];
NSString *urlMapString=[NSString stringWithFormat:#"http://www.logix.com/logix_webservice/map.php?format=json&truckno=%#",nam2];
NSURL *urlMap=[NSURL URLWithString:urlMapString];
NSData *dataMap=[NSData dataWithContentsOfURL:urlMap];
NSError *errorMap;
NSDictionary *jsonMap = [NSJSONSerialization JSONObjectWithData:dataMap options:kNilOptions error:&errorMap]; NSArray *resultsMap = [jsonMap valueForKey:#"posts"];
NSArray *resMap = [resultsMap valueForKey:#"post"];
NSArray *latitudeString=[resMap valueForKey:#"latitude"];
NSString *latOrgstring = [latitudeString objectAtIndex:0];
latitude=[latOrgstring doubleValue];
NSArray *longitudeString=[resMap valueForKey:#"longitude"];
NSString *longOrgstring = [longitudeString objectAtIndex:0];
longitude=[longOrgstring doubleValue];
NSString *ignation=[[resMap valueForKey:#"ignition"]objectAtIndex:0];
//MAP VIEW Point
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta=0.01f;
span.longitudeDelta=0.01f;
myRegion.center=center;
myRegion.span=span;
//Set our mapView
[MapViewC setRegion:myRegion animated:YES];
//Annotation
//1.create coordinate for use with the annotation
//CLLocationCoordinate2D wimbLocation;
wimbLocation1.latitude=latitude;
wimbLocation1.longitude=longitude;
Annotation * myAnnotation= [Annotation alloc];
CLLocation *someLocation=[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSDictionary *dictionary = [[placemarks objectAtIndex:0] addressDictionary];
addressOutlet=[dictionary valueForKey:#"Street"];
City=[dictionary valueForKey:#"City"];
State=[dictionary valueForKey:#"State"];
myAnnotation.coordinate=wimbLocation1;
if (addressOutlet!=NULL&&City!=NULL)
{
myAnnotation.title=addressOutlet;
myAnnotation.subtitle=[NSString stringWithFormat:#"%#,%#", City, State];
}
[self.MapViewC addAnnotation:myAnnotation];
[self line];
}];
}
-(void)line
{
CLLocationCoordinate2D coordinateArray[2];
coordinateArray[0] = CLLocationCoordinate2DMake(latitude, longitude);
coordinateArray[1] = CLLocationCoordinate2DMake(latitude, longitude);
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:2];
[self.MapViewC addOverlay:self.routeLine];
}
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor redColor];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 5;
}
return self.routeLineView;
}
return nil;
}
Kindly advice me to correct my errors. Thanks in advance...
Try this.... this will help you...
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.strokeColor = [UIColor redColor];
self.routeLineView.lineWidth = 5;
}
return self.routeLineView;
}

How to create route map using the google maps sdk for ios

Hi in my application i have to give route to my destination coordinates so i have integrated google map in my application but i dont how to give route navigation for the that. After long search i got some sample code. Its like if tape locations in map it will show the route direction on the map.
This is my smaple code.
(void)loadView {
waypoints_ = [[NSMutableArray alloc]init];
waypointStrings_ = [[NSMutableArray alloc]init];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:12.9259
longitude:77.6229
zoom:13];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.delegate = self;
self.view = mapView_;
}
- (void)mapView:(GMSMapView *)mapView didTapAtCoordinate:
(CLLocationCoordinate2D)coordinate {
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(
coordinate.latitude,
coordinate.longitude);
GMSMarker *marker = [GMSMarker markerWithPosition:position];
marker.map = mapView_;
[waypoints_ addObject:marker];
NSString *positionString = [[NSString alloc] initWithFormat:#"%f,%f",
coordinate.latitude,coordinate.longitude];
[waypointStrings_ addObject:positionString];
if([waypoints_ count]>1){
NSString *sensor = #"false";
NSArray *parameters = [NSArray arrayWithObjects:sensor, waypointStrings_,
nil];
NSArray *keys = [NSArray arrayWithObjects:#"sensor", #"waypoints", nil];
NSDictionary *query = [NSDictionary dictionaryWithObjects:parameters
forKeys:keys];
MDDirectionService *mds=[[MDDirectionService alloc] init];
SEL selector = #selector(addDirections:);
[mds setDirectionsQuery:query
withSelector:selector
withDelegate:self];
}
}
- (void)addDirections:(NSDictionary *)json {
NSDictionary *routes = [json objectForKey:#"routes"][0];
NSDictionary *route = [routes objectForKey:#"overview_polyline"];
NSString *overview_route = [route objectForKey:#"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:overview_route];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.map = mapView_;
}
The above code will show the route location when u tape on the map i want to do like my current location to my destination coordinate please tell me how to achieve this one.
for example this my destination coordinate 12.9259,77.6229
Thanks.
All you need to do is just select two points and give it too google to give you a route's JSON and it will draw it on your map. This is what I did which draw a route from device's location to your destination point :
-(void) updateRoute {
self.isMapUpdated = YES;
CLLocationCoordinate2D position2 = CLLocationCoordinate2DMake(
self.locationManager.location.coordinate.latitude,
self.locationManager.location.coordinate.longitude);
GMSMarker *marker2 = [GMSMarker markerWithPosition:position2];
marker2.map = self.mapView;
marker2.title = #"I AM HERE!!";
[waypoints_ addObject:marker2];
NSString *positionString2 = [[NSString alloc] initWithFormat:#"%f,%f",
self.locationManager.location.coordinate.latitude,self.locationManager.location.coordinate.longitude];
[waypointStrings_ addObject:positionString2];
CLLocationCoordinate2D position1 = CLLocationCoordinate2DMake( destination.LAT, destination.LONG);
GMSMarker *marker1 = [GMSMarker markerWithPosition:position1];
marker1.map = self.mapView;
marker1.icon = [UIImage imageNamed:#"marker.png"];
[waypoints_ addObject:marker1];
NSString *positionString1 = [[NSString alloc] initWithFormat:#"%f,%f",
destination.LAT,destination.LONG];
[waypointStrings_ addObject:positionString1];
if([waypoints_ count]>1){
NSString *sensor = #"false";
NSArray *parameters = [NSArray arrayWithObjects:sensor, waypointStrings_,
nil];
NSArray *keys = [NSArray arrayWithObjects:#"sensor", #"waypoints", nil];
NSDictionary *query = [NSDictionary dictionaryWithObjects:parameters
forKeys:keys];
MDDirectionService *mds=[[MDDirectionService alloc] init];
SEL selector = #selector(addDirections:);
[mds setDirectionsQuery:query
withSelector:selector
withDelegate:self];
}
}
- (void)addDirections:(NSDictionary *)json {
if([json objectForKey:#"routes"] != nil)
if([[json objectForKey:#"routes"] count] != 0){
NSDictionary *routes = [json objectForKey:#"routes"][0];
NSDictionary *route = [routes objectForKey:#"overview_polyline"];
NSString *overview_route = [route objectForKey:#"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:overview_route];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.strokeColor = [Utility colorWithHexString:#"790566"];
polyline.strokeWidth = 3.0;
polyline.map = self.mapView;
}
}
Also you need MDDirectionService header and main files to import to your project and add the header file to your class which you can download them from the simple app which Google provided it.

fitBounds in GoogleMaps SDK for ios does not fit

I want use fitBounds method in GoogleMaps for ios SDK and view does not fit. My varaibles are all right (path, arrays, etc...) because I can see polyline with markers on map. The only thing that does not work is fit to view. Where I have made mistake? thank you.
// Create a 'normal' polyline.
GMSPolyline *polyline = [[GMSPolyline alloc] init];
GMSMutablePath *path = [GMSMutablePath path];
locationInfoArray = [LocationInfoMemoryManager loadLocationDataWithPath:_locationInfoPathString];
for (int i=0; i<locationInfoArray.count; i++) {
LocationInfo* locationInfo = locationInfoArray[i];
CLLocationCoordinate2D locationPoint = {locationInfo.latitude, locationInfo.longitude};
[path addCoordinate:locationPoint];
}
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:[locationInfoArray[0] latitude]
longitude:[locationInfoArray[0] longitude]
zoom:5 ];
mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
polyline.path = path;
polyline.strokeColor = [UIColor blueColor];
polyline.strokeWidth = 10.f;
polyline.zIndex = 15; // above the larger geodesic line
polyline.map = mapView;
GMSMarker *startMarker = [[GMSMarker alloc] init];
startMarker.title = #"Start";
startMarker.snippet = #"Info will be here";
startMarker.position = CLLocationCoordinate2DMake([[locationInfoArray firstObject] latitude], [[locationInfoArray firstObject] longitude]);
startMarker.map = mapView;
startMarker.flat = NO;
//sydneyMarker.rotation = 30.0;
mapView.selectedMarker = startMarker;
GMSMarker *finishMarker = [[GMSMarker alloc] init];
finishMarker.title = #"Finish";
finishMarker.snippet = #"Info will be here";
finishMarker.position = CLLocationCoordinate2DMake([[locationInfoArray lastObject] latitude], [[locationInfoArray lastObject] longitude]);
finishMarker.map = mapView;
finishMarker.flat = NO;
mapView.selectedMarker = finishMarker;
//Here is probably problem
GMSCoordinateBounds *bounds; = [[GMSCoordinateBounds alloc] initWithPath:path];
GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds withPadding:20];
[mapView moveCamera:update];
self.view = mapView;
Is this code in loadView or viewDidLoad? Based on these earlier questions, I think camera updates only work correctly from viewWillAppear:
GMSCameraUpdate zooming out to the max distance rather than around a path
Fit bounds not working as expected

Resources