All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
AbstractOp.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/fe/serialization/xml/AbstractOp.cpp
22 
23  \brief Auxiliary classes and functions to serialize filter operations from a XML document.
24 */
25 
26 // TerraLib
27 #include "../../../common/Translator.h"
28 #include "../../../fe/BBOXOp.h"
29 #include "../../../fe/BinaryComparisonOp.h"
30 #include "../../../fe/BinaryLogicOp.h"
31 #include "../../../fe/BinarySpatialOp.h"
32 #include "../../../fe/DistanceBuffer.h"
33 #include "../../../fe/Globals.h"
34 #include "../../../fe/Literal.h"
35 #include "../../../fe/PropertyIsBetween.h"
36 #include "../../../fe/PropertyIsLike.h"
37 #include "../../../fe/PropertyIsNull.h"
38 #include "../../../fe/PropertyName.h"
39 #include "../../../fe/UnaryLogicOp.h"
40 #include "../../../xml/AbstractWriter.h"
41 #include "../../../xml/Reader.h"
42 #include "../../Exception.h"
43 #include "AbstractOp.h"
44 #include "Expression.h"
45 
46 // STL
47 #include <cassert>
48 
49 // Boost
50 #include <boost/format.hpp>
51 
52 
53 /* @name AbstractOp Reader Methods */
54 //@{
55 
56 te::fe::AbstractOp* BinaryComparsionOpReader(const char* opName, te::xml::Reader& reader);
57 
58 te::fe::AbstractOp* BetweenReader(const char* opName, te::xml::Reader& reader);
59 te::fe::AbstractOp* LikeReader(const char* opName, te::xml::Reader& reader);
60 te::fe::AbstractOp* NullReader(const char* opName, te::xml::Reader& reader);
61 
62 te::fe::AbstractOp* BinaryLogicOpReader(const char* opName, te::xml::Reader& reader);
63 te::fe::AbstractOp* UnaryLogicOpReader(const char* opName, te::xml::Reader& reader);
64 
65 te::fe::AbstractOp* BinarySpatialOpReader(const char* opName, te::xml::Reader& reader);
66 te::fe::AbstractOp* DistanceBufferReader(const char* opName, te::xml::Reader& reader);
67 te::fe::AbstractOp* BBOXReader(const char* opName, te::xml::Reader& reader);
68 
69 //@}
70 
71 /* @name AbstractOp Writer Methods */
72 //@{
73 
75 
79 
82 
86 
87 //@}
88 
89 std::string GetQualifiedName(const te::fe::AbstractOp* op)
90 {
91  std::string name = "ogc:";
92  name += op->getName();
93  return name;
94 }
95 
96 void te::fe::serialize::AbstractOp::reg(const std::string& opName, const AbstractOpFnctSerializeType& fncts)
97 {
98  m_fncts[opName] = fncts;
99 }
100 
102 {
103  std::string opName = reader.getElementLocalName();
104 
105  AbstractOpFnctIdxType::const_iterator it = m_fncts.find(opName);
106 
107  if(it == m_fncts.end())
108  throw Exception((boost::format(TE_TR("Could not find a reader for the following operator type: %1%.")) % opName).str());
109 
110  assert(it->second.second);
111 
112  return it->second.first(m_names.find(opName)->second, reader);
113 }
114 
116 {
117  assert(op);
118 
119  AbstractOpFnctIdxType::const_iterator it = m_fncts.find(op->getName());
120 
121  if(it == m_fncts.end())
122  throw Exception((boost::format(TE_TR("Could not find a writer for the following operator type: %1%.")) % op->getName()).str());
123 
124  assert(it->second.second);
125 
126  return it->second.second(op, writer);
127 }
128 
130 {
131 }
132 
134 {
135  // BinaryComparisonOp
142 
143  // IsBetween
145 
146  // IsLike
148 
149  // Null
151 
152  // BinaryLogicOp
155 
156  // UnaryLogicOp
158 
159  // BBOX
161 
162  // Binary SpatialOp
171 
172  // DistanceBuffer
175 
176  // string to char*
200 }
201 
203 {
204  assert(reader.getNodeType() == te::xml::START_ELEMENT);
205  assert(reader.getElementLocalName() == opName);
206 
207  std::auto_ptr<te::fe::BinaryComparisonOp> op(new te::fe::BinaryComparisonOp(opName));
208 
209  reader.next();
210 
211  op->setFirst( te::fe::serialize::Expression::getInstance().read(reader));
212 
213  op->setSecond( te::fe::serialize::Expression::getInstance().read(reader));
214 
215  assert(reader.getNodeType() == te::xml::END_ELEMENT);
216  reader.next();
217 
218  return op.release();
219 }
220 
221 te::fe::AbstractOp* BetweenReader(const char* opName, te::xml::Reader& reader)
222 {
223  assert(reader.getNodeType() == te::xml::START_ELEMENT);
225 
226  std::auto_ptr<te::fe::PropertyIsBetween> op(new te::fe::PropertyIsBetween);
227 
228  reader.next();
229 
230  op->setExpression(te::fe::serialize::Expression::getInstance().read(reader));
231 
232  op->setLowerBoundary(te::fe::serialize::Expression::getInstance().read(reader));
233 
234  op->setUpperBoundary(te::fe::serialize::Expression::getInstance().read(reader));
235 
236  assert(reader.getNodeType() == te::xml::END_ELEMENT);
237  reader.next();
238 
239  return op.release();
240 }
241 
242 te::fe::AbstractOp* LikeReader(const char* opName, te::xml::Reader& reader)
243 {
244  assert(reader.getNodeType() == te::xml::START_ELEMENT);
246  assert(reader.hasAttrs());
247 
248  std::auto_ptr<te::fe::PropertyIsLike> op(new te::fe::PropertyIsLike);
249 
250  std::string wildCard = reader.getAttr("wildCard");
251  assert(!wildCard.empty());
252  op->setWildCard(wildCard);
253 
254  std::string singleChar = reader.getAttr("singleChar");
255  assert(!singleChar.empty());
256  op->setSingleChar(singleChar);
257 
258  std::string escapeChar = reader.getAttr("escapeChar");
259  assert(!escapeChar.empty());
260  op->setEscapeChar(escapeChar);
261 
262  reader.next();
263 
264  assert(reader.getNodeType() == te::xml::START_ELEMENT);
265  assert(reader.getElementLocalName() == "PropertyName");
266 
267  op->setPropertyName(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
268 
269  assert(reader.getNodeType() == te::xml::START_ELEMENT);
270  assert(reader.getElementLocalName() == "Literal");
271 
272  op->setLiteral(static_cast<te::fe::Literal*>(te::fe::serialize::Expression::getInstance().read(reader)));
273 
274  assert(reader.getNodeType() == te::xml::END_ELEMENT);
275  reader.next();
276 
277  return op.release();
278 }
279 
280 te::fe::AbstractOp* NullReader(const char* opName, te::xml::Reader& reader)
281 {
282  assert(reader.getNodeType() == te::xml::START_ELEMENT);
284 
285  std::auto_ptr<te::fe::PropertyIsNull> op(new te::fe::PropertyIsNull);
286 
287  reader.next();
288 
289  assert(reader.getNodeType() == te::xml::START_ELEMENT);
290  assert(reader.getElementLocalName() == "PropertyName");
291 
292  op->setPropertyName(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
293 
294  assert(reader.getNodeType() == te::xml::END_ELEMENT);
295  reader.next();
296 
297  return op.release();
298 }
299 
301 {
302  assert(reader.getNodeType() == te::xml::START_ELEMENT);
303  assert(reader.getElementLocalName() == opName);
304 
305  std::auto_ptr<te::fe::BinaryLogicOp> op(new te::fe::BinaryLogicOp(opName));
306 
307  reader.next();
308 
309  // TODO: The BinaryLogicOp has a set of AbstractOp's. I don't know how to do this. The Reader never tells about END_ELEMENT's?
310  /*while(reader.getNodeType() != te::xml::END_ELEMENT)
311  op->add(te::serialize::AbstractOp::getInstance().read(reader));*/
312 
313  // So, for while, read only two AbstractOp's...
314  op->add(te::fe::serialize::AbstractOp::getInstance().read(reader));
315  op->add(te::fe::serialize::AbstractOp::getInstance().read(reader));
316 
317  assert(reader.getNodeType() == te::xml::END_ELEMENT);
318  reader.next();
319 
320  return op.release();
321 }
322 
324 {
325  assert(reader.getNodeType() == te::xml::START_ELEMENT);
326  assert(reader.getElementLocalName() == te::fe::Globals::sm_not);
327 
328  std::auto_ptr<te::fe::UnaryLogicOp> op(new te::fe::UnaryLogicOp(opName));
329 
330  reader.next();
331 
332  op->setOp(te::fe::serialize::AbstractOp::getInstance().read(reader));
333 
334  assert(reader.getNodeType() == te::xml::END_ELEMENT);
335  reader.next();
336 
337  return op.release();
338 }
339 
341 {
342  assert(reader.getNodeType() == te::xml::START_ELEMENT);
343  assert(reader.getElementLocalName() == opName);
344 
345  std::auto_ptr<te::fe::BinarySpatialOp> op(new te::fe::BinarySpatialOp(opName));
346 
347  reader.next();
348 
349  assert(reader.getNodeType() == te::xml::START_ELEMENT);
350  assert(reader.getElementLocalName() == "PropertyName");
351 
352  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
353 
354  // TODO: read Envelope or Geometry!
355  // op->setGeometry(...);
356  // op->setEnvelope(...);
357 
358  assert(reader.getNodeType() == te::xml::END_ELEMENT);
359  reader.next();
360 
361  return op.release();
362 }
363 
365 {
366  assert(reader.getNodeType() == te::xml::START_ELEMENT);
367  assert(reader.getElementLocalName() == opName);
368 
369  std::auto_ptr<te::fe::DistanceBuffer> op(new te::fe::DistanceBuffer(opName));
370 
371  reader.next();
372 
373  assert(reader.getNodeType() == te::xml::START_ELEMENT);
374  assert(reader.getElementLocalName() == "PropertyName");
375 
376  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
377 
378  // TODO: read geom and distance!
379  // op->setGeometry(...);
380  // op->setDistance(...);
381 
382  assert(reader.getNodeType() == te::xml::END_ELEMENT);
383  reader.next();
384 
385  return op.release();
386 }
387 
388 te::fe::AbstractOp* BBOXReader(const char* opName, te::xml::Reader& reader)
389 {
390  assert(reader.getNodeType() == te::xml::START_ELEMENT);
391  assert(reader.getElementLocalName() == te::fe::Globals::sm_bbox);
392 
393  std::auto_ptr<te::fe::BBOXOp> op(new te::fe::BBOXOp);
394 
395  reader.next();
396 
397  assert(reader.getNodeType() == te::xml::START_ELEMENT);
398  assert(reader.getElementLocalName() == "PropertyName");
399 
400  op->setProperty(static_cast<te::fe::PropertyName*>(te::fe::serialize::Expression::getInstance().read(reader)));
401 
402  // TODO: read envelope !
403  // op->setEnvelope(...);
404 
405  assert(reader.getNodeType() == te::xml::END_ELEMENT);
406  reader.next();
407 
408  return op.release();
409 }
410 
412 {
413  const te::fe::BinaryComparisonOp* binaryOp = dynamic_cast<const te::fe::BinaryComparisonOp*>(op);
414 
415  if(binaryOp == 0)
416  return;
417 
419 
420  te::fe::serialize::Expression::getInstance().write(binaryOp->getFirst(), writer);
421 
422  te::fe::serialize::Expression::getInstance().write(binaryOp->getSecond(), writer);
423 
424  writer.writeEndElement(GetQualifiedName(op));
425 }
426 
428 {
429  const te::fe::PropertyIsBetween* between = dynamic_cast<const te::fe::PropertyIsBetween*>(op);
430 
431  if(between == 0)
432  return;
433 
435 
436  te::fe::serialize::Expression::getInstance().write(between->getExpression(), writer);
437 
439 
441 
442  writer.writeEndElement(GetQualifiedName(op));
443 }
444 
446 {
447  const te::fe::PropertyIsLike* like = dynamic_cast<const te::fe::PropertyIsLike*>(op);
448 
449  if(like == 0)
450  return;
451 
453 
454  // Attributes
455  std::string wildCard = like->getWildCard();
456  assert(!wildCard.empty());
457 
458  std::string singleChar = like->getSingleChar();
459  assert(!singleChar.empty());
460 
461  std::string escapeChar = like->getEscapeChar();
462  assert(!escapeChar.empty());
463 
464  writer.writeAttribute("wildCard", wildCard);
465  writer.writeAttribute("singleChar", singleChar);
466  writer.writeAttribute("escapeChar", escapeChar);
467 
469 
471 
472  writer.writeEndElement(GetQualifiedName(op));
473 }
474 
476 {
477  const te::fe::PropertyIsNull* isNull = dynamic_cast<const te::fe::PropertyIsNull*>(op);
478 
479  if(isNull == 0)
480  return;
481 
483 
485 
486  writer.writeEndElement(GetQualifiedName(op));
487 }
488 
490 {
491  const te::fe::BinaryLogicOp* binaryLogicOp = dynamic_cast<const te::fe::BinaryLogicOp*>(op);
492 
493  if(binaryLogicOp == 0)
494  return;
495 
497 
498  assert(binaryLogicOp->size() >= 2);
499 
500  for(std::size_t i = 0; i < binaryLogicOp->size(); ++i)
501  te::fe::serialize::AbstractOp::getInstance().write(binaryLogicOp->getOp(i), writer);
502 
503  writer.writeEndElement(GetQualifiedName(op));
504 }
505 
507 {
508  const te::fe::UnaryLogicOp* unaryLogicOp = dynamic_cast<const te::fe::UnaryLogicOp*>(op);
509 
510  if(unaryLogicOp == 0)
511  return;
512 
514 
515  te::fe::serialize::AbstractOp::getInstance().write(unaryLogicOp->getOp(), writer);
516 
517  writer.writeEndElement(GetQualifiedName(op));
518 }
519 
521 {
522  const te::fe::BinarySpatialOp* binarySpatialOp = dynamic_cast<const te::fe::BinarySpatialOp*>(op);
523 
524  if(binarySpatialOp == 0)
525  return;
526 
528 
529  te::fe::serialize::Expression::getInstance().write(binarySpatialOp->getProperty(), writer);
530 
531  // Envelope || Geometry
532  //te::gml::Envelope* env = binarySpatialOp->getEnvelope();
533  //te::gm::Geometry* geom = binarySpatialOp->getGeometry();
534 
535  // TODO: write Envelope or Geometry!
536 
537  writer.writeEndElement(GetQualifiedName(op));
538 }
539 
541 {
542  const te::fe::DistanceBuffer* db = dynamic_cast<const te::fe::DistanceBuffer*>(op);
543 
544  if(db == 0)
545  return;
546 
548 
550 
551  te::gm::Geometry* geom = db->getGeometry();
552  assert(geom);
553 
555  assert(d);
556 
557  // TODO: write geom and distance!
558 
559  writer.writeEndElement(GetQualifiedName(op));
560 }
561 
563 {
564  const te::fe::BBOXOp* bbox = dynamic_cast<const te::fe::BBOXOp*>(op);
565 
566  if(bbox == 0)
567  return;
568 
570 
572 
573  te::gml::Envelope* env = bbox->getEnvelope();
574  assert(env);
575 
576  // TODO: write envelope !
577 
578  writer.writeEndElement(GetQualifiedName(op));
579 }
void BinaryLogicOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:489
static const char * sm_propertyIsLessThan
Definition: Globals.h:54
static const char * sm_touches
Definition: Globals.h:76
void UnaryLogicOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:506
const char * getName() const
It returns the operator name.
Definition: AbstractOp.h:82
te::fe::AbstractOp * DistanceBufferReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:364
te::gm::Geometry * getGeometry() const
It returns the geometry.
te::common::Distance * getDistance() const
It returns the distance.
static const char * sm_dWithin
Definition: Globals.h:83
PropertyName * getPropertyName() const
It returns the property name.
Distance buffer operator.
static const char * sm_contains
Definition: Globals.h:81
This class models a XML reader object.
Definition: Reader.h:55
void write(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer) const
Definition: AbstractOp.cpp:115
boost::function< te::fe::AbstractOp *(const char *opName, te::xml::Reader &)> AbstractOpReadFnctType
Definition: AbstractOp.h:60
te::fe::AbstractOp * BinaryLogicOpReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:300
virtual void writeStartElement(const std::string &qName)=0
static const char * sm_propertyIsGreaterThanOrEqualTo
Definition: Globals.h:57
static const char * sm_propertyIsGreaterThan
Definition: Globals.h:55
static const char * sm_crosses
Definition: Globals.h:79
static const char * sm_or
Definition: Globals.h:63
boost::function< void(const te::fe::AbstractOp *, te::xml::AbstractWriter &)> AbstractOpWriteFnctType
Definition: AbstractOp.h:61
A convenient and more compact way of encoding the very common bounding box constraint based on an env...
Definition: BBOXOp.h:71
PropertyName * getPropertyName() const
It returns the property name.
const std::string & getWildCard() const
It returns the wild character.
static const char * sm_intersects
Definition: Globals.h:80
A class for binary spatial operators.
te::fe::AbstractOp * BetweenReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:221
static const char * sm_disjoint
Definition: Globals.h:75
The PropertyIsBetween element is defined as a compact way of encoding a range check.
static const char * sm_within
Definition: Globals.h:77
This class models a XML writer object.
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:347
PropertyName * getProperty() const
It returns the property name.
std::size_t size() const
It returns the number of operands.
static const char * sm_propertyIsEqualTo
Definition: Globals.h:52
A logical operator that can be used to combine one conditional expressions.
Definition: UnaryLogicOp.h:46
The PropertyIsNull class encodes an operator that checks to see if the value of its content is NULL...
AbstractOpFnctIdxType m_fncts
Definition: AbstractOp.h:79
virtual std::string getElementLocalName() const =0
It returns the local part of the element name in the case of an element node.
te::gml::Envelope * getEnvelope() const
It returns the envelope.
Definition: BBOXOp.cpp:62
Literal * getLiteral() const
It returns the literal value.
static const char * sm_propertyIsLike
Definition: Globals.h:58
const std::string & getSingleChar() const
It returns the single wild character.
te::fe::AbstractOp * UnaryLogicOpReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:323
void BinarySpatialOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:520
Expression * getUpperBoundary() const
It returns the upper boundary expression.
static const char * sm_propertyIsNotEqualTo
Definition: Globals.h:53
It is intended to encode a character string comparison operator with pattern matching.
static T & getInstance()
It returns a reference to the singleton instance.
Definition: Singleton.h:120
PropertyName * getProperty() const
It returns the property name.
static const char * sm_beyond
Definition: Globals.h:84
AbstractOp * getOp(std::size_t i) const
It returns a specified operand.
void BetweenWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:427
Expression * getSecond() const
It returns the second operand.
const std::string & getEscapeChar() const
It returns the escape character.
te::fe::AbstractOp * NullReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:280
std::string GetQualifiedName(const te::fe::AbstractOp *op)
Definition: AbstractOp.cpp:89
AbstractOp * getOp() const
It returns the operand.
virtual std::string getAttr(const std::string &name) const =0
It returns the attribute value in the case of an element node with valid attributes.
void BBOXWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:562
Envelope defines an extent using a pair of positions defining opposite corners in arbitrary dimension...
Definition: Envelope.h:52
std::pair< AbstractOpReadFnctType, AbstractOpWriteFnctType > AbstractOpFnctSerializeType
Definition: AbstractOp.h:62
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
Definition: Geometry.h:73
static const char * sm_propertyIsNull
Definition: Globals.h:59
An abstract interface for operators.
Definition: AbstractOp.h:47
Auxiliary classes and functions to serialize filter operations from a XML document.
PropertyName * getProperty() const
It returns the property name.
Definition: BBOXOp.cpp:51
A class for binary comparison operators.
static const char * sm_and
Definition: Globals.h:62
te::fe::AbstractOp * BinaryComparsionOpReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:202
virtual void writeAttribute(const std::string &attName, const std::string &value)=0
virtual NodeType getNodeType() const =0
It return the type of node read.
te::fe::AbstractOp * LikeReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:242
static const char * sm_equals
Definition: Globals.h:74
virtual void writeEndElement(const std::string &qName)=0
A logical operator can be used to combine two or more conditional expressions.
Definition: BinaryLogicOp.h:58
void LikeWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:445
void BinaryComparsionOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:411
void reg(const std::string &opName, const AbstractOpFnctSerializeType &fncts)
Definition: AbstractOp.cpp:96
static const char * sm_overlaps
Definition: Globals.h:78
Auxiliary classes and functions to serialize filter expressions from a XML document.
static const char * sm_not
Definition: Globals.h:65
Expression * getFirst() const
It returns the first operand.
te::fe::AbstractOp * BinarySpatialOpReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:340
virtual bool hasAttrs() const =0
It tells if the element has attributes in the case of an element node.
void NullWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:475
static const char * sm_propertyIsBetween
Definition: Globals.h:60
static const char * sm_bbox
Definition: Globals.h:72
virtual bool next()=0
It gets the next event to be read.
Expression * getLowerBoundary() const
It returns the lower boundary expression.
void DistanceBufferOpWriter(const te::fe::AbstractOp *op, te::xml::AbstractWriter &writer)
Definition: AbstractOp.cpp:540
static const char * sm_propertyIsLessThanOrEqualTo
Definition: Globals.h:56
te::fe::AbstractOp * read(te::xml::Reader &reader) const
Definition: AbstractOp.cpp:101
Expression * getExpression() const
It returns the between expression.
A given distance has a measurement and a unit-of-measure.
Definition: Distance.h:44
te::fe::AbstractOp * BBOXReader(const char *opName, te::xml::Reader &reader)
Definition: AbstractOp.cpp:388