1 : /******************************************************************************
2 : * $Id: minidriver_wms.cpp 23722 2012-01-07 22:15:29Z 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 : #include "stdinc.h"
32 :
33 1106 : CPP_GDALWMSMiniDriverFactory(WMS)
34 :
35 3 : GDALWMSMiniDriver_WMS::GDALWMSMiniDriver_WMS() {
36 3 : }
37 :
38 3 : GDALWMSMiniDriver_WMS::~GDALWMSMiniDriver_WMS() {
39 3 : }
40 :
41 3 : CPLErr GDALWMSMiniDriver_WMS::Initialize(CPLXMLNode *config) {
42 3 : CPLErr ret = CE_None;
43 :
44 3 : if (ret == CE_None) {
45 3 : const char *version = CPLGetXMLValue(config, "Version", "1.1.0");
46 3 : if (version[0] != '\0') {
47 3 : m_version = version;
48 3 : m_iversion = VersionStringToInt(version);
49 3 : if (m_iversion == -1) {
50 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: Invalid version.");
51 0 : ret = CE_Failure;
52 : }
53 : } else {
54 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: Version missing.");
55 0 : ret = CE_Failure;
56 : }
57 : }
58 :
59 3 : if (ret == CE_None) {
60 3 : const char *base_url = CPLGetXMLValue(config, "ServerURL", "");
61 3 : if (base_url[0] != '\0') {
62 : /* Try the old name */
63 3 : base_url = CPLGetXMLValue(config, "ServerUrl", "");
64 : }
65 3 : if (base_url[0] != '\0') {
66 3 : m_base_url = base_url;
67 : } else {
68 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: ServerURL missing.");
69 0 : ret = CE_Failure;
70 : }
71 : }
72 :
73 3 : if (ret == CE_None) {
74 : /* SRS is WMS version 1.1 and earlier, if SRS is not set use default unless CRS is set
75 : CRS is WMS version 1.3, if CRS is not set use default unless SRS is set */
76 3 : const char *crs = CPLGetXMLValue(config, "CRS", "");
77 3 : const char *srs = CPLGetXMLValue(config, "SRS", "");
78 3 : if (m_iversion >= VersionStringToInt("1.3")) {
79 : /* Version 1.3 and above */
80 0 : if ((srs[0] != '\0') && (crs[0] == '\0')) {
81 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: WMS version 1.3 and above expects CRS however SRS was set instead.");
82 0 : ret = CE_Failure;
83 0 : } else if (crs[0] != '\0') {
84 0 : m_crs = crs;
85 : } else {
86 0 : m_crs = "EPSG:4326";
87 : }
88 : } else {
89 : /* Version 1.1.1 and below */
90 3 : if ((srs[0] == '\0') && (crs[0] != '\0')) {
91 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: WMS version 1.1.1 and below expects SRS however CRS was set instead.");
92 0 : ret = CE_Failure;
93 3 : } else if (srs[0] != '\0') {
94 3 : m_srs = srs;
95 : } else {
96 0 : m_srs = "EPSG:4326";
97 : }
98 : }
99 : }
100 :
101 3 : if (ret == CE_None) {
102 3 : if (m_srs.size()) {
103 3 : m_projection_wkt = ProjToWKT(m_srs);
104 0 : } else if (m_crs.size()) {
105 0 : m_projection_wkt = ProjToWKT(m_crs);
106 : }
107 : }
108 :
109 3 : if (ret == CE_None) {
110 3 : m_image_format = CPLGetXMLValue(config, "ImageFormat", "image/jpeg");
111 6 : m_layers = CPLGetXMLValue(config, "Layers", "");
112 6 : m_styles = CPLGetXMLValue(config, "Styles", "");
113 6 : m_transparent = CPLGetXMLValue(config, "Transparent","");
114 : // the transparent flag needs to be "TRUE" or "FALSE" in upper case according to the WMS spec so force upper case
115 13 : for(int i=0; i<(int)m_transparent.size();i++)
116 : {
117 10 : m_transparent[i] = (char) toupper(m_transparent[i]);
118 : }
119 : }
120 :
121 3 : if (ret == CE_None) {
122 3 : const char *bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
123 3 : if (bbox_order[0] != '\0') {
124 : int i;
125 15 : for (i = 0; i < 4; ++i) {
126 12 : if ((bbox_order[i] != 'x') && (bbox_order[i] != 'y') && (bbox_order[i] != 'X') && (bbox_order[i] != 'Y')) break;
127 : }
128 3 : if (i == 4) {
129 3 : m_bbox_order = bbox_order;
130 : } else {
131 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: Incorrect BBoxOrder.");
132 0 : ret = CE_Failure;
133 : }
134 : } else {
135 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: BBoxOrder missing.");
136 0 : ret = CE_Failure;
137 : }
138 : }
139 :
140 3 : return ret;
141 : }
142 :
143 3 : void GDALWMSMiniDriver_WMS::GetCapabilities(GDALWMSMiniDriverCapabilities *caps) {
144 3 : caps->m_capabilities_version = 1;
145 3 : caps->m_has_arb_overviews = 1;
146 3 : caps->m_has_image_request = 1;
147 3 : caps->m_has_tiled_image_requeset = 1;
148 3 : caps->m_max_overview_count = 32;
149 3 : }
150 :
151 5 : void GDALWMSMiniDriver_WMS::BuildURL(CPLString *url, const GDALWMSImageRequestInfo &iri, const char* pszRequest) {
152 : // 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
153 5 : CPLLocaleC oLocaleEnforcer;
154 5 : *url = m_base_url;
155 5 : if (m_base_url.ifind( "service=") == std::string::npos)
156 0 : URLAppend(url, "&service=WMS");
157 5 : URLAppendF(url, "&request=%s", pszRequest);
158 5 : URLAppendF(url, "&version=%s", m_version.c_str());
159 5 : URLAppendF(url, "&layers=%s", m_layers.c_str());
160 5 : URLAppendF(url, "&styles=%s", m_styles.c_str());
161 5 : if (m_srs.size()) URLAppendF(url, "&srs=%s", m_srs.c_str());
162 5 : if (m_crs.size()) URLAppendF(url, "&crs=%s", m_crs.c_str());
163 5 : if (m_transparent.size()) URLAppendF(url, "&transparent=%s", m_transparent.c_str());
164 5 : URLAppendF(url, "&format=%s", m_image_format.c_str());
165 5 : URLAppendF(url, "&width=%d", iri.m_sx);
166 5 : URLAppendF(url, "&height=%d", iri.m_sy);
167 : URLAppendF(url, "&bbox=%.8f,%.8f,%.8f,%.8f",
168 : GetBBoxCoord(iri, m_bbox_order[0]), GetBBoxCoord(iri, m_bbox_order[1]),
169 5 : GetBBoxCoord(iri, m_bbox_order[2]), GetBBoxCoord(iri, m_bbox_order[3]));
170 5 : }
171 :
172 1 : void GDALWMSMiniDriver_WMS::ImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri) {
173 1 : BuildURL(url, iri, "GetMap");
174 1 : CPLDebug("WMS", "URL = %s", url->c_str());
175 1 : }
176 :
177 1 : void GDALWMSMiniDriver_WMS::TiledImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri, const GDALWMSTiledImageRequestInfo &tiri) {
178 1 : ImageRequest(url, iri);
179 1 : }
180 :
181 :
182 4 : void GDALWMSMiniDriver_WMS::GetTiledImageInfo(CPLString *url,
183 : const GDALWMSImageRequestInfo &iri,
184 : const GDALWMSTiledImageRequestInfo &tiri,
185 : int nXInBlock,
186 : int nYInBlock)
187 : {
188 4 : BuildURL(url, iri, "GetFeatureInfo");
189 4 : URLAppendF(url, "&query_layers=%s", m_layers.c_str());
190 4 : URLAppendF(url, "&x=%d", nXInBlock);
191 4 : URLAppendF(url, "&y=%d", nYInBlock);
192 4 : const char* pszInfoFormat = CPLGetConfigOption("WMS_INFO_FORMAT", "application/vnd.ogc.gml");
193 4 : URLAppendF(url, "&info_format=%s", pszInfoFormat);
194 :
195 4 : CPLDebug("WMS", "URL = %s", url->c_str());
196 4 : }
197 :
198 :
199 2 : const char *GDALWMSMiniDriver_WMS::GetProjectionInWKT() {
200 2 : return m_projection_wkt.c_str();
201 : }
202 :
203 20 : double GDALWMSMiniDriver_WMS::GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what) {
204 20 : switch (what) {
205 5 : case 'x': return MIN(iri.m_x0, iri.m_x1);
206 5 : case 'y': return MIN(iri.m_y0, iri.m_y1);
207 5 : case 'X': return MAX(iri.m_x0, iri.m_x1);
208 5 : case 'Y': return MAX(iri.m_y0, iri.m_y1);
209 : }
210 0 : return 0.0;
211 : }
|