ios 高德地图加载瓦片地图_IOS 高德地图 API 加载 WMS 服务
IOS 高德地圖 API 加載 WMS 服務
本文主要介紹通過自定義高德地圖 MATileOverlay 接口,添加 WMS 服務到地圖上。廢話少說,先貼代碼。
代碼
自定義類 WMSTileOverlayUtil,繼承自高德地圖接口 MATileOverlay,主要重載函數:
- (NSURL *)URLForTilePath:(MATileOverlayPath)path;
- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result;,見代碼注釋。
#import
#import
@interface WMSTileOverlayUtil : MATileOverlay
- (id)initWithRootURL:(NSString *)rootRUL;
/**
* @brief 以tile path生成URL。用于加載tile,此方法默認填充URLTemplate
* @param path tile path
* @return 以tile path生成tileOverlay
*/
- (NSURL *)URLForTilePath:(MATileOverlayPath)path;
@end
#import "WMSTileOverlayUtil.h"
#import
#import
#import
#import "Api.h"
@implementation WMSTileOverlayUtil
{
NSString * rootURL;
NSInteger titleSize; // = 256
double initialResolution; // = 156543.03392804062;//2*Math.PI*6378137/titleSize;
double originShift; // = 20037508.342789244;//2*Math.PI*6378137/2.0; 周長的一半
double HALF_PI; // = Math.PI / 2.0;
double RAD_PER_DEGREE; // = Math.PI / 180.0;
double METER_PER_DEGREE; // = originShift / 180.0;//一度多少米
double DEGREE_PER_METER; // = 180.0 / originShift;//一米多少度
}
- (id)initWithRootURL:(NSString *)rootRUL {
self = [super init];
if (self) {
rootURL = rootRUL;
titleSize = 256;
initialResolution = 156543.03392804062;
originShift = 20037508.342789244;
HALF_PI = M_PI_2;
RAD_PER_DEGREE = M_PI / 180.0;
METER_PER_DEGREE = originShift / 180.0;
DEGREE_PER_METER = 180.0 / originShift;
}
return self;
}
/**
* @brief 以tile path生成URL。用于加載tile,此方法默認填充URLTemplate
* @param path tile path
* @return 以tile path生成tileOverlay
*/
- (NSURL *)URLForTilePath:(MATileOverlayPath)path {
NSString * strURL = [[NSString alloc] initWithFormat:@"%@%@", rootURL, [self titleBoundsByX:path.x
Y:path.y
Z:path.z]];
NSURL * url = [NSURL URLWithString:strURL];
return url;
}
/**
* @brief 加載被請求的tile,并以tile數據或加載tile失敗error訪問回調block;默認實現為首先用URLForTilePath去獲取URL,然后用異步NSURLConnection加載tile
* @param path tile path
* @param result 用來傳入tile數據或加載tile失敗的error訪問的回調block
*/
- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result {
if (path.z < 8) return;
NSURL * url = [self URLForTilePath:path];
NSString * strURL = url.absoluteString;
SuccessCallback successCallback = ^(id responseObject) {
UIImage * image = [UIImage imageWithData:responseObject];
NSData * data = UIImagePNGRepresentation(image);
result(data, nil);
};
FailureCallBack failureCallBack = ^(NSError *error) {
result(nil, error);
};
[Api GETWMSWith:strURL successCallback:successCallback failureCallBack:failureCallBack];
}
/**
* @brief 取消請求瓦片,當地圖顯示區域發生變化時,會取消顯示區域外的瓦片的下載, 當disableOffScreenTileLoading=YES時會被調用。since 5.3.0
* @param path tile path
*/
- (void)cancelLoadOfTileAtPath:(MATileOverlayPath)path {
[super cancelLoadOfTileAtPath:path];
}
/**
* 根據瓦片的x/y等級返回瓦片范圍
*
* @param tx x
* @param ty y
* @param zoom z
* @return url
*/
- (NSString *)titleBoundsByX:(NSInteger)tx Y:(NSInteger)ty Z:(NSInteger)zoom {
double minX = [self pixels2Meters:(tx * titleSize) zoom:zoom];
double maxY = -[self pixels2Meters:(ty * titleSize) zoom:zoom];
double maxX = [self pixels2Meters:((tx + 1) * titleSize) zoom:zoom];
double minY = -[self pixels2Meters:((ty + 1) * titleSize) zoom:zoom];
// 轉換成經緯度 高德坐標系經緯度
minX = [self meters2Lon:minX];
minY = [self meters2Lat:minY];
maxX = [self meters2Lon:maxX];
maxY = [self meters2Lat:maxY];
// 轉換成 gps 坐標系經緯度
CLLocationCoordinate2D gps_min = [LocationUtil GCJ02ToWGS84:CLLocationCoordinate2DMake(minY, minX)];
CLLocationCoordinate2D gps_max = [LocationUtil GCJ02ToWGS84:CLLocationCoordinate2DMake(maxY, maxX)];
minY = gps_min.latitude;
minX = gps_min.longitude;
maxY = gps_max.latitude;
maxX = gps_max.longitude;
NSString * result = [[NSString alloc] initWithFormat:@"%f,%f,%f,%f&width=256&height=256", minX, minY, maxX, maxY];
return result;
}
/**
* 根據像素、等級算出坐標
*
* @param p p
* @param zoom z
* @return double
*/
- (double)pixels2Meters:(NSInteger)p zoom:(NSInteger)zoom {
return p * [self resolution:zoom] - originShift;
}
/**
* 計算分辨率
*
* @param zoom z
* @return double
*/
- (double)resolution:(NSInteger)zoom {
return initialResolution / (pow(2, zoom));
}
/**
* X米轉經緯度
*/
- (double)meters2Lon:(double)mx {
double lon = mx * DEGREE_PER_METER;
return lon;
}
/**
* Y米轉經緯度
*/
- (double)meters2Lat:(double)my {
double lat = my * DEGREE_PER_METER;
lat = 180.0 / M_PI * (2 * atan(exp(lat * RAD_PER_DEGREE)) - HALF_PI);
return lat;
}
@end
其中,- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result; 函數中,使用自己寫的 網絡訪問層去請求 wms 服務,并通過 result 函數貼到地圖上。你也可以 改寫成自己的網絡訪問層。
有關 gcj02 轉 gps 請查看 請隨手點贊
問題
為啥要重載 - (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result; 函數,因為只是從載 - (NSURL *)URLForTilePath:(MATileOverlayPath)path; 生成 NSURL 后,loadTileAtPath 函數會去通過網絡請求加載 wms 服務,然而,這一步網絡請求會報錯:NSURLConnection -errorcode -1004,且一個星期沒有解決為啥報錯,所以只得重寫,如果有熟悉高德地圖 api 的小伙伴能夠給予解答,不勝感激。
注意
如果使用 AFNetworking 要注意修改支持的類型:
AFHTTPSessionManager * manager = [[AFHTTPSessionManager alloc] init];
AFHTTPResponseSerializer *serializer=[AFHTTPResponseSerializer serializer];
serializer.acceptableContentTypes = [NSSet setWithObject:@"image/png"];
manager.responseSerializer = serializer;
轉載自:https://blog.csdn.net/Bear_861110453/article/details/81564605
總結
以上是生活随笔為你收集整理的ios 高德地图加载瓦片地图_IOS 高德地图 API 加载 WMS 服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一加Ace 2 Pro受到了很多学生喜爱
- 下一篇: excel npoi 连接_Net操作E