1 : /******************************************************************************
2 : * $Id: minidriver_wms.cpp 23033 2011-09-03 18:46:11Z 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 1062 : 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 1 : void GDALWMSMiniDriver_WMS::ImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri) {
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 1 : *url = m_base_url;
154 1 : if (m_base_url.ifind( "service=") == std::string::npos)
155 0 : URLAppend(url, "&service=WMS");
156 1 : URLAppend(url, "&request=GetMap");
157 1 : URLAppendF(url, "&version=%s", m_version.c_str());
158 1 : URLAppendF(url, "&layers=%s", m_layers.c_str());
159 1 : URLAppendF(url, "&styles=%s", m_styles.c_str());
160 1 : if (m_srs.size()) URLAppendF(url, "&srs=%s", m_srs.c_str());
161 1 : if (m_crs.size()) URLAppendF(url, "&crs=%s", m_crs.c_str());
162 1 : if (m_transparent.size()) URLAppendF(url, "&transparent=%s", m_transparent.c_str());
163 1 : URLAppendF(url, "&format=%s", m_image_format.c_str());
164 1 : URLAppendF(url, "&width=%d", iri.m_sx);
165 1 : URLAppendF(url, "&height=%d", iri.m_sy);
166 : URLAppendF(url, "&bbox=%.8f,%.8f,%.8f,%.8f",
167 : GetBBoxCoord(iri, m_bbox_order[0]), GetBBoxCoord(iri, m_bbox_order[1]),
168 1 : GetBBoxCoord(iri, m_bbox_order[2]), GetBBoxCoord(iri, m_bbox_order[3]));
169 1 : CPLDebug("WMS", "URL = %s", url->c_str());
170 1 : }
171 :
172 1 : void GDALWMSMiniDriver_WMS::TiledImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri, const GDALWMSTiledImageRequestInfo &tiri) {
173 1 : ImageRequest(url, iri);
174 1 : }
175 :
176 2 : const char *GDALWMSMiniDriver_WMS::GetProjectionInWKT() {
177 2 : return m_projection_wkt.c_str();
178 : }
179 :
180 4 : double GDALWMSMiniDriver_WMS::GetBBoxCoord(const GDALWMSImageRequestInfo &iri, char what) {
181 4 : switch (what) {
182 1 : case 'x': return MIN(iri.m_x0, iri.m_x1);
183 1 : case 'y': return MIN(iri.m_y0, iri.m_y1);
184 1 : case 'X': return MAX(iri.m_x0, iri.m_x1);
185 1 : case 'Y': return MAX(iri.m_y0, iri.m_y1);
186 : }
187 0 : return 0.0;
188 : }
|