All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
UnitsOfMeasureManager.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/common/UnitsOfMeasureManager.cpp
22 
23  \brief A singleton class for dealing with units-of-measurement.
24 */
25 
26 // TerraLib
27 #include "Exception.h"
28 #include "STLUtils.h"
29 #include "StringUtils.h"
30 #include "Translator.h"
31 #include "UnitOfMeasure.h"
32 #include "UnitsOfMeasureManager.h"
33 
34 // STL
35 #include <algorithm>
36 #include <cassert>
37 
38 // Boost
39 #include <boost/algorithm/string.hpp>
40 #include <boost/foreach.hpp>
41 #include <boost/format.hpp>
42 #include <boost/property_tree/json_parser.hpp>
43 #include <boost/property_tree/ptree.hpp>
44 
46 {}
47 
49 {
50  clear();
51 }
52 
54 {
55  m_uoms.clear();
56  m_uomsIdxByName.clear();
57 }
58 
60 {
61  assert(uom.get());
62 
63  const_iterator it = m_uoms.find(uom->getId());
64  if(it != m_uoms.end())
65  return;
66 
67  m_uoms.insert(std::pair<unsigned int, UnitOfMeasurePtr>(uom->getId(),uom));
68 
69  std::string upstr = boost::to_upper_copy(uom->getName());
70  m_uomsIdxByName.insert(std::pair<std::string, unsigned int>(upstr,uom->getId()));
71 }
72 
73 void te::common::UnitsOfMeasureManager::insert(UnitOfMeasurePtr& uom, const std::vector<std::string>& alternativeNames)
74 {
75  insert(uom);
76 
77  for(std::size_t i=0; i<alternativeNames.size(); ++i)
78  {
79  std::string upstr = boost::to_upper_copy(alternativeNames[i]);
80  m_uomsIdxByName.insert(std::pair<std::string, unsigned int>(upstr,uom->getId()));
81  }
82 }
83 
85 {
86  assert(uom.get());
87 
88  iterator it = m_uoms.find(uom->getId());
89  if (it == m_uoms.end())
90  return;
91 
92  m_uoms.erase(it);
93 
94  for (std::map<std::string, unsigned int>::iterator itn = m_uomsIdxByName.begin(); itn != m_uomsIdxByName.end();)
95  {
96  if (itn->second == uom->getId())
97  m_uomsIdxByName.erase(itn++);
98  else
99  ++itn;
100  }
101 }
102 
105 {
106  const_iterator it = m_uoms.find(id);
107  if (it == m_uoms.end())
108  return UnitOfMeasurePtr();
109 
110  return it->second;
111 }
112 
114 te::common::UnitsOfMeasureManager::find(const std::string& name) const
115 {
116  std::string upstr = boost::to_upper_copy(name);
117 
118  std::map<std::string, unsigned int>::const_iterator it = m_uomsIdxByName.find(upstr);
119 
120  if(it != m_uomsIdxByName.end())
121  {
122  const_iterator it2 = m_uoms.find(it->second);
123  if (it2 != m_uoms.end())
124  return it2->second;
125  }
126 
127  return UnitOfMeasurePtr();
128 }
129 
131 te::common::UnitsOfMeasureManager::findBySymbol(const std::string& symbol) const
132 {
133  const_iterator it = m_uoms.begin();
134  while (it != m_uoms.end())
135  {
136  if (it->second->getSymbol() == symbol)
137  return it->second;
138  ++it;
139  }
140  return UnitOfMeasurePtr();
141 }
142 
143 void te::common::UnitsOfMeasureManager::getNames(UnitOfMeasurePtr& uom, std::vector<std::string>& names) const
144 {
145  std::map<std::string, unsigned int>::const_iterator it = m_uomsIdxByName.begin();
146  while (it != m_uomsIdxByName.end())
147  {
148  if (it->second == uom->getId())
149  names.push_back(it->first);
150  ++it;
151  }
152 }
153 
154 double te::common::UnitsOfMeasureManager::getConversion(const std::string& unitFromName, const std::string& unitToName) const
155 {
156  UnitOfMeasurePtr uFrom = this->find(unitFromName);
157  UnitOfMeasurePtr uTo = this->find(unitToName);
158 
159  if (uFrom->getType() != uTo->getType())
160  throw Exception(TR_COMMON("There is not conversion between units for different types of measures."));
161 
162  if (uFrom->getBaseUnitId() == uTo->getId()) // converting from derived to base
163  {
164  return (uFrom->getConversionValue());
165  }
166  else if (uTo->getBaseUnitId() == uFrom->getId()) // converting from base to derived
167  {
168  double a, b, c, d;
169 
170  uTo->getConversionFactors(a,b,c,d);
171  return ((b-d)/(c-a));
172  }
173  throw Exception(TR_COMMON("There is no known conversion."));
174 }
175 
177 {
178  if(!m_uoms.empty())
179  throw Exception(TR_COMMON("The unit of measure manager is already initialized!"));
180 
181  boost::property_tree::ptree pt;
182 
183  const char* te_env = getenv("TERRALIB_DIR");
184 
185  if(te_env == 0)
186  throw Exception(TR_COMMON("Environment variable \"TERRALIB_DIR\" not found.\nTry to set it before run the application."));
187 
188  std::string uom_file(te_env);
189  uom_file += "/resources/json/uom.json";
190 
191  boost::property_tree::json_parser::read_json(uom_file, pt);
192 
193  BOOST_FOREACH(boost::property_tree::ptree::value_type& v, pt.get_child("units"))
194  {
195  unsigned int id = v.second.get<unsigned int>("id");
196  std::string name = v.second.get<std::string>("name");
197  std::string symbol = v.second.get<std::string>("symbol");
198  std::string stype = v.second.get<std::string>("type");
199  std::string description = v.second.get<std::string>("description");
200  unsigned int targetUOM = v.second.get<unsigned int>("target_uom");
201  double a = v.second.get<double>("factor_a");
202  double b = v.second.get<double>("factor_b");
203  double c = v.second.get<double>("factor_c");
204  double d = v.second.get<double>("factor_d");
205 
206  MeasureType t = Length;
207 
208  if(stype == "length")
209  t = Length;
210  else if(stype == "area")
211  t = Area;
212  else if(stype == "volume")
213  t = Volume;
214  else if(stype == "angle")
215  t = Angle;
216  else if(stype == "scale")
217  t = Scale;
218  else if(stype == "time")
219  t = Time;
220  else if(stype == "speed")
221  t = Speed;
222  else
223  {
224  throw Exception((boost::format(TR_COMMON("Invalid unit of measure type: %1%!")) % stype).str());
225  }
226 
227  UnitOfMeasurePtr uom(new UnitOfMeasure(id, name, symbol, t, targetUOM, a, b, c, d, description));
228 
229  insert(uom);
230  }
231 }
232 
Utility functions for dealing with strings.
This file contains several utility functions for dealing with STL containers.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Definition: Exception.h:58
std::map< unsigned int, UnitOfMeasurePtr >::iterator iterator
mydialect insert("+", new te::da::BinaryOpEncoder("+"))
void getNames(UnitOfMeasurePtr &uom, std::vector< std::string > &names) const
Retrieves the alternative names for a unit of measure.
UnitOfMeasurePtr find(unsigned int id) const
Returns a unit of measure identified by its identificaton.
A class for representing a unit of measure.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
boost::shared_ptr< UnitOfMeasure > UnitOfMeasurePtr
double getConversion(const std::string &unitFromName, const std::string &unitToName) const
Calculates a multiplicative factor to convert from a given unit to its base unit and vice-versa...
void remove(UnitOfMeasurePtr &uom)
Removes a unit of measure from the manager.
A class to represent units of measure.
Definition: UnitOfMeasure.h:74
std::map< unsigned int, UnitOfMeasurePtr >::const_iterator const_iterator
void clear()
Removes all units from the catalogue.
UnitsOfMeasureManager()
It initializes the Singleton.
MeasureType
Defines the possible types of unit of measurements.
Definition: Enums.h:76
#define TR_COMMON(message)
It marks a string in order to get translated. This is the mark used in the Common module of TerraLib...
Definition: Config.h:173
void init()
It initializes the list of well kown units of measure.
UnitOfMeasurePtr findBySymbol(const std::string &symbol) const
Returns a unit of measure identified by its symbol.
A singleton class for dealing with units-of-measure.
void insert(UnitOfMeasurePtr &uom)
Inserts a new unit of measure to be managed.
This class is designed for dealing with multi-language text translation in TerraLib.