> 技术文档 > 基于GeoTools和SpringBoot的省域驾车最快路线生成实践

基于GeoTools和SpringBoot的省域驾车最快路线生成实践

目录

前言

一、相关空间表简介及设计

1、相关基础空间表

2、查找省会与地市信息

3、省级城市距离表设计

二、省会与地级市距离实现

1、系统工作流程图

2、查询指定省份的省会与地市

3、天地图行车导航

4、导航路径入库

三、成果展示

1、湖南省最快行车距离展示

2、新疆自治区最快行车展示

3、黑龙江省最快行车展示

四、总结


前言

        在当今数字化时代,地理信息系统(GIS)技术与现代交通出行需求的深度融合正不断催生出诸多创新应用,其中驾车路线规划作为人们日常出行中极为关键的一项服务,其重要性愈发凸显。无论是长途旅行、商务出差,还是日常通勤,人们都渴望能够获取到一条既快速又高效的驾车路线,以节省宝贵的时间成本。而基于 GeoTools 和 SpringBoot 的省域驾车最快路线生成实践,正是在这一背景下应运而生的前沿探索,它不仅汇聚了先进开源地理空间工具与高效微服务框架的双重优势,更是为解决大范围区域内复杂路况下的最优路线规划问题提供了全新的思路与方法。

        本次实践聚焦于省域这一相对较大范围的地理区域,相较于城市内部的路线规划,省域驾车路线面临着更多的挑战。省域内道路网络更为复杂,涵盖了高速公路、国道、省道以及乡村道路等多种类型,不同道路之间的连接关系、通行规则以及路况信息差异巨大。与常规的两点之间直线最短的计算方式不同,在两个城市的行车距离计算中,往往两者的距离会超出直线距离。因此我们通过驾车距离的长短来衡量与省会城市的联系度,也可以作为衡量交通对地域经济影响的因素评估做参考。同时,省域范围内的地理环境多样,山脉、河流、湖泊等自然地理要素对路线的选择也会产生重要影响。此外,跨区域的交通流量分布不均,节假日、特殊事件等还会引发交通流量的大幅波动,这些都使得省域驾车最快路线的生成难度大幅提升。然而,正是这些复杂多变的因素,也为基于 GeoTools 和 SpringBoot 的路线规划实践提供了丰富的应用场景和极具价值的研究课题。

        在接下来的章节中,我们将逐步展开对基于 GeoTools 和 SpringBoot 的省域驾车最快路线生成实践的详细阐述,从理论基础到实践操作,从技术实现到系统优化,全方位地呈现这一项目的全貌。让我们一同踏上这段充满挑战与机遇的探索之路,开启一场关于地理空间技术与交通出行服务融合创新的精彩旅程。

一、相关空间表简介及设计

        本节将重点介绍需要使用到的一些基础空间表和用于存储省级城市距离的空间表信息。通过本节的讲解,让大家知晓如何进行省级地市的信息查询。同时了解如何去存储省级城市距离及其路线信息。而这条路线信息在存储下来以后就可以在后续的分析中进行展示。因此将这部分内容放到第一节来讲解,是一个基础内容。

1、相关基础空间表

        为了查询省会城市还有其他的地级城市,这里我们需要使用两张表,第一张表是之前导入PostGIS空间表的biz_geographic_name表,另外一张是biz_city城市信息表。这两张表是我们最基础的两张表,通过省级行政区划代码找到biz_city表的的城市信息,然后查找对应的包含的省会及地区城市信息。为了方便大家了解这两张表的结构信息,这里分享这两张表的物理结构脚本:

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 ) FROMbiz_geographic_name T,biz_city tc WHEREtc.province_code = \'430000\' AND T.classz IN ( \'AD\', \'AC\' ) AND st_contains ( tc.geom, T.geom );

        使用数据库客户端软件执行以上SQL脚本后,可以看到以下结果:

        这个结果很重要,作为下一步计算的基础,首先我们需要先将计算的目标先查询出来。 

3、省级城市距离表设计

        为了存储两地的行车最快路线以及其行驶的里程数,同时也方便我们进行数据的查询,在第一次调用后,后面就不需要重新进行计算,这样能显著的提高我们的计算能力。所以呢,我们需要设计一张空间信息表,用来存储经过计算过的行车路线信息。这里给出一张物理结构,如下图所示:

空间表的物理表结构如下所示:

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 \'省市距离信息表\';

         作为行车计算的成果保存表,这张表在以后的计算中还会经常用到,大家也可以根据自己的实际需要增加其它的字段。

二、省会与地级市距离实现

        为了实现能够计算省域的省会与地级市的最快行车距离的计算。我们需要做以下的一些工作,首先需要明确一个详细的工作流,为了方便进行数据的生成。我们首先绘制一个具体的系统工作流程,然后使用天地图的驾车API来辅助生成距离的路线,同时计算同行时间,最后使用GeoTools来实现成果入库。

1、系统工作流程图

        为了实现省会及其地市的距离信息,基本需要按照以下五个步骤来实现:第一步是根据输入的省份code查询省会及对应得地级市信息,如果查找的地市信息,则进入循环,在循环中去调用天地图的最快行车API查询接口,最后将得到的路线信息及其实践进行一个批量的入库。 

2、查询指定省份的省会与地市

        在前面的内容中讲过,如何查询省会及其地级市信息,在查询出数据之后,通常来说,省会城市是返回的结果集中的第一条,因此在进行行车导航的时候,我们就默认第一条是省会城市。因此将第一条数据的经纬度作为目标点。需要说明的是,这里我们使用的是天地图的检索接口,因此返回的数据采用的坐标还是4326的坐标系,这里需要弄错了。不然可能会引起不必要的问题。根据省份code查询省会及其地级市的方法如下:

String province_code = \"430000\";String provinceName = \"湖南省\";List cityList = GeoNameService.findProvinceCityListByPcode(province_code);

        然后在返回的结果集当中,默认第一条数据是省会城市,因此需要将其单独拿出来作为目标城市,并提取具体的经纬度信息。

GeographicNameVo provincialCapital = cityList.get(0);String destInfo = provincialCapital.getLon() + \",\" + provincialCapital.getLat();

3、天地图行车导航

        下来就循环各个地级市,比如以湖南省为例,就是循环湘潭市、衡阳市、邵阳市、岳阳市、常德市、张家界市、益阳市、郴州市、永州市、怀化市、娄底市、湘西土家族苗族自治州这些城市,然后基于这些城市的经纬度坐标,分别计算与省会长沙市的最快通勤距离。调用过程方法如下所示:

List dataList = new ArrayList();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 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,实现动态写入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集成了许多方便的方法,可以进行数据操作。

//执行入库if(dataList.size() > 0) {distanceService.saveBatch(dataList, 100);}

        上述代码执行后,可以在控制台看到以下输出表示数据成功的保存到数据库中。

        以上就成果获得目标省份及其省会和地级市距离的信息。 

三、成果展示

        最后我们来看看我们的成果,以湖南省、新疆自治区、黑龙江省为例,这三个省的省会及其地级市的距离情况究竟是什么样的?篇幅有限,这里不能一一展开。如果感兴趣的,可以私聊或者在评论区留言,到时候可以穿一些成果的图片。

1、湖南省最快行车距离展示

        查询湖南省的各个地级市到省会长沙的具体SQL如下:

SELECT* ,st_srid ( geom ) FROMbiz_provincial_city_distance T WHERET.province_code = \'430000\' ORDER BYdistance;

         可以看到在湖南省的各地级市中,距离长沙最近的是湘潭60公里,而最远的则是湘西州387公里。具体列表如下:

1948389936998682626430000湖南省59.5900湘潭市1948389936734441473430000湖南省73.2500株洲市1948389936998682632430000湖南省78.6600益阳市1948389937334226946430000湖南省139.1500娄底市1948389936998682629430000湖南省155.4200岳阳市1948389936998682630430000湖南省171.5900常德市1948389936998682627430000湖南省191.4800衡阳市1948389936998682628430000湖南省218.2000邵阳市1948389936998682634430000湖南省312.9900永州市1948389936998682633430000湖南省318.0400郴州市1948389936998682631430000湖南省320.3500张家界市1948389936998682635430000湖南省385.1900怀化市1948389937556525057430000湖南省387.1100湘西土家族苗族自治州

2、新疆自治区最快行车距离展示

        下面再来看下我国最大的一个省份,新疆自治区的各地市与省会乌鲁木齐的距离又是多少呢?距离乌鲁木齐最近的是昌吉35公里,最远的则是1334.7100喀什。

1948410402484256769650000新疆维吾尔自治区34.9700昌吉回族自治州1948410402400370690650000新疆维吾尔自治区191.2700吐鲁番市1948410402513616897650000新疆维吾尔自治区342.0900巴音郭楞蒙古自治州1948410402169683970650000新疆维吾尔自治区389.7900克拉玛依市1948410402484256770650000新疆维吾尔自治区519.0300博尔塔拉蒙古自治州1948410402400370691650000新疆维吾尔自治区585.5400哈密地区1948410402832384004650000新疆维吾尔自治区618.0900塔城地区1948410402832384005650000新疆维吾尔自治区618.0900塔城地区1948410402832384003650000新疆维吾尔自治区689.1600伊犁哈萨克自治州1948410402832384006650000新疆维吾尔自治区793.7300阿勒泰地区1948410402513616898650000新疆维吾尔自治区877.0100阿克苏地区1948410402832384002650000新疆维吾尔自治区1278.1100和田地区1948410402652028930650000新疆维吾尔自治区1294.6200克孜勒苏柯尔克孜自治州1948410402773663746650000新疆维吾尔自治区1334.7100喀什地区

3、黑龙江省最快行车距离展示

        最后来看一下我国的北疆,黑龙江省的最快行车距离展示。使用客户端软件运行以上sql后,可以看到如下结果。距离哈尔滨最近的是绥化市112公里,最远的是黑河市560公里。

1948411772348157953230000黑龙江省112.7800绥化市1948411772171997186230000黑龙江省153.4400大庆市1948411771584794626230000黑龙江省302.9300齐齐哈尔市1948411772171997187230000黑龙江省322.4100伊春市1948411772171997190230000黑龙江省330.8700牡丹江市1948411772171997188230000黑龙江省380.4400佳木斯市1948411772171997189230000黑龙江省427.0100七台河市1948411771853230081230000黑龙江省444.5100鹤岗市1948411771853230082230000黑龙江省452.5800双鸭山市1948411771765149697230000黑龙江省477.3500鸡西市1948411772171997191230000黑龙江省569.4200黑河市

四、总结

        以上就是本文的主要内容, 本次实践聚焦于省域这一相对较大范围的地理区域,相较于城市内部的路线规划,省域驾车路线面临着更多的挑战。省域内道路网络更为复杂,涵盖了高速公路、国道、省道以及乡村道路等多种类型,不同道路之间的连接关系、通行规则以及路况信息差异巨大。与常规的两点之间直线最短的计算方式不同,在两个城市的行车距离计算中,往往两者的距离会超出直线距离。因此我们通过驾车距离的长短来衡量与省会城市的联系度,也可以作为衡量交通对地域经济影响的因素评估做参考。在本文中,我们将逐步展开对基于 GeoTools 和 SpringBoot 的省域驾车最快路线生成实践的详细阐述,从理论基础到实践操作,从技术实现到系统优化,全方位地呈现这一项目的全貌。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。