【发布时间】:2023-04-03 00:35:01
【问题描述】:
我的视图控制器有两个自定义注释视图作为源和目标。我成功地在它们之间建立了一个覆盖路径,并将目标箭头图标的方向设置在同一行覆盖路径中。现在,当我通过按键盘上的“Alt”键在模拟器上旋转地图时,箭头图标不会随覆盖路径方向旋转。为了旋转箭头图标,我采用了地图视图摄像机角度并尝试通过该摄像机角度更新箭头图标方向,但似乎无法正常工作。下面是代码sn-p。我怎样才能做到这一点 ?有没有更好的解决方案?任何形式的帮助都会非常显着。谢谢。
在我的 ViewController.m 文件中 -
#import "MoreController.h"
#import "Annotation.h"
@interface MoreController ()
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@property (strong, nonatomic) Annotation *destination;
@end
@implementation MoreController
- (void) makeOverlayPathBetweenConsecutiveLocation:(Annotation *)source toDest:(Annotation *)destination {
MKMapPoint startPoint = MKMapPointForCoordinate(source.coordinate);
MKMapPoint endPoint = MKMapPointForCoordinate(destination.coordinate);
MKMapPoint *pointArray = malloc(sizeof(CLLocationCoordinate2D) * 2);
pointArray[0] = startPoint;
pointArray[1] = endPoint;
MKPolyline *routeLine = [MKPolyline polylineWithPoints:pointArray count:2];
[self.mapView addOverlay:routeLine];
}
- (CLLocationDirection) getDirection:(Annotation *)source toDest:(Annotation *)destination {
CLLocation *startLocation = [source getLocation];
CLLocation *endLocation = [destination getLocation];
//Determine the direction
double lat1 = startLocation.coordinate.latitude * M_PI / 180.0;
double lon1 = startLocation.coordinate.longitude * M_PI / 180.0;
double lat2 = endLocation.coordinate.latitude * M_PI / 180.0;
double lon2 = endLocation.coordinate.longitude * M_PI / 180.0;
double dLon = lon2 - lon1;
double y = sin(dLon) * cos(lat2);
double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
double radiansBearing = atan2(y, x);
CLLocationDirection directionBetweenPoints = radiansBearing * 180.0 / M_PI;
return directionBetweenPoints;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
CLLocationCoordinate2D sourceCoordinate = {
51.0455555556,
1.94722222222
};
CLLocationCoordinate2D destCoordinate = {
51.0491666667,
1.80805555556
};
Annotation *sourceAnnotation = [[Annotation alloc] initWithCoordinate:sourceCoordinate forTitle:@"Source" forSubTitle:@"From"];
[sourceAnnotation setTypeOfAnnotation:PIN_ANNOTATION];
Annotation *destAnnotation = [[Annotation alloc] initWithCoordinate:destCoordinate forTitle:@"Destination" forSubTitle:@"To"];
[destAnnotation setTypeOfAnnotation:ARROW_ANNOTATION];
[destAnnotation setDirection:[self getDirection:sourceAnnotation toDest:destAnnotation]];
[self makeOverlayPathBetweenConsecutiveLocation:sourceAnnotation toDest:destAnnotation];
[self.mapView addAnnotation:sourceAnnotation];
[self.mapView addAnnotation:destAnnotation];
[self.mapView setRegion:MKCoordinateRegionMake(destCoordinate, MKCoordinateSpanMake(0.3, 0.3))
animated:YES];
self.destination = destAnnotation;
}
- (MKOverlayRenderer *) mapView:(MKMapView *) mapView viewForOverlay:(id) overlay {
if ([overlay isKindOfClass:[MKPolyline class]]) {
MKPolyline *route = overlay;
MKPolylineRenderer *routeRenderer = [[MKPolylineRenderer alloc] initWithPolyline:route];
routeRenderer.strokeColor = [UIColor blueColor];
routeRenderer.lineWidth = 2.0;
return routeRenderer;
} else {
return nil;
}
}
//Determine the direction of arrow icon
- (UIImage*)rotatedImage:(UIImage*)sourceImage byDegreesFromNorth:(double)degrees {
CGSize rotateSize = sourceImage.size;
UIGraphicsBeginImageContext(rotateSize);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, rotateSize.width/2, rotateSize.height/2);
CGContextRotateCTM(context, ( degrees * M_PI/180.0 ) );
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(UIGraphicsGetCurrentContext(),
CGRectMake(-rotateSize.width/2,-rotateSize.height/2,rotateSize.width, rotateSize.height),
sourceImage.CGImage);
UIImage *rotatedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return rotatedImage;
}
//Make custom annotaion pin if the annotation is of ship's current position
- (MKAnnotationView *) mapView:(MKMapView *) mapView viewForAnnotation: (id) annotation {
MKAnnotationView *customAnnotationView;
NSString *reuseId = @"custom";
if ([annotation isKindOfClass:[Annotation class]]){
Annotation *_annotation = (Annotation*)annotation;
if ([[_annotation typeOfAnnotation] isEqualToString:PIN_ANNOTATION]) {
customAnnotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
[customAnnotationView setCanShowCallout:YES];
} else {
customAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
//Determine the direction
UIImage *arrowImage = [UIImage imageNamed:@"arrow"];
double direction = [_annotation direction];
[customAnnotationView setImage:[self rotatedImage:arrowImage byDegreesFromNorth:direction]];
[customAnnotationView setCanShowCallout:YES];
}
} else {
return nil;
}
return customAnnotationView;
}
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
MKMapCamera *camera = self.mapView.camera;
CLLocationDirection mapAngle = camera.heading;
NSLog(@"map angle : %f", mapAngle);
if (mapAngle && (self.destination != nil)) {
//Determine the arrow icon direction
[self.mapView removeAnnotation:self.destination];
[self.destination setDirection:mapAngle];
[self.mapView addAnnotation:self.destination];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
和我的自定义注释文件 -
#import "Annotation.h"
@implementation Annotation
@synthesize coordinate=_coordinate;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate forTitle:(NSString *)title forSubTitle:(NSString *)territory {
self = [super init];
if (self != nil) {
_coordinate = coordinate;
_name = title;
_territory = territory;
}
return self;
}
-(CLLocation *) getLocation {
return [[CLLocation alloc] initWithLatitude: _coordinate.latitude longitude: _coordinate.longitude];
}
//Add a Callout
- (NSString*) title {
return self.name;
}
//Add a Callout
- (NSString*) subtitle {
return self.territory;
}
@end
【问题讨论】:
标签: ios objective-c annotations mkmapview cllocationmanager