Antworten:
Ich habe eine Lösung gefunden, die sehr einfach ist und den Trick macht. Verwenden Sie diese MKCoordinateRegionMakeWithDistance
Option, um den Abstand in Metern vertikal und horizontal einzustellen und den gewünschten Zoom zu erzielen. Und wenn Sie dann Ihren Standort aktualisieren, erhalten Sie natürlich die richtigen Koordinaten, oder Sie können sie direkt CLLocationCoordinate2D
beim Start angeben , wenn Sie dies tun müssen:
CLLocationCoordinate2D noLocation;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
self.mapView.showsUserLocation = YES;
Schnell:
let location = ...
let region = MKCoordinateRegion( center: location.coordinate, latitudinalMeters: CLLocationDistance(exactly: 5000)!, longitudinalMeters: CLLocationDistance(exactly: 5000)!)
mapView.setRegion(mapView.regionThatFits(region), animated: true)
MKCoordinateRegionMakeWithDistance
es noch in Swift. Diese Lösung funktioniert!
Basierend auf der Tatsache, dass Längengradlinien an jedem Punkt der Karte gleichmäßig voneinander beabstandet sind, gibt es eine sehr einfache Implementierung, um centerCoordinate und zoomLevel festzulegen:
@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));
Es ist nicht eingebaut, aber ich habe diesen Code gesehen / verwendet . Dies ermöglicht Ihnen Folgendes:
[mapView setCenterCoordinate:myCoord zoomLevel:13 animated:YES];
Hinweis: Dies ist nicht mein Code, ich habe ihn nicht geschrieben und kann ihn daher nicht gutschreiben
Sie können auch zoomen, indem Sie MKCoordinateRegion verwenden und das Delta für Breite, Breite und Länge einstellen. Unten finden Sie eine Kurzreferenz und hier die iOS-Referenz. Es macht nichts Besonderes, sollte es Ihnen aber ermöglichen, den Zoom beim Zeichnen der Karte einzustellen.
MKCoordinateRegion region;
region.center.latitude = {desired lat};
region.center.longitude = {desired lng};
region.span.latitudeDelta = 1;
region.span.longitudeDelta = 1;
mapView.region = region;
Bearbeiten 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];
Eine einfache Swift-Implementierung, wenn Sie Steckdosen verwenden.
@IBOutlet weak var mapView: MKMapView! {
didSet {
let noLocation = CLLocationCoordinate2D()
let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 500, 500)
self.mapView.setRegion(viewRegion, animated: false)
}
}
Basierend auf der Antwort von @ Carnal.
Schnelle Implementierung
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
zu Ihrer erstellen map
, definieren Sie es als eine MapViewWithZoom
anstelle einer einfachen MKMapView
. Dann können Sie einfach die map.zoomLevel = 1
map.zoomLevel = 0.5
mapView.zoomLevel -= 2
Für Swift 3 ist es ziemlich schnell vorwärts:
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)
}
Definieren Sie einfach die Lat-, Long-Meter <CLLocationDistance>
und die mapView passt die Zoomstufe an Ihre Werte an.
Basierend auf der großartigen Antwort von @ AdilSoomro . Ich habe mir Folgendes ausgedacht:
@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
Ich hoffe, das folgende Codefragment würde Ihnen helfen.
- (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];
}
Sie können einen beliebigen Wert anstelle von 0,5 wählen, um die Zoomstufe zu verringern oder zu erhöhen. Ich habe diese Methoden beim Klicken auf zwei Schaltflächen verwendet.
Eine Swift 2.0-Antwort mit NSUserDefaults zum Speichern und Wiederherstellen des Zooms und der Position der Karte.
Funktion zum Speichern der Kartenposition und zum Zoomen:
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")
}
Führen Sie die Funktion jedes Mal aus, wenn die Karte verschoben wird:
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool)
{
saveMapRegion();
}
Funktion zum Speichern des Kartenzooms und der Position:
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)
}
}
Fügen Sie dies zu viewDidLoad hinzu:
restoreMapRegion()
Ich weiß, dass dies eine späte Antwort ist, aber ich wollte nur das Problem der Einstellung der Zoomstufe selbst ansprechen. Die Antwort von Goldmine ist großartig, aber ich fand, dass sie in meiner Bewerbung nicht gut genug funktioniert.
Bei näherer Betrachtung stellt Goldmine fest, dass "Längengrade an jedem Punkt der Karte gleich weit voneinander entfernt sind". Dies ist nicht wahr, es sind tatsächlich Breitengradlinien, die gleichmäßig von -90 (Südpol) bis +90 (Nordpol) beabstandet sind. Längengradlinien sind am Äquator am breitesten beabstandet und konvergieren zu einem Punkt an den Polen.
Die Implementierung, die ich übernommen habe, besteht daher darin, die Breitengradberechnung wie folgt zu verwenden:
@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
Hoffe, es hilft in diesem späten Stadium.
Hier stelle ich meine Antwort und ihre Arbeit für schnelle 4.2 .
Basierend auf der Antwort von 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
Erweiterung basierend auf dieser Antwort (+ Genauigkeit der Gleitkommazoomstufe):
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)
}
}