Complete Note#1 in the http://wiki.osgeo.org/wiki/GEOS_Provenance_Review to get out...
[geos.git] / doc / example.cpp
blobb0b2bb841a53a8cbc366956f134d239efbcaf98f
1 /**********************************************************************
3 * GEOS - Geometry Engine Open Source
4 * http://geos.osgeo.org
6 * Copyright (C) 2001-2002 Vivid Solutions Inc.
7 * Copyright (C) 2005 Refractions Research Inc.
9 * This is free software; you can redistribute and/or modify it under
10 * the terms of the GNU Lesser General Public Licence as published
11 * by the Free Software Foundation.
12 * See the COPYING file for more information.
14 *********************************************************************
16 * This file should document by example usage of the GEOS library.
17 * It could actually be a live discuss-by-example board for
18 * architectural design choices.
20 * --strk;
22 * DEBUGGING TIPS:
23 * use -D__USE_MALLOC at compile time for gcc 2.91, 2.95, 3.0 and 3.1
24 * and GLIBCXX_FORCE_NEW or GLIBCPP_FORCE_NEW at run time with gcc 3.2.2+
25 * to force libstdc++ avoid caching memory. This should remove some
26 * obscure reports from memory checkers like valgrind.
28 **********************************************************************/
30 #include <geos/geom/PrecisionModel.h>
31 #include <geos/geom/GeometryFactory.h>
32 #include <geos/geom/Geometry.h>
33 #include <geos/geom/Point.h>
34 #include <geos/geom/LinearRing.h>
35 #include <geos/geom/LineString.h>
36 #include <geos/geom/Polygon.h>
37 #include <geos/geom/GeometryCollection.h>
38 #include <geos/geom/Coordinate.h>
39 #include <geos/geom/CoordinateSequence.h>
40 #include <geos/geom/CoordinateArraySequence.h>
41 #include <geos/geom/IntersectionMatrix.h>
42 #include <geos/io/WKBReader.h>
43 #include <geos/io/WKBWriter.h>
44 #include <geos/io/WKTWriter.h>
45 #include <geos/util/GeometricShapeFactory.h>
46 #include <geos/geom/util/SineStarFactory.h>
47 #include <geos/util/GEOSException.h>
48 #include <geos/util/IllegalArgumentException.h>
49 #include <geos/opLinemerge.h>
50 #include <geos/opPolygonize.h>
51 #include <vector>
52 #include <sstream>
53 #include <iomanip>
54 #include <cstdlib> // exit()
56 #ifndef M_PI
57 #define M_PI 3.14159265358979323846
58 #endif
60 // Set to 0 to skip section
61 #define GEOMETRIC_SHAPES 1
62 #define RELATIONAL_OPERATORS 1
63 #define COMBINATIONS 1
64 #define UNARY_OPERATIONS 1
65 #define LINEMERGE 1
66 #define POLYGONIZE 1
69 using namespace std;
70 using namespace geos;
71 using namespace geos::geom;
72 using namespace geos::operation::polygonize;
73 using namespace geos::operation::linemerge;
74 using geos::util::GEOSException;
75 using geos::util::IllegalArgumentException;
78 // Prototypes
79 void wkt_print_geoms(vector<Geometry *> *geoms);
82 // This object will be used to construct our geometries.
83 // It might be bypassed by directly call geometry constructors,
84 // but that would be boring because you'd need to specify
85 // a PrecisionModel and a SRID everytime: those infos are
86 // cached inside a GeometryFactory object.
87 GeometryFactory *global_factory;
89 //#define DEBUG_STREAM_STATE 1
93 // This function tests writing and reading WKB
94 // TODO:
95 // - compare input and output geometries for equality
96 // - remove debugging lines (on stream state)
98 void WKBtest(vector<Geometry*>*geoms)
100 stringstream s(ios_base::binary|ios_base::in|ios_base::out);
101 io::WKBReader wkbReader(*global_factory);
102 io::WKBWriter wkbWriter;
103 Geometry *gout;
105 #if DEBUG_STREAM_STATE
106 cout<<"WKBtest: machine byte order: "<<BYTE_ORDER<<endl;
107 #endif
110 unsigned int ngeoms=geoms->size();
111 for (unsigned int i=0; i<ngeoms; ++i)
113 Geometry *gin = (*geoms)[i];
115 #if DEBUG_STREAM_STATE
116 cout<<"State of stream before WRITE: ";
117 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
118 " good:"<<s.good()<<
119 " eof:"<<s.eof()<<
120 " bad:"<<s.bad()<<
121 " fail:"<<s.fail()<<endl;
122 #endif
124 #if DEBUG_STREAM_STATE
125 cout<<"State of stream after SEEKP: ";
126 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
127 " good:"<<s.good()<<
128 " eof:"<<s.eof()<<
129 " bad:"<<s.bad()<<
130 " fail:"<<s.fail()<<endl;
131 #endif
133 wkbWriter.write(*gin, s);
134 #if DEBUG_STREAM_STATE
135 cout<<"wkbWriter wrote and reached ";
136 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<endl;
138 cout<<"State of stream before DUMP: ";
139 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
140 " good:"<<s.good()<<
141 " eof:"<<s.eof()<<
142 " bad:"<<s.bad()<<
143 " fail:"<<s.fail()<<endl;
144 #endif
146 #if DEBUG_STREAM_STATE
147 cout<<"State of stream after DUMP: ";
148 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
149 " good:"<<s.good()<<
150 " eof:"<<s.eof()<<
151 " bad:"<<s.bad()<<
152 " fail:"<<s.fail()<<endl;
153 #endif
155 s.seekg(0, ios::beg); // rewind reader pointer
157 #if DEBUG_STREAM_STATE
158 cout<<"State of stream before READ: ";
159 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
160 " good:"<<s.good()<<
161 " eof:"<<s.eof()<<
162 " bad:"<<s.bad()<<
163 " fail:"<<s.fail()<<endl;
164 #endif
166 gout = wkbReader.read(s);
168 #if DEBUG_STREAM_STATE
169 cout<<"State of stream after READ: ";
170 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
171 " good:"<<s.good()<<
172 " eof:"<<s.eof()<<
173 " bad:"<<s.bad()<<
174 " fail:"<<s.fail()<<endl;
175 #endif
177 gin->normalize();
178 gout->normalize();
179 int failed = gin->compareTo(gout);
180 if ( failed ) cout<<"{"<<i<<"} (WKB) ";
181 else cout<<"["<<i<<"] (WKB) ";
183 io::WKBReader::printHEX(s, cout);
184 cout<<endl;
186 if ( failed ) {
187 io::WKTWriter wkt;
188 cout<<" IN: "<<wkt.write(gin)<<endl;
189 cout<<" OUT: "<<wkt.write(gout)<<endl;
192 s.seekp(0, ios::beg); // rewind writer pointer
194 delete gout;
200 // This function will print given geometries in WKT
201 // format to stdout. As a side-effect, will test WKB
202 // output and input, using the WKBtest function.
203 void
204 wkt_print_geoms(vector<Geometry *> *geoms)
206 WKBtest(geoms); // test WKB parser
208 // WKT-print given geometries
209 io::WKTWriter *wkt = new io::WKTWriter();
210 for (unsigned int i=0; i<geoms->size(); i++) {
211 const Geometry *g = (*geoms)[i];
212 string tmp=wkt->write(g);
213 cout<<"["<<i<<"] (WKT) "<<tmp<<endl;
215 delete wkt;
218 // This is the simpler geometry you can get: a point.
219 Point *
220 create_point(double x, double y)
222 Coordinate c(x, y);
223 Point *p = global_factory->createPoint(c);
224 return p;
227 // This function will create a LinearString
228 // geometry with the shape of the letter U
229 // having top-left corner at given coordinates
230 // and 'side' height and width
231 LineString *
232 create_ushaped_linestring(double xoffset, double yoffset, double side)
234 // We will use a coordinate list to build the linestring
235 CoordinateSequence *cl = new CoordinateArraySequence();
237 cl->add(Coordinate(xoffset, yoffset));
238 cl->add(Coordinate(xoffset, yoffset+side));
239 cl->add(Coordinate(xoffset+side, yoffset+side));
240 cl->add(Coordinate(xoffset+side, yoffset));
242 // Now that we have a CoordinateSequence we can create
243 // the linestring.
244 // The newly created LineString will take ownership
245 // of the CoordinateSequence.
246 LineString *ls = global_factory->createLineString(cl);
248 // This is what you do if you want the new LineString
249 // to make a copy of your CoordinateSequence:
250 // LineString *ls = global_factory->createLineString(*cl);
252 return ls; // our LineString
255 // This function will create a LinearRing
256 // geometry rapresenting a square with the given origin
257 // and side
258 LinearRing *
259 create_square_linearring(double xoffset, double yoffset, double side)
261 // We will use a coordinate list to build the linearring
262 CoordinateSequence *cl = new CoordinateArraySequence();
264 cl->add(Coordinate(xoffset, yoffset));
265 cl->add(Coordinate(xoffset, yoffset+side));
266 cl->add(Coordinate(xoffset+side, yoffset+side));
267 cl->add(Coordinate(xoffset+side, yoffset));
268 cl->add(Coordinate(xoffset, yoffset));
270 // Now that we have a CoordinateSequence we can create
271 // the linearring.
272 // The newly created LinearRing will take ownership
273 // of the CoordinateSequence.
274 LinearRing *lr = global_factory->createLinearRing(cl);
276 // This is what you do if you want the new LinearRing
277 // to make a copy of your CoordinateSequence:
278 // LinearRing *lr = global_factory->createLinearRing(*cl);
280 return lr; // our LinearRing
283 // This function will create a Polygon
284 // geometry rapresenting a square with the given origin
285 // and side and with a central hole 1/3 sided.
286 Polygon *
287 create_square_polygon(double xoffset, double yoffset, double side)
289 // We need a LinearRing for the polygon shell
290 LinearRing *outer = create_square_linearring(xoffset,yoffset,side);
292 // And another for the hole
293 LinearRing *inner = create_square_linearring(xoffset+(side/3),
294 yoffset+(side/3),(side/3));
296 // If we need to specify any hole, we do it using
297 // a vector of Geometry pointers (I don't know why
298 // not LinearRings)
299 vector<Geometry *> *holes = new vector<Geometry *>;
301 // We add the newly created geometry to the vector
302 // of holes.
303 holes->push_back(inner);
305 // And finally we call the polygon constructor.
306 // Both the outer LinearRing and the vector of holes
307 // will be referenced by the resulting Polygon object,
308 // thus we CANNOT delete them, neither the holes, nor
309 // the vector containing their pointers, nor the outer
310 // LinearRing. Everything will be deleted at Polygon
311 // deletion time (this is inconsistent with LinearRing
312 // behaviour... what should we do?).
313 Polygon *poly = global_factory->createPolygon(outer, holes);
315 return poly;
319 // This function will create a GeometryCollection
320 // containing copies of all Geometries in given vector.
322 GeometryCollection *
323 create_simple_collection(vector<Geometry *> *geoms)
325 return global_factory->createGeometryCollection(*geoms);
326 // if you wanted to transfer ownership of vector end
327 // its elements you should have call:
328 // return global_factory->createGeometryCollection(geoms);
332 // This function uses GeometricShapeFactory to render
333 // a circle having given center and radius
335 Polygon *
336 create_circle(double centerX, double centerY, double radius)
338 geos::util::GeometricShapeFactory shapefactory(global_factory);
339 shapefactory.setCentre(Coordinate(centerX, centerY));
340 shapefactory.setSize(radius);
341 // same as:
342 // shapefactory.setHeight(radius);
343 // shapefactory.setWidth(radius);
344 return shapefactory.createCircle();
348 // This function uses GeometricShapeFactory to render
349 // an ellipse having given center and axis size
351 Polygon *
352 create_ellipse(double centerX, double centerY, double width, double height)
354 geos::util::GeometricShapeFactory shapefactory(global_factory);
355 shapefactory.setCentre(Coordinate(centerX, centerY));
356 shapefactory.setHeight(height);
357 shapefactory.setWidth(width);
358 return shapefactory.createCircle();
362 // This function uses GeometricShapeFactory to render
363 // a rectangle having lower-left corner at given coordinates
364 // and given sizes.
366 Polygon *
367 create_rectangle(double llX, double llY, double width, double height)
369 geos::util::GeometricShapeFactory shapefactory(global_factory);
370 shapefactory.setBase(Coordinate(llX, llY));
371 shapefactory.setHeight(height);
372 shapefactory.setWidth(width);
373 shapefactory.setNumPoints(4); // we don't need more then 4 points for a rectangle...
374 // can use setSize for a square
375 return shapefactory.createRectangle();
379 // This function uses GeometricShapeFactory to render
380 // an arc having lower-left corner at given coordinates,
381 // given sizes and given angles.
383 LineString *
384 create_arc(double llX, double llY, double width, double height, double startang, double endang)
386 geos::util::GeometricShapeFactory shapefactory(global_factory);
387 shapefactory.setBase(Coordinate(llX, llY));
388 shapefactory.setHeight(height);
389 shapefactory.setWidth(width);
390 // shapefactory.setNumPoints(100); // the default (100 pts)
391 // can use setSize for a square
392 return shapefactory.createArc(startang, endang);
395 auto_ptr<Polygon>
396 create_sinestar(double cx, double cy, double size, int nArms, double armLenRat)
398 geos::geom::util::SineStarFactory fact(global_factory);
399 fact.setCentre(Coordinate(cx, cy));
400 fact.setSize(size);
401 fact.setNumPoints(nArms*5);
402 fact.setArmLengthRatio(armLenRat);
403 fact.setNumArms(nArms);
404 return fact.createSineStar();
407 // Start reading here
408 void do_all()
410 vector<Geometry *> *geoms = new vector<Geometry *>;
411 vector<Geometry *> *newgeoms;
413 // Define a precision model using 0,0 as the reference origin
414 // and 2.0 as coordinates scale.
415 PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);
417 // Initialize global factory with defined PrecisionModel
418 // and a SRID of -1 (undefined).
419 global_factory = new GeometryFactory(pm, -1);
421 // We do not need PrecisionMode object anymore, it has
422 // been copied to global_factory private storage
423 delete pm;
425 ////////////////////////////////////////////////////////////////////////
426 // GEOMETRY CREATION
427 ////////////////////////////////////////////////////////////////////////
429 // Read function bodies to see the magic behind them
430 geoms->push_back(create_point(150, 350));
431 geoms->push_back(create_square_linearring(0,0,100));
432 geoms->push_back(create_ushaped_linestring(60,60,100));
433 geoms->push_back(create_square_linearring(0,0,100));
434 geoms->push_back(create_square_polygon(0,200,300));
435 geoms->push_back(create_square_polygon(0,250,300));
436 geoms->push_back(create_simple_collection(geoms));
438 #if GEOMETRIC_SHAPES
439 // These ones use a GeometricShapeFactory
440 geoms->push_back(create_circle(0, 0, 10));
441 geoms->push_back(create_ellipse(0, 0, 8, 12));
442 geoms->push_back(create_rectangle(-5, -5, 10, 10)); // a square
443 geoms->push_back(create_rectangle(-5, -5, 10, 20)); // a rectangle
444 // The upper-right quarter of a vertical ellipse
445 geoms->push_back(create_arc(0, 0, 10, 20, 0, M_PI/2));
446 geoms->push_back(create_sinestar(10, 10, 100, 5, 2).release()); // a sine star
447 #endif
449 // Print all geoms.
450 cout<<"--------HERE ARE THE BASE GEOMS ----------"<<endl;
451 wkt_print_geoms(geoms);
454 #if UNARY_OPERATIONS
456 ////////////////////////////////////////////////////////////////////////
457 // UNARY OPERATIONS
458 ////////////////////////////////////////////////////////////////////////
460 /////////////////////////////////////////////
461 // CENTROID
462 /////////////////////////////////////////////
464 // Find centroid of each base geometry
465 newgeoms = new vector<Geometry *>;
466 for (unsigned int i=0; i<geoms->size(); i++) {
467 Geometry *g = (*geoms)[i];
468 newgeoms->push_back( g->getCentroid() );
471 // Print all convex hulls
472 cout<<endl<<"------- AND HERE ARE THEIR CENTROIDS -----"<<endl;
473 wkt_print_geoms(newgeoms);
475 // Delete the centroids
476 for (unsigned int i=0; i<newgeoms->size(); i++) {
477 delete (*newgeoms)[i];
479 delete newgeoms;
481 /////////////////////////////////////////////
482 // BUFFER
483 /////////////////////////////////////////////
485 newgeoms = new vector<Geometry *>;
486 for (unsigned int i=0; i<geoms->size(); i++) {
487 Geometry *g = (*geoms)[i];
488 try {
489 Geometry *g2 = g->buffer(10);
490 newgeoms->push_back(g2);
492 catch (const GEOSException& exc) {
493 cerr <<"GEOS Exception: geometry "<<i<<"->buffer(10): "<<exc.what()<<"\n";
497 cout<<endl<<"--------HERE COMES THE BUFFERED GEOMS ----------"<<endl;
498 wkt_print_geoms(newgeoms);
500 for (unsigned int i=0; i<newgeoms->size(); i++) {
501 delete (*newgeoms)[i];
503 delete newgeoms;
505 /////////////////////////////////////////////
506 // CONVEX HULL
507 /////////////////////////////////////////////
509 // Make convex hulls of geometries
510 newgeoms = new vector<Geometry *>;
511 for (unsigned int i=0; i<geoms->size(); i++) {
512 Geometry *g = (*geoms)[i];
513 newgeoms->push_back( g->convexHull() );
516 // Print all convex hulls
517 cout<<endl<<"--------HERE COMES THE HULLS----------"<<endl;
518 wkt_print_geoms(newgeoms);
520 // Delete the hulls
521 for (unsigned int i=0; i<newgeoms->size(); i++) {
522 delete (*newgeoms)[i];
524 delete newgeoms;
526 #endif // UNARY_OPERATIONS
528 #if RELATIONAL_OPERATORS
530 ////////////////////////////////////////////////////////////////////////
531 // RELATIONAL OPERATORS
532 ////////////////////////////////////////////////////////////////////////
534 cout<<"-------------------------------------------------------------------------------"<<endl;
535 cout<<"RELATIONAL OPERATORS"<<endl;
536 cout<<"-------------------------------------------------------------------------------"<<endl;
538 /////////////////////////////////////////////
539 // DISJOINT
540 /////////////////////////////////////////////
542 cout<<endl;
543 cout<<" DISJOINT ";
544 for (unsigned int i=0; i<geoms->size(); i++) {
545 cout<<"\t["<<i<<"]";
547 cout<<endl;
548 for (unsigned int i=0; i<geoms->size(); i++) {
549 Geometry *g1 = (*geoms)[i];
550 cout<<" ["<<i<<"]\t";
551 for (unsigned int j=0; j<geoms->size(); j++) {
552 Geometry *g2 = (*geoms)[j];
553 try {
554 if ( g1->disjoint(g2) ) cout<<" 1\t";
555 else cout<<" 0\t";
557 // Geometry Collection is not a valid argument
558 catch (const IllegalArgumentException& exc) {
559 cout<<" X\t";
561 catch (const std::exception& exc) {
562 cerr<<exc.what()<<endl;
565 cout<<endl;
568 /////////////////////////////////////////////
569 // TOUCHES
570 /////////////////////////////////////////////
572 cout<<endl;
573 cout<<" TOUCHES ";
574 for (unsigned int i=0; i<geoms->size(); i++) {
575 cout<<"\t["<<i<<"]";
577 cout<<endl;
578 for (unsigned int i=0; i<geoms->size(); i++) {
579 Geometry *g1 = (*geoms)[i];
580 cout<<" ["<<i<<"]\t";
581 for (unsigned int j=0; j<geoms->size(); j++) {
582 Geometry *g2 = (*geoms)[j];
583 try {
584 if ( g1->touches(g2) ) cout<<" 1\t";
585 else cout<<" 0\t";
587 // Geometry Collection is not a valid argument
588 catch (const IllegalArgumentException& exc) {
589 cout<<" X\t";
591 catch (const std::exception& exc) {
592 cerr<<exc.what()<<endl;
595 cout<<endl;
598 /////////////////////////////////////////////
599 // INTERSECTS
600 /////////////////////////////////////////////
602 cout<<endl;
603 cout<<" INTERSECTS ";
604 for (unsigned int i=0; i<geoms->size(); i++) {
605 cout<<"\t["<<i<<"]";
607 cout<<endl;
608 for (unsigned int i=0; i<geoms->size(); i++) {
609 Geometry *g1 = (*geoms)[i];
610 cout<<" ["<<i<<"]\t";
611 for (unsigned int j=0; j<geoms->size(); j++) {
612 Geometry *g2 = (*geoms)[j];
613 try {
614 if ( g1->intersects(g2) ) cout<<" 1\t";
615 else cout<<" 0\t";
617 // Geometry Collection is not a valid argument
618 catch (const IllegalArgumentException& exc) {
619 cout<<" X\t";
621 catch (const std::exception& exc) {
622 cerr<<exc.what()<<endl;
625 cout<<endl;
628 /////////////////////////////////////////////
629 // CROSSES
630 /////////////////////////////////////////////
632 cout<<endl;
633 cout<<" CROSSES ";
634 for (unsigned int i=0; i<geoms->size(); i++) {
635 cout<<"\t["<<i<<"]";
637 cout<<endl;
638 for (unsigned int i=0; i<geoms->size(); i++) {
639 Geometry *g1 = (*geoms)[i];
640 cout<<" ["<<i<<"]\t";
641 for (unsigned int j=0; j<geoms->size(); j++) {
642 Geometry *g2 = (*geoms)[j];
643 try {
644 if ( g1->crosses(g2) ) cout<<" 1\t";
645 else cout<<" 0\t";
647 // Geometry Collection is not a valid argument
648 catch (const IllegalArgumentException& exc) {
649 cout<<" X\t";
651 catch (const std::exception& exc) {
652 cerr<<exc.what()<<endl;
655 cout<<endl;
658 /////////////////////////////////////////////
659 // WITHIN
660 /////////////////////////////////////////////
662 cout<<endl;
663 cout<<" WITHIN ";
664 for (unsigned int i=0; i<geoms->size(); i++) {
665 cout<<"\t["<<i<<"]";
667 cout<<endl;
668 for (unsigned int i=0; i<geoms->size(); i++) {
669 Geometry *g1 = (*geoms)[i];
670 cout<<" ["<<i<<"]\t";
671 for (unsigned int j=0; j<geoms->size(); j++) {
672 Geometry *g2 = (*geoms)[j];
673 try {
674 if ( g1->within(g2) ) cout<<" 1\t";
675 else cout<<" 0\t";
677 // Geometry Collection is not a valid argument
678 catch (const IllegalArgumentException& exc) {
679 cout<<" X\t";
681 catch (const std::exception& exc) {
682 cerr<<exc.what()<<endl;
685 cout<<endl;
688 /////////////////////////////////////////////
689 // CONTAINS
690 /////////////////////////////////////////////
692 cout<<endl;
693 cout<<" CONTAINS ";
694 for (unsigned int i=0; i<geoms->size(); i++) {
695 cout<<"\t["<<i<<"]";
697 cout<<endl;
698 for (unsigned int i=0; i<geoms->size(); i++) {
699 Geometry *g1 = (*geoms)[i];
700 cout<<" ["<<i<<"]\t";
701 for (unsigned int j=0; j<geoms->size(); j++) {
702 Geometry *g2 = (*geoms)[j];
703 try {
704 if ( g1->contains(g2) ) cout<<" 1\t";
705 else cout<<" 0\t";
707 // Geometry Collection is not a valid argument
708 catch (const IllegalArgumentException& exc) {
709 cout<<" X\t";
711 catch (const std::exception& exc) {
712 cerr<<exc.what()<<endl;
715 cout<<endl;
718 /////////////////////////////////////////////
719 // OVERLAPS
720 /////////////////////////////////////////////
722 cout<<endl;
723 cout<<" OVERLAPS ";
724 for (unsigned int i=0; i<geoms->size(); i++) {
725 cout<<"\t["<<i<<"]";
727 cout<<endl;
728 for (unsigned int i=0; i<geoms->size(); i++) {
729 Geometry *g1 = (*geoms)[i];
730 cout<<" ["<<i<<"]\t";
731 for (unsigned int j=0; j<geoms->size(); j++) {
732 Geometry *g2 = (*geoms)[j];
733 try {
734 if ( g1->overlaps(g2) ) cout<<" 1\t";
735 else cout<<" 0\t";
737 // Geometry Collection is not a valid argument
738 catch (const IllegalArgumentException& exc) {
739 cout<<" X\t";
741 catch (const std::exception& exc) {
742 cerr<<exc.what()<<endl;
745 cout<<endl;
748 /////////////////////////////////////////////
749 // RELATE
750 /////////////////////////////////////////////
752 cout<<endl;
753 cout<<" RELATE ";
754 for (unsigned int i=0; i<geoms->size(); i++) {
755 cout<<"\t["<<i<<"]";
757 cout<<endl;
758 for (unsigned int i=0; i<geoms->size(); i++) {
759 Geometry *g1 = (*geoms)[i];
760 cout<<" ["<<i<<"]\t";
761 for (unsigned int j=0; j<geoms->size(); j++) {
762 Geometry *g2 = (*geoms)[j];
763 IntersectionMatrix *im=NULL;
764 try {
765 // second argument is intersectionPattern
766 string pattern = "212101212";
767 if ( g1->relate(g2, pattern) ) cout<<" 1\t";
768 else cout<<" 0\t";
770 // get the intersectionMatrix itself
771 im=g1->relate(g2);
772 delete im; // delete afterwards
774 // Geometry Collection is not a valid argument
775 catch (const IllegalArgumentException& exc) {
776 cout<<" X\t";
778 catch (const std::exception& exc) {
779 cerr<<exc.what()<<endl;
782 cout<<endl;
785 /////////////////////////////////////////////
786 // EQUALS
787 /////////////////////////////////////////////
789 cout<<endl;
790 cout<<" EQUALS ";
791 for (unsigned int i=0; i<geoms->size(); i++) {
792 cout<<"\t["<<i<<"]";
794 cout<<endl;
795 for (unsigned int i=0; i<geoms->size(); i++) {
796 Geometry *g1 = (*geoms)[i];
797 cout<<" ["<<i<<"]\t";
798 for (unsigned int j=0; j<geoms->size(); j++) {
799 Geometry *g2 = (*geoms)[j];
800 try {
801 if ( g1->equals(g2) ) cout<<" 1\t";
802 else cout<<" 0\t";
804 // Geometry Collection is not a valid argument
805 catch (const IllegalArgumentException& exc) {
806 cout<<" X\t";
808 catch (const std::exception& exc) {
809 cerr<<exc.what()<<endl;
812 cout<<endl;
815 /////////////////////////////////////////////
816 // EQUALS_EXACT
817 /////////////////////////////////////////////
819 cout<<endl;
820 cout<<"EQUALS_EXACT ";
821 for (unsigned int i=0; i<geoms->size(); i++) {
822 cout<<"\t["<<i<<"]";
824 cout<<endl;
825 for (unsigned int i=0; i<geoms->size(); i++) {
826 Geometry *g1 = (*geoms)[i];
827 cout<<" ["<<i<<"]\t";
828 for (unsigned int j=0; j<geoms->size(); j++) {
829 Geometry *g2 = (*geoms)[j];
830 try {
831 // second argument is a tolerance
832 if ( g1->equalsExact(g2, 0.5) ) cout<<" 1\t";
833 else cout<<" 0\t";
835 // Geometry Collection is not a valid argument
836 catch (const IllegalArgumentException& exc) {
837 cout<<" X\t";
839 catch (const std::exception& exc) {
840 cerr<<exc.what()<<endl;
843 cout<<endl;
846 /////////////////////////////////////////////
847 // IS_WITHIN_DISTANCE
848 /////////////////////////////////////////////
850 cout<<endl;
851 cout<<"IS_WITHIN_DIST";
852 for (unsigned int i=0; i<geoms->size(); i++) {
853 cout<<"\t["<<i<<"]";
855 cout<<endl;
856 for (unsigned int i=0; i<geoms->size(); i++) {
857 Geometry *g1 = (*geoms)[i];
858 cout<<" ["<<i<<"]\t";
859 for (unsigned int j=0; j<geoms->size(); j++) {
860 Geometry *g2 = (*geoms)[j];
861 try {
862 // second argument is the distance
863 if ( g1->isWithinDistance(g2,2) ) cout<<" 1\t";
864 else cout<<" 0\t";
866 // Geometry Collection is not a valid argument
867 catch (const IllegalArgumentException& exc) {
868 cout<<" X\t";
870 catch (const std::exception& exc) {
871 cerr<<exc.what()<<endl;
874 cout<<endl;
877 #endif // RELATIONAL_OPERATORS
879 #if COMBINATIONS
881 ////////////////////////////////////////////////////////////////////////
882 // COMBINATIONS
883 ////////////////////////////////////////////////////////////////////////
885 cout<<endl;
886 cout<<"-------------------------------------------------------------------------------"<<endl;
887 cout<<"COMBINATIONS"<<endl;
888 cout<<"-------------------------------------------------------------------------------"<<endl;
890 /////////////////////////////////////////////
891 // UNION
892 /////////////////////////////////////////////
894 // Make unions of all geoms
895 newgeoms = new vector<Geometry *>;
896 for (unsigned int i=0; i<geoms->size()-1; i++) {
897 Geometry *g1 = (*geoms)[i];
898 for (unsigned int j=i+1; j<geoms->size(); j++) {
899 Geometry *g2 = (*geoms)[j];
900 try {
901 Geometry *g3 = g1->Union(g2);
902 newgeoms->push_back(g3);
904 // It's illegal to union a collection ...
905 catch (const IllegalArgumentException& ill) {
906 //cerr <<ill.toString()<<"\n";
908 catch (const std::exception& exc) {
909 cerr<<exc.what()<<endl;
914 // Print all unions
915 cout<<endl<<"----- AND HERE ARE SOME UNION COMBINATIONS ------"<<endl;
916 wkt_print_geoms(newgeoms);
918 // Delete the resulting geoms
919 for (unsigned int i=0; i<newgeoms->size(); i++) {
920 delete (*newgeoms)[i];
922 delete newgeoms;
925 /////////////////////////////////////////////
926 // INTERSECTION
927 /////////////////////////////////////////////
929 // Compute intersection of adhiacent geometries
930 newgeoms = new vector<Geometry *>;
931 for (unsigned int i=0; i<geoms->size()-1; i++) {
932 Geometry *g1 = (*geoms)[i];
933 for (unsigned int j=i+1; j<geoms->size(); j++) {
934 Geometry *g2 = (*geoms)[j];
935 try {
936 Geometry *g3 = g1->intersection(g2);
937 newgeoms->push_back(g3);
939 // Collection are illegal as intersection argument
940 catch (const IllegalArgumentException& ill) {
941 //cerr <<ill.toString()<<"\n";
943 catch (const std::exception& exc) {
944 cerr<<exc.what()<<endl;
949 cout<<endl<<"----- HERE ARE SOME INTERSECTIONS COMBINATIONS ------"<<endl;
950 wkt_print_geoms(newgeoms);
952 // Delete the resulting geoms
953 for (unsigned int i=0; i<newgeoms->size(); i++) {
954 delete (*newgeoms)[i];
956 delete newgeoms;
958 /////////////////////////////////////////////
959 // DIFFERENCE
960 /////////////////////////////////////////////
962 // Compute difference of adhiacent geometries
963 newgeoms = new vector<Geometry *>;
964 for (unsigned int i=0; i<geoms->size()-1; i++) {
965 Geometry *g1 = (*geoms)[i];
966 for (unsigned int j=i+1; j<geoms->size(); j++) {
967 Geometry *g2 = (*geoms)[j];
968 try {
969 Geometry *g3 = g1->difference(g2);
970 newgeoms->push_back(g3);
972 // Collection are illegal as difference argument
973 catch (const IllegalArgumentException& ill) {
974 //cerr <<ill.toString()<<"\n";
976 catch (const std::exception& exc) {
977 cerr<<exc.what()<<endl;
982 cout<<endl<<"----- HERE ARE SOME DIFFERENCE COMBINATIONS ------"<<endl;
983 wkt_print_geoms(newgeoms);
985 // Delete the resulting geoms
986 for (unsigned int i=0; i<newgeoms->size(); i++) {
987 delete (*newgeoms)[i];
989 delete newgeoms;
991 /////////////////////////////////////////////
992 // SYMMETRIC DIFFERENCE
993 /////////////////////////////////////////////
995 // Compute symmetric difference of adhiacent geometries
996 newgeoms = new vector<Geometry *>;
997 for (unsigned int i=0; i<geoms->size()-1; i++) {
998 Geometry *g1 = (*geoms)[i];
999 for (unsigned int j=i+1; j<geoms->size(); j++) {
1000 Geometry *g2 = (*geoms)[j];
1001 try {
1002 Geometry *g3 = g1->symDifference(g2);
1003 newgeoms->push_back(g3);
1005 // Collection are illegal as symdifference argument
1006 catch (const IllegalArgumentException& ill) {
1007 //cerr <<ill.toString()<<"\n";
1009 catch (const std::exception& exc) {
1010 cerr<<exc.what()<<endl;
1015 cout<<endl<<"----- HERE ARE SYMMETRIC DIFFERENCES ------"<<endl;
1016 wkt_print_geoms(newgeoms);
1018 // Delete the resulting geoms
1019 for (unsigned int i=0; i<newgeoms->size(); i++) {
1020 delete (*newgeoms)[i];
1022 delete newgeoms;
1024 #endif // COMBINATIONS
1026 #if LINEMERGE
1028 /////////////////////////////////////////////
1029 // LINEMERGE
1030 /////////////////////////////////////////////
1031 LineMerger lm;
1032 lm.add(geoms);
1033 vector<LineString *> *mls = lm.getMergedLineStrings();
1034 newgeoms = new vector<Geometry *>;
1035 for (unsigned int i=0; i<mls->size(); i++)
1036 newgeoms->push_back((*mls)[i]);
1037 delete mls;
1039 cout<<endl<<"----- HERE IS THE LINEMERGE OUTPUT ------"<<endl;
1040 wkt_print_geoms(newgeoms);
1042 // Delete the resulting geoms
1043 for (unsigned int i=0; i<newgeoms->size(); i++) {
1044 delete (*newgeoms)[i];
1046 delete newgeoms;
1048 #endif // LINEMERGE
1050 #if POLYGONIZE
1052 /////////////////////////////////////////////
1053 // POLYGONIZE
1054 /////////////////////////////////////////////
1055 Polygonizer plgnzr;
1056 plgnzr.add(geoms);
1057 vector<Polygon *> *polys = plgnzr.getPolygons();
1058 newgeoms = new vector<Geometry *>;
1059 for (unsigned int i=0; i<polys->size(); i++)
1060 newgeoms->push_back((*polys)[i]);
1061 delete polys;
1063 cout<<endl<<"----- HERE IS POLYGONIZE OUTPUT ------"<<endl;
1064 wkt_print_geoms(newgeoms);
1066 // Delete the resulting geoms
1067 for (unsigned int i=0; i<newgeoms->size(); i++) {
1068 delete (*newgeoms)[i];
1070 delete newgeoms;
1072 #endif // POLYGONIZE
1074 /////////////////////////////////////////////
1075 // CLEANUP
1076 /////////////////////////////////////////////
1078 // Delete base geometries
1079 for (unsigned int i=0; i<geoms->size(); i++) {
1080 delete (*geoms)[i];
1082 delete geoms;
1084 delete global_factory;
1088 main()
1090 cout<<"GEOS "<<geosversion()<<" ported from JTS "<<jtsport()<<endl;
1093 do_all();
1095 // All exception thrown by GEOS are subclasses of this
1096 // one, so this is a catch-all
1097 catch (const GEOSException& exc)
1099 cerr <<"GEOS Exception: "<<exc.what()<<"\n";
1100 exit(1);
1102 catch (const exception &e)
1104 cerr <<"Standard exception thrown: "<<e.what()<<endl;
1105 exit(1);
1107 // and this is a catch-all non standard ;)
1108 catch (...)
1110 cerr <<"unknown exception trown!\n";
1111 exit(1);
1114 // Unload is no more necessary
1115 //io::Unload::Release();
1117 exit(0);
1120 /**********************************************************************
1121 * $Log$
1122 * Revision 1.46 2006/04/09 11:07:54 mloskot
1123 * Small fixes in doc/example.cpp.
1125 * Revision 1.45 2006/04/04 08:16:46 strk
1126 * Changed GEOSException hierarchy to be derived from std::runtime_exception.
1127 * Removed the GEOSException::toString redundant method (use ::what() instead)
1129 * Revision 1.44 2006/03/28 15:19:22 strk
1130 * Added macros for sections skip (useful in debugging)
1132 * Revision 1.43 2006/03/15 18:44:51 strk
1133 * Bug #60 - Missing <cmath> header in some files
1135 * Revision 1.42 2006/03/06 21:27:39 strk
1136 * Cascading fixed after Unload definition moved to geos::io namespace
1138 * Revision 1.41 2006/03/06 19:40:46 strk
1139 * geos::util namespace. New GeometryCollection::iterator interface, many cleanups.
1141 * Revision 1.40 2006/03/06 15:23:14 strk
1142 * geos::io namespace
1144 * Revision 1.39 2006/03/03 10:46:21 strk
1145 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
1147 * Revision 1.38 2006/02/19 19:46:49 strk
1148 * Packages <-> namespaces mapping for most GEOS internal code (uncomplete, but working). Dir-level libs for index/ subdirs.
1150 * Revision 1.37 2006/02/09 15:52:47 strk
1151 * GEOSException derived from std::exception; always thrown and cought by const ref.
1153 * Revision 1.36 2006/01/31 19:07:33 strk
1154 * - Renamed DefaultCoordinateSequence to CoordinateArraySequence.
1155 * - Moved GetNumGeometries() and GetGeometryN() interfaces
1156 * from GeometryCollection to Geometry class.
1157 * - Added getAt(int pos, Coordinate &to) funtion to CoordinateSequence class.
1158 * - Reworked automake scripts to produce a static lib for each subdir and
1159 * then link all subsystem's libs togheter
1160 * - Moved C-API in it's own top-level dir capi/
1161 * - Moved source/bigtest and source/test to tests/bigtest and test/xmltester
1162 * - Fixed PointLocator handling of LinearRings
1163 * - Changed CoordinateArrayFilter to reduce memory copies
1164 * - Changed UniqueCoordinateArrayFilter to reduce memory copies
1165 * - Added CGAlgorithms::isPointInRing() version working with
1166 * Coordinate::ConstVect type (faster!)
1167 * - Ported JTS-1.7 version of ConvexHull with big attention to
1168 * memory usage optimizations.
1169 * - Improved XMLTester output and user interface
1170 * - geos::geom::util namespace used for geom/util stuff
1171 * - Improved memory use in geos::geom::util::PolygonExtractor
1172 * - New ShortCircuitedGeometryVisitor class
1173 * - New operation/predicate package
1175 * Revision 1.35 2005/11/30 11:27:07 strk
1176 * catch std::exception by ref
1178 * Revision 1.34 2005/11/30 11:25:12 strk
1179 * includes cleanup
1181 * Revision 1.33 2005/09/27 16:20:43 strk
1182 * Reverted previous change, fixed the bug by turning WKBReader.factory
1183 * into a reference rather then a real object. ABI still breaks, but API
1184 * at least is safe (we didn't release any WKB-aware package so breaking
1185 * ABI is not a big deal at this stage).
1187 * Revision 1.32 2005/09/27 16:00:26 strk
1188 * Fixed bug in WKBReader destroying the GeometryFactory used in Geometry
1189 * construction. Changed it's definition to *require* a GeometryFactory
1190 * pointer parameter.
1192 * Revision 1.31 2005/09/26 08:17:19 strk
1193 * Removed memory leak from WKB tester
1195 * Revision 1.30 2005/09/03 21:26:42 strk
1196 * Reworked WKB I/O to avoid use of templates and make better use of STL
1198 * Revision 1.29 2005/07/11 12:17:26 strk
1199 * Commented out useless include
1201 * Revision 1.28 2005/04/29 16:36:28 strk
1202 * Made WKBReader use global_factory, for having WKB reads produce
1203 * same context of input geoms.
1205 * Revision 1.27 2005/04/29 15:34:20 strk
1206 * Typedef'ed biostringstream, preferred parameter for
1207 * WKB parser templates.
1208 * Added << operator for biostringstream.
1209 * Typedef'ed WKBWriter and WKBReader to be parametrized by
1210 * biostringstream.
1211 * Added WKBtest in doc/example.cpp
1213 * Revision 1.26 2004/12/08 13:54:43 strk
1214 * gcc warnings checked and fixed, general cleanups.
1216 * Revision 1.25 2004/10/13 10:03:02 strk
1217 * Added missing linemerge and polygonize operation.
1218 * Bug fixes and leaks removal from the newly added modules and
1219 * planargraph (used by them).
1220 * Some comments and indentation changes.
1222 * Revision 1.24 2004/07/22 16:58:01 strk
1223 * runtime version extractor functions split. geos::version() is now
1224 * geos::geosversion() and geos::jtsport()
1226 * Revision 1.23 2004/07/17 09:19:32 strk
1227 * added GEOS version report
1229 *********************************************************************/