跳到主要内容
极客日志极客日志
首页博客AI提示词GitHub精选代理工具
搜索
|注册
博客列表

目录

  1. 前言
  2. 一、基础空间数据简介
  3. 1、涉及相关表
  4. 2、省域道路长度检索
  5. 二、Java 后台实现
  6. 1、道路视图对象
  7. 2、Mapper 空间检索查询
  8. 3、控制 API 实现
  9. 三、WebGIS 界面实现
  10. 1、里程图例及初始化
  11. 2、各地市信息展示
  12. 四、成果展示
  13. 1、总体展示
  14. 2、分区域说明
  15. 五、总结
Java大前端java

Java+Leaflet 实现湖南省道路长度 WebGIS 系统

基于 Java 和 Leaflet 构建湖南省道路长度 WebGIS 系统的实践。通过 PostGIS 处理 OSM 空间数据,利用 MyBatis Plus 进行后端检索,结合 Leaflet 在前端展示各地市行政区划及道路里程。系统实现了省域道路长度检索、分级统计及地图可视化,为交通规划和管理提供技术支持。

CodeArtist发布于 2026/4/5更新于 2026/4/189 浏览
Java+Leaflet 实现湖南省道路长度 WebGIS 系统

前言

地理信息系统(GIS)技术在城市规划、交通管理等领域发挥重要作用。湖南省交通网络密集,如何高效管理和展示道路长度信息对交通规划具有重要意义。本文介绍基于 Java 和 Leaflet 构建的湖南省道路长度 WebGIS 系统,通过地图形式直观展示道路里程,方便用户查询分析。

文章配图

一、基础空间数据简介

1、涉及相关表

序号表名说明
1biz_urban_road_mileage_info城市道路里程信息表,业务信息表
2biz_geographic_name城市名称信息表,点状空间数据表
3biz_city市级行政区划信息表,面状空间数据

我们需要在地图上展示湖南省各地市的行政区划范围及政府驻地标注信息。数据来源于 OSM,时效性可能非最新,如需权威数据可从官网获取,代码逻辑一致。

2、省域道路长度检索

采用空间数据库表关联业务表进行查询,SQL 如下:

SELECT t1.*, T3.province_code, t3.province_name, st_asgeojson ( t3.geom ) geomJson, st_x ( t2.geom ) lon, st_y ( t2.geom ) lat FROM biz_urban_road_mileage_info t1, biz_geographic_name t2, biz_city t3 WHERE t1.parent_code = '430000' AND t1.city_code = t3.city_code AND T1.city_name = t2.NAME AND st_contains ( t3.geom, t2.geom );

执行后可在客户端查看结果。实际应用中需动态替换省份信息。

二、Java 后台实现

1、道路视图对象

根据业务需要扩展子类,包装成视图对象返回数据。核心代码如下:

package com.yelang.project.extend.earthquake.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Data
@ToString(callSuper=true)

      {
          ;
    
     String provinceCode;
    
     String provinceName;
    
     String geomJson;
     String lat;
     String lon;
}
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog

更多推荐文章

查看全部
  • Linux 系统安装 OpenClaw 并接入 QQ 机器人
  • C++ 进阶核心知识点整理
  • 解析 skill-creator:如何编写高质量 AI Skill
  • OpenHarmony 中使用 web_socket 实现跨平台 WebSocket 通信
  • 基于改进 YOLOv11n 的无人机红外目标检测算法
  • JDK21 下载与安装指南
  • 基于 JeecgBoot 低代码平台构建请假审批系统实战
  • SM4 国密算法原理与 C++跨平台实现详解

相关免费在线工具

  • 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

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

@EqualsAndHashCode(callSuper=false)
public
class
UrbanRoadMileageInfoVO
extends
UrbanRoadMileageInfo
implements
Serializable
private
static
final
long
serialVersionUID
=
1101541707654186490L
@TableField(exist = false,value= "province_code")
private
@TableField(exist = false,value= "province_name")
private
@TableField(exist = false)
private
private
private

2、Mapper 空间检索查询

使用 MybatisPlus 进行数据库检索,将 SQL 写入 Mapper 对象。

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.UrbanRoadMileageInfo;
import com.yelang.project.extend.earthquake.domain.UrbanRoadMileageInfoVO;
public interface UrbanRoadMileageInfoMapper extends BaseMapper<UrbanRoadMileageInfo>{
    static final String LIST_BYPROVINCE_SQL = "SELECT t1.city_code,MAX(t1.city_name) AS city_name," +
        " SUM(CASE WHEN r.fclass IN ('motorway', 'motorway_link') THEN ST_Length(r.geom::geography) ELSE 0 END) AS highway_length, " +
        " SUM(CASE WHEN r.fclass IN ('trunk', 'trunk_link') THEN ST_Length(r.geom::geography) ELSE 0 END) AS trunk_length, " +
        " SUM(CASE WHEN r.fclass IN ('primary', 'primary_link') THEN ST_Length(r.geom::geography) ELSE 0 END) AS primary_length, " +
        " SUM(CASE WHEN r.fclass IN ('secondary', 'secondary_link') THEN ST_Length(r.geom::geography) ELSE 0 END) AS secondary_length," +
        " SUM(CASE WHEN r.fclass IN ('tertiary', 'tertiary_link') THEN ST_Length(r.geom::geography) ELSE 0 END) AS tertiary_length, " +
        " SUM(CASE WHEN r.fclass IN ('residential', 'living_street') THEN ST_Length(r.geom::geography) ELSE 0 END) AS residential_length, " +
        " SUM(CASE WHEN r.fclass IN ('service', 'unclassified') THEN ST_Length(r.geom::geography) ELSE 0 END) AS service_length, " +
        " SUM(CASE WHEN r.fclass IN ('footway', 'pedestrian', 'path') THEN ST_Length(r.geom::geography) ELSE 0 END) AS pedestrian_length, " +
        " SUM(CASE WHEN r.fclass = 'cycleway' THEN ST_Length(r.geom::geography) ELSE 0 END) AS cycleway_length, " +
        " SUM(CASE WHEN r.fclass = 'track' THEN ST_Length(r.geom::geography) ELSE 0 END) AS track_length," +
        " SUM(CASE WHEN r.fclass in ('steps', 'footway') THEN ST_Length(r.geom::geography) ELSE 0 END) AS steps_length," +
        " SUM(ST_Length(r.geom::geography)) AS total_length " +
        " FROM biz_road_network r JOIN biz_city t1 ON ST_Contains(t1.geom, r.geom) WHERE t1.province_code = #{province_code} " +
        " GROUP BY t1.city_code ORDER BY total_length DESC ";
    @Select(LIST_BYPROVINCE_SQL)
    public List<UrbanRoadMileageInfo> getListByProvinceCode(@Param("province_code")String provinceCode);
    final static String GET_ROADMILEAGELIST_BY_PROVINCECODE = "<script>" +
        " SELECT t1.*,T3.province_code,t3.province_name,st_asgeojson ( t3.geom ) geomJson, " +
        " st_x ( t2.geom ) lon,st_y ( t2.geom ) lat " +
        " FROM biz_urban_road_mileage_info t1,biz_geographic_name t2,biz_city t3 " +
        " WHERE t1.parent_code = #{provinceCode} AND t1.city_code = t3.city_code " +
        " AND T1.city_name = t2.NAME AND st_contains ( t3.geom, t2.geom ) " +
        "</script>";
    @Select(GET_ROADMILEAGELIST_BY_PROVINCECODE)
    List<UrbanRoadMileageInfoVO> getRoadMileageList(@Param("provinceCode") String provinceCode);
}

3、控制 API 实现

控制层 API 分为页面跳转和获取各地级市信息列表。

package com.yelang.project.extend.earthquake.controller;
import java.util.List;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yelang.framework.web.controller.BaseController;
import com.yelang.framework.web.domain.AjaxResult;
import com.yelang.project.extend.earthquake.domain.UrbanRoadMileageInfoVO;
import com.yelang.project.extend.earthquake.service.IUrbanRoadMileageInfoService;
@Controller
@RequestMapping("/eq/urbanroadmileageinfo")
public class UrbanRoadMileageInfoController extends BaseController{
    private String prefix = "earthquake/urbanroadmileageinfo";
    @Autowired
    private IUrbanRoadMileageInfoService urbanRoadMileageInfoService;
    @RequiresPermissions("eq:urbanroadmileageinfo:map")
    @GetMapping("/")
    public String main(ModelMap mmap){
        return prefix + "/main";
    }
    @RequiresPermissions("eq:urbanroadmileageinfo:list")
    @GetMapping("/data/{pcode}")
    @ResponseBody
    public AjaxResult ewsnProvinceList(@PathVariable("pcode") String pcode){
        List<UrbanRoadMileageInfoVO> dataList = urbanRoadMileageInfoService.getRoadMileageList(pcode);
        return AjaxResult.success().put("data", dataList);
    }
}

三、WebGIS 界面实现

1、里程图例及初始化

根据不同道路长度设置颜色配置数组。

//里程颜色配置
var colorList = [
    {name:"5 千公里以下",color:"#00FF00",rgb:new Color(0, 255, 0),colorDesc:"绿色"},
    {name:"5 千 -8 千公里",color:"#FFFF00",rgb:new Color(255, 255, 0),colorDesc:"黄色"},
    {name:"8 千 -1.1 万公里",color:"#FFA500",rgb:new Color(255, 165, 0),colorDesc:"蓝色"},
    {name:"1.1 万 -1.4 万公里",color:"#113fc1",rgb:new Color(255, 0, 0),colorDesc:"橙色"},
    {name:"1.4 万 -1.6 万公里",color:"#800080",rgb:new Color(128, 0, 128),colorDesc:"紫色"},
    {name:"1.6 万以上",color:"#FF0000",rgb:new Color(153, 51, 102),colorDesc:"红色"}
];

颜色识别转换方法:

function getColorByLength(length){
    if(length >= 0 && length <= 5000) { return "#00FF00"; }
    if(length >= 5001 && length <= 8000) { return "#FFFF00"; }
    if(length >= 8001 && length <= 11000) { return "#FFA500"; }
    if(length >= 11001 && length <= 14000) { return "#113fc1"; }
    if(length >= 14001 && length <= 16000) { return "#800080"; }
    if(length >= 16001) { return "#FF0000"; }
}

2、各地市信息展示

数据库保存单位为米,页面展示需转换为万公里。

function buildShowInfo(index,color,data){
    var length = parseFloat(data.totalLength) / (1000.0 * 10000 );
    var result = "<div + color + ";' animation-spaceInDown onclick='showDetails("+data.cityCode+")'><div>" + data.cityName ;
    result += "<span>:"+ length.toFixed(2) +"万公里</span></div>";
    result += "</div>";
    return result;
}

道路地图标注方法:

function previewRoadMap(pid,provinceCode,name){
    previewProvince(pid,name);
    $.ajax({
        type:"get",
        url:ctx + "eq/urbanroadmileageinfo/data/" + provinceCode,
        data:{},
        dataType:"json",
        cache:false,
        processData:false,
        success:function(result){
            if(result.code == web_status.SUCCESS){
                collisionLayer.clearLayers();
                var dataArray = result.data;
                if(dataArray != null && dataArray.length > 1){
                    var legendData = new Array();
                    for(var i =0;i< dataArray.length;i++){
                        var areaData = dataArray[i];
                        var tempTotalLength = parseFloat(areaData.totalLength) / 1000.0;
                        var color = getColorByLength(tempTotalLength);
                        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) });
                        showLayerGroup.addLayer(areaLayer);
                        L.marker([areaData.lat, areaData.lon], { icon: myIcon}).addTo(collisionLayer);
                    }
                    collisionLayer.addTo(showLayerGroup);
                }
            }
        },
        error:function(){
            $.modal.alertWarning("获取空间信息失败");
        }
    });
}

四、成果展示

1、总体展示

文章配图

按道路里程降序排序结果如下:

430100 长沙市 17753221.56551351
430400 衡阳市 14434666.394707818
430600 岳阳市 14222249.927994445
430900 益阳市 13073704.1462314
430700 常德市 11931665.375579692
431100 永州市 10818152.494340602
431000 郴州市 10666092.158735342
431200 怀化市 10115713.30456733
430500 邵阳市 9892107.19298748
430200 株洲市 7374936.096146714
433100 湘西土家族苗族自治州 6795835.819083372
431300 娄底市 572764.899432551
430300 湘潭市 4861742.381742725
430800 张家界市 3836270.2965029962

省会长沙市、衡阳市、岳阳市位列前三,空间分布集中在东部和东南部。

2、分区域说明

文章配图

道路里程较长的集中在东北部的岳阳、益阳、常德等地区和南部的衡阳市。

文章配图

湘西北的道路里程相对较弱,可能与山区地质环境有关。

文章配图

南部地区除衡阳外,邵阳、永州、郴州等地市排名中等,未来交通发展需合理规划。

五、总结

本文介绍了基于 Java 和 Leaflet 构建湖南省道路长度 WebGIS 系统的实践。通过将 Java 和 Leaflet 结合,为系统构建提供了良好的技术平台。未来可进一步完善功能,如增加道路拥堵实时监测、与其他交通系统集成,并探索人工智能、大数据等技术应用,为道路管理提供智能化解决方案。

  • Java Web 开发环境搭建:IDEA 与 Tomcat 安装部署指南
  • 2026 年全球十大 AI 大模型深度解析
  • 基于YOLOv8的智能停车位检测系统(Python+PySide6)
  • 基于YOLOv5-v8的快递包裹检测系统(Python+PySide6+训练代码)
  • 前端无障碍性实践:确保网站对所有人可用
  • 从后端视角理解前端三基石:HTML、CSS 与 JavaScript
  • VS Code 内置聊天与 GitHub Copilot Chat 区别及汉化指南
  • GitHub Copilot 代码生成工具简介
  • HBuilder 真机运行模块脚本加载失败解决方案
  • Docker 部署 OpenJDK 指南:替代方案、步骤与最佳实践
  • YOLOv8 算法架构、核心创新与部署详解
  • YOLOv8 算法详解:架构、核心创新与部署实践