/* -*-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 */ #ifndef OSGEARTH_CUBE_H #define OSGEARTH_CUBE_H 1 #include #include #include #include namespace osgEarth { namespace Contrib { using namespace osgEarth; /** * Utilities for working with cube and cubeface coordinates. */ class OSGEARTH_EXPORT CubeUtils { public: /** * Converts lat/long into face coordinates. You can optionally supply a "face hint" * if you already know which face the result will be in. This is handy for resolving * border ambiguities (i.e. a lat/lon that falls on the border of two faces). */ static bool latLonToFaceCoords( double lat_deg, double lon_deg, double& out_x, double& out_y, int& out_face, int faceHint = -1 ); /** * Converts face coordinates into lat/long. */ static bool faceCoordsToLatLon( double x, double y, int face, double& out_lat_deg, double& out_lon_deg ); /** * Get the face # containing a TileKey. */ static int getFace( const TileKey& key ); /** * Converts cube coordinates (0,0=>6,1) to face coordinates (0,0=>1,1,F). * WARNING. If the cube coordinate lies on a face boundary, this method will * always return the lower-numbered face. The "extent" version of this * method (below) is better b/c it's unambiguous. */ static bool cubeToFace( double& in_out_x, double& in_out_y, int& out_face ); /** * Converts cube coordinates (0,0=>6,1) to face coordinates (0,0=>1,1,F). This * version takes an extent, which is better than the non-extent version since it * can resolve face-border ambiguity. */ static bool cubeToFace( double& in_out_xmin, double& in_out_ymin, double& in_out_xmax, double& in_out_ymax, int& out_face ); /** * Converts face coordinates (0,0=>1,1 +F) to cube coordinates (0,0=>6,1). */ static bool faceToCube( double& in_out_x, double& in_out_y, int face ); }; /** * The "Cube" SRS represents a 6-face cube, each face being in unit coordinates (0,0=>1,1). * the cube as whole lays out all six faces side by side, resulting in a space * measuring (0,0=>6,1). The face number corresponds to the x-axis ordinal. */ class OSGEARTH_EXPORT CubeSpatialReference : public SpatialReference { public: CubeSpatialReference( const Key& key); // CUBE is a projected coordinate system. virtual bool isGeographic() const override { return false; } virtual bool isProjected() const override { return true; } // This SRS uses a WGS84 lat/long SRS under the hood for reprojection. So we need the // pre/post transforms to move from cube to latlong and back. virtual const SpatialReference* preTransform ( std::vector& points ) const override; virtual const SpatialReference* postTransform( std::vector& points ) const override; virtual bool transformExtentToMBR( const SpatialReference* to_srs, double& in_out_xmin, double& in_out_ymin, double& in_out_xmax, double& in_out_ymax ) const override; private: bool transformInFaceExtentToMBR( const SpatialReference* to_srs, int face, double& in_out_xmin, double& in_out_ymin, double& in_out_xmax, double& in_out_ymax ) const; virtual ~CubeSpatialReference(); }; /** * Custom profile for the unified cube tile layout. * * This is a whole-earth profile consisting of 6 cube faces. The first 4 faces * represent the equatorial regions between -45 and 45 degrees latitude. The lat * 2 faces represent the polar regions. * * The face extents in lat/long are: (lat,lon min => lat,lon max) * * Face 0 : (-180, -45 => -90, 45) * Face 1 : (-90, -45 => 0, 45) * Face 2 : (0, -45 => 90, 45) * Face 3 : (90, -45 => 180, 45 ) * Face 4 : (-180, 45 => 180, 90) * Face 5 : (-180, -90 => 180, -45) * * Each face was a local unit coordinate system of (0.0, 0.0 => 1.0, 1.0). The * profile lays the 6 faces out in a row, making a cube coordinate system * of (0.0, 0.0 => 6.0, 1.0). * * NOTE! This profile is non-contiguous and cannot be created as a single * rectangular domain. */ class OSGEARTH_EXPORT UnifiedCubeProfile : public Profile { public: UnifiedCubeProfile(); virtual ~UnifiedCubeProfile(); public: // utilities /** * Gets the cube face associated with a tile key (in cube srs). */ static int getFace( const TileKey& key ); public: // Profile void getIntersectingTiles( const GeoExtent& extent, unsigned localLOD, std::vector< TileKey >& out_intersectingKeys ) const; unsigned getEquivalentLOD(const Profile* rhsProfile, unsigned rhsLOD) const; private: GeoExtent _faceExtent_gcs[6]; GeoExtent transformGcsExtentOnFace( const GeoExtent& gcsExtent, int face ) const; }; } } #endif // OSGEARTH_CUBE_H