Question

How do I add and animate a visual element along an arc, which I have created inside mapkit?

The following code will create a nice arc between two points. Imagine an animated visual that will represent an airplane flying along this arc.

-(void)addArc
{
    CLLocationCoordinate2D sanFrancisco = { 37.774929, -122.419416 };
    CLLocationCoordinate2D newYork = { 40.714353, -74.005973 };
    CLLocationCoordinate2D pointsArc[] = { sanFrancisco, newYork };
    //
    MKGeodesicPolyline *geodesic;
    geodesic = [MKGeodesicPolyline polylineWithCoordinates:&pointsArc[0]
                                                     count:2];
    //
    [self.mapView addOverlay:geodesic];
}

enter image description here

Was it helpful?

Solution

The annotation might be the best option actually. Define an annotation class with an assignable coordinate property (or use MKPointAnnotation).

Amazingly, the MKGeodesicPolyline class is kind enough to supply the individual points that it calculated to create the arc through the points property (gives the MKMapPoints) or the getCoordinates:range: method (gives the CLLocationCoordinate2Ds).

(Actually, that property and method are in the MKMultiPoint class which MKPolyline is a subclass of and MKGeodesicPolyline is a subclass of MKPolyline.)

Just update the annotation's coordinate property on a timer and the map view will automatically move the annotation.

Note: For an arc this long, there will be thousands of points.

Here's a very simple, crude example using the points property (easier to use than the getCoordinates:range: method) and performSelector:withObject:afterDelay::

//declare these ivars:
MKGeodesicPolyline *geodesic;
MKPointAnnotation *thePlane;
int planePositionIndex;

//after you add the geodesic overlay, initialize the plane:
thePlane = [[MKPointAnnotation alloc] init];
thePlane.coordinate = sanFrancisco;
thePlane.title = @"Plane";
[mapView addAnnotation:thePlane];

planePositionIndex = 0;
[self performSelector:@selector(updatePlanePosition) withObject:nil afterDelay:0.5];

-(void)updatePlanePosition
{
    //this example updates the position in increments of 50...
    planePositionIndex = planePositionIndex + 50;

    if (planePositionIndex >= geodesic.pointCount)
    {
        //plane has reached end, stop moving
        return;
    }

    MKMapPoint nextMapPoint = geodesic.points[planePositionIndex];

    //convert MKMapPoint to CLLocationCoordinate2D...
    CLLocationCoordinate2D nextCoord = MKCoordinateForMapPoint(nextMapPoint);

    //update the plane's coordinate...
    thePlane.coordinate = nextCoord;

    //schedule the next update...    
    [self performSelector:@selector(updatePlanePosition) withObject:nil afterDelay:0.5];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top