Browse Source

Show tiles from a higher zoom level to fill gaps

Johannes Hofmann 8 years ago
parent
commit
364907e29e
2 changed files with 123 additions and 13 deletions
  1. 82
    5
      src/coord.rs
  2. 41
    8
      src/tile_cache_gl.rs

+ 82
- 5
src/coord.rs View File

103
     pub height: f64,
103
     pub height: f64,
104
 }
104
 }
105
 
105
 
106
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
107
-pub struct TileCoord {
108
-    pub zoom: u32,
109
-    pub x: i32,
110
-    pub y: i32,
106
+impl ScreenRect {
107
+    pub fn subdivide(&self, sub_tile: &SubTileCoord) -> ScreenRect {
108
+        let scale = 1.0 / f64::from(sub_tile.size);
109
+        let w = self.width * scale;
110
+        let h = self.height * scale;
111
+        ScreenRect {
112
+            x: self.x + f64::from(sub_tile.x) * w,
113
+            y: self.y + f64::from(sub_tile.y) * h,
114
+            width: w,
115
+            height: h,
116
+        }
117
+    }
111
 }
118
 }
112
 
119
 
113
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
120
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
117
     pub y: u32,
124
     pub y: u32,
118
 }
125
 }
119
 
126
 
127
+impl SubTileCoord {
128
+    pub fn subdivide(&self, other: &SubTileCoord) -> SubTileCoord {
129
+        SubTileCoord {
130
+            x: self.x * other.size + other.x,
131
+            y: self.y * other.size + other.y,
132
+            size: self.size * other.size,
133
+        }
134
+    }
135
+}
136
+
137
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
138
+pub struct TileCoord {
139
+    pub zoom: u32,
140
+    pub x: i32,
141
+    pub y: i32,
142
+}
143
+
120
 impl TileCoord {
144
 impl TileCoord {
121
     pub fn new(zoom: u32, x: i32, y: i32) -> TileCoord {
145
     pub fn new(zoom: u32, x: i32, y: i32) -> TileCoord {
122
         TileCoord {
146
         TileCoord {
168
         }
192
         }
169
     }
193
     }
170
 
194
 
195
+    pub fn children(&self) -> [(TileCoord, SubTileCoord); 4] {
196
+        [
197
+            (
198
+                TileCoord {
199
+                    zoom: self.zoom + 1,
200
+                    x: self.x * 2,
201
+                    y: self.y * 2,
202
+                },
203
+                SubTileCoord {
204
+                    size: 2,
205
+                    x: 0,
206
+                    y: 0,
207
+                },
208
+            ),
209
+            (
210
+                TileCoord {
211
+                    zoom: self.zoom + 1,
212
+                    x: self.x * 2 + 1,
213
+                    y: self.y * 2,
214
+                },
215
+                SubTileCoord {
216
+                    size: 2,
217
+                    x: 1,
218
+                    y: 0,
219
+                },
220
+            ),
221
+            (
222
+                TileCoord {
223
+                    zoom: self.zoom + 1,
224
+                    x: self.x * 2,
225
+                    y: self.y * 2 + 1,
226
+                },
227
+                SubTileCoord {
228
+                    size: 2,
229
+                    x: 0,
230
+                    y: 1,
231
+                },
232
+            ),
233
+            (
234
+                TileCoord {
235
+                    zoom: self.zoom + 1,
236
+                    x: self.x * 2 + 1,
237
+                    y: self.y * 2 + 1,
238
+                },
239
+                SubTileCoord {
240
+                    size: 2,
241
+                    x: 1,
242
+                    y: 1,
243
+                },
244
+            ),
245
+        ]
246
+    }
247
+
171
     #[inline]
248
     #[inline]
172
     fn normalize_coord(coord: i32, zoom: u32) -> i32 {
249
     fn normalize_coord(coord: i32, zoom: u32) -> i32 {
173
         let max = Self::get_zoom_level_tiles(zoom);
250
         let max = Self::get_zoom_level_tiles(zoom);

+ 41
- 8
src/tile_cache_gl.rs View File

25
             y2: self.y2 - margin_y,
25
             y2: self.y2 - margin_y,
26
         }
26
         }
27
     }
27
     }
28
+
29
+    pub fn subdivide(&self, sub_tile: &SubTileCoord) -> TextureRect {
30
+        let scale = 1.0 / f64::from(sub_tile.size);
31
+        let w = (self.x2 - self.x1) * scale;
32
+        let h = (self.y2 - self.y1) * scale;
33
+        TextureRect {
34
+            x1: self.x1 + f64::from(sub_tile.x) * w,
35
+            y1: self.y1 + f64::from(sub_tile.y) * h,
36
+            x2: self.x1 + f64::from(sub_tile.x + 1) * w,
37
+            y2: self.y1 + f64::from(sub_tile.y + 1) * h,
38
+        }
39
+    }
28
 }
40
 }
29
 
41
 
30
 #[derive(Clone, Debug)]
42
 #[derive(Clone, Debug)]
137
                     }
149
                     }
138
                 );
150
                 );
139
             } else {
151
             } else {
140
-                // look for cached tiles in lower zoom layers
152
+                // exact tile not found
153
+
154
+                // default tile
141
                 let mut tex_sub_rect = self.slot_to_texture_rect(Self::default_slot());
155
                 let mut tex_sub_rect = self.slot_to_texture_rect(Self::default_slot());
142
                 let mut tex_rect = tex_sub_rect;
156
                 let mut tex_rect = tex_sub_rect;
157
+
158
+                // look for cached tiles in lower zoom layers
143
                 for dist in 1..31 {
159
                 for dist in 1..31 {
144
                     if let Some((parent_tile, sub_coord)) = vt.tile.parent(dist) {
160
                     if let Some((parent_tile, sub_coord)) = vt.tile.parent(dist) {
145
                         if let Some(slot) = self.store(parent_tile, source, cache, false) {
161
                         if let Some(slot) = self.store(parent_tile, source, cache, false) {
147
                             tex_rect = self.slot_to_texture_rect(slot);
163
                             tex_rect = self.slot_to_texture_rect(slot);
148
                             break;
164
                             break;
149
                         }
165
                         }
166
+                    } else {
167
+                        break;
150
                     }
168
                     }
151
                 }
169
                 }
152
-                tvt.push(
153
-                    TexturedVisibleTile {
154
-                        screen_rect: vt.rect,
155
-                        tex_rect: tex_sub_rect,
156
-                        tex_minmax: tex_rect.inset(inset_x, inset_y),
170
+
171
+                // look for cached tiles in higher zoom layers
172
+                for &(child_tile, child_sub_coord) in &vt.tile.children() {
173
+                    if let Some(slot) = self.store(child_tile, source, cache, false) {
174
+                        let tex_rect = self.slot_to_texture_rect(slot);
175
+
176
+                        tvt.push(
177
+                            TexturedVisibleTile {
178
+                                screen_rect: vt.rect.subdivide(&child_sub_coord),
179
+                                tex_rect: tex_rect,
180
+                                tex_minmax: tex_rect.inset(inset_x, inset_y),
181
+                            }
182
+                        );
183
+                    } else {
184
+                        tvt.push(
185
+                            TexturedVisibleTile {
186
+                                screen_rect: vt.rect.subdivide(&child_sub_coord),
187
+                                tex_rect: tex_sub_rect.subdivide(&child_sub_coord),
188
+                                tex_minmax: tex_rect.inset(inset_x, inset_y),
189
+                            }
190
+                        );
157
                     }
191
                     }
158
-                );
192
+                }
159
             };
193
             };
160
-
161
         }
194
         }
162
 
195
 
163
         tvt
196
         tvt