Trying to implement a polyline but it doesn't appear - ios

I am trying to get a polyline which should be there in my track application. I have gone through various questions and websites regarding this but I can't really guess where I am going wrong. It will be great if someone can help me out? :)
My Code -->
CLLocation *currentLocation = [locations lastObject];
[linerArray addObject:currentLocation];
CLLocationDegrees lat = currentLocation.coordinate.latitude;
CLLocationDegrees lngt= currentLocation.coordinate.longitude;
CLLocationCoordinate2D lccoordinates = CLLocationCoordinate2DMake(lat, lngt);
NSInteger calculateCoordinates= linerArray.count;
CLLocationCoordinate2D coordinates[calculateCoordinates];
for (NSInteger initialStart= 0; initialStart < calculateCoordinates; initialStart ++) {
CLLocation *lct = [linerArray objectAtIndex:initialStart];
CLLocationCoordinate2D cord2 = lct.coordinate;
coordinates[initialStart] = cord2;
}
//drawing a polyline
MKPolyline *pline = [MKPolyline polylineWithCoordinates:coordinates count:calculateCoordinates];
[self.viewMap addOverlay:pline];
}
//Designing overlay polyline or setting polyine view
-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{
MKPolylineRenderer *polylineRender = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
polylineRender.lineWidth = 7.0f;
polylineRender.strokeColor = [UIColor blueColor];
return polylineRender;
}

Related

Recording the movement of the user in 10 meter increments and displaying it as a line in MKMapView doesn’t work

I‘m a beginner trying to solve a problem in which I have to display the location path of the user every ten meters after the user hits ‚start‘.
I‘ve set up the location manager. The location is being updated, the problem is that it doesn't show a visual path between the starting point and the current user location.
How do I show the visual path?
I tried to calculate the route with MKDirectionsRequest and -Response and it worked well with two given locations, which in this case I don't have though. I also tried the MKMapPoints but to be honest it isn't the point of our homework, in that it would make it unnecessarily complicated.
Here is my current state:
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *newLocation;
newLocation = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(newLocation.coordinate.latitude, newLocation.coordinate.longitude) altitude:kCLLocationAccuracyNearestTenMeters horizontalAccuracy:kCLLocationAccuracyNearestTenMeters verticalAccuracy:newLocation.verticalAccuracy timestamp:newLocation.timestamp];
newLocation = [locations lastObject];
if (newLocation.horizontalAccuracy < 0) {
return;
}
NSInteger count = [locations count];
if (count > 1) {
CLLocationCoordinate2D coordinates[count];
for (NSInteger i = 0; i < count; i++) {
coordinates[i] = [(CLLocation *)locations[i] coordinate];
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coordinates count:count];
[self.mapView addOverlay:polyline level:MKOverlayLevelAboveRoads];
}
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(self.wegAnnotation.coordinate, 200, 200);
[mapView setRegion:region];
[manager stopUpdatingLocation];
self.myLocationManager = nil;
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay {
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithOverlay:overlay];
renderer.strokeColor = [UIColor blueColor];
renderer.lineWidth = 5.0;
return renderer;
}

In IOS track user location in Google Map

I am using google map SDKs in my iOS project to track the user location and a draw a route line of the user path for his movement.I want to add two images for the starting point of the user and another for user movement. I can't add these images.Please help me to add these images. Here is my code:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
//get the latest location
CLLocation *currentLocation = [locations lastObject];
//store latest location in stored track array;
[self.locations addObject:currentLocation];
//get latest location coordinates
CLLocationDegrees Latitude = currentLocation.coordinate.latitude;
CLLocationDegrees Longitude = currentLocation.coordinate.longitude;
CLLocationCoordinate2D locationCoordinates = CLLocationCoordinate2DMake(Latitude, Longitude);
//zoom map to show users location
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(locationCoordinates, 1000,1000);
MKCoordinateRegion adjustedRegion = [mapview regionThatFits:viewRegion];
[mapview setRegion:adjustedRegion animated:YES];
NSInteger numberOfSteps = self.locations.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [self.locations objectAtIndex:index];
CLLocationCoordinate2D coordinate2 = location.coordinate;
coordinates[index] = coordinate2;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[mapview addOverlay:polyLine];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor redColor];
polylineView.lineWidth = 10.0;
return polylineView;
}
This code draw the user path. But I want this type of output.
Someone please help me.
Add annotations to mapview, for first and last objects of your self.locations array. You will also need to remove the old annotation each time the location is updated to a new one.
Let centerY and centerX be the center point for the image
CLLocationDegrees offset = 0.01; // change size here
CLLocationDegrees southWestY = centerY - offset;
CLLocationDegrees southWestX = centerX - offset;
CLLocationDegrees northEastY = centerY + offset;
CLLocationDegrees northEastX = centerX + offset;
CLLocationCoordinate2D southWest = CLLocationCoordinate2DMake(southWestY,southWestX);
CLLocationCoordinate2D northEast = CLLocationCoordinate2DMake(northEastY,northEastX);
GMSCoordinateBounds *overlayBounds = [[GMSCoordinateBounds alloc] initWithCoordinate:southWest coordinate:northEast];
GMSGroundOverlay *overlay = [GMSGroundOverlay groundOverlayWithBounds:overlayBounds icon:[UIImage imagedNamed:#"YourImage.png"]];
overlay.bearing = 0;
overlay.map = self.mapView
With this approach (unlike with the marker) the image will zoom in and out as the user zooms in/out of the map.

Multiple overlays vs continous redrawing im MKMapView

I am drawing users location path on MKMapView live and I am wondering what's better approach.
Currently I am gathering all location data in location manager and I am redrawing whole overlay every second.
- (void)showLines {
NSArray *locations = [[SHLocationManager sharedInstance] locations];
CLLocationCoordinate2D *pointsCoordinate = (CLLocationCoordinate2D *)malloc(sizeof(CLLocationCoordinate2D) * locations.count);
[locations enumerateObjectsUsingBlock:^(CLLocation *location, NSUInteger idx, BOOL *stop) {
pointsCoordinate[idx] = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude);
}];
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:pointsCoordinate count:locations.count];
free(pointsCoordinate);
[self.mapView removeOverlays:self.mapView.overlays];
[self.mapView addOverlay:polyline];
}
- (MKPolylineRenderer *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay{
MKPolylineRenderer *polylineView = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
polylineView.strokeColor = [UIColor colorWithRed:0.17 green:0.57 blue:0.85 alpha:1];
polylineView.lineWidth = 8.0;
polylineView.alpha = 1;
return polylineView;
}
Is it better to draw a line for every pair of point's I get from location manager?
It would create number of overlays - don't know how it would affect performance.
What's better in your opinion?

Create MKPolyline with only recent CLLocations

My app loads the user's past polylines and displays them on the map. Then the app starts tracking and a straight line is drawn from the last updated coordinate to the first, thereby connecting the two separate lines when they should be separate (shown here
I want to remove this straight line, so I'm thinking the easiest way would be to discard coordinates that are outside a set time frame (e.g 1 minute), so polylines on the map remain separate. I'm not sure how to do this though... I'm a beginner so any suggestions would be much appreciated!
I use this code when loading the past polyline
(IBAction)didClickLoadCoordinates:(id)sender {
// get a reference to the appDelegate so you can access the global managedObjectContext
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Route"];
NSError *error;
id results = [appDelegate.managedObjectContext executeFetchRequest:request error:&error];
if ([results count]) {
polyLine = (Route *)(results[0]);
NSArray *coordinates = polyLine.coordinates;
int ct = 0;
for (CLLocation *loc in coordinates) {
NSLog(#"location %d: %#", ct++, loc);
}
// this copies the array to your mutableArray
_locationsArray = [coordinates mutableCopy];
}
NSInteger numberOfSteps = _locationsArray.count;
//convert to coordinates array to construct the polyline
CLLocationCoordinate2D clCoordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_locationsArray objectAtIndex:index];
CLLocationCoordinate2D coordinate2 = location.coordinate;
clCoordinates[index] = coordinate2;
}
MKPolyline *routeLine = [MKPolyline polylineWithCoordinates:clCoordinates count:numberOfSteps];
[_mapView addOverlay:routeLine];
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
And this code to just normally update the cllocations and make the polyline
//get the latest location
CLLocation *currentLocation = [locations lastObject];
//get latest location coordinates
CLLocationDegrees latitude = currentLocation.coordinate.latitude;
CLLocationDegrees longitude = currentLocation.coordinate.longitude;
CLLocationCoordinate2D locationCoordinates = CLLocationCoordinate2DMake(latitude, longitude);
//zoom map to show users location
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(locationCoordinates, 2000, 2000);
MKCoordinateRegion adjustedRegion = [_mapView regionThatFits:viewRegion];
[_mapView setRegion:adjustedRegion animated:YES];
//store latest location in stored track array
[_locationsArray addObject:currentLocation];
//create cllocationcoordinates to use for construction of polyline
NSInteger numberOfSteps = _locationsArray.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++) {
CLLocation *location = [_locationsArray objectAtIndex:index];
CLLocationCoordinate2D coordinate2 = location.coordinate;
coordinates[index] = coordinate2;
}
MKPolyline *routeLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
[_mapView addOverlay:routeLine];
NSLog(#"%#", _locationsArray);

Drop Pin in MapView using Custom Addresses

I created a map view in my app. Now I want the user to be able to add several addresses to drop pins at those locations. I also want the user to be able to remove these pins.
Does anyone know where I can find a good tutorial, or where to start? I have no experience with mapviews...
try this......
-
(void)ShowPins
{
activity.hidden=YES;
[activity stopAnimating];
double lat;
double lng;
for (int ijk=0; ijk<arrayLocationList.count; ijk++)
{
/*Set your lat and long here*/
lat=[[[[arrayLocationList objectAtIndex:ijk]objectForKey:#"location"] objectForKey:#"lat"] doubleValue];
lng=[[[[arrayLocationList objectAtIndex:ijk]objectForKey:#"location"] objectForKey:#"lng"] doubleValue];
CLLocationCoordinate2D geos = CLLocationCoordinate2DMake(lat, lng);
MKPlacemark* marker = [[MKPlacemark alloc] initWithCoordinate:geos addressDictionary:nil];
[mapVieww addAnnotation:marker];
}
CLLocationCoordinate2D coord1 = {.latitude = lat, .longitude =lng};
MKCoordinateSpan span = {.latitudeDelta = .03,.longitudeDelta = .03};
MKCoordinateRegion region = {coord1, span};
[mapVieww setRegion:region];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation;
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"annotation1"];
UILabel *lable=[[UILabel alloc]init];
[newAnnotation addSubview:lable];
newAnnotation.pinColor = MKPinAnnotationColorRed;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = NO;
[newAnnotation setSelected:YES animated:YES];
return newAnnotation;
}
To Drop pins at several locations u have to try this code:
You need to put all those location latitude and longitude in an array and call this function everytime after incrementing the num value
-(void)Mapview
{ NSMutableArray* annotations=[[NSMutableArray alloc] init];
CLLocationCoordinate2D theCoordinate1;
theCoordinate1.latitude = [latit[num]doubleValue];
theCoordinate1.longitude = [longit[num]doubleValue];
Annotation* myAnnotation1=[[Annotation alloc] init];
myAnnotation1.coordinate=theCoordinate1;
[map_view addAnnotation:myAnnotation1];
map_view.showsUserLocation = NO;
[annotations addObject:myAnnotation1];
MKMapRect rect = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 20);
if (MKMapRectIsNull(rect)) {
rect = pointRect;
} else {
rect = MKMapRectUnion(rect, pointRect);
}
}
map_view.visibleMapRect = rect;
}
You can edit this code by adding leftcallout acessoryview or modify the contents in callout view .
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
map_view.showsUserLocation= NO;
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
MKPinAnnotationView* pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"AnnotationIdentifier"];
if(pinView == nil)
{
pinView = pinView=[[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:#"currentloc"] ;
pinView.centerOffset = CGPointMake(0,60);
pinView.animatesDrop=YES;
pinView.canShowCallout=YES;
}
return pinView;
}
To Remove the pins you can use this code
[self.map_view removeAnnotations:map_view.annotations];
(or)
[self.map_view removeAnnotations: [self.map_view.annotations filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"!(self isKindOfClass: %#)", [MKUserLocation class]]]];

Resources