Разделить линии дорожной сети OSM после импорта OSM2PO для создания водосбора с pgrouting

Я хочу создать водосбор с pgrouting на основе файла osm.pbf. После импорта pbf-файла с OSM2PO расчет водосбора с pgrouting работает нормально. Но для более детального результата было бы неплохо разбить все более длинные дороги хотя бы через 2 км. Разделение строк с помощью PostGIS не проблема, но это разрушит мою сеть маршрутизации. Есть ли другой способ добавить больше вершин? Спасибо!


person Martin    schedule 04.04.2018    source источник


Ответы (1)


На самом деле, вы можете разделить линии дорог, как вам нравится, а затем воссоздать свой дорожный граф с помощью pgr_createTopology и pgr_analyzeGraph. Мне удалось сделать это, используя следующую функцию в plpgsql

CREATE OR REPLACE FUNCTION public.__create_roads_graph(
    tabname text)
    RETURNS text
    LANGUAGE 'plpgsql'
AS $BODY$

DECLARE
        counter integer;
        expr text;
        vert_tab character varying;
        r record;
BEGIN
    expr := 'select count(*) as cnt from %s';
    expr := format(expr, tabname);
    counter := 0;
    for r in execute expr
    loop
        counter = r.cnt;
    end loop;
    if counter = 0
    then
        return 'Cancel';
    end if;

    expr := 'update ' || tabname || ' set km = ST_Length(geom_way::geography)/1000';
    execute expr;
    expr := 'update ' || tabname || ' set kmh=(CASE WHEN class=1 THEN 90 WHEN class=2 THEN 60 WHEN class=3 THEN 30 WHEN class=4 THEN 10 ELSE 0 END)
                            WHERE kmh is null OR kmh < 1';
    execute expr;
    expr := 'update ' || tabname || ' set cost = km / kmh where cost is null or cost=0';
    execute expr;
    expr := 'update ' || tabname || ' set reverse_cost = km / kmh where reverse_cost is null or reverse_cost=0';
    execute expr;
    expr := 'update ' || tabname || ' set x1=ST_X(ST_StartPoint(geom_way)), 
                           y1=ST_Y(ST_StartPoint(geom_way)), 
                           x2=ST_X(ST_EndPoint(geom_way)), 
                           y2=ST_Y(ST_EndPoint(geom_way))';
    execute expr;
    expr := format('select * from pgr_createTopology( %L, %s, %L, %L, %L, %L, %L, %s)', 
                   tabname, 0.000001, 'geom_way', 'id', 'source', 'target', 'true', 'true');
    execute expr;

    vert_tab := tabname ||  '_vertices_pgr';
    perform __bvv_recreate_vertices_table(vert_tab);

    expr := format('insert into %s(id, cnt, the_geom) with RECURSIVE united as (SELECT source AS id, x1 AS x, y1 AS y
                       FROM %s UNION ALL select target AS id, x2 AS x, y2 AS y
                       FROM %s) select id, count(*) as cnt, 
                       ST_SetSrid(ST_MakePoint(avg(x), avg(y)), 4326) from united group by id order by id', 
                        vert_tab, tabname, tabname);



    /*expr := format('select * from pgr_analyzeGraph( %L, %s, %L, %L, %L, %L)', 
                   tabname, 0.000001, 'geom_way', 'id', 'source', 'target');*/
    execute expr;
    RETURN 'Ok';
END

Вы можете увидеть, как выглядит маршрут до разделения сегмента дороги Узлы и маршрут до разделения

После разделения и выполнения функции _create_roads_graph вы видите дополнительный узел в центре линии, измененную нумерацию узлов и идентичный предыдущему маршруту

После разделения

person Vadym    schedule 01.12.2018