Recherche…


Ajouter MKMapView

Rapide

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

Il est recommandé de stocker mapView en tant que propriété du ViewController car vous souhaiterez peut-être y accéder dans des implémentations plus complexes.

Objectif c

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

Changer le type de carte

Il existe 5 types différents ( MKMapType ), MKMapView peut afficher.

iPhone OS 3

.la norme

Affiche un plan de ville indiquant la position de toutes les routes et certains noms de route.

Swift 2

mapView.mapType = .Standard

Swift 3

mapView.mapType = .standard

Objectif c

_mapView.mapType = MKMapTypeStandard;

Exemple MKMapType.standard

iPhone OS 3

.Satellite

Affiche des images satellites de la zone.

Swift 2

mapView.mapType = .Satellite

Swift 3

mapView.mapType = .satellite

Objectif c

_mapView.mapType = MKMapTypeSatellite;

Exemple MKMapType.satellite

iOS 9

.satelliteFlyover

Affiche une image satellite de la zone avec les données de survol disponibles.

Swift 2

mapView.mapType = .SatelliteFlyover

Swift 3

mapView.mapType = .satelliteFlyover

Objectif c

_mapView.mapType = MKMapTypeSatelliteFlyover;
iPhone OS 3

.hybride

Affiche une image satellite de la zone avec des informations sur les routes et les noms de routes superposées.

Swift 2

mapView.mapType = .Hybrid

Swift 3

mapView.mapType = .hybrid

Objectif c

_mapView.mapType = MKMapTypeHybrid;

MKMapType.hybrid exemple

iOS 9

.hybridFlyover

Affiche une image satellite hybride avec des données de survol disponibles.

Swift 2

mapView.mapType = .HybridFlyover

Swift 3

mapView.mapType = .hybridFlyover

Objectif c

_mapView.mapType = MKMapTypeHybridFlyover;

Définir le zoom / région pour la carte

Pour définir un certain niveau de zoom, disons que nous voulons agrandir l'emplacement de l'utilisateur avec l'emplacement de l'utilisateur en tant que centre et 2 km de zone en tant que rayon. Ensuite, nous utilisons le code suivant

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

Implémentation de la recherche locale à l'aide de MKLocalSearch

MKLocalSearch permet aux utilisateurs de rechercher un emplacement en utilisant des chaînes en langage naturel comme "gym". Une fois la recherche terminée, la classe renvoie une liste d'emplacements dans une région spécifiée correspondant à la chaîne de recherche.

Les résultats de la recherche sont sous la forme de MKMapItem dans l'objet MKLocalSearchResponse.

permet d'essayer par exemple

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 Tile-Overlay

Dans certains cas, vous ne souhaitez peut-être pas utiliser les cartes par défaut, indique Apple.

Vous pouvez ajouter une superposition à votre mapView qui contient des tuiles personnalisées, par exemple à partir d' OpenStreetMap .

Supposons que self.mapView est votre MKMapView que vous avez déjà ajouté à votre ViewController .

Au début, votre ViewController doit être conforme au protocole MKMapViewDelegate .

class MyViewController: UIViewController, MKMapViewDelegate

Ensuite, vous devez définir le ViewController tant que délégué de mapView

mapView.delegate = self

Ensuite, vous configurez la superposition pour la carte. Vous aurez besoin d'un modèle d'URL pour cela. L'URL devrait être similaire à ceci sur tous les serveurs de tuiles et même si vous stockeriez les données de carte hors ligne: 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

Après avoir configuré la superposition, vous devez l'ajouter à votre mapView .

mapView.add(overlay, level: .aboveLabels)

Pour utiliser des cartes personnalisées, il est recommandé d'utiliser .aboveLabels pour level . Sinon, les étiquettes par défaut seraient visibles sur votre carte personnalisée. Si vous voulez voir les étiquettes par défaut, vous pouvez choisir .aboveRoads ici.

Si vous exécutez votre projet maintenant, vous reconnaîtrez que votre carte affichera toujours la carte par défaut:

première exécution. carte toujours par défaut visible

C'est parce que nous n'avons pas encore dit à mapView comment rendre la superposition. C'est la raison pour laquelle vous avez dû définir le délégué auparavant. Maintenant, vous pouvez ajouter func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer à votre contrôleur de vue:

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

Cela retournera le bon MKOverlayRenderer à votre mapView . Si vous exécutez votre projet maintenant, vous devriez voir une carte comme celle-ci:

superposition de travail OSM

Si vous souhaitez afficher une autre carte, il vous suffit de modifier le modèle d'URL. Il y a une liste de serveurs de tuiles dans le wiki OSM.

Exemple d'utilisation de UserLocation et UserTracking

Cela montrera l'emplacement de l'utilisateur sur la carte

Objectif c

[self.map setShowsUserLocation:YES];

Rapide

self.map?.showsUserLocation = true

entrer la description de l'image ici

Cela va suivre l'emplacement de l'utilisateur sur la carte, en mettant à jour les régions en fonction

Objectif c

[self.map setUserTrackingMode:MKUserTrackingModeFollow];

Rapide

self.map?.userTrackingMode = .follow

Ajouter une annotation de point / pin sur la carte

Pour annoter un point d'intérêt sur la carte, nous utilisons l'annotation des broches. Maintenant, commencez par créer l'objet d'annotation en premier.

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

Maintenant, fournissez la coordonnée au pointAnnotation, comme

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

Maintenant, fournissez le titre et le sous-titre à l'annotation,

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

Maintenant, ajoutez cette annotation à la carte.

[self.mapView addAnnotation:pointAnnotation];

Yeaah .. Hourra .. vous avez fait le travail. Vous pouvez maintenant voir une annotation de point (broche de couleur rouge) à une coordonnée donnée.

Mais maintenant, que faire si vous voulez changer la couleur de la goupille (3 couleurs disponibles sont - Violet, rouge et vert). Suivez ensuite cette étape.

définir le délégué de mapview sur soi-même,

self.mapView.delegate = self;

Ajoutez l'implémentation de MKMapViewDelegate. Maintenant, ajoutez la méthode suivante,

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

Simuler un emplacement personnalisé

Étape 1: Dans Xcode: Fichier -> Nouveau -> Fichier -> Ressource -> Fichier GPX -> Suivant -> Donnez un nom au fichier GPX (c'est Taipei dans cet exemple) -> Créer

Étape 2: Modifier le fichier 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>

Étape 3: Lorsque le simulateur est en cours d'exécution:

entrer la description de l'image ici

Vous pouvez répéter ce processus pour créer plusieurs emplacements.

Faites défiler pour coordonner et zoomer

Lorsque vous affichez un emplacement pour vos utilisateurs, vous pouvez souhaiter que MKMapView affiche une coordonnée au niveau du zoom au lieu de définir une région à afficher. Cette fonctionnalité n'est pas implémentée par défaut. Vous devez donc étendre MKMapView avec une méthode qui effectue le calcul complexe d'un niveau de coordonnées et d'un niveau de zoom à une 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)
        }
    }
}

(La version originale de Swift 2 de Mylene Bayan est disponible sur GitHub )

Après avoir implémenté cette extension , vous pouvez définir la coordonnée centrale comme suit:

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

zoomLevel est une valeur Double , généralement comprise entre 0 et 21 (ce qui correspond à un niveau de zoom très élevé), mais des valeurs allant jusqu'à 28 sont autorisées.

Travailler avec l'annotation

Obtenir toutes les annotations

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

Obtenir une vue d'annotation

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"];
    }
}

Supprimer toutes les annotations

[mapView removeAnnotations:mapView.annotations]

Supprimer une seule annotation

//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];
    
}

Ajustez le rectangle visible de la carte pour afficher toutes les annotations

Rapide:

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

Objectif c:

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

Démo:

entrer la description de l'image ici



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow