基于GeoTools和SpringBoot的省域駕車最快路線規(guī)劃方法
前言
在當今數(shù)字化時代,地理信息系統(tǒng)(GIS)技術與現(xiàn)代交通出行需求的深度融合正不斷催生出諸多創(chuàng)新應用,其中駕車路線規(guī)劃作為人們日常出行中極為關鍵的一項服務,其重要性愈發(fā)凸顯。無論是長途旅行、商務出差,還是日常通勤,人們都渴望能夠獲取到一條既快速又高效的駕車路線,以節(jié)省寶貴的時間成本。而基于 GeoTools 和 SpringBoot 的省域駕車最快路線生成實踐,正是在這一背景下應運而生的前沿探索,它不僅匯聚了先進開源地理空間工具與高效微服務框架的雙重優(yōu)勢,更是為解決大范圍區(qū)域內復雜路況下的最優(yōu)路線規(guī)劃問題提供了全新的思路與方法。
推薦閱讀:使用SpringBoot整合高德地圖實現(xiàn)路線規(guī)劃功能

本次實踐聚焦于省域這一相對較大范圍的地理區(qū)域,相較于城市內部的路線規(guī)劃,省域駕車路線面臨著更多的挑戰(zhàn)。省域內道路網(wǎng)絡更為復雜,涵蓋了高速公路、國道、省道以及鄉(xiāng)村道路等多種類型,不同道路之間的連接關系、通行規(guī)則以及路況信息差異巨大。與常規(guī)的兩點之間直線最短的計算方式不同,在兩個城市的行車距離計算中,往往兩者的距離會超出直線距離。因此我們通過駕車距離的長短來衡量與省會城市的聯(lián)系度,也可以作為衡量交通對地域經濟影響的因素評估做參考。同時,省域范圍內的地理環(huán)境多樣,山脈、河流、湖泊等自然地理要素對路線的選擇也會產生重要影響。此外,跨區(qū)域的交通流量分布不均,節(jié)假日、特殊事件等還會引發(fā)交通流量的大幅波動,這些都使得省域駕車最快路線的生成難度大幅提升。然而,正是這些復雜多變的因素,也為基于 GeoTools 和 SpringBoot 的路線規(guī)劃實踐提供了豐富的應用場景和極具價值的研究課題。
在接下來的章節(jié)中,我們將逐步展開對基于 GeoTools 和 SpringBoot 的省域駕車最快路線生成實踐的詳細闡述,從理論基礎到實踐操作,從技術實現(xiàn)到系統(tǒng)優(yōu)化,全方位地呈現(xiàn)這一項目的全貌。讓我們一同踏上這段充滿挑戰(zhàn)與機遇的探索之路,開啟一場關于地理空間技術與交通出行服務融合創(chuàng)新的精彩旅程。
一、相關空間表簡介及設計
本節(jié)將重點介紹需要使用到的一些基礎空間表和用于存儲省級城市距離的空間表信息。通過本節(jié)的講解,讓大家知曉如何進行省級地市的信息查詢。同時了解如何去存儲省級城市距離及其路線信息。而這條路線信息在存儲下來以后就可以在后續(xù)的分析中進行展示。因此將這部分內容放到第一節(jié)來講解,是一個基礎內容。
1、相關基礎空間表
為了查詢省會城市還有其他的地級城市,這里我們需要使用兩張表,第一張表是之前導入PostGIS空間表的biz_geographic_name表,另外一張是biz_city城市信息表。這兩張表是我們最基礎的兩張表,通過省級行政區(qū)劃代碼找到biz_city表的的城市信息,然后查找對應的包含的省會及地區(qū)城市信息。為了方便大家了解這兩張表的結構信息,這里分享這兩張表的物理結構腳本:
CREATE TABLE "public"."biz_city" (
"id" int8 NOT NULL,
"province_code" varchar(16) COLLATE "pg_catalog"."default" NOT NULL,
"province_name" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
"city_code" varchar(16) COLLATE "pg_catalog"."default" NOT NULL,
"city_name" varchar(512) COLLATE "pg_catalog"."default" NOT NULL,
"type" varchar(32) COLLATE "pg_catalog"."default",
"geom" "public"."geometry",
CONSTRAINT "pk_biz_city" PRIMARY KEY ("id")
);
CREATE INDEX "idx_biz_city_citycode" ON "public"."biz_city" USING btree (
"city_code" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
CREATE INDEX "idx_biz_city_pcode" ON "public"."biz_city" USING btree (
"province_code" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
COMMENT ON COLUMN "public"."biz_city"."id" IS '主鍵ID';
COMMENT ON COLUMN "public"."biz_city"."province_code" IS '省份編碼';
COMMENT ON COLUMN "public"."biz_city"."province_name" IS '省份名稱';
COMMENT ON COLUMN "public"."biz_city"."city_code" IS '市級編碼';
COMMENT ON COLUMN "public"."biz_city"."city_name" IS '實際名稱';
COMMENT ON COLUMN "public"."biz_city"."type" IS '類型';
COMMENT ON COLUMN "public"."biz_city"."geom" IS 'geom';
CREATE TABLE "public"."biz_geographic_name" (
"pk_id" int8 NOT NULL,
"name" varchar(255) COLLATE "pg_catalog"."default" NOT NULL,
"pinyin" varchar(255) COLLATE "pg_catalog"."default",
"classz" varchar(4) COLLATE "pg_catalog"."default",
"bz" varchar(100) COLLATE "pg_catalog"."default",
"slx" varchar(20) COLLATE "pg_catalog"."default",
"geom" "public"."geometry" NOT NULL,
CONSTRAINT "pk_biz_geographic_name" PRIMARY KEY ("pk_id")
);
CREATE INDEX "idex_biz_geographic_name_classz" ON "public"."biz_geographic_name" USING btree (
"classz" COLLATE "pg_catalog"."default" "pg_catalog"."text_ops" ASC NULLS LAST
);
CREATE INDEX "idx_biz_geographic_name_geom" ON "public"."biz_geographic_name" USING gist (
"geom" "public"."gist_geometry_ops_2d"
);
COMMENT ON COLUMN "public"."biz_geographic_name"."pk_id" IS '主鍵id';
COMMENT ON COLUMN "public"."biz_geographic_name"."name" IS '地名';
COMMENT ON COLUMN "public"."biz_geographic_name"."pinyin" IS '漢語拼音';
COMMENT ON COLUMN "public"."biz_geographic_name"."classz" IS 'classz';
COMMENT ON COLUMN "public"."biz_geographic_name"."bz" IS '備注';
COMMENT ON COLUMN "public"."biz_geographic_name"."slx" IS 'slx';
COMMENT ON COLUMN "public"."biz_geographic_name"."geom" IS '空間對象';
COMMENT ON TABLE "public"."biz_geographic_name" IS '地名基礎信息表,用于存儲中國范圍內的地名信息';2、查找省會與地市信息
查詢省會與地市信息的SQL如下:
SELECT T .*, st_x ( T.geom ) lon, st_y ( T.geom ) lat, st_asgeojson ( T.geom ) FROM biz_geographic_name T, biz_city tc WHERE tc.province_code = '430000' AND T.classz IN ( 'AD', 'AC' ) AND st_contains ( tc.geom, T.geom );
使用數(shù)據(jù)庫客戶端軟件執(zhí)行以上SQL腳本后,可以看到以下結果:

這個結果很重要,作為下一步計算的基礎,首先我們需要先將計算的目標先查詢出來。
3、省級城市距離表設計
為了存儲兩地的行車最快路線以及其行駛的里程數(shù),同時也方便我們進行數(shù)據(jù)的查詢,在第一次調用后,后面就不需要重新進行計算,這樣能顯著的提高我們的計算能力。所以呢,我們需要設計一張空間信息表,用來存儲經過計算過的行車路線信息。這里給出一張物理結構,如下圖所示:

空間表的物理表結構如下所示:
CREATE TABLE "public"."biz_provincial_city_distance" (
"pk_id" int8 NOT NULL,
"province_code" varchar(16) NOT NULL DEFAULT ''::character varying,
"province_name" varchar(64) NOT NULL DEFAULT ''::character varying,
"distance" numeric(10,4) NOT NULL DEFAULT 0,
"city_name" varchar(64) NOT NULL DEFAULT ''::character varying,
"geom" "geometry",
"source" varchar(10) NOT NULL DEFAULT ''::character varying,
CONSTRAINT "pk_biz_provincial_city_distanc" PRIMARY KEY ("pk_id")
);
COMMENT ON COLUMN "biz_provincial_city_distance"."pk_id" IS '主鍵';
COMMENT ON COLUMN "biz_provincial_city_distance"."province_code" IS '省份code';
COMMENT ON COLUMN "biz_provincial_city_distance"."province_name" IS '省份name';
COMMENT ON COLUMN "biz_provincial_city_distance"."distance" IS '距離';
COMMENT ON COLUMN "biz_provincial_city_distance"."city_name" IS '城市名稱';
COMMENT ON COLUMN "biz_provincial_city_distance"."geom" IS '路線信息';
COMMENT ON COLUMN "biz_provincial_city_distance"."source" IS '來源';
COMMENT ON TABLE "biz_provincial_city_distance" IS '省市距離信息表';作為行車計算的成果保存表,這張表在以后的計算中還會經常用到,大家也可以根據(jù)自己的實際需要增加其它的字段。
二、省會與地級市距離實現(xiàn)
為了實現(xiàn)能夠計算省域的省會與地級市的最快行車距離的計算。我們需要做以下的一些工作,首先需要明確一個詳細的工作流,為了方便進行數(shù)據(jù)的生成。我們首先繪制一個具體的系統(tǒng)工作流程,然后使用天地圖的駕車API來輔助生成距離的路線,同時計算同行時間,最后使用GeoTools來實現(xiàn)成果入庫。
1、系統(tǒng)工作流程圖

為了實現(xiàn)省會及其地市的距離信息,基本需要按照以下五個步驟來實現(xiàn):第一步是根據(jù)輸入的省份code查詢省會及對應得地級市信息,如果查找的地市信息,則進入循環(huán),在循環(huán)中去調用天地圖的最快行車API查詢接口,最后將得到的路線信息及其實踐進行一個批量的入庫。
2、查詢指定省份的省會與地市
在前面的內容中講過,如何查詢省會及其地級市信息,在查詢出數(shù)據(jù)之后,通常來說,省會城市是返回的結果集中的第一條,因此在進行行車導航的時候,我們就默認第一條是省會城市。因此將第一條數(shù)據(jù)的經緯度作為目標點。需要說明的是,這里我們使用的是天地圖的檢索接口,因此返回的數(shù)據(jù)采用的坐標還是4326的坐標系,這里需要弄錯了。不然可能會引起不必要的問題。根據(jù)省份code查詢省會及其地級市的方法如下:
String province_code = "430000"; String provinceName = "湖南省"; List<GeographicNameVo> cityList = GeoNameService.findProvinceCityListByPcode(province_code);
然后在返回的結果集當中,默認第一條數(shù)據(jù)是省會城市,因此需要將其單獨拿出來作為目標城市,并提取具體的經緯度信息。
GeographicNameVo provincialCapital = cityList.get(0); String destInfo = provincialCapital.getLon() + "," + provincialCapital.getLat();
3、天地圖行車導航
下來就循環(huán)各個地級市,比如以湖南省為例,就是循環(huán)湘潭市、衡陽市、邵陽市、岳陽市、常德市、張家界市、益陽市、郴州市、永州市、懷化市、婁底市、湘西土家族苗族自治州這些城市,然后基于這些城市的經緯度坐標,分別計算與省會長沙市的最快通勤距離。調用過程方法如下所示:
List<ProvincialCityDistance> dataList = new ArrayList<ProvincialCityDistance>();
for(int i = 1;i<cityList.size();i++) {
GeographicNameVo sourceCity = cityList.get(i);
String origInfo = sourceCity.getLon() + "," + sourceCity.getLat();
String postStr = "%7B'orig':'" + origInfo + "','dest':'" + destInfo + "','style':'" + 0 + "'%7D";
HttpResponse<String> resp = tdtOptService.drivePlan(postStr, "search", TDT_SERVER_KEY);
JAXBContext context = JAXBContext.newInstance(TdtResult.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
TdtResult result = (TdtResult) unmarshaller.unmarshal(new StringReader(resp.getBodyResult()));
System.out.println("距離: " + result.getDistance());
System.out.println("時長: " + result.getDuration());
String geom = convertToLineStringWKT(result.getRoutelatlon());
geom = "SRID=" + 4326 +";" + geom;//拼接srid,實現(xiàn)動態(tài)寫入
System.out.println(geom);
ProvincialCityDistance dinstance = new ProvincialCityDistance(province_code, provinceName, new BigDecimal(result.getDistance()), sourceCity.getName(), geom, "tianditu");
dataList.add(dinstance);
}這里需要注意的是,由于調用的是天地圖的API,因此這里的SRID就直接設置為4326。如果是其他的導航平臺,比如高德或者百度就需用進行坐標的轉換,否則還會遇到其它的問題。
4、導航路徑入庫
最后調用批量入庫的方法,代碼很簡單,Mybatis_Plus集成了許多方便的方法,可以進行數(shù)據(jù)操作。
//執(zhí)行入庫
if(dataList.size() > 0) {
distanceService.saveBatch(dataList, 100);
}上述代碼執(zhí)行后,可以在控制臺看到以下輸出表示數(shù)據(jù)成功的保存到數(shù)據(jù)庫中。


以上就成果獲得目標省份及其省會和地級市距離的信息。
三、成果展示
最后我們來看看我們的成果,以湖南省、新疆自治區(qū)、黑龍江省為例,這三個省的省會及其地級市的距離情況究竟是什么樣的?篇幅有限,這里不能一一展開。如果感興趣的,可以私聊或者在評論區(qū)留言,到時候可以穿一些成果的圖片。
1、湖南省最快行車距離展示
查詢湖南省的各個地級市到省會長沙的具體SQL如下:
SELECT * , st_srid ( geom ) FROM biz_provincial_city_distance T WHERE T.province_code = '430000' ORDER BY distance;
可以看到在湖南省的各地級市中,距離長沙最近的是湘潭60公里,而最遠的則是湘西州387公里。具體列表如下:
1948389936998682626 430000 湖南省 59.5900 湘潭市 1948389936734441473 430000 湖南省 73.2500 株洲市 1948389936998682632 430000 湖南省 78.6600 益陽市 1948389937334226946 430000 湖南省 139.1500 婁底市 1948389936998682629 430000 湖南省 155.4200 岳陽市 1948389936998682630 430000 湖南省 171.5900 常德市 1948389936998682627 430000 湖南省 191.4800 衡陽市 1948389936998682628 430000 湖南省 218.2000 邵陽市 1948389936998682634 430000 湖南省 312.9900 永州市 1948389936998682633 430000 湖南省 318.0400 郴州市 1948389936998682631 430000 湖南省 320.3500 張家界市 1948389936998682635 430000 湖南省 385.1900 懷化市 1948389937556525057 430000 湖南省 387.1100 湘西土家族苗族自治州

2、新疆自治區(qū)最快行車距離展示
下面再來看下我國最大的一個省份,新疆自治區(qū)的各地市與省會烏魯木齊的距離又是多少呢?距離烏魯木齊最近的是昌吉35公里,最遠的則是1334.7100喀什。
1948410402484256769 650000 新疆維吾爾自治區(qū) 34.9700 昌吉回族自治州 1948410402400370690 650000 新疆維吾爾自治區(qū) 191.2700 吐魯番市 1948410402513616897 650000 新疆維吾爾自治區(qū) 342.0900 巴音郭楞蒙古自治州 1948410402169683970 650000 新疆維吾爾自治區(qū) 389.7900 克拉瑪依市 1948410402484256770 650000 新疆維吾爾自治區(qū) 519.0300 博爾塔拉蒙古自治州 1948410402400370691 650000 新疆維吾爾自治區(qū) 585.5400 哈密地區(qū) 1948410402832384004 650000 新疆維吾爾自治區(qū) 618.0900 塔城地區(qū) 1948410402832384005 650000 新疆維吾爾自治區(qū) 618.0900 塔城地區(qū) 1948410402832384003 650000 新疆維吾爾自治區(qū) 689.1600 伊犁哈薩克自治州 1948410402832384006 650000 新疆維吾爾自治區(qū) 793.7300 阿勒泰地區(qū) 1948410402513616898 650000 新疆維吾爾自治區(qū) 877.0100 阿克蘇地區(qū) 1948410402832384002 650000 新疆維吾爾自治區(qū) 1278.1100 和田地區(qū) 1948410402652028930 650000 新疆維吾爾自治區(qū) 1294.6200 克孜勒蘇柯爾克孜自治州 1948410402773663746 650000 新疆維吾爾自治區(qū) 1334.7100 喀什地區(qū)

3、黑龍江省最快行車距離展示
最后來看一下我國的北疆,黑龍江省的最快行車距離展示。使用客戶端軟件運行以上sql后,可以看到如下結果。距離哈爾濱最近的是綏化市112公里,最遠的是黑河市560公里。
1948411772348157953 230000 黑龍江省 112.7800 綏化市 1948411772171997186 230000 黑龍江省 153.4400 大慶市 1948411771584794626 230000 黑龍江省 302.9300 齊齊哈爾市 1948411772171997187 230000 黑龍江省 322.4100 伊春市 1948411772171997190 230000 黑龍江省 330.8700 牡丹江市 1948411772171997188 230000 黑龍江省 380.4400 佳木斯市 1948411772171997189 230000 黑龍江省 427.0100 七臺河市 1948411771853230081 230000 黑龍江省 444.5100 鶴崗市 1948411771853230082 230000 黑龍江省 452.5800 雙鴨山市 1948411771765149697 230000 黑龍江省 477.3500 雞西市 1948411772171997191 230000 黑龍江省 569.4200 黑河市

四、總結
以上就是本文的主要內容, 本次實踐聚焦于省域這一相對較大范圍的地理區(qū)域,相較于城市內部的路線規(guī)劃,省域駕車路線面臨著更多的挑戰(zhàn)。省域內道路網(wǎng)絡更為復雜,涵蓋了高速公路、國道、省道以及鄉(xiāng)村道路等多種類型,不同道路之間的連接關系、通行規(guī)則以及路況信息差異巨大。與常規(guī)的兩點之間直線最短的計算方式不同,在兩個城市的行車距離計算中,往往兩者的距離會超出直線距離。因此我們通過駕車距離的長短來衡量與省會城市的聯(lián)系度,也可以作為衡量交通對地域經濟影響的因素評估做參考。在本文中,我們將逐步展開對基于 GeoTools 和 SpringBoot 的省域駕車最快路線生成實踐的詳細闡述,從理論基礎到實踐操作,從技術實現(xiàn)到系統(tǒng)優(yōu)化,全方位地呈現(xiàn)這一項目的全貌。行文倉促,定有不足之處,歡迎各位朋友在評論區(qū)批評指正,不勝感激。
到此這篇關于基于GeoTools和SpringBoot的省域駕車最快路線規(guī)劃方法的文章就介紹到這了,更多相關GeoTools和SpringBoot駕車路線內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot+aop實現(xiàn)主從數(shù)據(jù)庫的讀寫分離操作
讀寫分離的作用是為了緩解寫庫,也就是主庫的壓力,但一定要基于數(shù)據(jù)一致性的原則,就是保證主從庫之間的數(shù)據(jù)一定要一致,這篇文章給大家介紹SpringBoot+aop實現(xiàn)主從數(shù)據(jù)庫的讀寫分離操作,感興趣的朋友跟隨小編一起看看吧2024-03-03
Java基礎知識精通循環(huán)結構與break及continue
循環(huán)結構是指在程序中需要反復執(zhí)行某個功能而設置的一種程序結構。它由循環(huán)體中的條件,判斷繼續(xù)執(zhí)行某個功能還是退出循環(huán),選擇結構用于判斷給定的條件,根據(jù)判斷的結果判斷某些條件,根據(jù)判斷的結果來控制程序的流程2022-04-04
java實現(xiàn)切割wav音頻文件的方法詳解【附外部jar包下載】
這篇文章主要介紹了java實現(xiàn)切割wav音頻文件的方法,結合實例形式詳細分析了java切割wav音頻文件的相關原理、操作技巧與注意事項,并附帶外部jar包供讀者下載,需要的朋友可以參考下2019-05-05
Java使用freemarker實現(xiàn)word下載方式
文章介紹了如何使用FreeMarker實現(xiàn)Word文件下載,包括引用依賴、創(chuàng)建Word模板、將Word文件存為XML格式、更改后綴為FTL模板、處理圖片和代碼實現(xiàn)2025-02-02
深入剖析SpringBoot配置文件加載順序(一場配置界的權力游戲)
這篇文章給大家介紹SpringBoot配置文件的加載順序,從配置文件的優(yōu)先級、加載位置、文件類型優(yōu)先級,到實戰(zhàn)場景解析和底層原理,通過實戰(zhàn)場景解析,感興趣的朋友跟隨小編一起看看吧2026-01-01
Java訪問WebService返回XML數(shù)據(jù)的方法
這篇文章主要介紹了Java訪問WebService返回XML數(shù)據(jù)的方法,涉及java操作WebService的相關技巧,需要的朋友可以參考下2015-06-06

