我在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