Szukaj…


Dodaj MKMapView

Szybki

let mapView = MKMapView(frame: CGRect(x: 0, y: 0, width: 320, height: 500))

Zaleca się przechowywać mapView jako właściwość zawierającego ViewController ponieważ możesz chcieć uzyskać do niego dostęp w bardziej złożonych implementacjach.

Cel C

self.map = [[MKMapView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.map];

Zmień typ mapy

Istnieje 5 różnych typów ( MKMapType ), MKMapView może wyświetlać MKMapView .

iPhone OS 3

.standard

Wyświetla mapę ulic, która pokazuje pozycję wszystkich dróg i niektóre nazwy dróg.

Swift 2

mapView.mapType = .Standard

Szybki 3

mapView.mapType = .standard

Cel C

_mapView.mapType = MKMapTypeStandard;

Przykład MKMapType.standard

iPhone OS 3

.satelita

Wyświetla zdjęcia satelitarne obszaru.

Swift 2

mapView.mapType = .Satellite

Szybki 3

mapView.mapType = .satellite

Cel C

_mapView.mapType = MKMapTypeSatellite;

Przykład MKMapType.satellite

iOS 9

.satelliteFlyover

Wyświetla zdjęcie satelitarne obszaru z danymi estakady, jeśli są dostępne.

Swift 2

mapView.mapType = .SatelliteFlyover

Szybki 3

mapView.mapType = .satelliteFlyover

Cel C

_mapView.mapType = MKMapTypeSatelliteFlyover;
iPhone OS 3

.hybrydowy

Wyświetla zdjęcie satelitarne obszaru z warstwami informacji o nazwie drogi i nazwy drogi.

Swift 2

mapView.mapType = .Hybrid

Szybki 3

mapView.mapType = .hybrid

Cel C

_mapView.mapType = MKMapTypeHybrid;

Przykład MKMapType.hybrid

iOS 9

.hybridFlyover

Wyświetla hybrydowy obraz satelitarny z danymi estakady, jeśli są dostępne.

Swift 2

mapView.mapType = .HybridFlyover

Szybki 3

mapView.mapType = .hybridFlyover

Cel C

_mapView.mapType = MKMapTypeHybridFlyover;

Ustaw Zoom / Region dla mapy

Aby ustawić poziom powiększenia, powiedzmy, że chcemy powiększyć lokalizację użytkownika z lokalizacją użytkownika jako centrum i 2 km obszaru jako promieniem. Następnie używamy następującego kodu

MKUserLocation *userLocation = _mapView.userLocation;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance (userLocation.location.coordinate, 2000, 2000);
[_mapView setRegion:region animated:NO];

Lokalna implementacja wyszukiwania przy użyciu MKLocalSearch

MKLocalSearch umożliwia użytkownikom wyszukiwanie lokalizacji przy użyciu ciągów języka naturalnego, takich jak „siłownia”. Po zakończeniu wyszukiwania klasa zwraca listę lokalizacji w określonym regionie pasujących do wyszukiwanego ciągu.

Wyniki wyszukiwania mają postać MKMapItem w obiekcie MKLocalSearchResponse.

spróbujmy przez przykład

MKLocalSearchRequest *request = 
    [[MKLocalSearchRequest alloc] init];//initialising search request
request.naturalLanguageQuery = @”Gym”; // adding query
request.region = _mapView.region; //setting region
MKLocalSearch *search = 
     [[MKLocalSearch alloc]initWithRequest:request];//initiate search

[search startWithCompletionHandler:^(MKLocalSearchResponse 
     *response, NSError *error) 
{
   if (response.mapItems.count == 0)
       NSLog(@"No Matches");
   else
       for (MKMapItem *item in response.mapItems)
       {
           NSLog(@"name = %@", item.name);
           NSLog(@"Phone = %@", item.phoneNumber);
        }
}];

OpenStreetMap nakładka kafelkowa

W niektórych przypadkach możesz nie chcieć używać domyślnych map, zapewnia Apple.

Możesz dodać do mapView która zawiera niestandardowe kafelki, na przykład z OpenStreetMap .

Załóżmy, że self.mapView to twój MKMapView , który już dodałeś do swojego ViewController .

Najpierw ViewController musi być zgodny z protokołem MKMapViewDelegate .

class MyViewController: UIViewController, MKMapViewDelegate

Następnie musisz ustawić ViewController jako delegata mapView

mapView.delegate = self

Następnie skonfigurujesz nakładkę dla mapy. W tym celu potrzebujesz szablonu adresu URL. Adres URL powinien być podobny do tego na wszystkich serwerach kafelków, a nawet gdyby dane map były przechowywane offline: http://tile.openstreetmap.org/{z}/{x}/{y}.png

let urlTeplate = "http://tile.openstreetmap.org/{z}/{x}/{y}.png"
let overlay = MKTileOverlay(urlTemplate: urlTeplate)
overlay.canReplaceMapContent = true

Po skonfigurowaniu nakładki musisz dodać ją do mapView .

mapView.add(overlay, level: .aboveLabels)

Aby użyć niestandardowych map, zaleca się użycie .aboveLabels dla level . W przeciwnym razie domyślne etykiety byłyby widoczne na Twojej mapie niestandardowej. Jeśli chcesz zobaczyć domyślne etykiety, możesz wybrać .aboveRoads tutaj.

Gdybyś teraz uruchomił swój projekt, rozpoznałbyś, że twoja mapa nadal pokazuje domyślną mapę:

pierwszy bieg. wciąż widoczna domyślna mapa

To dlatego, że nie powiedzieliśmy jeszcze mapView , jak renderować nakładkę. To jest powód, dla którego musiałeś wcześniej ustawić delegata. Teraz możesz dodać func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer do kontrolera widoku:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    if overlay is MKTileOverlay {
        let renderer = MKTileOverlayRenderer(overlay: overlay)
        return renderer
    } else {
        return MKTileOverlayRenderer()
    }
}

Spowoduje to zwrócenie prawidłowego MKOverlayRenderer do mapView . Jeśli teraz uruchomisz projekt, powinieneś zobaczyć mapę taką jak ta:

działająca nakładka OSM

Jeśli chcesz wyświetlić inną mapę, wystarczy zmienić szablon adresu URL. Na Wiki OSM znajduje się lista serwerów kafelków .

Pokaż przykład UserLocation i UserTracking

Spowoduje to wyświetlenie lokalizacji użytkownika na mapie

Cel C

[self.map setShowsUserLocation:YES];

Szybki

self.map?.showsUserLocation = true

wprowadź opis zdjęcia tutaj

Będzie to śledzić lokalizację użytkownika na mapie, aktualizując regiony zgodnie

Cel C

[self.map setUserTrackingMode:MKUserTrackingModeFollow];

Szybki

self.map?.userTrackingMode = .follow

Dodawanie opisu pin / point na mapie

Aby dodać adnotację do jakiegoś interesującego miejsca na mapie, używamy adnotacji pinezką. Teraz zacznij od utworzenia obiektu adnotacji w pierwszej kolejności.

MKPointAnnotation *pointAnnotation = [[MKPointAnnotation alloc] init];

Teraz podaj współrzędną do pointAnnotation, as

CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(23.054625,72.534562);
pointAnnotation.coordinate = coordinate;

Teraz podaj tytuł i podtytuły adnotacji,

pointAnnotation.title = @"XYZ Point";
pointAnnotation.subtitle = @"Ahmedabad Area";

Dodaj tę adnotację do mapy.

[self.mapView addAnnotation:pointAnnotation];

Tak .. Hurra ... wykonałeś robotę. Teraz możesz zobaczyć adnotację punktową (czerwona szpilka) na danej współrzędnej.

Ale teraz, co jeśli chcesz zmienić kolor pinezki (3 dostępne kolory to - Fioletowy, czerwony i zielony). Następnie wykonaj ten krok.

ustaw delegata mapview na siebie,

self.mapView.delegate = self;

Dodaj implementację MKMapViewDelegate. Teraz dodaj następującą metodę,

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    // If it's the user location, just return nil, because it have user location's own annotation, if you want to change that, then use this object;
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        //Use dequed pin if available
        MKAnnotationView *pinView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"PinAnnotationView"];
    
        if (!pinView)
        {
            // If not dequed, then create new.
            pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"PinAnnotationView"];
            pinView.canShowCallout = YES;
            pinView.image = [UIImage imageNamed:@"abc.png"];
            pinView.calloutOffset = CGPointMake(0, 32);
        } else {
            pinView.annotation = annotation;
        }
        return pinView;
    }
    return nil;
}

Symuluj niestandardową lokalizację

Krok 1: W Xcode: Plik -> Nowy -> Plik -> Zasób -> Plik GPX -> Dalej -> Nadaj nazwę plikowi GPX (w tym przykładzie jest to Taipei ) -> Utwórz

Krok 2: Edytuj plik GPX

<?xml version="1.0"?>
<gpx version="1.1" creator="Xcode">
    <wpt lat="25.041865" lon="121.551361"> // Edit the latitude and longitude 
        <name>Taipei</name> // Edit the name of the location
        <time>2014-09-24T14:55:37Z</time>
    </wpt>
</gpx>

Krok 3: Gdy symulator jest uruchomiony:

wprowadź opis zdjęcia tutaj

Możesz powtórzyć ten proces, aby utworzyć wiele lokalizacji.

Przewiń do współrzędnych i poziomu powiększenia

Kiedy wyświetlasz lokalizację użytkownikom, możesz chcieć, aby MKMapView wyświetlał współrzędną na poziomie powiększenia zamiast ustawiać region do pokazywania. Ta funkcja nie jest domyślnie implementowana, dlatego należy rozszerzyć MKMapView o metody, które wykonują złożone obliczenia od współrzędnej i poziomu powiększenia do MKCoordinateRegion .

let MERCATOR_OFFSET = 268435456.0
let MERCATOR_RADIUS = 85445659.44705395
let DEGREES = 180.0

public extension MKMapView {
    
    //MARK: Map Conversion Methods
    
    private func longitudeToPixelSpaceX(longitude:Double)->Double{
        return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / DEGREES)
    }
    
    private func latitudeToPixelSpaceY(latitude:Double)->Double{
        return round(MERCATOR_OFFSET - MERCATOR_RADIUS * log((1 + sin(latitude * M_PI / DEGREES)) / (1 - sin(latitude * M_PI / DEGREES))) / 2.0)
    }
    
    private func pixelSpaceXToLongitude(pixelX:Double)->Double{
        return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * DEGREES / M_PI
    }
    
    private func pixelSpaceYToLatitude(pixelY:Double)->Double{
        return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * DEGREES / M_PI
    }
    
    private func coordinateSpanWithCenterCoordinate(centerCoordinate:CLLocationCoordinate2D, zoomLevel:Double)->MKCoordinateSpan{
        // convert center coordiate to pixel space
        let centerPixelX = longitudeToPixelSpaceX(longitude: centerCoordinate.longitude)
        let centerPixelY = latitudeToPixelSpaceY(latitude: centerCoordinate.latitude)
        print(centerCoordinate)
        // determine the scale value from the zoom level
        let zoomExponent:Double = 20.0 - zoomLevel
        let zoomScale:Double = pow(2.0, zoomExponent)
        // scale the map’s size in pixel space
        let mapSizeInPixels = self.bounds.size
        let scaledMapWidth = Double(mapSizeInPixels.width) * zoomScale
        let scaledMapHeight = Double(mapSizeInPixels.height) * zoomScale
        // figure out the position of the top-left pixel
        let topLeftPixelX = centerPixelX - (scaledMapWidth / 2.0)
        let topLeftPixelY = centerPixelY - (scaledMapHeight / 2.0)
        // find delta between left and right longitudes
        let minLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX)
        let maxLng = pixelSpaceXToLongitude(pixelX: topLeftPixelX + scaledMapWidth)
        let longitudeDelta = maxLng - minLng
        let minLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY)
        let maxLat = pixelSpaceYToLatitude(pixelY: topLeftPixelY + scaledMapHeight)
        let latitudeDelta = -1.0 * (maxLat - minLat)
        return MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)
    }
    
    /**
     Sets the center of the `MKMapView` to a `CLLocationCoordinate2D` with a custom zoom-level. There is no nee to set a region manually. :-)
     
     - author: Mylene Bayan (on GitHub)
     */
    public func setCenter(_ coordinate:CLLocationCoordinate2D, zoomLevel:Double, animated:Bool){
        // clamp large numbers to 28
        var zoomLevel = zoomLevel
        zoomLevel = min(zoomLevel, 28)
        // use the zoom level to compute the region
        print(coordinate)
        let span = self.coordinateSpanWithCenterCoordinate(centerCoordinate: coordinate, zoomLevel: zoomLevel)
        let region = MKCoordinateRegionMake(coordinate, span)
        if region.center.longitude == -180.00000000{
            print("Invalid Region")
        }
        else{
            self.setRegion(region, animated: animated)
        }
    }
}

(Oryginalną wersję Swift 2 autorstwa Mylene Bayan można znaleźć na GitHub )

Po zaimplementowaniu tego extension możesz ustawić współrzędną środkową w następujący sposób:

let centerCoordinate = CLLocationCoordinate2DMake(48.136315, 11.5752901) //latitude, longitude
mapView?.setCenter(centerCoordinate, zoomLevel: 15, animated: true)

zoomLevel jest wartością Double , zwykle pomiędzy 0 a 21 (co jest bardzo wysokim poziomem powiększenia), ale dopuszczalne są wartości do 28 .

Praca z adnotacjami

Uzyskaj wszystkie adnotacje

//following method returns all annotations object added on map
NSArray *allAnnotations = mapView.annotations;

Uzyskaj widok adnotacji

for (id<MKAnnotation> annotation in mapView.annotations)
{
    MKAnnotationView* annotationView = [mapView viewForAnnotation:annotation];
    if (annotationView)
    {
       // Do something with annotation view 
       // for e.g change image of annotation view
       annotationView.image = [UIImage imageNamed:@"SelectedPin.png"];
    }
}

Usuń wszystkie adnotacje

[mapView removeAnnotations:mapView.annotations]

Usuń pojedynczą adnotację

//getting all Annotation
NSArray *allAnnotations = self.myMapView.annotations;

if (allAnnotations.count > 0)
{
    //getting first annoation
    id <MKAnnotation> annotation=[allAnnotations firstObject];
    
    //removing annotation
    [mapView removeAnnotation:annotation];
    
}

Dostosuj widoczny prostokąt widoku mapy, aby wyświetlić wszystkie adnotacje

Szybki:

mapView.showAnnotations(mapView.annotations, animated: true)

Cel C:

[mapView showAnnotations:mapView.annotations animated:YES];

Próbny:

wprowadź opis zdjęcia tutaj



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow