I'm able to draw GMSPolyline on GoogleMaps with array of locations like this
GMSMutablePath *path = [GMSMutablePath path];
for (int i = 0; i <anotherArray.count; i++) {
NSString *string1 = [anotherArray2 objectAtIndex:i];
NSString *string2 = [anotherArray objectAtIndex:i];
[path addCoordinate:CLLocationCoordinate2DMake(string1.doubleValue,string2.doubleValue)];
}
GMSPolyline *rectangle = [GMSPolyline polylineWithPath:path];
rectangle.strokeColor = [UIColor blueColor];
rectangle.map = mapView_;
rectangle.strokeWidth = 2.0f;
But the locations I'm getting from backend server.
So I have to refresh every 10 seconds,getting new locations and adding it to existing path. These are all working fine.
But when I am adding new locations to existing path is moving very fast.
Cause I have a GMSMarker at starting of path and it is looking like jumping from one place to another place.
So how can I animate GMSMarker like slowly moving from one place to another place?
Check on this tutorial. It states how to draw the route lines on the map using the GMSPolyline class. From this related SO thread:
Change your else block to be something more like this:
[CATransaction begin];
[CATransaction setAnimationDuration:2.0];
marker.position = coordindates;
[CATransaction commit];
We enable you to use Core
Animation
for animating Google Maps.
For a worked sample, please see
AnimatedCurrentLocationViewController.{c,m} in the SDK sample
application.
Also based from this SO post, avoid using 1px stroke-width of line. Instead, use 4px stroke-width. You can also check on this GitHub sample.
Related
I tried to draw a route with Google Maps on iOS that come from Google Direction API.
I hit this end point
NSString *urlString = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&mode=driving&key=%#", origin, destination, gDirectionKey];
Then I got its routes that I draw with GMSPolyline
GMSPath *path =[GMSPath pathFromEncodedPath:resultData[#"routes"][0][#"overview_polyline"][#"points"]];
if (routeToCustomer == nil)
routeToCustomer = [[GMSPolyline alloc] init];
routeToCustomer.path = path;
routeToCustomer.strokeWidth = 7;
routeToCustomer.strokeColor = [UIColor colorWithHexString:ACTIVE_COLOR];
routeToCustomer.map = _mapView;
It looks like that the starting line doesn't start in its coordinate, but in the nearest way. See image below.
Is it possible to draw line from its coordinate into "starting direction"? If so, any help would be appreciated. Thank you.
You will need draw a polyline from starting point of google direction result and actual starting point in mapView.
GMSMutablePath *path = [GMSMutablePath path];
[path addCoordinate:CLLocationCoordinate2DMake(actualLat,actualLon)];
[path addCoordinate:CLLocationCoordinate2DMake(startLat,startLon)];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
I am using Google Map SDK for iOS. I am drawing polylines in Driving mode.
But when i stop,and Zoom google map then, my Current position cursor automatically moves and redraw zigzag polylines, due to that all previous polylines drawn get overlapped and polylines get completely changed.Same things happens when i go in background and drive.
Could i know why is it happening? And How can I draw smooth polylines in driving and walking mode same time in same path.
My Code-
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
pointString=[NSString stringWithFormat:#"%f,%f",newLocation.coordinate.latitude,newLocation.coordinate.longitude];
CLLocationDistance kilometers = [newLocation distanceFromLocation:oldLocation] / 1000;
NSLog(#"Distance Travelled in Kilometer :%f",kilometers);
[self.points addObject:pointString];
GMSMutablePath *path = [GMSMutablePath path];
for (int i=0; i<self.points.count; i++)
{
NSArray *latlongArray = [[self.points objectAtIndex:i]componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
[path addLatitude:[[latlongArray objectAtIndex:0] doubleValue] longitude:[[latlongArray objectAtIndex:1] doubleValue]];
}
if (self.points.count>2)
{
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.strokeColor = [UIColor blueColor];
polyline.strokeWidth = 5.f;
polyline.map = mapView_;
self.mapContainerView = mapView_;
}
}
If , I remain in Same position, then Googme map Cursor position automaticalaly moves and draw polylines like this.
add a NSLocationAlwaysUsageDescription and a UIBackgroundModes -> "location" to Info.plist
AND
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9) {
manager.allowsBackgroundLocationUpdates = YES;
}
Before allowing background location updtaes:
enter image description here
After Allowing background location updtaes:
enter image description here
Most of this itinerary has been drawn in the background.
Two things are going on. First, the GPS chip does not always return the same location when standing still. The determined GPS location always fluctuates a bit. iOS does an effort to detect that you're standing still, and then supply the same location, but I think that is done to a lesser extend in Driving mode.
Second, by using the convoluted way to store the samples as strings, you go through a %f conversion, which looses accuracy. That can exaggerate any differences between locations. If you use the CLLocation objects directly, you're likely getting a better result (and much cleaner code):
[self.points addObject:newLocation];
GMSMutablePath *path = [GMSMutablePath path];
for (CLLocation *col in self.points)
{
[path addLatitude:col.latitude longitude:col.longitude];
}
Also, make sure you set the correct settings on the CLLocationManager:
theLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
theLocationManager.distanceFilter = kCLDistanceFilterNone;
theLocationManager.activityType = CLActivityTypeOtherNavigation;
theLocationManager.allowsBackgroundLocationUpdates = YES
One other thing. It is also very strange that you change the view in the didUpdateToLocation: method:
self.mapContainerView = mapView_;
You should just use setNeedsDisplay on the existing view, after updating the path.
hey everyone I'm working on an iOS app and I integrated Google Maps API and I'm using Objective C
I implemented a function that put marks on the maps for every touch to the screen + I get the longitude and latitude of that mark
I want to draw straight lines between those marks, every time I add a new mark it should be linked with the one before
Any ideas please !
GMSMutablePath *path = [GMSMutablePath path];
[path addCoordinate:CLLocationCoordinate2DMake(37.36, -122.0)];
[path addCoordinate:CLLocationCoordinate2DMake(37.45, -122.0)];
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.map = mapView_;
In addition to Ekta's answer: If you want to change the line when your Marker is dragged, you just need to follow these steps:
Clear your map using [mapview clear];
Redraw the line using directions given by Ekta.
Hope it helps.
I have a list of 50+ coordinates. What is the most efficient way to draw lines between all these coordinates (should create a "circular" path because they all have a display order) that is also easy to customize (line thickness, color, etc...)?
Thanks!
I am not sure I understand your question for certain. If you are looking for a list of points to display from end to end, then you will want to create a MKPolyline object from those points, making sure the points are added to the myPoints array in the order you want to connect them:
CLLocationCoordinate2D coordinates[[myPoints count]];
int i = 0;
for (Checkpoint *point in myPoints)
{
coordinates[i] = CLLocationCoordinate2DMake([point.lat floatValue] , [point.lon floatValue]);
i++;
}
self.polyline = [MKPolyline polylineWithCoordinates:coordinates count: [myPoints count]];
[mapView addOverlay:self.polyline];
Then make sure you are implementing the delegate method - mapView:rendererForOverlay:. Here's an example, but tailor it to your needs:
-(MKOverlayRenderer*)mapView:(MKMapView*)mapView rendererForOverlay:(id <MKOverlay>)overlay
{
MKPolylineRenderer* lineView = [[MKPolylineRenderer alloc] initWithPolyline:self.polyline];
lineView.strokeColor = [UIColor blueColor];
lineView.lineWidth = 7;
return lineView;
}
However, if you really want a closed loop (circular) object, then you will want to create a MKPolygon object instead. The process is quite similar; in that case replace the self.polyline initializer above with this code:
self.polygon = [MKPolygon polygonWithCoordinates:coordinates count: [myPoints count]];
[mapView addOverlay:self.polygon];
The - mapView:rendererForOverlay: code should remain the same I think. I haven't tested this code, but hopefully it gets you moving in the right direction.
I am using google map sdk for ios to provide directions between current user location and an end location. I have so far achieved to draw a GMSPolyline between the current user location and the end location using the code below and it's working great.
GMSPath *encodedPath = [GMSPath pathFromEncodedPath:encodedPathSting];
self.polyline = [GMSPolyline polylineWithPath:encodedPath];
self.polyline.strokeWidth = 4;
self.polyline.strokeColor = [UIColor colorWithRed:55.0/255.0 green:160.0/255.0 blue:250.0/255.0 alpha:1.0];;
self.polyline.map = self.mapView;
Is it possible to remove a part of the GMSPolyline that has been covered by the user through driving/walking? The GMSPolyline must gradually decrease in length as we trace the path.
One way to achieve this is by redrawing the path repeatedly but this is not or may not be efficient.
Thanks.
So get the latlng point of the polyline in an array as described here:
//route is the MKRoute in this example
//but the polyline can be any MKPolyline
NSUInteger pointCount = route.polyline.pointCount;
//allocate a C array to hold this many points/coordinates...
CLLocationCoordinate2D * routeCoordinates = malloc(pointCount * sizeof(CLLocationCoordinate2D));
//get the coordinates (all of them)...
[route.polyline getCoordinates: routeCoordinates
range: NSMakeRange(0, pointCount)
];
//this part just shows how to use the results...
NSLog(#"route pointCount = %d", pointCount);
for (int c = 0; c < pointCount; c++) {
NSLog(#"routeCoordinates[%d] = %f, %f",
c, routeCoordinates[c].latitude, routeCoordinates[c].longitude);
}
//free the memory used by the C array when done with it...
free(routeCoordinates);
Then, implement a while loop for the first point as you move along the path like this:
int c = 0;
while (pointCount.size() > 0)
{
pointCount.get(0).remove();
}
Note: I'm not that experienced with iOS and haven't tested this solution. Treat it as a suggestion rather than a fix. Thanks!
Hope it helps!