1 : /******************************************************************************
2 : * $Id: wmsdriver.h 24235 2012-04-14 14:41:42Z rouault $
3 : *
4 : * Project: WMS Client Driver
5 : * Purpose: Implementation of Dataset and RasterBand classes for WMS
6 : * and other similar services.
7 : * Author: Adam Nowacki, nowak@xpam.de
8 : *
9 : ******************************************************************************
10 : * Copyright (c) 2007, Adam Nowacki
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 : class GDALWMSDataset;
32 : class GDALWMSRasterBand;
33 :
34 : CPLString MD5String(const char *s);
35 : CPLString ProjToWKT(const CPLString &proj);
36 : void URLAppend(CPLString *url, const char *s);
37 : void URLAppendF(CPLString *url, const char *s, ...);
38 : void URLAppend(CPLString *url, const CPLString &s);
39 : CPLString BufferToVSIFile(GByte *buffer, size_t size);
40 : CPLErr MakeDirs(const char *path);
41 :
42 :
43 : int StrToBool(const char *p);
44 : int URLSearchAndReplace (CPLString *base, const char *search, const char *fmt, ...);
45 : /* Convert a.b.c.d to a * 0x1000000 + b * 0x10000 + c * 0x100 + d */
46 : int VersionStringToInt(const char *version);
47 :
48 :
49 : class GDALWMSImageRequestInfo {
50 : public:
51 : double m_x0, m_y0;
52 : double m_x1, m_y1;
53 : int m_sx, m_sy;
54 : };
55 :
56 : class GDALWMSDataWindow {
57 : public:
58 : double m_x0, m_y0;
59 : double m_x1, m_y1;
60 : int m_sx, m_sy;
61 : int m_tx, m_ty, m_tlevel;
62 : enum { BOTTOM = -1, DEFAULT = 0, TOP = 1 } m_y_origin;
63 :
64 31 : GDALWMSDataWindow() : m_x0(-180), m_y0(90), m_x1(180), m_y1(-90),
65 : m_sx(-1), m_sy(-1), m_tx(0), m_ty(0),
66 31 : m_tlevel(-1), m_y_origin(DEFAULT) {}
67 : };
68 :
69 : class GDALWMSTiledImageRequestInfo {
70 : public:
71 : int m_x, m_y;
72 : int m_level;
73 : };
74 :
75 : class GDALWMSRasterIOHint {
76 : public:
77 : int m_x0, m_y0;
78 : int m_sx, m_sy;
79 : int m_overview;
80 : bool m_valid;
81 : };
82 :
83 : class GDALWMSMiniDriverCapabilities {
84 : public:
85 : /* Version N capabilities require all version N and earlier variables to be set to correct values */
86 : int m_capabilities_version;
87 :
88 : /* Version 1 capabilities */
89 : int m_has_image_request; // 1 if ImageRequest method is implemented
90 : int m_has_tiled_image_requeset; // 1 if TiledImageRequest method is implemented
91 : int m_has_arb_overviews; // 1 if ImageRequest method supports arbitrary overviews / resolutions
92 : int m_max_overview_count; // Maximum number of overviews supported if known, -1 otherwise
93 : };
94 :
95 : /* All data returned by mini-driver as pointer should remain valid for mini-driver lifetime
96 : and should be freed by mini-driver destructor unless otherwise specified. */
97 : class GDALWMSMiniDriver {
98 : friend class GDALWMSDataset;
99 : public:
100 : GDALWMSMiniDriver();
101 : virtual ~GDALWMSMiniDriver();
102 :
103 : public:
104 : /* Read mini-driver specific configuration. */
105 : virtual CPLErr Initialize(CPLXMLNode *config);
106 :
107 : public:
108 : virtual void GetCapabilities(GDALWMSMiniDriverCapabilities *caps);
109 : virtual void ImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri);
110 : virtual void TiledImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri, const GDALWMSTiledImageRequestInfo &tiri);
111 : virtual void GetTiledImageInfo(CPLString *url,
112 : const GDALWMSImageRequestInfo &iri,
113 : const GDALWMSTiledImageRequestInfo &tiri,
114 : int nXInBlock,
115 : int nYInBlock);
116 :
117 : /* Return data projection in WKT format, NULL or empty string if unknown */
118 : virtual const char *GetProjectionInWKT();
119 :
120 : protected:
121 : GDALWMSDataset *m_parent_dataset;
122 : };
123 :
124 : class GDALWMSMiniDriverFactory {
125 : public:
126 : GDALWMSMiniDriverFactory();
127 : virtual ~GDALWMSMiniDriverFactory();
128 :
129 : public:
130 : virtual GDALWMSMiniDriver* New() = 0;
131 : virtual void Delete(GDALWMSMiniDriver *instance) = 0;
132 :
133 : public:
134 50 : const CPLString &GetName() {
135 50 : return m_name;
136 : }
137 :
138 : protected:
139 : CPLString m_name;
140 : };
141 :
142 : class GDALWMSMiniDriverManager {
143 : public:
144 : GDALWMSMiniDriverManager();
145 : ~GDALWMSMiniDriverManager();
146 :
147 : public:
148 : void Register(GDALWMSMiniDriverFactory *mdf);
149 : GDALWMSMiniDriverFactory *Find(const CPLString &name);
150 :
151 : protected:
152 : std::list<GDALWMSMiniDriverFactory *> m_mdfs;
153 : };
154 :
155 : #define H_GDALWMSMiniDriverFactory(name) \
156 : class GDALWMSMiniDriverFactory_##name : public GDALWMSMiniDriverFactory { \
157 : public: \
158 : GDALWMSMiniDriverFactory_##name(); \
159 : virtual ~GDALWMSMiniDriverFactory_##name(); \
160 : \
161 : public: \
162 : virtual GDALWMSMiniDriver* New(); \
163 : virtual void Delete(GDALWMSMiniDriver *instance); \
164 : };
165 :
166 : #define CPP_GDALWMSMiniDriverFactory(name) \
167 : GDALWMSMiniDriverFactory_##name::GDALWMSMiniDriverFactory_##name() { \
168 : m_name = #name;\
169 : } \
170 : \
171 : GDALWMSMiniDriverFactory_##name::~GDALWMSMiniDriverFactory_##name() { \
172 : } \
173 : \
174 : GDALWMSMiniDriver* GDALWMSMiniDriverFactory_##name::New() { \
175 : return new GDALWMSMiniDriver_##name(); \
176 : } \
177 : \
178 : void GDALWMSMiniDriverFactory_##name::Delete(GDALWMSMiniDriver *instance) { \
179 : delete instance; \
180 : }
181 :
182 : class GDALWMSCache {
183 : public:
184 : GDALWMSCache();
185 : ~GDALWMSCache();
186 :
187 : public:
188 : CPLErr Initialize(CPLXMLNode *config);
189 : CPLErr Write(const char *key, const CPLString &file_name);
190 : CPLErr Read(const char *key, CPLString *file_name);
191 :
192 : protected:
193 : CPLString KeyToCacheFile(const char *key);
194 :
195 : protected:
196 : CPLString m_cache_path;
197 : CPLString m_postfix;
198 : int m_cache_depth;
199 : };
200 :
201 : class GDALWMSDataset : public GDALPamDataset {
202 : friend class GDALWMSRasterBand;
203 :
204 : public:
205 : GDALWMSDataset();
206 : virtual ~GDALWMSDataset();
207 :
208 : virtual const char *GetProjectionRef();
209 : virtual CPLErr SetProjection(const char *proj);
210 : virtual CPLErr GetGeoTransform(double *gt);
211 : virtual CPLErr SetGeoTransform(double *gt);
212 : virtual CPLErr AdviseRead(int x0, int y0, int sx, int sy, int bsx, int bsy, GDALDataType bdt, int band_count, int *band_map, char **options);
213 : virtual const char *GetMetadataItem( const char * pszName,
214 : const char * pszDomain = "" );
215 :
216 : const GDALWMSDataWindow *WMSGetDataWindow() const;
217 : void WMSSetClamp(bool flag);
218 : void WMSSetBlockSize(int x, int y);
219 : void WMSSetRasterSize(int x, int y);
220 : void WMSSetDataType(GDALDataType type);
221 : void WMSSetDataWindow(GDALWMSDataWindow &window);
222 : void WMSSetBandsCount(int count);
223 1 : void SetColorTable(GDALColorTable *pct) { m_poColorTable=pct; }
224 :
225 : void WMSSetNoDataValue(const char * pszNoData);
226 : void WMSSetMinValue(const char* pszMin);
227 : void WMSSetMaxValue(const char* pszMax);
228 :
229 5 : void mSetBand(int i, GDALRasterBand *band) { SetBand(i,band); };
230 60 : GDALWMSRasterBand *mGetBand(int i) { return reinterpret_cast<GDALWMSRasterBand *>(GetRasterBand(i)); };
231 :
232 :
233 : void WMSSetDefaultDataWindowCoordinates(double x0, double y0, double x1, double y1);
234 : void WMSSetDefaultTileLevel(int tlevel);
235 : void WMSSetDefaultTileCount(int tilecountx, int tilecounty);
236 : void WMSSetDefaultBlockSize(int x, int y);
237 : void WMSSetDefaultOverviewCount(int overview_count);
238 : void WMSSetNeedsDataWindow(int flag);
239 :
240 : static GDALDataset* Open(GDALOpenInfo *poOpenInfo);
241 : static int Identify(GDALOpenInfo *poOpenInfo);
242 : static GDALDataset *CreateCopy( const char * pszFilename,
243 : GDALDataset *poSrcDS,
244 : int bStrict, char ** papszOptions,
245 : GDALProgressFunc pfnProgress,
246 : void * pProgressData );
247 :
248 : protected:
249 : virtual CPLErr IRasterIO(GDALRWFlag rw, int x0, int y0, int sx, int sy, void *buffer, int bsx, int bsy, GDALDataType bdt, int band_count, int *band_map, int pixel_space, int line_space, int band_space);
250 : CPLErr Initialize(CPLXMLNode *config);
251 :
252 : GDALWMSDataWindow m_data_window;
253 : GDALWMSMiniDriver *m_mini_driver;
254 : GDALWMSMiniDriverCapabilities m_mini_driver_caps;
255 : GDALWMSCache *m_cache;
256 : CPLString m_projection;
257 : GDALColorTable *m_poColorTable;
258 : std::vector<double> vNoData, vMin, vMax;
259 : GDALDataType m_data_type;
260 : int m_block_size_x, m_block_size_y;
261 : GDALWMSRasterIOHint m_hint;
262 : int m_use_advise_read;
263 : int m_verify_advise_read;
264 : int m_offline_mode;
265 : int m_http_max_conn;
266 : int m_http_timeout;
267 : int m_clamp_requests;
268 : int m_unsafeSsl;
269 : std::vector<int> m_http_zeroblock_codes;
270 : int m_zeroblock_on_serverexceptions;
271 : CPLString m_osUserAgent;
272 : CPLString m_osReferer;
273 :
274 : GDALWMSDataWindow m_default_data_window;
275 : int m_default_block_size_x, m_default_block_size_y;
276 : int m_default_tile_count_x, m_default_tile_count_y;
277 : int m_default_overview_count;
278 :
279 : int m_bNeedsDataWindow;
280 :
281 : CPLString m_osXML;
282 : };
283 :
284 : class GDALWMSRasterBand : public GDALPamRasterBand {
285 : friend class GDALWMSDataset;
286 :
287 : char** BuildHTTPRequestOpts();
288 : void ComputeRequestInfo( GDALWMSImageRequestInfo &iri,
289 : GDALWMSTiledImageRequestInfo &tiri,
290 : int x, int y);
291 :
292 : CPLString osMetadataItem;
293 : CPLString osMetadataItemURL;
294 :
295 : public:
296 : GDALWMSRasterBand(GDALWMSDataset *parent_dataset, int band, double scale);
297 : virtual ~GDALWMSRasterBand();
298 : void AddOverview(double scale);
299 : virtual double GetNoDataValue( int * );
300 : virtual double GetMinimum( int * );
301 : virtual double GetMaximum( int * );
302 : virtual GDALColorTable *GetColorTable();
303 : virtual CPLErr AdviseRead(int x0, int y0, int sx, int sy, int bsx, int bsy, GDALDataType bdt, char **options);
304 :
305 : virtual GDALColorInterp GetColorInterpretation();
306 : virtual CPLErr SetColorInterpretation( GDALColorInterp );
307 : virtual CPLErr IReadBlock(int x, int y, void *buffer);
308 : virtual CPLErr IRasterIO(GDALRWFlag rw, int x0, int y0, int sx, int sy, void *buffer, int bsx, int bsy, GDALDataType bdt, int pixel_space, int line_space);
309 : virtual int HasArbitraryOverviews();
310 : virtual int GetOverviewCount();
311 : virtual GDALRasterBand *GetOverview(int n);
312 :
313 : virtual const char *GetMetadataItem( const char * pszName,
314 : const char * pszDomain = "" );
315 :
316 : protected:
317 : CPLErr ReadBlocks(int x, int y, void *buffer, int bx0, int by0, int bx1, int by1, int advise_read);
318 : bool IsBlockInCache(int x, int y);
319 : void AskMiniDriverForBlock(CPLString *url, int x, int y);
320 : CPLErr ReadBlockFromFile(int x, int y, const char *file_name, int to_buffer_band, void *buffer, int advise_read);
321 : CPLErr ZeroBlock(int x, int y, int to_buffer_band, void *buffer);
322 : CPLErr ReportWMSException(const char *file_name);
323 :
324 : protected:
325 : GDALWMSDataset *m_parent_dataset;
326 : double m_scale;
327 : std::vector<GDALWMSRasterBand *> m_overviews;
328 : int m_overview;
329 : GDALColorInterp m_color_interp;
330 : };
331 :
332 : GDALWMSMiniDriverManager *GetGDALWMSMiniDriverManager();
333 : void DestroyWMSMiniDriverManager(void);
|