2012-01-29 18 views
51

(Korzystanie z iOS 5 i Xcode 4.2)narysować okrąg o promieniu 1000m wokół lokalizacji użytkowników w MKMapView

Mam MKMapView i chcesz narysować okrąg o promieniu 1000m wokół lokalizacji użytkownika.

Na pozór wydaje się, że wdrożenie metody delegowania widoku mapy w widoku mapView:viewForAnnotation: i dodanie niestandardowego widoku MKAnnotationView dla lokalizacji użytkowników byłoby idealnym rozwiązaniem. Wyglądałoby to mniej więcej tak:

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

Adnotacje na mapie nie są jednak skalowane podczas powiększania i pomniejszania mapy.

Tak więc próbowałem dodać nakładkę (ponieważ nakładki skalują się z mapą), używając klasy MKCircle i ustawiając współrzędne dla najnowszych współrzędnych z mojego delegata lokalizacji Manger/map. Jednakże, ponieważ coordinate property z MKCircle jest tylko do odczytu, muszę usunąć nakładkę, a następnie dodać nową za każdym razem, gdy użytkownik się porusza. Powoduje zauważalne migotanie, jak to się dzieje.

Czy istnieje sposób na płynne wprowadzanie skali adnotacji, ponieważ widok mapy jest skalowany i wyrzucany? Czy istnieje dobry sposób na płynne przeniesienie nakładki ze zmianami w lokalizacji użytkowników?

Byłbym bardzo wdzięczny za pomoc :)

+7

myślę zwyczaj nakładki i nakładki widok jest co trzeba (czyli to, co wydaje się być @Flink sugerując). Jednak przykład Apple bliżej Twoich wymagań to aplikacja LocationReminders z WWDC 2010. Jeśli jesteś zarejestrowanym programistą, możesz go znaleźć [tutaj] (http://connect.apple.com/cgi-bin/WebObjects/MemberSite .woa/wa/getSoftware? code = y & source = x & bundleID = 20645). Niestandardowy rysuje nakładkę okrągłą, której rozmiar i położenie mogą zmieniać się dynamicznie. – Anna

+0

Dzięki za link, brzmi dokładnie tak, jakbym potrzebował tego przykładu. Dodatkowo jestem zarejestrowanym programistą, więc to jest przydatne :) –

+0

Link jest uszkodzony, ale znalazłem to na github: https://github.com/master-nevi/WWDC-2010/tree/master/LocationReminders – foson

Odpowiedz

3

spróbuj użyć kodu z Apple Breadcrumb example

+0

Nie jestem pewnie, jak przykład Breadcrumb rozwiąże problem z poruszaniem się MKCirecle. – user836026

+1

Możesz narysować własny okrąg – Shmidt

+0

Nie jestem pewien, jak to zrobić, używając metody crumbPath. – user836026

74

Spróbuj niestandardowej nakładki. Dodaj ten w viewDidLoad:

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

userLocation można uzyskać przez przechowywanie MKUserLocationAnnotation jako własność. Następnie, aby narysować okrąg, umieść go w delegacie widoku mapy:

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

przesuń kółko, gdy zmienia się lokalizacja użytkownika –

+0

w jaki sposób przesuniemy kółko? musielibyśmy stworzyć nowe MKCircle za każdym razem, kiedy się porusza? – yuf

+0

Wymaga aktualizacji na iOS 7! – Hyperbole

39

Zaktualizowana wersja systemu iOS 8.0 za pomocą 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

Nie można zwrócić 'nil' w' mapView: rendererfForOverlay' patrz poprawka: http://stackoverflow.com/a/32452494/723980 –

+0

rendererForOverlay jest zamieniany na rendererFor – Guy

2

Nie rozumiałam odpowiedzi na pytanie o benwad. So here is clearer answer:

Dodanie koła jest całkiem proste. Zgodne MKMapViewDelegate

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

W viewDidLoad, tworzą krąg adnotacji i dodać go do mapy:

CLLocationCoordinate2D center = {39.0, -74.00}; 

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

Następnie wdrożyć MapView: viewForOverlay: powrót widok.

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

Ale jeśli chcesz krąg, aby zawsze być tej samej wielkości, bez względu na poziom zoomu, musisz zrobić coś innego. Tak jak mówisz, w regionDidChange: animated :, pobierz latitudeDelta, a następnie utwórz nowy okrąg (z promieniem pasującym do szerokości), usuń stary i dodaj nowy.

Uwaga dla mnie: nie zapomnij połączyć widoku mapy z delegatem kontrolera widoku. W przeciwnym razie viewForOverlay nie zostanie wywołany.

0

Łatwo dodać krąg.Zgodny z MKMapViewDelegate. śledzić mieszek kroki ,,,

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

Krok 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 

jest przestarzała od iOS 4.0

0

Korzystanie MKCircleRenderer, można w stanie dodać go w następujący sposób.

zmienne

Declare klasy podstawowej dla nakładki i jego renderujący:

MKCircle circleOverlay; 
MKCircleRenderer circleRenderer; 

Wdrożenie MKMapView.OverlayRenderer dostarczenie renderujący nakładki:

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

utworzyć nakładkę, w tym przypadku okręgu ustawioną w pobliżu lokalizacji użytkownika (szerokość i długość geograficzna) i dodaj ją do mapy:

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

Swift 3/Xcode 8 tutaj:

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

Następnie nazwać tak:

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

Co to jest 'self.selectedPoll"? Gdzie to jest od – BlueBoy

+0

@ promień zaokrąglenia: 10, tutaj 10 zawiera jaką wartość? Mam na myśli w metrach lub metrach lub kilogramach. –

Powiązane problemy