diff --git a/database/postgis/fields.go b/database/postgis/fields.go index 30491f2..70d467b 100644 --- a/database/postgis/fields.go +++ b/database/postgis/fields.go @@ -42,6 +42,16 @@ func (t *geometryType) PrepareInsertSql(i int, spec *TableSpec) string { } func (t *geometryType) GeneralizeSql(colSpec *ColumnSpec, spec *GeneralizedTableSpec) string { + return fmt.Sprintf(`ST_SimplifyPreserveTopology("%s", %f) as "%s"`, + colSpec.Name, spec.Tolerance, colSpec.Name, + ) +} + +type validatedGeometryType struct { + geometryType +} + +func (t *validatedGeometryType) GeneralizeSql(colSpec *ColumnSpec, spec *GeneralizedTableSpec) string { return fmt.Sprintf(`ST_Buffer(ST_SimplifyPreserveTopology("%s", %f), 0) as "%s"`, colSpec.Name, spec.Tolerance, colSpec.Name, ) @@ -51,12 +61,13 @@ var pgTypes map[string]ColumnType func init() { pgTypes = map[string]ColumnType{ - "string": &simpleColumnType{"VARCHAR"}, - "bool": &simpleColumnType{"BOOL"}, - "int8": &simpleColumnType{"SMALLINT"}, - "int32": &simpleColumnType{"INT"}, - "int64": &simpleColumnType{"BIGINT"}, - "float32": &simpleColumnType{"REAL"}, - "geometry": &geometryType{"GEOMETRY"}, + "string": &simpleColumnType{"VARCHAR"}, + "bool": &simpleColumnType{"BOOL"}, + "int8": &simpleColumnType{"SMALLINT"}, + "int32": &simpleColumnType{"INT"}, + "int64": &simpleColumnType{"BIGINT"}, + "float32": &simpleColumnType{"REAL"}, + "geometry": &geometryType{"GEOMETRY"}, + "validated_geometry": &validatedGeometryType{geometryType{"GEOMETRY"}}, } } diff --git a/mapping/fields.go b/mapping/fields.go index b4c50e6..318b707 100644 --- a/mapping/fields.go +++ b/mapping/fields.go @@ -24,6 +24,7 @@ func init() { "mapping_key": {"mapping_key", "string", Key, nil}, "mapping_value": {"mapping_value", "string", Value, nil}, "geometry": {"geometry", "geometry", Geometry, nil}, + "validated_geometry": {"validated_geometry", "validated_geometry", Geometry, nil}, "wayzorder": {"wayzorder", "int32", WayZOrder, nil}, "pseudoarea": {"pseudoarea", "float32", PseudoArea, nil}, "zorder": {"zorder", "int32", nil, MakeZOrder}, diff --git a/test/imposm_system_test.py b/test/imposm_system_test.py index 8d04af4..8a8c48b 100644 --- a/test/imposm_system_test.py +++ b/test/imposm_system_test.py @@ -418,6 +418,23 @@ def test_generalized_banana_polygon_is_valid(): park = query_row(db_conf, 'osm_landusages_gen1', 7101) assert park['geometry'].is_valid, park +def test_generalized_linestring_is_valid(): + """Generalized linestring is valid.""" + road = query_row(db_conf, 'osm_roads', 7201) + # geometry is not simple, but valid + # check that geometry 'survives' simplification + assert not road['geometry'].is_simple, road['geometry'].wkt + assert road['geometry'].is_valid, road['geometry'].wkt + assert road['geometry'].length > 1000000 + road = query_row(db_conf, 'osm_roads_gen0', 7201) + # but simplified geometies are simple + assert road['geometry'].is_valid, road['geometry'].wkt + assert road['geometry'].length > 1000000 + road = query_row(db_conf, 'osm_roads_gen1', 7201) + assert road['geometry'].is_valid, road['geometry'].wkt + assert road['geometry'].length > 1000000 + + ####################################################################### def test_update(): """Diff import applies""" diff --git a/test/test.osm b/test/test.osm index d46e8fd..48d2e06 100644 --- a/test/test.osm +++ b/test/test.osm @@ -327,6 +327,19 @@ + + + + + + + + + + + + + diff --git a/test/test_mapping.json b/test/test_mapping.json index 9a7d604..e45df05 100644 --- a/test/test_mapping.json +++ b/test/test_mapping.json @@ -50,7 +50,7 @@ "key": null }, { - "type": "geometry", + "type": "validated_geometry", "name": "geometry", "key": null }, @@ -835,7 +835,7 @@ "key": null }, { - "type": "geometry", + "type": "validated_geometry", "name": "geometry", "key": null },