首页 > 其他分享 >iOS小技能:地理编码(地址转坐标)

iOS小技能:地理编码(地址转坐标)

时间:2022-09-28 16:04:55浏览次数:51  
标签:编码 dto 经纬度 void iOS 地址 坐标 responseObject


前言

需求: 手动输入位置信息需要进行地理编码获取经纬度,判断是否为国内地址。


I 高德位置服务:地理编码(地址转坐标)

用户在高德地图官网申请Web服务API类型Key:https://lbs.amap.com/dev/

开发 > Web服务 API > 开发指南 > API文档 > 地理/逆地理编码 :https://lbs.amap.com/api/webservice/guide/api/georegeo/

1.1地理编码 API 服务地址

  • restapi.amap.com/v3/geocode/…

商户进件→商户详情,重新定位,若输入的地址只有国家+市(例如:中国浙江),点击确定后,去请求第三方地理编码信息(高德API)的时候会转换失败,获取不到经纬度信息。 提示:【获取经纬度失败,请输入详细地址!】

1.2适用场景

  • 地理编码:将手动输入的详细的结构化地址转换为高德经纬度坐标。且支持对地标性名胜景区、建筑物名称解析为高德经纬度坐标。 1、结构化地址举例:北京市朝阳区阜通东大街6号转换后经纬度:116.480881,39.989410 2、地标性建筑举例:天安门转换后经纬度:116.397499,39.908722
  • 逆地理编码:将经纬度转换为详细结构化的地址,且返回附近周边的POI、AOI信息。 1、例如:116.480881,39.989410 转换地址描述后:北京市朝阳区阜通东大街6号

1.3 结构化地址信息 address请求参数的要求

  • 规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
  • 另外这个API的对地址的具体要求是: 结构化地址的定义: 首先,地址肯定是一串字符,内含国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦等建筑物名称。按照由大区域名称到小区域名称组合在一起的字符。一个有效的地址应该是独一无二的。注意:针对大陆、港、澳地区的地理编码转换时可以将国家信息选择性的忽略,但省、市、城镇等级别的地址构成是不能忽略的。暂时不支持返回台湾省的详细地址信息。
  • 需要对请求参数不准确,进行异常处理
if(dto.status.integerValue == 1){
// 获取经纬度 ,如果失败,提示【获取经纬度失败,请输入准确的经营地址!】






void (^noLocationdataBlock)(void) = ^void(void) {

[SVProgressHUD showInfoWithStatus:@"获取经纬度失败,请输入准确的经营地址!"];


};

// responseObject: {
// status = 1;
// info = OK;
// infocode = 10000;
// count = 0;
// geocodes = (
// );
if(dto.geocodes.count<=0){

noLocationdataBlock();
return ;
}

CRMgeocodesDto *geocodesDto = dto.geocodes.firstObject;

if([NSStringQCTtoll isBlankString:geocodesDto.location]){
noLocationdataBlock();

return ;


}

NSArray *array = [responseObject[@"geocodes"][0][@"location"] componentsSeparatedByString:@","];

if(array.count<=1){
noLocationdataBlock();

return;
}

1.4接口返回的格式

  • 返回的dto模型定义
  • location
"114.468664,38.037057";
2020-04-10 11:43:29.914038+0800 Housekeeper[943:136269] responseObject:  {
count = 1;
geocodes = (
{
adcode = 350503;
building = {
name = (
);
type = (
);
};
city = "\U6cc9\U5dde\U5e02";
citycode = 0595;
country = "\U4e2d\U56fd";
district = "\U4e30\U6cfd\U533a";
"formatted_address" = "\U798f\U5efa\U7701\U6cc9\U5dde\U5e02\U4e30\U6cfd\U533a\U5bcc\U5927\U53a6";
level = "\U5174\U8da3\U70b9";
location = "118.620285,24.908597";
neighborhood = {
name = (
);
type = (
);
};
number = (
);
province = "\U798f\U5efa\U7701";
street = (
);
township = (
);
}
);
info = OK;
infocode = 10000;
status = 1;
}

1.5 通过逆地理编码进行判断是否在大陆

通过经纬度进行判断。利用高德SDK进行判断。(​​如果是手动输入位置信息就进行逆地理编码获取经纬度​​)

/**
处理地理编码
*/
- (void)setupGeocode{

__weak __typeof__(self) weakSelf = self;

if (weakSelf.locationView.adressTextView.text.length > 0) {
[SVProgressHUD showWithStatus:@"定位中.."];
AFHTTPSessionManager *managers = [AFHTTPSessionManager manager];
managers.requestSerializer = [AFHTTPRequestSerializer serializer];

managers.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"text/plain",@"application/json",@"text/javascript",nil];



// NSString *urlStr = [NSString stringWithFormat:@"https://restapi.amap.com/v3/geocode/geo"];
NSString *urlStr = k_amap_geocode;


NSDictionary *dict = @{@"key" : @"" , @"address" : weakSelf.locationView.adressTextView.text};



[managers GET:urlStr parameters:dict progress:^(NSProgress * _Nonnull downloadProgress) {

NSLog(@"downloadProgress: %@",downloadProgress);
[SVProgressHUD dismiss];


} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {


NSLog(@"商户进件→商户详情,重新定位,若输入的地址只有国家+市(例如:中国浙江),点击确定后,去请求第三方地理编码信息(高德API)的时候会转换失败,获取不到经纬度信息。 提示:【获取经纬度失败,请输入详细地址!】 responseObject: %@",responseObject);

//status
// 返回结果状态值
// 返回值为 0 或 1,0 表示请求失败;1 表示请求成功


CRMgeoDto *dto = [CRMgeoDto mj_objectWithKeyValues:responseObject];

if(dto.status.integerValue == 1){
// 获取经纬度 ,如果失败,提示【获取经纬度失败,请输入准确的经营地址!】






void (^noLocationdataBlock)(void) = ^void(void) {

[SVProgressHUD showInfoWithStatus:@"获取经纬度失败,请输入准确的经营地址!"];


};

// responseObject: {
// status = 1;
// info = OK;
// infocode = 10000;
// count = 0;
// geocodes = (
// );
if(dto.geocodes.count<=0){

noLocationdataBlock();
return ;
}

CRMgeocodesDto *geocodesDto = dto.geocodes.firstObject;

if([NSStringQCTtoll isBlankString:geocodesDto.location]){
noLocationdataBlock();

return ;


}

NSArray *array = [responseObject[@"geocodes"][0][@"location"] componentsSeparatedByString:@","];

if(array.count<=1){
noLocationdataBlock();

return;
}


[weakSelf locotionRequestLat:array[1] Lon:array[0] adress:weakSelf.locationView.adressTextView.text];


[weakSelf.locationView.adressTextView resignFirstResponder];


weakSelf.locationView.frame = CGRectMake(0, kHeight, kWidth, KWratio(self.locationViewH));



weakSelf.bacV.hidden = YES;



}else{

[SVProgressHUD showInfoWithStatus:@"请输入准确的经营地址!"];

}

// if ([[NSString stringWithFormat:@"%@",responseObject[@"status"]]isEqualToString:@"1"]) {




// } else {



// }

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[SVProgressHUD showInfoWithStatus:@"网络错误!"];
}];
} else {
[SVProgressHUD showInfoWithStatus:@"请输入经营地址"];
}


}

II 腾讯位置服务:文字地址到经纬度的转换能力(webService)

lbs.qq.com/service/web…

API: ​​https://apis.map.qq.com/ws/geocoder/v1/?address=​

2.1 key的配置

问题:没有启用WebserviceAPI"

"message" : "此key未开启WebserviceAPI功能,您可登录lbs.qq.com,进入控制台key管理界面,找到此key并设置启用WebserviceAPI"

解决方式:


2.2 请求API

/**
处理地理编码:通过逆地理编码进行判断是否在大陆
//status 状态码,0为正常,其它为异常,
*/
- (void)setupGeocode:(NSString*)addressText block:(void (^)(CRMGeocoderDto* geocoder))block
{


NSString *urlStr = k_amap_geocode_Tencent;


NSMutableDictionary *params = [NSMutableDictionary dictionary];


[params setValue:self.locationManager.apiKey forKey:@"key"];
[params setValue:addressText forKey:@"address"];





[QCTNetworkHelper GETAPI:urlStr parameters:params success:^(NSDictionary* responseObj) {

void (^noLocationdataBlock)(void) = ^void(void) {

[SVProgressHUD showInfoWithStatus:@"获取经纬度失败,请输入准确的经营地址!"];


};

if(![responseObj.allKeys containsObject:@"result"]){
noLocationdataBlock();
return ;

}
NSDictionary *result = responseObj[@"result"];


CRMGeocoderDto *dto = [CRMGeocoderDto mj_objectWithKeyValues:result];


if(block){
block(dto);

}



} failure:nil bizFailure:nil isShowLoadingDataGif:YES];





}

2.3 返回数据

{
"status" : 0,
"message" : "query ok",
"result" : {
"location" : {
"lng" : 117.15011,
"lat" : 39.138150000000003
},
"address_components" : {
"district" : "南开区",
"street_number" : "",
"province" : "天津市",
"city" : "天津市",
"street" : ""
},
"similarity" : 0.80000000000000004,
"title" : "南开区",
"deviation" : 1000,
"ad_info" : {
"adcode" : "120104"
},
"level" : 2,
"reliability" : 1
}
}

see also

公众号:iOS逆向

标签:编码,dto,经纬度,void,iOS,地址,坐标,responseObject
From: https://blog.51cto.com/iosre/5719640

相关文章

  • 从几个开源项目浅谈IOS视频流输出方案
    IOS远程控制技术当中,最重要的环节是视频的输出,本文就目前出现的几种IOS视频流技术做一个实践和对比,重点会放在比较这几个方案在性能上的优缺点。方案分析IOS视频流方案,目前......
  • iOS小技能:金额格式处理 (货币符号本地化)
    引言iOS系统自带格式化NSFormatter的常用子类有:NSNumberFormatter(数字格式化)、NSDateFormatter(NSISO8601DateFormatter日期格式化)、NSPersonNameComponentsFormatter(名片格......
  • [iOS]遇到了一个问题:“XXXX”中无法使用Apple Pay ,检查此应用的设置并确定其设计可使
     在钥匙串里查看,发现当时申请的MerchantIDXXXX证书过期1.到apple开发者: https://developer.apple.com/account/#/overview/ 查看 Certificates,Identifiers......
  • ios(siri)控制windows的一种思路
    通过siri控制Windows可以解决一些远程控制场景。比如:睡觉前远程关闭电脑;语音(siri)控制电脑音量,控制应用运行等;具体实现:1.需要电脑开启sshserver,可以在Windows【设置】......
  • 使用iOS手势UIGestureRecognizer(转)
    UIKit中包含了UIGestureRecognizer类,用于检测发生在设备中的手势。UIGestureRecognizer是一个抽象类,定义了所有手势的基本行为,它有下面一些子类用于处理具体的手势:1、......
  • ios开发之app内起动用户评价 (转)
    ios开发之app内启动用户评价恰当的指引用户去给app评分是获得用户反馈的一种不错的途径。“通过customurlscheme启动应用程序”这篇文章里讲了通过url启动地图、邮件等程......
  • ios游戏发布流程
    这里假设你已经有苹果的开发者帐号了。其实早在两年前我就已经用过这个了,现在再回忆一下。因为苹果现在为开发者增加了macos的appstore发布权限,也增加了tvOS发布应用权限,......
  • 9、FFmpeg使用clion+mingw32编译学习y420p,yuv,rgb编码
    基本思想:继续学习ffmpeg基础知识第一步:进行y420p解码,然后将数据转rgb24格式,显示,重点学习了sws_getContext函数,可以通过他进行各种转码cmakelists.txt文件内容cmake_minimum_......
  • 自编码器
    自编码器构成编码器(Encoder)解码器(Decoder)目的将输入变量\(x\)编码为中间变量\(y\),再将中间变量\(y\)解码为输出变量\(\widetilde{x}\)对比输入\(x\)与输出......
  • vue3+vant+vue-router+axios+pinia+vite框架搭建
    vue3的官网地址:https://cn.vuejs.org/;这里要说一下,vue3不支持IE11,如果要兼容IE11及其一下,不建议使用vue3。创建vue脚手架,如果你需要使用ts,则需要node版本>=16。本文按照......