Line data Source code
1 : /******************************************************************************
2 : * $Id$
3 : *
4 : * Project: GRIB Driver
5 : * Purpose: GDALDataset driver for GRIB translator for read support
6 : * Author: Bas Retsios, retsios@itc.nl
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, ITC
10 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
11 : *
12 : * Permission is hereby granted, free of charge, to any person obtaining a
13 : * copy of this software and associated documentation files (the "Software"),
14 : * to deal in the Software without restriction, including without limitation
15 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 : * and/or sell copies of the Software, and to permit persons to whom the
17 : * Software is furnished to do so, subject to the following conditions:
18 : *
19 : * The above copyright notice and this permission notice shall be included
20 : * in all copies or substantial portions of the Software.
21 : *
22 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 : * DEALINGS IN THE SOFTWARE.
29 : ******************************************************************************
30 : *
31 : */
32 :
33 : #ifndef GRIBDATASET_H
34 : #define GRIBDATASET_H
35 :
36 : #include "cpl_port.h"
37 :
38 : #include <cerrno>
39 : #include <cmath>
40 : #include <cstddef>
41 : #include <cstdio>
42 : #include <cstdlib>
43 : #include <cstring>
44 : #if HAVE_FCNTL_H
45 : #include <fcntl.h>
46 : #endif
47 :
48 : #include <algorithm>
49 : #include <memory>
50 : #include <string>
51 :
52 : #include "cpl_conv.h"
53 : #include "cpl_error.h"
54 : #include "cpl_multiproc.h"
55 : #include "cpl_string.h"
56 : #include "cpl_vsi.h"
57 : #include "degrib/degrib/degrib2.h"
58 : #include "degrib/degrib/inventory.h"
59 : #include "degrib/degrib/meta.h"
60 : #include "degrib/degrib/myerror.h"
61 : #include "degrib/degrib/type.h"
62 : #include "gdal.h"
63 : #include "gdal_frmts.h"
64 : #include "gdal_pam.h"
65 : #include "gdal_priv.h"
66 : #include "ogr_spatialref.h"
67 :
68 : /************************************************************************/
69 : /* ==================================================================== */
70 : /* GRIBDataset */
71 : /* ==================================================================== */
72 : /************************************************************************/
73 :
74 : class GRIBArray;
75 : class GRIBRasterBand;
76 :
77 : namespace gdal
78 : {
79 : namespace grib
80 : {
81 : class InventoryWrapper;
82 : }
83 : } // namespace gdal
84 :
85 : class GRIBDataset final : public GDALPamDataset
86 : {
87 : friend class GRIBArray;
88 : friend class GRIBRasterBand;
89 :
90 : public:
91 : GRIBDataset();
92 : ~GRIBDataset();
93 :
94 : static GDALDataset *Open(GDALOpenInfo *);
95 : static int Identify(GDALOpenInfo *);
96 : static GDALDataset *CreateCopy(const char *pszFilename,
97 : GDALDataset *poSrcDS, int bStrict,
98 : char **papszOptions,
99 : GDALProgressFunc pfnProgress,
100 : void *pProgressData);
101 :
102 : CPLErr GetGeoTransform(double *padfTransform) override;
103 :
104 74 : const OGRSpatialReference *GetSpatialRef() const override
105 : {
106 74 : return m_poSRS.get();
107 : }
108 :
109 23 : std::shared_ptr<GDALGroup> GetRootGroup() const override
110 : {
111 23 : return m_poRootGroup;
112 : }
113 :
114 : private:
115 : void SetGribMetaData(grib_MetaData *meta);
116 : static GDALDataset *OpenMultiDim(GDALOpenInfo *);
117 : static std::unique_ptr<gdal::grib::InventoryWrapper>
118 : Inventory(VSILFILE *, GDALOpenInfo *);
119 :
120 : VSILFILE *fp;
121 : // Calculate and store once as GetGeoTransform may be called multiple times.
122 : double adfGeoTransform[6];
123 :
124 : GIntBig nCachedBytes;
125 : GIntBig nCachedBytesThreshold;
126 : int bCacheOnlyOneBand;
127 :
128 : // Split&Swap: transparent rewrap around the prime meridian instead of the
129 : // antimeridian rows after nSplitAndSwapColumn are placed at the beginning
130 : // while rows before are placed at the end
131 : int nSplitAndSwapColumn;
132 :
133 : GRIBRasterBand *poLastUsedBand;
134 : std::shared_ptr<GDALGroup> m_poRootGroup{};
135 : std::shared_ptr<OGRSpatialReference> m_poSRS{};
136 : std::unique_ptr<OGRSpatialReference> m_poLL{};
137 : std::unique_ptr<OGRCoordinateTransformation> m_poCT{};
138 : };
139 :
140 : /************************************************************************/
141 : /* ==================================================================== */
142 : /* GRIBRasterBand */
143 : /* ==================================================================== */
144 : /************************************************************************/
145 :
146 : class GRIBRasterBand final : public GDALPamRasterBand
147 : {
148 : friend class GRIBArray;
149 : friend class GRIBDataset;
150 :
151 : public:
152 : GRIBRasterBand(GRIBDataset *, int, inventoryType *);
153 : virtual ~GRIBRasterBand();
154 : virtual CPLErr IReadBlock(int, int, void *) override;
155 : virtual const char *GetDescription() const override;
156 :
157 : virtual double GetNoDataValue(int *pbSuccess = nullptr) override;
158 : virtual char **GetMetadata(const char *pszDomain = "") override;
159 : virtual const char *GetMetadataItem(const char *pszName,
160 : const char *pszDomain = "") override;
161 :
162 : void FindPDSTemplateGRIB2();
163 :
164 : void UncacheData();
165 :
166 : static void ReadGribData(VSILFILE *, vsi_l_offset, int, double **,
167 : grib_MetaData **);
168 :
169 : private:
170 : CPLErr LoadData();
171 : void FindNoDataGrib2(bool bSeekToStart = true);
172 : void FindMetaData();
173 : // Heuristic search for the start of the message
174 : static vsi_l_offset FindTrueStart(VSILFILE *, vsi_l_offset);
175 :
176 : vsi_l_offset start;
177 : int subgNum;
178 : char *longFstLevel;
179 :
180 : double *m_Grib_Data;
181 : grib_MetaData *m_Grib_MetaData;
182 :
183 : int nGribDataXSize;
184 : int nGribDataYSize;
185 : int m_nGribVersion;
186 :
187 : bool m_bHasLookedForNoData;
188 : double m_dfNoData;
189 : bool m_bHasNoData;
190 :
191 : int m_nDisciplineCode = -1;
192 : std::string m_osDisciplineName{};
193 : int m_nCenter = -1;
194 : std::string m_osCenterName{};
195 : int m_nSubCenter = -1;
196 : std::string m_osSubCenterName{};
197 : std::string m_osSignRefTimeName{};
198 : std::string m_osRefTime{};
199 : std::string m_osProductionStatus{};
200 : std::string m_osType{};
201 : int m_nPDTN = -1;
202 : std::vector<GUInt32> m_anPDSTemplateAssembledValues{};
203 : bool bLoadedPDS = false;
204 : bool bLoadedMetadata = false;
205 : };
206 :
207 : namespace gdal
208 : {
209 : namespace grib
210 : {
211 :
212 : // Thin layer to manage allocation and deallocation.
213 : class InventoryWrapper
214 : {
215 : public:
216 307 : InventoryWrapper()
217 307 : {
218 307 : }
219 :
220 307 : virtual ~InventoryWrapper()
221 307 : {
222 307 : }
223 :
224 : // Modifying the contents pointed to by the return is allowed.
225 455 : inventoryType *get(int i) const
226 : {
227 455 : if (i < 0 || i >= static_cast<int>(inv_len_))
228 0 : return nullptr;
229 455 : return inv_ + i;
230 : }
231 :
232 737 : uInt4 length() const
233 : {
234 737 : return inv_len_;
235 : }
236 :
237 : size_t num_messages() const
238 : {
239 : return num_messages_;
240 : }
241 :
242 310 : int result() const
243 : {
244 310 : return result_;
245 : }
246 :
247 : protected:
248 : inventoryType *inv_ = nullptr;
249 : uInt4 inv_len_ = 0;
250 : int num_messages_ = 0;
251 : int result_ = 0;
252 : };
253 :
254 : } // namespace grib
255 : } // namespace gdal
256 :
257 : const char *const apszJ2KDrivers[] = {"JP2KAK", "JP2OPENJPEG", "JPEG2000",
258 : "JP2ECW"};
259 :
260 : #endif // GRIBDATASET_H
|