All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SpatialReferenceSystemManager.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2001-2009 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/srs/SpatialReferenceSystemManager.cpp
22 
23  \brief A singleton to manage Coordinate Systems representations.
24 */
25 
26 // Boost
27 #include <boost/foreach.hpp>
28 #include <boost/property_tree/ptree.hpp>
29 #include <boost/property_tree/json_parser.hpp>
30 
31 // TerraLib
32 #include "../common/Translator.h"
33 #include "../common/UnitsOfMeasureManager.h"
34 #include "Exception.h"
36 #include "WKTReader.h"
37 
38 // STL
39 #include <algorithm>
40 #include <cassert>
41 
42 te::srs::SpatialReferenceSystemManager::srs_desc::srs_desc(const std::string& name, unsigned int auth_id, const std::string& auth_name, const std::string& p4txt, const std::string& wkt):
43  m_name(name),
44  m_auth_id(auth_id),
45  m_auth_name(auth_name),
46  m_p4txt(p4txt),
47  m_wkt(wkt)
48 {}
49 
50 std::string
52 {
53  std::string ssrid = m_auth_name;
54  ssrid += ":";
55  ssrid += boost::lexical_cast<std::string>(m_auth_id);
56  return ssrid;
57 }
58 
60 {
61 }
62 
64 {
65  clear();
66 }
67 
69 {
70  if(!m_set.empty())
71  throw Exception(TR_SRS("The spatial reference system manager is already initialized!"));
72 
73  const char* te_env = getenv("TERRALIB_DIR");
74 
75  if(te_env == 0)
76  throw Exception(TR_SRS("Environment variable \"TERRALIB_DIR\" not found.\nTry to set it before run the application."));
77 
78  try
79  {
80  std::ifstream f;
81 
82  std::string jsonf(te_env);
83  jsonf += "/resources/json/srs.json";
84 
85  f.open(jsonf.c_str());
86  if (!f.is_open())
87  return;
88 
89  boost::property_tree::ptree pt;
90  boost::property_tree::json_parser::read_json(f,pt);
91  BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("SRSs"))
92  {
93  if (v.second.get<unsigned int>("srid") > 100000)
94  add(v.second.get<std::string>("name"), v.second.get<std::string>("pj4txt"),
95  v.second.get<std::string>("wkt"), v.second.get<unsigned int>("srid"), "USER");
96  else
97  add(v.second.get<std::string>("name"), v.second.get<std::string>("pj4txt"),
98  v.second.get<std::string>("wkt"), v.second.get<unsigned int>("srid"));
99  }
100  f.close();
101  }
102  catch(boost::property_tree::json_parser::json_parser_error &je)
103  {
104  std::string errmsg = "Error parsing: " + je.filename() + ": " + je.message();
105  te::srs::Exception ex(TR_SRS(errmsg));
106  throw(ex);
107  }
108  catch (std::exception const& e)
109  {
110  std::cerr << e.what() << std::endl;
111  }
112  return;
113 }
114 
115 void te::srs::SpatialReferenceSystemManager::add(const std::string& name, const std::string& p4Txt, const std::string& wkt, unsigned int id, const std::string& authName)
116 {
117  std::string key = authName;
118  key += ":";
119  key += boost::lexical_cast<std::string>(id);
120 
121  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
122  if (it != boost::multi_index::get<0>(m_set).end())
123  throw te::srs::Exception(TR_SRS("The CS identification already exists in the manager."));
124 
125  srs_desc record(name, id, authName, p4Txt, wkt);
126  m_set.insert(record);
127 }
128 
129 bool te::srs::SpatialReferenceSystemManager::recognizes(unsigned int id, const std::string& authName) const
130 {
131  std::string key = authName;
132  key += ":";
133  key += boost::lexical_cast<std::string>(id);
134 
135  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
136  if (it == boost::multi_index::get<0>(m_set).end())
137  {
138  key = "USER";
139  key += ":";
140  key += boost::lexical_cast<std::string>(id);
141  it = boost::multi_index::get<0>(m_set).find(key);
142  return (it != boost::multi_index::get<0>(m_set).end());
143  }
144  else
145  return true;
146 }
147 
148 std::auto_ptr<te::srs::SpatialReferenceSystem> te::srs::SpatialReferenceSystemManager::getSpatialReferenceSystem(unsigned int id, const std::string& authName) const
149 {
150  std::string wkt = getWkt(id,authName);
151  if (wkt.empty())
152  return std::auto_ptr<te::srs::SpatialReferenceSystem>();
153 
154  try
155  {
156  return std::auto_ptr<te::srs::SpatialReferenceSystem>(te::srs::WKTReader::read(wkt.c_str()));
157  }
158  catch(...)
159  {
160  throw te::srs::Exception(TR_SRS("Error parsing the registered CS WKT."));
161  }
162  return std::auto_ptr<te::srs::SpatialReferenceSystem>();
163 }
164 
165 
166 std::string te::srs::SpatialReferenceSystemManager::getName(unsigned int id, const std::string& authName) const
167 {
168  std::string key = authName;
169  key += ":";
170  key += boost::lexical_cast<std::string>(id);
171 
172  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
173  if (it == boost::multi_index::get<0>(m_set).end())
174  {
175  key = "USER";
176  key += ":";
177  key += boost::lexical_cast<std::string>(id);
178  it = boost::multi_index::get<0>(m_set).find(key);
179  if (it!=boost::multi_index::get<0>(m_set).end())
180  return it->m_name;
181  }
182  else
183  return it->m_name;
184 
185  return "";
186 }
187 
188 std::string te::srs::SpatialReferenceSystemManager::getWkt(unsigned int id, const std::string& authName) const
189 {
190  std::string key = authName;
191  key += ":";
192  key += boost::lexical_cast<std::string>(id);
193 
194  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
195  if (it==boost::multi_index::get<0>(m_set).end())
196  {
197  key = "USER";
198  key += ":";
199  key += boost::lexical_cast<std::string>(id);
200  it = boost::multi_index::get<0>(m_set).find(key);
201  if (it!=boost::multi_index::get<0>(m_set).end())
202  return it->m_wkt;
203  }
204  else
205  return it->m_wkt;
206 
207  return "";
208 }
209 
210 std::string te::srs::SpatialReferenceSystemManager::getP4Txt(unsigned int id, const std::string& authName) const
211 {
212  std::string key = authName;
213  key += ":";
214  key += boost::lexical_cast<std::string>(id);
215 
216  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
217  if (it==boost::multi_index::get<0>(m_set).end())
218  {
219  key = "USER";
220  key += ":";
221  key += boost::lexical_cast<std::string>(id);
222  it = boost::multi_index::get<0>(m_set).find(key);
223  if (it!=boost::multi_index::get<0>(m_set).end())
224  return it->m_p4txt;
225  }
226  else
227  return it->m_p4txt;
228 
229  return "";
230 }
231 
232 std::pair<std::string,unsigned int> te::srs::SpatialReferenceSystemManager::getIdFromName(const std::string& name) const
233 {
234  boost::multi_index::nth_index<srs_set,1>::type::iterator it = boost::multi_index::get<1>(m_set).find(name);
235  if (it==boost::multi_index::get<1>(m_set).end())
236  throw te::srs::Exception(TR_SRS("CS name not recognized."));
237 
238  return std::pair<std::string,unsigned int>(it->m_auth_name, it->m_auth_id);
239 }
240 
241 
242 std::pair<std::string,unsigned int> te::srs::SpatialReferenceSystemManager::getIdFromP4Txt(const std::string& p4Txt) const
243 {
244  boost::multi_index::nth_index<srs_set,2>::type::iterator it = boost::multi_index::get<2>(m_set).find(p4Txt);
245  if (it==boost::multi_index::get<2>(m_set).end())
246  throw te::srs::Exception(TR_SRS("CS name not recognized."));
247 
248  return std::pair<std::string,unsigned int>(it->m_auth_name, it->m_auth_id);
249 }
250 
251 std::pair<std::string,unsigned int> te::srs::SpatialReferenceSystemManager::getIdFromWkt(const std::string& wkt) const
252 {
253  boost::multi_index::nth_index<srs_set,3>::type::iterator it = boost::multi_index::get<3>(m_set).find(wkt);
254  if (it==boost::multi_index::get<3>(m_set).end())
255  throw te::srs::Exception(TR_SRS("CS name not recognized."));
256 
257  return std::pair<std::string,unsigned int>(it->m_auth_name, it->m_auth_id);
258 }
259 
260 void te::srs::SpatialReferenceSystemManager::remove(unsigned int id, const std::string& authName)
261 {
262  std::string key = authName;
263  key += ":";
264  key += boost::lexical_cast<std::string>(id);
265 
266  boost::multi_index::nth_index<srs_set,0>::type::iterator it = boost::multi_index::get<0>(m_set).find(key);
267  if (it==boost::multi_index::get<0>(m_set).end())
268  {
269  key = "USER";
270  key += ":";
271  key += boost::lexical_cast<std::string>(id);
272  it = boost::multi_index::get<0>(m_set).find(key);
273  if (it!=boost::multi_index::get<0>(m_set).end())
274  m_set.erase(it);
275  }
276  else
277  m_set.erase(it);
278 }
279 
281 {
282  m_set.clear();
283 }
284 
285 std::pair<te::srs::SpatialReferenceSystemManager::iterator,te::srs::SpatialReferenceSystemManager::iterator>
287 {
289  te::srs::SpatialReferenceSystemManager::iterator>(boost::multi_index::get<0>(m_set).begin(), boost::multi_index::get<0>(m_set).end());
290 }
291 
293 {
294  return m_set.size();
295 }
296 
298 {
299  std::string unitName= "metre";
300  if (isGeographic(id,authName))
301  unitName = "degree";
302 
303  std::string pjstr = getP4Txt(id,authName);
304  if (pjstr.empty())
306 
307  std::size_t found = pjstr.find("+units=");
308  if (found!=std::string::npos)
309  {
310  std::size_t aux = pjstr.find(" ", found);
311  std::string unitsymbol = pjstr.substr(found+7,aux-(found+7));
313  }
314 
316 }
317 
318 
319 bool te::srs::SpatialReferenceSystemManager::isGeographic(unsigned int id, const std::string& authName)
320 {
321  std::string pjstr = getP4Txt(id,authName);
322  return (pjstr.find("+proj=longlat")!=std::string::npos);
323 }
An exception class for the SRS module.
std::pair< std::string, unsigned int > getIdFromName(const std::string &name) const
Returns a coordinate system identification given a name.
void clear()
Removes all coordinate system representations from the manager.
bool isGeographic(unsigned int id, const std::string &authName)
Checks if a SRS with a given id refers to a geographic spatial reference system.
std::pair< std::string, unsigned int > getIdFromP4Txt(const std::string &p4Txt) const
Returns a coordinate system identification given a PROJ4 description.
std::string getWkt(unsigned int id, const std::string &authName="EPSG") const
Returns a coordinate system WKT description given an id.
static SpatialReferenceSystem * read(const char *wkt)
It returns a valid SRS from a given WKT.
Definition: WKTReader.cpp:31
size_t size() const
Returns the number of objects in the manager.
void add(const std::string &name, const std::string &p4Txt, const std::string &wkt, unsigned int id, const std::string &authName="EPSG")
Adds a &lt;id, authority&gt; to the manager.
A class to manage Coordinate Systems representations.
UnitOfMeasurePtr find(unsigned int id) const
Returns a unit of measure identified by its identificaton.
boost::shared_ptr< UnitOfMeasure > UnitOfMeasurePtr
#define TR_SRS(message)
It marks a string in order to get translated. This is a special mark used in the SRS module of TerraL...
Definition: Config.h:63
std::pair< te::srs::SpatialReferenceSystemManager::iterator, te::srs::SpatialReferenceSystemManager::iterator > getIterators() const
Returns an iterator mechanism over the coordinate system descriptions in the manager.
srs_desc(const std::string &name, unsigned int auth_id, const std::string &auth_name, const std::string &p4txt, const std::string &wkt)
std::string getP4Txt(unsigned int id, const std::string &authName="EPSG") const
Returns a coordinate system PROJ4 description given an identification.
SpatialReferenceSystemPtr getSpatialReferenceSystem(unsigned int id, const std::string &authName="EPSG") const
Returns a pointer to a coordinate system given an identification.
void remove(unsigned int id, const std::string &authName="EPSG")
Removes a coordinate system representation from the manager, given its identification.
boost::multi_index::nth_index< srs_set, 0 >::type::iterator iterator
An iterator by SRS &lt;id,authority&gt;
te::common::UnitOfMeasurePtr getUnit(unsigned int id, const std::string &authName="EPSG")
Returns the unit of measure for a SRS with a given id.
bool recognizes(unsigned int id, const std::string &authName="EPSG") const
Returns true is a pair &lt;id, authority&gt; is recognized by the manager.
std::pair< std::string, unsigned int > getIdFromWkt(const std::string &wkt) const
Returns a coordinate system identification given a WKT description.
UnitOfMeasurePtr findBySymbol(const std::string &symbol) const
Returns a unit of measure identified by its symbol.
std::string getName(unsigned int id, const std::string &authName="EPSG") const
Returns a coordinate system name given an identification.
static UnitsOfMeasureManager & getInstance()
It returns a reference to the singleton instance.
void init()
Inializes the manager from a JSON file containing instances of SRSs.