2012-01-29 16 views
51

(utilizzando iOS 5 e Xcode 4.2)Disegnare un cerchio di raggio intorno 1000m posizione degli utenti in MKMapView

Ho un MKMapView e voglio disegnare un cerchio di raggio 1000m intorno alla posizione dell'utente.

In apparenza sembra che l'implementazione del metodo delegato della vista mappa mapView:viewForAnnotation: e l'aggiunta di un MKAnnotationView personalizzato per la posizione degli utenti, sarebbe una soluzione perfetta. Sarebbe simile a questa:

- (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; 
    } 
} 

Tuttavia annotazioni sulla mappa non scala quando si esegue lo zoom in e out della mappa.

Così ho provato ad aggiungere una sovrapposizione (perché le sovrapposizioni si ridimensionano con la mappa), usando la classe MKCircle e impostando le sue coordinate con le ultime coordinate dal mio delegato posizione/vista/mappa. Tuttavia, poiché lo coordinate property di MKCircle è in sola lettura, devo rimuovere l'overlay e aggiungerne uno nuovo ogni volta che l'utente si sposta. Causando uno sfarfallio evidente come succede.

Esiste un modo per rendere uniforme una scala di annotazione mentre la vista della mappa viene ridimensionata? O c'è un buon modo per fare in modo che una sovrapposizione si sposti perfettamente con le modifiche nella posizione degli utenti?

sarei molto grato per il vostro aiuto :)

+7

penso che un modulo elettronico personalizzato e vista sovrapposizione è quello che vi serve (che è ciò che @Flink sembra implicare). Tuttavia, un esempio di Apple più vicino alle tue esigenze è l'app LocationReminders del WWDC 2010. Se sei uno sviluppatore registrato, puoi trovarlo [qui] (http://connect.apple.com/cgi-bin/WebObjects/MemberSite .woa/wa/getSoftware? code = y & source = x & BundleID = 20645). Personalizza una sovrapposizione di cerchio la cui dimensione e posizione possono cambiare dinamicamente. – Anna

+0

Grazie per il link, suona esattamente come l'esempio di cui ho bisogno. Inoltre sono uno sviluppatore registrato, quindi è comodo :) –

+0

Il collegamento è interrotto, ma ho trovato questo su github: https://github.com/master-nevi/WWDC-2010/tree/master/LocationReminders – foson

risposta

3

tenta di utilizzare il codice Apple Breadcrumb example

+0

Non lo sono certo come l'esempio di Breadcrumb risolverà il problema del movimento MKCirecle. – user836026

+1

È possibile disegnare la propria cerchia – Shmidt

+0

Non sono sicuro di come farlo utilizzando crumbPath. – user836026

74

Prova un modulo elettronico personalizzato. Aggiungere questo viewDidLoad:

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

userLocation può essere ottenuto memorizzando il MKUserLocationAnnotation come una proprietà. Quindi, per disegnare effettivamente il cerchio, mettilo nel delegato della vista mappa:

- (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; 
} 
+0

sposta il cerchio ogni volta che la localizzazione dell'utente cambia –

+0

come spostiamo il cerchio? avremmo bisogno di creare un nuovo MKCircle ogni volta che si muove? – yuf

+0

Richiede l'aggiornamento per iOS 7! – Hyperbole

39

Una versione aggiornata per iOS 8.0 che utilizza 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 
     } 
    } 
} 
+2

Impossibile restituire 'nil' in' mapView: rendererfForOverlay' vedere per correzione: http://stackoverflow.com/a/32452494/723980 –

+0

rendererForOverlay è sostituito con rendererFor – Guy

2

Non ho capito risposta benwad. So here is clearer answer:

È abbastanza facile aggiungere un cerchio. Conforme alla MKMapViewDelegate

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

In viewDidLoad, Creare un cerchio di annotazione e aggiungerlo alla mappa:

CLLocationCoordinate2D center = {39.0, -74.00}; 

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

quindi implementare MapView: viewForOverlay: per restituire la vista.

- (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; 
} 

Ma se si desidera che il cerchio sia sempre la stessa dimensione, non importa il livello di zoom, dovrete fare qualcosa di diverso. Come dici tu, in regionDidChange: animated :, prendi latitudeDelta, quindi crea un nuovo cerchio (con un raggio che si adatta alla larghezza), rimuovi quello vecchio e aggiungi quello nuovo.

Nota da parte mia: non dimenticare di connettere mapview con il delegato del controller di visualizzazione. Altrimenti viewForOverlay non verrà chiamato.

0

È facile aggiungere un cerchio.Conforme a MKMapViewDelegate. seguite le fasi sotto ,,,

Fase 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]; 

Fase 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
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay 

è deprecato in quanto iOS 4.0

0

Utilizzando MKCircleRenderer, si potrebbe in grado di aggiungerlo come segue.

variabili

Declare a livello di classe per la sovrapposizione e il suo renderer:

MKCircle circleOverlay; 
MKCircleRenderer circleRenderer; 

Implementare MKMapView.OverlayRenderer per fornire un renderer per la sovrapposizione:

mapView.OverlayRenderer = (m, o) => { 
    if(circleRenderer == null) { 
     circleRenderer = new MKCircleRenderer(o as MKCircle); 
     circleRenderer.FillColor = UIColor.Green; 
     circleRenderer.Alpha = 0.5f; 
    } 
    return circleRenderer; 
}; 

Creare una sovrapposizione, in questo caso un cerchio posizionato vicino alla posizione dell'utente (latitudine, longitudine) e aggiungerlo alla mappa:

var coords = new CLLocationCoordinate2D(39.11, 30.13); //user location 
circleOverlay = MKCircle.Circle (coords, 1000); 
mapView.AddOverlay (circleOverlay); 
11

Swift 3/Xcode 8 qui:

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() 
    } 
} 

quindi chiamare in questo modo:

self.addRadiusCircle(location: CLLocation(latitude: YOUR_LAT_HERE, longitude: YOUR_LNG_HERE)) 
+0

Che cos'è 'self.selectedPoll"? da – BlueBoy

+0

@thexande radius: 10, qui 10 contiene quale valore? Voglio dire in miglia o metri o kilometro. –

Problemi correlati