Skip to content

Commit a6df932

Browse files
committed
integrate station importance, split to separate SQL file from station clustering
1 parent 8542742 commit a6df932

File tree

7 files changed

+193
-199
lines changed

7 files changed

+193
-199
lines changed

import/docker-startup.sh

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ function create_update_functions_views() {
8484
$PSQL -f sql/api_milestone_functions.sql
8585
$PSQL -f sql/signal_features.sql
8686
$PSQL -f sql/get_station_importance.sql
87+
$PSQL -f sql/update_station_importance.sql
88+
osm2pgsql-gen \
89+
--database gis \
90+
--style openrailwaymap.lua
91+
$PSQL -f sql/stations_clustered.sql
8792
$PSQL -f sql/tile_views.sql
8893
$PSQL -f sql/api_facility_views.sql
8994
}
@@ -92,6 +97,10 @@ function refresh_materialized_views() {
9297
echo "Updating materialized views"
9398
$PSQL -f sql/update_signal_features.sql
9499
$PSQL -f sql/update_station_importance.sql
100+
osm2pgsql-gen \
101+
--database gis \
102+
--style openrailwaymap.lua
103+
$PSQL -f sql/update_stations_clustered.sql
95104
$PSQL -f sql/update_api_views.sql
96105
}
97106

@@ -134,35 +143,9 @@ filter)
134143

135144
;;
136145

137-
process)
138-
139-
$PSQL -c "drop table if exists stations_q;"
140-
141-
$PSQL -c "create table if not exists stations_q as
142-
select
143-
id,
144-
center as way,
145-
importance,
146-
0.0::real as discr_iso,
147-
0::int as irank,
148-
0::int as dirank
149-
from grouped_stations_with_importance;
150-
"
151-
152-
$PSQL -c "CREATE INDEX IF NOT EXISTS stations_q_id_idx
153-
ON stations_q
154-
USING btree(id);
155-
"
156-
157-
osm2pgsql-gen \
158-
--database gis \
159-
--style openrailwaymap.lua
160-
161-
;;
162-
163146
*)
164147

165-
echo "Invalid argument '$1'. Supported: import, update, refresh, filter, process"
148+
echo "Invalid argument '$1'. Supported: import, update, refresh, filter"
166149
exit 1
167150

168151
;;

import/openrailwaymap.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,10 +1481,10 @@ end
14811481

14821482
function osm2pgsql.process_gen()
14831483
osm2pgsql.run_gen('discrete-isolation', {
1484-
name = 'stations',
1484+
name = 'station_importance',
14851485
debug = true,
1486-
src_table = 'stations_q',
1487-
dest_table = 'stations_q',
1486+
src_table = 'stations_with_importance',
1487+
dest_table = 'stations_with_importance',
14881488
geom_column = 'way',
14891489
id_column = 'id',
14901490
importance_column = 'importance',

import/sql/get_station_importance.sql

Lines changed: 10 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -103,66 +103,7 @@ CREATE OR REPLACE VIEW station_nodes_platforms_rel_count AS
103103
) sr
104104
GROUP BY id;
105105

106-
-- Clustered stations without importance
107-
CREATE MATERIALIZED VIEW IF NOT EXISTS stations_clustered AS
108-
SELECT
109-
row_number() over (order by name, station, railway_ref, uic_ref, feature) as id,
110-
name,
111-
station,
112-
railway_ref,
113-
uic_ref,
114-
feature,
115-
state,
116-
array_agg(facilities.id) as station_ids,
117-
ST_Centroid(ST_ConvexHull(ST_RemoveRepeatedPoints(ST_Collect(way)))) as center,
118-
ST_Buffer(ST_ConvexHull(ST_RemoveRepeatedPoints(ST_Collect(way))), 50) as buffered,
119-
ST_NumGeometries(ST_RemoveRepeatedPoints(ST_Collect(way))) as count
120-
FROM (
121-
SELECT
122-
*,
123-
ST_ClusterDBSCAN(way, 400, 1) OVER (PARTITION BY name, station, railway_ref, uic_ref, feature, state) AS cluster_id
124-
FROM (
125-
SELECT
126-
st_collect(any_value(s.way), st_collect(distinct q.way)) as way,
127-
name,
128-
station,
129-
railway_ref,
130-
uic_ref,
131-
feature,
132-
state,
133-
id
134-
FROM stations s
135-
left join stop_areas sa
136-
ON (ARRAY[s.osm_id] <@ sa.node_ref_ids AND s.osm_type = 'N')
137-
OR (ARRAY[s.osm_id] <@ sa.way_ref_ids AND s.osm_type = 'W')
138-
OR (ARRAY[s.osm_id] <@ sa.stop_ref_ids AND s.osm_type = 'N')
139-
left join (
140-
select
141-
sa.osm_id as stop_area_id,
142-
se.way
143-
from stop_areas sa
144-
join station_entrances se
145-
on array[se.osm_id] <@ sa.node_ref_ids
146-
147-
union all
148-
149-
select
150-
sa.osm_id as stop_area_id,
151-
pl.way
152-
from stop_areas sa
153-
join platforms pl
154-
on array[pl.osm_id] <@ sa.platform_ref_ids
155-
) q on q.stop_area_id = sa.osm_id
156-
group by name, station, railway_ref, uic_ref, feature, state, id
157-
) stations_with_entrances
158-
) AS facilities
159-
GROUP BY cluster_id, name, station, railway_ref, uic_ref, feature, state;
160-
161-
CREATE INDEX IF NOT EXISTS stations_clustered_station_ids
162-
ON stations_clustered
163-
USING gin(station_ids);
164-
165-
CREATE MATERIALIZED VIEW IF NOT EXISTS stations_with_importance AS
106+
CREATE OR REPLACE VIEW stations_with_importance_view AS
166107
SELECT
167108
id,
168109
max(importance) as importance
@@ -210,100 +151,12 @@ CREATE MATERIALIZED VIEW IF NOT EXISTS stations_with_importance AS
210151
) all_stations_with_importance
211152
GROUP BY id;
212153

213-
CREATE INDEX IF NOT EXISTS stations_with_importance_idx
214-
ON stations_with_importance
215-
USING btree(id);
216-
217-
-- Final table with station nodes and the number of route relations
218-
-- needs about 3 to 4 minutes for whole Germany
219-
-- or about 20 to 30 minutes for the whole planet
220-
CREATE MATERIALIZED VIEW IF NOT EXISTS grouped_stations_with_importance AS
221-
SELECT
222-
-- Aggregated station columns
223-
array_agg(DISTINCT station_id ORDER BY station_id) as station_ids,
224-
hstore(string_agg(nullif(name_tags::text, ''), ',')) as name_tags,
225-
array_agg(osm_id ORDER BY osm_id) as osm_ids,
226-
array_agg(osm_type ORDER BY osm_id) as osm_types,
227-
array_remove(array_agg(DISTINCT s.operator ORDER BY s.operator), null) as operator,
228-
array_remove(array_agg(DISTINCT s.network ORDER BY s.network), null) as network,
229-
array_remove(string_to_array(array_to_string(array_agg(DISTINCT array_to_string(s.position, U&'\\001E')), U&'\\001E'), U&'\\001E'), null) as position,
230-
array_remove(array_agg(DISTINCT s.wikidata ORDER BY s.wikidata), null) as wikidata,
231-
array_remove(array_agg(DISTINCT s.wikimedia_commons ORDER BY s.wikimedia_commons), null) as wikimedia_commons,
232-
array_remove(array_agg(DISTINCT s.wikimedia_commons_file ORDER BY s.wikimedia_commons_file), null) as wikimedia_commons_file,
233-
array_remove(array_agg(DISTINCT s.wikipedia ORDER BY s.wikipedia), null) as wikipedia,
234-
array_remove(array_agg(DISTINCT s.image ORDER BY s.image), null) as image,
235-
array_remove(array_agg(DISTINCT s.mapillary ORDER BY s.mapillary), null) as mapillary,
236-
array_remove(array_agg(DISTINCT s.note ORDER BY s.note), null) as note,
237-
array_remove(array_agg(DISTINCT s.description ORDER BY s.description), null) as description,
238-
array_remove(string_to_array(array_to_string(array_agg(DISTINCT array_to_string(s.yard_purpose, U&'\\001E')), U&'\\001E'), U&'\\001E'), null) as yard_purpose,
239-
bool_or(s.yard_hump) as yard_hump,
240-
-- Aggregated importance
241-
max(sr.importance) as importance,
242-
-- Re-grouped clustered stations columns
243-
clustered.id as id,
244-
any_value(clustered.center) as center,
245-
any_value(clustered.buffered) as buffered,
246-
any_value(clustered.name) as name,
247-
any_value(clustered.station) as station,
248-
any_value(clustered.railway_ref) as railway_ref,
249-
any_value(clustered.uic_ref) as uic_ref,
250-
any_value(clustered.feature) as feature,
251-
any_value(clustered.state) as state,
252-
any_value(clustered.count) as count
253-
FROM (
254-
SELECT
255-
id,
256-
UNNEST(sc.station_ids) as station_id,
257-
name, station, railway_ref, uic_ref, feature, state, station_ids, center, buffered, count
258-
FROM stations_clustered sc
259-
) clustered
260-
JOIN stations s
261-
ON clustered.station_id = s.id
262-
JOIN stations_with_importance sr
263-
ON clustered.station_id = sr.id
264-
GROUP BY clustered.id;
265-
266-
CREATE INDEX IF NOT EXISTS grouped_stations_with_importance_center_index
267-
ON grouped_stations_with_importance
268-
USING GIST(center);
269-
270-
CREATE INDEX IF NOT EXISTS grouped_stations_with_importance_buffered_index
271-
ON grouped_stations_with_importance
272-
USING GIST(buffered);
273-
274-
CREATE INDEX IF NOT EXISTS grouped_stations_with_importance_osm_ids_index
275-
ON grouped_stations_with_importance
276-
USING GIN(osm_ids);
277-
278-
CLUSTER grouped_stations_with_importance
279-
USING grouped_stations_with_importance_center_index;
280-
281-
CREATE MATERIALIZED VIEW IF NOT EXISTS stop_area_groups_buffered AS
282-
SELECT
283-
sag.osm_id,
284-
ST_Buffer(ST_ConvexHull(ST_RemoveRepeatedPoints(ST_Collect(gs.buffered))), 20) as way
285-
FROM stop_area_groups sag
286-
JOIN stop_areas sa
287-
ON ARRAY[sa.osm_id] <@ sag.stop_area_ref_ids
288-
JOIN stations s
289-
ON (ARRAY[s.osm_id] <@ sa.node_ref_ids AND s.osm_type = 'N')
290-
OR (ARRAY[s.osm_id] <@ sa.way_ref_ids AND s.osm_type = 'W')
291-
OR (ARRAY[s.osm_id] <@ sa.stop_ref_ids AND s.osm_type = 'N')
292-
JOIN (
293-
SELECT
294-
unnest(osm_ids) AS osm_id,
295-
unnest(osm_types) AS osm_type,
296-
buffered
297-
FROM grouped_stations_with_importance
298-
) gs
299-
ON s.osm_id = gs.osm_id and s.osm_type = gs.osm_type
300-
GROUP BY sag.osm_id
301-
-- Only use station area groups that have more than one station area
302-
HAVING COUNT(distinct sa.osm_id) > 1;
303-
304-
CREATE INDEX IF NOT EXISTS stop_area_groups_buffered_index
305-
ON stop_area_groups_buffered
306-
USING GIST(way);
307-
308-
CLUSTER stop_area_groups_buffered
309-
USING stop_area_groups_buffered_index;
154+
-- Not a materialized view because the Osm2Pgsql scripts update the discrete isolation values
155+
CREATE TABLE IF NOT EXISTS stations_with_importance (
156+
id BIGINT NOT NULL PRIMARY KEY,
157+
way GEOMETRY NOT NULL,
158+
importance NUMERIC NOT NULL DEFAULT 0,
159+
discr_iso REAL NOT NULL DEFAULT 0.0, -- Column name is fixed
160+
irank BIGINT NOT NULL DEFAULT 0, -- Column name is fixed
161+
dirank BIGINT NOT NULL DEFAULT 0 -- Column name is fixed
162+
);

0 commit comments

Comments
 (0)