From 69bb49f49c15d7ff5dcb253bec166959422f86df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Sat, 13 Mar 2021 16:44:31 +0200 Subject: [PATCH] aggregate and filter rivers --- IV/Makefile | 8 ++------ IV/aggregate-rivers.sql | 37 +++++++++++++++++++++++++++++++++++++ IV/filter-rivers-query.awk | 12 ------------ 3 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 IV/aggregate-rivers.sql delete mode 100755 IV/filter-rivers-query.awk diff --git a/IV/Makefile b/IV/Makefile index 8ced223..96e268a 100644 --- a/IV/Makefile +++ b/IV/Makefile @@ -1,11 +1,7 @@ -# HACK HACK -EMPTY := -SPACE := $(EMPTY) $(EMPTY) - -RIVERS ?= Visinčia Šalčia Žeimena Lakaja Nemunas +WHERE ?= name='Visinčia' OR name='Šalčia' OR name='Nemunas' .faux_filter-rivers: .faux_import-osm - ./filter-rivers-query.awk $(RIVERS) | ./db -f - + ./db -v where="$(WHERE)" -f aggregate-rivers.sql touch $@ .faux_import-osm: lithuania-latest.osm.pbf .faux.db diff --git a/IV/aggregate-rivers.sql b/IV/aggregate-rivers.sql new file mode 100644 index 0000000..786c4c5 --- /dev/null +++ b/IV/aggregate-rivers.sql @@ -0,0 +1,37 @@ +/* Aggregates rivers by name and proximity. */ +drop function if exists aggregate_rivers; +create function aggregate_rivers() returns table(osm_id bigint, name text, way geometry) as $$ +declare + c record; + cc record; + changed boolean; +begin + while (select count(1) from agg_tmp_objects) > 0 loop + select * from agg_tmp_objects limit 1 into c; + delete from agg_tmp_objects a where a.osm_id = c.osm_id; + changed = true; + while changed loop + changed = false; + for cc in (select * from agg_tmp_objects a where a.name = c.name and st_dwithin(a.way, c.way, 500)) loop + c.way = st_linemerge(st_union(c.way, cc.way)); + delete from agg_tmp_objects a where a.osm_id = cc.osm_id; + changed = true; + end loop; + end loop; -- while changed + return query select c.osm_id, c.name, c.way; + end loop; -- count(1) from agg_tmp_objects > 0 + return; +end +$$ language plpgsql; + +create temporary table agg_tmp_objects (osm_id bigint, name text, way geometry); +create index agg_tmp_objects_id on agg_tmp_objects(osm_id); +create index agg_tmp_objects_gix on agg_tmp_objects using gist(way) include(name); + +insert into agg_tmp_objects + select p.osm_id, p.name, p.way from planet_osm_line p + where waterway in ('river', 'stream', 'canal') and :where; + +drop table if exists agg_rivers; +create table agg_rivers as (select * from aggregate_rivers()); +drop table agg_tmp_objects; diff --git a/IV/filter-rivers-query.awk b/IV/filter-rivers-query.awk deleted file mode 100755 index 4991147..0000000 --- a/IV/filter-rivers-query.awk +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/awk -f - -BEGIN { - print "DROP TABLE IF EXISTS rivers;" - printf "CREATE TABLE rivers AS SELECT name,way FROM planet_osm_line WHERE " - for (i = 1; i < ARGC; i++) { - printf "name='%s'", ARGV[i] - if (i != ARGC - 1) - printf " OR "; - } - print ";"; -}