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 {
|
type DeltaCoordsCache struct {
|
||||||
cache
|
cache
|
||||||
lruList *list.List
|
lruList *list.List
|
||||||
|
@ -247,8 +276,14 @@ func (self *DeltaCoordsCache) PutCoords(nodes []element.Node) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bunch.coords = append(bunch.coords, nodes[start:i]...)
|
if self.linearImport {
|
||||||
sort.Sort(byId(bunch.coords))
|
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.needsWrite = true
|
||||||
bunch.Unlock()
|
bunch.Unlock()
|
||||||
}
|
}
|
||||||
|
@ -260,8 +295,16 @@ func (self *DeltaCoordsCache) PutCoords(nodes []element.Node) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.needsWrite = true
|
||||||
bunch.Unlock()
|
bunch.Unlock()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -112,20 +112,76 @@ func checkReadWriteDeltaCoords(t *testing.T, withLinearImport bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = cache.GetCoord(999999)
|
// test overwrite
|
||||||
if err != NotFound {
|
insertAndCheck(t, cache, 100, 50, 50)
|
||||||
t.Error("missing node returned not NotFound")
|
|
||||||
}
|
|
||||||
|
|
||||||
// test delete
|
// test delete
|
||||||
cache.PutCoords([]element.Node{mknode(999999)})
|
|
||||||
|
|
||||||
_, err = cache.GetCoord(999999)
|
_, err = cache.GetCoord(999999)
|
||||||
if err == NotFound {
|
if err != NotFound {
|
||||||
t.Error("missing coord")
|
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 {
|
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)
|
park = query_row(db_conf, 'osm_landusages', -7301)
|
||||||
assert park['geometry'].is_valid, park
|
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():
|
def test_update():
|
||||||
"""Diff import applies"""
|
"""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)['type'] == 'mp'
|
||||||
assert query_row(db_conf, 'osm_buildings', 51011) == None
|
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():
|
def test_deploy_and_revert_deploy():
|
||||||
"""Revert deploy succeeds"""
|
"""Revert deploy succeeds"""
|
||||||
|
|
|
@ -165,6 +165,15 @@
|
||||||
<way id="51011" />
|
<way id="51011" />
|
||||||
</delete>
|
</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>
|
</osmChange>
|
||||||
|
|
|
@ -898,4 +898,24 @@
|
||||||
<tag k="building" v="mp"/>
|
<tag k="building" v="mp"/>
|
||||||
</relation>
|
</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>
|
</osm>
|
||||||
|
|
Loading…
Reference in New Issue