如何實現復雜的導航功能


本文要求讀者具備如下知識和技術背景:

1 熟悉Java開發,知道如何正確的編譯運行Java代碼;

2 知道GIS的基本概念,知道地圖導航的基本概念;

3 對GeoTools有一定的認識

 

一開始先來明確我們的任務:在基本的路徑查詢基礎上

1 實現單行道限制

2 實現左右拐彎限制

3 實現動態路況限制

4 選擇最短距離和最短時間

 

圖和圖的搜索

    要想了解路徑查詢的算法,首先得了解一下它的數學模型“圖”。簡而言之,圖就是一系列的點和點之間的連接關系。【Graph

    所謂路徑查詢,可以簡化成對一個圖的搜索。例如:從點6到點1的最短路徑是,6-4-5-1,或者6-4-3-2-1,又或者6-4-5-2-3-4-5-1。如你所見,從6到1之間可以有許多條路徑,其中第一條和第二條我們認為是合理的,第三條是不合理的,因為它有重復路段。所以查詢節點間路徑的算法就顯得至關重要了。經典的查詢算法有:Dijkstra和它的改進版本A*。這兩個算法的實現各種語言都有,也很成熟了,我們不需要自己去寫,但是最為一種訓練,有興趣的讀者可以自己試着實現。

    我在這里只介紹一下基本概念。從前面的例子我們看到兩點間可以有多條路徑,但是實際上我們一般只關心一條路徑,就拿開車來說,我們關心駕駛時間最少的路。一般情況下,實際距離短駕駛時間就少,所以我們先從實際距離入手。作為搜索算法如何確定距離最短呢。6-4-5-1一定比6-4-3-2-1距離短嗎。顯然我們不能僅僅根據節點的個數來判斷距離。事實是我們除了擁有點和點之間的連接外,還需要連接的屬性,這里就是距離。用上面的例子我們來指定距離:

6-4距離10

4-5距離7

5-1距離6

4-3距離2

3-2距離4

2-1距離1

6-4-5-1距離10+7+6=23

6-4-3-2-1距離10+2+4+1=17

    顯然第二條路雖然節點多但是距離短。這里需要引人一個概念“開銷”,在這個例子中目前我們使用路徑距離來代表開銷。我們總是選擇開銷小的路徑。現實中影響駕駛時間的因素除了距離還有道路擁堵情況,所以我們增加屬性,叫擁堵系數,假設距離乘上系數才是我們需要的開銷:

6-4距離10  擁堵1

4-5距離7   擁堵2

5-1距離6   擁堵1

4-3距離2   擁堵13

3-2距離4   擁堵11

2-1距離1  擁堵11

6-4-5-1距離10*1+7*2+6*1=30

6-4-3-2-1距離10*1+2*13+4*11+1*11=91

    可以看到,雖然第二條路的實際距離短,但是由於擁堵情況嚴重,它的開銷遠大於第一條路。在這種情況下我們應該選擇實際距離長的第一條路。我們可以不斷對上面的計算進行完善,增加更多的屬性來應對更復雜的實際情況。

 

分析任務

    有了上面的知識我們來看看我們的任務:

1 實現單行道限制

    我們可以給連接增加屬性叫“行駛方向限制”,有三個值,分別是:“正向通行”,“反向通行”,“雙向通行”。然后在計算開銷的時候,判斷當前方向是否與連接節點的方向一致,然后根據“行駛方向限制”的值來決定是否允許通行,如果不允許則返回一個極大值代表開銷。

2 實現左右拐彎限制

    在實現單行線的基礎上就可以實現拐彎限制,但是需要在數據制作上做文章:image

我們不能用一條線來代表一個路段,而應該用並行且方向相反的兩條線,這樣拐彎的地方也自然變成了單行線的一部分了。

3 實現動態路況限制

這個在上一節介紹圖的時候已經說明了不在贅述。

4 選擇最短距離和最短時間

這個在上一節介紹圖的時候已經說明了不在贅述。

 

代碼實現

代碼  路網數據

改程序要求:

1 路網數據是Shapfile格式保存的線段數據

2 屬性必須提供兩個:

  id  整數

  type 整數  只有三個值 1:正向通行;-1:反向通行;0:雙向通行

程序采用Java編寫,利用GeoTools 11軟件包中的graph擴展實現圖的搜索。程序啟動后需要先選擇路網數據,然后可見主界面,在主界面地圖上點擊設置起止位置。不同方向會選擇不同道路,如圖:

image image

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM