iOS高德地圖添加自定義瓦片地圖

瓦片地圖

首先解釋一下什么是瓦片地圖,我們使用的地圖(例如百度,高德)都有一個(gè)底圖卦方,在每一級(jí)的縮放比例下,都有一張很大的底圖泰佳,這張底圖按固定的大小切割成若干份盼砍,在地圖顯示時(shí)根據(jù)顯示范圍和縮放比例尘吗,請(qǐng)求對(duì)應(yīng)幾張小的底圖,這些底圖就是瓦片地圖浇坐。

項(xiàng)目需求

項(xiàng)目使用的是高德地圖睬捶,基本的操作可以參考官方文檔,然后需要疊加自己的瓦片地圖近刘。在官方文檔中找了好久擒贸,終于在繪制面_繪制瓦片圖層這一節(jié)中找到了相應(yīng)的方法。主要步驟是先添加一個(gè)MATileOverlay到地圖中觉渴,然后實(shí)現(xiàn)delegate中的mapView:viewForOverlay:函數(shù)介劫,返回一個(gè)renderer對(duì)象。項(xiàng)目中用到的所有地圖都要加載這個(gè)瓦片服務(wù)案淋,所以直接從MAMapView繼承出一個(gè)自定義MapView座韵。

代碼實(shí)現(xiàn)

自定義一個(gè)PPGMapView,繼承自MAMapView踢京。

#import <MAMapKit/MAMapKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface PPGMapView : MAMapView

@end

NS_ASSUME_NONNULL_END

在初始化時(shí)添加自定義瓦片圖層誉碴。

- (void)commonInit {
    // delegate指向自己
    self.delegate = self;
    // 初始化縮放級(jí)別
    self.zoomLevel = 18.f;
    self.showsUserLocation = YES;
    self.userTrackingMode = MAUserTrackingModeFollow;
    // 添加自定義瓦片圖層
    PPGTileOverlay *overlay = [[PPGTileOverlay alloc] init];
    overlay.maximumZ = 20;
    overlay.minimumZ = 14;
    overlay.boundingMapRect = MAMapRectWorld;
    [self addOverlay:overlay];
}

實(shí)現(xiàn)renderer方法

- (MAOverlayRenderer *)mapView:(MAMapView *)mapView rendererForOverlay:(id <MAOverlay>)overlay {
    // 外部delegate首先進(jìn)行響應(yīng),如果沒有實(shí)現(xiàn)瓣距,則使用自定義地圖的實(shí)現(xiàn)
    if ([self.extDelegate respondsToSelector:_cmd]) {
        MAOverlayRenderer *renderer = [self.extDelegate mapView:mapView rendererForOverlay:overlay];
        if (renderer) {
            return renderer;
        }
    }
    if ([overlay isKindOfClass:[MATileOverlay class]]) {
        // 默認(rèn)的瓦片底圖renderer
        MATileOverlayRenderer *renderer = [[MATileOverlayRenderer alloc] initWithTileOverlay:overlay];
        return renderer;
    }
    return nil;
}

下面是自定義瓦片地圖的代碼

/**
 自定義瓦片圖層黔帕,繼承自MATileOverlay
 */
@interface PPGTileOverlay : MATileOverlay

@end

@implementation PPGTileOverlay

- (NSURL *)URLForTilePath:(MATileOverlayPath)path {
#warning 自行替換ip和端口號(hào)
    NSString *urlStr = [NSString stringWithFormat:@"http://ip:port/mapImg/tiles/%ld/%ld_%ld.png", (long)path.z, (long)path.x, (long)path.y];
    return [NSURL URLWithString:urlStr];
}

// 使用template和上面的方法會(huì)丟掉端口號(hào),所以自己去請(qǐng)求蹈丸,然后回調(diào)結(jié)果
- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *, NSError *))result {
    NSURL *url = [self URLForTilePath:path];
    // 使用SDWebImage管理本地瓦片
    SDImageCache *cache = [SDImageCache sharedImageCache];
    UIImage *image = [cache imageFromCacheForKey:[url absoluteString]];
    if (image) {
        result(UIImagePNGRepresentation(image), nil);
    } else {
        // 在3D地圖中如果瓦片請(qǐng)求失敗成黄,會(huì)一直重復(fù)去請(qǐng)求,這里用set存儲(chǔ)已請(qǐng)求的瓦片白华,不做重復(fù)請(qǐng)求
        static NSMutableSet *urlSet;
        if (urlSet == nil) {
            urlSet = [NSMutableSet new];
        }
        if ([urlSet containsObject:url]) {
            return;
        }
        [[SDWebImageDownloader sharedDownloader] downloadImageWithURL:url options:SDWebImageDownloaderHighPriority progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
            if (finished && data) {
                [cache storeImageDataToDisk:data forKey:[url absoluteString]];
            }
            result(data, error);
            [urlSet addObject:url];
        }];
    }
}

@end

到這里瓦片地圖就添加上去了慨默,這里還有一個(gè)delegate的問題,因?yàn)槲覀兂跏蓟臅r(shí)候設(shè)置delegate為自己了弧腥,瓦片地圖才能正常顯示厦取,如果這是在使用的時(shí)候delegate設(shè)置為另外一個(gè)對(duì)象,而他沒實(shí)現(xiàn)上面的renderer 方法管搪,那么我們的瓦片地圖又不能顯示了虾攻,所以這里使用了外部delegate方法。

在自定義MapView中添加一個(gè)Extension更鲁,添加私有屬性extDelegate

@interface PPGMapView () <MAMapViewDelegate>

/**
 外部的代理
 */
@property (nonatomic, weak) id<MAMapViewDelegate> extDelegate;

@end

重寫setDelegate方法和respondsToSelector方法

// 保存本地delegate霎箍,記錄外部delegate
- (void)setDelegate:(id<MAMapViewDelegate>)delegate {
    if (delegate == self) {
        [super setDelegate:delegate];
    } else {
        self.extDelegate = delegate;
    }
}

- (BOOL)respondsToSelector:(SEL)aSelector {
    BOOL responds = [super respondsToSelector:aSelector];
    if (responds) {
        return responds;
    } else {
        return [self.extDelegate respondsToSelector:aSelector];
    }
}

runtime轉(zhuǎn)發(fā)方法到外部delegate

// runtime消息轉(zhuǎn)發(fā)
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([self.extDelegate respondsToSelector:aSelector]) {
        return self.extDelegate;
    }
    return nil;
}

代碼倉庫地址:
https://github.com/gaopeng-hz/TileOverlay

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市澡为,隨后出現(xiàn)的幾起案子漂坏,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顶别,死亡現(xiàn)場(chǎng)離奇詭異谷徙,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)驯绎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門完慧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人剩失,你說我怎么就攤上這事屈尼。” “怎么了拴孤?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵脾歧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我演熟,道長(zhǎng)涨椒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任绽媒,我火速辦了婚禮,結(jié)果婚禮上免猾,老公的妹妹穿的比我還像新娘是辕。我一直安慰自己,他們只是感情好猎提,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布获三。 她就那樣靜靜地躺著,像睡著了一般锨苏。 火紅的嫁衣襯著肌膚如雪疙教。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天伞租,我揣著相機(jī)與錄音贞谓,去河邊找鬼。 笑死葵诈,一個(gè)胖子當(dāng)著我的面吹牛裸弦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播作喘,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼理疙,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了泞坦?” 一聲冷哼從身側(cè)響起窖贤,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赃梧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體滤蝠,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年槽奕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了几睛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粤攒,死狀恐怖所森,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情夯接,我是刑警寧澤焕济,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站盔几,受9級(jí)特大地震影響晴弃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逊拍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一上鞠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芯丧,春花似錦芍阎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至骗露,卻和暖如春岭佳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背萧锉。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工珊随, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人驹暑。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓玫恳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親优俘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子京办,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容