Skip to content

Commit 0ca82bb

Browse files
committed
update: fix expire tiles when nodes are deleted before ways
Expire tiles were missing if nodes were deleted before ways, or ways before relation. closes #197
1 parent 59fdb6c commit 0ca82bb

File tree

5 files changed

+110
-31
lines changed

5 files changed

+110
-31
lines changed

expire/tilelist.go

+23-11
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ func (tl *TileList) ExpireNodes(nodes []osm.Node, closed bool) {
7676
tiles := numBboxTiles(box, tl.zoom)
7777
if tiles > 500 {
7878
tl.expireLine(nodes)
79-
} else {
79+
} else if !box.isEmpty() {
8080
tl.expireBox(box)
8181
}
8282
} else {
@@ -109,6 +109,10 @@ func (tl *TileList) expireLine(nodes []osm.Node) {
109109
tl.mu.Lock()
110110
defer tl.mu.Unlock()
111111
for i := 0; i < len(nodes)-1; i++ {
112+
// skip empty nodes (missing from cache)
113+
if (nodes[i].Long == 0 && nodes[i].Lat == 0) || (nodes[i+1].Long == 0 && nodes[i+1].Lat == 0) {
114+
continue
115+
}
112116
x1, y1 := tileCoord(nodes[i].Long, nodes[i].Lat, tl.zoom)
113117
x2, y2 := tileCoord(nodes[i+1].Long, nodes[i+1].Lat, tl.zoom)
114118
if int(x1) == int(x2) && int(y1) == int(y2) {
@@ -176,21 +180,29 @@ type bbox struct {
176180
minx, miny, maxx, maxy float64
177181
}
178182

183+
func (b bbox) isEmpty() bool {
184+
return b == bbox{math.MaxFloat64, math.MaxFloat64, -math.MaxFloat64, -math.MaxFloat64}
185+
}
186+
179187
func nodesBbox(nodes []osm.Node) bbox {
180-
b := bbox{nodes[0].Long, nodes[0].Lat, nodes[0].Long, nodes[0].Lat}
188+
b := bbox{math.MaxFloat64, math.MaxFloat64, -math.MaxFloat64, -math.MaxFloat64}
189+
190+
for _, nd := range nodes {
191+
if nd.Lat == 0 && nd.Long == 0 {
192+
continue
193+
}
181194

182-
for i := 1; i < len(nodes); i++ {
183-
if b.maxx < nodes[i].Long {
184-
b.maxx = nodes[i].Long
195+
if b.maxx < nd.Long {
196+
b.maxx = nd.Long
185197
}
186-
if b.maxy < nodes[i].Lat {
187-
b.maxy = nodes[i].Lat
198+
if b.maxy < nd.Lat {
199+
b.maxy = nd.Lat
188200
}
189-
if b.minx > nodes[i].Long {
190-
b.minx = nodes[i].Long
201+
if b.minx > nd.Long {
202+
b.minx = nd.Long
191203
}
192-
if b.miny > nodes[i].Lat {
193-
b.miny = nodes[i].Lat
204+
if b.miny > nd.Lat {
205+
b.miny = nd.Lat
194206
}
195207
}
196208
return b

test/expire_tiles.osc

+25-14
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,33 @@
4949
</modify>
5050

5151
<!-- create way -->
52-
<node id="20401" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="2" />
53-
<node id="20402" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="2" />
54-
<way id="20451" version="1" timestamp="2011-11-11T00:11:11Z">
55-
<nd ref="20401"/>
56-
<nd ref="20402"/>
57-
<tag k="highway" v="motorway"/>
58-
</way>
52+
<create>
53+
<node id="20401" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0001" lat="2" />
54+
<node id="20402" version="1" timestamp="2011-11-11T00:11:11Z" lon="4.0002" lat="2" />
55+
<way id="20451" version="1" timestamp="2011-11-11T00:11:11Z">
56+
<nd ref="20401"/>
57+
<nd ref="20402"/>
58+
<tag k="highway" v="motorway"/>
59+
</way>
60+
</create>
5961

6062
<!-- create long way -->
61-
<node id="20501" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.00" lat="2" />
62-
<node id="20502" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.05" lat="2" />
63-
<way id="20551" version="1" timestamp="2011-11-11T00:11:11Z">
64-
<nd ref="20501"/>
65-
<nd ref="20502"/>
66-
<tag k="highway" v="motorway"/>
67-
</way>
63+
<create>
64+
<node id="20501" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.00" lat="2" />
65+
<node id="20502" version="1" timestamp="2011-11-11T00:11:11Z" lon="5.05" lat="2" />
66+
<way id="20551" version="1" timestamp="2011-11-11T00:11:11Z">
67+
<nd ref="20501"/>
68+
<nd ref="20502"/>
69+
<tag k="highway" v="motorway"/>
70+
</way>
71+
</create>
6872

73+
<!-- delete way including its nodes -->
74+
<delete>
75+
<node id="20601" version="2" timestamp="2011-11-11T00:11:11Z" lon="6.0001" lat="2" />
76+
<node id="20602" version="2" timestamp="2011-11-11T00:11:11Z" lon="6.0002" lat="2" />
77+
<way id="20651" version="2" timestamp="2011-11-11T00:11:11Z" />
78+
</delete>
6979

7080

7181
<!-- modify relation -->
@@ -79,6 +89,7 @@
7989

8090
<!-- delete relation -->
8191
<delete>
92+
<way id="30251" version="1" timestamp="2011-11-11T00:11:11Z" />
8293
<relation id="30291" version="1" timestamp="2011-11-11T00:11:11Z">
8394
<member type="way" ref="30251" role="outer"/>
8495
<tag k="building" v="true"/>

test/expire_tiles.osm

+8
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252
<!-- create long way -->
5353
<!-- <way id="20551" ... -->
5454

55+
<!-- delete way including its nodes -->
56+
<node id="20601" version="1" timestamp="2011-11-11T00:11:11Z" lon="6.0001" lat="2" />
57+
<node id="20602" version="1" timestamp="2011-11-11T00:11:11Z" lon="6.0002" lat="2" />
58+
<way id="20651" version="1" timestamp="2011-11-11T00:11:11Z">
59+
<nd ref="20601"/>
60+
<nd ref="20602"/>
61+
<tag k="highway" v="motorway"/>
62+
</way>
5563

5664
<!-- modify relation -->
5765
<node id="30101" version="1" timestamp="2011-11-11T00:11:11Z" lon="1.0001" lat="3" />

test/expire_tiles_test.go

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ func TestExpireTiles(t *testing.T) {
6363
{"osm_roads", 20151, "motorway", nil},
6464
{"osm_roads", 20251, "motorway", nil},
6565
{"osm_roads", 20351, "motorway", nil},
66+
{"osm_roads", 20651, "motorway", nil},
6667

6768
{"osm_buildings", -30191, "yes", nil},
6869
{"osm_buildings", -30291, "yes", nil},
@@ -106,6 +107,7 @@ func TestExpireTiles(t *testing.T) {
106107
{"modify way from node (new)", []tile{{8328, 8283, 14}}, true},
107108
{"create way", []tile{{8374, 8100, 14}}, true},
108109
{"create long way", []tile{{8419, 8100, 14}, {8420, 8100, 14}, {8421, 8100, 14}}, true},
110+
{"delete way including its nodes", []tile{{8465, 8100, 14}}, true},
109111

110112
{"modify relation", []tile{{8237, 8055, 14}}, true},
111113
{"delete relation", []tile{{8283, 8055, 14}}, true},

update/deleter.go

+52-6
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,15 @@ type Deleter struct {
2020
tmRelationMember mapping.RelationMatcher
2121
expireor expire.Expireor
2222
singleIDSpace bool
23+
24+
// Cache deleted nodes with lat/long and ways with refs, to be able to
25+
// calculate expire tiles when nodes/ways are removed before the depending
26+
// ways/relations.
27+
deletedNodes map[int64]osm.Node
28+
deletedWays map[int64][]int64
29+
30+
// Cache deleted elements to avoid processing them multiple times.
2331
deletedRelations map[int64]struct{}
24-
deletedWays map[int64]struct{}
2532
deletedMembers map[int64]struct{}
2633
}
2734

@@ -43,8 +50,9 @@ func NewDeleter(db database.Deleter, osmCache *cache.OSMCache, diffCache *cache.
4350
tmRelation: tmRelation,
4451
tmRelationMember: tmRelationMember,
4552
singleIDSpace: singleIDSpace,
53+
deletedNodes: make(map[int64]osm.Node),
4654
deletedRelations: make(map[int64]struct{}),
47-
deletedWays: make(map[int64]struct{}),
55+
deletedWays: make(map[int64][]int64),
4856
deletedMembers: make(map[int64]struct{}),
4957
}
5058
}
@@ -126,15 +134,20 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool)
126134
}
127135

128136
if deleted && d.expireor != nil {
129-
if err := d.osmCache.Ways.FillMembers(elem.Members); err != nil {
137+
err := d.osmCache.Ways.FillMembers(elem.Members)
138+
if err == cache.NotFound {
139+
d.fillMembersFromDeleted(elem.Members)
140+
} else if err != nil {
130141
return err
131142
}
132143
for _, m := range elem.Members {
133144
if m.Way == nil {
134145
continue
135146
}
136147
err := d.osmCache.Coords.FillWay(m.Way)
137-
if err != nil {
148+
if err == cache.NotFound {
149+
d.fillWayFromDeleted(m.Way)
150+
} else if err != nil {
138151
continue
139152
}
140153
expire.ExpireProjectedNodes(d.expireor, m.Way.Nodes, 4326, deletedPolygon)
@@ -144,7 +157,7 @@ func (d *Deleter) deleteRelation(id int64, deleteRefs bool, deleteMembers bool)
144157
}
145158

146159
func (d *Deleter) deleteWay(id int64, deleteRefs bool) error {
147-
d.deletedWays[id] = struct{}{}
160+
d.deletedWays[id] = nil
148161

149162
elem, err := d.osmCache.Ways.GetWay(id)
150163
if err != nil {
@@ -153,6 +166,8 @@ func (d *Deleter) deleteWay(id int64, deleteRefs bool) error {
153166
}
154167
return err
155168
}
169+
170+
d.deletedWays[id] = elem.Refs
156171
if elem.Tags == nil {
157172
return nil
158173
}
@@ -180,9 +195,12 @@ func (d *Deleter) deleteWay(id int64, deleteRefs bool) error {
180195
}
181196
if deleted && d.expireor != nil {
182197
err := d.osmCache.Coords.FillWay(elem)
183-
if err != nil {
198+
if err == cache.NotFound {
199+
d.fillWayFromDeleted(elem)
200+
} else if err != nil {
184201
return err
185202
}
203+
186204
expire.ExpireProjectedNodes(d.expireor, elem.Nodes, 4326, deletedPolygon)
187205
}
188206
return nil
@@ -192,10 +210,18 @@ func (d *Deleter) deleteNode(id int64) error {
192210
elem, err := d.osmCache.Nodes.GetNode(id)
193211
if err != nil {
194212
if err == cache.NotFound {
213+
if elem, err := d.osmCache.Coords.GetCoord(id); err == nil {
214+
// Cache from Coords for fillWayFromDeleted.
215+
d.deletedNodes[id] = *elem
216+
}
195217
return nil
196218
}
197219
return err
198220
}
221+
222+
// Cache for fillWayFromDeleted.
223+
d.deletedNodes[id] = *elem
224+
199225
if elem.Tags == nil {
200226
return nil
201227
}
@@ -289,3 +315,23 @@ func (d *Deleter) Delete(delElem osm.Diff) error {
289315
}
290316
return nil
291317
}
318+
319+
func (d *Deleter) fillWayFromDeleted(w *osm.Way) {
320+
for i := range w.Nodes {
321+
if w.Nodes[i].ID == 0 {
322+
if nd, ok := d.deletedNodes[w.Refs[i]]; ok {
323+
w.Nodes[i] = nd
324+
}
325+
}
326+
}
327+
}
328+
329+
func (d *Deleter) fillMembersFromDeleted(members []osm.Member) {
330+
for i, m := range members {
331+
if m.Type == osm.WayMember && m.Way == nil {
332+
if refs, ok := d.deletedWays[m.ID]; ok {
333+
members[i].Way = &osm.Way{Element: osm.Element{ID: m.ID}, Refs: refs}
334+
}
335+
}
336+
}
337+
}

0 commit comments

Comments
 (0)