1 /* 2 * Copyright (C) 2010-2011 Dmitry Marakasov 3 * 4 * This file is part of glosm. 5 * 6 * glosm is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation, either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * glosm is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with glosm. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef TILEMANAGER_HH 21 #define TILEMANAGER_HH 22 23 #include <glosm/BBox.hh> 24 #include <glosm/Projection.hh> 25 26 #include <pthread.h> 27 28 #include <list> 29 #include <map> 30 #include <set> 31 32 class Geometry; 33 class GeometryDatasource; 34 class Viewer; 35 class Tile; 36 37 /** 38 * Generic quadtree tile manager 39 * 40 * This class is serves as a base class for layers and manages tile 41 * loading, displaying and disposal. 42 * 43 * @todo this class is planned to handle multilayer tile hierarchies, 44 * however for now level is fixed 45 */ 46 class TileManager { 47 public: 48 enum RequestFlags { 49 SYNC = 0x01, 50 BLOB = 0x02, 51 }; 52 53 protected: 54 /** 55 * Tile identifier 56 */ 57 struct TileId { 58 int level; 59 int x; 60 int y; 61 TileIdTileManager::TileId62 TileId(int lev, int xx, int yy) : level(lev), x(xx), y(yy) { 63 } 64 operator ==TileManager::TileId65 inline bool operator==(const TileId& other) const { 66 return x == other.x && y == other.y && level == other.level; 67 } 68 operator !=TileManager::TileId69 inline bool operator!=(const TileId& other) const { 70 return x != other.x || y != other.y || level != other.level; 71 } 72 }; 73 74 /** 75 * Single node of a quadtree 76 */ 77 struct QuadNode { 78 Tile* tile; 79 int generation; 80 BBoxi bbox; 81 82 QuadNode* childs[4]; 83 QuadNodeTileManager::QuadNode84 QuadNode() : tile(NULL), generation(0), bbox(BBoxi::ForGeoTile(0, 0, 0)) { 85 childs[0] = childs[1] = childs[2] = childs[3] = NULL; 86 } 87 }; 88 89 /** 90 * Single tile loading request 91 */ 92 struct TileTask { 93 TileId id; 94 BBoxi bbox; 95 TileTaskTileManager::TileTask96 TileTask(const TileId& i, const BBoxi& b) : id(i), bbox(b) { 97 } 98 }; 99 100 /** 101 * Holder of data for LoadLocality request 102 */ 103 struct RecLoadTilesInfo { 104 enum Modes { 105 BBOX, 106 LOCALITY 107 }; 108 109 union { 110 const Viewer* viewer; 111 const BBoxi* bbox; 112 }; 113 114 int mode; 115 int flags; 116 Vector3i viewer_pos; 117 float closest_distance; 118 int queue_size; 119 RecLoadTilesInfoTileManager::RecLoadTilesInfo120 RecLoadTilesInfo() : queue_size(0) { 121 } 122 }; 123 124 protected: 125 typedef std::list<TileTask> TilesQueue; 126 typedef std::vector<QuadNode**> GCQueue; 127 128 protected: 129 /* @todo it would be optimal to delegate these to layer via either 130 * virtual methods or templates */ 131 int level_; 132 float range_; 133 volatile int flags_; 134 bool height_effect_; 135 size_t size_limit_; 136 137 const Projection projection_; 138 139 mutable pthread_mutex_t tiles_mutex_; 140 /* protected by tiles_mutex_ */ 141 QuadNode root_; 142 int generation_; 143 size_t total_size_; 144 int tile_count_; 145 /* /protected by tiles_mutex_ */ 146 147 mutable pthread_mutex_t queue_mutex_; 148 pthread_cond_t queue_cond_; 149 /* protected by queue_mutex_ */ 150 TilesQueue queue_; 151 TileId loading_; 152 /* /protected by queue_mutex_ */ 153 154 pthread_t loading_thread_; 155 volatile bool thread_die_flag_; 156 157 protected: 158 /** 159 * Constructs Tile 160 */ 161 TileManager(const Projection projection); 162 163 /** 164 * Destructor 165 */ 166 virtual ~TileManager(); 167 168 /** 169 * Spawns a single tile with specified bbox 170 */ 171 virtual Tile* SpawnTile(const BBoxi& bbox, int flags) const = 0; 172 173 /** 174 * Recursive tile loading function for viewer's locality 175 * 176 * @todo remove code duplication with RecLoadTilesBBox 177 */ 178 void RecLoadTilesLocality(RecLoadTilesInfo& info, QuadNode** pnode, int level = 0, int x = 0, int y = 0); 179 180 /** 181 * Recursive tile loading function for given bbox 182 * 183 * @todo remove code duplication with RecLoadTilesLocality 184 */ 185 void RecLoadTilesBBox(RecLoadTilesInfo& info, QuadNode** pnode, int level = 0, int x = 0, int y = 0); 186 187 /** 188 * Recursive function that places tile into specified quadtree point 189 */ 190 void RecPlaceTile(QuadNode* node, Tile* tile, int level = 0, int x = 0, int y = 0); 191 192 /** 193 * Recursive function for tile rendering 194 */ 195 void RecRenderTiles(QuadNode* node, const Viewer& viewer); 196 197 /** 198 * Recursive function for destroying tiles and quadtree nodes 199 */ 200 void RecDestroyTiles(QuadNode* node); 201 202 /** 203 * Recursive function for garbage collecting unneeded tiles 204 */ 205 void RecGarbageCollectTiles(QuadNode* node, GCQueue& gcqueue); 206 207 /** 208 * Thread function for tile loading 209 */ 210 void LoadingThreadFunc(); 211 212 /** 213 * Static wrapper for thread function 214 */ 215 static void* LoadingThreadFuncWrapper(void* arg); 216 217 /** 218 * Loads tiles 219 */ 220 void Load(RecLoadTilesInfo& info); 221 222 protected: 223 /** 224 * Renders visible tiles 225 */ 226 void Render(const Viewer& viewer); 227 228 protected: 229 static bool GenerationCompare(QuadNode** x, QuadNode** y); 230 231 public: 232 /** 233 * Loads square area of tiles 234 */ 235 void LoadArea(const BBoxi& bbox, int flags = 0); 236 237 /** 238 * Loads tiles in locality of Viewer 239 */ 240 void LoadLocality(const Viewer& viewer, int flags = 0); 241 242 /** 243 * Destroys unneeded tiles 244 */ 245 void GarbageCollect(); 246 247 /** 248 * Destroys all tiles 249 */ 250 void Clear(); 251 252 /** 253 * Sets designated tile level 254 * 255 * @param level desired level 256 */ 257 void SetLevel(int level); 258 259 /** 260 * Sets range in which tiles are visible 261 * 262 * @param range range in meters 263 */ 264 void SetRange(float range); 265 266 /** 267 * Sets flags for tile spawinig 268 * 269 * @param flags flags 270 * @see GeometryGenerator::GetGeometry 271 */ 272 void SetFlags(int flags); 273 274 /** 275 * Sets mode of taking viewer height into account 276 * 277 * @param enabled if true, height is taken into account 278 * when calculating distance from viewer to tile 279 */ 280 void SetHeightEffect(bool enabled); 281 282 /** 283 * Sets limit on cumulative tiles size 284 * 285 * @param limit size limit in bytes 286 */ 287 void SetSizeLimit(size_t limit); 288 }; 289 290 #endif 291