fix updating nodes in DeltaCoordsCache
Updating an existing node in the DeltaCoordsCache resulted in duplicate nodes instead of a single updated node. GetCoord returned the first node, depending on the sort order.master
parent
e4d1156ff8
commit
96b5f1c394
|
@ -93,6 +93,35 @@ func (b *coordsBunch) DeleteCoord(id int64) {
|
|||
}
|
||||
}
|
||||
|
||||
// PutCoord puts a single coord into the coords bunch. This function
|
||||
// does support updating nodes.
|
||||
func (b *coordsBunch) PutCoord(node element.Node) {
|
||||
idx := sort.Search(len(b.coords), func(i int) bool {
|
||||
return b.coords[i].Id >= node.Id
|
||||
})
|
||||
if idx < len(b.coords) {
|
||||
if b.coords[idx].Id == node.Id {
|
||||
// overwrite
|
||||
b.coords[idx] = node
|
||||
} else {
|
||||
// insert
|
||||
b.coords = append(b.coords, node)
|
||||
copy(b.coords[idx+1:], b.coords[idx:])
|
||||
b.coords[idx] = node
|
||||
}
|
||||
} else {
|
||||
// append
|
||||
b.coords = append(b.coords, node)
|
||||
}
|
||||
}
|
||||
|
||||
// PutCoords puts multiple coords into the coords bunch. This bulk function
|
||||
// does not support duplicate or updated nodes.
|
||||
func (b *coordsBunch) PutCoords(nodes []element.Node) {
|
||||
b.coords = append(b.coords, nodes...)
|
||||
sort.Sort(byId(b.coords))
|
||||
}
|
||||
|
||||
type DeltaCoordsCache struct {
|
||||
cache
|
||||
lruList *list.List
|
||||
|
@ -247,8 +276,14 @@ func (self *DeltaCoordsCache) PutCoords(nodes []element.Node) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bunch.coords = append(bunch.coords, nodes[start:i]...)
|
||||
sort.Sort(byId(bunch.coords))
|
||||
if self.linearImport {
|
||||
bunch.PutCoords(nodes[start:i])
|
||||
} else {
|
||||
for _, node := range nodes[start:i] {
|
||||
// single inserts to handle updated coords
|
||||
bunch.PutCoord(node)
|
||||
}
|
||||
}
|
||||
bunch.needsWrite = true
|
||||
bunch.Unlock()
|
||||
}
|
||||
|
@ -260,8 +295,16 @@ func (self *DeltaCoordsCache) PutCoords(nodes []element.Node) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bunch.coords = append(bunch.coords, nodes[start:]...)
|
||||
sort.Sort(byId(bunch.coords))
|
||||
|
||||
if self.linearImport {
|
||||
bunch.PutCoords(nodes[start:])
|
||||
} else {
|
||||
for _, node := range nodes[start:] {
|
||||
// single inserts to handle updated coords
|
||||
bunch.PutCoord(node)
|
||||
}
|
||||
}
|
||||
|
||||
bunch.needsWrite = true
|
||||
bunch.Unlock()
|
||||
return nil
|
||||
|
|
|
@ -112,20 +112,76 @@ func checkReadWriteDeltaCoords(t *testing.T, withLinearImport bool) {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = cache.GetCoord(999999)
|
||||
if err != NotFound {
|
||||
t.Error("missing node returned not NotFound")
|
||||
}
|
||||
// test overwrite
|
||||
insertAndCheck(t, cache, 100, 50, 50)
|
||||
|
||||
// test delete
|
||||
cache.PutCoords([]element.Node{mknode(999999)})
|
||||
|
||||
_, err = cache.GetCoord(999999)
|
||||
if err == NotFound {
|
||||
t.Error("missing coord")
|
||||
if err != NotFound {
|
||||
t.Error("found missing node")
|
||||
}
|
||||
err = cache.DeleteCoord(999999)
|
||||
insertAndCheck(t, cache, 999999, 10, 10)
|
||||
deleteAndCheck(t, cache, 999999)
|
||||
}
|
||||
|
||||
func insertAndCheck(t *testing.T, cache *DeltaCoordsCache, id int64, lon, lat float64) {
|
||||
newNode := mknode(id)
|
||||
newNode.Long = lon
|
||||
newNode.Lat = lat
|
||||
|
||||
err := cache.PutCoords([]element.Node{newNode})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Errorf("error during PutCoords for %v: %s", newNode, err)
|
||||
}
|
||||
|
||||
result, err := cache.GetCoord(id)
|
||||
if err != nil {
|
||||
t.Errorf("got error after getting inserted node %d: %s", id, err)
|
||||
}
|
||||
if result == nil || result.Long != lon || result.Lat != lat {
|
||||
t.Errorf("invalid coords %f, %f != %v", lon, lat, result)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteAndCheck(t *testing.T, cache *DeltaCoordsCache, id int64) {
|
||||
err := cache.DeleteCoord(id)
|
||||
if err != nil {
|
||||
t.Errorf("error during DeleteCoord for %d: %s", id, err)
|
||||
}
|
||||
|
||||
result, err := cache.GetCoord(id)
|
||||
if err != NotFound {
|
||||
t.Error("found deleted coord", result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSingleUpdate(t *testing.T) {
|
||||
cache_dir, _ := ioutil.TempDir("", "imposm3_test")
|
||||
defer os.RemoveAll(cache_dir)
|
||||
|
||||
cache, err := newDeltaCoordsCache(cache_dir)
|
||||
if err != nil {
|
||||
t.Fatal()
|
||||
}
|
||||
|
||||
// insert and update in empty batch
|
||||
insertAndCheck(t, cache, 123, 10, 10)
|
||||
insertAndCheck(t, cache, 123, 10, 11)
|
||||
|
||||
// insert and update in same batch
|
||||
insertAndCheck(t, cache, 1, 1, 1)
|
||||
insertAndCheck(t, cache, 2, 2, 2)
|
||||
insertAndCheck(t, cache, 3, 3, 3)
|
||||
insertAndCheck(t, cache, 4, 4, 4)
|
||||
insertAndCheck(t, cache, 3, 10, 11)
|
||||
insertAndCheck(t, cache, 2, 10, 11)
|
||||
insertAndCheck(t, cache, 1, 10, 11)
|
||||
insertAndCheck(t, cache, 4, 10, 11)
|
||||
// repeat after flushing
|
||||
cache.Flush()
|
||||
insertAndCheck(t, cache, 1, 1, 1)
|
||||
insertAndCheck(t, cache, 2, 2, 2)
|
||||
insertAndCheck(t, cache, 3, 3, 3)
|
||||
insertAndCheck(t, cache, 4, 4, 4)
|
||||
|
||||
}
|
||||
|
|
|
@ -446,6 +446,11 @@ def test_relation_with_gap():
|
|||
park = query_row(db_conf, 'osm_landusages', -7301)
|
||||
assert park['geometry'].is_valid, park
|
||||
|
||||
def test_updated_nodes1():
|
||||
"""Zig-Zag line is inserted."""
|
||||
road = query_row(db_conf, 'osm_roads', 60000)
|
||||
assert_almost_equal(road['geometry'].length, 14035.61150207768)
|
||||
|
||||
#######################################################################
|
||||
def test_update():
|
||||
"""Diff import applies"""
|
||||
|
@ -588,6 +593,12 @@ def test_duplicate_ids2():
|
|||
assert query_row(db_conf, 'osm_buildings', -51011)['type'] == 'mp'
|
||||
assert query_row(db_conf, 'osm_buildings', 51011) == None
|
||||
|
||||
def test_updated_way2():
|
||||
"""All nodes of straightened way are updated."""
|
||||
road = query_row(db_conf, 'osm_roads', 60000)
|
||||
# new length 0.1 degree
|
||||
assert_almost_equal(road['geometry'].length, 20037508.342789244/180.0/10.0)
|
||||
|
||||
#######################################################################
|
||||
def test_deploy_and_revert_deploy():
|
||||
"""Revert deploy succeeds"""
|
||||
|
|
|
@ -165,6 +165,15 @@
|
|||
<way id="51011" />
|
||||
</delete>
|
||||
|
||||
|
||||
|
||||
<!-- update zig-zag line with coords internaly cached in differend deltacoords bunches -->
|
||||
<modify>
|
||||
<node id="60001" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.00"/>
|
||||
<node id="60002" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.01"/>
|
||||
<node id="60003" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.02"/>
|
||||
<node id="61004" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.03"/>
|
||||
<node id="62005" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.04"/>
|
||||
<node id="63006" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.05"/>
|
||||
<node id="64007" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.06"/>
|
||||
<node id="64008" version="1" timestamp="2011-11-11T00:11:11Z" lat="0" lon="20.10"/>
|
||||
</modify>
|
||||
</osmChange>
|
||||
|
|
|
@ -898,4 +898,24 @@
|
|||
<tag k="building" v="mp"/>
|
||||
</relation>
|
||||
|
||||
<!-- zig-zag line with coords internaly cached in differend deltacoords bunches -->
|
||||
<node id="60001" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.01" lon="20.00"/>
|
||||
<node id="60002" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.00" lon="20.01"/>
|
||||
<node id="60003" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.01" lon="20.02"/>
|
||||
<node id="61004" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.00" lon="20.03"/>
|
||||
<node id="62005" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.01" lon="20.04"/>
|
||||
<node id="63006" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.00" lon="20.05"/>
|
||||
<node id="64007" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.01" lon="20.06"/>
|
||||
<node id="64008" version="1" timestamp="2011-11-11T00:11:11Z" lat="0.00" lon="20.10"/>
|
||||
<way id="60000" version="1" timestamp="2011-11-11T00:11:11Z">
|
||||
<nd ref="60001"/>
|
||||
<nd ref="60002"/>
|
||||
<nd ref="60003"/>
|
||||
<nd ref="61004"/>
|
||||
<nd ref="62005"/>
|
||||
<nd ref="63006"/>
|
||||
<nd ref="64007"/>
|
||||
<nd ref="64008"/>
|
||||
<tag k="highway" v="residential"/>
|
||||
</way>
|
||||
</osm>
|
||||
|
|
Loading…
Reference in New Issue