Skip to content

Commit ba0f8d0

Browse files
committed
Use trigger to check geometry validity on first import
Instead of importing all data and then only checking the geometry when clustering the data. Because there are more things happening in parallel on the first import this makes the whole import slightly faster.
1 parent 9622948 commit ba0f8d0

File tree

4 files changed

+37
-15
lines changed

4 files changed

+37
-15
lines changed

src/flex-table.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,12 @@ void table_connection_t::start(bool append)
176176
table().has_geom_column() ? flex_table_t::table_type::interim
177177
: flex_table_t::table_type::permanent,
178178
table().full_name()));
179+
180+
if (table().has_geom_column() && table().geom_column().srid() != 4326) {
181+
create_geom_check_trigger(m_db_connection.get(), table().schema(),
182+
table().name(),
183+
table().geom_column().name());
184+
}
179185
}
180186

181187
prepare();
@@ -195,6 +201,11 @@ void table_connection_t::stop(bool updateable, bool append)
195201
util::timer_t timer;
196202

197203
if (table().has_geom_column()) {
204+
if (table().geom_column().needs_isvalid()) {
205+
drop_geom_check_trigger(m_db_connection.get(), table().schema(),
206+
table().name());
207+
}
208+
198209
log_info("Clustering table '{}' by geometry...", table().name());
199210

200211
// Notices about invalid geometries are expected and can be ignored
@@ -207,14 +218,6 @@ void table_connection_t::stop(bool updateable, bool append)
207218
std::string sql = "INSERT INTO {} SELECT * FROM {}"_format(
208219
table().full_tmp_name(), table().full_name());
209220

210-
if (table().geom_column().srid() != 4326) {
211-
// libosmium assures validity of geometries in 4326.
212-
// Transformation to another projection could make the geometry
213-
// invalid. Therefore add a filter to drop those.
214-
sql += " WHERE ST_IsValid(\"{}\")"_format(
215-
table().geom_column().name());
216-
}
217-
218221
auto const postgis_version = get_postgis_version(*m_db_connection);
219222

220223
sql += " ORDER BY ";

src/pgsql-helper.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ void create_geom_check_trigger(pg_conn_t *db_connection,
5555
qualified_name(schema, table), func_name));
5656
}
5757

58+
void drop_geom_check_trigger(pg_conn_t *db_connection,
59+
std::string const &schema,
60+
std::string const &table)
61+
{
62+
std::string func_name = qualified_name(schema, table + "_osm2pgsql_valid");
63+
64+
db_connection->exec("DROP TRIGGER \"{}\" ON {};"_format(
65+
table + "_osm2pgsql_valid", qualified_name(schema, table)));
66+
67+
db_connection->exec("DROP FUNCTION IF EXISTS {} ();"_format(func_name));
68+
}
69+
5870
void analyze_table(pg_conn_t const &db_connection, std::string const &schema,
5971
std::string const &name)
6072
{

src/pgsql-helper.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ void create_geom_check_trigger(pg_conn_t *db_connection,
3131
std::string const &table,
3232
std::string const &geom_column);
3333

34+
void drop_geom_check_trigger(pg_conn_t *db_connection,
35+
std::string const &schema,
36+
std::string const &table);
37+
3438
void analyze_table(pg_conn_t const &db_connection, std::string const &schema,
3539
std::string const &name);
3640

src/table.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ void table_t::start(std::string const &conninfo, std::string const &table_space)
132132

133133
//create the table
134134
m_sql_conn->exec(sql);
135+
136+
if (m_srid != "4326") {
137+
create_geom_check_trigger(m_sql_conn.get(), m_target->schema,
138+
m_target->name, "way");
139+
}
135140
}
136141

137142
prepare();
@@ -185,6 +190,11 @@ void table_t::stop(bool updateable, bool enable_hstore_index,
185190
if (!m_append) {
186191
util::timer_t timer;
187192

193+
if (m_srid != "4326") {
194+
drop_geom_check_trigger(m_sql_conn.get(), m_target->schema,
195+
m_target->name);
196+
}
197+
188198
log_info("Clustering table '{}' by geometry...", m_target->name);
189199

190200
// Notices about invalid geometries are expected and can be ignored
@@ -195,13 +205,6 @@ void table_t::stop(bool updateable, bool enable_hstore_index,
195205
"CREATE TABLE {} {} AS SELECT * FROM {}"_format(
196206
qual_tmp_name, m_table_space, qual_name);
197207

198-
if (m_srid != "4326") {
199-
// libosmium assures validity of geometries in 4326.
200-
// Transformation to another projection could make the geometry
201-
// invalid. Therefore add a filter to drop those.
202-
sql += " WHERE ST_IsValid(way)";
203-
}
204-
205208
auto const postgis_version = get_postgis_version(*m_sql_conn);
206209

207210
sql += " ORDER BY ";

0 commit comments

Comments
 (0)