实现目标
- 通过raster2pgsql命令将一份 TIF 格式的数字高程数据导入到postgresql+postgis数据库中;
- 并实现根据坐标查询高程值的功能;
实验环境
- Ubuntu 22.04 + Postgresql 14 + PostGIS 3.2
- 导入栅格数据文件名词 dem.tif
- 导入数据库的 schema 为 public,新创建的数据表名称为 dem
实现步骤
-
首先确保 postgresql 数据库支持 raster 数据类型。不然执行数据导入时会报 ERROR: type “raster” does not exist Position 的错误。在 postgresql 控制台执行如下命令安装支持栅格数据的扩展插件:
CREATE EXTENSION postgis_raster;
-
通过 raster2pgsql 命令将栅格数据转换成导入数据库的 SQL 脚本文件。
raster2pgsql -I -C -F -t 100x100 -s 4326 dem.tif public.dem > dem.sql # ----- 参数说明 ------- # -I 对空间字段创建空间索引 # -C 对空间数据字段创建标准的数据库约束 # -F 增加一个属性字段存储生成该切片的数据文件名。如果同一个表中存储多个tif导入的数据时有用。 # -t 切片数据的大小,格式为 width x height。值为 auto 时自动计算切片大小 # -s 栅格数据的投影编号,实验数据为 4326 投影
-
通过 psql 命令执行 SQL 脚本,将数据导入数据库。
psql -h localhost -p 5432 -d postgres -U db_user_name -W -f dem.sql # ----- 参数说明 ------- # -h 数据库服务的主机地址,示例使用安装再本机的数据库,地址为locahost # -p Postgresql数据库运行的端口号,默认 5432 可以不写 # -d 导入目标数据库的名称,示例使用默认数据库 postgres # -U 链接数据库的用户名,根据本地实际情况替换 # -W 必须使用输入秘密方式登陆 # -f 要执行的 SQL 脚本文件路径
-
查询指定坐标位置的高程数据,例如要查询经纬度(106.1253, 29.5052)位置点高程值
SELECT ST_Value(rast, ST_SetSRID(ST_MakePoint(106.1253, 29.5052), 4326)) val FROM dem WHERE ST_Intersects(rast, ST_SetSRID(ST_MakePoint(106.1253, 29.5052), 4326))
- 通过 ST_MakePoint 函数创建要查询的点对象
- 通过 ST_SetSRID 函数设置创建点对象的空间投影
- 通过 ST_Intersects 函数查询出该点所在的栅格切片 rast
- 通过 ST_Value 函数从找到的 rast 切片中提取指定位置的高程值
-
查询指定空间范围内某条线上各个点位置对应的高程值
SELECT ST_Value(dm.rast, ps.geom) val FROM dem AS dm, ( SELECT (ST_DumpPoints(geom)).geom FROM a_line_data WHERE ST_Intersects(geom, ST_MakeEnvelope( 106.0950, 29.4494, 106.1470, 29.5090, 4326)) ) AS ps WHERE ST_Intersects(dm.rast, ps.geom))
- 通过 ST_MakeEnvelope 函数创建要查询的空间范围
- 通过 ST_DumpPoints 函数将查询到的线数据导出成一组点坐标
- 通过 ST_Intersects 函数查询出各个点所在的栅格切片 rast
- 通过 ST_Value 函数从找到的 rast 切片中提取指定点位置的高程值
应用场景
- 查询一条河流所在流域范围内的地形高度落差,也就是河道落差。
- 查询一条道路所经过区域的地形高度变化,获取道路的坡度。