Skip to content

Commit

Permalink
Change handling of platforms with multiple dhids
Browse files Browse the repository at this point in the history
  • Loading branch information
janikkaden committed Aug 24, 2023
1 parent 7f3a6d5 commit 380fd0e
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 74 deletions.
4 changes: 2 additions & 2 deletions pipeline/stop_places/lua/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package.path = package.path .. ';/scripts/osm2pgsql/?.lua'

require 'stop_areas'
require 'platforms'
require 'platforms_members'
require 'platforms_edges'
require 'stop_positions'
require 'entrances'
require 'parking'
Expand All @@ -20,7 +20,7 @@ end

function osm2pgsql.process_way(object)
if extract_platforms(object, 'way') then return end
if extract_platforms_members(object, 'way') then return end
if extract_platforms_edges(object, 'way') then return end
if extract_parking(object, 'way') then return end
if extract_highways(object, 'way') then return end
extract_pois(object, 'way')
Expand Down
49 changes: 14 additions & 35 deletions pipeline/stop_places/lua/platforms.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,42 +18,21 @@ local extract_conditions = {
}
}

-- Create tables

local tables = {
-- Create table that contains all platforms
platforms_table = osm2pgsql.define_table({
name = "platforms",
ids = {
type = 'any',
id_column = 'osm_id',
type_column = 'osm_type'
},
columns = {
{ column = 'IFOPT', type = 'text', not_null = true },
{ column = 'tags', type = 'jsonb', not_null = true },
{ column = 'geom', type = 'geometry', not_null = true, projection = 4326 }
}
}),

-- Create table that contains the mapping of the public_transport area to its members
platforms_members_ref = osm2pgsql.define_relation_table("platforms_members_ref", {
{ column = 'member_id', type = 'BIGINT' },
{ column = 'osm_type', type = 'text', sql_type = 'CHAR(1)' }
})
}

platforms_table = osm2pgsql.define_table({
name = "platforms",
ids = {
type = 'any',
id_column = 'osm_id',
type_column = 'osm_type'
},
columns = {
{ column = 'IFOPT', type = 'text', not_null = true },
{ column = 'tags', type = 'jsonb', not_null = true },
{ column = 'geom', type = 'geometry', not_null = true, projection = 4326 }
}
})

function extract_platforms(object, osm_type)
local is_platform = extract_by_conditions_to_table(object, osm_type, extract_conditions, tables.platforms_table)
if is_platform and osm_type == 'relation' then
-- Go through all members and store them in a separate reference table
for _, member in ipairs(object.members) do
tables.platforms_members_ref:add_row({
member_id = member.ref,
osm_type = member.type:upper()
})
end
end
return is_platform
return extract_by_conditions_to_table(object, osm_type, extract_conditions, platforms_table)
end
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ local extract_conditions = {
}
}

-- Create table that contains members of platforms
local platforms_members_table = osm2pgsql.define_table({
name = "platforms_members",
-- Create table that contains edges of platforms
local platforms_edges_table = osm2pgsql.define_table({
name = "platforms_edges",
ids = {
type = 'any',
id_column = 'osm_id',
Expand All @@ -23,6 +23,6 @@ local platforms_members_table = osm2pgsql.define_table({
})


function extract_platforms_members(object, osm_type)
return extract_by_conditions_to_table(object, osm_type, extract_conditions, platforms_members_table)
function extract_platforms_edges(object, osm_type)
return extract_by_conditions_to_table(object, osm_type, extract_conditions, platforms_edges_table)
end
51 changes: 19 additions & 32 deletions pipeline/stop_places/sql/stop_places.sql
Original file line number Diff line number Diff line change
Expand Up @@ -623,51 +623,38 @@ CREATE OR REPLACE AGGREGATE jsonb_combine(jsonb)
* QUAYS *
*********/

/*
* Create view that splits all platforms that have multiple IFOPTs into multiple platforms.
* The tags of the platform relation and the corresponding ref entry are merged.
* The geometry, id and type of the ref element is used as the new platform element.
/* Create view that splits all platforms that have multiple IFOPTs into multiple platforms.
* Ways that touch a platform and have the corresponding ref tag are added to the platform edges.
* This is done by using the ST_Touches function.
* The ST_Touches function is used to find all edges that share a node with a platform.
* Platform edges can be part of a platform relation or must share some node with a platform.
* Because of this just using the members of a platform relation is not sufficient.
* This is only done for platforms that don't are a relation and therefore still have multiple IFOPTs.
*/
CREATE OR REPLACE VIEW platforms_split AS (
SELECT p1.member_osm_type, p1.member_osm_id, p2."IFOPT", jsonb_concat(p.tags, p1.tags) as tags, p1.geom
SELECT COALESCE(pe.osm_type,p.osm_type) as osm_type,
COALESCE(pe.osm_id,p.osm_id) as osm_id,
COALESCE(p1."IFOPT",p."IFOPT") as "IFOPT",
COALESCE(jsonb_concat(p.tags, pe.tags), p.tags) as tags,
COALESCE(pe.geom,p.geom) as geom
FROM platforms p
-- Join the mapping of platforms to their corresponding ref entry
-- only the rows where the IFOPT has multiple values are used (IFOPT entries with a ';' in them)
JOIN
(
SELECT ptr.relation_id as platform_osm_id, pts.osm_id as member_osm_id, ptr.osm_type as member_osm_type, pts.tags->>'ref' as "ref", pts.tags, pts.geom as geom
FROM platforms_members pts
JOIN platforms_members_ref ptr
ON pts.osm_id = ptr.member_id AND pts.osm_type = ptr.osm_type
) p1
ON p."IFOPT" LIKE '%;%' AND
p1.platform_osm_id = p.osm_id
LEFT JOIN platforms_edges pe
ON p."IFOPT" LIKE '%;%' AND ST_Touches(p.geom, pe.geom) AND array_position(string_to_array(p.tags->>'ref', ';'), pe.tags->>'ref') IS NOT NULL
-- Join the mapping of splitted IFOPTs to the corresponding ref entry
-- only the rows where the IFOPT has multiple values are used
-- unnest is used to split the IFOPTs and refs into multiple corresponding rows
JOIN
LEFT JOIN
(
SELECT unnest(string_to_array(p."IFOPT", ';')) as "IFOPT", unnest(string_to_array(p.tags->>'ref', ';')) as pref from platforms p
SELECT unnest(string_to_array(p."IFOPT", ';')) as "IFOPT", unnest(string_to_array(p.tags->>'ref', ';')) as p_ref from platforms p
WHERE p."IFOPT" LIKE '%;%'
) p2
) p1
ON
p2.pref = p1."ref"
p1.p_ref = pe.tags->>'ref'
);


/*
* Insert all newly generated splitted platforms into the platforms table.
*/
INSERT INTO platforms
SELECT * FROM platforms_split;


/*
* Delete all platforms with multiple IFOPTs that have been splitted before.
*/
DELETE FROM platforms p WHERE p."IFOPT" LIKE '%;%';


/*
* Sometimes there can be multiple platforms with the same IFOPT that have to be merged into one single platform.
* See: https://github.com/OPENER-next/osm2vdv462/issues/8
Expand All @@ -691,7 +678,7 @@ CREATE OR REPLACE VIEW platforms_merged AS (
-- only cluster elements that are directly next to each other (distance of 0)
-- at least two elements are required to create a cluster
ST_ClusterDBSCAN(geom, 0, 1) OVER() AS cluster_id
FROM platforms
FROM platforms_split
) p1
GROUP BY p1."IFOPT", p1.cluster_id
);
Expand Down

0 comments on commit 380fd0e

Please sign in to comment.