All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Utils.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/wms/Utils.cpp
22 
23  \brief Utility functions for WMS driver.
24 */
25 
26 // TerraLib
27 #include "../common/StringUtils.h"
28 #include "../geometry/Envelope.h"
29 #include "Config.h"
30 #include "Utils.h"
31 
32 // Boost
33 #include <boost/lexical_cast.hpp>
34 
35 // STL
36 #include <cassert>
37 
38 void te::wms::BuildLayersInfo(char** subdatasets, std::map<std::string, WMSLayerInfo>& info)
39 {
40  if(subdatasets == 0)
41  return;
42 
43  for(char** i = subdatasets; *i != 0; i = i + 2)
44  {
45  std::string request = std::string(*i); // Pseudo-GetMap request. e.g. "SUBDATASET_1_NAME=WMS:http://..."
46  std::string title = std::string(*(i + 1)); // User-friendly layer name. e.g. "SUBDATASET_1_DESC=Seritinga-MG"
47 
48  // Removing the key of GDAL metadata
49  std::size_t pos = request.find("=");
50  assert(pos != std::string::npos);
51  request = request.substr(pos + 1);
52 
53  // Removing the key of GDAL metadata
54  pos = title.find("=");
55  assert(pos != std::string::npos);
56  title = title.substr(pos + 1);
57 
58  std::map<std::string, std::string> kvps;
59  te::common::ExtractKVP(request, kvps, "&", "=", true);
60 
61  // Builds the informations from the current layer
62  WMSLayerInfo currentLayerInfo = BuildLayerInfo(kvps);
63  currentLayerInfo.m_title = title;
64  currentLayerInfo.m_pseudoGetMapRequest = request;
65 
66  // Adding the informations
67  info[currentLayerInfo.m_name] = currentLayerInfo;
68  }
69 }
70 
71 te::wms::WMSLayerInfo te::wms::BuildLayerInfo(const std::map<std::string, std::string>& kvp)
72 {
73  WMSLayerInfo info;
74 
75  assert(kvp.find("LAYERS") != kvp.end());
76  info.m_name = kvp.find("LAYERS")->second;
77 
78  std::map<std::string, std::string>::const_iterator it = kvp.find("BBOX");
79  if(it != kvp.end())
80  info.m_bbox = it->second;
81 
82  it = kvp.find("SRS");
83  if(it != kvp.end())
84  info.m_srs = it->second;
85 
86  it = kvp.find("CRS");
87  if(it != kvp.end())
88  info.m_srs = it->second;
89 
90  it = kvp.find("VERSION");
91  if(it != kvp.end())
92  info.m_version = it->second;
93 
94  return info;
95 }
96 
97 void te::wms::ExtractRequestValues(const std::string& request,
98  std::string& layer,
99  std::string& width,
100  std::string& height,
101  std::string& format)
102 {
103  assert(!request.empty());
104 
105  // Default parameters
106  width = TE_WMS_DEFAULT_WIDTH;
107  height = TE_WMS_DEFAULT_HEIGHT;
109 
110  std::map<std::string, std::string> kvp;
111  te::common::ExtractKVP(request, kvp, "&", "=", false);
112 
113  // Layers
114  std::map<std::string, std::string>::const_iterator it = kvp.find("LAYER");
115  if(it != kvp.end())
116  layer = it->second;
117  else
118  {
119  // Here assumes that is a simple request by name
120  layer = request;
121  return;
122  }
123 
124  // Width
125  it = kvp.find("WIDTH");
126  if(it != kvp.end())
127  width = it->second;
128 
129  // Height
130  it = kvp.find("HEIGHT");
131  if(it != kvp.end())
132  height = it->second;
133 
134  // Format
135  it = kvp.find("FORMAT");
136  if(it != kvp.end())
137  format = it->second;
138 }
139 
140 std::string te::wms::BuildGetMapRequest(const std::string& serverUrl,
141  const WMSLayerInfo& info,
142  const std::string& width,
143  const std::string& height,
144  const std::string& format,
145  const std::string& bbox)
146 {
147  assert(!serverUrl.empty());
148 
149  // Remove "WMS:" from given server url, if exists
150  std::string url = serverUrl;
151  if(url.find("WMS:") != std::string::npos)
152  {
153  std::size_t pos = serverUrl.find(":");
154  url = url.substr(pos + 1);
155  }
156 
157  // Build the GetMap request using the GDAL format. Details: http://www.gdal.org/frmt_wms.html
158  std::string request = "<GDAL_WMS>";
159 
160  // Service
161  request += "<Service name=\"WMS\">";
162  request += "<Version>" + info.m_version + "</Version>";
163  request += "<ServerUrl>" + url + "</ServerUrl>";
164  request += "<SRS>" + info.m_srs + "</SRS>";
165  request += "<ImageFormat>" + format + "</ImageFormat>";
166  request += "<Transparent>TRUE</Transparent>";
167  request += "<Layers>" + info.m_name + "</Layers>";
168  request += "</Service>";
169 
170  // Extract the BBOX corners
171  std::string ulx, uly, lrx, lry;
172  if(bbox.empty())
173  GetBBOXValues(info.m_bbox, ulx, uly, lrx, lry);
174  else
175  GetBBOXValues(bbox, ulx, uly, lrx, lry);
176 
177  // DataWindow
178  request += "<DataWindow>";
179  request += "<UpperLeftX>" + ulx + "</UpperLeftX>";
180  request += "<UpperLeftY>" + lry + "</UpperLeftY>";
181  request += "<LowerRightX>" + lrx + "</LowerRightX>";
182  request += "<LowerRightY>" + uly + "</LowerRightY>";
183  request += "<SizeX>" + width + "</SizeX>";
184  request += "<SizeY>" + height + "</SizeY>";
185  request += "</DataWindow>";
186 
187  request += "<BandsCount>4</BandsCount>";
188 
189  // BlockSize
190  request += "<BlockSizeX>" + width + "</BlockSizeX>";
191  request += "<BlockSizeY>" + height + "</BlockSizeY>";
192 
193  // Cache (It is a test!)
194  request += "<Cache>";
195  request += "<Path>./gdalwmscache</Path>";
196  request += "<Depth>2</Depth>";
197  request += "</Cache>";
198 
199  request += "</GDAL_WMS>";
200 
201  return request;
202 }
203 
204 void te::wms::GetBBOXValues(const std::string& bbox,
205  std::string& ulx, std::string& uly,
206  std::string& lrx, std::string& lry)
207 {
208  std::vector<std::string> values;
209  te::common::Tokenize(bbox, values, ",");
210 
211  assert(values.size() == 4);
212 
213  ulx = values[0];
214  uly = values[1];
215  lrx = values[2];
216  lry = values[3];
217 }
218 
220  std::string& ulx, std::string& uly,
221  std::string& lrx, std::string& lry)
222 {
223  ulx = boost::lexical_cast<std::string>(e.m_llx);
224  uly = boost::lexical_cast<std::string>(e.m_lly);
225  lrx = boost::lexical_cast<std::string>(e.m_urx);
226  lry = boost::lexical_cast<std::string>(e.m_ury);
227 }
228 
229 std::string te::wms::GetBBOX(const te::gm::Envelope& e)
230 {
231  std::string ulx, uly, lrx, lry;
232  GetBBOXValues(e, ulx, uly, lrx, lry);
233 
234  return ulx + "," + uly + "," + lrx + "," + lry;
235 }
void GetBBOXValues(const std::string &bbox, std::string &ulx, std::string &uly, std::string &lrx, std::string &lry)
Definition: Utils.cpp:204
#define TE_WMS_DEFAULT_WIDTH
It specifies the default width used on GetMap request.
Definition: Config.h:46
std::string m_pseudoGetMapRequest
Definition: WMSLayerInfo.h:48
Informations about WMS Layers.
Definition: WMSLayerInfo.h:44
#define TE_WMS_DEFAULT_IMAGE_FORMAT
It specifies the default image format used on GetMap request.
Definition: Config.h:60
double m_urx
Upper right corner x-coordinate.
Definition: Envelope.h:346
void ExtractKVP(const std::string &kvpStr, std::map< std::string, std::string > &kvp, const std::string &kvpDelimiter="&", const std::string &kvDelimiter="=", bool toUpper=false)
It extracts a key-value map from a string.
Definition: StringUtils.h:251
std::string BuildGetMapRequest(const std::string &serverUrl, const WMSLayerInfo &info, const std::string &width, const std::string &height, const std::string &format, const std::string &bbox="")
Definition: Utils.cpp:140
Configuration flags for the TerraLib WMS module.
std::string GetBBOX(const te::gm::Envelope &e)
Definition: Utils.cpp:229
std::string m_version
Definition: WMSLayerInfo.h:51
void Tokenize(const std::string &str, std::vector< std::string > &tokens, const std::string &delimiters=" ")
It tokenizes a given string with a delimiter of your own choice.
Definition: StringUtils.h:216
double m_llx
Lower left corner x-coordinate.
Definition: Envelope.h:344
#define TE_WMS_DEFAULT_HEIGHT
It specifies the default height used on GetMap request.
Definition: Config.h:53
An Envelope defines a 2D rectangular region.
Definition: Envelope.h:51
void BuildLayersInfo(char **subdatasets, std::map< std::string, WMSLayerInfo > &info)
Definition: Utils.cpp:38
void ExtractRequestValues(const std::string &request, std::string &layer, std::string &width, std::string &height, std::string &format)
Definition: Utils.cpp:97
Utility functions for WMS driver.
double m_lly
Lower left corner y-coordinate.
Definition: Envelope.h:345
double m_ury
Upper right corner y-coordinate.
Definition: Envelope.h:347
WMSLayerInfo BuildLayerInfo(const std::map< std::string, std::string > &kvp)
Definition: Utils.cpp:71