Sprawdź, czy zmienił się poziom powiększenia


Używam MapKit na iPhonie.
Skąd mogę wiedzieć, że użytkownik zmieni poziom powiększenia (powiększ/pomniejsz mapę)?
Próbowałem użyć

mapView: (MKMapView *) mapView regionDidChangeAnimated: (BOOL) animated;

ale jest to wywoływane nawet wtedy, gdy karta jest tylko przeciągnięta.
Niestety podczas przeciągania mapy mapView.region.span również się zmienia ...
Wsparcie?
10x.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Obliczanie poziomu powiększenia jest dość proste. Zobacz fragment poniżej. Możesz pobrać parametr mRect z właściwości
visibleMapRect
w Twojej instancji
MKMapView
.
+ (NSUInteger)zoomLevelForMapRect:(MKMapRect)mRect withMapViewSizeInPixels:(CGSize)viewSizeInPixels
{
NSUInteger zoomLevel = MAXIMUM_ZOOM;// MAXIMUM_ZOOM is 20 with MapKit
MKZoomScale zoomScale = mRect.size.width/viewSizeInPixels.width;//MKZoomScale is just a CGFloat typedef
double zoomExponent = log2(zoomScale);
zoomLevel = (NSUInteger)(MAXIMUM_ZOOM - ceil(zoomExponent));
return zoomLevel;
}

Prawdopodobnie możesz po prostu zatrzymać się na kroku
zoomScale
, ponieważ to powie Ci, czy skala w ogóle się zmieniła.
Zrozumiałem to po przeczytaniu kilku doskonałych postów na blogu Troya Branta na ten temat:
http://troybrant.net/blog/2010 ... guide
http://troybrant.net/blog/2010 ... uide/
/

Swift 3

extension MKMapView { var zoomLevel: Int {
let maxZoom: Double = 20
let zoomScale = self.visibleMapRect.size.width/Double(self.frame.size.width)
let zoomExponent = log2(zoomScale)
return Int(maxZoom - ceil(zoomExponent))
}}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Uznałem to za bardzo przydatne i na podstawie tych odpowiedzi opracowałem następujący kod.
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated 
{
mapRegion = self.mapView.region;
}
-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated{MKCoordinateRegion newRegion = self.mapView.region;NSInteger zFactor;
if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) > 1.5){
NSLog(@"Zoom in changed");
zFactor = 20;
CustomPlacemark *aO;
MKAnnotationView *aV;
for (aO in self.mapView.annotations) {
aV = [[self mapView] viewForAnnotation:aO];
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);
[[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];
}
}
if ((mapRegion.span.latitudeDelta/newRegion.span.latitudeDelta) < 0.75){
NSLog(@"Zoom out");
zFactor = -20;
CustomPlacemark *aO;
MKAnnotationView *aV;
for (aO in self.mapView.annotations) {
aV = [[self mapView] viewForAnnotation:aO];
aV.frame = CGRectMake(aV.frame.origin.x, aV.frame.origin.y, aV.frame.size.width+zFactor, aV.frame.size.height+zFactor);
[[[self mapView] viewForAnnotation:aO] setFrame:aV.frame];
}
}
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mam następującą kategorię MKMapView, w której dołączam metodę szybkiego uzyskania aktualnego poziomu powiększenia mapy:
@implementation MKMapView (ZoomLevel)- (NSUInteger) zoomLevel {
MKCoordinateRegion region = self.region; double centerPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude];
double topLeftPixelX = [MKMapView longitudeToPixelSpaceX: region.center.longitude - region.span.longitudeDelta/2]; double scaledMapWidth = (centerPixelX - topLeftPixelX) * 2;
CGSize mapSizeInPixels = self.bounds.size;
double zoomScale = scaledMapWidth/mapSizeInPixels.width;
double zoomExponent = log(zoomScale)/log(2);
double zoomLevel = 21 - zoomExponent; return zoomLevel;
}@end

Aby uzyskać poziom powiększenia, możesz wywołać następujące polecenia w delegatach i określić, czy poziom powiększenia uległ zmianie:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
NSUInteger zoomLevel = [mapView zoomLevel];
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

możesz posłuchać metody
mapView: regionDidChangeAnimated:
. Jednak to nie mówi ci, czy zmienił się poziom powiększenia, tylko jeśli mapa była animowana.
Będziesz także musiał posłuchać właściwości
region
widoku mapy. Zawiera wartości latitudeDelta i longitudeDelta, których można użyć do obliczenia zmiany poziomu powiększenia.
to znaczy w pliku .h
@class MyMapViewController {
...
MKCoordinateRegion mapRegion;
}
@end

i w swoim pliku .m
- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated {
mapRegion = mapView.region;
}- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
newRegion = mapView.region; if (mapRegion.span.latitudeDelta != newRegion.span.latitudeDelta ||
mapRegion.span.longitudeDelta != newRegion.span.longitudeDelta)
NSLog(@"The zoom has changed");
}

Powinno to określić, czy skala mapy uległa zmianie.
jednak trzeba uważać na powiększenie, ponieważ Ziemia jest zakrzywiona :( jeśli mapa się przewija, latitudeDelta i longitudeDelta zmienią się nieznacznie tylko z powodu kształtu Ziemi, a nie z powodu powiększenia przez użytkownika. Być może będziesz musiał wykryć dużą zmianę w deltach i zignorować drobne zmiany.
Mam nadzieję że to pomoże.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

O wiele prostsza odpowiedź

:
Najłatwiejszym sposobem uzyskania liczby całkowitej dla bieżącego poziomu powiększenia jest użycie funkcji MapView: regionDidChangeAnimated. Ta funkcja rozpoznaje każdą zmianę powiększenia i daje podstawę do obliczenia współczynnika skali.
Po prostu wstaw tę funkcję do swojej klasy MapView (

działa dla Swift 3.0

):
var mapView: MKMapView! = nil...func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
let zoomWidth = mapView.visibleMapRect.size.width
let zoomFactor = Int(log2(zoomWidth)) - 9
print("...REGION DID CHANGE: ZOOM FACTOR \(zoomFactor)")
}

I otrzymujesz z niego wartość zoomFactor, gdzie 0 jest najbliższym punktem, który możesz powiększyć na mapie, a każda wyższa wartość to duże powiększenie ... :-)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Obliczanie skali powiększenia w rozwiązaniu MKMapView - Swift

Stworzyłem następujące rozszerzenie dla MKMapView, abyś mógł uzyskać skalę powiększenia na mapie. Rozwiązanie jest podobne do powyższego, ale w Swift.
Istnieje również dodatkowa funkcja
scaleWithPrecision (_: Int64)
, która zaokrągla skalę, którą f.ex może odfiltrować. małe powiększenie w MapView
extension MKMapView { var scale: Double { return self.scaleWithPrecision(1)
} func scaleWithPrecision(precision: Int64) -> Double { let mapBoundsWidth = Double(self.bounds.size.width)
let mapRectWidth:Double = self.visibleMapRect.size.width let scale: Double = round(Double(precision)*mapBoundsWidth/mapRectWidth)/Double(precision) return scale
}
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz zapisać Delta Latitude, a następnie, gdy nazywa się ona
RegionDidChangeanymated:
, sprawdź, czy wyróżnia się nowa Delta Latitude. Myślę, że Delta Latitude pozostaje stała, dopóki karta zostanie zwiększona.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się