我在iPhone上使用MapKit。 如何知道用戶何時更改縮放級別(放大地圖)?檢查縮放級別是否改變
我試過用mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;但即使僅在拖動地圖時纔會調用。 不幸的是,當地圖拖動時,mapView.region.span也會發生變化...
幫助?
10X
我在iPhone上使用MapKit。 如何知道用戶何時更改縮放級別(放大地圖)?檢查縮放級別是否改變
我試過用mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated;但即使僅在拖動地圖時纔會調用。 不幸的是,當地圖拖動時,mapView.region.span也會發生變化...
幫助?
10X
這是很簡單的計算縮放級別。請參見下面的代碼片段,您可以從該mRect參數visibleMapRect
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;
}
您可以在計算zoomScale
的步驟中停止,因爲它會告訴您縮放是否已經改變。
我想通了這東西了從主題閱讀特洛伊Brants優秀的博客文章:
http://troybrant.net/blog/2010/01/mkmapview-and-zoom-levels-a-visual-guide/
斯威夫特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))
}
}
可能不是你想要聽到的答案,但我不相信有一個特定的委託方法這一點。 (目前肯定沒有公開的。)
因此,您必須使用您已突出顯示的mapView:regionDidChangeAnimated:方法。
您可以保存緯度增量,然後當調用regionDidChangeAnimated:
時,檢查新緯度增量是否不同。我認爲只要地圖沒有放大,緯度三角洲就會保持不變。
你可以聽mapView:regionDidChangeAnimated:
方法。但是,這並不會告訴您縮放級別是否發生了變化,就像地圖是動畫一樣。
您還需要聽地圖視圖的region
屬性。這包含可用於計算縮放級別是否已更改的緯度Delta和經度Delta值。
@class MyMapViewController {
...
MKCoordinateRegion mapRegion;
}
@end
,並在您.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");
}
如果地圖縮放更改時,這應檢測
即。
但是,由於地球是彎曲的,你應該研究變焦變化:(如果地圖是滾動的緯度,則經度和緯度只會因爲地球的形狀而稍微變化,而不是因爲用戶放大。可能需要檢測三角洲大的變化,而忽略細微的變化。
希望有所幫助。
比我的答案要完整得多。我認爲經度三角洲在你走向兩極時會發生變化,但是無論你走到哪裏,緯度三角洲都會保持不變。可能需要一些測試來檢查它是否足夠使用。 – 2010-12-05 15:53:01
我永遠不會記得哪些變化,哪些不會,所以我剛剛在我的回答中都測試過了:)我想你可以測試一下,看看他們是否改變它必須是一個用戶縮放,如果只有一個改變它很多是一個滾動? – deanWombourne 2010-12-05 16:19:34
夥計們我希望你能在發佈之前對你的「解決方案」進行一些小小的檢查。 非你的想法工作。跨度三角洲確實發生了變化 - 而且變化很大。 – Rizon 2010-12-06 00:36:52
我發現這非常有幫助,並制定了以下代碼基於這些答案。
- (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];
}
}
}
,我有以下的MKMapView類中,我包括快速獲取當前縮放級別地圖的方法:
@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
爲了得到縮放級別,您可以撥打以下的代表和確定縮放級別已經改變:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated {
NSUInteger zoomLevel = [mapView zoomLevel];
}
計數放大規模的MKMapView - 迅速解決
我爲MKMapView創建了以下擴展,因此您可以在地圖上獲得縮放比例。該解決方案與上面介紹的類似,但在Swift中。
還有一個額外的功能scaleWithPrecision(_:Int64)
四捨五入的規模,允許過濾掉f.ex。在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
}
}
小變焦的變化更簡單的答案:
來獲得當前縮放級別的整數最簡單的方法,就是使用的MapView功能:regionDidChangeAnimated。此功能可識別變焦中的每個變化,併爲您提供變焦係數計算的基礎。
只需插入此功能到您的MapView類(作品雨燕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)")
}
,你會得到一個zoomFactor值出來,其中0表示最近點,你可以放大地圖和每一個更高的值是一個遙遠的距離放大... :-)
好吧,你錯了。 跨度值在您拖動地圖時發生變化。 – Rizon 2010-12-06 00:31:46