将 MapKit 地图的缩放/边界与 RouteMe 地图的缩放/边界匹配

Posted

技术标签:

【中文标题】将 MapKit 地图的缩放/边界与 RouteMe 地图的缩放/边界匹配【英文标题】:Match the zoom/bounds of a MapKit map with the zoom/bounds of a RouteMe map 【发布时间】:2011-11-09 01:22:40 【问题描述】:

编辑:我认为我的问题是此代码适用于整数缩放级别,但我希望它适用于浮动缩放级别。

我有一个 ios 应用,用户可以在其中切换基于 RouteMe 的地图和基于 MapKit 的地图。

当他们切换来源时,我希望能够在一个和另一个中显示完全相同的区域。但是,我不知道如何使它们匹配,因为 RouteMe 和 MapKit 使用不同的数据结构来描述地图边界。

这里有一些代码让它有点接近,但并不准确。此代码来自:http://troybrant.net/blog/2010/01/set-the-zoom-level-of-an-mkmapview/

我不确定是否应该修复此代码,或者我可能忽略了一个更简单的解决方案。代码从列出的最后一个方法开始执行:

#define MERCATOR_OFFSET 268435456
#define MERCATOR_RADIUS 85445659.44705395

#pragma mark -
#pragma mark Map conversion methods

- (double)longitudeToPixelSpaceX:(double)longitude 
  return round(MERCATOR_OFFSET + MERCATOR_RADIUS * longitude * M_PI / 180.0);


- (double)latitudeToPixelSpaceY:(double)latitude 
  return round(MERCATOR_OFFSET - MERCATOR_RADIUS * logf((1 + sinf(latitude * M_PI / 180.0)) / (1 - sinf(latitude * M_PI / 180.0))) / 2.0);


- (double)pixelSpaceXToLongitude:(double)pixelX 
  return ((round(pixelX) - MERCATOR_OFFSET) / MERCATOR_RADIUS) * 180.0 / M_PI;


- (double)pixelSpaceYToLatitude:(double)pixelY 
  return (M_PI / 2.0 - 2.0 * atan(exp((round(pixelY) - MERCATOR_OFFSET) / MERCATOR_RADIUS))) * 180.0 / M_PI;



- (MKCoordinateSpan)coordinateSpanWithMapView:(MKMapView *)mapView
                             centerCoordinate:(CLLocationCoordinate2D)centerCoordinate
                                 andZoomLevel:(NSInteger)zoomLevel 
  // convert center coordiate to pixel space
  double centerPixelX = [self longitudeToPixelSpaceX:centerCoordinate.longitude];
  double centerPixelY = [self latitudeToPixelSpaceY:centerCoordinate.latitude];

  // determine the scale value from the zoom level
  NSInteger zoomExponent = 20 - zoomLevel;
  double zoomScale = pow(2, zoomExponent);

  // scale the map’s size in pixel space
  CGSize mapSizeInPixels = mapView.bounds.size;
  double scaledMapWidth = mapSizeInPixels.width * zoomScale;
  double scaledMapHeight = mapSizeInPixels.height * zoomScale;

  // figure out the position of the top-left pixel
  double topLeftPixelX = centerPixelX - (scaledMapWidth / 2);
  double topLeftPixelY = centerPixelY - (scaledMapHeight / 2);

  // find delta between left and right longitudes
  CLLocationDegrees minLng = [self pixelSpaceXToLongitude:topLeftPixelX];
  CLLocationDegrees maxLng = [self pixelSpaceXToLongitude:topLeftPixelX + scaledMapWidth];
  CLLocationDegrees longitudeDelta = maxLng - minLng;

  // find delta between top and bottom latitudes
  CLLocationDegrees minLat = [self pixelSpaceYToLatitude:topLeftPixelY];
  CLLocationDegrees maxLat = [self pixelSpaceYToLatitude:topLeftPixelY + scaledMapHeight];
  CLLocationDegrees latitudeDelta = -1 * (maxLat - minLat);

  // create and return the lat/lng span
  MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
  return span;



- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
                    zoomLevel:(NSUInteger)zoomLevel
                     animated:(BOOL)animated 

  // use the zoom level to compute the region
  MKCoordinateSpan span = [self coordinateSpanWithMapView:self       
                               centerCoordinate:centerCoordinate
                                   andZoomLevel:zoomLevel];
  MKCoordinateRegion region = MKCoordinateRegionMake(centerCoordinate, span);

  // set the region like normal
  [self setRegion:region animated:animated];

【问题讨论】:

我注意到关于 MKMapView 的一件事是,如果您设置区域然后立即读取它,您会得到不同的值。在我们的应用程序中,我设置了触发委托回调的值,然后读取新值并使用它来确定将叠加层放置在哪里。不确定这是否有帮助。 :-( 【参考方案1】:

不幸的是,这是 Google Maps API 的一个限制,它在设置地图的缩放级别时只接受整数值:当您设置 MKMapView 的显示区域时,Apple 的 MapKit 代码正在调用底层的 Google Maps API,而结果 - 无论您使用哪个 MapKit 方法来设置区域 - 是缩小到最接近的整数缩放级别的地图。

Troy Brant 的代码带你走了一圈,并在 MapKit API 之上放置了一个层,允许你直接设置缩放级别……但最终你无法精确控制 MKMapView 显示的区域,除非缩放级别你想要的地图恰好是一个整数。

Stack Overflow 上出现了关于这个问题的几个变体(例如,MKMapView setRegion "snaps" to predefined zoom levels? 和 MKMapView show incorrectly saved region),但到目前为止,还没有人想出一种编程方式来制作具有非整数缩放级别的地图,并且我怀疑这需要谷歌和苹果之间的合作才能实现。

【讨论】:

很好地总结了问题和缺乏解决方案。我想我必须想出别的办法,因为这目前是不可能的。谢谢斯科特。

以上是关于将 MapKit 地图的缩放/边界与 RouteMe 地图的缩放/边界匹配的主要内容,如果未能解决你的问题,请参考以下文章

Mapkit 显示注释区域

MapKit 缩放到用户当前位置

Yandex MapKit 3.0。获取屏幕和缩放的中心,在地图上获取位置

mapkit 地图视图幻灯片滑动到并放大效果?

iPhone Mapkit 蓝点/用户位置区域缩放问题

使用 Alamofire 和 Mapkit Swift 3 请求