首页 > 作文

使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐)

更新时间:2023-04-04 16:11:57 阅读: 评论:0

目录
基础准备工作1.postgis 的安装2.加载post gis扩展3.河流矢量图层转成单线格式4.河流矢量数据导入postgresql数据库5.河流数据拓扑处理pg分析处理函数1.函数编写2.参数说明3.内部调用函数说明4.输出结果验证

基础准备工作

1.postgis 的安装

在安装postgis前首先必须安装postgresql,然后再安装好的stack builder中选择安装postgis组件。具体安装步骤可参照postgis的安装与初步使用

2.加载post gis扩展

选中指定数据库,执行加载扩展语句

–添加支持create extension postgis;  --添加postgis扩展create extension pgrouting;   --添加pgrouting扩展create extension postgis_topology;create extension fuzzystrmatch;create extension postgis_tiger_geocoder;

在做两点间河流轨迹及流经长度计算过程中,需要加载postgis和pgrouting两个扩展

可以通过查看加载扩展的版本验证扩展加载是否成功

–查看postgresql版本show rver_version;–查看postgis版本lect postgis_full_version();–查看pgrouting版本lect pgr_version();

3.河流矢量图层转成单线格式

河流包括各种汇入和汇出,为了实现流经流域的计算,河流水系矢量数据需要一个河流一个id的方式,可以在河流交汇点处将河流进行打段处理。

4.河流矢量数据导入postgresql数据库

打开位于“开始>所有程序>postgis 2.3 bundle for postgresql”之中的postgis shapefile import/export manager。

首先单击”view connection details”按钮,打开”postgis connection”对话框,输入用户名”postgres”及其对应的密码,设置连接的数据库,如下图所示:

连接数据库之后,单击”add file”按钮,加入***.shp文件,并将其srid设置为”4326″,如下图所示。这一步绝对不能省略,否则不能正确导入数据。

5.河流数据拓扑处理

在数据分析过程中,使用到了pgrouting扩展中的 pgr_dijkstra 算法

dijkstra算法(迪杰斯特拉算法),由荷兰计算机科学家edsger dijkstra于1956年提出。它是一种图搜索算法,它解决了非负代价边路径图的最短路径问题,即从起始顶点(start_vid)到结束顶点(end_vid)的最短路径。此算法可以与有向图或无向图一起使用。

函数的签名摘要:

在实际使用中,需要先明确所有的顶点,并为所有顶点分配唯一的编号,拓展训练激励口号函数的 start_vid 和 end_vid 都是整型数值,函数使用edges_sql参数(sql脚本)筛选出和顶点相邻的所有边信息(即河流信息)。

所以,在使用pgr_dijkstra方法前,需要

对找到河流的所有顶点信息,并做唯一整型值编号在数据库中为每条河流设置好起始顶点和结束顶点
--筛选出所有顶点信息,st_dump函数主要是将multilinestring类型 调整成 linestring类型lect  st_astext(st_startpoint((st_dump(geom)).geom)) from singleriverunion lect  st_astext(st_endpoint((st_dump(geom)).geom)) from singleriver

将查询结果在excel中进行整型值编号,再导入到postgresql中的新建表distinctpoint 中,然后关联河流数据表,更新河流的开始顶点(source)和结束顶点编号(target)

--更新起始顶点编号update singleriver qt source=tt.sourcepointfrom singleriver s,(lect gid,p.id as sourcepoint from (lect gid,st_astext(st_startpoint((st_dump(geom)).geom)) as startpoint, st_astext(st_endpoint((st_dump(geom)).geom)) as endpoint from singleriver )sleft join distinctpoint pon s.startpoint=p.point) ttwhere q.gid=tt.gid
--插入结束顶点编号update singleriver qt target=tt.endpointfrom singleriver s,(lect gid,p.id as endpoint from (lect gid,st_astext(st_startpoint((st_dump(geom)).geom)) as startpoint, st_astext(st_endpoint((st_dump(geom)).geom)) as endpoint from singleriv花木兰影评er )sleft join distinctpoint pon s.endpoint=p.point) ttwhere q.gid=tt.gid

至此,河流拓扑数据处理完成

pg分析处理函数

1.函数编写

create or replace function "public"."pgr_shortest_river"(in "star次氯酸是强酸还是弱酸tx" float8, in "starty" float8, in "endx" float8, in "endy" float8, out "river_name" varchar, out "v_shpath" varchar, out "cost" float8)  returns tof "pg_catalog"."record" as $body$ declare v_startline geometry;--离起点最近的线 v_endline geometry;--离终点最近的线 v_starttarget integer;--距离起点最近线的终点 v_endsource integer;--距离终点最近线的起点 v_statpoint geometry;--在v_startline上距离起点最近的点 v_endpoint geometry;--在v_endline上距离终点最近的点 v_res geometry;--最短路径分析结果 v_perstart float;--v_statpoint在v_res上的百分比 v_perend float;--v_endpoint在v_res上的百分比 v_rec record; first_name varchar;end_name varchar;first_cost double precision;end_cost double precision;begin --查询离起点最近的线 execute 'lect (st_dump(geom)).geom as geom,target as target,name from singleriver where st_dwithin(geom,st_geometryfromtext(''point('|| startx ||' ' || starty||')''),0.01) order by st_distance(geom,st_geometryfromtext(''point('|| startx ||' '|| starty ||')'')) limit 1' into v_startline ,v_starttarget,first_name; rai notice '起点线段%',v_startline;rai notice '起点位置%',v_starttarget;rai notice '河流名称%',first_name;--查询离终点最近的线 execute 'lect (st_dump(geom)).geom as geom,"source" as source,name from singleriverwhere st_dwithin(geom,st_geometryfromtext(''point('|| endx || ' ' || endy ||')''),0组织文化.01) order by st_distance(geom,st_geometryfromtext(''point('|| endx ||' ' || endy ||')'')) limit 1' into v_endline,v_endsource,end_name; --如果没找到最近的线,就返回null if (v_startline is null) or (v_endline is null) then return; end if ; lect st_clostpoint(v_startline, st_geometryfromtext('point('|| startx ||' ' || starty ||')')) into v_statpoint; lect st_clostpoint(v_endline, st_geometryfromtext('point('|| endx ||' ' || endy ||')')) into v_endpoint; --计算距离起点最近线上的点在该线中的位置lect st_linelocatepoint(st_linemerge(v_startline), v_statpoint) into v_perstart;lect st_linelocatepoint(st_linemerge(v_endline), v_endpoint) into v_perend;lect st_distancesphere(v_statpoint,st_pointn(st_geometryn(v_startline,1), st_numpoints(st_geometryn(v_startline,1)))) into first_cost;lect st_distancesphere(st_pointn(st_geometryn(v_endline,1),1),v_endpoint) into end_cost; if (st_int活出自己的霸道句子ercts(st_geomfromtext('point('|| startx ||' '|| starty ||') '), v_startline) and st_intercts(st_geomfromtext('point('|| endx ||' '|| endy ||') '), v_startline)) then lect st_distancesphere(v_statpoint, v_endpoint) into first_cost;lect st_linelocatepoint(st_linemerge(v_startline), v_endpoint) into v_perend;for v_rec in lect st_linesubstring(st_linemerge(v_startline), v_perstart,v_perend) as point,coalesce(end_name,'无名河流') as name,end_cost as cost loopv_shpath:= st_asgeojson(v_rec.point);cost:= v_rec.cost;river_name:= v_rec.name;return next;end loop;return;end if;--最短路径 for v_rec in (lect st_linesubstring(st_linemerge(v_startline),v_perstart,1) as point,coalesce(first_name,'无名河流') as name,first_cost as costunion alllect st_linemerge(b.geom) as point,coalesce(b.name,'无名河流') as name,st_length(geom, fal) as costfrom pgr_dijkstra('lect gid as id, source, target, st_length(geom, fal) as cost from singleriverwhere st_intercts(geom,st_buffer(st_linefromtext(''linestring('||startx||' ' || starty ||','|| endx ||' ' || endy ||')''),0.05))', v_starttarget, v_endsource , fal ) a, singleriver b where a.edge = b.gidunion alllect st_linesubstring(st_linemerge(v_endline),0,v_perend) as point,coalesce(end_name,'无名河流') as name,end_cost as cost)loopv_shpath:= st_asgeojson(v_rec.point);cost:= v_rec.cost;river_name:= v_rec.name;return next;end loop; end; $body$  language plpgsql volatile strict  cost 100  rows 1000

2.参数说明

输入参数:开始点和结束点的经纬度坐标

输出结果:river_name:河流名称;v_shppath:流经的河流路径; cost:河流流经长度

3.内部调用函数说明

函数调用过程,根据postgis不同版本,函数名称可能会有偏差,有版本展示形式为st_linesubstring ,有版本展示形式为st_line_substring

4.输出结果验证

为了验证河流输出结果是否正确,流经河流路径是否连通,可以通过在线geojson地图(geojson.io)呈现出来验证。

在右侧json-features-geometry 中填充函数输出的v_shppath参数内容(按照行单独输入,可以输入多个,注意需要增加json属性)

到此这篇关于使用postgis完成两点间的河流轨迹及流经长度的计算的文章就介绍到这了,更多相关postgis两点间的河流轨迹计算内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 16:11:56,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/a5b3ff2a7815bc17b781a67d653e645d.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐).doc

本文 PDF 下载地址:使用PostGIS完成两点间的河流轨迹及流经长度的计算(推荐).pdf

标签:河流   顶点   函数   起点
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图