4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #ifndef XCSOAR_RASTERTILE_CACHE_HPP
25 #define XCSOAR_RASTERTILE_CACHE_HPP
27 #include "RasterTile.hpp"
28 #include "Geo/GeoBounds.hpp"
29 #include "Util/NonCopyable.hpp"
30 #include "Util/StaticArray.hpp"
31 #include "Util/Serial.hpp"
39 #define RASTER_SLOPE_FACT 12
41 struct RasterLocation
;
43 class OperationEnvironment
;
45 class RasterTileCache
: private NonCopyable
{
46 static constexpr unsigned MAX_RTC_TILES
= 4096;
49 * The maximum number of tiles which are loaded at a time. This
50 * must be limited because the amount of memory is finite.
53 static constexpr unsigned MAX_ACTIVE_TILES
= 128;
54 #elif !defined(_WIN32_WCE)
55 // desktop: use a lot of memory
56 static constexpr unsigned MAX_ACTIVE_TILES
= 512;
57 #elif !defined(_WIN32_WCE) || (_WIN32_WCE >= 0x0400 && !defined(GNAV))
58 // embedded: use less memory
59 static constexpr unsigned MAX_ACTIVE_TILES
= 32;
61 // old Windows CE and Altair: use only little memory
62 static constexpr unsigned MAX_ACTIVE_TILES
= 16;
66 * The width and height of the terrain bitmap is shifted by this
67 * number of bits to determine the overview size.
69 static constexpr unsigned OVERVIEW_BITS
= 4;
72 * Target number of steps in intersection searches; total distance
73 * is shifted by this number of bits
75 static constexpr unsigned INTERSECT_BITS
= 7;
79 * The fixed-point fractional part of sub-pixel coordinates.
81 * Do not edit! There are still some hard-coded code sections left,
82 * e.g. CombinedDivAndMod().
84 static constexpr unsigned SUBPIXEL_BITS
= 8;
87 friend struct RTDistanceSort
;
89 struct MarkerSegmentInfo
{
90 static constexpr uint16_t NO_TILE
= (uint16_t)-1;
93 * The position of this marker segment within the file.
98 * The associated tile number. -1 if this segment does not belong
104 * The number of follow-up segments.
108 MarkerSegmentInfo() {}
109 MarkerSegmentInfo(uint32_t _file_offset
, int _tile
=NO_TILE
)
110 :file_offset(_file_offset
), tile(_tile
), count(0) {}
112 bool IsTileSegment() const {
113 return tile
!= NO_TILE
;
127 unsigned width
, height
;
128 unsigned short tile_width
, tile_height
;
129 unsigned tile_columns
, tile_rows
;
130 unsigned num_marker_segments
;
136 /** is the "bounds" attribute valid? */
137 bool bounds_initialised
;
142 * This serial gets updated each time the tiles get loaded or
147 AllocatedGrid
<RasterTile
> tiles
;
148 unsigned short tile_width
, tile_height
;
150 RasterBuffer overview
;
152 unsigned int width
, height
;
153 unsigned int overview_width_fine
, overview_height_fine
;
157 StaticArray
<MarkerSegmentInfo
, 8192> segments
;
160 * The number of remaining segments after the current one.
162 mutable unsigned remaining_segments
;
165 * An array that is used to sort the requested tiles by distance.
166 * This is only used by PollTiles() internally, but is stored in the
167 * class because it would be too large for the stack.
169 StaticArray
<uint16_t, MAX_RTC_TILES
> request_tiles
;
172 * Progress callbacks for loading the file during startup.
174 OperationEnvironment
*operation
;
177 RasterTileCache():operation(NULL
) {
182 void ScanTileLine(GridLocation start
, GridLocation end
,
183 short *buffer
, unsigned size
, bool interpolate
) const;
187 * Determine the non-interpolated height at the specified pixel
190 * @param x the pixel column within the map; may be out of range
191 * @param y the pixel row within the map; may be out of range
194 short GetHeight(unsigned x
, unsigned y
) const;
197 * Determine the interpolated height at the specified sub-pixel
200 * @param lx the sub-pixel column within the map; may be out of range
201 * @param ly the sub-pixel row within the map; may be out of range
204 short GetInterpolatedHeight(unsigned int lx
,
205 unsigned int ly
) const;
208 * Scan a straight line and fill the buffer with the specified
209 * number of samples along the line.
211 * @param start the sub-pixel start location
212 * @param end the sub-pixel end location
214 void ScanLine(const RasterLocation start
, const RasterLocation end
,
215 short *buffer
, unsigned size
, bool interpolate
) const;
217 bool FirstIntersection(int origin_x
, int origin_y
,
218 int destination_x
, int destination_y
,
221 const int slope_fact
, const int h_ceiling
,
223 RasterLocation
&_location
, int &h_int
,
224 const bool can_climb
) const;
226 gcc_pure RasterLocation
227 Intersection(int origin_x
, int origin_y
,
228 int destination_x
, int destination_y
,
229 int h_origin
, const int slope_fact
) const;
232 void LoadJPG2000(const char *path
);
235 * Load a world file (*.tfw or *.j2w).
237 bool LoadWorldFile(const TCHAR
*path
);
241 * Get field (not interpolated) directly, without bringing tiles to front.
242 * @param px X position/256
243 * @param px Y position/256
244 * @param tile_index Remember position of active tile, or -1 for overview
245 * @return the terrain altitude and a flag that is true when the
246 * value was loaded from a "fine" tile
249 std::pair
<short, bool> GetFieldDirect(unsigned px
, unsigned py
) const;
252 bool LoadOverview(const char *path
, const TCHAR
*world_file
,
253 OperationEnvironment
&operation
);
255 bool SaveCache(FILE *file
) const;
256 bool LoadCache(FILE *file
);
258 void UpdateTiles(const char *path
, int x
, int y
, unsigned radius
);
261 * Determines if there are still tiles scheduled to be loaded. Call
262 * this after UpdateTiles() to determine if UpdateTiles() should be
265 bool IsDirty() const {
269 bool GetInitialised() const {
273 const Serial
&GetSerial() const {
279 const GeoBounds
&GetBounds() const {
280 assert(bounds_initialised
);
287 const MarkerSegmentInfo
*
288 FindMarkerSegment(uint32_t file_offset
) const;
291 /* callback methods for libjasper (via jas_rtc.cpp) */
293 long SkipMarkerSegment(long file_offset
) const;
294 void MarkerSegment(long file_offset
, unsigned id
);
296 bool TileRequest(unsigned index
);
298 short *GetOverview() {
299 return overview
.GetData();
302 void SetSize(unsigned width
, unsigned height
,
303 unsigned tile_width
, unsigned tile_height
,
304 unsigned tile_columns
, unsigned tile_rows
);
305 short* GetImageBuffer(unsigned index
);
306 void SetLatLonBounds(double lon_min
, double lon_max
,
307 double lat_min
, double lat_max
);
308 void SetTile(unsigned index
, int xstart
, int ystart
, int xend
, int yend
);
310 void SetInitialised(bool val
) {
315 bool PollTiles(int x
, int y
, unsigned radius
);
318 short GetMaxElevation() const {
319 return overview
.GetMaximum();
322 unsigned int GetWidth() const { return width
; }
323 unsigned int GetHeight() const { return height
; }
325 unsigned GetFineWidth() const {
326 return width
<< SUBPIXEL_BITS
;
329 unsigned GetFineHeight() const {
330 return height
<< SUBPIXEL_BITS
;
334 unsigned GetFineTileWidth() const {
335 return tile_width
<< SUBPIXEL_BITS
;
338 unsigned GetFineTileHeight() const {
339 return tile_height
<< SUBPIXEL_BITS
;