Zoom MKMapView to fit polyline and annotation pins - Horizontal orientation

584 views Asked by At

I have an iOS app with a view that contains a few different labels plus a small MKMapView.

On the map view, I have draw a trip route (using a polyline) and have added two annotation pins, one at the start of the route and the other at the end of the route.

All I am trying to do is to change the map zoom/rotation, so that the polyline and two annotation pins, fit the size of the map view. However everything I have tried has failed.

My approach

1) Add the polyline to the map view.

2) Use setVisibleMapRect to adjust the map view, so that the polyline fits within the map. (I have also added some padding, by using the edge insets parameter).

3) Use MKMapCamera to change the rotation of the map, so that the polyline + pins are presented in a horizontal manner.

Here is my code:

// Convert the preview string to a
// MKPolyline map direction object.
MKPolyline *map_data = [self polyline_with_encoded_string:[trip preview]];

// Add the polyline to the map view.
[main_map addOverlay:map_data];

// Set the display area around the polyline.
[main_map setVisibleMapRect:[map_data boundingMapRect] edgePadding:UIEdgeInsetsMake(28.0, 28.0, 28.0, 28.0) animated:YES];

// Calculate the current clockwise degree.
double degree = [self calculate_bearing_angle:[trip.startPoint latitude] :[trip.startPoint longitude] :[trip.stopPoint latitude] :[trip.stopPoint longitude]];

// Change the degree to the approriate
// trip polyline degree (anti-clockwise).

if ((degree >= 0) && (degree <= 90)) {
    degree = (270 + degree);
}

else if ((degree > 90) && (degree <= 180)) {
    degree = (270 - (degree - 90));
}

else if ((degree > 180) && (degree <= 270)) {
    degree = (360 - (degree - 180));
}

else if ((degree > 270) && (degree <= 360)) {
    degree = (90 + degree);
}

// Rotate the map so that the trip polyline
// fits horizontally rather than vertically.
MKMapCamera *map_camera = [[main_map camera] copy];
[map_camera setHeading:degree];
[main_map setCamera:map_camera animated:YES];

I am using the following method to figure out the angle of the polyline:

-(double)calculate_bearing_angle:(double)start_lat :(double)start_lon :(double)end_lat :(double)end_lon {

    // Get the seperate latitude/longitude values.
    double from_lat = DEGREES_TO_RADIANS(start_lat);
    double from_lon = DEGREES_TO_RADIANS(start_lon);
    double to_lat = DEGREES_TO_RADIANS(end_lat);
    double to_lon = DEGREES_TO_RADIANS(end_lon);

    // Calculate the bearing angle.
    double degree = RADIANS_TO_DEGREES(atan2(sin(to_lon - from_lon) * cos(to_lat), cos(from_lat) * sin(to_lat) - sin(from_lat) * cos(to_lat) * cos(to_lon - from_lon)));

    if (degree >= 0) {
        return degree;
    }

    else {
        return (360 + degree);
    }
}

I have tried everything, but either way the end result is that certain polylines at certain angles are rotated to the correct horizontal angle and others arn't.... what an earth am I doing wrong? Or is there a better built in approach to this problem?

All I want to do, is to change this:

enter image description here

... to this:

enter image description here

1

There are 1 answers

2
Reinier Melian On BEST ANSWER

I had been working in your problem, for me this method [[self.map camera] setHeading:90.f]; works as intended, so maybe your problem is in the calculation on radians and the latter process, but maybe your problem is also related to the copy of camera. I use this method directly on the mapĀ“s camera and works great. I hope this helps you