用户引导,根据经纬度和日期计算日出日落时间

2019-10-02 00:58栏目:专项工作
TAG:

在开发的过程中,偶尔会遇到需要在引导图上进行 镂空、画虚线,找了一下资料,写了下工具类,具体实现的效果如下。

直接计算日出和日落时间会比较复杂,可以通过计算当地的“正午”时间、当地的“白天”时长,用正午时间平分白天时长,得到当地的日出时间和日落时间。

首先我们来看一个iOS开发手动构建打包的故事......

ag真人 1Paste_Image.png

计算正午时间

一个地方的正午时间,可以通过当地经度与当地所属时区经度的差计算得到。全世界有24个时区,每个时区相隔1小时,因此每个时区之间相差的经度是 360 / 24 = 15°。已北京为例,北京所属时区为东8区,东8区的中心经度是15 * 8 = 120°(因此东8区的范围是112.5° - 127.5°)。

ag真人,北京的经度是116.46,与东8区中心相差 120 - 116.46 = 3.54,又因为1小时相当于15°,可得

时差 = 3.54 * 1 / 15 = 0.236 小时 = 14.16 分钟

地球是自西向东旋转,因此经度小于时区中心的位置,正午来得比时区中心要晚,正午时间是12:00

  • 时差

因此北京的正午时间应该是 12 + 0.236 = 12.236 小时

ag真人 2Paste_Image.png

ZZHollowUtil.h文件

计算白天的时长

ag真人 3图1

一个地方白天的时长,可以由一定角度下的太阳光照射出的昼夜分隔线(上图经过B点的斜线),切割这个地方的纬线比例得到。纬线一圈是24小时,根据切割比例就可以得出当地的白天时长。

ag真人 4图2

用直观一点的图2来解释,太阳以一定角度斜射地球,A地点此刻是正午,白天是B1-A-B2,夜晚是B1-C-B2,因此A点的白天时间为B1-A-B2所占的角度在24小时中的占比。

先来看图2的左边,假设上图中阳光入射角为α,A点的纬度为θ,根据三角函数可得:

O‘B / O'O = tanα

O'O / AO = sinθ

所以 O'O = AO * sin θ ,O'B = O'O * tanα = AO * sin θ * tanα

再看图2的右边,是这个纬度截面的平面图:

已知 O'B = r * sin θ * tanα

O'B1 是这个纬度截面的圆的半径 r',这个半径的计算方法在上篇计算经纬度距离的文章中已经给出:r' = r * cosθ

因此 O'B1 与 O'B 的夹角 cosβ = O'B / O'B1,这样我们就能计算出β

最终可以得到:A点的白天角度 = (360 - β * 2) A点的白天时间 = A点的白天角度 / 360 * 24

为了进行上面这些计算,需要知道A点阳光入射角为α

就如大家熟悉的,我们平常手动打包都要经历更新代码、更新build version、使用Xcode Archive出IPA包。然后如果是内测包就保存到本地,如果要使用内测分发网站,就要上传到相应的网站并配置好相应的参数;如果是上传TestFlight或者App Store包则直接上传。这一套下来,偶尔做做还觉得没什么,如果是遇到频繁修改需求、调整UI、修复BUG,又或者是同时有好几个任务分支需要分别打包的时候,就会十分抓狂了,最后不能自拔,堕落深渊。

#import <Foundation/Foundation.h>/** 这个类用来镂空UIView,并且在镂空部分边缘添加虚线 注意: 一个UIView 只能调用一次 -addHollowWithPath:inView: ,否则会有冲突,显示效果上会有问题 建议: 将需要镂空的路径,用UIBezierPath 的 -appendPath: 方法加在一起,再调用。 -addLineWithCGPath:inView: 可以多次调用 例如: UIBezierPath *path = [UIBezierPath bezierPath]; [path appendPath:path_0]; [path appendPath:path_1]; [ZZHollowUtil addHollowWithPath:path inView:self]; [ZZHollowUtil addLineWithCGPath:path_1.CGPath inView:self]; [ZZHollowUtil addLineWithCGPath:path_2.CGPath inView:self]; */@interface ZZHollowUtil : NSObject// 镂空+ addHollowWithPath:(UIBezierPath *)path inView:view;// 画虚线 默认:黑白相间+ addLineWithCGPath:(CGPathRef)path inView:view;+ addLineWithCGPath:(CGPathRef)path stockerColor:(UIColor *)stokerColor fillColor:(UIColor *)fillColor inView:view;@end

计算阳光入射角α

阳光入射角α是太阳光线与地球赤道面的夹角,春分和秋分时α = 0,夏至时α = 23°27′,冬至时α = - 23°27′。因为1年有365天(暂时忽略闰年的误差),春分、夏至、秋分、冬至把365天分为4个部分,因此可以根据具体日期,得到这个日期的α。

ag真人 5Paste_Image.png

ZZHollowUtil.m文件

最后,举个例子

以北京,5月25日为例,落在春分到夏至的区间内,是春分过后65天。而春分到夏至一共有92天,这个区间已经过去了65%,因此可以计算得出5月25日的 α = 23°27′ * 0.71 = 16.65

北京的经度:116.46,纬度:39.92,5月25日太阳光与赤道的夹角 α = 16.65

代入上面的公式:

O'B = r * sin θ * tanα = r * sin 39.92 * tan 16.65

O'B1 = r' = r * cosθ = r * cos 39.92

cosβ = O'B / O'B1 ; β = arccos(O'B / O'B1) = arccos(r * sin 39.92 * tan 16.65 / r * cos 39.92)

北京白天在纬度切面所占的角度 = (360 - β * 2)

北京白天在纬度切面所占的时间 = (360 - β * 2) / 360 * 24 = 208.96 / 360 * 24 = 13.93 h

又根据上面的计算,北京的实际正午时间是 12.236小时

日出时间 = 12.236 + 13.93 / 2 = 5.27,大约是 05:16

日落时间= 12.236 - 13.93 / 2 = 19.201,大约是 19:12

难道就这样了吗?就只能这样屈服于可恶的现实吗?不!我们要直面惨淡的人生,敢于挑战种种操蛋的困难!在这里,我要向大家传授一套“组合拳”,虽然不像军体拳一样能够克制女子防狼术,但是确实能大大减轻苦逼iOS开发们的工作,提升效率。

#import "ZZHollowUtil.h"@implementation ZZHollowUtil+ addHollowWithPath:(UIBezierPath *)path inView:view { dispatch_async(dispatch_get_main_queue(), ^{ UIBezierPath *aPath = [UIBezierPath bezierPathWithRect:view.bounds]; [aPath appendPath:[path bezierPathByReversingPath]]; //创建出CAShapeLayer CAShapeLayer *shapeLayer = [CAShapeLayer layer]; //让贝塞尔曲线与CAShapeLayer产生联系 shapeLayer.path = aPath.CGPath; //添加并显示 [view.layer setMask:shapeLayer]; });}+ addLineWithCGPath:(CGPathRef)path inView:view { [self addLineWithCGPath:path stockerColor:[UIColor whiteColor] fillColor:[UIColor blackColor] inView:view];}+ addLineWithCGPath:(CGPathRef)path stockerColor:(UIColor *)stokerColor fillColor:(UIColor *)fillColor inView:view{ CAShapeLayer *border = [CAShapeLayer layer]; border.strokeColor = stokerColor.CGColor; border.fillColor = fillColor.CGColor; border.path = path; border.frame = view.bounds; border.lineWidth = 2.f; border.lineCap = @"square"; border.lineDashPattern = @[@6, @4]; [view.layer addSublayer:border];}@end

备注

以上方法只能得到一个粗略的日出日落时间,与实际时间有比较大的误差,仅用于理解日出日落时间的计算方法。

  • Git: 管理代码,这里我使用OSChina的git仓库服务;
  • Jenkins: 提供构建平台,从git仓库拉取代码、更改build version、调用fastlane;
  • Fastlane: 构建代码、打包、上传
  • Fir: 内测分发网站

版权声明:本文由ag真人发布于专项工作,转载请注明出处:用户引导,根据经纬度和日期计算日出日落时间