diff --git a/database/postgis/postgis.go b/database/postgis/postgis.go index 8c710ec..7b28681 100644 --- a/database/postgis/postgis.go +++ b/database/postgis/postgis.go @@ -512,10 +512,10 @@ func (pg *PostGIS) DeleteElem(elem element.OSMElem) error { // handle deletes of geometries that did not match in ProbeXxx. // we have to handle multipolygon relations that took the tags of the // main-member. those tags are not avail. during delete. just try to - // delete from each polygon table. - if v, ok := elem.Tags["type"]; ok && (v == "multipolygon" || v == "boundary") { + // delete from each polygon/relation table. + if _, ok := elem.Tags["type"]; ok { for _, tableSpec := range pg.Tables { - if tableSpec.GeometryType != "polygon" { + if tableSpec.GeometryType != "polygon" && tableSpec.GeometryType != "geometry" && tableSpec.GeometryType != "relation" { continue } pg.txRouter.Delete(tableSpec.Name, elem.Id) diff --git a/diff/deleter.go b/diff/deleter.go index c872f68..99482c3 100644 --- a/diff/deleter.go +++ b/diff/deleter.go @@ -83,18 +83,12 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool) if elem.Tags == nil { return nil } - if matches := d.tmPolygons.MatchRelation(elem); len(matches) > 0 { - if err := d.delDb.Delete(d.RelId(elem.Id), matches); err != nil { - return err - } - } else { - // handle relations with tags from members by deleting - // from all tables - e := element.OSMElem(elem.OSMElem) - e.Id = -e.Id - if err := d.delDb.DeleteElem(e); err != nil { - return err - } + // delete from all tables to handle relations with tags from members + // and relation_members + e := element.OSMElem(elem.OSMElem) + e.Id = -e.Id + if err := d.delDb.DeleteElem(e); err != nil { + return err } if deleteRefs { diff --git a/test/helper_test.go b/test/helper_test.go index d3a43f9..c29466e 100644 --- a/test/helper_test.go +++ b/test/helper_test.go @@ -237,11 +237,11 @@ func (s *importTestSuite) query(t *testing.T, table string, id int64, keys []str } func (s *importTestSuite) queryTags(t *testing.T, table string, id int64) record { - stmt := fmt.Sprintf(`SELECT osm_id, ST_AsText(geometry), tags FROM "%s"."%s" WHERE osm_id=$1`, dbschemaProduction, table) + stmt := fmt.Sprintf(`SELECT osm_id, tags FROM "%s"."%s" WHERE osm_id=$1`, dbschemaProduction, table) row := s.db.QueryRow(stmt, id) r := record{} h := hstore.Hstore{} - if err := row.Scan(&r.id, &r.wkt, &h); err != nil { + if err := row.Scan(&r.id, &h); err != nil { if err == sql.ErrNoRows { r.missing = true } else { @@ -320,6 +320,29 @@ func (s *importTestSuite) queryGeom(t *testing.T, table string, id int64) *geos. return geom } +func (s *importTestSuite) queryDynamic(t *testing.T, table, where string) []map[string]string { + stmt := fmt.Sprintf(`SELECT hstore(r) FROM (SELECT ST_AsText(geometry) AS wkt, * FROM "%s"."%s" WHERE %s) AS r`, dbschemaProduction, table, where) + rows, err := s.db.Query(stmt) + if err != nil { + t.Fatal(err) + } + results := []map[string]string{} + for rows.Next() { + h := hstore.Hstore{} + if err := rows.Scan(&h); err != nil { + t.Fatal(err) + } + r := make(map[string]string) + for k, v := range h.Map { + if v.Valid { + r[k] = v.String + } + } + results = append(results, r) + } + return results +} + type checkElem struct { table string id int64 diff --git a/test/route_relation.osc b/test/route_relation.osc index 7f21e40..ff6ad12 100644 --- a/test/route_relation.osc +++ b/test/route_relation.osc @@ -1,3 +1,12 @@ + + + + + + + + + diff --git a/test/route_relation.osm b/test/route_relation.osm index b1d5682..25c42cc 100644 --- a/test/route_relation.osm +++ b/test/route_relation.osm @@ -99,7 +99,25 @@ + + + + + + + + + + + + + + + + + + diff --git a/test/route_relation_test.go b/test/route_relation_test.go index 16b52a0..a03facc 100644 --- a/test/route_relation_test.go +++ b/test/route_relation_test.go @@ -2,6 +2,7 @@ package test import ( "database/sql" + "strconv" "testing" @@ -46,8 +47,68 @@ func TestRouteRelation_Deploy(t *testing.T) { } } +func TestRouteRelation_RelationData(t *testing.T) { + // check tags of relation + r := ts.queryTags(t, "osm_routes", -100901) + if r.tags["name"] != "Bus 301: A => B" { + t.Error(r) + } +} + +func TestRouteRelation_MemberGeomUpdated1(t *testing.T) { + rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502") + if len(rows) != 1 { + t.Fatal(rows) + } + g := ts.g.FromWkt(rows[0]["wkt"]) + if g.Length() != 111.32448543701321 { + t.Fatal(g.Length()) + } + + rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503") + if len(rows) != 1 { + t.Fatal(rows) + } + if rows[0]["name"] != "" { + t.Error(rows[0]) + } +} + // ####################################################################### func TestRouteRelation_Update(t *testing.T) { ts.updateOsm(t, "./build/route_relation.osc.gz") } + +// ####################################################################### + +func TestRouteRelation_MemberGeomUpdated2(t *testing.T) { + rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100502") + if len(rows) != 1 { + t.Fatal(rows) + } + g := ts.g.FromWkt(rows[0]["wkt"]) + if g.Length() != 184.97560221624542 { + t.Fatal(g.Length()) + } + + rows = ts.queryDynamic(t, "osm_route_members", "osm_id = -100902 AND member = 100503") + if len(rows) != 1 { + t.Fatal(rows) + } + if rows[0]["name"] != "new name" { + t.Error(rows[0]) + } +} + +func TestRouteRelation_MemberNotUpdated(t *testing.T) { + // check that member is not updated if no node/way changed + rows := ts.queryDynamic(t, "osm_route_members", "osm_id = -100903 AND member = 100501") + if len(rows) != 1 { + t.Fatal(rows) + } + if id, err := strconv.ParseInt(rows[0]["id"], 10, 32); err != nil || id > 27 { + t.Error("member was re-inserted", rows) + } + +}