2011-11-09 25 views
5

編輯的界限:我相信我的問題是,這個代碼適用於整數縮放級別,但我想它的浮動縮放級別工作。匹配變焦/ A MapKit地圖縮放/界一RouteMe地圖

我有一個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]; 
} 
+0

我注意到的關於MKMapView的一件事是,如果您設置區域然後立即讀回,您將返回不同的值。在我們的應用程序中,我設置了觸發委託回調的值,然後讀取新值並使用它來確定放置覆蓋的位置。不知道這是否有幫助。 :-( – EricS

回答

4

不幸的是,這是Google Maps API的限制,只設置地圖的縮放級別時接受整數值:蘋果的MapKit代碼調用底層谷歌地圖API時你設置一個MKMapView的顯示區域,並且結果 - 無論您使用哪種MapKit方法來設置區域 - 都是縮小到最接近的整數縮放級別的地圖。

特洛伊布蘭特的代碼會帶你一整圈,並在MapKit API之上放置一層,允許你直接設置縮放級別......但最終你沒有精確控制MKMapView顯示的區域,除非縮放你想要的地圖的級別恰好是一個整數。

在這個問題上有幾個變化上都出現堆棧溢出(例如,MKMapView setRegion "snaps" to predefined zoom levels?MKMapView show incorrectly saved region),但至今沒有人想出了一個綱領性的方式讓一個非整數縮放級別的地圖,我懷疑它谷歌和蘋果之間的合作才能實現。

+0

問題的總結和缺乏解決方案,我想我必須找出其他的東西,因爲這目前不可能,謝謝Scott。 –