postgis+geoserver实现路径规划遇到的问题及解决方法

    技术2022-07-10  131

    ERROR: line_locate_point: 1st arg isn’t a line

    可能原因:

    ST_Line_Locate_Point函数处的参数问题 参考博客PostGIS 结合Openlayers以及Geoserver实现最短路径分析(二)使用openlayers+geosrever实现路线规划并没有出现结果,之后修改了部分代码终于解决了问题。 修改的函数代码: CREATE OR REPLACE FUNCTION "public"."pgr_shortestpath"("tbl" varchar, "startx" float8, "starty" float8, "endx" float8, "endy" float8) RETURNS "public"."geometry" AS $BODY$ declare v_startLine geometry;--离起点最近的线 v_endLine geometry;--离终点最近的线 v_startTarget integer;--距离起点最近线的终点 v_startSource integer; v_endSource integer;--距离终点最近线的起点 v_endTarget integer; v_statpoint geometry;--在v_startLine上距离起点最近的点 v_endpoint geometry;--在v_endLine上距离终点最近的点 v_res geometry;--最短路径分析结果 v_res_a geometry; v_res_b geometry; v_res_c geometry; v_res_d geometry; v_perStart float;--v_statpoint在v_res上的百分比 v_perEnd float;--v_endpoint在v_res上的百分比 v_shPath_se geometry;--开始到结束 v_shPath_es geometry;--结束到开始 v_shPath geometry;--最终结果 tempnode float; begin --查询离起点最近的线 --4326坐标系 --找起点15米范围内的最近线 execute 'select geom, source, target from ' ||tbl|| ' where ST_DWithin(geom,ST_Geometryfromtext(''point('||startx ||' ' || starty||')'',4326),15) order by ST_Distance(geom,ST_GeometryFromText(''point('|| startx ||' '|| starty ||')'',4326)) limit 1' into v_startLine, v_startSource ,v_startTarget; --查询离终点最近的线 --找终点15米范围内的最近线 execute 'select geom, source, target from ' ||tbl|| ' where ST_DWithin(geom,ST_Geometryfromtext(''point('|| endx || ' ' || endy ||')'',4326),15) order by ST_Distance(geom,ST_GeometryFromText(''point('|| endx ||' ' || endy ||')'',4326)) limit 1' into v_endLine, v_endSource,v_endTarget; --如果没找到最近的线,就返回null if (v_startLine is null) or (v_endLine is null) then return null; end if ; raise notice '%', v_startLine; raise notice '%', v_endLine; select ST_ClosestPoint(v_startLine, ST_Geometryfromtext('point('|| startx ||' ' || starty ||')',4326)) into v_statpoint; select ST_ClosestPoint(v_endLine, ST_GeometryFromText('point('|| endx ||' ' || endy ||')',4326)) into v_endpoint; -- ST_Distance --从开始的起点到结束的起点最短路径 execute 'SELECT st_linemerge(st_union(b.geom)) ' || 'FROM pgr_kdijkstraPath( ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' ||v_startSource|| ', ' ||'array['||v_endSource||'] , false, false ) a, ' ||tbl|| ' b WHERE a.id3=b.gid GROUP by id1 ORDER by id1' into v_res ; --从开始的终点到结束的起点最短路径 execute 'SELECT st_linemerge(st_union(b.geom)) ' || 'FROM pgr_kdijkstraPath( ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' ||v_startTarget|| ', ' ||'array['||v_endSource||'] , false, false ) a, ' ||tbl|| ' b WHERE a.id3=b.gid GROUP by id1 ORDER by id1' into v_res_b ; --从开始的起点到结束的终点最短路径 execute 'SELECT st_linemerge(st_union(b.geom)) ' || 'FROM pgr_kdijkstraPath( ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' ||v_startSource || ', ' ||'array['||v_endTarget||'] , false, false ) a, ' || tbl || ' b WHERE a.id3=b.gid GROUP by id1 ORDER by id1' into v_res_c ; --从开始的终点到结束的终点最短路径 execute 'SELECT st_linemerge(st_union(b.geom)) ' || 'FROM pgr_kdijkstraPath( ''SELECT gid as id, source, target, length as cost FROM ' || tbl ||''',' ||v_startTarget || ', ' ||'array['||v_endTarget||'] , false, false ) a, ' || tbl || ' b WHERE a.id3=b.gid GROUP by id1 ORDER by id1' into v_res_d ; if(ST_Length(v_res) > ST_Length(v_res_b)) then v_res = v_res_b; end if; if(ST_Length(v_res) > ST_Length(v_res_c)) then v_res = v_res_c; end if; if(ST_Length(v_res) > ST_Length(v_res_d)) then v_res = v_res_d; end if; --如果找不到最短路径,就返回null --if(v_res is null) then -- return null; --end if; --将v_res,v_startLine,v_endLine进行拼接 raise notice '%', v_res; select ST_LineMerge(ST_Union(array[v_res,v_startLine,v_endLine])) into v_res; raise notice '%', v_res; select ST_Line_Locate_Point(ST_GeometryN(v_res,1), v_statpoint) into v_perStart; select ST_Line_Locate_Point(ST_GeometryN(v_res,1), v_endpoint) into v_perEnd; if(v_perStart > v_perEnd) then tempnode = v_perStart; v_perStart = v_perEnd; v_perEnd = tempnode; end if; --截取v_res --拼接线 SELECT ST_Line_SubString(v_res,v_perStart, v_perEnd) into v_shPath; raise notice '%', v_shPath; return v_shPath; end; $BODY$ LANGUAGE plpgsql VOLATILE STRICT COST 100

    这里注意ST_Line_Locate_Point接受的参数类型,可能会出现参数类型的错误,解决方法就是调用ST_GeometryN将前面得到的结果进行一次转换。

    传入了MultiLineString类型的数据 要实现路线规划的数据需要进行打断,打断方法可以参考: ArcMap将MultiLineString类型的线要素转换成LineString类型线要素,或者使用arcpy中FeatureToLine_management函数来打断。 但是打断之后把数据存入数据库之后调用函数st_geometrytype来查看数据类型还是MultiLineString,看了很多博客,目前只找到一种解决方法,就是使用positgis的插件PostGis Shapefile Import/Export Manager,在录入数据之前勾选 最后成功解决问题。 找不到PostGis Shapefile Import/Export Manager可以参考:postgis安装之后找不到PostGis Shapefile Import/Export Manager的解决方法

    openlayers路线规划结果出现很多杂乱线条的问题

    例图: geoserver配置: 将配置修改为: 解决: (具体原因没去研究)

    Processed: 0.014, SQL: 9