1 : /******************************************************************************
2 : * $Id: minidriver_wms.cpp 18345 2009-12-19 11:02:39Z 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 988 : CPP_GDALWMSMiniDriverFactory(WMS)
34 :
35 2 : GDALWMSMiniDriver_WMS::GDALWMSMiniDriver_WMS() {
36 2 : }
37 :
38 4 : GDALWMSMiniDriver_WMS::~GDALWMSMiniDriver_WMS() {
39 4 : }
40 :
41 2 : CPLErr GDALWMSMiniDriver_WMS::Initialize(CPLXMLNode *config) {
42 2 : CPLErr ret = CE_None;
43 :
44 2 : if (ret == CE_None) {
45 2 : const char *version = CPLGetXMLValue(config, "Version", "1.1.0");
46 2 : if (version[0] != '\0') {
47 2 : m_version = version;
48 2 : m_iversion = VersionStringToInt(version);
49 2 : 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 2 : if (ret == CE_None) {
60 2 : const char *base_url = CPLGetXMLValue(config, "ServerURL", "");
61 2 : if (base_url[0] != '\0') {
62 : /* Try the old name */
63 2 : base_url = CPLGetXMLValue(config, "ServerUrl", "");
64 : }
65 2 : if (base_url[0] != '\0') {
66 2 : 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 2 : 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 2 : const char *crs = CPLGetXMLValue(config, "CRS", "");
77 2 : const char *srs = CPLGetXMLValue(config, "SRS", "");
78 2 : 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 2 : 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 2 : } else if (srs[0] != '\0') {
94 2 : m_srs = srs;
95 : } else {
96 0 : m_srs = "EPSG:4326";
97 : }
98 : }
99 : }
100 :
101 2 : if (ret == CE_None) {
102 2 : if (m_srs.size()) {
103 2 : 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 2 : if (ret == CE_None) {
110 2 : m_image_format = CPLGetXMLValue(config, "ImageFormat", "image/jpeg");
111 4 : m_layers = CPLGetXMLValue(config, "Layers", "");
112 4 : m_styles = CPLGetXMLValue(config, "Styles", "");
113 4 : 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 2 : int i=0;
116 4 : while (m_transparent[i] != '\0')
117 : {
118 0 : m_transparent[i] = toupper(m_transparent[i]);
119 0 : i ++;
120 : }
121 : }
122 :
123 2 : if (ret == CE_None) {
124 2 : const char *bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
125 2 : if (bbox_order[0] != '\0') {
126 : int i;
127 10 : for (i = 0; i < 4; ++i) {
128 8 : if ((bbox_order[i] != 'x') && (bbox_order[i] != 'y') && (bbox_order[i] != 'X') && (bbox_order[i] != 'Y')) break;
129 : }
130 2 : if (i == 4) {
131 2 : m_bbox_order = bbox_order;
132 : } else {
133 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: Incorrect BBoxOrder.");
134 0 : ret = CE_Failure;
135 : }
136 : } else {
137 0 : CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, WMS mini-driver: BBoxOrder missing.");
138 0 : ret = CE_Failure;
139 : }
140 : }
141 :
142 2 : return ret;
143 : }
144 :
145 2 : void GDALWMSMiniDriver_WMS::GetCapabilities(GDALWMSMiniDriverCapabilities *caps) {
146 2 : caps->m_capabilities_version = 1;
147 2 : caps->m_has_arb_overviews = 1;
148 2 : caps->m_has_image_request = 1;
149 2 : caps->m_has_tiled_image_requeset = 1;
150 2 : caps->m_max_overview_count = 32;
151 2 : }
152 :
153 1 : void GDALWMSMiniDriver_WMS::ImageRequest(CPLString *url, const GDALWMSImageRequestInfo &iri) {
154 : // 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
155 1 : *url = m_base_url;
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 0 : const char *GDALWMSMiniDriver_WMS::GetProjectionInWKT() {
177 0 : 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 : }
|