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];
}
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 MKMapPoint
s) or the getCoordinates:range:
method (gives the CLLocationCoordinate2D
s).
(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];
}