直接正題,沒得BB
首先說明一下室內定位從架構上嚴格來講分為3步:
1、室內地圖以及室內地圖能相關的一些成熟API
2、以任意方式來獲取室內定位的坐標
3、將室內定位的坐標轉化成室內地圖的API或者一種能兼容兩者的轉換方式
(可選)4、定位穩定性的濾波處理,試定位坐標點不出現 跳點、卡頓、掉幀、北偏角指向性錯誤等影響用戶體驗的處理方案
目前市場中室內定位資源比較散亂,主要分為地圖供應商和定位服務商兩種,也有將室內定位資源合並的企業,比如 某石科技
所以要是想對室內定位有研究的最好還是需要多方了解提供商的SDK相關信息
最近我們公司的室內定位項目馬上殺青了,才有空寫個博客散散心,總結一下iOS開發中踩過的坑:
1、手機端地圖出現黑色無色模型,Web端出現透明模型。
2、路徑導航無法規划路線。
3、無法繪制路徑/SDK的相關方法/對象不執行。
4、地圖對象創建后未銷毀,造成第二次地圖對象在規划路徑的時候閃退、崩潰。
5、地圖圖標出現黑塊。
6、返回上一級界面后未執行dealloc方法。
7、路徑繞遠。
8、U型彎道或L型彎道在路網吸附的模式下路過會出現跳點。
9、地圖加載失敗。
10、地圖的繪制/解析慢。
========================分割線=========================
我的解決方案:
1、手機端地圖出現黑色無色模型,Web端出現透明模型。
原因:這個是因為主題不兼容造成的,地圖在SDK解析過程中根據資源包已經賦予其顏色屬性了,如果沒有相關資源包就默認為黑色
我使用的是蜂鳥視圖,我們地圖屬性和顯示是經過定制的,所以使用常規的主題就會造成黑塊模型的出現。
WEB端JS的SDK做過相關處理,所以展示只是透明的模型。
解決:與其相關開發人員溝通,重新更新一個定制的主題即可。
2、路徑導航無法規划路線。
原因:因為沒有相關路網能抵達終點,路網的結構大致是這樣的:
黑色區域是可到達的路網,紅色是禁止掉的路網。明白了吧,如果終點的附近沒有黑色路網,那么就代表這個點位是無法到達的
具體附近是多少,請注意供應商的API文檔說明
解決:要和相關地圖供應商聯合解決這個問題,因為具體有那些點位可達/不可達,最好去實地勘探一下。
3、無法繪制路徑/SDK的相關方法/對象不執行。
原因:請核對和官方的工程配置的做法是否有出入的地方,我出現這個原因是因為Other Linker Flags 中有個-ObjC錯寫成-Objc了,
C必須是大寫,要么XCode編譯器不會全編譯框架中的OC文件,編譯確實無錯,但是一旦調用相關API的時候,這個API會引起崩潰等風險。
解決:Other Linker Flags 中添加-ObjC,大小寫要分清
4、地圖對象創建后未銷毀,造成第二次地圖對象在規划路徑的時候閃退、崩潰。
原因:上一個地圖對象成為了僵屍對象,在執行規划路線/或者其他操作的時候同時操作了僵屍對象,這個在崩潰的時候會有日志:
“你操作了一個不可操作的對象/指針”
解決:不管怎么使用地圖視圖對象,一定要在這個VC地圖界面推出棧的時候(我用的push方法)查看是否執行dealloc方法,
如果沒有,最好在點擊退出的一瞬間將全部View remove掉,包括地圖視圖和相關View對象,然后指針置空,一定保證執行了dealloc。
保證程序穩定的情況下才能做更多事。
5、地圖圖標出現黑塊。
原因:這個說起來很尷尬=。= 因為需求中有一個模擬導航,需要模擬這個定位點一點點移動在線路上,並且行走等事件。
是吧、、肯定用到了NSTimer啊。。。所以這個原因是因為在另一種我沒想到的邏輯下退出界面,導致Timer沒被銷毀和暫停。
然后呢,地圖又是OpenGL繪制的。。在下一次進入地圖界面的時候,Timer占用了一個子線程,導致OpenGL一直沒時間去繪制圖標
導致地圖一些元素顯示成了黑塊。。
解決:一定要統計有幾種退出界面的方法,然后封裝一個安全的方法(就是在不釋放空對象的前提下能kill掉Timer),
在每種情況下退出界面都要執行這個能安全的kill掉Timer的方法,最后一定要監督dealloc方法的執行與否。
6、返回上一級界面后未執行dealloc方法。
原因:之前也提過很多了,主要是SDK中一些對象與主控制器的強引用造成的,這種很常見,要養成隨時查看dealloc的習慣。
有些人會想了:現在不都ARC了么?誰還會關心這些啊?
這樣想很不對,ARC可以為開發者節省很多代碼,使用ARC以后再也不需要關心什么時候retain,什么時候release,
但是這並不意味你可以不思考內存管理,你可能需要經常性地問自己這個問題:誰持有這個對象?
解決:注意哪些是Strong引用的對象再被操作,什么時候把他置nil,保證能降低一個內存開銷,性能上也是有很大的提升。
7、路徑繞遠。
原因:因為路網稀疏,導致想到達一個終點必須按照路網的規划來走,有興趣的可以研究一下dijstra算法,
這個是大部分主流地圖/導航的一個解決方案。
路網稀疏,只能這么走:
路網原因繞的遠,不怪你不怪SDK,只怪地圖路網沒設計好。
解決:當然是與供應商溝通咯=。=。。程序又做不了什么。。。。
8、U型彎道或L型彎道在路網吸附的模式下路過會出現跳點。
原因:因為路徑吸附的原理是判斷你的定位點在路徑周邊大概多少米之內,將點位強制吸附到路徑上
遇到U型彎道/L型彎道就會出現兩個判定,,說白了就是兩條路吸附范圍發生重疊造成的判定混亂。。懂了吧 =。=
解決:還是溝通咯。。只能讓他們把路網規划的更密一些,減少U型彎道的產生,至於L型么。。。小跳而已
誰也不會全程盯着手機看吧。。室內導航。。抬抬頭就能知道該咋走了,,我就跳跳 =。=
9、地圖加載失敗。以及 10、地圖的繪制/解析慢。
原因:因為整個地圖文件是經過混淆的,而且解析引擎是C++(蜂鳥視圖),解析完后再OpenGL繪制。。
聽着都繁瑣=。=。。當然慢了。。而且整個SDK流程是必須先經過認證后才能獲得解析權限。。當然慢咯。。
解決:沒辦法。。但是可以把解析和UI操作分開來做:
先解析地圖,然后頁面隨便展示一個 HUB或者Toast或者小菊花等等。。表示我們正在瘋狂的畫地圖。。。
然后設置兩個回調,一個地圖成功和失敗:
這個BOOL是在地圖解析完后,准備執行下一個操作的時候的限制判斷
如果解析成功則執行UI的創建和添加等等。。。如果失敗則顯示一個加載失敗的圖片。
注意,最后我是將所有操作全部回調到了主線程來執行的。。
這樣就可以不卡死主線程的情況下先推出界面,同時進行解析、解析完成后再將地圖添加到視圖,失敗了就展示失敗的頁面就好。
如果把解析(就是地圖的構造方法)放在ViewDidLoad中,會卡死主線程1~8秒不等。。。這樣肯定行不通的,比較平滑的處理先暫時只能這樣。。
養成注釋的習慣最好=。= 維護和二次開發的時候會很方便 =。=
曬一張我的一個主繼承對象的h文件=。=
被人吐槽成把項目當SDK做。。
最后=。= Axc大法好。。。。