目錄:
- 一勾徽、問題出現(xiàn)場景
- 二、常見的計算里程方法
1统扳、最土及常見的計算里程方法
2捂蕴、初步優(yōu)化方案:
3、正確的判斷/解決飄的問題
4闪幽、更多關于解決隧道里定位會飄的問題
5啥辨、其他里程計算方法(后續(xù)補充) - 三、CLLocation詳解
前言
如果你的app不追求深度盯腌、精確度溉知,請略過本文章。
一腕够、問題出現(xiàn)場景
路測级乍,里程計算不準確。WTF帚湘。玫荣。。什么場景會有這種需求大诸?捅厂??
答:如果你做的app是一款如滴滴司機端一樣资柔,需要計算從接乘客上車到將乘客送達焙贷,乘客下車的這段長距離的里程值的時候,相信你就會有本文所要講的里程計算問題了贿堰。
二辙芍、常見的計算里程方法
1、最土及常見的計算里程方法
通過兩點位置,計算距離故硅,累積相加得到最后的里程值庶灿。
- 會出現(xiàn)的問題:
定位飄了怎么辦?如海底隧道燈弱信號地方吃衅。
2往踢、初步優(yōu)化方案:
加上定時器,通過定時器時間及兩點距離對該時間內的時速做判斷捐晶,超過閾值菲语,認為當前點無效妄辩,取下一個點跟上一個有效點比較惑灵。
- 會出現(xiàn)的問題:
判斷錯誤,因為雖然定時器的時間都是增加的眼耀,但是定位給出的位置英支,有可能是我們之前給的位置。即可能出現(xiàn)如下返回的位置信息:
<+24.50999425,+118.18279171> +/- 10.00m (speed 8.95 mps / course 158.55) @ 17/6/23 中國標準時間17:37:48
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
<+24.50910223,+118.18314439> +/- 10.00m (speed 8.32 mps / course 166.99) @ 17/6/23 中國標準時間17:37:59
<+24.50317363,+118.18252758> +/- 10.00m (speed 10.28 mps / course 198.28) @ 17/6/23 中國標準時間17:39:04
<+24.50280620,+118.18241544> +/- 10.00m (speed 10.81 mps / course 189.49) @ 17/6/23 中國標準時間17:39:08
//>>>這里開始異常了(飄回了一個之前好久定位到的點)
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
<+24.50958770,+118.18296699> +/- 10.00m (speed 9.96 mps / course 160.66) @ 17/6/23 中國標準時間17:37:53
//<<<這里結束異常了
<+24.50187348,+118.18212644> +/- 10.00m (speed 10.47 mps / course 197.23) @ 17/6/23 中國標準時間17:39:19
<+24.50145111,+118.18199236> +/- 10.00m (speed 9.20 mps / course 195.82) @ 17/6/23 中國標準時間17:39:24
仔細觀察數據會發(fā)現(xiàn):
所以哮伟,通過兩點位置所得的距離干花,加上定時器時間間隔來判斷點是否有效的方法是錯誤的。
那么問題來了楞黄,既然不能使用定時器的時間間隔池凄,那兩點之間所用的時間怎么算?答應該采用CLLocation里面的timestamp來計算時間差鬼廓。
3肿仑、正確的判斷/解決飄的問題
從上我們知道,在隧道里由于定位會飄的問題碎税,所以定位給出的位置尤慰,有可能是我們之前給的位置。所以我們不能采用自己約定的時間差(一般是計時器)來計算時速雷蹂。
仔細觀察如下參考數據:
上次計算地點為:<+24.52033493,+118.19203987> +/- 373.66m (speed -1.00 mps / course -1.00) @ 17/6/23 中國標準時間16:51:27
本次計算地點為:<+24.56114169,+118.22883818> +/- 2000.00m (speed -1.00 mps / course -1.00) @ 17/6/23 中國標準時間16:52:17
我們得出伟端,其實每個定位點CLLocation是有帶該點的時間的。所以雖然計算兩點的時速的時候匪煌,不能采用自己的時間差责蝠,但是可以采用CLLocation里面的timestamp來計算時間差,這也才是正解萎庭。即:我們應該判斷最新的位置的時間timestamp是不是比上次的timestamp大玛歌。否則,該點就是我們之前已經獲取到的點擎椰,而不是當前時間的最新點支子。
4、更多關于解決隧道里定位會飄的問題
更完善的過濾方法可參考:iOS定位服務达舒,無效/不準確位置的過濾
5值朋、其他里程計算方法
后續(xù)補充叹侄,待完善。昨登。趾代。。丰辣。撒强。
三、CLLocation詳解
CLLocation值修改笙什?
CLLocationCoordinate2D chongQingCoordinate = CLLocationCoordinate2DMake(29.554941, 106.55329); //重慶市
CLLocation *chongQingLocation = [[CLLocation alloc] initWithLatitude:chongQingCoordinate.latitude longitude:chongQingCoordinate.longitude];
self.location = chongQingLocation;
其他基本知識
精確度設置
設置代理后飘哨,你還要設置需要的準確度。就像我們剛剛說的精確度越高越耗電琐凭。如果你只是要是應用程序確定是哪個國家或是哪個州那么就不要設置很高的精確度芽隆。記住一點有時候你并不能得到你需要的精確度。
下面說一個設置代理和設置精確度的例子:
locationManager.delegate = self;
locationManager.desiredAccuracy =kCLLocationAccuracyBest;
精確度使用的是一個double類型的常量统屈。單位是米胚吁,所以如果你設置desiredAccuracy=10那么精確度就是10米,這就告訴 Location Manager盡可能達到10米的精確度愁憔。還可以設置為其他常量:
多久調用一次代理
默認情況是這樣的,每當位置改變時Location Manager就調用一次代理腕扶。
而通過設置distance filter可以實現(xiàn)當位置改變超出一定范圍時Location Manager才調用相應的代理方法。這樣可以達到省電的目的吨掌。
例如:locationManager.distanceFilter =1000.0f;
附設置默認值的方法是:
locationManager.distanceFilter =kCLDistanceFilterNone;
Error Notifications
如果Core Location不能指定你當前的位置半抱,它將調用CLLocation的第二個代理方法:locationManager:didFailWithError:,最常見的是用戶取消使用定位信息思犁。
獲取定位的信息
①獲取經緯度
CLLocationDegrees latitude =theLocation.coordinate.latitude;
CLLocationDegrees longitude =theLocation.coordinate.longitude;
②獲取這個定位點是什么時間定到的
NSDate *timestamp = theLocation. timestamp;
CLLocation的另一個屬性timestamp用來告訴Location Manager是什么時候定位的代虾。
③獲取海拔altitude
CLLocationDistance altitude = theLocation.altitude;
海拔值可能會有誤差。
@property(readonly, nonatomic) CLLocationAccuracy horizontalAccuracy;//水平的精確度(負數無效)
@property(readonly, nonatomic) CLLocationAccuracy verticalAccuracy; //垂直的精確度(負數無效)
所以每一個CLLocation對象都有一個叫verticalAccuracy的屬性來判斷精確度激蹲。其表示海拔數值可能會有verticalAccuracy大小的誤差棉磨,當verticalAccuracy為負值時,那是Core Location在通知你不能獲取海拔高度学辱。
horizontalAccuracy屬性描述調整的中心點乘瓤。horizontalAccuracy值越大越不精確。
計算兩點的距離
CLLocationDistance distance =[fromLocation getDistanceFrom:toLocation];
返回兩個時間段內的距離策泣,有時候它是不考慮海拔的衙傀,所以要自己計算距離。
CLLocation的其他屬性
//航向 萨咕、路徑 取值為:0.0 ~ 359.9 真北方向表示:0.0
@property(readonly, nonatomic) CLLocationDirection course ;
//速度 m/s
@property(readonly, nonatomic) CLLocationSpeed speed ;
//時間
@property(readonly, nonatomic, copy) NSDate *timestamp;
//顯示樓層的信息统抬,如果當地支持的話
@property(readonly, nonatomic, copy) CLFloor *floor ;
//CLFloor中的一個屬性,顯示低第幾層樓
@property(readonly, nonatomic) NSInteger level;
//位置的描述,一般的對象都是可以調用這個屬性來顯示字符描述
@property (nonatomic, readonly, copy) NSString *description;
End
結束聪建!