Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: WMS Client Driver
4 : * Purpose: Implementation of Dataset and RasterBand classes for WMS
5 : * and other similar services.
6 : * Author: Adam Nowacki, nowak@xpam.de
7 : *
8 : ******************************************************************************
9 : * Copyright (c) 2007, Adam Nowacki
10 : * Copyright (c) 2007-2012, Even Rouault <even dot rouault at spatialys.com>
11 : *
12 : * SPDX-License-Identifier: MIT
13 : ****************************************************************************/
14 :
15 : #include "wmsdriver.h"
16 : #include "minidriver_wms.h"
17 :
18 : #include <algorithm>
19 :
20 4 : WMSMiniDriver_WMS::WMSMiniDriver_WMS() : m_iversion(0)
21 : {
22 4 : }
23 :
24 8 : WMSMiniDriver_WMS::~WMSMiniDriver_WMS()
25 : {
26 8 : }
27 :
28 8 : static double GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what)
29 : {
30 8 : switch (what)
31 : {
32 2 : case 'x':
33 2 : return std::min(iri.m_x0, iri.m_x1);
34 2 : case 'y':
35 2 : return std::min(iri.m_y0, iri.m_y1);
36 2 : case 'X':
37 2 : return std::max(iri.m_x0, iri.m_x1);
38 2 : case 'Y':
39 2 : return std::max(iri.m_y0, iri.m_y1);
40 : }
41 0 : return 0.0;
42 : }
43 :
44 4 : CPLErr WMSMiniDriver_WMS::Initialize(CPLXMLNode *config,
45 : CPL_UNUSED char **papszOpenOptions)
46 : {
47 4 : CPLErr ret = CE_None;
48 :
49 : {
50 4 : const char *version = CPLGetXMLValue(config, "Version", "1.1.0");
51 4 : if (version[0] != '\0')
52 : {
53 4 : m_version = version;
54 4 : m_iversion = VersionStringToInt(version);
55 4 : if (m_iversion == -1)
56 : {
57 0 : CPLError(CE_Failure, CPLE_AppDefined,
58 : "GDALWMS, WMS mini-driver: Invalid version.");
59 0 : ret = CE_Failure;
60 : }
61 : }
62 : else
63 : {
64 0 : CPLError(CE_Failure, CPLE_AppDefined,
65 : "GDALWMS, WMS mini-driver: Version missing.");
66 0 : ret = CE_Failure;
67 : }
68 : }
69 :
70 4 : if (ret == CE_None)
71 : {
72 4 : const char *base_url = CPLGetXMLValue(config, "ServerURL", "");
73 4 : if (base_url[0] != '\0')
74 : {
75 : /* Try the old name */
76 4 : base_url = CPLGetXMLValue(config, "ServerUrl", "");
77 : }
78 4 : if (base_url[0] != '\0')
79 : {
80 4 : m_base_url = base_url;
81 : }
82 : else
83 : {
84 0 : CPLError(CE_Failure, CPLE_AppDefined,
85 : "GDALWMS, WMS mini-driver: ServerURL missing.");
86 0 : ret = CE_Failure;
87 : }
88 : }
89 :
90 4 : if (ret == CE_None)
91 : {
92 : /* SRS is WMS version 1.1 and earlier, if SRS is not set use default
93 : unless CRS is set CRS is WMS version 1.3, if CRS is not set use
94 : default unless SRS is set */
95 4 : const char *crs = CPLGetXMLValue(config, "CRS", "");
96 4 : const char *srs = CPLGetXMLValue(config, "SRS", "");
97 4 : if (m_iversion >= VersionStringToInt("1.3"))
98 : {
99 : /* Version 1.3 and above */
100 0 : if ((srs[0] != '\0') && (crs[0] == '\0'))
101 : {
102 0 : CPLError(CE_Failure, CPLE_AppDefined,
103 : "GDALWMS, WMS mini-driver: WMS version 1.3 and above "
104 : "expects CRS however SRS was set instead.");
105 0 : ret = CE_Failure;
106 : }
107 0 : else if (crs[0] != '\0')
108 : {
109 0 : m_crs = crs;
110 : }
111 : else
112 : {
113 0 : m_crs = "EPSG:4326";
114 : }
115 : }
116 : else
117 : {
118 : /* Version 1.1.1 and below */
119 4 : if ((srs[0] == '\0') && (crs[0] != '\0'))
120 : {
121 0 : CPLError(CE_Failure, CPLE_AppDefined,
122 : "GDALWMS, WMS mini-driver: WMS version 1.1.1 and "
123 : "below expects SRS however CRS was set instead.");
124 0 : ret = CE_Failure;
125 : }
126 4 : else if (srs[0] != '\0')
127 : {
128 4 : m_srs = srs;
129 : }
130 : else
131 : {
132 0 : m_srs = "EPSG:4326";
133 : }
134 : }
135 : }
136 :
137 4 : if (ret == CE_None)
138 : {
139 4 : if (!m_srs.empty())
140 : {
141 4 : m_oSRS = ProjToSRS(m_srs);
142 : }
143 0 : else if (!m_crs.empty())
144 : {
145 0 : m_oSRS = ProjToSRS(m_crs);
146 : }
147 : }
148 :
149 4 : if (ret == CE_None)
150 : {
151 4 : m_image_format = CPLGetXMLValue(config, "ImageFormat", "image/jpeg");
152 : m_info_format =
153 4 : CPLGetConfigOption("WMS_INFO_FORMAT", "application/vnd.ogc.gml");
154 4 : m_layers = CPLGetXMLValue(config, "Layers", "");
155 4 : m_styles = CPLGetXMLValue(config, "Styles", "");
156 4 : m_transparent = CPLGetXMLValue(config, "Transparent", "");
157 : // the transparent flag needs to be "TRUE" or "FALSE" in upper case
158 : // according to the WMS spec so force upper case
159 9 : for (int i = 0; i < (int)m_transparent.size(); i++)
160 : {
161 5 : m_transparent[i] =
162 5 : (char)toupper(static_cast<unsigned char>(m_transparent[i]));
163 : }
164 : }
165 :
166 4 : if (ret == CE_None)
167 : {
168 4 : const char *bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
169 4 : if (bbox_order[0] != '\0')
170 : {
171 : int i;
172 20 : for (i = 0; i < 4; ++i)
173 : {
174 16 : if ((bbox_order[i] != 'x') && (bbox_order[i] != 'y') &&
175 8 : (bbox_order[i] != 'X') && (bbox_order[i] != 'Y'))
176 0 : break;
177 : }
178 4 : if (i == 4)
179 : {
180 4 : m_bbox_order = bbox_order;
181 : }
182 : else
183 : {
184 0 : CPLError(CE_Failure, CPLE_AppDefined,
185 : "GDALWMS, WMS mini-driver: Incorrect BBoxOrder.");
186 0 : ret = CE_Failure;
187 : }
188 : }
189 : else
190 : {
191 0 : CPLError(CE_Failure, CPLE_AppDefined,
192 : "GDALWMS, WMS mini-driver: BBoxOrder missing.");
193 0 : ret = CE_Failure;
194 : }
195 : }
196 :
197 4 : return ret;
198 : }
199 :
200 4 : void WMSMiniDriver_WMS::GetCapabilities(WMSMiniDriverCapabilities *caps)
201 : {
202 4 : caps->m_has_getinfo = 1;
203 4 : }
204 :
205 2 : void WMSMiniDriver_WMS::BuildURL(CPLString &url,
206 : const GDALWMSImageRequestInfo &iri,
207 : const char *pszRequest)
208 : {
209 : // http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&width=1000&height=500&layers=modis,global_mosaic&styles=&srs=EPSG:4326&format=image/jpeg&bbox=-180.000000,-90.000000,180.000000,090.000000
210 2 : url = m_base_url;
211 :
212 2 : URLPrepare(url);
213 2 : url += "request=";
214 2 : url += pszRequest;
215 :
216 2 : if (url.ifind("service=") == std::string::npos)
217 1 : url += "&service=WMS";
218 :
219 4 : url += CPLOPrintf(
220 : "&version=%s&layers=%s&styles=%s&format=%s&width=%d&height=%d&bbox=%."
221 : "8f,%.8f,%.8f,%.8f",
222 : m_version.c_str(), m_layers.c_str(), m_styles.c_str(),
223 2 : m_image_format.c_str(), iri.m_sx, iri.m_sy,
224 2 : GetBBoxCoord(iri, m_bbox_order[0]), GetBBoxCoord(iri, m_bbox_order[1]),
225 4 : GetBBoxCoord(iri, m_bbox_order[2]), GetBBoxCoord(iri, m_bbox_order[3]));
226 :
227 2 : if (!m_srs.empty())
228 2 : url += CPLOPrintf("&srs=%s", m_srs.c_str());
229 2 : if (!m_crs.empty())
230 0 : url += CPLOPrintf("&crs=%s", m_crs.c_str());
231 2 : if (!m_transparent.empty())
232 1 : url += CPLOPrintf("&transparent=%s", m_transparent.c_str());
233 2 : }
234 :
235 2 : CPLErr WMSMiniDriver_WMS::TiledImageRequest(
236 : WMSHTTPRequest &request, const GDALWMSImageRequestInfo &iri,
237 : CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri)
238 : {
239 2 : CPLString &url = request.URL;
240 2 : BuildURL(url, iri, "GetMap");
241 2 : return CE_None;
242 : }
243 :
244 0 : void WMSMiniDriver_WMS::GetTiledImageInfo(
245 : CPLString &url, const GDALWMSImageRequestInfo &iri,
246 : CPL_UNUSED const GDALWMSTiledImageRequestInfo &tiri, int nXInBlock,
247 : int nYInBlock)
248 : {
249 0 : BuildURL(url, iri, "GetFeatureInfo");
250 0 : url += CPLOPrintf("&query_layers=%s&x=%d&y=%d&info_format=%s",
251 : m_layers.c_str(), nXInBlock, nYInBlock,
252 0 : m_info_format.c_str());
253 0 : }
|