DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/GDAL
2024-12-25 07:49:36 +08:00

319 lines
11 KiB
C++

/* -*-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/>
*/
#pragma once
#include <osgEarth/Common>
#include <osgEarth/ImageLayer>
#include <osgEarth/ElevationLayer>
#include <osgEarth/URI>
#include <osgEarth/Containers>
/**
* GDAL (Geospatial Data Abstraction Library) Layers
*/
class GDALDataset;
class GDALRasterBand;
namespace osgEarth
{
namespace GDAL
{
/**
* Encapsulates a user-supplied GDALDataset
*/
class OSGEARTH_EXPORT ExternalDataset : public osg::Referenced // NO EXPORT; header only
{
public:
//! Default constructor
ExternalDataset() = default;
//! Init constructor
ExternalDataset(GDALDataset* dataset, bool ownsDataset) :
_dataset(dataset), _ownsDataset(ownsDataset) {}
public:
GDALDataset* dataset() const { return _dataset; };
void setDataset(GDALDataset* dataset) { _dataset = dataset; };
bool ownsDataset() const { return _ownsDataset; };
void setOwnsDataset(bool ownsDataset) { _ownsDataset = ownsDataset; };
private:
GDALDataset* _dataset = nullptr;
bool _ownsDataset = true;
};
// GDAL-specific serialization data to be incorpoated by the LayerOptions below
class OSGEARTH_EXPORT Options
{
public:
Options() { }
Options(const ConfigOptions& input);
OE_OPTION(URI, url);
OE_OPTION(std::string, connection);
OE_OPTION(unsigned, subDataSet, 0u);
OE_OPTION(RasterInterpolation, interpolation, INTERP_AVERAGE);
OE_OPTION(ProfileOptions, warpProfile);
OE_OPTION(bool, useVRT, false);
OE_OPTION(bool, coverageUsesPaletteIndex, true);
OE_OPTION(bool, singleThreaded, false);
OE_OPTION(ProfileOptions, fallbackProfile);
void readFrom(const Config& conf);
void writeTo(Config& conf) const;
};
/**
* Driver for reading raster data using GDAL.
* It is rarely necessary to use this object directly; use a
* GDALImageLayer or GDALElevationLayer instead.
*/
class OSGEARTH_EXPORT Driver
{
public:
using Ptr = std::shared_ptr<Driver>;
//! Constructs a new driver
virtual ~Driver();
//! Value to interpet as "no data"
void setNoDataValue(float value) { _noDataValue = value; }
//! Minimum valid data value (anything less is "no data")
void setMinValidValue(float value) { _minValidValue = value; }
//! Maximum valid data value (anything more is "no data")
void setMaxValidValue(float value) { _maxValidValue = value; }
//! Maximum LOD at which to return real data
void setMaxDataLevel(unsigned value) { _maxDataLevel = value; }
//! Assign an external GDAL dataset to use.
void setExternalDataset(ExternalDataset* value);
//! Opens and initializes the connection to the dataset
Status open(
const std::string& name,
const GDAL::Options& options,
unsigned tileSize,
const Profile* fallback_profile,
DataExtentList* out_dataExtents,
const osgDB::Options* readOptions,
bool verbose);
//! Creates an image if possible
osg::Image* createImage(
const TileKey& key,
unsigned tileSize,
bool isCoverage,
ProgressCallback* progress);
//! Creates a heightfield if possible
osg::HeightField* createHeightField(
const TileKey& key,
unsigned tileSize,
ProgressCallback* progress);
//! Creates a heightfield if possible using a faster path that creates a temporary warped VRT.
osg::HeightField* createHeightFieldWithVRT(
const TileKey& key,
unsigned tileSize,
ProgressCallback* progress);
//! Profile of the underlying data source
const Profile* getProfile() { return _profile.get(); }
private:
void pixelToGeo(double, double, double&, double&);
void geoToPixel(double, double, double&, double&);
bool isValidValue(float, GDALRasterBand*);
bool intersects(const TileKey&);
float getInterpolatedValue(GDALRasterBand* band, double x, double y, bool applyOffset = true);
optional<float> _noDataValue, _minValidValue, _maxValidValue;
optional<unsigned> _maxDataLevel = 30;
GDALDataset* _srcDS = nullptr;
GDALDataset* _warpedDS = nullptr;
double _linearUnits = 1.0;
double _geotransform[6];
double _invtransform[6];
GeoExtent _extents;
Bounds _bounds;
osg::ref_ptr<const Profile> _profile;
GDAL::Options _gdalOptions;
const GDAL::Options& gdalOptions() const { return _gdalOptions; }
osg::ref_ptr<GDAL::ExternalDataset> _externalDataset;
std::string _name;
const std::string& getName() const { return _name; }
};
//! Creates an OSG image from an entire GDAL dataset
extern OSGEARTH_EXPORT osg::Image* reprojectImage(
const osg::Image* srcImage,
const std::string srcWKT,
double srcMinX, double srcMinY, double srcMaxX, double srcMaxY,
const std::string destWKT,
double destMinX, double destMinY, double destMaxX, double destMaxY,
int width = 0,
int height = 0,
bool useBilinearInterpolation = true);
struct LayerBase
{
protected:
mutable Util::PerThread<GDAL::Driver::Ptr> _driverPerThread;
mutable std::mutex _singleThreadingMutex;
mutable GDAL::Driver::Ptr _driverSingleThreaded = nullptr;
mutable Util::ReadWriteMutex _createCloseMutex;
};
}
}
namespace osgEarth
{
/**
* Image layer connected to a GDAL raster dataset
*/
class OSGEARTH_EXPORT GDALImageLayer : public ImageLayer, public GDAL::LayerBase
{
public: // serialization
class OSGEARTH_EXPORT Options : public ImageLayer::Options, public GDAL::Options {
public:
META_LayerOptions(osgEarth, Options, ImageLayer::Options);
virtual Config getConfig() const;
private:
void fromConfig(const Config&);
};
public:
META_Layer(osgEarth, GDALImageLayer, Options, ImageLayer, GDALImage);
//! Base URL for TMS requests
void setURL(const URI& value);
const URI& getURL() const;
//! Database connection for GDAL database queries (alternative to URL)
void setConnection(const std::string& value);
const std::string& getConnection() const;
//! GDAL sub-dataset index (optional)
void setSubDataSet(const unsigned& value);
const unsigned& getSubDataSet() const;
//! Interpolation method for resampling (default is bilinear)
void setInterpolation(const RasterInterpolation& value);
const RasterInterpolation& getInterpolation() const;
//! Use a single-threaded driver (default is multi-threaded)
void setSingleThreaded(bool value);
bool getSingleThreaded() const;
//! User-supplied external dataset
void setExternalDataset(GDAL::ExternalDataset* value);
public: // Layer
//! Called by the constructor
void init() override;
//! Establishes a connection to the TMS repository
Status openImplementation() override;
//! Closes down any GDAL connections
Status closeImplementation() override;
//! Gets a raster image for the given tile key
GeoImage createImageImplementation(const TileKey& key, ProgressCallback* progress) const override;
};
//! Elevation layer connected to a GDAL facility
class OSGEARTH_EXPORT GDALElevationLayer : public ElevationLayer, public GDAL::LayerBase
{
public: // serialization
class OSGEARTH_EXPORT Options : public ElevationLayer::Options, public GDAL::Options {
public:
META_LayerOptions(osgEarth, Options, ElevationLayer::Options);
virtual Config getConfig() const;
private:
void fromConfig(const Config&);
};
public:
META_Layer(osgEarth, GDALElevationLayer, Options, ElevationLayer, GDALElevation);
//! Base URL for TMS requests
void setURL(const URI& value);
const URI& getURL() const;
//! Database connection for GDAL database queries (alternative to URL)
void setConnection(const std::string& value);
const std::string& getConnection() const;
//! GDAL sub-dataset index (optional)
void setSubDataSet(const unsigned& value);
const unsigned& getSubDataSet() const;
//! Forced profile for reprojection (still need this?)
void setWarpProfile(const ProfileOptions& value);
const ProfileOptions& getWarpProfile() const;
//! Interpolation method for resampling (default is bilinear)
void setInterpolation(const RasterInterpolation& value);
const RasterInterpolation& getInterpolation() const;
//! User-supplied external dataset
void setExternalDataset(GDAL::ExternalDataset* value);
GDAL::ExternalDataset* getExtenalDataset() const;
//! Use the new VRT read approach
void setUseVRT(const bool& value);
const bool& getUseVRT() const;
//! Use a single-threaded driver (default is multi-threaded)
void setSingleThreaded(bool value);
bool getSingleThreaded() const;
public: // Layer
//! Called by the constructor
void init() override;
//! Establishes a connection to the repository
Status openImplementation() override;
//! Closes down any GDAL connections
Status closeImplementation() override;
//! Gets a heightfield for the given tile key
GeoHeightField createHeightFieldImplementation(const TileKey& key, ProgressCallback* progress) const override;
};
} // namespace osgEarth
OSGEARTH_SPECIALIZE_CONFIG(osgEarth::GDALImageLayer::Options);
OSGEARTH_SPECIALIZE_CONFIG(osgEarth::GDALElevationLayer::Options);