跳到主要内容Spring Boot 与 Leaflet 实现省域迂回可视化实战 | 极客日志Java大前端java算法
Spring Boot 与 Leaflet 实现省域迂回可视化实战
基于 Spring Boot 后端与 Leaflet 前端构建省域迂回可视化系统的实战方案。通过空间数据库存储区县距离及路线几何信息,利用 MyBatis 进行 SQL 查询获取迂回系数。前端使用 Leaflet 加载 GeoJSON 数据,根据迂回系数映射颜色色带,实现路径的直观展示。系统支持按省份查询,展示了重庆、广东、浙江等地的迂回情况,为交通规划与物流优化提供数据支持。
片刻1 浏览 引言
地理空间数据的可视化在交通管理、资源调配等领域具有重要意义。省域迂回可视化技术能够精准呈现区域内复杂路径,辅助交通规划与物流优化。
一、空间数据基础
1、相关空间表
省域区县距离信息表存储计算结果,结构如下:

表结构定义语句:
CREATE TABLE "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" ;
COMMENT "biz_provincial_city_distance"."province_code" ;
COMMENT "biz_provincial_city_distance"."province_name" ;
COMMENT "biz_provincial_city_distance"."distance" ;
COMMENT "biz_provincial_city_distance"."city_name" ;
COMMENT "biz_provincial_city_distance"."geom" ;
COMMENT biz_provincial_city_distance."source" ;
COMMENT "biz_provincial_city_distance" ;
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
IS
'主键'
ON
COLUMN
IS
'省份 code'
ON
COLUMN
IS
'省份 name'
ON
COLUMN
IS
'距离'
ON
COLUMN
IS
'城市名称'
ON
COLUMN
IS
'路线信息'
ON
IS
'来源'
ON
TABLE
IS
'省市距离信息表'
2、空间数据查询
SELECT T.pk_id pkId, T.province_name, T.city_name cityName, T.distance, st_asgeojson(T.geom) geomJson, ST_Length(T.geom::geography)/1000.0 AS navDist, ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))/1000.0 AS lineDist, (ST_Length(T.geom::geography)/ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))) AS detourCoefficient, st_x(ST_StartPoint(T.geom)) lon, st_y(ST_StartPoint(T.geom)) lat FROM biz_provincial_city_distance T WHERE T.province_code = '430000' ORDER BY detourCoefficient;
二、SpringBoot 后端实现
1、模型层实现
package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import java.math.BigDecimal;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
@ToString
public class ProvincialCityDistanceVO implements Serializable {
private static final long serialVersionUID = -9036168942653219124L;
private Long pkId;
private String cityName;
private BigDecimal distance = new BigDecimal(0);
private String geomJson;
private BigDecimal navDist = new BigDecimal(0);
private BigDecimal lineDist = new BigDecimal(0);
private BigDecimal detourCoefficient = new BigDecimal(0);
private String lat;
private String lon;
}
package com.yelang.project.extend.earthquake.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yelang.project.extend.earthquake.domain.ProvincialCityDistance;
import com.yelang.project.extend.earthquake.domain.ProvincialCityDistanceVO;
public interface ProvincialCityDistanceMapper extends BaseMapper<ProvincialCityDistance> {
static final String FIND_LIST_BY_PROVINCE_CODE = "<script>" +
" SELECT T.pk_id pkId,T.city_name cityName,T.distance,st_asgeojson(T.geom) geomJson, " +
" ST_Length(T.geom::geography)/1000.0 AS navDist,st_x(ST_StartPoint(T.geom)) lon,st_y(ST_StartPoint(T.geom)) lat, " +
" ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))/1000.0 AS lineDist, " +
" (ST_Length(T.geom::geography)/ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))) AS detourCoefficient " +
" FROM biz_provincial_city_distance T WHERE T.province_code = #{code} ORDER BY detourCoefficient " +
"</script>";
@Select(FIND_LIST_BY_PROVINCE_CODE)
List<ProvincialCityDistanceVO> findListByProvinceCode(@Param("code")String code);
}
2、控制层实现
@RequiresPermissions("eq:detourcoefficient:map")
@GetMapping("/detourcoefficient")
public String detourcoefficient(){
return prefix + "/detourcoefficient";
}
@RequiresPermissions("eq:detourcoefficient:list")
@GetMapping("/detourcoefficient/list/{pcode}")
@ResponseBody
public AjaxResult detourcoefficientList(@PathVariable("pcode") String pcode){
List<ProvincialCityDistanceVO> dataList = provinceCityDistanceService.findListByProvinceCode(pcode);
return AjaxResult.success().put("data", dataList);
}
三、Leaflet 前端实现
1、迂回系数设置及色带配置
| 分类名 | 迂回系数范围 | 颜色值 (Hex) | RGB 值 (R, G, B) | 描述 |
|---|
| 直线路径 | 1.0 - 1.2 | #00FF00 | (0, 255, 0) | 路径几乎为直线,效率高 |
| 轻微迂回 | 1.2 - 1.5 | #FFFF00 | (255, 255, 0) | 轻微偏离直线,效率中等 |
| 中等迂回 | 1.5 - 2.0 | #FFA500 | (255, 165, 0) | 明显偏离直线,效率较低 |
| 严重迂回 | 2.0 - 3.0 | #FF0000 | (255, 0, 0) | 高度偏离直线,效率低 |
| 极端迂回 | > 3.0 | #8B0000 | (139, 0, 0) | 极度偏离直线,效率极低 |
var detourFactorColorList = [
{name:"直线路径,1.0 - 1.2",color:"#00FF00",rgb:new Color(0, 255, 0),infoDesc:"路径几乎为直线,效率高"},
{name:"轻微迂回,1.2 - 1.5",color:"#FFFF00",rgb:new Color(75,0,130),infoDesc:"轻微偏离直线,效率中等"},
{name:"中等迂回,1.5 - 2.0",color:"#FFA500",rgb:new Color(255, 165, 0),infoDesc:"明显偏离直线,效率较低"},
{name:"严重迂回,2.0 - 3.0",color:"#FF0000",rgb:new Color(255, 0, 0),infoDesc:"高度偏离直线,效率低"},
{name:"极端迂回,> 3.0",color:"#8B0000",rgb:new Color(139, 0, 0),infoDesc:"极度偏离直线,效率极低"}
];
var DIY_BLUE_GREEN_YELLOW_RED_SCHEME;
$(document).ready(function () {
initSidebar();
var legendData = new Array();
var colorArray = new Array();
for(var i=0;i<detourFactorColorList.length;i++){
var _tempData = detourFactorColorList[i];
legendData.push({ label: "\xa0\xa0"+_tempData.name , type: "rectangle", radius: 12, color: _tempData.color, fillColor: _tempData.color, fillOpacity: 0.8, weight: 2});
colorArray.push(_tempData.rgb);
}
DIY_BLUE_GREEN_YELLOW_RED_SCHEME = new MultiColorScheme('', 1.0,3.5 ,colorArray);
initLegend(legendData);
});
2、区县迂回展示
function getColorByDetourCoefficient(detourCoefficient){
var _tempVal = parseFloat(detourCoefficient);
if(_tempVal >= 1.0 && _tempVal < 1.2){ return "#00FF00"; }
if(_tempVal >= 1.2 && _tempVal < 1.5){ return "#FFFF00"; }
if(_tempVal >= 1.5 && _tempVal < 2.0){ return "#FFA500"; }
if(_tempVal >= 2.0 && _tempVal < 3.0){ return "#FF0000"; }
if(_tempVal > 3.0){ return "#8B0000"; }
return "#8B0000";
}
function previewDetourCoefficient(pid,provinceCode,name){
previewProvince(pid,name);
$.ajax({
type:"get",
url:prefix + "/detourcoefficient/list/" + provinceCode,
data:{},
dataType:"json",
cache:false,
processData:false,
success:function(result){
if(result.code == web_status.SUCCESS){
$("#title_info").html(name+"城市迂回可视化<sub>(L1:导航距离,L2:直线距离)</sub>");
collisionLayer.clearLayers();
for(var i=0;i< result.data.length;i++){
var areaData = result.data[i];
var color = getColorByDetourCoefficient(areaData.detourCoefficient);
var areaLayer = L.geoJSON(JSON.parse(areaData.geomJson),{style: {color:color,fillColor:color,weight:3,"opacity":0.65, fillOpacity: 0.65 }}).addTo(mymap);
var myIcon = L.divIcon({ iconSize: null, className: '', popupAnchor:[5,5], shadowAnchor:[5,5], html: buildShowInfo(i,color,areaData) });
collisionLayer.addLayer(areaLayer);
L.marker([areaData.lat,areaData.lon], { icon: myIcon}).addTo(collisionLayer);
}
collisionLayer.addTo(showLayerGroup);
}
},
error:function(){
$.modal.alertWarning("获取空间信息失败");
}
});
}
四、成果展示
1、全国迂回整体情况
SELECT T.pk_id pkId, T.province_name, T.city_name cityName, T.distance, st_asgeojson(T.geom) geomJson, ST_Length(T.geom::geography)/1000.0 AS navDist, ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))/1000.0 AS lineDist, (ST_Length(T.geom::geography)/ST_DistanceSphere(ST_StartPoint(T.geom), ST_EndPoint(T.geom))) AS detourCoefficient, st_x(ST_StartPoint(T.geom)) lon, st_y(ST_StartPoint(T.geom)) lat FROM biz_provincial_city_distance T ORDER BY detourCoefficient;
最接近于直线的五个地方:崇明县、辽宁省盘山县、河南省中牟县、广东省天河区、内蒙古自治区东河区。
迂回比较严重的后 5 名:湖北省武昌区、香港特别行政区屯门区、山西省石楼县、西藏嘉黎县、西藏林周县、西藏边坝县等。
2、重庆市迂回展示
province_name cityname distance navdist linedist detourcoefficient
重庆市 潼南区 110.3600 110.51047762948166 97.68331602216999 1.13131374045902
重庆市 梁平县 191.5700 191.7131775208737 168.59402255844 1.1371291497266451
重庆市 永川区 74.1700 74.37440135004668 64.62314433581 1.1508941899138319
重庆市 荣昌区 108.7900 109.06056033597619 94.19726107911 1.157789080983825
重庆市 奉节县 374.5000 374.68521001493286 322.99202917579004 1.1600447570519103
province_name cityname distance navdist linedist
重庆市 渝中区 3.6800 3.779657849744212 2.13279590328
重庆市 酉阳土家族苗族自治县 363.2200 363.60072614988763 229.62231250973
重庆市 南岸区 17.9100 17.9817585049283 11.492966037059999
重庆市 秀山土家族苗族自治县 418.8200 419.2231938929248 269.17448974303
重庆市 璧山区 49.9000 50.05221534418218 33.45105579760005
3、广东省迂回展示
province_name cityname distance navdist linedist detourcoefficient
广东省 天河区 10.4600 10.555375116530177 9.93596533891 1.0623401709338216
广东省 清新区 80.8300 80.78129002608327 71.98357029 1.122218440967014
广东省 云浮市 143.3900 143.69688311709783 127.0862245763 1.1307038476922031
广东省 云城区 143.4400 143.74862299137553 126.89855706838 1.1327837472093223
广东省 化州市 359.1700 359.34341542307055 315.04612745022 1.1406057212363288
province_name cityname distance navdist linedist
广东省 南海区 24.5800 24.65194449512291 16.601655223810003
广东省 江海区 95.2500 95.28713899437355 64.93929472111
广东省 禅城区 28.6400 28.71179642381173 19.632861564219997
广东省 江门市 92.4900 92.42245085649293 63.888415391150005
广东省 高明区 66.1700 66.26498995756911 45.82280085688
4、浙江省迂回展示
province_name cityname distance navdist linedist detourcoefficient
浙江省 鄞州区 153.0700 153.44879641871103 143.26062911380998 1.0711163099584553
浙江省 宁波市 160.7100 161.15227733629254 148.7463844915 1.083402987489094
浙江省 江东区 157.2100 157.6070345898314 143.5287695282 1.098086711869047
浙江省 北仑区 184.4600 184.9446572990281 167.80979248393 1.1021088493196187
浙江省 海曙区 155.7700 156.16887660282018 141.40475136639 1.1044103899887725
province_name cityname distance navdist linedist detourcoefficient
浙江省 江干区 7.9600 8.070236761912987 5.1719456935400006 1.5603869878202874
浙江省 滨江区 14.1100 14.165315020539612 9.09033017652 1.558283884685302
浙江省 下城区 3.9400 4.061935738299966 2.6452204945499997 1.5355754829016535
浙江省 西湖区 4.3000 4.42778184607228 2.90129519486 1.5261397233610143
浙江省 拱墅区 7.5300 7.5972077517023 5.17180335205 1.46896675305832
五、总结
本文介绍了基于 Spring Boot 和 Leaflet 构建省域迂回可视化系统的完整流程,涵盖数据库设计、后端 API 开发及前端地图交互实现。通过实际案例展示了不同省份的迂回系数分布,验证了方案的有效性。