DROP table if exists tempseg.relation_direction_geometries;
CREATE SEQUENCE tempseg_relation_direction_geometries_seq increment by 2;
SELECT rr.id as relation_id,sequence_id,linestring,
nextval('tempseg_relation_direction_geometries_seq') as ordering,
CASE WHEN rr.direction = 'roles' THEN
CASE WHEN m.member_role='' then 'any'
WHEN m.member_role is null then 'any'
--handle US:US 6, North&East, West&South
WHEN relation_id=337473 then
CASE WHEN m.member_role='east' then 'north'
WHEN m.member_role='west' then 'south'
ELSE m.member_role
END
ELSE m.member_role
END
WHEN rr.direction='' then 'any'
WHEN rr.direction is null then 'any'
ELSE rr.direction
END as direction
into tempseg.relation_direction_geometries
FROM route_relations rr
JOIN relation_members AS m ON (rr.id=m.relation_id)
JOIN ways AS w ON ( member_id = w.id )
WHERE npoints(linestring) > 1 -- has to be a line or the st_collect breaks
-- and relation_id=69364
order by relation_id,direction,sequence_id;
-- first fix the directions of any to be all
drop table if exists tempseg.nother_table;
select rdg.relation_id,rdg.sequence_id,rdg.linestring,rdg.ordering,b.direction
into tempseg.nother_table
from tempseg.relation_direction_geometries rdg
join (select distinct relation_id,direction
from tempseg.relation_direction_geometries d
where direction != 'any') b on (b.relation_id=rdg.relation_id)
where rdg.direction='any';
-- Theoretically, that is every 'any' duplicated at most
-- need to make sure I handle lines that *only* have any direction?
-- then merge those
-- first the ones in 'nother_table
drop table if exists tempseg.initial_routelines cascade;
select relation_id,
direction,
-- st_numGeometries(st_linemerge(st_collect(linestring)))
st_linemerge(st_collect(linestring))
as linestring
into tempseg.initial_routelines
from (
select rdg.relation_id,
rdg.direction,
rdg.linestring,
rdg.sequence_id
from tempseg.relation_direction_geometries rdg
where rdg.direction != 'any'
UNION
select n.relation_id,
n.direction,
n.linestring,
n.sequence_id
from tempseg.nother_table n
) q group by relation_id,direction;
-- now add the 'any' direction ones
insert into tempseg.initial_routelines
select relation_id,
'both' as direction,
-- st_numGeometries(st_linemerge(st_collect(linestring)))
st_linemerge(st_collect(linestring))
as linestring
from (
select rdg.relation_id,
rdg.direction,
rdg.linestring,
rdg.sequence_id
from tempseg.relation_direction_geometries rdg
where rdg.direction = 'any' and
rdg.relation_id not in (select distinct relation_id from tempseg.nother_table)
) a
group by relation_id, direction;
-- okay, now clean up those multilines
drop table if exists tempseg.route_relations_split_lines cascade;
CREATE TABLE tempseg.route_relations_split_lines (
relation_id bigint not null,
direction text,
id4 serial primary key,
segment_id int not null
);
SELECT AddGeometryColumn( 'tempseg','route_relations_split_lines', 'routeline', 4326, 'LINESTRING', 2);
-- truncate tempseg.route_relations_split_lines;
insert into tempseg.route_relations_split_lines
(relation_id,direction,segment_id,routeline)
SELECT
relation_id,direction,generate_series(1,(Select ST_NumGeometries(linestring))*2,2) as segment_id,
ST_GeometryN(linestring, generate_series(1, ST_NumGeometries(linestring))) AS routeline
FROM tempseg.initial_routelines
where ST_NumGeometries(linestring) is not null
-- and relation_id = 70350
order by relation_id,direction
;
-- select distinct relation_id from tempseg.route_relations_split_lines order by relation_id;
-- relation_id
-- -------------
-- -- 70350
-- -- 74660
-- -- skipping 74885
-- -- 76279
-- I did those above 4 on OSM, and all of them were off ramps attached
-- to the main relation, or wrong way segments. So try this...just
-- drop all short segments
-- select relation_id,direction,segment_id,
-- st_length_Spheroid(
-- routeline,
-- 'SPHEROID["GRS_1980",6378137,298.257222101]') as llength
-- from tempseg.route_relations_split_lines
-- where relation_id in (70350, 74660, 74885, 76279)
-- order by relation_id,direction,llength;
-- so, first try getting rid of lines under 500 meters
drop table if exists tempseg.fixed_relations;
select relation_id,direction
into tempseg.fixed_relations
from (
select GeometryType(st_linemerge(st_collect(routeline))) as geomtype,relation_id,direction from tempseg.route_relations_split_lines
group by relation_id,direction
order by geomtype
)a where geomtype = 'LINESTRING';
-- manually ratchet up the length from 100 to 1000, I guess
delete from tempseg.route_relations_split_lines
where
(st_length_Spheroid(
routeline,
'SPHEROID["GRS_1980",6378137,298.257222101]')) < 200
;
insert into tempseg.fixed_relations (relation_id,direction)
select relation_id,direction
from (
select GeometryType(
st_linemerge(st_collect(routeline))) as geomtype,
relation_id,direction
from tempseg.route_relations_split_lines
left outer join tempseg.fixed_relations q using(relation_id,direction) where q.relation_id is null
group by relation_id,direction
order by geomtype
)a where geomtype = 'LINESTRING';
delete from tempseg.route_relations_split_lines
where
(st_length_Spheroid(
routeline,
'SPHEROID["GRS_1980",6378137,298.257222101]')) < 400
;
insert into tempseg.fixed_relations (relation_id,direction)
select relation_id,direction
from (
select GeometryType(
st_linemerge(st_collect(routeline))) as geomtype,
relation_id,direction
from tempseg.route_relations_split_lines
left outer join tempseg.fixed_relations q using(relation_id,direction) where q.relation_id is null
group by relation_id,direction
order by geomtype
)a where geomtype = 'LINESTRING';
delete from tempseg.route_relations_split_lines
where
(st_length_Spheroid(
routeline,
'SPHEROID["GRS_1980",6378137,298.257222101]')) < 600
;
insert into tempseg.fixed_relations (relation_id,direction)
select relation_id,direction
from (
select GeometryType(
st_linemerge(st_collect(routeline))) as geomtype,
relation_id,direction
from tempseg.route_relations_split_lines
left outer join tempseg.fixed_relations q using(relation_id,direction) where q.relation_id is null
group by relation_id,direction
order by geomtype
)a where geomtype = 'LINESTRING';
delete from tempseg.route_relations_split_lines
where
(st_length_Spheroid(
routeline,
'SPHEROID["GRS_1980",6378137,298.257222101]')) < 800
;
insert into tempseg.fixed_relations (relation_id,direction)
select relation_id,direction
from (
select GeometryType(
st_linemerge(st_collect(routeline))) as geomtype,
relation_id,direction
from tempseg.route_relations_split_lines
left outer join tempseg.fixed_relations q using(relation_id,direction) where q.relation_id is null
group by relation_id,direction
order by geomtype
)a where geomtype = 'LINESTRING';
-- select GeometryType(st_linemerge(st_collect(routeline))) as geomtype,relation_id,direction from tempseg.route_relations_split_lines
-- left outer join tempseg.fixed_relations q using(relation_id,direction) where q.relation_id is null
-- and id4 not in
-- ( select id4
-- from tempseg.route_relations_split_lines
-- where (st_length_Spheroid(
-- routeline,
-- 'SPHEROID["GRS_1980",6378137,298.257222101]')) < 900
-- )
-- group by relation_id,direction
-- order by geomtype;
-- okay, that has pretty much run out of its usefulness. Now I need
-- to insert segments as needed. My thought is for those geoms with
-- two or three parts, make segments to join the parts, if that
-- segment is less than 1km
-- how?
-- select geometry 1 of N, last point, join with first point, geometry 2 of N
-- so make a new temp table
drop table if exists tempseg.more_split_lines cascade;
CREATE TABLE tempseg.more_split_lines (
relation_id bigint not null,
direction text,
id4 serial primary key,
fix boolean default false,
segment_id int not null
);
SELECT AddGeometryColumn( 'tempseg','more_split_lines', 'routeline', 4326, 'LINESTRING', 2);
insert into tempseg.more_split_lines
(relation_id,direction,segment_id,routeline)
SELECT
relation_id,direction,generate_series(1,(Select ST_NumGeometries(linestring))*2,2) as segment_id,
ST_GeometryN(linestring, generate_series(1, ST_NumGeometries(linestring))) AS routeline
from (
select st_linemerge(st_collect(routeline)) as linestring,
relation_id,direction
from tempseg.route_relations_split_lines
left outer join tempseg.fixed_relations q using(relation_id,direction)
where q.relation_id is null
group by relation_id,direction
) b
where ST_NumGeometries(linestring) is not null;
-- self join, construct joining segments
insert into tempseg.more_split_lines
(relation_id, direction, segment_id, fix,routeline)
select rl1.relation_id, rl1.direction,rl1.segment_id + 1 as segment_id,
true as fix,
st_makeline(
st_endpoint(rl1.routeline),
st_startpoint(rl2.routeline)
) as routeline
from tempseg.more_split_lines rl1
join tempseg.more_split_lines rl2
on (rl1.relation_id=rl2.relation_id
and rl1.direction = rl2.direction
and rl1.segment_id + 2 = rl2.segment_id
)
where not ST_equals(st_endpoint(rl1.routeline),
st_startpoint(rl2.routeline))
and ST_Distance_Sphere(st_endpoint(rl1.routeline),
st_startpoint(rl2.routeline)) < 1000
;
-- select GeometryType(st_linemerge(st_collect(routeline))) as geomtype,
-- relation_id,direction
-- from tempseg.more_split_lines
-- group by relation_id,direction
-- order by geomtype;
-- Okay, that is as good as I can get for now
drop table if exists tempseg.revised_route_lines cascade;
CREATE TABLE tempseg.revised_route_lines (
relation_id bigint not null,
direction text,
id4 serial primary key,
unique (relation_id,direction)
);
SELECT AddGeometryColumn( 'tempseg','revised_route_lines', 'routeline', 4326, 'GEOMETRY', 2);
insert into tempseg.revised_route_lines
(routeline,relation_id,direction)
select st_linemerge(st_collect(routeline)),
relation_id,direction
from tempseg.more_split_lines
group by relation_id,direction;
insert into tempseg.revised_route_lines
(routeline,relation_id,direction)
select st_linemerge(st_collect(routeline)),
relation_id,direction
from tempseg.route_relations_split_lines
join tempseg.fixed_relations q using(relation_id,direction)
group by relation_id,direction;
insert into tempseg.revised_route_lines
(routeline,relation_id,direction)
select linestring,relation_id,direction
from tempseg.initial_routelines
where geometrytype(linestring)='LINESTRING';