web-dev-qa-db-fra.com

Tracez un cercle de 1000 m de rayon autour de l'emplacement des utilisateurs dans MKMapView

(sous iOS 5 et Xcode 4.2)

J'ai un MKMapView et je veux dessiner un cercle de 1000m de rayon autour de l'emplacement de l'utilisateur.

En surface, il semblerait que la mise en œuvre de la méthode déléguée mapView: viewForAnnotation: , et l'ajout d'un MKAnnotationView personnalisé pour l'emplacement des utilisateurs, serait une solution parfaite. Cela ressemblerait à quelque chose comme ceci:

- (MKAnnotationView *)mapView:(MKMapView *)mapView
            viewForAnnotation:(id <MKAnnotation>)annotation
{
    // If it's the user location, return my custom MKAnnotationView.
    if ([annotation isKindOfClass:[MKUserLocation class]]) {
        return myCustomAnnotationView;
    } else {
        return nil;
    }
}

Cependant, les annotations sur la carte ne sont pas mises à l'échelle lorsque vous effectuez un zoom avant ou arrière sur la carte.

J'ai donc essayé d'ajouter une superposition (car les superpositions évoluent avec la carte), en utilisant la classe MKCircle et en définissant ses coordonnées sur les dernières coordonnées de mon délégué locationManger/map view. Cependant, comme la propriété de coordonnées de MKCircle est en lecture seule, je dois supprimer la superposition puis en ajouter une nouvelle chaque fois que l'utilisateur se déplace. Causant un scintillement notable à mesure qu'il se produit.

Existe-t-il un moyen de créer une échelle d'annotation de manière transparente lorsque la vue de la carte est mise à l'échelle à l'intérieur et à l'extérieur? Ou existe-t-il un bon moyen de faire en sorte qu'une superposition se déplace de manière transparente avec les modifications de l'emplacement des utilisateurs?

Je vous serais très reconnaissant de votre aide :)

58
Jon Cox

Essayez une superposition personnalisée. Ajoutez ceci dans viewDidLoad:

MKCircle *circle = [MKCircle circleWithCenterCoordinate:userLocation.coordinate radius:1000];
[map addOverlay:circle];

userLocation peut être obtenu en stockant MKUserLocationAnnotation en tant que propriété. Ensuite, pour dessiner le cercle, placez-le dans le délégué de la vue de la carte:

- (MKOverlayRenderer *)mapView:(MKMapView *)map viewForOverlay:(id <MKOverlay>)overlay
{
    MKCircleRenderer *circleView = [[MKCircleRenderer alloc] initWithOverlay:overlay];
    circleView.strokeColor = [UIColor redColor];
    circleView.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
    return circleView;
}
79
benwad

Une version mise à jour pour iOS 8.0 utilisant Swift.

import Foundation
import MapKit

class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate{
    var locationManager: CLLocationManager = CLLocationManager()

    @IBOutlet var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // We use a predefined location
        var location = CLLocation(latitude: 46.7667 as CLLocationDegrees, longitude: 23.58 as CLLocationDegrees)

        addRadiusCircle(location)
    }

    func addRadiusCircle(location: CLLocation){
        self.mapView.delegate = self
        var circle = MKCircle(centerCoordinate: location.coordinate, radius: 10000 as CLLocationDistance)
        self.mapView.addOverlay(circle)
    }

    func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        if overlay is MKCircle {
            var circle = MKCircleRenderer(overlay: overlay)
            circle.strokeColor = UIColor.redColor()
            circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
            circle.lineWidth = 1
            return circle
        } else {
            return nil
        }
    }
}
46
vladCovaliov

Swift 3/Xcode 8 ici:

func addRadiusCircle(location: CLLocation){
    if let poll = self.selectedPoll {
        self.mapView.delegate = self
        let circle = MKCircle(center: location.coordinate, radius: 10)
        self.mapView.add(circle)
    }
}

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKCircle {
        let circle = MKCircleRenderer(overlay: overlay)
        circle.strokeColor = UIColor.red
        circle.fillColor = UIColor(red: 255, green: 0, blue: 0, alpha: 0.1)
        circle.lineWidth = 1
        return circle
    } else {
        return MKPolylineRenderer()
    }
}

Appelez ensuite comme ceci:

self.addRadiusCircle(location: CLLocation(latitude: YOUR_LAT_HERE, longitude: YOUR_LNG_HERE))
18
thexande

Essayez d'utiliser le code de exemple Apple Breadcrumb

3
Shmidt

Je n'ai pas compris la réponse de Benwad. Voici donc une réponse plus claire :

Il est assez facile d'ajouter un cercle. Conforme à MKMapViewDelegate

@interface MyViewController : UIViewController <MKMapViewDelegate>
@property (weak, nonatomic) IBOutlet MKMapView *mapView;
@end

Dans viewDidLoad, créez une annotation de cercle et ajoutez-la à la carte:

CLLocationCoordinate2D center = {39.0, -74.00};

// Add an overlay
MKCircle *circle = [MKCircle circleWithCenterCoordinate:center radius:150000];
[self.mapView addOverlay:circle];

Ensuite, implémentez mapView: viewForOverlay: pour renvoyer la vue.

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
    MKCircleView *circleView = [[MKCircleView alloc] initWithOverlay:overlay];
    [circleView setFillColor:[UIColor redColor]];
    [circleView setStrokeColor:[UIColor blackColor]];
    [circleView setAlpha:0.5f];
    return circleView;
}

Mais si vous souhaitez que le cercle soit toujours de la même taille, quel que soit le niveau de zoom, vous devrez faire quelque chose de différent. Comme vous le dites, dans regionDidChange: animated :, obtenez la latitudeDelta, puis créez un nouveau cercle (avec un rayon qui correspond à la largeur), supprimez l'ancien et ajoutez le nouveau.

Remarque de ma part: n'oubliez pas de connecter mapview à votre délégué de contrôleur de vue. Sinon, viewForOverlay ne sera pas appelé.

2
RealNmae
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay

il est obsolète depuis iOS 4.0

0
e a

Il est facile d'ajouter un cercle. Conforme à MKMapViewDelegate. suivez les étapes ci-dessous ,

Étape 1 :

 CLLocationCoordinate2D center= {self.locationManager.location.coordinate.latitude, self.locationManager.location.coordinate.longitude};
// Add an overlay
MKCircle *circle= [MKCircle circleWithCenterCoordinate:center radius: 20000];//your distance like 20000(like meters)
[myMapView addOverlay:circle];

Étape 2 :

 - (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
 {
    MKCircleView *C_View = [[MKCircleView alloc] initWithOverlay:overlay];
    [C_View setFillColor:[UIColor lightGrayColor]];
    [C_View setStrokeColor:[UIColor blackColor]];
    [C_View setAlpha:0.5f];

    return C_View;
 }
0
Kupendiran iOS