iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合
1.地图坐标转换那些事
(1)投影坐标系与地理坐标系
地理坐标系使用三维球面来定义地球上的位置,单位即经纬度。但经纬度无法精确测量距离戒面积,也难以在平面地图戒计算机屏幕上显示数据。通过投影的方式可以将其转换成平面的投影坐标系,不同的投影方式可能会带来不同的变形及误差,类似于把一个橘子的橘子皮剥开摊平到桌面。




GPS以及iOS系统定位获得的坐标是地理坐标系WGS1984,Web地图一般用的坐标细是投影坐标系WGS 1984 Web Mercator,国内出于相关法律法规要求,对国内所有GPS设备及地图数据都进行了加密偏移处理,代号GCJ-02,这样GPS定位获得的坐标与地图上的位置刚好对应上,特殊的是百度地图在这基础上又进行一次偏移,所以在处理系统定位坐标及相关地图SDK坐标时需要转换处理下,根据网络资源,目前有一些公开的转换算法。
(2)系统定位坐标显示在原生地图、谷歌地图或高德地图--WGS1984转GCJ-02
苹果地图及谷歌地图用的都是高德地图的数据,所以这三种情况坐标处理方法一样,即将WGS1984坐标转换成偏移后的GCJ-02才可以在地图上正确显示位置。
const double a = 6378245.0;
const double ee = 0.00669342162296594323; + (CLLocationCoordinate2D)transform:(CLLocationCoordinate2D) latLng
{
double wgLat = latLng.latitude;
double wgLon = latLng.longitude;
double mgLat;
double mgLon; if ([self outOfChina:wgLat :wgLon ])
{
return latLng;
}
double dLat = [self transformLat:wgLon-105.0 :wgLat - 35 ];
double dLon = [self transformLon:wgLon-105.0 :wgLat - 35 ]; double radLat = wgLat / 180.0 * M_PI;
double magic = sin(radLat);
magic = 1 - ee * magic * magic;
double sqrtMagic = sqrt(magic);
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * M_PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * cos(radLat) * M_PI);
mgLat = wgLat + dLat;
mgLon = wgLon + dLon;
CLLocationCoordinate2D loc2D ;
loc2D.latitude = mgLat;
loc2D.longitude = mgLon; return loc2D;
} + (BOOL) outOfChina:(double) lat :(double) lon
{
if (lon < 72.004 || lon > 137.8347) {
return true;
}
if (lat < 0.8293 || lat > 55.8271) {
return true;
}
return false;
} + (double) transformLat:(double)x :(double) y
{
double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y +
0.2 * sqrt(fabs(x));
ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 *sin(2.0 * x *M_PI)) * 2.0 /
3.0;
ret += (20.0 * sin(y * M_PI) + 40.0 *sin(y / 3.0 *M_PI)) * 2.0 / 3.0;
ret += (160.0 * sin(y / 12.0 * M_PI) + 320 *sin(y * M_PI / 30.0)) * 2.0 /
3.0;
return ret;
} + (double) transformLon:(double) x :(double) y
{
double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(fabs(x));
ret += (20.0 * sin(6.0 * x * M_PI) + 20.0 * sin(2.0 * x * M_PI)) * 2.0 /
3.0;
ret += (20.0 * sin(x * M_PI) + 40.0 * sin(x / 3.0 * M_PI)) * 2.0 / 3.0;
ret += (150.0 * sin(x / 12.0 *M_PI) + 300.0 *sin(x / 30.0 * M_PI)) * 2.0 /
3.0;
return ret;
}
(3)使用百度地图SDK
使用百度地图SDK,定位也使用sdk中提供的方法,则获得坐标是百度在GCJ-02基础上再一次偏移的坐标,如果要将定位坐标显示在苹果地图上,则需要转换成GCJ-02下的坐标,JZLocationConverter提供了三种坐标间的转换方法,
(4)参考
2.block引用循环及检测方法&weak–strong dance
使用block需要注意避免引用循环造成内存问题,如图所示,对于strong属性的property或者复用的cell,都是被self持有或者说强引用的,在使用block回调前,需要将self声明为一个weak类型的weakSelf再进行使用,否则将造成引用循环。


但并不是所有block回调处理中都需要使用weakSelf,例如self并没有强引用vc,在vc里使用self,是不会造成引用循环的。

对于类似这种可能造成引用循环的地方,使用Instrumens的Leaks工具是检测不出来的,比较便捷的方法是在controller检测“dealloc”是否执行,当然也有可能是其它原因造成,但只要有引用循环发生则controller肯定无法释放,“dealloc”也是无法执行的。
当然,这是一般情况,有一些特殊情况例如多线程下block,block里的weak变量执行指令前可能已经被释放掉了,这时可以对其__strong 一下,这样系统会在block执行完成后再释放该变量。
3.UICollectionviewLayout及瀑布流
目前用到了一些第三方的UICollectionviewLayout类库,例如CSStickyHeaderFlowLayout,提供header悬停及下拉放大的视差效果等
通过自定义UICollectionviewLayout可以灵活自定义很多布局效果,以经典的瀑布流为例。

其特点是cell的高度不一致,首尾间隔要保持一致,如此一来就需要自定义layout来调整cell的布局位置。
这里cell高度随机生成为40-140之间的数值。

(1)计算并缓存相关布局信息

重点是计算布局这里,第一行Y值都相同,但后续每个cell的高度不同,需要去调整cell的位置,首先找到目前高度最小的那一列(排列第一行时,所有cell的Y值一致,将第一列当做高度最小的一列或者将顶部间距看成是一行高度一致的cell),将cell排列在此列下方,并更新此列的Y值,然后再继续找高度最小的一列,将cell排列在其下方并更新此列Y值,以此类推,不断寻找高度最小的那一列,将后续cell排列在其下方并更新这一列的Y值,即可完成布局,当然设置cell布局时还要将cell之间的间隔考虑进去。
(2)计算contentSize并生成布局
contentSize中关键是高度,这里取高度最大那一列的Y值即为collectionview的高度。

(3)参考
4.图层混合
使用Instruments中的Core Animation工具能够检测图层渲染和动画的相关问题,包括图层混合问题,即当多个图层叠加在一起,颜色不同时,处理这样的颜色混合情况会消耗GPU资源,监测发现这些区域会变红,其它正常区域为绿色

对于UILabel的图层混合问题,将其设置为与背景色一致并裁剪即可。(不会产生离屏渲染)

iOS开发笔记15:地图坐标转换那些事、block引用循环/weak–strong dance、UICollectionviewLayout及瀑布流、图层混合的更多相关文章
- iOS开发笔记6:图片轮播及其无限循环效果
平时APP中的广告位或者滚动的新闻图片等用到的就是图片轮播这种效果,实现方式主要有两种,一种是ScrollView+ImageView,另一种则是通过CollectionView,今天总结的是Scro ...
- iOS开发小技巧--键盘处理以及解决block造成循环引用的小技巧
- iOS开发笔记--什么时候调用layoutSubviews
iOS开发笔记--什么时候调用layoutSubviews 分类: iOS2014-04-22 16:15 610人阅读 评论(0) 收藏 举报 今天在写程序时候遇见layoutSubviews触发时 ...
- 【Swift】iOS开发笔记(二)
前言 这个系列主要是一些开发中遇到的坑记录分享,有助于初学者跨过这些坑,攒够 7 条发一篇. 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯 ...
- 那些在学习iOS开发前就应该知道的事(part 2)
英文原文:Things I wish I had known before starting iOS development—Part 2 http://www.cocoachina.com/ios/ ...
- iOS开发笔记7:Text、UI交互细节、两个动画效果等
Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...
- iOS开发笔记-两种单例模式的写法
iOS开发笔记-两种单例模式的写法 单例模式是开发中最常用的写法之一,iOS的单例模式有两种官方写法,如下: 不使用GCD #import "ServiceManager.h" ...
- IOS开发笔记(4)数据离线缓存与读取
IOS开发笔记(4)数据离线缓存与读取 分类: IOS学习2012-12-06 16:30 7082人阅读 评论(0) 收藏 举报 iosiOSIOS 方法一:一般将服务器第一次返回的数据保存在沙盒里 ...
- IOS开发笔记 IOS如何访问通讯录
IOS开发笔记 IOS如何访问通讯录 其实我是反对这类的需求,你说你读我的隐私,我肯定不愿意的. 幸好ios6.0 以后给了个权限控制.当打开app的时候你可以选择拒绝. 实现方法: [plain] ...
随机推荐
- Java -- 获取当前日期、当月月初日期、月末日期
Learn From:http://blog.csdn.net/sunhuwh/article/details/39161323 public class CalendarTest { public ...
- [c++] Collection of key and difficult points
Operator Overload 1. 在重载下标运算符时(数组符号):不可重载为友元函数,必须是非static类的成员函数. why 2. overload ++ 时,如果是: int a; ...
- 利用栈实现算术表达式求值(Java语言描述)
利用栈实现算术表达式求值(Java语言描述) 算术表达式求值是栈的典型应用,自己写栈,实现Java栈算术表达式求值,涉及栈,编译原理方面的知识.声明:部分代码参考自茫茫大海的专栏. 链栈的实现: pa ...
- 关于python中赋值、浅拷贝、深拷贝之间区别的深入分析
当重新学习了计算机基础课程<数据结构和算法分析>后再来看这篇自己以前写的博文,发现错误百出.python内置数据类型之所以会有这些特性,归根结底是它采用的是传递内存地址的方式,而不是传递真 ...
- C#设计模式——单件模式(Singleton Pattern)
一.概述在软件开发过程中,我们有时候需要保证一个类仅有一个实例,比如在一个电脑用户下只能运行一个outlook实例.这时就需要用到单件模式.二.单件模式单件模式保证一个类仅有一个实例,并提供一个访问它 ...
- C#获取url中参数键值对的方法
方法如下: /// <summary> /// 遍历Url中的参数列表 /// </summary> /// <returns>如:(?userName=keley ...
- ActiveReports 9 新功能:借助目录(TOC)控件为报表添加目录功能
在最新发布的ActiveReports 9报表控件中添加了多项新功能,以帮助你在更短的时间里创建外观绚丽.功能强大的报表系统,本文将重点介绍新增文档目录控件(TOC),通过拖拽操作便可添加报表目录. ...
- [PHP] java读取PHP接口数据
和安卓是一个道理,读取json数据 PHP文件: <?php class Test{ //日志路径 const LOG_PATH="E:\phpServer\Apache\logs\\ ...
- [python学习笔记]Day3
函数 如: def is_leapyear(year): if (year%4 == 0 and year%100 != 0) or (year%400 == 0): return True else ...
- Linux Shell系列教程之(十二)Shell until循环
本文是Linux Shell系列教程的第(十二)篇,更多Linux Shell教程请看:Linux Shell系列教程 在上两篇文章Linux Shell系列教程之(十)Shell for循环和Lin ...