web-dev-qa-db-fra.com

Définition du niveau de zoom pour un MKMapView

J'ai une carte qui montre correctement, la seule chose que je veux faire maintenant est de régler le niveau de zoom lors du chargement. Y a-t-il un moyen de faire cela?

Merci

100
jarryd

Je me suis trouvé une solution, qui est très simple et fait l'affaire. Utilisez MKCoordinateRegionMakeWithDistance afin de définir la distance en mètres verticalement et horizontalement pour obtenir le zoom souhaité. Et bien entendu, lorsque vous mettez à jour votre position, vous obtenez les bonnes coordonnées ou vous pouvez l'indiquer directement dans le CLLocationCoordinate2D au démarrage, si c'est ce que vous devez faire:

CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];          
[self.mapView setRegion:adjustedRegion animated:YES];
self.mapView.showsUserLocation = YES;

Rapide:

let location = ...
let region = MKCoordinateRegionMakeWithDistance(location.coordinate, CLLocationDistance(exactly: 5000)!, CLLocationDistance(exactly: 5000)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
177
Carnal

Sur la base du fait que les lignes de longitude sont espacées de manière égale en tout point de la carte, une implémentation très simple permet de définir les propriétés centerCoordinate et zoomLevel:

@interface MKMapView (ZoomLevel)

@property (assign, nonatomic) NSUInteger zoomLevel;

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                   animated:(BOOL)animated;

@end


@implementation MKMapView (ZoomLevel)

- (void)setZoomLevel:(NSUInteger)zoomLevel {
    [self setCenterCoordinate:self.centerCoordinate zoomLevel:zoomLevel animated:NO];
}

- (NSUInteger)zoomLevel {
    return log2(360 * ((self.frame.size.width/256) / self.region.span.longitudeDelta)) + 1;
}

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
zoomLevel:(NSUInteger)zoomLevel animated:(BOOL)animated {
    MKCoordinateSpan span = MKCoordinateSpanMake(0, 360/pow(2, zoomLevel)*self.frame.size.width/256);
    [self setRegion:MKCoordinateRegionMake(centerCoordinate, span) animated:animated];
}

@end
45
quentinadam

Ce n'est pas intégré, mais j'ai vu/utilisé this code. Cela vous permet d'utiliser ceci:

[mapView setCenterCoordinate:myCoord zoomLevel:13 animated:YES];

Note: Ce n'est pas mon code, je ne l'ai pas écrit, donc je ne peux pas en prendre le crédit

27
PostMan

Vous pouvez également zoomer en utilisant MKCoordinateRegion et en définissant son delta de latitude et de longitude. Vous trouverez ci-dessous une référence rapide et ici est la référence iOS. Cela ne fera rien d'extraordinaire mais devrait vous permettre de définir le zoom lorsqu'il dessine la carte.


MKCoordinateRegion region;
region.center.latitude = {desired lat};
region.center.longitude = {desired lng};
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
mapView.region = region;

Éditer 1:

MKCoordinateRegion region;
region.center.latitude = {desired lat};
region.center.longitude = {desired lng};
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
region = [mapView regionThatFits:region];
[mapView setRegion:region animated:TRUE];
16
DerekH

Une simple implémentation Swift, si vous utilisez des points de vente. 

@IBOutlet weak var mapView: MKMapView! {
    didSet {
        let noLocation = CLLocationCoordinate2D()
        let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500)
        self.mapView.setRegion(viewRegion, animated: false)
    }
}

Basé sur la réponse de @ Carnal. 

10
swennemen

Mise en œuvre rapide

import Foundation
import MapKit

class MapViewWithZoom: MKMapView {

    var zoomLevel: Int {
        get {
            return Int(log2(360 * (Double(self.frame.size.width/256) / self.region.span.longitudeDelta)) + 1);
        }

        set (newZoomLevel){
            setCenterCoordinate(coordinate:self.centerCoordinate, zoomLevel: newZoomLevel, animated: false)
        }
    }

    private func setCenterCoordinate(coordinate: CLLocationCoordinate2D, zoomLevel: Int, animated: Bool){
        let span = MKCoordinateSpanMake(0, 360 / pow(2, Double(zoomLevel)) * Double(self.frame.size.width) / 256)
        setRegion(MKCoordinateRegionMake(coordinate, span), animated: animated)
    }
}
9
Vlad Spreys

Pour Swift 3 c'est assez rapide:

private func setMapRegion(for location: CLLocationCoordinate2D, animated: Bool)
{
    let viewRegion = MKCoordinateRegionMakeWithDistance(location, <#T##latitudinalMeters: CLLocationDistance##CLLocationDistance#>, <#T##longitudinalMeters: CLLocationDistance##CLLocationDistance#>)
    MapView.setRegion(viewRegion, animated: animated)
}

Il suffit de définir le <CLLocationDistance> lat-, long-Metre __ et le mapView adaptera le niveau de zoom à vos valeurs.

7
zero3nna

Basé sur l'excellent answer de AdilSoomro. Je suis venu avec ceci:

@interface MKMapView (ZoomLevel)
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel
                   animated:(BOOL)animated;

-(double) getZoomLevel;
@end



@implementation MKMapView (ZoomLevel)

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                  zoomLevel:(NSUInteger)zoomLevel animated:(BOOL)animated {
    MKCoordinateSpan span = MKCoordinateSpanMake(0, 360/pow(2, zoomLevel)*self.frame.size.width/256);
    [self setRegion:MKCoordinateRegionMake(centerCoordinate, span) animated:animated];
}


-(double) getZoomLevel {
    return log2(360 * ((self.frame.size.width/256) / self.region.span.longitudeDelta));
}

@end
6
Nick

J'espère que la suite du fragment de code vous aidera.

- (void)handleZoomOutAction:(id)sender {
    MKCoordinateRegion newRegion=MKCoordinateRegionMake(mapView.region.center,MKCoordinateSpanMake(mapView.region.s       pan.latitudeDelta/0.5, mapView.region.span.longitudeDelta/0.5));
    [mapView setRegion:newRegion];
}


- (void)handleZoomInAction:(id)sender {
    MKCoordinateRegion newRegion=MKCoordinateRegionMake(mapView.region.center,MKCoordinateSpanMake(mapView.region.span.latitudeDelta*0.5, mapView.region.span.longitudeDelta*0.5));
    [mapView setRegion:newRegion];
}

Vous pouvez choisir n’importe quelle valeur au lieu de 0,5 pour réduire ou augmenter le niveau de zoom. J'ai utilisé ces méthodes en cliquant sur deux boutons. 

3
execv

Je sais que la réponse est tardive, mais je voulais simplement aborder moi-même la question du réglage du niveau de zoom. La réponse de goldmine est excellente, mais j'ai constaté que cela ne fonctionnait pas assez bien dans mon application.

À y regarder de plus près, Goldmine déclare que "les lignes de longitude sont espacées de manière égale en tout point de la carte". Ce n'est pas vrai, ce sont en fait des lignes de latitude espacées de manière égale de -90 (pôle sud) à +90 (pôle nord). Les lignes de longitude sont espacées au maximum à l'équateur et convergent vers un point situé aux pôles.

L’implémentation que j’ai adoptée consiste donc à utiliser le calcul de la latitude comme suit:

@implementation MKMapView (ZoomLevel)

- (void)setCenterCoordinate:(CLLocationCoordinate2D)coordinate
    zoomLevel:(NSUInteger)zoom animated:(BOOL)animated
{
    MKCoordinateSpan span = MKCoordinateSpanMake(180 / pow(2, zoom) * 
        self.frame.size.height / 256, 0);
    [self setRegion:MKCoordinateRegionMake(coordinate, span) animated:animated];
}

@end

J'espère que cela aide à ce stade avancé.

2
gektron

Une réponse Swift 2.0 utilisant NSUserDefaults pour enregistrer et restaurer le zoom et la position de la carte.

Fonction pour enregistrer la position de la carte et zoomer:

func saveMapRegion() {
    let mapRegion = [
        "latitude" : mapView.region.center.latitude,
        "longitude" : mapView.region.center.longitude,
        "latitudeDelta" : mapView.region.span.latitudeDelta,
        "longitudeDelta" : mapView.region.span.longitudeDelta
    ]
    NSUserDefaults.standardUserDefaults().setObject(mapRegion, forKey: "mapRegion")
}

Exécutez la fonction chaque fois que la carte est déplacée:

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) 
{
        saveMapRegion();
}

Fonction pour enregistrer le zoom et la position de la carte:

func restoreMapRegion() 
{
    if let mapRegion = NSUserDefaults.standardUserDefaults().objectForKey("mapRegion") 
    {

        let longitude = mapRegion["longitude"] as! CLLocationDegrees
        let latitude = mapRegion["latitude"] as! CLLocationDegrees
        let center = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)

        let longitudeDelta = mapRegion["latitudeDelta"] as! CLLocationDegrees
        let latitudeDelta = mapRegion["longitudeDelta"] as! CLLocationDegrees
        let span = MKCoordinateSpan(latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta)

        let savedRegion = MKCoordinateRegion(center: center, span: span)

        self.mapView.setRegion(savedRegion, animated: false)
    }
}

Ajoutez ceci à viewDidLoad:

restoreMapRegion()
2
David T

Ici, je mets ma réponse et son travail pour Swift 4.2 .

Réglage du niveau de zoom pour un MKMapView

0
Ashu

Basé sur le quentinadam réponse

Swift 5.1

// size refers to the width/height of your tile images, by default is 256.0
// Seems to get better results using round()
// frame.width is the width of the MKMapView

let zoom = round(log2(360 * Double(frame.width) / size / region.span.longitudeDelta))
0
vauxhall

Rapide:

Map.setRegion(MKCoordinateRegion(center: locValue, latitudinalMeters: 200, longitudinalMeters: 200), animated: true)

locValue est votre coordonnée.

0
time.