Вопрос по ios, ios5 – MapTypeStyle в MapKit

5

Интересно узнать, есть ли способ настроить наши карты MapKit, как мы это делаем с объектом MapTypeStyle в API Карт Google.

Если я ссылаюсь на документы Apple, в MKMapView есть опция mapType, которая принимаетКонстанта MKMapType но нет параметров стилей, таких как MapOptions сMapTypeStyle иMapTypeStyler который очень мощный для быстрой настройки карт.

Итак, мой вопрос: есть ли способ достичь чего-то подобного с помощью инфраструктуры MapKit, если нет, то какая библиотека / библиотека лучше всего подходит для этого? Я думаю оMapBox и аналогичные продукты.

Вы можете изменить цвета MKMapView, изменив закрытый класс, но я уверен, что Apple не допустит этого. Если вы все же заинтересованы в этой опции, я опубликую вам пример кода. Jonathan Cichon
@ Ли Армстронг, я добавил короткий пример кода Jonathan Cichon
Это было бы приятно видеть! Lee Armstrong

Ваш Ответ

3   ответа
2

нный вариант для этого - выбрать подход гибридного приложения, а затем настроить стили, используя html / javascript на самой странице.

Error: User Rate Limit Exceeded 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

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded rayfranco
Error: User Rate Limit Exceeded
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();
    }
}

Also check this out if you want unsupported "terrain" mode http://openradar.appspot.com/9621632

Я на самом деле в середине программы, которая требует наложения плиток на карту.Этот пример было очень полезно. Вы захотите изучить MKOverlay и MKOverlayView. Проект, который я делаю, включает в себя использованиеgheat, Я получаю доступ к плиткам через NSURLConnection и храню их локально.суть моей реализации.

Error: User Rate Limit Exceeded rayfranco

Похожие вопросы