354 lines
12 KiB
Plaintext
354 lines
12 KiB
Plaintext
|
/* -*-c++-*- */
|
||
|
/* osgEarth - Geospatial SDK for OpenSceneGraph
|
||
|
* Copyright 2020 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_GRID_PROFILE_H
|
||
|
#define OSGEARTH_TILE_GRID_PROFILE_H 1
|
||
|
|
||
|
#include <osgEarth/Common>
|
||
|
#include <osgEarth/Config>
|
||
|
#include <osgEarth/GeoData>
|
||
|
#include <osgEarth/SpatialReference>
|
||
|
#include <vector>
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
class TileKey;
|
||
|
|
||
|
/**
|
||
|
* Configuration options for initializing a Profile.
|
||
|
* TODO: refactor into Profile::Options
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT ProfileOptions : public ConfigOptions
|
||
|
{
|
||
|
public:
|
||
|
ProfileOptions( const ConfigOptions& options =ConfigOptions() );
|
||
|
ProfileOptions( const std::string& namedProfile );
|
||
|
|
||
|
/** dtor */
|
||
|
virtual ~ProfileOptions() { }
|
||
|
|
||
|
/** Returns true if this configuration is well-defined and usable */
|
||
|
bool defined() const;
|
||
|
|
||
|
public: // properties
|
||
|
|
||
|
/** Gets the optional Well-Known Profile string. */
|
||
|
optional<std::string>& namedProfile() { return _namedProfile; }
|
||
|
const optional<std::string>& namedProfile() const { return _namedProfile; }
|
||
|
|
||
|
/** Gets the spatial reference system initialization string to use for the profile. */
|
||
|
optional<std::string>& srsString() { return _srsInitString; }
|
||
|
const optional<std::string>& srsString() const { return _srsInitString; }
|
||
|
|
||
|
/** Gets the vertical spatial reference init string for this profile. */
|
||
|
optional<std::string>& vsrsString() { return _vsrsInitString; }
|
||
|
const optional<std::string>& vsrsString() const { return _vsrsInitString; }
|
||
|
|
||
|
/** Geospatial bounds for this profile's extent */
|
||
|
optional<Bounds>& bounds() { return _bounds; }
|
||
|
const optional<Bounds>& bounds() const { return _bounds; }
|
||
|
|
||
|
/** Number of tiles in the X axis at LOD 0 */
|
||
|
optional<int>& numTilesWideAtLod0() { return _numTilesWideAtLod0; }
|
||
|
const optional<int>& numTilesWideAtLod0() const { return _numTilesWideAtLod0; }
|
||
|
|
||
|
/** Number of tiles on the Y axis at LOD 0 */
|
||
|
optional<int>& numTilesHighAtLod0() { return _numTilesHighAtLod0; }
|
||
|
const optional<int>& numTilesHighAtLod0() const { return _numTilesHighAtLod0; }
|
||
|
|
||
|
public:
|
||
|
Config getConfig() const;
|
||
|
|
||
|
protected:
|
||
|
virtual void mergeConfig( const Config& conf );
|
||
|
|
||
|
private:
|
||
|
void fromConfig( const Config& conf );
|
||
|
|
||
|
optional<std::string> _namedProfile;
|
||
|
optional<std::string> _srsInitString;
|
||
|
optional<std::string> _vsrsInitString;
|
||
|
optional<Bounds> _bounds;
|
||
|
optional<int> _numTilesWideAtLod0;
|
||
|
optional<int> _numTilesHighAtLod0;
|
||
|
};
|
||
|
}
|
||
|
OSGEARTH_SPECIALIZE_CONFIG(osgEarth::ProfileOptions);
|
||
|
|
||
|
|
||
|
namespace osgEarth
|
||
|
{
|
||
|
/**
|
||
|
* A "profile" defines the layout of a data source. The profile conveys the
|
||
|
* spatial reference system (SRS), the geospatial extents within that SRS, and
|
||
|
* the tiling scheme.
|
||
|
*/
|
||
|
class OSGEARTH_EXPORT Profile : public osg::Referenced
|
||
|
{
|
||
|
public:
|
||
|
// well knowns
|
||
|
static std::string GLOBAL_GEODETIC;
|
||
|
static std::string GLOBAL_MERCATOR;
|
||
|
static std::string SPHERICAL_MERCATOR;
|
||
|
static std::string PLATE_CARREE;
|
||
|
|
||
|
public:
|
||
|
|
||
|
static const Profile* create(
|
||
|
const std::string& srs_string,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
const std::string& vsrs_string ="",
|
||
|
unsigned int numTilesWideAtLod0 =0,
|
||
|
unsigned int numTilesHighAtLod0 =0 );
|
||
|
|
||
|
static const Profile* create(
|
||
|
const SpatialReference* srs,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
double geoxmin, double geoymin, double geoxmax, double geoymax,
|
||
|
unsigned int numTilesWideAtLod0 =0,
|
||
|
unsigned int numTilesHighAtLod0 =0 );
|
||
|
|
||
|
static const Profile* create(
|
||
|
const SpatialReference* srs,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
unsigned int numTilesWideAtLod0 =0,
|
||
|
unsigned int numTilesHighAtLod0 =0 );
|
||
|
|
||
|
static const Profile* create(
|
||
|
const std::string& wellKnownName,
|
||
|
const SpatialReference* srs,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
unsigned int numTilesWideAtLod0 = 0,
|
||
|
unsigned int numTilesHighAtLod0 = 0);
|
||
|
|
||
|
static const Profile* create(
|
||
|
const SpatialReference* srs);
|
||
|
|
||
|
static const Profile* create(
|
||
|
const std::string& srs_string,
|
||
|
const std::string& vsrs_string,
|
||
|
unsigned int numTilesWideAtLod0 =0,
|
||
|
unsigned int numTilesHighAtLod0 =0 );
|
||
|
|
||
|
static const Profile* create(
|
||
|
const ProfileOptions& options );
|
||
|
|
||
|
static const Profile* create(
|
||
|
const std::string& name);
|
||
|
|
||
|
static const Profile* create_with_vdatum(
|
||
|
const std::string& name,
|
||
|
const std::string& vsrsString);
|
||
|
|
||
|
/**
|
||
|
* Returns true if the profile is properly initialized.
|
||
|
*/
|
||
|
bool isOK() const;
|
||
|
|
||
|
/**
|
||
|
* Gets the extent of the profile (in the profile's SRS)
|
||
|
*/
|
||
|
const GeoExtent& getExtent() const;
|
||
|
|
||
|
/**
|
||
|
* Gets the extent of the profile (in lat/long.)
|
||
|
*/
|
||
|
const GeoExtent& getLatLongExtent() const;
|
||
|
|
||
|
/**
|
||
|
* Gets the spatial reference system underlying this profile.
|
||
|
*/
|
||
|
const SpatialReference* getSRS() const;
|
||
|
|
||
|
/**
|
||
|
* Given an x-resolution, specified in the profile's SRS units, calculates and
|
||
|
* returns the closest LOD level.
|
||
|
*/
|
||
|
unsigned int getLevelOfDetailForHorizResolution( double resolution, int tileSize ) const;
|
||
|
|
||
|
/**
|
||
|
* Gets the tile keys that comprise the tiles at the root (LOD 0) of this
|
||
|
* profile. Same as calling getAllKeysAtLOD(0).
|
||
|
*/
|
||
|
void getRootKeys(std::vector<TileKey>& out_keys ) const;
|
||
|
|
||
|
/**
|
||
|
* Gets all the tile keys at the specified LOD.
|
||
|
*/
|
||
|
void getAllKeysAtLOD(unsigned lod, std::vector<TileKey>& out_keys) const;
|
||
|
|
||
|
/**
|
||
|
* Calculates an extent given a tile location in this profile.
|
||
|
*/
|
||
|
virtual GeoExtent calculateExtent(unsigned int lod, unsigned int tileX, unsigned int tileY) const;
|
||
|
|
||
|
/**
|
||
|
* Gets whether the two profiles can be treated as equivalent.
|
||
|
* @param rhs
|
||
|
* Comparison profile
|
||
|
*/
|
||
|
bool isEquivalentTo( const Profile* rhs ) const;
|
||
|
|
||
|
/**
|
||
|
* Gets whether the two profiles can be treated as equivalent (without regard
|
||
|
* for any vertical datum information - i.e., still returns true if the SRS
|
||
|
* vertical datums are different)
|
||
|
* @param rhs
|
||
|
* Comparison profile
|
||
|
*/
|
||
|
bool isHorizEquivalentTo( const Profile* rhs ) const;
|
||
|
|
||
|
/**
|
||
|
*Gets the tile dimensions at the given lod.
|
||
|
*/
|
||
|
void getTileDimensions(unsigned int lod, double& out_width, double& out_height) const;
|
||
|
|
||
|
/**
|
||
|
*Gets the number wide and high at the given lod
|
||
|
*/
|
||
|
void getNumTiles(unsigned int lod, unsigned int& out_tiles_wide, unsigned int& out_tiles_high) const;
|
||
|
|
||
|
/**
|
||
|
*Gets the intersecting tiles of this Profile with the given TileKey.
|
||
|
*/
|
||
|
void getIntersectingTiles(
|
||
|
const TileKey& key,
|
||
|
std::vector<TileKey>& out_intersectingKeys) const;
|
||
|
|
||
|
/**
|
||
|
*Gets the intersecting tiles of this Profile with the given extents
|
||
|
*/
|
||
|
virtual void getIntersectingTiles(
|
||
|
const GeoExtent& extent,
|
||
|
unsigned localLOD,
|
||
|
std::vector<TileKey>& out_intersectingKeys) const;
|
||
|
|
||
|
/**
|
||
|
* Clamps the incoming extents to the extents of this profile, and then converts the
|
||
|
* clamped extents to this profile's SRS, and returns the result. Returned GeoExtent::INVALID
|
||
|
* if the transformation fails.
|
||
|
*/
|
||
|
GeoExtent clampAndTransformExtent( const GeoExtent& input, bool* out_clamped =0L ) const;
|
||
|
|
||
|
/**
|
||
|
* Creates a tile key for a tile that contains the input location at the specified LOD.
|
||
|
* Express the coordinates in the profile's SRS.
|
||
|
* Returns TileKey::INVALID if the point lies outside the profile's extents.
|
||
|
*/
|
||
|
TileKey createTileKey( double x, double y, unsigned int level ) const;
|
||
|
|
||
|
//! Creates a tile key for a tile that contains the input location.
|
||
|
//! @param point Point at which to create the tile key
|
||
|
//! @param lod LOD at which to create the tile key
|
||
|
//! @return tile key containing the point
|
||
|
TileKey createTileKey(const GeoPoint& point, unsigned level) const;
|
||
|
|
||
|
/**
|
||
|
* Returns a readable description of the profile.
|
||
|
*/
|
||
|
std::string toString() const;
|
||
|
|
||
|
/**
|
||
|
* Builds and returns a ProfileOptions for this profile
|
||
|
*/
|
||
|
ProfileOptions toProfileOptions() const;
|
||
|
|
||
|
/**
|
||
|
* Returns a signature hash code unique to this profile.
|
||
|
*/
|
||
|
const std::string& getFullSignature() const { return _fullSignature; }
|
||
|
|
||
|
/**
|
||
|
* Returns a signature hash code that uniquely identifies this profile
|
||
|
* without including any vertical datum information. This is useful for
|
||
|
* seeing if two profiles are horizontally compatible.
|
||
|
*/
|
||
|
const std::string& getHorizSignature() const { return _horizSignature; }
|
||
|
|
||
|
/**
|
||
|
* Given another Profile and an LOD in that Profile, determine
|
||
|
* the LOD in this Profile that is nearly equivalent.
|
||
|
*/
|
||
|
virtual unsigned getEquivalentLOD(const Profile* profile, unsigned lod) const;
|
||
|
|
||
|
/**
|
||
|
* Given a LOD-0 tile height, determine the LOD in this Profile that
|
||
|
* most closely houses a tile with that height.
|
||
|
*/
|
||
|
virtual unsigned getLOD(double tileHeight) const;
|
||
|
|
||
|
//! Get the hash code for this profile
|
||
|
std::size_t hash() const { return _hash; }
|
||
|
|
||
|
public:
|
||
|
|
||
|
/**
|
||
|
* Makes a clone of this profile but replaces the SRS with a custom one.
|
||
|
*/
|
||
|
Profile* overrideSRS( const SpatialReference* srs ) const;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
Profile(
|
||
|
const SpatialReference* srs,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
unsigned int x_tiles_at_lod0 =0,
|
||
|
unsigned int y_tiles_at_lod0 =0 );
|
||
|
|
||
|
Profile(
|
||
|
const SpatialReference* srs,
|
||
|
double xmin, double ymin, double xmax, double ymax,
|
||
|
double geoxmin, double geoymin, double geoxmax, double geoymax,
|
||
|
unsigned int x_tiles_at_lod0 =0,
|
||
|
unsigned int y_tiles_at_lod0 =0 );
|
||
|
|
||
|
/** dtor */
|
||
|
virtual ~Profile() { }
|
||
|
|
||
|
|
||
|
virtual void addIntersectingTiles(
|
||
|
const GeoExtent& key_ext,
|
||
|
unsigned localLOD,
|
||
|
std::vector<TileKey>& out_intersectingKeys) const;
|
||
|
|
||
|
|
||
|
private:
|
||
|
|
||
|
std::string _wellKnownName;
|
||
|
GeoExtent _extent;
|
||
|
GeoExtent _latlong_extent;
|
||
|
unsigned _numTilesWideAtLod0;
|
||
|
unsigned _numTilesHighAtLod0;
|
||
|
std::string _fullSignature;
|
||
|
std::string _horizSignature;
|
||
|
std::size_t _hash;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace std {
|
||
|
// std::hash specialization for Profile
|
||
|
template<> struct hash<osgEarth::Profile> {
|
||
|
inline size_t operator()(const osgEarth::Profile& value) const {
|
||
|
return value.hash();
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
|
||
|
#endif // OSGEARTH_TILE_GRID_PROFILE_H
|