Demo:  https://github.com/xushiyou23/AMapTesting

转:

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Bear_861110453/article/details/81564605
 
本文主要介绍通过自定义高德地图 MATileOverlay 接口,添加 WMS 服务到地图上。

自定义类 WMSTileOverlayUtil,继承自高德地图接口 MATileOverlay,主要重载函数: 
- (NSURL *)URLForTilePath:(MATileOverlayPath)path; 
- (void)loadTileAtPath:(MATileOverlayPath)path result:(void (^)(NSData *tileData, NSError *error))result;,见代码注释。

#import <Foundation/Foundation.h>
#import <MAMapKit/MATileOverlay.h> @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 <MAMapKit/MAMapKit.h>
#import <AMapFoundationKit/AMapFoundationKit.h>
#import <math.h> #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( WGS-84) 转 为高德地图需要的坐标
CLLocationCoordinate2D amapcoord = AMapCoordinateConvert(CLLocationCoordinate2DMake(minY, minX), AMapCoordinateTypeGPS);
minY = amapcoord.latitude;
minX = amapcoord.longitude; CLLocationCoordinate2D maxAmapcoord = AMapCoordinateConvert(CLLocationCoordinate2DMake(maxY, maxX), AMapCoordinateTypeGPS);
maxY = maxAmapcoord.latitude;
maxX = maxAmapcoord.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 函数贴到地图上。你也可以 改写成自己的网络访问层。

问题

为啥要重载 - (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;

iOS 利用高德地图WMS服务的更多相关文章

  1. 高德地图-搜索服务-POI搜索

    高德地图-搜索服务-POI搜索 之前公司项目收货地址仿饿了么的收货地址,结果发现自己实现的关键字搜索和周边搜索,搜索到的poi列表跟饿了么的并不完全一样,后来考虑了下,应该是搜索的范围.类型之类的设置 ...

  2. 利用高德地图javascriptAPI做一个自己的地图

    最近由于项目中需要制作一个地图,用来选择活动地点,我就花了两天利用高德地图的javascriptAPI自制了一个地图的demo.在这了记录一下我学习的过程. 一.进入高德地图官网,再找到高德地图的开放 ...

  3. 【视频教学】如何利用高德地图IOS SDK进行开发?

    Step1:使用IOS SDK可以做什么高德地图 iOS SDK 是一套基于 iOS 5.1.1 及以上版本的地图应用程序开发接口.通过该接口,用户可使用高德地图数据和服务轻松构建功能丰富.交互性强的 ...

  4. iOS导入高德地图出现缺失armv7--"Undefined symbols for architecture armv7"

    在已有项目中使用pod导入高德地图,报了以下错误: ld: warning: directory not found for option '-L/Users/paul/iOS/yun-hui-yi/ ...

  5. iOS的高德地图标注特定位置

    在开发时有时候遇到项目里面需要展示公司的位置,这时如果导入百度地图什么的就太浪费资源,而且还占内存 这时只要调用自动高德地图的就行了 自己写一个控制器,导入框架 现在导入系统框架只要多打次就能出来了, ...

  6. iOS 去除高德地图下方的 logo 图标

    [self.mapView.subviews enumerateObjectsUsingBlock:^(__kindof UIView * _Nonnull obj, NSUInteger idx, ...

  7. 安卓开发笔记①:利用高德地图API进行定位、开发电子围栏、天气预报、轨迹记录、搜索周边(位置)

    高德地图开发时需要导入的包在下面的网盘链接中:(由于高德地图api更新得太快,官网上最新的包使用起来没有之前的方便,所以以下提供最全面的原始包) 链接:http://pan.baidu.com/s/1 ...

  8. android开发对应高德地图定位服务进度一

    进行android的高德地图开发首先需要进入高德地图的控制台进行注册登录.之后创建新的应用并且绑定软件得到相应的key. 这里面需要找到自己软件对应的多个SHA1.这里有发布版和调试版,以及对应的软件 ...

  9. ios开发--高德地图SDK使用简介

    高德LBS开放平台将高德最专业的定位.地图.搜索.导航等能力,以API.SDK等形式向广大开发者免费开放.本章节我们来简单学习一下如何使用它的定位及地图SDK. 一.相关框架及环境配置 地图SDK 对 ...

随机推荐

  1. Dynamics CRM项目实例之八:CRM 2015的产品系列,克隆,修订

    关注本人微信和易信公众号: 微软动态CRM专家罗勇,回复139或者20150106可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me!       今天的博客主要是关于D ...

  2. Dynamics 365设置错误通知首选项的方法

    本人微信公众号:微软动态CRM专家罗勇 ,回复288或者20181205可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 使用 ...

  3. Echarts地图使用经验-地图变形和添加数据

    关于echart2,echart3地图的使用一点人生经验: 1.echart3,echart2加载地图变形修复. 最近在使用echart2使用过程中,发现加载海南地图会产生变形.如下图,海南地图产生了 ...

  4. android集成twitter登录

    Twitter曾经举行了自己四年以来的第一场开发者大会.而这场名为“Flight”的大会,也是以后它的年度惯例. 这次大会的主题也完全围绕开发者进行.大会的焦点是一个名叫Fabric的新SDK,里面包 ...

  5. mssql sqlserver 索引专题

    摘要: 下文将详细讲述sql server 索引的相关知识,如下所示: 实验环境: sql server 2008 R2 sqlserver索引简介: mssql sqlsever 索引分类简介 ms ...

  6. python正则表达式模块re

    正则表达式的特殊元素 匹配符号 描述 '.'(点dot) 在默认模式下,它匹配除换行符之外的任何字符.如果指定了DOTALL标志,则匹配包括换行符在内的任何字符 '^'(Caret) 匹配以字符串开头 ...

  7. 【Spring】application.xml文件配置

    什么是Spring? Spring是分层的javaEE full-stack(一站式)轻量级开源框架. ---注解配置--针对SSM <?xml version="1.0" ...

  8. Bootstrap -- 文本,背景,其他样式

    Bootstrap -- 文本,背景,其他样式 1. 文本样式:展示了不同的文本颜色 使用文本样式: <!DOCTYPE html> <html> <head> & ...

  9. 如何用Nginx解决前端跨域问题?

    前言 在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调. 最简单的解决方法,就是把浏览器设为忽略安全问题,设置--di ...

  10. 云数据库PolarDB(一)

    一.出现的背景及PolarDB简介 阿里云,中国第一家拥有完整云计算能力的企业. 2015年,在计算界的奥运会Sort Benchmark中,阿里云计算100TB数据排序只用了不到7分钟,把Apach ...