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 >> -(',' >> 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 endProjectedCoordinateSystem()
WKTActions m_a
Definition: WKTParser.h:346
void reset()
This method resets the Action class to original state.
WKTParser()
Default constructor.
Definition: WKTParser.h:74
void initProjection()
Definition: WKTParser.h:178
qi::rule< Iterator, ascii::space_type > projection
Definition: WKTParser.h:366
void setSpheroidName(const std::string &name)
void initParameter()
Definition: WKTParser.h:186
void setPrimeMeridian(const double &primem)
qi::rule< Iterator, ascii::space_type > upTag
Definition: WKTParser.h:356
void setAuthorityName(const std::string &name)
qi::rule< Iterator, ascii::space_type > projectedCSTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > downTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > authorityCode
Definition: WKTParser.h:384
qi::rule< Iterator > datumName
Definition: WKTParser.h:382
void setAxisValue(const std::string &value)
void setConversionFactor(const double &f)
qi::rule< Iterator, ascii::space_type > srs
Definition: WKTParser.h:352
qi::rule< Iterator, ascii::space_type > invFlattening
Definition: WKTParser.h:380
qi::rule< Iterator > spheroidName
Definition: WKTParser.h:382
qi::rule< Iterator, ascii::space_type > ez
Definition: WKTParser.h:364
A class that implements the Grammar Rules for well known text (WKT) format for Spatial Reference Syst...
Definition: WKTActions.h:53
qi::rule< Iterator, ascii::space_type > dy
Definition: WKTParser.h:364
qi::rule< Iterator > parameterName
Definition: WKTParser.h:382
qi::rule< Iterator > projectionName
Definition: WKTParser.h:382
qi::rule< Iterator, ascii::space_type > unitTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > projectionTag
Definition: WKTParser.h:356
void setEx(const double &ex)
void createGeographicCoordinateSystem()
qi::rule< Iterator > authorityName
Definition: WKTParser.h:386
A Spatial Reference System, also known as a Coordinate System.
qi::rule< Iterator, ascii::space_type > geographicCS
Definition: WKTParser.h:354
qi::rule< Iterator, ascii::space_type > ex
Definition: WKTParser.h:364
void setUnitName(const std::string &name)
void initDoubleValues()
Definition: WKTParser.h:262
qi::rule< Iterator, ascii::space_type > spheroid
Definition: WKTParser.h:370
qi::rule< Iterator > csName
Definition: WKTParser.h:382
SpatialReferenceSystem * getSRS()
It returns the SRS generated by the parser process.
void setPPM(const double &ppm)
void initSpatialReferenceSystems()
Definition: WKTParser.h:126
void setEz(const double &ez)
void initAuthority()
Definition: WKTParser.h:288
qi::rule< Iterator, ascii::space_type > datum
Definition: WKTParser.h:360
void setDx(const double &dx)
qi::rule< Iterator, ascii::space_type > rigthDelimiter
Definition: WKTParser.h:388
void setProjectionName(const std::string &name)
SpatialReferenceSystem * getSRS()
It returns the SRS generated by the parser process.
Definition: WKTParser.h:332
void setDy(const double &dy)
A class that implements the Grammar Rules for well known text (WKT) format of Spatial Reference Syste...
Definition: WKTParser.h:64
void initQuotedNames()
Definition: WKTParser.h:223
qi::rule< Iterator, ascii::space_type > primeMeridianTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > authority
Definition: WKTParser.h:384
qi::rule< Iterator, ascii::space_type > value
Definition: WKTParser.h:380
URI C++ Library.
qi::rule< Iterator > unitName
Definition: WKTParser.h:382
qi::rule< Iterator, ascii::space_type > southTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > eastTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > projectedCS
Definition: WKTParser.h:354
qi::rule< Iterator, ascii::space_type > axisValue
Definition: WKTParser.h:378
qi::rule< Iterator, ascii::space_type > leftDelimiter
Definition: WKTParser.h:388
void reset()
This method resets the Parser to original state.
Definition: WKTParser.h:342
qi::rule< Iterator, ascii::space_type > toWGS84
Definition: WKTParser.h:362
void setDatumName(const std::string &name)
qi::rule< Iterator, ascii::space_type > ey
Definition: WKTParser.h:364
qi::rule< Iterator, ascii::space_type > datumTag
Definition: WKTParser.h:356
void setAxisName(const std::string &name)
qi::rule< Iterator, ascii::space_type > westTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > conversionFactor
Definition: WKTParser.h:380
void setSemiMajorAxis(const double &rad)
qi::rule< Iterator, ascii::space_type > unit
Definition: WKTParser.h:374
void initPrimeMeridian()
Definition: WKTParser.h:205
qi::rule< Iterator, ascii::space_type > axisTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > spheroidTag
Definition: WKTParser.h:356
qi::rule< Iterator > primeMeridianName
Definition: WKTParser.h:382
qi::rule< Iterator, ascii::space_type > parameter
Definition: WKTParser.h:368
qi::rule< Iterator, ascii::space_type > axis
Definition: WKTParser.h:376
qi::rule< Iterator, ascii::space_type > dz
Definition: WKTParser.h:364
void initDelimiters()
Definition: WKTParser.h:312
qi::rule< Iterator, ascii::space_type > semiMajorAxis
Definition: WKTParser.h:380
void setParameter(const std::string &name)
qi::rule< Iterator, ascii::space_type > primeMeridian
Definition: WKTParser.h:372
qi::rule< Iterator, ascii::space_type > sevenParams
Definition: WKTParser.h:362
qi::rule< Iterator, ascii::space_type > ppm
Definition: WKTParser.h:364
qi::rule< Iterator > axisName
Definition: WKTParser.h:382
void endGeographicCoordinateSystem()
void setName(const std::string &name)
qi::rule< Iterator, ascii::space_type > geographicCSTag
Definition: WKTParser.h:356
void setParameterValue(const double &value)
qi::rule< Iterator, ascii::space_type > toWGS84Tag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > authorityTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > parameterTag
Definition: WKTParser.h:356
qi::rule< Iterator, ascii::space_type > dx
Definition: WKTParser.h:364
void setEy(const double &ey)
void setDz(const double &dz)
qi::rule< Iterator, ascii::space_type > northTag
Definition: WKTParser.h:356
void createProjectedCoordinateSystem()
void setAuthorityCode(const std::string &code)
void setInverseFlattening(const double &invflat)
qi::rule< Iterator, ascii::space_type > longitude
Definition: WKTParser.h:380
qi::rule< Iterator, ascii::space_type > otherTag
Definition: WKTParser.h:356