Réponses:
Je me suis trouvé une solution, qui est très simple et fait l'affaire. Utilisez MKCoordinateRegionMakeWithDistance
pour régler la distance en mètres verticalement et horizontalement pour obtenir le zoom souhaité. Et puis bien sûr, lorsque vous mettez à jour votre emplacement, vous obtiendrez les bonnes coordonnées, ou vous pouvez le spécifier directement 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 = MKCoordinateRegion( center: location.coordinate, latitudinalMeters: CLLocationDistance(exactly: 5000)!, longitudinalMeters: CLLocationDistance(exactly: 5000)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
MKCoordinateRegionMakeWithDistance
est toujours là à Swift. Cette solution fonctionne!
Sur la base du fait que les lignes de longitude sont espacées de manière égale en tout point de la carte, il existe une implémentation très simple pour définir le centerCoordinate et le 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
- (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 z = log2(360 * ((self.mapView.frame.size.width/256) / self.mapView.region.span.longitudeDelta));
Ce n'est pas intégré, mais j'ai vu / utilisé ce code. Cela vous permet d'utiliser ceci:
[mapView setCenterCoordinate:myCoord zoomLevel:13 animated:YES];
Remarque: ce n'est pas mon code, je ne l'ai pas écrit, donc je ne peux pas m'en attribuer le mérite
Vous pouvez également zoomer en utilisant MKCoordinateRegion et en définissant son delta de latitude et de longitude. Voici une référence rapide et voici la référence iOS. Il ne fera rien d'extraordinaire mais devrait vous permettre de régler 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;
Modifier 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];
Une implémentation simple de 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.
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 = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 360 / pow(2, Double(zoomLevel)) * Double(self.frame.size.width) / 256)
setRegion(MKCoordinateRegion(center: coordinate, span: span), animated: animated)
}
}
IBOutlet
à votre map
, vous le définissez comme un MapViewWithZoom
au lieu d'un simple MKMapView
. Ensuite, vous pouvez simplement régler le niveau de zoom avec map.zoomLevel = 1
oumap.zoomLevel = 0.5
mapView.zoomLevel -= 2
Pour Swift 3, c'est une avance 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)
}
Définissez simplement les lat-, long-Meters <CLLocationDistance>
et la mapView adaptera le niveau de zoom à vos valeurs.
Basé sur l'excellente réponse de @ AdilSoomro . J'ai trouvé 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
J'espère que le fragment de code suivant 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.
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()
Je sais que c'est une réponse tardive, mais je voulais juste aborder la question du réglage du niveau de zoom moi-même. La réponse de goldmine est excellente mais je trouve que cela ne fonctionne pas suffisamment bien dans mon application.
En y regardant 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 façon égale de -90 (pôle sud) à +90 (pôle nord). Les lignes de longitude sont espacées à leur plus large à l'équateur, convergeant vers un point aux pôles.
La mise en œuvre que j'ai adoptée consiste donc à utiliser le calcul de 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 tardif.
Ici, j'ai mis ma réponse et son fonctionnement pour swift 4.2 .
Basé sur la réponse de quentinadam
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))
MKMapView
extension basée sur cette réponse (+ précision du niveau de zoom en virgule flottante):
import Foundation
import MapKit
extension MKMapView {
var zoomLevel: Double {
get {
return 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: Double, animated: Bool) {
let span = MKCoordinateSpan(latitudeDelta: 0, longitudeDelta: 360 / pow(2, zoomLevel) * Double(self.frame.size.width) / 256)
setRegion(MKCoordinateRegion(center: coordinate, span: span), animated: animated)
}
}