srs/WKTParser.h
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 WKTParser.h
22 
23  \brief A class that implements the grammar rules for well known text (WKT) of Spatial Reference Systems.
24  It is based on boost::spirit V2 and WKT BNF definition available in the OGC Coordinate Transformation
25  Services Specification - Revision 1.00 - pages 18 and 19.
26 
27  \warning Do not use this class. It is for TerraLib internal use. Try the te::srs::WKTReader instead.
28  */
29 
30 #ifndef __TERRALIB_SRS_INTERNAL_WKTPARSER_H
31 #define __TERRALIB_SRS_INTERNAL_WKTPARSER_H
32 
33 // TerraLib
34 #include "WKTActions.h"
35 
36 // boost
37 #include <boost/bind/bind.hpp>
38 #include <boost/spirit/include/qi.hpp>
39 
40 // STL
41 #include <iostream>
42 #include <string>
43 
44 // Auxiliaries namespaces
45 namespace qi = boost::spirit::qi;
46 namespace ascii = boost::spirit::ascii;
47 
48 // Using the following boost::spirit definitions
49 using qi::as_string;
50 using qi::char_;
51 using qi::double_;
52 using ascii::no_case;
53 
54 namespace te
55 {
56  namespace srs
57  {
58  /*!
59  \class WKTParser
60 
61  \brief A class that implements the Grammar Rules for well known text (WKT) format of Spatial Reference Systems.
62  */
63  template<typename Iterator>
64  class WKTParser : public qi::grammar<Iterator, ascii::space_type>
65  {
66  public:
67 
68  /** @name Constructor
69  * Initilizer methods.
70  */
71  //@{
72 
73  /*! \brief Default constructor. */
74  WKTParser() : WKTParser::base_type(srs)
75  {
77 
78  // Initializing all rules
79  initTags();
81  initDatum();
82  initToWGS84();
84  initParameter();
85  initAxis();
86  initSpheroid();
88  initUnits();
91  initAuthority();
93  }
94 
95  //@}
96 
97  private:
98 
99  /** @name Initializer methods.
100  * Methods to initialize the grammar rules.
101  */
102  //@{
103 
104  void initTags()
105  {
106  projectedCSTag = "PROJCS";
107  geographicCSTag = "GEOGCS";
108  datumTag = "DATUM";
109  toWGS84Tag = "TOWGS84";
110  spheroidTag = "SPHEROID";
111  projectionTag = "PROJECTION";
112  parameterTag = "PARAMETER";
113  primeMeridianTag = "PRIMEM";
114  unitTag = "UNIT";
115  authorityTag = "AUTHORITY";
116  axisTag = "AXIS";
117  northTag = "NORTH";
118  southTag = "SOUTH";
119  eastTag = "EAST";
120  westTag = "WEST";
121  upTag = "UP";
122  downTag = "DOWN";
123  otherTag = "OTHER";
124  }
125 
127  {
129  >> leftDelimiter
130  >> csName >> ','
131  >> geographicCS >> ','
132  >> projection >> *(',' >> parameter) >> *(',' >> axis)
133  >> ',' >> unit >> *(',' >> axis) >> -(',' >> authority)
135 
137  >> leftDelimiter
138  >> csName >> ','
139  >> datum >> ','
140  >> primeMeridian >> ','
141  >> unit >> -(',' >> authority)
143  }
144 
145  void initDatum()
146  {
147  datum = (datumTag[boost::bind(&WKTActions::createDatum, &m_a)]
148  >> leftDelimiter
149  >> datumName >> ','
150  >> spheroid >> -(',' >> toWGS84) >> -(',' >> authority)
151  >> rigthDelimiter)[boost::bind(&WKTActions::endDatum, &m_a)];
152  }
153 
154  void initToWGS84()
155  {
157  sevenParams = dx >> ',' >> dy >> ',' >> dz >> ',' >> ex >> ',' >> ey >> ',' >> ez >> ',' >> ppm;
158 
159 #if BOOST_VERSION < 106000
160  dx = double_[boost::bind(&WKTActions::setDx, &m_a, ::_1)];
161  dy = double_[boost::bind(&WKTActions::setDy, &m_a, ::_1)];
162  dz = double_[boost::bind(&WKTActions::setDz, &m_a, ::_1)];
163  ex = double_[boost::bind(&WKTActions::setEx, &m_a, ::_1)];
164  ey = double_[boost::bind(&WKTActions::setEy, &m_a, ::_1)];
165  ez = double_[boost::bind(&WKTActions::setEz, &m_a, ::_1)];
166  ppm = double_[boost::bind(&WKTActions::setPPM, &m_a, ::_1)];
167 #else
168  dx = double_[boost::bind(&WKTActions::setDx, &m_a, boost::placeholders::_1)];
169  dy = double_[boost::bind(&WKTActions::setDy, &m_a, boost::placeholders::_1)];
170  dz = double_[boost::bind(&WKTActions::setDz, &m_a, boost::placeholders::_1)];
171  ex = double_[boost::bind(&WKTActions::setEx, &m_a, boost::placeholders::_1)];
172  ey = double_[boost::bind(&WKTActions::setEy, &m_a, boost::placeholders::_1)];
173  ez = double_[boost::bind(&WKTActions::setEz, &m_a, boost::placeholders::_1)];
174  ppm = double_[boost::bind(&WKTActions::setPPM, &m_a, boost::placeholders::_1)];
175 #endif
176  }
177 
179  {
181  >> leftDelimiter
182  >> projectionName >> -(',' >> authority)
183  >> rigthDelimiter;
184  }
185 
187  {
189  >> leftDelimiter
190  >> parameterName >> ','
191  >> value
192  >> rigthDelimiter;
193  }
194 
196  {
198  >> leftDelimiter
199  >> spheroidName >> ','
200  >> semiMajorAxis >> ','
201  >> invFlattening >> -(',' >> authority)
202  >> rigthDelimiter)[boost::bind(&WKTActions::endSpheroid, &m_a)];
203  }
204 
206  {
208  >> leftDelimiter
209  >> primeMeridianName >> ','
210  >> longitude >> -(',' >> authority)
211  >> rigthDelimiter;
212  }
213 
214  void initUnits()
215  {
216  unit = unitTag
217  >> leftDelimiter
218  >> unitName >> ','
219  >> conversionFactor >> -(',' >> authority)
220  >> rigthDelimiter;
221  }
222 
224  {
225 #if BOOST_VERSION < 106000
226  unitName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setUnitName, &m_a, ::_1)] >> '"';
227 
228  spheroidName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setSpheroidName, &m_a, ::_1)] >> '"';
229 
230  projectionName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setProjectionName, &m_a, ::_1)] >> '"';
231 
232  datumName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setDatumName, &m_a, ::_1)] >> '"';
233 
234  axisName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAxisName, &m_a, ::_1)] >> '"';
235 
236  axisValue = as_string[(+(char_ - ']'))][boost::bind(&WKTActions::setAxisValue, &m_a, ::_1)];
237 
238  csName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setName, &m_a, ::_1)] >> '"';
239 
240  parameterName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setParameter, &m_a, ::_1)] >> '"';
241 #else
242  unitName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setUnitName, &m_a, boost::placeholders::_1)] >> '"';
243 
244  spheroidName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setSpheroidName, &m_a, boost::placeholders::_1)] >> '"';
245 
246  projectionName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setProjectionName, &m_a, boost::placeholders::_1)] >> '"';
247 
248  datumName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setDatumName, &m_a, boost::placeholders::_1)] >> '"';
249 
250  axisName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAxisName, &m_a, boost::placeholders::_1)] >> '"';
251 
252  axisValue = as_string[(+(char_ - ']'))][boost::bind(&WKTActions::setAxisValue, &m_a, boost::placeholders::_1)];
253 
254  csName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setName, &m_a, boost::placeholders::_1)] >> '"';
255 
256  parameterName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setParameter, &m_a, boost::placeholders::_1)] >> '"';
257 #endif
258 
259  primeMeridianName = '"' >> (+(char_ - '"')) >> '"';
260  }
261 
263  {
264 #if BOOST_VERSION < 106000
265  value = double_[boost::bind(&WKTActions::setParameterValue, &m_a, ::_1)];
266 
267  semiMajorAxis = double_[boost::bind(&WKTActions::setSemiMajorAxis, &m_a, ::_1)];
268 
269  longitude = double_[boost::bind(&WKTActions::setPrimeMeridian, &m_a, ::_1)];
270 
271  invFlattening = double_[boost::bind(&WKTActions::setInverseFlattening, &m_a, ::_1)];
272 
273  conversionFactor = double_[boost::bind(&WKTActions::setConversionFactor, &m_a, ::_1)];
274 
275 #else
276  value = double_[boost::bind(&WKTActions::setParameterValue, &m_a, boost::placeholders::_1)];
277 
278  semiMajorAxis = double_[boost::bind(&WKTActions::setSemiMajorAxis, &m_a, boost::placeholders::_1)];
279 
280  longitude = double_[boost::bind(&WKTActions::setPrimeMeridian, &m_a, boost::placeholders::_1)];
281 
282  invFlattening = double_[boost::bind(&WKTActions::setInverseFlattening, &m_a, boost::placeholders::_1)];
283 
284  conversionFactor = double_[boost::bind(&WKTActions::setConversionFactor, &m_a, boost::placeholders::_1)];
285 #endif
286  }
287 
289  {
291 #if BOOST_VERSION < 106000
292  authorityName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAuthorityName, &m_a, ::_1)] >> '"';
293  authorityCode = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAuthorityCode, &m_a, ::_1)] >> '"';
294 #else
295  authorityName = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAuthorityName, &m_a, boost::placeholders::_1)] >> '"';
296  authorityCode = '"' >> as_string[(+(char_ - '"'))][boost::bind(&WKTActions::setAuthorityCode, &m_a, boost::placeholders::_1)] >> '"';
297 #endif
298  }
299 
300  void initAxis()
301  {
303 
304  axis = axisTag
305  >> leftDelimiter
306  >> axisName >> ','
307  >> axisValue
308  >> rigthDelimiter;
309  }
310 
311 
313  {
314  leftDelimiter = char_('(') | char_('[');
315  rigthDelimiter = char_(')') | char_(']');
316  }
317 
318  //@}
319 
320  public:
321 
322  /** @name Access method.
323  * Method to access the SRS generated.
324  */
325  //@{
326 
327  /*!
328  \brief It returns the SRS generated by the parser process.
329 
330  \note The caller of this method will take the ownership of the SRS.
331  */
333 
334  //@}
335 
336  /*!
337  \brief This method resets the Parser to original state.
338 
339  \note Should be called case the parser processing faill.
340  \note Basically, it is responsable to free the memory.
341  */
342  void reset() { m_a.reset(); }
343 
344  private:
345 
346  WKTActions m_a; //<! Semanthic actions to grammar rules.
347 
348  /** @name Rules of WKT Grammar.
349  */
350  //@{
351 
352  qi::rule<Iterator, ascii::space_type> srs;
353 
354  qi::rule<Iterator, ascii::space_type> projectedCS, geographicCS;
355 
356  qi::rule<Iterator, ascii::space_type> projectedCSTag, geographicCSTag, datumTag, spheroidTag, projectionTag,
359 
360  qi::rule<Iterator, ascii::space_type> datum;
361 
362  qi::rule<Iterator, ascii::space_type> toWGS84, sevenParams;
363 
364  qi::rule<Iterator, ascii::space_type> dx, dy, dz, ex, ey, ez, ppm;
365 
366  qi::rule<Iterator, ascii::space_type> projection;
367 
368  qi::rule<Iterator, ascii::space_type> parameter;
369 
370  qi::rule<Iterator, ascii::space_type> spheroid;
371 
372  qi::rule<Iterator, ascii::space_type> primeMeridian;
373 
374  qi::rule<Iterator, ascii::space_type> unit;
375 
376  qi::rule<Iterator, ascii::space_type> axis;
377 
378  qi::rule<Iterator, ascii::space_type> axisValue;
379 
380  qi::rule<Iterator, ascii::space_type> value, semiMajorAxis, longitude, invFlattening, conversionFactor;
381 
383 
384  qi::rule<Iterator, ascii::space_type> authority, authorityCode;
385 
386  qi::rule<Iterator> authorityName;
387 
388  qi::rule<Iterator, ascii::space_type> leftDelimiter, rigthDelimiter;
389 
390  //@}
391 
392  }; // WKTParser
393 
394  } // namespace srs
395 } // namespace te
396 
397 #endif // __TERRALIB_SRS_INTERNAL_WKTPARSER_H
void reset()
This method resets the Action class to original state.
WKTParser()
Default constructor.
Definition: srs/WKTParser.h:74
qi::rule< Iterator, ascii::space_type > projection
void setSpheroidName(const std::string &name)
void setPrimeMeridian(const double &primem)
qi::rule< Iterator, ascii::space_type > upTag
void setAuthorityName(const std::string &name)
qi::rule< Iterator, ascii::space_type > projectedCSTag
qi::rule< Iterator, ascii::space_type > downTag
qi::rule< Iterator, ascii::space_type > authorityCode
qi::rule< Iterator > datumName
void setAxisValue(const std::string &value)
void setConversionFactor(const double &f)
qi::rule< Iterator, ascii::space_type > srs
qi::rule< Iterator, ascii::space_type > invFlattening
qi::rule< Iterator > spheroidName
qi::rule< Iterator, ascii::space_type > ez
A class that implements the Grammar Rules for well known text (WKT) format for Spatial Reference Syst...
qi::rule< Iterator, ascii::space_type > dy
qi::rule< Iterator > parameterName
qi::rule< Iterator > projectionName
qi::rule< Iterator, ascii::space_type > unitTag
qi::rule< Iterator, ascii::space_type > projectionTag
void setEx(const double &ex)
void createGeographicCoordinateSystem()
qi::rule< Iterator > authorityName
A Spatial Reference System, also known as a Coordinate System.
qi::rule< Iterator, ascii::space_type > geographicCS
qi::rule< Iterator, ascii::space_type > ex
void setUnitName(const std::string &name)
qi::rule< Iterator, ascii::space_type > spheroid
qi::rule< Iterator > csName
void setPPM(const double &ppm)
void initSpatialReferenceSystems()
void setEz(const double &ez)
qi::rule< Iterator, ascii::space_type > datum
void setDx(const double &dx)
qi::rule< Iterator, ascii::space_type > rigthDelimiter
void setProjectionName(const std::string &name)
SpatialReferenceSystem * getSRS()
It returns the SRS generated by the parser process.
void setDy(const double &dy)
A class that implements the Grammar Rules for well known text (WKT) format of Spatial Reference Syste...
Definition: srs/WKTParser.h:64
qi::rule< Iterator, ascii::space_type > primeMeridianTag
qi::rule< Iterator, ascii::space_type > authority
qi::rule< Iterator, ascii::space_type > value
URI C++ Library.
Definition: Attributes.h:37
qi::rule< Iterator > unitName
qi::rule< Iterator, ascii::space_type > southTag
qi::rule< Iterator, ascii::space_type > eastTag
qi::rule< Iterator, ascii::space_type > projectedCS
qi::rule< Iterator, ascii::space_type > axisValue
qi::rule< Iterator, ascii::space_type > leftDelimiter
void reset()
This method resets the Parser to original state.
qi::rule< Iterator, ascii::space_type > toWGS84
void setDatumName(const std::string &name)
qi::rule< Iterator, ascii::space_type > ey
qi::rule< Iterator, ascii::space_type > datumTag
void setAxisName(const std::string &name)
qi::rule< Iterator, ascii::space_type > westTag
qi::rule< Iterator, ascii::space_type > conversionFactor
void setSemiMajorAxis(const double &rad)
qi::rule< Iterator, ascii::space_type > unit
qi::rule< Iterator, ascii::space_type > axisTag
qi::rule< Iterator, ascii::space_type > spheroidTag
qi::rule< Iterator > primeMeridianName
qi::rule< Iterator, ascii::space_type > parameter
qi::rule< Iterator, ascii::space_type > axis
qi::rule< Iterator, ascii::space_type > dz
SpatialReferenceSystem * getSRS()
It returns the SRS generated by the parser process.
qi::rule< Iterator, ascii::space_type > semiMajorAxis
void setParameter(const std::string &name)
qi::rule< Iterator, ascii::space_type > primeMeridian
qi::rule< Iterator, ascii::space_type > sevenParams
qi::rule< Iterator, ascii::space_type > ppm
qi::rule< Iterator > axisName
void endGeographicCoordinateSystem()
void setName(const std::string &name)
qi::rule< Iterator, ascii::space_type > geographicCSTag
void setParameterValue(const double &value)
qi::rule< Iterator, ascii::space_type > toWGS84Tag
qi::rule< Iterator, ascii::space_type > authorityTag
qi::rule< Iterator, ascii::space_type > parameterTag
qi::rule< Iterator, ascii::space_type > dx
void setEy(const double &ey)
void setDz(const double &dz)
qi::rule< Iterator, ascii::space_type > northTag
void createProjectedCoordinateSystem()
void setAuthorityCode(const std::string &code)
void setInverseFlattening(const double &invflat)
qi::rule< Iterator, ascii::space_type > longitude
qi::rule< Iterator, ascii::space_type > otherTag