geometry/Geometry.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/geometry/Geometry.cpp
22 
23  \brief Geometry is the root class of the geometries hierarchy, it follows OGC Simple Feature Specification - SFS (Simple Feature Access - Part 1: Common Architecture) and ISO SQL/MM Spatial.
24 */
25 
26 // TerraLib
27 #include "../common/Globals.h"
28 #include "../core/translator/Translator.h"
29 #include "../datatype/Enums.h"
30 #include "Envelope.h"
31 #include "Exception.h"
32 #include "Geometry.h"
33 #include "GEOSReader.h"
34 #include "GEOSWriter.h"
35 #include "Utils.h"
36 #include "WKTReader.h"
37 #include "WKTWriter.h"
38 #include "WKBSize.h"
39 #include "WKBWriter.h"
40 
41 // STL
42 #include <cassert>
43 #include <cstring>
44 #include <memory>
45 #include <sstream>
46 
47 #ifdef TERRALIB_GEOS_ENABLED
48 // GEOS
49 #include <geos/geom/Geometry.h>
50 #include <geos/geom/IntersectionMatrix.h>
51 #include <geos/geom/Point.h>
52 #include <geos/operation/buffer/OffsetCurveBuilder.h>
53 #include <geos/operation/union/CascadedPolygonUnion.h>
54 #include <geos/util/GEOSException.h>
55 #endif
56 
57 std::map<std::string, te::gm::GeomType> te::gm::Geometry::sm_geomTypeMap;
58 
60  : m_gType(t),
61  m_srid(srid),
62  m_mbr(mbr)
63 {
64 }
65 
67  : m_gType(rhs.m_gType),
68  m_srid(rhs.m_srid),
69  m_mbr(nullptr)
70 {
71 }
72 
74 {
75  delete m_mbr;
76 }
77 
79 {
80  if(this != &rhs)
81  {
82  m_gType = rhs.m_gType;
83 
84  m_srid = rhs.m_srid;
85 
86  delete m_mbr;
87 
88  m_mbr = rhs.m_mbr ? new Envelope(*rhs.m_mbr) : nullptr;
89  }
90 
91  return *this;
92 }
93 
95 {
96  return GetCoordDimension(m_gType);
97 }
98 
100 {
101  return GetGeomFromEnvelope(getMBR(), m_srid);
102 }
103 
105 {
106  if(m_mbr == nullptr)
107  computeMBR(true);
108 
109  return m_mbr;
110 }
111 
112 std::string te::gm::Geometry::asText() const _NOEXCEPT_OP(true)
113 {
114  std::stringstream stream(std::ios_base::in | std::ios_base::out);
115 
116  stream.precision(18);
117 
118  WKTWriter::write(this, stream);
119 
120  return stream.str();
121 }
122 
123 char* te::gm::Geometry::asBinary(std::size_t& size) const _NOEXCEPT_OP(false)
124 {
125  size = WKBSize::size(this);
126 
127  char* wkb = new char[size];
128 
130 
131  return wkb;
132 }
133 
135 {
136  return WKBSize::size(this);
137 }
138 
140 {
141  WKBWriter::write(this, wkb, byteOrder);
142 }
143 
145 {
146 #ifdef TERRALIB_GEOS_ENABLED
147  try
148  {
149  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
150 
151  return g->isEmpty();
152  }
153  catch(geos::util::GEOSException& e)
154  {
155  throw te::common::Exception(e.what());
156  }
157 #else
158  throw Exception(TE_TR("isEmpty routine is supported by GEOS! Please, enable the GEOS support."));
159 #endif
160 }
161 
163 {
164 #ifdef TERRALIB_GEOS_ENABLED
165  try
166  {
167  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
168 
169  return g->isSimple();
170  }
171  catch(geos::util::GEOSException& e)
172  {
173  throw te::common::Exception(e.what());
174  }
175 #else
176  throw Exception(TE_TR("isSimple routine is supported by GEOS! Please, enable the GEOS support."));
177 #endif
178 }
179 
181 {
182 #ifdef TERRALIB_GEOS_ENABLED
183  try
184  {
185  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
186 
187  return g->isValid();
188  }
189  catch(const geos::util::GEOSException& e)
190  {
191  throw te::common::Exception(e.what());
192  }
193 #else
194  throw Exception(TE_TR("isValid routine is supported by GEOS! Please, enable the GEOS support."));
195 #endif
196 }
197 
199 {
200  if((m_gType & 0xF00) == 0xB00) // it is zm
201  return true;
202 
203  if((m_gType & 0x0F00) == 0x300) // it is z
204  return true;
205 
206  return false; // it is 2D or M
207 }
208 
210 {
211  if((m_gType & 0xF00) == 0xB00) // it is zm
212  return true;
213 
214  if((m_gType & 0xF00) == 0x700) // it is m
215  return true;
216 
217  return false; // it is 2D or z
218 }
219 
221 {
222  te::gm::GeomType gType = this->get2DGeomTypeId();
223 
224  switch (gType)
225  {
231  return true;
232  default:
233  return false;
234  }
235 }
236 
238 {
239 #ifdef TERRALIB_GEOS_ENABLED
240  try
241  {
242  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
243 
244  std::unique_ptr<geos::geom::Geometry> b(g->getBoundary());
245 
246  return GEOSReader::read(b.get());
247  }
248  catch(geos::util::GEOSException& e)
249  {
250  throw te::common::Exception(e.what());
251  }
252 #else
253  throw te::common::Exception(TE_TR("getBoundary routine is supported by GEOS! Please, enable the GEOS support."));
254 #endif
255 }
256 
258 {
259  te::gm::Coord2D coord2d;
260 
261 #ifdef TERRALIB_GEOS_ENABLED
262  try
263  {
264  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
265 
266  std::unique_ptr<geos::geom::Point> point(thisGeom->getCentroid());
267 
268  coord2d.x = point->getX();
269  coord2d.y = point->getY();
270  }
271  catch(geos::util::GEOSException& e)
272  {
273  throw te::common::Exception(e.what());
274  }
275 #else
276  throw te::common::Exception(TE_TR("getCentroid routine is supported by GEOS! Please, enable the GEOS support."));
277 #endif
278 
279  return coord2d;
280 }
281 
282 bool te::gm::Geometry::equals(const Geometry* const rhs, const bool exact) const _NOEXCEPT_OP(false)
283 {
284 #ifdef TERRALIB_GEOS_ENABLED
285  if( m_srid != rhs->m_srid )
286  {
287  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
288  }
289 
290  try
291  {
292  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
293 
294  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
295 
296  if(exact == true)
297  return thisGeom->equalsExact(rhsGeom.get());
298  else
299  return thisGeom->equals(rhsGeom.get());
300  }
301  catch(geos::util::GEOSException& e)
302  {
303  throw te::common::Exception(e.what());
304  }
305 #else
306  throw te::common::Exception(TE_TR("equals routine is supported by GEOS! Please, enable the GEOS support."));
307 #endif
308 }
309 
310 bool te::gm::Geometry::disjoint(const Geometry* const rhs) const _NOEXCEPT_OP(false)
311 {
312 #ifdef TERRALIB_GEOS_ENABLED
313  if( m_srid != rhs->m_srid )
314  {
315  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
316  }
317 
318  try
319  {
320  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
321 
322  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
323 
324  return thisGeom->disjoint(rhsGeom.get());
325  }
326  catch(geos::util::GEOSException& e)
327  {
328  throw te::common::Exception(e.what());
329  }
330 #else
331  throw te::common::Exception(TE_TR("disjoint routine is supported by GEOS! Please, enable the GEOS support."));
332 #endif
333 }
334 
335 bool te::gm::Geometry::intersects(const Geometry* const rhs) const _NOEXCEPT_OP(false)
336 {
337 #ifdef TERRALIB_GEOS_ENABLED
338  if( m_srid != rhs->m_srid )
339  {
340  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
341  }
342 
343  try
344  {
345  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
346 
347  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
348 
349  return thisGeom->intersects(rhsGeom.get());
350  }
351  catch(geos::util::GEOSException& e)
352  {
353  throw te::common::Exception(e.what());
354  }
355 
356 #else
357  throw te::common::Exception(TE_TR("intersects routine is supported by GEOS! Please, enable the GEOS support."));
358 #endif
359 }
360 
361 bool te::gm::Geometry::touches(const Geometry* const rhs) const _NOEXCEPT_OP(false)
362 {
363 #ifdef TERRALIB_GEOS_ENABLED
364  if( m_srid != rhs->m_srid )
365  {
366  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
367  }
368 
369  try
370  {
371  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
372 
373  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
374 
375  return thisGeom->touches(rhsGeom.get());
376  }
377  catch(geos::util::GEOSException& e)
378  {
379  throw te::common::Exception(e.what());
380  }
381 #else
382  throw te::common::Exception(TE_TR("touches routine is supported by GEOS! Please, enable the GEOS support."));
383 #endif
384 }
385 
386 bool te::gm::Geometry::crosses(const Geometry* const rhs) const _NOEXCEPT_OP(false)
387 {
388 #ifdef TERRALIB_GEOS_ENABLED
389  if( m_srid != rhs->m_srid )
390  {
391  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
392  }
393 
394  try
395  {
396  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
397 
398  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
399 
400  return thisGeom->crosses(rhsGeom.get());
401  }
402  catch(geos::util::GEOSException& e)
403  {
404  throw te::common::Exception(e.what());
405  }
406 #else
407  throw te::common::Exception(TE_TR("crosses routine is supported by GEOS! Please, enable the GEOS support."));
408 #endif
409 }
410 
411 bool te::gm::Geometry::within(const Geometry* const rhs) const _NOEXCEPT_OP(false)
412 {
413 #ifdef TERRALIB_GEOS_ENABLED
414  if( m_srid != rhs->m_srid )
415  {
416  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
417  }
418 
419  try
420  {
421  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
422 
423  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
424 
425  return thisGeom->within(rhsGeom.get());
426  }
427  catch(geos::util::GEOSException& e)
428  {
429  throw te::common::Exception(e.what());
430  }
431 #else
432  throw te::common::Exception(TE_TR("within routine is supported by GEOS! Please, enable the GEOS support."));
433 #endif
434 }
435 
436 bool te::gm::Geometry::contains(const Geometry* const rhs) const _NOEXCEPT_OP(false)
437 {
438 #ifdef TERRALIB_GEOS_ENABLED
439  if( m_srid != rhs->m_srid )
440  {
441  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
442  }
443 
444  try
445  {
446  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
447 
448  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
449 
450  return thisGeom->contains(rhsGeom.get());
451  }
452  catch(geos::util::GEOSException& e)
453  {
454  throw te::common::Exception(e.what());
455  }
456 #else
457  throw te::common::Exception(TE_TR("contains routine is supported by GEOS! Please, enable the GEOS support."));
458 #endif
459 }
460 
461 bool te::gm::Geometry::overlaps(const Geometry* const rhs) const _NOEXCEPT_OP(false)
462 {
463 #ifdef TERRALIB_GEOS_ENABLED
464  if( m_srid != rhs->m_srid )
465  {
466  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
467  }
468 
469  try
470  {
471  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
472 
473  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
474 
475  return thisGeom->overlaps(rhsGeom.get());
476  }
477  catch(geos::util::GEOSException& e)
478  {
479  throw te::common::Exception(e.what());
480  }
481 #else
482  throw te::common::Exception(TE_TR("overlaps routine is supported by GEOS! Please, enable the GEOS support."));
483 #endif
484 }
485 
486 bool te::gm::Geometry::relate(const Geometry* const rhs, const std::string& matrix) const _NOEXCEPT_OP(false)
487 {
488  assert(matrix.size() == 9);
489 
490 #ifdef TERRALIB_GEOS_ENABLED
491  if( m_srid != rhs->m_srid )
492  {
493  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
494  }
495 
496  try
497  {
498  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
499 
500  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
501 
502  return thisGeom->relate(rhsGeom.get(), matrix);
503  }
504  catch(geos::util::GEOSException& e)
505  {
506  throw te::common::Exception(e.what());
507  }
508 
509 #else
510  throw te::common::Exception(TE_TR("relate routine is supported by GEOS! Please, enable the GEOS support."));
511 #endif
512 }
513 
514 std::string te::gm::Geometry::relate(const Geometry* const rhs) const _NOEXCEPT_OP(false)
515 {
516 #ifdef TERRALIB_GEOS_ENABLED
517  if( m_srid != rhs->m_srid )
518  {
519  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
520  }
521 
522  try
523  {
524  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
525 
526  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
527 
528  std::unique_ptr<geos::geom::IntersectionMatrix> m(thisGeom->relate(rhsGeom.get()));
529 
530  return m->toString();
531  }
532  catch(geos::util::GEOSException& e)
533  {
534  throw te::common::Exception(e.what());
535  }
536 #else
537  throw te::common::Exception(TE_TR("relate routine is supported by GEOS! Please, enable the GEOS support."));
538 #endif
539 }
540 
541 bool te::gm::Geometry::covers(const Geometry* const rhs) const _NOEXCEPT_OP(false)
542 {
543 #ifdef TERRALIB_GEOS_ENABLED
544  if( m_srid != rhs->m_srid )
545  {
546  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
547  }
548 
549  try
550  {
551  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
552 
553  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
554 
555  return thisGeom->covers(rhsGeom.get());
556  }
557  catch(geos::util::GEOSException& e)
558  {
559  throw te::common::Exception(e.what());
560  }
561 #else
562  throw te::common::Exception(TE_TR("covers routine is supported by GEOS! Please, enable the GEOS support."));
563 #endif
564 }
565 
566 bool te::gm::Geometry::coveredBy(const Geometry* const rhs) const _NOEXCEPT_OP(false)
567 {
568 #ifdef TERRALIB_GEOS_ENABLED
569  if( m_srid != rhs->m_srid )
570  {
571  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
572  }
573 
574  try
575  {
576  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
577 
578  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
579 
580  return thisGeom->coveredBy(rhsGeom.get());
581  }
582  catch(geos::util::GEOSException& e)
583  {
584  throw te::common::Exception(e.what());
585  }
586 #else
587  throw te::common::Exception(TE_TR("coveredBy routine is supported by GEOS! Please, enable the GEOS support."));
588 #endif
589 }
590 
591 te::gm::Geometry* te::gm::Geometry::locateBetween(const double& /*mStart*/, const double& /*mEnd*/) const _NOEXCEPT_OP(false)
592 {
593  return nullptr;
594 }
595 
596 double te::gm::Geometry::distance(const Geometry* const rhs) const _NOEXCEPT_OP(false)
597 {
598 #ifdef TERRALIB_GEOS_ENABLED
599  if( m_srid != rhs->m_srid )
600  {
601  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
602  }
603 
604  try
605  {
606  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
607 
608  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
609 
610  return thisGeom->distance(rhsGeom.get());
611  }
612  catch(geos::util::GEOSException& e)
613  {
614  throw te::common::Exception(e.what());
615  }
616 #else
617  throw te::common::Exception(TE_TR("distance routine is supported by GEOS! Please, enable the GEOS support."));
618 #endif
619 }
620 
622 {
623 #ifdef TERRALIB_GEOS_ENABLED
625 #else
626  return buffer(distance, 16, CapRoundType);
627 #endif
628 }
629 
630 te::gm::Geometry* te::gm::Geometry::buffer(const double& distance, int quadrantSegments) const _NOEXCEPT_OP(false)
631 {
632  return buffer(distance, quadrantSegments, CapRoundType);
633 }
634 
636  int quadrantSegments,
637  BufferCapStyle endCapStyle) const _NOEXCEPT_OP(false)
638 {
639 #ifdef TERRALIB_GEOS_ENABLED
640  try
641  {
642  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
643 
644  std::unique_ptr<geos::geom::Geometry> bg(g->buffer(distance, quadrantSegments, static_cast<int>(endCapStyle)));
645 
646  bg->setSRID(m_srid);
647 
648  return GEOSReader::read(bg.get());
649  }
650  catch(geos::util::GEOSException& e)
651  {
652  throw te::common::Exception(e.what());
653  }
654 #else
655  throw te::common::Exception(TE_TR("buffer routine is supported by GEOS! Please, enable the GEOS support."));
656 #endif
657 }
658 
660 {
661 #ifdef TERRALIB_GEOS_ENABLED
662  try
663  {
664  std::unique_ptr<geos::geom::Geometry> g(GEOSWriter::write(this));
665 
666  std::unique_ptr<geos::geom::Geometry> hull(g->convexHull());
667 
668  hull->setSRID(m_srid);
669 
670  return GEOSReader::read(hull.get());
671  }
672  catch(geos::util::GEOSException& e)
673  {
674  throw te::common::Exception(e.what());
675  }
676 #else
677  throw te::common::Exception(TE_TR("convexHull routine is supported by GEOS! Please, enable the GEOS support."));
678 #endif
679 }
680 
682 {
683 #ifdef TERRALIB_GEOS_ENABLED
684  if( m_srid != rhs->m_srid )
685  {
686  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
687  }
688 
689  try
690  {
691  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
692 
693  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
694 
695  std::unique_ptr<geos::geom::Geometry> intersectionGeom(thisGeom->intersection(rhsGeom.get()));
696 
697  intersectionGeom->setSRID(m_srid);
698 
699  return GEOSReader::read(intersectionGeom.get());
700  }
701  catch(geos::util::GEOSException& e)
702  {
703  throw te::common::Exception(e.what());
704  }
705 #else
706  throw te::common::Exception(TE_TR("intersection routine is supported by GEOS! Please, enable the GEOS support."));
707 #endif
708 }
709 
711 {
712 #ifdef TERRALIB_GEOS_ENABLED
713  if( m_srid != rhs->m_srid )
714  {
715  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
716  }
717 
718  try
719  {
720  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
721 
722  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
723 
724  std::unique_ptr<geos::geom::Geometry> unionGeom(thisGeom-> Union(rhsGeom.get()));
725 
726  unionGeom->setSRID(m_srid);
727 
728  return GEOSReader::read(unionGeom.get());
729  }
730  catch(geos::util::GEOSException& e)
731  {
732  throw te::common::Exception(e.what());
733  }
734 #else
735  throw te::common::Exception(TE_TR("Union routine is supported by GEOS! Please, enable the GEOS support."));
736 #endif
737 }
738 
740 {
741 #ifdef TERRALIB_GEOS_ENABLED
742  if( m_srid != rhs->m_srid )
743  {
744  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
745  }
746 
747  try
748  {
749  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
750 
751  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
752 
753  std::unique_ptr<geos::geom::Geometry> differenceGeom(thisGeom->difference(rhsGeom.get()));
754 
755  differenceGeom->setSRID(m_srid);
756 
757  return GEOSReader::read(differenceGeom.get());
758  }
759  catch(geos::util::GEOSException& e)
760  {
761  throw te::common::Exception(e.what());
762  }
763 #else
764  throw te::common::Exception(TE_TR("difference routine is supported by GEOS! Please, enable the GEOS support."));
765 #endif
766 }
767 
769 {
770 #ifdef TERRALIB_GEOS_ENABLED
771  if( m_srid != rhs->m_srid )
772  {
773  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
774  }
775 
776  try
777  {
778  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
779 
780  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
781 
782  std::unique_ptr<geos::geom::Geometry> symDifferenceGeom(thisGeom->symDifference(rhsGeom.get()));
783 
784  symDifferenceGeom->setSRID(m_srid);
785 
786  return GEOSReader::read(symDifferenceGeom.get());
787  }
788  catch(geos::util::GEOSException& e)
789  {
790  throw te::common::Exception(e.what());
791  }
792 #else
793  throw te::common::Exception(TE_TR("symDifference routine is supported by GEOS! Please, enable the GEOS support."));
794 #endif
795 }
796 
797 bool te::gm::Geometry::dWithin(const Geometry* const rhs, const double& distance) const _NOEXCEPT_OP(false)
798 {
799  assert(distance >= 0.0);
800 
801 #ifdef TERRALIB_GEOS_ENABLED
802  if( m_srid != rhs->m_srid )
803  {
804  throw te::common::Exception(TE_TR("this method must not be used with different SRIDs geometries."));
805  }
806 
807  try
808  {
809  std::unique_ptr<geos::geom::Geometry> thisGeom(GEOSWriter::write(this));
810 
811  std::unique_ptr<geos::geom::Geometry> rhsGeom(GEOSWriter::write(rhs));
812 
813  return thisGeom->isWithinDistance(rhsGeom.get(), distance);
814  }
815  catch(geos::util::GEOSException& e)
816  {
817  throw te::common::Exception(e.what());
818  }
819 #else
820  throw te::common::Exception(TE_TR("dWithin routine is supported by GEOS! Please, enable the GEOS support."));
821 #endif
822 }
823 
825 {
826  std::map<std::string, GeomType>::const_iterator it = sm_geomTypeMap.find(gtype);
827 
828  if(it != sm_geomTypeMap.end())
829  return it->second;
830 
832 }
833 
834 const std::string te::gm::Geometry::get2DGeometryType() const _NOEXCEPT_OP(true)
835 {
836  switch (m_gType)
837  {
842  return "Geometry";
843 
844  case te::gm::PointType:
845  case te::gm::PointZType:
846  case te::gm::PointMType:
847  case te::gm::PointZMType:
848  return "Point";
849 
854  return "LineString";
855 
856  case te::gm::PolygonType:
860  return "Polygon";
861 
866  return "GeometryCollection";
867 
872  return "MultiPoint";
873 
878  return "MultiLineString";
879 
884  return "MultiPolygon";
885 
890  return "CircularString";
891 
896  return "CompoundCurve";
897 
902  return "CurvePolygon";
903 
908  return "MultiSurface";
909 
910  default:
911  return "UnknownGeometry";
912  }
913 }
914 
916 {
917  switch (m_gType)
918  {
923  return te::gm::GeometryType;
924 
925  case te::gm::PointType:
926  case te::gm::PointZType:
927  case te::gm::PointMType:
928  case te::gm::PointZMType:
929  return te::gm::PointType;
930 
935  return te::gm::LineStringType;
936 
937  case te::gm::PolygonType:
941  return te::gm::PolygonType;
942 
948 
953  return te::gm::MultiPointType;
954 
960 
966 
972 
978 
984 
990 
991  default:
993  }
994 }
995 
996 std::string te::gm::Geometry::getGeomTypeString(const int& gId)
997 {
998  std::map<std::string, GeomType>::const_iterator it;
999 
1000  for (it = sm_geomTypeMap.begin(); it != sm_geomTypeMap.end(); ++it)
1001  {
1002  if (it->second == static_cast<GeomType>(gId))
1003  return it->first;
1004  }
1005 
1006  return "UNKNOWGEOMETRYTYPE";
1007 }
1008 
1009 bool te::gm::Geometry::isGeomType(const std::string& stype)
1010 {
1011  return getGeomTypeId(stype) != te::gm::UnknownGeometryType;
1012 }
1013 
1015 {
1016  if(!sm_geomTypeMap.empty())
1017  return;
1018 
1019  sm_geomTypeMap["GEOMETRY"] = te::gm::GeometryType;
1020  sm_geomTypeMap["GEOMETRYZ"] = te::gm::GeometryZType;
1021  sm_geomTypeMap["GEOMETRYM"] = te::gm::GeometryMType;
1022  sm_geomTypeMap["GEOMETRYZM"] = te::gm::GeometryZMType;
1023 
1024  sm_geomTypeMap["POINT"] = te::gm::PointType;
1025  sm_geomTypeMap["POINTM"] = te::gm::PointMType;
1026  sm_geomTypeMap["POINTZ"] = te::gm::PointZType;
1027  sm_geomTypeMap["POINTZM"] = te::gm::PointZMType;
1028 
1029  sm_geomTypeMap["LINESTRING"] = te::gm::LineStringType;
1030  sm_geomTypeMap["LINESTRINGM"] = te::gm::LineStringMType;
1031  sm_geomTypeMap["LINESTRINGZ"] = te::gm::LineStringZType;
1032  sm_geomTypeMap["LINESTRINGZM"] = te::gm::LineStringZMType;
1033 
1034  sm_geomTypeMap["POLYGON"] = te::gm::PolygonType;
1035  sm_geomTypeMap["POLYGONM"] = te::gm::PolygonMType;
1036  sm_geomTypeMap["POLYGONZ"] = te::gm::PolygonZType;
1037  sm_geomTypeMap["POLYGONZM"] = te::gm::PolygonZMType;
1038 
1039  sm_geomTypeMap["MULTIPOINT"] = te::gm::MultiPointType;
1040  sm_geomTypeMap["MULTIPOINTM"] = te::gm::MultiPointMType;
1041  sm_geomTypeMap["MULTIPOINTZ"] = te::gm::MultiPointZType;
1042  sm_geomTypeMap["MULTIPOINTZM"] = te::gm::MultiPointZMType;
1043 
1044  sm_geomTypeMap["MULTILINESTRING"] = te::gm::MultiLineStringType;
1045  sm_geomTypeMap["MULTILINESTRINGM"] = te::gm::MultiLineStringMType;
1046  sm_geomTypeMap["MULTILINESTRINGZ"] = te::gm::MultiLineStringZType;
1047  sm_geomTypeMap["MULTILINESTRINGZM"] = te::gm::MultiLineStringZMType;
1048 
1049  sm_geomTypeMap["MULTIPOLYGON"] = te::gm::MultiPolygonType;
1050  sm_geomTypeMap["MULTIPOLYGONM"] = te::gm::MultiPolygonMType;
1051  sm_geomTypeMap["MULTIPOLYGONZ"] = te::gm::MultiPolygonZType;
1052  sm_geomTypeMap["MULTIPOLYGONZM"] = te::gm::MultiPolygonZMType;
1053 
1054  sm_geomTypeMap["MULTISURFACE"] = te::gm::MultiSurfaceType;
1055  sm_geomTypeMap["MULTISURFACEM"] = te::gm::MultiSurfaceMType;
1056  sm_geomTypeMap["MULTISURFACEZ"] = te::gm::MultiSurfaceZType;
1057  sm_geomTypeMap["MULTISURFACEZM"] = te::gm::MultiSurfaceZMType;
1058 
1059  sm_geomTypeMap["GEOMETRYCOLLECTION"] = te::gm::GeometryCollectionType;
1060  sm_geomTypeMap["GEOMETRYCOLLECTIONM"] = te::gm::GeometryCollectionMType;
1061  sm_geomTypeMap["GEOMETRYCOLLECTIONZ"] = te::gm::GeometryCollectionZType;
1062  sm_geomTypeMap["GEOMETRYCOLLECTIONZM"] = te::gm::GeometryCollectionZMType;
1063 }
1064 
1066 {
1067  return te::dt::GEOMETRY_TYPE;
1068 }
1069 
virtual Geometry * difference(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns a geometric object that represents the point set difference with another geometry...
GeomType
Each enumerated type is compatible with a Well-known Binary (WKB) type code.
virtual Geometry * symDifference(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns a geometric object that represents the point set symetric difference with another geometry...
double y
y-coordinate.
Definition: Coord2D.h:114
bool isCollection() const _NOEXCEPT_OP(true)
It returns true if this geometric object is a collection.
BufferCapStyle
Buffer end cap style.
static void loadGeomTypeId()
It loads the internal MAP of geometry type names to geometry type ids.
virtual double distance(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns the shortest distance between any two points in the two geometry objects.
double x
x-coordinate.
Definition: Coord2D.h:113
Base exception class for plugin module.
virtual Geometry * buffer(const double &distance) const _NOEXCEPT_OP(false)
This method calculates the buffer of a geometry.
bool isMeasured() const _NOEXCEPT_OP(true)
It returns true if this geometric object has m coordinate values.
GeomType getGeomTypeId() const _NOEXCEPT_OP(true)
It returns the geometry subclass type identifier.
int m_srid
The Spatial Reference System code associated to the Geometry.
virtual Geometry * intersection(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns a geometric object that represents the point set intersection with another geometry...
virtual bool dWithin(const Geometry *const rhs, const double &distance) const _NOEXCEPT_OP(false)
It returns true if the geometries are within the specified distance.
static const MachineByteOrder sm_machineByteOrder
A flag that indicates the machine byte order (Big Endian or Little Endian).
virtual bool disjoint(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object is spatially disjoint from rhs geometry.
virtual bool relate(const Geometry *const rhs, const std::string &matrix) const _NOEXCEPT_OP(false)
It returns true if this geometry object is spatially related to rhs geometry according to the pattern...
static std::size_t size(const Geometry *geom)
It calculates the number of bytes required to encode the geometry in a WKB format.
Definition: WKBSize.cpp:47
#define _NOEXCEPT_OP(x)
An utility struct for representing 2D coordinates.
Definition: Coord2D.h:40
#define TE_TR(message)
It marks a string in order to get translated.
Definition: Translator.h:242
virtual Geometry * Union(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns a geometric object that represents the point set union with another geometry.
virtual bool intersects(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object spatially intersects rhs geometry.
virtual bool touches(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object spatially touches rhs geometry.
virtual bool isSimple() const _NOEXCEPT_OP(false)
It returns true if this geometric object has no anomalous points, such as self intersection or self t...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
std::size_t getWkbSize() const _NOEXCEPT_OP(true)
It returns the size required by a WKB representation for this geometric object.
int GetCoordDimension(GeomType t)
It returns the number of measurements or axes needed to describe a position in a coordinate system...
void write(const Geometry *geom)
It serializes the geometry to a WKB representation into the specified buffer.
Definition: WKBWriter.cpp:145
A class that serializes a geometry to the WKB format.
virtual bool overlaps(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if this geometry object spatially overlaps rhs geometry.
virtual Geometry * locateBetween(const double &mStart, const double &mEnd) const _NOEXCEPT_OP(false)
It returns a derived geometry collection value according to the range of coordinate values inclusivel...
te::gm::Coord2D getCentroid() const _NOEXCEPT_OP(false)
It will get the centroid of the input geometries.
Utility functions for the Geometry Module.
int b
Definition: TsRtree.cpp:32
virtual void computeMBR(bool cascade) const _NOEXCEPT_OP(true)=0
It computes the minimum bounding rectangle for the geometry.
An Envelope defines a 2D rectangular region.
Geometry * getEnvelope() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle (MBR) for the geometry.
#define TE_GEOS_DEFAULT_QUADRANT_SEGMENTS
Determines the number of default segments used to create buffers.
virtual GeomType get2DGeomTypeId() const _NOEXCEPT_OP(true)
It returns the 2D geometry subclass type identifier.
const Envelope * getMBR() const _NOEXCEPT_OP(true)
It returns the minimum bounding rectangle for the geometry in an internal representation.
virtual bool isValid() const _NOEXCEPT_OP(false)
It tells if the geometry is well formed.
An Envelope defines a 2D rectangular region.
std::string asText() const _NOEXCEPT_OP(true)
It returns an string with the Well-Known Text Representation for the geometry.
int getTypeCode() const
It returns the data type code associated to the data value.
virtual bool within(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object is spatially within rhs geometry.
void write(const Geometry *geom)
It serializes the geometry to a WKT representation.
Definition: WKTWriter.cpp:52
virtual bool isEmpty() const _NOEXCEPT_OP(false)
It returns true if this geometric object is the empty Geometry.
virtual bool contains(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if this geometry object spatially contains rhs geometry.
virtual const std::string get2DGeometryType() const _NOEXCEPT_OP(true)
It returns the name of 2D geometry subclass.
MachineByteOrder
Endianness.
virtual ~Geometry()
Virtual destructor.
bool is3D() const _NOEXCEPT_OP(true)
It returns true if this geometric object has z coordinate values.
char * asBinary(std::size_t &size) const _NOEXCEPT_OP(false)
It serializes the geometric object to a Well-known Binary Representation (WKB).
static geos::geom::Geometry * write(const Geometry *teGeom)
It reads a TerraLib geometry and make a GEOS geometry.
A class that converts a GEOS geometry to a TerraLib geometry.
This class is designed to declare objects to be thrown as exceptions by TerraLib. ...
Geometry is the root class of the geometries hierarchy, it follows OGC and ISO standards.
virtual Geometry & operator=(const Geometry &rhs) _NOEXCEPT_OP(true)
Assignment operator.
Envelope * m_mbr
The geometry minimum bounding rectangle.
A class that converts a TerraLib geometry to a GEOS geometry.
static bool isGeomType(const std::string &stype)
It tells if the given string is a geometry data type.
A class that computes the number of bytes necessary to encode a geometry in WKB.
virtual Geometry * getBoundary() const _NOEXCEPT_OP(false)
It returns the geometry boundary.
GeomType m_gType
Internal geometry type.
static std::string getGeomTypeString(const int &gId)
It returns the TerraLib geometry type string given a type id.
virtual bool crosses(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if the geometry object spatially crosses rhs geometry.
static std::map< std::string, GeomType > sm_geomTypeMap
A set of geometry type names (in UPPER CASE).
An exception class for the Geometry module.
A class that serializes a geometry to the WKT format.
int getCoordinateDimension() const _NOEXCEPT_OP(true)
It returns the number of measurements or axes needed to describe a position in a coordinate system...
A class that deserializes a geometry from a valid WKT.
virtual Geometry * convexHull() const _NOEXCEPT_OP(false)
This method calculates the Convex Hull of a geometry.
TEGEOMEXPORT Geometry * GetGeomFromEnvelope(const Envelope *const e, int srid)
It creates a Geometry (a polygon) from the given envelope.
virtual bool coveredBy(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if this geometry object is spatially covered by rhs geometry.
virtual bool equals(const Geometry *const rhs, const bool exact=false) const _NOEXCEPT_OP(false)
It returns true if the geometry object is spatially equal to rhs geometry.
Geometry(GeomType t, int srid=0, Envelope *mbr=0) _NOEXCEPT_OP(true)
It initializes the Geometry with the specified spatial reference system id and envelope.
virtual bool covers(const Geometry *const rhs) const _NOEXCEPT_OP(false)
It returns true if this geometry object spatially covers the rhs geometry.
void getWkb(char *wkb, te::common::MachineByteOrder byteOrder) const _NOEXCEPT_OP(false)
It serializes the geometry to a WKB representation into the specified buffer.