rustprooflabs / pgosm-flex

PgOSM Flex provides high quality OpenStreetMap datasets in PostGIS (Postgres) using the osm2pgsql Flex output.
MIT License
100 stars 20 forks source link

Add turn restriction layer / data #400

Open rustprooflabs opened 1 month ago

rustprooflabs commented 1 month ago

Details

A discussion about turn restrictions on the main osm2pgsql project (https://github.com/osm2pgsql-dev/osm2pgsql/discussions/2215) caught my eye. The idea seems worth exploring to attempt to add a turn restriction layer to PgOSM Flex.

I think this could be implemented similarly to the nested place polygon data set. Some data will be loaded to Postgres via osm2pgsql, and custom functions are developed to handle loading data from that data set into a structure that is usable for common use cases.

What needs to be done?

While I fully intend to work forward on this idea as I have time.... Help is appreciated! Everything from ideas shared in comments, reviewing PRs, and submitting PRs is welcome (see the contributing page). I'll keep this issue updated as progress is made.

Example Starting Point

This file was shared in the original discussion: https://raw.githubusercontent.com/Andreas4242/Andreas_file_tools/main/compatible.lua

The relevant bits to integrate into PgOSM Flex are below. This site seems to be a good place to verify what is expected in the data. https://ahorn.lima-city.de/tr/

turn_restrictions = osm2pgsql.define_table{
    name = prefix .. 'turn_restrictions',
    ids = { type = 'relation', id_column = 'relation_id' },
    columns = {
        { column = 'restriction', type = 'text' },
        { column = 'from_way', type = 'bigint' },
        { column = 'via_node', type = 'bigint', null = true },
        { column = 'to_way', type = 'bigint' },
        { column = 'members', type = 'jsonb' },
        { column = 'tags', type = 'jsonb' }
    }
}

function osm2pgsql.process_relation(object)
    if clean_tags(object.tags) then
        return
    end

     if object.tags.type == 'restriction' then
        local restriction = {
            restriction = object.tags.restriction or 'no_turn',
            from_way = -1,
            via_node = nil,
            to_way = -1,
            members = object.members,
            tags = object.tags
        }

        for _, member in ipairs(object.members) do
            if member.role == 'from' and member.type == 'w' then
                restriction.from_way = member.ref
            elseif member.role == 'to' and member.type == 'w' then
                restriction.to_way = member.ref
            elseif member.role == 'via' and member.type == 'n' then
                restriction.via_node = member.ref
            end
        end

        -- Debugging: Print the restriction data before inserting
        -- print("Restriction Data: ", table_to_string(restriction))

        turn_restrictions:insert(restriction)
    end

...
...
...