Lorsque j'utilise setShowsUserLocation
avec MKMapView
pour suivre l'emplacement de l'utilisateur, comment définir le filtre de précision et de distance? Je ne parle pas de CLLocationManager
.
Merci,
Vous ne pouvez pas contrôler la précision du gestionnaire d'emplacement interne MKMapView
(celui utilisé pour suivre l'utilisateur avec le point bleu), mais vous pouvez créer le vôtre et l'utiliser pour recentrer la carte. Voici une recette ...
Dans le délégué de l'emplacement central:
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"User has denied location services");
} else {
NSLog(@"Location manager did fail with error: %@", error.localizedFailureReason);
}
}
Juste avant de configurer le gestionnaire d'emplacement:
if (![CLLocationManager locationServicesEnabled]){
NSLog(@"location services are disabled"];
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied){
NSLog(@"location services are blocked by the user");
return;
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized){
NSLog(@"location services are enabled");
}
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined){
NSLog(@"about to show a dialog requesting permission");
}
self.locationManager = [CLLocationManager new];
self.locationManager.purpose = @"Tracking your movements on the map.";
self.locationManager.delegate = self;
/* Pinpoint our location with the following accuracy:
*
* kCLLocationAccuracyBestForNavigation highest + sensor data
* kCLLocationAccuracyBest highest
* kCLLocationAccuracyNearestTenMeters 10 meters
* kCLLocationAccuracyHundredMeters 100 meters
* kCLLocationAccuracyKilometer 1000 meters
* kCLLocationAccuracyThreeKilometers 3000 meters
*/
self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
/* Notify changes when device has moved x meters.
* Default value is kCLDistanceFilterNone: all movements are reported.
*/
self.locationManager.distanceFilter = 10.0f;
/* Notify heading changes when heading is > 5.
* Default value is kCLHeadingFilterNone: all movements are reported.
*/
self.locationManager.headingFilter = 5;
// update location
if ([CLLocationManager locationServicesEnabled]){
[self.locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
MKCoordinateRegion region = { { 0.0f, 0.0f }, { 0.0f, 0.0f } };
region.center = newLocation.coordinate;
region.span.longitudeDelta = 0.15f;
region.span.latitudeDelta = 0.15f;
[self.mapView setRegion:region animated:YES];
}
Mettez cela sur le délégué. MKMapView n'a pas de filtre de distance ou de précision, seul CLLocationManager en a. Ce que MKMapView a est une étendue de région autour d'un point, dans l'exemple ci-dessus 0,15 degrés (0,15 * 111 Km).
La documentation ne dit pas d'où MKMapView
obtient ses mises à jour. j'ai essayé
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
NSLog(@"newLocation %@", newLocation.timestamp);
NSLog(@"last map location %@", [NSString stringWithFormat:@"%@",[[[self.mapView userLocation] location] timestamp]]);
}
et je reçois des valeurs différentes sur chacun. Il semble que MKMapView
utilise son propre CLLocationManager
, ce qui signifie que vous ne pouvez pas définir sa précision. Vous ne pouvez pas non plus ajouter votre délégué pour le CLLocationManager
du MKMapView
.
Mon impression est que la seule façon de définir la précision est de définir la position de l'utilisateur sur NON et de créer une annotation personnalisée avec un point bleu, ce qui signifie recentrer la carte manuellement telle que publiée. Vous pouvez obtenir le graphique à points bleus à partir du SDK avec l'extracteur d'illustrations du projet github.
Je ne sais pas si je manque quelque chose ou si cette partie de MKMapView
est juste nul.
Pour afficher la carte, voici un exemple de code.
Importez d'abord MKMapKit et CoreLocation Framework dans votre fichier .h.
#import <MapKit/MapKit.h>
#import <CoreLocation/CoreLocation.h>
Ajouter MKMapKit et CoreLocation Delegate dans un fichier .h
@interface MapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate>
CGPoint gameMapCenter = CGPointMake([[UIScreen mainScreen] bounds].size.width / 2, [[UIScreen mainScreen] bounds].size.height / 2);
gameMapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 640, 620)];
[gameMapView setCenter:gameMapCenter];
[gameMapView setMapType:MKMapTypeStandard];
[gameMapView setDelegate:self];
[self.view addSubview:gameMapView];
[gameMapView setShowsUserLocation:YES];
Utilisez CLLocationManager
pour récupérer l'emplacement de l'utilisateur.
Déclarez une instance de CLLocationManager
CLLocationManager *locationManager;
Dans ViewDidLoad
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManger startUpdatingLocation];
startUpdatingLocation
Implémentation de la méthode:
(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
//Your Stuff
}
Vous ne pouvez pas définir la précision, cependant, vous pouvez obtenir la précision via userLocation dans la méthode déléguée MKMapView.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"%f", userLocation.location.horizontalAccuracy);
}