Просмотр исходного кода

Show tiles from a higher zoom level to fill gaps

Johannes Hofmann 8 лет назад
Родитель
Сommit
364907e29e
2 измененных файлов: 123 добавлений и 13 удалений
  1. 82
    5
      src/coord.rs
  2. 41
    8
      src/tile_cache_gl.rs

+ 82
- 5
src/coord.rs Просмотреть файл

@@ -103,11 +103,18 @@ pub struct ScreenRect {
103 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 120
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@@ -117,6 +124,23 @@ pub struct SubTileCoord {
117 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 144
 impl TileCoord {
121 145
     pub fn new(zoom: u32, x: i32, y: i32) -> TileCoord {
122 146
         TileCoord {
@@ -168,6 +192,59 @@ impl 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 248
     #[inline]
172 249
     fn normalize_coord(coord: i32, zoom: u32) -> i32 {
173 250
         let max = Self::get_zoom_level_tiles(zoom);

+ 41
- 8
src/tile_cache_gl.rs Просмотреть файл

@@ -25,6 +25,18 @@ impl TextureRect {
25 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 42
 #[derive(Clone, Debug)]
@@ -137,9 +149,13 @@ impl<'a> TileCacheGl<'a> {
137 149
                     }
138 150
                 );
139 151
             } else {
140
-                // look for cached tiles in lower zoom layers
152
+                // exact tile not found
153
+
154
+                // default tile
141 155
                 let mut tex_sub_rect = self.slot_to_texture_rect(Self::default_slot());
142 156
                 let mut tex_rect = tex_sub_rect;
157
+
158
+                // look for cached tiles in lower zoom layers
143 159
                 for dist in 1..31 {
144 160
                     if let Some((parent_tile, sub_coord)) = vt.tile.parent(dist) {
145 161
                         if let Some(slot) = self.store(parent_tile, source, cache, false) {
@@ -147,17 +163,34 @@ impl<'a> TileCacheGl<'a> {
147 163
                             tex_rect = self.slot_to_texture_rect(slot);
148 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 196
         tvt