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.
.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;
.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:
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:
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
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:
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: