/* -*-c++-*- */ /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph * Copyright 2015 Pelican Mapping * http://osgearth.org * * osgEarth is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ #ifndef OSGEARTH_TILE_KEY_H #define OSGEARTH_TILE_KEY_H 1 #include <osgEarth/Common> #include <osgEarth/Profile> #include <osg/ref_ptr> #include <osg/Version> #include <string> namespace osgEarth { /** * Uniquely identifies a single tile on the map, relative to a Profile. * Profiles have an origin of 0,0 at the top left. */ class OSGEARTH_EXPORT TileKey { public: /** * Constructs an invalid TileKey. */ TileKey() { } /** * Creates a new TileKey with the given tile xy at the specified level of detail * * @param lod * The level of detail (subdivision recursion level) of the tile * @param tile_x * The x index of the tile * @param tile_y * The y index of the tile * @param profile * The profile for the tile */ TileKey( unsigned int lod, unsigned int tile_x, unsigned int tile_y, const Profile* profile ); /** Copy constructor. */ TileKey( const TileKey& rhs ); /** dtor */ virtual ~TileKey() { } /** Compare two tilekeys for equality. */ bool operator == (const TileKey& rhs) const { return valid() && rhs.valid() && _lod==rhs._lod && _x==rhs._x && _y==rhs._y && _profile->isHorizEquivalentTo(rhs._profile.get()); } /** Compare two tilekeys for inequality */ bool operator != (const TileKey& rhs) const { return !(*this == rhs); } /** Sorts tilekeys, ignoring profiles */ bool operator < (const TileKey& rhs) const { if (_lod < rhs._lod) return true; if (_lod > rhs._lod) return false; if (_x < rhs._x) return true; if (_x > rhs._x) return false; return _y < rhs._y; } /** * Canonical invalid tile key. */ static TileKey INVALID; /** * Gets the string representation of the key, formatted like: * "lod_x_y" */ const std::string& str() const { return _key; } /** * Gets the profile within which this key is interpreted. */ const osgEarth::Profile* getProfile() const; /** * Whether this is a valid key. */ bool valid() const { return _profile.valid(); } /** * Get the quadrant relative to this key's parent. */ unsigned getQuadrant() const; public: /** * Gets a reference to the child key of this key in the specified * quadrant (0, 1, 2, or 3). */ TileKey createChildKey( unsigned int quadrant ) const; /** * Creates and returns a key that represents the parent tile of this key. */ TileKey createParentKey() const; /** * Creates and returns a key that represents an ancestor tile corresponding to * the specified LOD. */ TileKey createAncestorKey( int ancestorLod ) const; /** * Creates a key that represents this tile's neighbor at the same LOD. Wraps * around in X and Y automatically. For example, xoffset=-1 yoffset=1 will * give you the key for the tile SW of this tile. */ TileKey createNeighborKey( int xoffset, int yoffset ) const; /** * Gets the level of detail of the tile represented by this key. */ unsigned getLevelOfDetail() const { return _lod; } unsigned getLOD() const { return _lod; } /** * Gets the geospatial extents of the tile represented by this key. */ const GeoExtent& getExtent() const { return _extent; } /** * Gets the extents of this key's tile, in pixels */ void getPixelExtents( unsigned int& out_minx, unsigned int& out_miny, unsigned int& out_maxx, unsigned int& out_maxy, const unsigned int& tile_size) const; /** * Gets the X and Y indexes of this tile at its level of detail. */ void getTileXY( unsigned int& out_tile_x, unsigned int& out_tile_y) const; unsigned int getTileX() const { return _x; } unsigned int getTileY() const { return _y; } /** * Maps this tile key to another tile key in order to account in * a resolution difference. For example: we are requesting data for * a TileKey at LOD 4, at a tile size of 32. The source data's tile * size if 256. That means the source data at LOD 1 will contain the * data necessary to build the tile. * * usage: TileKey tk = mapResolution(31, 256); * * We want a 31x31 tile. The source data is 256x256. This will return * a TileKey that access the appropriate source data, which we will then * need to crop to populate our tile. * * You can set "minimumLOD" if you don't want a key below a certain LOD. */ TileKey mapResolution( unsigned targetSize, unsigned sourceDataSize, unsigned minimumLOD =0) const; protected: std::string _key; unsigned int _lod; unsigned int _x; unsigned int _y; osg::ref_ptr<const Profile> _profile; GeoExtent _extent; }; } #endif // OSGEARTH_TILE_KEY_H