234 строки
9.4 KiB
C++
234 строки
9.4 KiB
C++
/******************************************************************************
|
|
*
|
|
* Project: WCS Client Driver
|
|
* Purpose: Implementation of Dataset class for WCS.
|
|
* Author: Frank Warmerdam, warmerdam@pobox.com
|
|
*
|
|
******************************************************************************
|
|
* Copyright (c) 2006, Frank Warmerdam
|
|
* Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
|
|
* Copyright (c) 2017, Ari Jolma
|
|
* Copyright (c) 2017, Finnish Environment Institute
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
* to deal in the Software without restriction, including without limitation
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included
|
|
* in all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
* DEALINGS IN THE SOFTWARE.
|
|
****************************************************************************/
|
|
|
|
/************************************************************************/
|
|
/* ==================================================================== */
|
|
/* WCSDataset */
|
|
/* ==================================================================== */
|
|
/************************************************************************/
|
|
|
|
#include "cpl_string.h"
|
|
#include "gdal_pam.h"
|
|
|
|
class WCSRasterBand;
|
|
|
|
class WCSDataset CPL_NON_FINAL : public GDALPamDataset
|
|
{
|
|
friend class WCSRasterBand;
|
|
friend class WCSDataset100;
|
|
friend class WCSDataset110;
|
|
friend class WCSDataset201;
|
|
|
|
CPLString m_cache_dir;
|
|
bool bServiceDirty;
|
|
CPLXMLNode *psService;
|
|
|
|
char *apszCoverageOfferingMD[2];
|
|
|
|
char **papszSDSModifiers;
|
|
|
|
int m_Version; // eg 100 for 1.0.0, 110 for 1.1.0
|
|
const char *Version() const;
|
|
|
|
CPLString osCRS; // name of the CRS
|
|
OGRSpatialReference m_oSRS{};
|
|
bool native_crs; // the CRS is the native CRS of the server
|
|
bool axis_order_swap; // the CRS requires x and y coordinates to be swapped
|
|
// for requests
|
|
double adfGeoTransform[6];
|
|
bool SetCRS(const CPLString &crs, bool native);
|
|
void SetGeometry(const std::vector<int> &size,
|
|
const std::vector<double> &origin,
|
|
const std::vector<std::vector<double>> &offsets);
|
|
|
|
CPLString osBandIdentifier;
|
|
|
|
CPLString osDefaultTime;
|
|
std::vector<CPLString> aosTimePositions;
|
|
|
|
int TestUseBlockIO(int, int, int, int, int, int) const;
|
|
CPLErr DirectRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
|
|
GDALDataType, int, int *, GSpacing nPixelSpace,
|
|
GSpacing nLineSpace, GSpacing nBandSpace,
|
|
GDALRasterIOExtraArg *psExtraArg);
|
|
|
|
virtual CPLErr IRasterIO(GDALRWFlag, int, int, int, int, void *, int, int,
|
|
GDALDataType, int, int *, GSpacing nPixelSpace,
|
|
GSpacing nLineSpace, GSpacing nBandSpace,
|
|
GDALRasterIOExtraArg *psExtraArg) override;
|
|
|
|
virtual std::vector<double> GetExtent(int nXOff, int nYOff, int nXSize,
|
|
int nYSize, int nBufXSize,
|
|
int nBufYSize) = 0;
|
|
|
|
virtual CPLString GetCoverageRequest(bool scaled, int nBufXSize,
|
|
int nBufYSize,
|
|
const std::vector<double> &extent,
|
|
CPLString osBandList) = 0;
|
|
|
|
CPLErr GetCoverage(int nXOff, int nYOff, int nXSize, int nYSize,
|
|
int nBufXSize, int nBufYSize, int nBandCount,
|
|
int *panBandList, GDALRasterIOExtraArg *psExtraArg,
|
|
CPLHTTPResult **ppsResult);
|
|
|
|
virtual CPLString DescribeCoverageRequest()
|
|
{
|
|
return "";
|
|
}
|
|
virtual CPLXMLNode *CoverageOffering(CPLXMLNode *psDC) = 0;
|
|
|
|
int DescribeCoverage();
|
|
|
|
virtual bool ExtractGridInfo() = 0;
|
|
|
|
int EstablishRasterDetails();
|
|
|
|
virtual CPLErr ParseCapabilities(CPLXMLNode *, CPLString) = 0;
|
|
virtual void ParseCoverageCapabilities(CPLXMLNode *, const CPLString &,
|
|
CPLXMLNode *) = 0;
|
|
|
|
GDALDataset *GDALOpenResult(CPLHTTPResult *psResult);
|
|
|
|
void FlushMemoryResult();
|
|
|
|
CPLString osResultFilename;
|
|
|
|
GByte *pabySavedDataBuffer;
|
|
|
|
char **papszHttpOptions;
|
|
|
|
int nMaxCols;
|
|
int nMaxRows;
|
|
|
|
public:
|
|
WCSDataset(int version, const char *cache_dir);
|
|
virtual ~WCSDataset();
|
|
|
|
static WCSDataset *CreateFromMetadata(const CPLString &, CPLString);
|
|
static WCSDataset *CreateFromCapabilities(CPLString, CPLString, CPLString);
|
|
|
|
static GDALDataset *Open(GDALOpenInfo *);
|
|
static int Identify(GDALOpenInfo *);
|
|
|
|
virtual CPLErr GetGeoTransform(double *) override;
|
|
const OGRSpatialReference *GetSpatialRef() const override;
|
|
virtual char **GetFileList(void) override;
|
|
|
|
virtual char **GetMetadataDomainList() override;
|
|
virtual char **GetMetadata(const char *pszDomain) override;
|
|
};
|
|
|
|
class WCSDataset100 final : public WCSDataset
|
|
{
|
|
std::vector<double> GetExtent(int nXOff, int nYOff, int nXSize, int nYSize,
|
|
int nBufXSize, int nBufYSize) override;
|
|
CPLString GetCoverageRequest(bool scaled, int nBufXSize, int nBufYSize,
|
|
const std::vector<double> &extent,
|
|
CPLString osBandList) override;
|
|
CPLString DescribeCoverageRequest() override;
|
|
CPLXMLNode *CoverageOffering(CPLXMLNode *psDC) override;
|
|
bool ExtractGridInfo() override;
|
|
CPLErr ParseCapabilities(CPLXMLNode *, CPLString) override;
|
|
void ParseCoverageCapabilities(CPLXMLNode *, const CPLString &,
|
|
CPLXMLNode *) override;
|
|
|
|
public:
|
|
explicit WCSDataset100(const char *cache_dir) : WCSDataset(100, cache_dir)
|
|
{
|
|
}
|
|
};
|
|
|
|
class WCSDataset110 CPL_NON_FINAL : public WCSDataset
|
|
{
|
|
std::vector<double> GetExtent(int nXOff, int nYOff, int nXSize, int nYSize,
|
|
int nBufXSize, int nBufYSize) override;
|
|
CPLString GetCoverageRequest(bool scaled, int nBufXSize, int nBufYSize,
|
|
const std::vector<double> &extent,
|
|
CPLString osBandList) override;
|
|
CPLString DescribeCoverageRequest() override;
|
|
CPLXMLNode *CoverageOffering(CPLXMLNode *psDC) override;
|
|
bool ExtractGridInfo() override;
|
|
CPLErr ParseCapabilities(CPLXMLNode *, CPLString) override;
|
|
void ParseCoverageCapabilities(CPLXMLNode *, const CPLString &,
|
|
CPLXMLNode *) override;
|
|
|
|
public:
|
|
WCSDataset110(int version, const char *cache_dir)
|
|
: WCSDataset(version, cache_dir)
|
|
{
|
|
}
|
|
};
|
|
|
|
class WCSDataset201 final : public WCSDataset110
|
|
{
|
|
std::vector<double> GetExtent(int nXOff, int nYOff, int nXSize, int nYSize,
|
|
int nBufXSize, int nBufYSize) override;
|
|
CPLString GetSubdataset(const CPLString &coverage);
|
|
bool SetFormat(CPLXMLNode *coverage);
|
|
static bool ParseGridFunction(CPLXMLNode *coverage,
|
|
std::vector<int> &axisOrder);
|
|
int ParseRange(CPLXMLNode *coverage, const CPLString &range_subset,
|
|
char ***metadata);
|
|
CPLString GetCoverageRequest(bool scaled, int nBufXSize, int nBufYSize,
|
|
const std::vector<double> &extent,
|
|
CPLString osBandList) override;
|
|
CPLString DescribeCoverageRequest() override;
|
|
bool GridOffsets(CPLXMLNode *grid, CPLString subtype, bool swap_grid_axis,
|
|
std::vector<double> &origin,
|
|
std::vector<std::vector<double>> &offset,
|
|
std::vector<CPLString> labels, char ***metadata);
|
|
bool Offset2GeoTransform(std::vector<double> origin,
|
|
std::vector<std::vector<double>> offset);
|
|
bool ExtractGridInfo() override;
|
|
|
|
public:
|
|
explicit WCSDataset201(const char *cache_dir)
|
|
: WCSDataset110(201, cache_dir)
|
|
{
|
|
}
|
|
};
|
|
|
|
#define DIGIT_ZERO '0'
|
|
|
|
// The WCS URL parameters that can be set
|
|
// - through options to the service file
|
|
// - to the URL
|
|
// These are also inherited from template service file.
|
|
// Fundamental URL parameters (service, version, request, coverage)
|
|
// and parameters that require more work from the driver's part, such
|
|
// as subsetting parameters (subset, rangesubset) are not in this
|
|
// list.
|
|
|
|
#define WCS_URL_PARAMETERS \
|
|
"Format", "Interpolation", "MediaType", "UpdateSequence", \
|
|
"GEOTIFF:COMPRESSION", "GEOTIFF:JPEG_QUALITY", "GEOTIFF:PREDICTOR", \
|
|
"GEOTIFF:INTERLEAVE", "GEOTIFF:TILING", "GEOTIFF:TILEWIDTH"
|