2012-04-27 12 views
5

我想知道是否有任何方法配置我們的MapKit地圖,就像我們在Google Maps API中使用MapTypeStyle對象一樣。MapKit中的MapTypeStyle

如果我指的是蘋果文檔的查看,的MKMapView有需要MKMapType constant但沒有風格的參數,如MapOptions用於與MapTypeStyleMapTypeStyler至極是快速的地圖定製非常強大的一個地圖類型選項。

所以我的問題是:有沒有什麼辦法可以實現與MapKit框架類似的東西,如果沒有,最好的框架/庫是做什麼的?我正在考慮MapBox及類似產品。

+0

您可以通過修改私有類來修改MKMapView的顏色,但我確信蘋果不會允許這個 。如果你對這個選項感興趣,我會發布你的代碼示例。 – 2012-05-05 17:20:19

+0

這將很高興看到! – 2012-05-07 06:04:39

+1

@李阿姆斯特朗我添加了一個簡短的示例代碼 – 2012-05-07 07:47:06

回答

3

有幾個選擇給你我的朋友。你可以使用這些框架

http://cloudmade.com/products/iphone-sdk

https://github.com/route-me/route-me

的一個或者你可以只使用mapbox。他們的api看起來不錯。 或者,您可以提供自己的地圖圖塊和覆蓋圖mapkit。像這樣的事情在MKOverlayView

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context { 

NSURL* fileURL = [(HeatMap*)self.overlay localUrlForStyle:@"alien" withMapRect:mapRect andZoomScale:zoomScale]; 
NSData *imageData = [NSData dataWithContentsOfURL:fileURL ]; 
if (imageData != nil) { 
    UIImage* img = [UIImage imageNamed:@"aTileX.png"]; 
    // Perform the image render on the current UI context 
    UIGraphicsPushContext(context); 
    [img drawInRect:[self rectForMapRect:mapRect] blendMode:kCGBlendModeNormal alpha:1.0]; 
    UIGraphicsPopContext(); 
    } 
} 

,如果你想不支持的「地形」也看看這個模式 http://openradar.appspot.com/9621632

我實際上是在需要在地圖上覆蓋瓦片程序的中間。 This example一直很有幫助。你會想看看MKOverlay和MKOverlayView。我正在做的項目涉及使用gheat。我通過NSURLConnection訪問磁貼並將它們存儲在本地。 A gist我的實施。

+0

自定義拼貼選項似乎是我最好的方法,因爲我的地圖被限制在一個城市範圍內,只有很少的縮放級別。如果有任何方法可以在本地存儲切片,我可以使用此解決方案進行製作。 你能否參考一些關於覆蓋在答案中的更多信息/鏈接,以便將此問題標記爲已接受? 非常感謝。 – rayfranco 2012-05-08 20:45:47

2

沒有辦法用mapkit自然地定製地圖樣式。您唯一的選擇是選擇混合應用程序方法,然後在頁面中使用html/javascript自定義樣式。

+0

這是一個聰明和簡單的解決方案,但沒有一個我可以用在我的情況。我積極參與,以便人們可以看到適合其他人需求的解決方案。 – rayfranco 2012-05-08 20:30:36

2

由於在一個名爲MKMapTileView的私人課程中繪製圖塊,您不能簡單地編寫一個類別。您必須爲自定義繪圖實現另一個類。這個類的方法將被用來在運行時過載MKMapTileView實現:

頭文件

@interface MyColorMap : NSObject 
+ (void)overLoadMethods:(Class)destinationClass; 
@end 

Imlementation:

#import "MyColorMap.h" 
#import <objc/runtime.h> 

@implementation MyColorMap 

+ (void)overLoadMethods:(Class)destinationClass { 
    // get the original method for drawing a tile 
    Method originalDrawLayer = class_getInstanceMethod(destinationClass, @selector(drawLayer:inContext:)); 

    // get the method we will replace with the original implementation of 'drawLayer:inContext:' later 
    Method backupDrawLayer = class_getInstanceMethod([self class], @selector(backupDrawLayer:inContext:)); 

    // get the method we will use to draw our own colors 
    Method myDrawLayer = class_getInstanceMethod([self class], @selector(myDrawLayer:inContext:)); 

    // dito with the implementations 
    IMP impOld = method_getImplementation(originalDrawLayer); 
    IMP impNew = method_getImplementation(myDrawLayer); 

    // replace the original 'drawLayer:inContext:' with our own implementation 
    method_setImplementation(originalDrawLayer, impNew); 

    // set the original 'drawLayer:inContext:' implementation to our stub-method, so wie can call it later on 
    SEL selector = method_getName(backupDrawLayer); 
    const char *types = method_getTypeEncoding(backupDrawLayer); 
    class_addMethod(destinationClass, selector, impOld, types); 
} 


- (void)backupDrawLayer:(CALayer*)l inContext:(CGContextRef)c { 
    // stub method, implementation will never be called. The only reason we implement this is so we can call the original method durring runtime 
} 

- (void)myDrawLayer:(CALayer*)l inContext:(CGContextRef)c { 
    // set background to white so wie can use it for blendmode 
    CGContextSetFillColorWithColor(c, [[UIColor whiteColor] CGColor]); 
    CGContextFillRect(c, CGContextGetClipBoundingBox(c)); 

    // set blendmode so the map will show as grayscale 
    CGContextSetBlendMode(c, kCGBlendModeLuminosity); 
    // kCGBlendModeExclusion for inverted colors etc. 

    // calling the stub-method which will become the original method durring runtime 
    [self backupDrawLayer:l inContext:c]; 

    // if you want more advanced manipulations you can alter the context after drawing: 

// int w = CGBitmapContextGetWidth(c); 
// int h = CGBitmapContextGetHeight(c); 
//  
// unsigned char* data = CGBitmapContextGetData(c); 
// if (data != NULL) { 
//  int maxY = h; 
//  for(int y = 0; y<maxY; y++) { 
//   for(int x = 0; x<w; x++) { 
//     
//    int offset = 4*((w*y)+x); 
//    char r = data[offset]; 
//    char g = data[offset+1]; 
//    char b = data[offset+2]; 
//    char a = data[offset+3]; 
//     
//    // do what ever you want with the pixels 
//     
//    data[offset] = r; 
//    data[offset+1] = g; 
//    data[offset+2] = b; 
//    data[offset+3] = a; 
//   } 
//  } 
// } 
} 

現在你必須之前調用[MyColorMap overLoadMethods:NSClassFromString(@"MKMapTileView")]在一些點使用MKMapView

+0

對於一個如此簡單的需求,這看起來像是一個深入的破解:)我可能會使用重疊(請參閱@ jb1a1答案),因爲我沒有看到使用解決方案的好處。仍然是一件好事,要知道。感謝您分享此示例。 Hope MapKit即將升級,讓我們自定義地圖JS方式。 – rayfranco 2012-05-08 20:51:12

+0

這似乎不適用於iOS 6的MKMapView控件。這個版本可能不使用「MKMapTileView」嗎? – 2013-04-29 07:56:33

+0

在iOS 6中地圖完全重構。大多數新的渲染使用openGL,這種破解不再有效。 – 2013-04-29 09:22:17