前言
在数字化时代,地理信息数据的分析与可视化对于城市规划、资源管理、环境监测及交通物流等领域至关重要。确定各省的东西南北四至极点所在的区县,并将其可视化展示,可以为相关领域的研究与决策提供有价值的参考。
本次研究聚焦于基于 SpringBoot 和 PostGIS 的各省东西南北四至极点区县可视化项目。本项目旨在整合 SpringBoot 的高效开发能力和 PostGIS 的强大空间数据处理功能,构建一个精准、实时且交互性强的可视化平台,为地理信息相关领域的研究和实践提供参考。
一、空间检索简介
本节重点介绍空间检索知识,包括空间表结构展示以及基于 PostGIS 进行省域范围的区县四至空间检索实践。
1、空间表结构
本实例涉及的空间表结构如下,该表存储区域信息(省份对象的区县信息):

具体的表结构 SQL 如下所示:
CREATE TABLE "public"."biz_area" (
"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,
"area_code" varchar(16) COLLATE "pg_catalog"."default" NOT NULL,
"area_name" varchar(512) COLLATE "pg_catalog"."default" NOT NULL,
"type" varchar(32) COLLATE "pg_catalog"."default",
"geom" "public"."geometry",
CONSTRAINT "pk_biz_area" PRIMARY KEY ("id")
);
区县表的查询数据结果如下所示:

2、四至空间检索
实现空间四至的求解,可转换为寻找当前面数据的四至范围极值的问题。因此只需要找到能包围当前面数据的最大点的坐标即可。为了方便实现按照某省份来查询其对应的四至范围,在 PostgreSQL 中使用子查询来进行数据的过滤,首先定义 with 子句。查询的 SQL 如下:
WITH temp_area AS (
SELECT * FROM biz_area T WHERE T.province_code = '510000'
),
bounds_info AS (
(SELECT '最东' AS direction, T.*, ST_X(dp.geom) AS x, ST_Y(dp.geom) AS y FROM temp_area T, LATERAL ST_DumpPoints(T.geom) AS dp ORDER BY x DESC LIMIT 1)
UNION
(SELECT '最西' AS direction, T.*, ST_X(dp.geom) AS x, ST_Y(dp.geom) AS y FROM temp_area T, LATERAL ST_DumpPoints(T.geom) AS dp ORDER BY x ASC LIMIT 1)
UNION
(SELECT '最北' AS direction, T.*, ST_X(dp.geom) AS x, ST_Y(dp.geom) AS y FROM temp_area T, LATERAL ST_DumpPoints(T.geom) AS dp ORDER BY y ASC LIMIT 1)
UNION
(SELECT '最南' direction, T., ST_X(dp.geom) x, ST_Y(dp.geom) y temp_area T, ST_DumpPoints(T.geom) dp y LIMIT )
)
direction,id, province_code, province_name, city_code, city_name,area_code,area_name,type,st_asgeojson(geom) geomJson, x lon,y lat bounds_info;
这里我们以四川省为例,查询四川省的四至县域结果:

可以直观地看到,四川省最东边是达州市的宣汉县,最西边是甘孜藏族自治州的石渠县,最南边是凉山彝族自治州的会理县,最北边是阿坝藏族羌族自治州的若尔盖县。
二、前后端实现
介绍完空间表以及四至的空间检索实现后,接下来介绍如何在前后端实现接口的接入和 WebGIS 界面的可视化。
1、后端实现
后端将前面的四至查询函数包装成一个公共的方法,供后续的分析方法调用。在 Mapper 中定义查询请求的方法体,具体代码如下:
static final String FIND_ESWNAREA_BYPROVINCE_SQL = "<script>" +
" WITH temp_area AS ( SELECT * FROM biz_area T WHERE T.province_code = #{province_code} ), " +
" bounds_info AS (" +
" ( SELECT '最东' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y " +
" FROM temp_area T,LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY x DESC LIMIT 1 " +
" ) UNION " +
" ( SELECT '最西' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y " +
" FROM temp_area T,LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY x ASC LIMIT 1 " +
" ) UNION " +
" ( SELECT '最南' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y " +
" FROM temp_area T, LATERAL ST_DumpPoints ( T.geom ) AS dp ORDER BY y ASC LIMIT 1 " +
" ) UNION " +
" (SELECT '最北' AS direction,T.*,ST_X ( dp.geom ) AS x,ST_Y ( dp.geom ) AS y " +
" FROM temp_area T, LATERAL ST_DumpPoints( T.geom ) AS dp ORDER BY y DESC LIMIT 1 " +
") SELECT direction,id,province_code,province_name,city_code,city_name,area_code, " +
" area_name,type, st_asgeojson(geom) geomJson, x lon,y lat FROM bounds_info " +
"</script>";
/**
* - 根据省份 code 查询对应省份的四至区县信息
* @param provinceCode 需要查询的目标省份 code
* @return
*/
@Select(FIND_ESWNAREA_BYPROVINCE_SQL)
List<EwsnAreaVo> findEswnAreaByProvinceCode(@Param("province_code")String provinceCode);
这里仅介绍 Mapper 的实现,具体的业务层和控制层代码比较简单,在此不再赘述。
2、前端集成
介绍完后端的方法实现后,再来介绍一下前端如何使用 Leaflet 来进行具体的展示。关于地图页面的展示分为两个部分,第一部分展示省份信息,第二部分是展示四至极值的所在区县信息。
首先是展示省份信息的方法,关键代码如下:
function previewProvince(gid,name){
var myStyle = {color:"red",weight:3,"opacity":0.65};
$.ajax({
type:"get",
url:prefix + "/geojson/" + gid,
data:{},
dataType:"json",
cache:false,
processData:false,
success:function(result){
if(result.code == web_status.SUCCESS){
var geojson = JSON.parse(result.data);
var areaLayer = L.geoJSON(geojson,{style:myStyle}).addTo(mymap);
var myIcon = L.divIcon({ className: 'my-div-icon', iconSize: 100 });
showLayerGroup.clearLayers();
showLayerGroup.addLayer(areaLayer);
}
},
error:function(){
$.modal.alertWarning("获取空间信息失败");
}
});
}
展示东南西北四至点和所在区县的核心方法如下:
function previewEwsn(pid,provinceCode,name){
previewProvince(pid,name);
$.ajax({
type:"get",
url:prefix + "/ewsnprovince/list/" + provinceCode,
data:{},
dataType:"json",
cache:false,
processData:false,
success:function(result){
if(result.code == web_status.SUCCESS){
var legendData = new Array();
for(var i=0;i< result.data.length;i++){
var areaData = result.data[i];
var color = ccolor = getRandomColor();
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({ : , : , :[,], :[,], : (i,color,areaData) });
showLayerGroup.(areaLayer);
L.([areaData.,areaData.], { : myIcon}).(showLayerGroup);
legendData.({ : +areaData. + areaData., : , : , : color, : color, : , : });
}
mymap.(showLayerGroup.());
(legendData);
}
},
:(){
$.modal.();
}
});
}
三、成果展示
从东西南北中四个方向各选取一些省份及其对应的四至区县来进行展示和讲解。各个省份排名不分先后,区县信息位置是准确的。
1、东部省份

上海市四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 上海崇明区 |
| 2 | 最东边 | 上海崇明区 |
| 3 | 最西边 | 上海青浦区 |
| 4 | 最南边 | 上海金山区 |

江苏省四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 连云港市赣榆区 |
| 2 | 最东边 | 南通市启东市 |
| 3 | 最西边 | 徐州市丰县 |
| 4 | 最南边 | 苏州市吴江区 |
2、西部省份

西藏自治区四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 那曲市双湖县 |
| 2 | 最东边 | 昌都市芒康县 |
| 3 | 最西边 | 阿里地区札达县 |
| 4 | 最南边 | 山南市错那县 |
3、南部省份

广西壮族自治区四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 桂林市全州县 |
| 2 | 最东边 | 贺州市八步区 |
| 3 | 最西边 | 百色市西林县 |
| 4 | 最南边 | 北海市海城区 |
4、北部省份

河北省四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 承德市围场满族蒙古族自治县 |
| 2 | 最东边 | 秦皇岛市山海关区 |
| 3 | 最西边 | 邯郸市涉县 |
| 4 | 最南边 | 邯郸市魏县 |
5、中部省份

湖北省四至:
| 序号 | 四至 | 所在区县 |
| 1 | 最北边 | 十堰市郧西县 |
| 2 | 最东边 | 黄冈市黄梅县 |
| 3 | 最西边 | 恩施土家族苗族自治州利川市 |
| 4 | 最南边 | 咸宁市通城县 |
四、总结
本文介绍了基于 SpringBoot 和 PostGIS 的各省东西南北四至极点区县可视化项目,整合了 SpringBoot 的高效开发能力和 PostGIS 的强大空间数据处理功能,构建了精准、实时且交互性强的可视化平台。


