2012-04-27 6 views
5

Google Map APIのMapTypeStyleオブジェクトと同じように、MapKitマップを設定する方法があるかどうかはわかります。MapKitのMapTypeStyle

私はアップルドキュメントのを参照する場合、MKMapViewはMKMapType constantを取りませんが、MapOptionsなどの一切のスタイルパラメータMapTypeStyleとし、MapTypeStylerウィッヒは速いマップのカスタマイズのための非常に強力ですマップタイプのオプションを持っています。

私の質問です:MapKitフレームワークと似たようなものを実現する方法はありますか?そうでない場合は、これを行うための最良のフレームワーク/ライブラリは何ですか?私はMapBoxと同様の製品について考えています。

+0

MKMapViewの色は、プライベートクラスを変更することで変更できますが、Appleが許可しないと確信していますこの 。それにもかかわらず、このオプションに興味があれば、サンプルコードを投稿します。 –

+0

それは見てよかったでしょう! –

+1

@Lee Armstrong私は短いサンプルコードを追加しました –

答えて

3

あなたのためにいくつかのオプションがあります。あなたはこれらのフレームワーク

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

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

それとも、単にmapboxを使用することのいずれかを使用することができます。彼らのAPIはかなりよく見えます。 また、独自のマップタイルとオーバーレイマップキットを用意しています。 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

カスタムタイルオプションは私の場合、私のマップがいくつかのズームレベルで1つの都市範囲に制限されているので、私の場合は最良のアプローチと思われます。私はこれを掘り下げます。タイルをローカルに保存する方法があれば、おそらくこのソリューションをプロダクションに使用します。 あなたの答えに重ねて表示される情報やリンクを参考にしてください。私はこの質問に合格とマークしますか? ありがとうございました。 – rayfranco

2

mapkitでネイティブにマップスタイルをカスタマイズする方法はありません。これに対する唯一の選択肢は、ハイブリッドアプリのアプローチを選択し、ページ自体にhtml/javascriptを使用してスタイルをカスタマイズすることです。

+0

これはスマートでシンプルなソリューションですが、私の場合は使用できません。私は人々が他の誰かのニーズに合ったこのソリューションを見ることができるようにupvoted。 – rayfranco

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

+0

これは、iOS 6のMKMapViewコントロールでは機能しないようです。このバージョンでは "MKMapTileView"は使用されていませんか? iOS 6の –

+0

は完全にリファクタリングされています。新しいレンダリングのほとんどは、OpenGLを使用しており、このハックはもはや機能しません。 –