文章同步更新于我的个人博客:松果猿的博客,欢迎访问获取更多技术分享。

同时,您也可以关注我的微信公众号:松果猿的代码工坊,获取最新文章推送和编程技巧。

首先创建数据库:

image-20250306141714903

执行以下语句安装postgis扩展:

1
CREATE EXTENSION postgis;

或者右键点击数据库的扩展>创建扩展

image-20250306143742427

数据库建好后,下面我们导入shp数据,在开始菜单找到PostGIS Shapefile and DBF Loader Exporter,打开它,准备将我们的数据导入数据库:

image-20250306141343481

在弹窗中点击View connection details连接我们刚刚创建的数据库

image-20250306141417693

输入用户名密码等等:

image-20250306141450959

在日志中看到Connection succeeded即成功:

image-20250306141915661

点击Add File将我们的数据添加进去:

image-20250306142336413

注意这里的文件路径不能有中文,点击Import导入数据库

image-20250306143335667

查看日志出现Shapefile import completed即导入成功

image-20250306143904193

下面我们来到查询工具执行语句

(1) 找出江苏省的邻省;

1
2
SELECT p1.name FROM province p1,province p2 
WHERE ST_Touches(p1.geom,p2.geom) AND p2.name='江苏省

image-20250306144703718

同理,以下是其他相关查询语句,熟悉不同类型的空间关系函数及使用方法:

(2) 找出京广线所经过的省份;

1
2
select railway.name, province.name from railway, province where
ST_Crosses(railway.geom,province.geom) and railway.name='京广线'

(3) 找出距离每条铁路最近的省会城市

1
2
3
SELECT c1.name , r.name FROM city c1, railway r 
WHERE ST_Distance(c1.geom,r.geom)<ALL(SELECT ST_Distance(c2.geom,r.geom)
FROM city C2 WHERE c1.name<>c2.name)

(4) 距离京广线 100 公里之内的的省会城市

1
2
SELECT c.name FROM railway r,city c 
WHERE ST_Within(c.geom,ST_Buffer(r.geom,100000)) and r.name='京广线'

(5) 列出每个省份的名字和面积

1
SELECT p.name, ST_Area(p.geom) Area FROM province p

(6) 求出每条铁路经过的省份及在其境内的长度 intersects & intersection

1
2
SELECT r.name,p.name,ST_Length(ST_Intersection(r.geom,p.geom)) Length FROM 
railway r,province p WHERE ST_Crosses(r.geom,p.geom) and ST_IsValid(p.geom)=true

(7) 每个城市到北京的距离

1
2
SELECT c1.name,ST_Distance(c1.geom,c2.geom) Distance 
FROM city c1, city c2 WHERE c2.name='北京'

(8) 按照邻省数目列出所有省份;

1
2
3
SELECT p1.name, Count(p2.name) FROM province p1, province p2 
WHERE ST_Touches(p1.geom,p2.geom)
GROUP BY p1.name ORDER BY Count(p2.name)

(9) 查询只有一个邻省的省份;

1
2
3
SELECT p1.name, Count(p2.name) FROM province p1, province p2 
WHERE ST_Touches(p1.geom,p2.geom)
GROUP BY p1.name HAVING Count(p2.name)=1

(10) 查询邻省最多的省份。

第 1 步:

1
2
3
CREATE VIEW Neighbor AS 
SELECT p1.name,Count(p2.name) num_neighbors FROM province p1, province p2
WHERE ST_Touches(p1.geom, p2.geom) GROUP BY p1.name

第 2 步:

1
2
SELECT name, num_neighbors FROM Neighbor WHERE 
num_neighbors=(SELECT Max(num_neighbors) FROM Neighbor)

本文的相关shp数据下载链接:https://github.com/songguo1/postgresql