HotPixel: do not invalidate reference to original point. Fixes #498.
[geos.git] / doc / example.cpp
blob3f4f9df38aacaab54fb75865ba44b200dbf8714c
1 /**********************************************************************
2 * $Id$
4 * GEOS - Geometry Engine Open Source
5 * http://geos.refractions.net
7 * Copyright (C) 2001-2002 Vivid Solutions Inc.
8 * Copyright (C) 2005 Refractions Research Inc.
10 * This is free software; you can redistribute and/or modify it under
11 * the terms of the GNU Lesser General Public Licence as published
12 * by the Free Software Foundation.
13 * See the COPYING file for more information.
15 *********************************************************************
17 * This file should document by example usage of the GEOS library.
18 * It could actually be a live discuss-by-example board for
19 * architectural design choices.
21 * --strk;
23 * DEBUGGING TIPS:
24 * use -D__USE_MALLOC at compile time for gcc 2.91, 2.95, 3.0 and 3.1
25 * and GLIBCXX_FORCE_NEW or GLIBCPP_FORCE_NEW at run time with gcc 3.2.2+
26 * to force libstdc++ avoid caching memory. This should remove some
27 * obscure reports from memory checkers like valgrind.
29 **********************************************************************/
31 #include <geos/geom/PrecisionModel.h>
32 #include <geos/geom/GeometryFactory.h>
33 #include <geos/geom/Geometry.h>
34 #include <geos/geom/Point.h>
35 #include <geos/geom/LinearRing.h>
36 #include <geos/geom/LineString.h>
37 #include <geos/geom/Polygon.h>
38 #include <geos/geom/GeometryCollection.h>
39 #include <geos/geom/Coordinate.h>
40 #include <geos/geom/CoordinateSequence.h>
41 #include <geos/geom/CoordinateArraySequence.h>
42 #include <geos/geom/IntersectionMatrix.h>
43 #include <geos/io/WKBReader.h>
44 #include <geos/io/WKBWriter.h>
45 #include <geos/io/WKTWriter.h>
46 #include <geos/util/GeometricShapeFactory.h>
47 #include <geos/geom/util/SineStarFactory.h>
48 #include <geos/util/GEOSException.h>
49 #include <geos/util/IllegalArgumentException.h>
50 #include <geos/opLinemerge.h>
51 #include <geos/opPolygonize.h>
52 #include <vector>
53 #include <sstream>
54 #include <iomanip>
55 #include <cstdlib> // exit()
57 #ifndef M_PI
58 #define M_PI 3.14159265358979323846
59 #endif
61 // Set to 0 to skip section
62 #define GEOMETRIC_SHAPES 1
63 #define RELATIONAL_OPERATORS 1
64 #define COMBINATIONS 1
65 #define UNARY_OPERATIONS 1
66 #define LINEMERGE 1
67 #define POLYGONIZE 1
70 using namespace std;
71 using namespace geos;
72 using namespace geos::geom;
73 using namespace geos::operation::polygonize;
74 using namespace geos::operation::linemerge;
75 using geos::util::GEOSException;
76 using geos::util::IllegalArgumentException;
79 // Prototypes
80 void wkt_print_geoms(vector<Geometry *> *geoms);
83 // This object will be used to construct our geometries.
84 // It might be bypassed by directly call geometry constructors,
85 // but that would be boring because you'd need to specify
86 // a PrecisionModel and a SRID everytime: those infos are
87 // cached inside a GeometryFactory object.
88 GeometryFactory *global_factory;
90 //#define DEBUG_STREAM_STATE 1
94 // This function tests writing and reading WKB
95 // TODO:
96 // - compare input and output geometries for equality
97 // - remove debugging lines (on stream state)
99 void WKBtest(vector<Geometry*>*geoms)
101 stringstream s(ios_base::binary|ios_base::in|ios_base::out);
102 io::WKBReader wkbReader(*global_factory);
103 io::WKBWriter wkbWriter;
104 Geometry *gout;
106 #if DEBUG_STREAM_STATE
107 cout<<"WKBtest: machine byte order: "<<BYTE_ORDER<<endl;
108 #endif
111 unsigned int ngeoms=geoms->size();
112 for (unsigned int i=0; i<ngeoms; ++i)
114 Geometry *gin = (*geoms)[i];
116 #if DEBUG_STREAM_STATE
117 cout<<"State of stream before WRITE: ";
118 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
119 " good:"<<s.good()<<
120 " eof:"<<s.eof()<<
121 " bad:"<<s.bad()<<
122 " fail:"<<s.fail()<<endl;
123 #endif
125 #if DEBUG_STREAM_STATE
126 cout<<"State of stream after SEEKP: ";
127 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
128 " good:"<<s.good()<<
129 " eof:"<<s.eof()<<
130 " bad:"<<s.bad()<<
131 " fail:"<<s.fail()<<endl;
132 #endif
134 wkbWriter.write(*gin, s);
135 #if DEBUG_STREAM_STATE
136 cout<<"wkbWriter wrote and reached ";
137 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<endl;
139 cout<<"State of stream before DUMP: ";
140 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
141 " good:"<<s.good()<<
142 " eof:"<<s.eof()<<
143 " bad:"<<s.bad()<<
144 " fail:"<<s.fail()<<endl;
145 #endif
147 #if DEBUG_STREAM_STATE
148 cout<<"State of stream after DUMP: ";
149 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
150 " good:"<<s.good()<<
151 " eof:"<<s.eof()<<
152 " bad:"<<s.bad()<<
153 " fail:"<<s.fail()<<endl;
154 #endif
156 s.seekg(0, ios::beg); // rewind reader pointer
158 #if DEBUG_STREAM_STATE
159 cout<<"State of stream before READ: ";
160 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
161 " good:"<<s.good()<<
162 " eof:"<<s.eof()<<
163 " bad:"<<s.bad()<<
164 " fail:"<<s.fail()<<endl;
165 #endif
167 gout = wkbReader.read(s);
169 #if DEBUG_STREAM_STATE
170 cout<<"State of stream after READ: ";
171 cout<<"p:"<<s.tellp()<<" g:"<<s.tellg()<<
172 " good:"<<s.good()<<
173 " eof:"<<s.eof()<<
174 " bad:"<<s.bad()<<
175 " fail:"<<s.fail()<<endl;
176 #endif
178 gin->normalize();
179 gout->normalize();
180 int failed = gin->compareTo(gout);
181 if ( failed ) cout<<"{"<<i<<"} (WKB) ";
182 else cout<<"["<<i<<"] (WKB) ";
184 io::WKBReader::printHEX(s, cout);
185 cout<<endl;
187 if ( failed ) {
188 io::WKTWriter wkt;
189 cout<<" IN: "<<wkt.write(gin)<<endl;
190 cout<<" OUT: "<<wkt.write(gout)<<endl;
193 s.seekp(0, ios::beg); // rewind writer pointer
195 delete gout;
201 // This function will print given geometries in WKT
202 // format to stdout. As a side-effect, will test WKB
203 // output and input, using the WKBtest function.
204 void
205 wkt_print_geoms(vector<Geometry *> *geoms)
207 WKBtest(geoms); // test WKB parser
209 // WKT-print given geometries
210 io::WKTWriter *wkt = new io::WKTWriter();
211 for (unsigned int i=0; i<geoms->size(); i++) {
212 const Geometry *g = (*geoms)[i];
213 string tmp=wkt->write(g);
214 cout<<"["<<i<<"] (WKT) "<<tmp<<endl;
216 delete wkt;
219 // This is the simpler geometry you can get: a point.
220 Point *
221 create_point(double x, double y)
223 Coordinate c(x, y);
224 Point *p = global_factory->createPoint(c);
225 return p;
228 // This function will create a LinearString
229 // geometry with the shape of the letter U
230 // having top-left corner at given coordinates
231 // and 'side' height and width
232 LineString *
233 create_ushaped_linestring(double xoffset, double yoffset, double side)
235 // We will use a coordinate list to build the linestring
236 CoordinateSequence *cl = new CoordinateArraySequence();
238 cl->add(Coordinate(xoffset, yoffset));
239 cl->add(Coordinate(xoffset, yoffset+side));
240 cl->add(Coordinate(xoffset+side, yoffset+side));
241 cl->add(Coordinate(xoffset+side, yoffset));
243 // Now that we have a CoordinateSequence we can create
244 // the linestring.
245 // The newly created LineString will take ownership
246 // of the CoordinateSequence.
247 LineString *ls = global_factory->createLineString(cl);
249 // This is what you do if you want the new LineString
250 // to make a copy of your CoordinateSequence:
251 // LineString *ls = global_factory->createLineString(*cl);
253 return ls; // our LineString
256 // This function will create a LinearRing
257 // geometry rapresenting a square with the given origin
258 // and side
259 LinearRing *
260 create_square_linearring(double xoffset, double yoffset, double side)
262 // We will use a coordinate list to build the linearring
263 CoordinateSequence *cl = new CoordinateArraySequence();
265 cl->add(Coordinate(xoffset, yoffset));
266 cl->add(Coordinate(xoffset, yoffset+side));
267 cl->add(Coordinate(xoffset+side, yoffset+side));
268 cl->add(Coordinate(xoffset+side, yoffset));
269 cl->add(Coordinate(xoffset, yoffset));
271 // Now that we have a CoordinateSequence we can create
272 // the linearring.
273 // The newly created LinearRing will take ownership
274 // of the CoordinateSequence.
275 LinearRing *lr = global_factory->createLinearRing(cl);
277 // This is what you do if you want the new LinearRing
278 // to make a copy of your CoordinateSequence:
279 // LinearRing *lr = global_factory->createLinearRing(*cl);
281 return lr; // our LinearRing
284 // This function will create a Polygon
285 // geometry rapresenting a square with the given origin
286 // and side and with a central hole 1/3 sided.
287 Polygon *
288 create_square_polygon(double xoffset, double yoffset, double side)
290 // We need a LinearRing for the polygon shell
291 LinearRing *outer = create_square_linearring(xoffset,yoffset,side);
293 // And another for the hole
294 LinearRing *inner = create_square_linearring(xoffset+(side/3),
295 yoffset+(side/3),(side/3));
297 // If we need to specify any hole, we do it using
298 // a vector of Geometry pointers (I don't know why
299 // not LinearRings)
300 vector<Geometry *> *holes = new vector<Geometry *>;
302 // We add the newly created geometry to the vector
303 // of holes.
304 holes->push_back(inner);
306 // And finally we call the polygon constructor.
307 // Both the outer LinearRing and the vector of holes
308 // will be referenced by the resulting Polygon object,
309 // thus we CANNOT delete them, neither the holes, nor
310 // the vector containing their pointers, nor the outer
311 // LinearRing. Everything will be deleted at Polygon
312 // deletion time (this is inconsistent with LinearRing
313 // behaviour... what should we do?).
314 Polygon *poly = global_factory->createPolygon(outer, holes);
316 return poly;
320 // This function will create a GeometryCollection
321 // containing copies of all Geometries in given vector.
323 GeometryCollection *
324 create_simple_collection(vector<Geometry *> *geoms)
326 return global_factory->createGeometryCollection(*geoms);
327 // if you wanted to transfer ownership of vector end
328 // its elements you should have call:
329 // return global_factory->createGeometryCollection(geoms);
333 // This function uses GeometricShapeFactory to render
334 // a circle having given center and radius
336 Polygon *
337 create_circle(double centerX, double centerY, double radius)
339 geos::util::GeometricShapeFactory shapefactory(global_factory);
340 shapefactory.setCentre(Coordinate(centerX, centerY));
341 shapefactory.setSize(radius);
342 // same as:
343 // shapefactory.setHeight(radius);
344 // shapefactory.setWidth(radius);
345 return shapefactory.createCircle();
349 // This function uses GeometricShapeFactory to render
350 // an ellipse having given center and axis size
352 Polygon *
353 create_ellipse(double centerX, double centerY, double width, double height)
355 geos::util::GeometricShapeFactory shapefactory(global_factory);
356 shapefactory.setCentre(Coordinate(centerX, centerY));
357 shapefactory.setHeight(height);
358 shapefactory.setWidth(width);
359 return shapefactory.createCircle();
363 // This function uses GeometricShapeFactory to render
364 // a rectangle having lower-left corner at given coordinates
365 // and given sizes.
367 Polygon *
368 create_rectangle(double llX, double llY, double width, double height)
370 geos::util::GeometricShapeFactory shapefactory(global_factory);
371 shapefactory.setBase(Coordinate(llX, llY));
372 shapefactory.setHeight(height);
373 shapefactory.setWidth(width);
374 shapefactory.setNumPoints(4); // we don't need more then 4 points for a rectangle...
375 // can use setSize for a square
376 return shapefactory.createRectangle();
380 // This function uses GeometricShapeFactory to render
381 // an arc having lower-left corner at given coordinates,
382 // given sizes and given angles.
384 LineString *
385 create_arc(double llX, double llY, double width, double height, double startang, double endang)
387 geos::util::GeometricShapeFactory shapefactory(global_factory);
388 shapefactory.setBase(Coordinate(llX, llY));
389 shapefactory.setHeight(height);
390 shapefactory.setWidth(width);
391 // shapefactory.setNumPoints(100); // the default (100 pts)
392 // can use setSize for a square
393 return shapefactory.createArc(startang, endang);
396 auto_ptr<Polygon>
397 create_sinestar(double cx, double cy, double size, int nArms, double armLenRat)
399 geos::geom::util::SineStarFactory fact(global_factory);
400 fact.setCentre(Coordinate(cx, cy));
401 fact.setSize(size);
402 fact.setNumPoints(nArms*5);
403 fact.setArmLengthRatio(armLenRat);
404 fact.setNumArms(nArms);
405 return fact.createSineStar();
408 // Start reading here
409 void do_all()
411 vector<Geometry *> *geoms = new vector<Geometry *>;
412 vector<Geometry *> *newgeoms;
414 // Define a precision model using 0,0 as the reference origin
415 // and 2.0 as coordinates scale.
416 PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);
418 // Initialize global factory with defined PrecisionModel
419 // and a SRID of -1 (undefined).
420 global_factory = new GeometryFactory(pm, -1);
422 // We do not need PrecisionMode object anymore, it has
423 // been copied to global_factory private storage
424 delete pm;
426 ////////////////////////////////////////////////////////////////////////
427 // GEOMETRY CREATION
428 ////////////////////////////////////////////////////////////////////////
430 // Read function bodies to see the magic behind them
431 geoms->push_back(create_point(150, 350));
432 geoms->push_back(create_square_linearring(0,0,100));
433 geoms->push_back(create_ushaped_linestring(60,60,100));
434 geoms->push_back(create_square_linearring(0,0,100));
435 geoms->push_back(create_square_polygon(0,200,300));
436 geoms->push_back(create_square_polygon(0,250,300));
437 geoms->push_back(create_simple_collection(geoms));
439 #if GEOMETRIC_SHAPES
440 // These ones use a GeometricShapeFactory
441 geoms->push_back(create_circle(0, 0, 10));
442 geoms->push_back(create_ellipse(0, 0, 8, 12));
443 geoms->push_back(create_rectangle(-5, -5, 10, 10)); // a square
444 geoms->push_back(create_rectangle(-5, -5, 10, 20)); // a rectangle
445 // The upper-right quarter of a vertical ellipse
446 geoms->push_back(create_arc(0, 0, 10, 20, 0, M_PI/2));
447 geoms->push_back(create_sinestar(10, 10, 100, 5, 2).release()); // a sine star
448 #endif
450 // Print all geoms.
451 cout<<"--------HERE ARE THE BASE GEOMS ----------"<<endl;
452 wkt_print_geoms(geoms);
455 #if UNARY_OPERATIONS
457 ////////////////////////////////////////////////////////////////////////
458 // UNARY OPERATIONS
459 ////////////////////////////////////////////////////////////////////////
461 /////////////////////////////////////////////
462 // CENTROID
463 /////////////////////////////////////////////
465 // Find centroid of each base geometry
466 newgeoms = new vector<Geometry *>;
467 for (unsigned int i=0; i<geoms->size(); i++) {
468 Geometry *g = (*geoms)[i];
469 newgeoms->push_back( g->getCentroid() );
472 // Print all convex hulls
473 cout<<endl<<"------- AND HERE ARE THEIR CENTROIDS -----"<<endl;
474 wkt_print_geoms(newgeoms);
476 // Delete the centroids
477 for (unsigned int i=0; i<newgeoms->size(); i++) {
478 delete (*newgeoms)[i];
480 delete newgeoms;
482 /////////////////////////////////////////////
483 // BUFFER
484 /////////////////////////////////////////////
486 newgeoms = new vector<Geometry *>;
487 for (unsigned int i=0; i<geoms->size(); i++) {
488 Geometry *g = (*geoms)[i];
489 try {
490 Geometry *g2 = g->buffer(10);
491 newgeoms->push_back(g2);
493 catch (const GEOSException& exc) {
494 cerr <<"GEOS Exception: geometry "<<i<<"->buffer(10): "<<exc.what()<<"\n";
498 cout<<endl<<"--------HERE COMES THE BUFFERED GEOMS ----------"<<endl;
499 wkt_print_geoms(newgeoms);
501 for (unsigned int i=0; i<newgeoms->size(); i++) {
502 delete (*newgeoms)[i];
504 delete newgeoms;
506 /////////////////////////////////////////////
507 // CONVEX HULL
508 /////////////////////////////////////////////
510 // Make convex hulls of geometries
511 newgeoms = new vector<Geometry *>;
512 for (unsigned int i=0; i<geoms->size(); i++) {
513 Geometry *g = (*geoms)[i];
514 newgeoms->push_back( g->convexHull() );
517 // Print all convex hulls
518 cout<<endl<<"--------HERE COMES THE HULLS----------"<<endl;
519 wkt_print_geoms(newgeoms);
521 // Delete the hulls
522 for (unsigned int i=0; i<newgeoms->size(); i++) {
523 delete (*newgeoms)[i];
525 delete newgeoms;
527 #endif // UNARY_OPERATIONS
529 #if RELATIONAL_OPERATORS
531 ////////////////////////////////////////////////////////////////////////
532 // RELATIONAL OPERATORS
533 ////////////////////////////////////////////////////////////////////////
535 cout<<"-------------------------------------------------------------------------------"<<endl;
536 cout<<"RELATIONAL OPERATORS"<<endl;
537 cout<<"-------------------------------------------------------------------------------"<<endl;
539 /////////////////////////////////////////////
540 // DISJOINT
541 /////////////////////////////////////////////
543 cout<<endl;
544 cout<<" DISJOINT ";
545 for (unsigned int i=0; i<geoms->size(); i++) {
546 cout<<"\t["<<i<<"]";
548 cout<<endl;
549 for (unsigned int i=0; i<geoms->size(); i++) {
550 Geometry *g1 = (*geoms)[i];
551 cout<<" ["<<i<<"]\t";
552 for (unsigned int j=0; j<geoms->size(); j++) {
553 Geometry *g2 = (*geoms)[j];
554 try {
555 if ( g1->disjoint(g2) ) cout<<" 1\t";
556 else cout<<" 0\t";
558 // Geometry Collection is not a valid argument
559 catch (const IllegalArgumentException& exc) {
560 cout<<" X\t";
562 catch (const std::exception& exc) {
563 cerr<<exc.what()<<endl;
566 cout<<endl;
569 /////////////////////////////////////////////
570 // TOUCHES
571 /////////////////////////////////////////////
573 cout<<endl;
574 cout<<" TOUCHES ";
575 for (unsigned int i=0; i<geoms->size(); i++) {
576 cout<<"\t["<<i<<"]";
578 cout<<endl;
579 for (unsigned int i=0; i<geoms->size(); i++) {
580 Geometry *g1 = (*geoms)[i];
581 cout<<" ["<<i<<"]\t";
582 for (unsigned int j=0; j<geoms->size(); j++) {
583 Geometry *g2 = (*geoms)[j];
584 try {
585 if ( g1->touches(g2) ) cout<<" 1\t";
586 else cout<<" 0\t";
588 // Geometry Collection is not a valid argument
589 catch (const IllegalArgumentException& exc) {
590 cout<<" X\t";
592 catch (const std::exception& exc) {
593 cerr<<exc.what()<<endl;
596 cout<<endl;
599 /////////////////////////////////////////////
600 // INTERSECTS
601 /////////////////////////////////////////////
603 cout<<endl;
604 cout<<" INTERSECTS ";
605 for (unsigned int i=0; i<geoms->size(); i++) {
606 cout<<"\t["<<i<<"]";
608 cout<<endl;
609 for (unsigned int i=0; i<geoms->size(); i++) {
610 Geometry *g1 = (*geoms)[i];
611 cout<<" ["<<i<<"]\t";
612 for (unsigned int j=0; j<geoms->size(); j++) {
613 Geometry *g2 = (*geoms)[j];
614 try {
615 if ( g1->intersects(g2) ) cout<<" 1\t";
616 else cout<<" 0\t";
618 // Geometry Collection is not a valid argument
619 catch (const IllegalArgumentException& exc) {
620 cout<<" X\t";
622 catch (const std::exception& exc) {
623 cerr<<exc.what()<<endl;
626 cout<<endl;
629 /////////////////////////////////////////////
630 // CROSSES
631 /////////////////////////////////////////////
633 cout<<endl;
634 cout<<" CROSSES ";
635 for (unsigned int i=0; i<geoms->size(); i++) {
636 cout<<"\t["<<i<<"]";
638 cout<<endl;
639 for (unsigned int i=0; i<geoms->size(); i++) {
640 Geometry *g1 = (*geoms)[i];
641 cout<<" ["<<i<<"]\t";
642 for (unsigned int j=0; j<geoms->size(); j++) {
643 Geometry *g2 = (*geoms)[j];
644 try {
645 if ( g1->crosses(g2) ) cout<<" 1\t";
646 else cout<<" 0\t";
648 // Geometry Collection is not a valid argument
649 catch (const IllegalArgumentException& exc) {
650 cout<<" X\t";
652 catch (const std::exception& exc) {
653 cerr<<exc.what()<<endl;
656 cout<<endl;
659 /////////////////////////////////////////////
660 // WITHIN
661 /////////////////////////////////////////////
663 cout<<endl;
664 cout<<" WITHIN ";
665 for (unsigned int i=0; i<geoms->size(); i++) {
666 cout<<"\t["<<i<<"]";
668 cout<<endl;
669 for (unsigned int i=0; i<geoms->size(); i++) {
670 Geometry *g1 = (*geoms)[i];
671 cout<<" ["<<i<<"]\t";
672 for (unsigned int j=0; j<geoms->size(); j++) {
673 Geometry *g2 = (*geoms)[j];
674 try {
675 if ( g1->within(g2) ) cout<<" 1\t";
676 else cout<<" 0\t";
678 // Geometry Collection is not a valid argument
679 catch (const IllegalArgumentException& exc) {
680 cout<<" X\t";
682 catch (const std::exception& exc) {
683 cerr<<exc.what()<<endl;
686 cout<<endl;
689 /////////////////////////////////////////////
690 // CONTAINS
691 /////////////////////////////////////////////
693 cout<<endl;
694 cout<<" CONTAINS ";
695 for (unsigned int i=0; i<geoms->size(); i++) {
696 cout<<"\t["<<i<<"]";
698 cout<<endl;
699 for (unsigned int i=0; i<geoms->size(); i++) {
700 Geometry *g1 = (*geoms)[i];
701 cout<<" ["<<i<<"]\t";
702 for (unsigned int j=0; j<geoms->size(); j++) {
703 Geometry *g2 = (*geoms)[j];
704 try {
705 if ( g1->contains(g2) ) cout<<" 1\t";
706 else cout<<" 0\t";
708 // Geometry Collection is not a valid argument
709 catch (const IllegalArgumentException& exc) {
710 cout<<" X\t";
712 catch (const std::exception& exc) {
713 cerr<<exc.what()<<endl;
716 cout<<endl;
719 /////////////////////////////////////////////
720 // OVERLAPS
721 /////////////////////////////////////////////
723 cout<<endl;
724 cout<<" OVERLAPS ";
725 for (unsigned int i=0; i<geoms->size(); i++) {
726 cout<<"\t["<<i<<"]";
728 cout<<endl;
729 for (unsigned int i=0; i<geoms->size(); i++) {
730 Geometry *g1 = (*geoms)[i];
731 cout<<" ["<<i<<"]\t";
732 for (unsigned int j=0; j<geoms->size(); j++) {
733 Geometry *g2 = (*geoms)[j];
734 try {
735 if ( g1->overlaps(g2) ) cout<<" 1\t";
736 else cout<<" 0\t";
738 // Geometry Collection is not a valid argument
739 catch (const IllegalArgumentException& exc) {
740 cout<<" X\t";
742 catch (const std::exception& exc) {
743 cerr<<exc.what()<<endl;
746 cout<<endl;
749 /////////////////////////////////////////////
750 // RELATE
751 /////////////////////////////////////////////
753 cout<<endl;
754 cout<<" RELATE ";
755 for (unsigned int i=0; i<geoms->size(); i++) {
756 cout<<"\t["<<i<<"]";
758 cout<<endl;
759 for (unsigned int i=0; i<geoms->size(); i++) {
760 Geometry *g1 = (*geoms)[i];
761 cout<<" ["<<i<<"]\t";
762 for (unsigned int j=0; j<geoms->size(); j++) {
763 Geometry *g2 = (*geoms)[j];
764 IntersectionMatrix *im=NULL;
765 try {
766 // second argument is intersectionPattern
767 string pattern = "212101212";
768 if ( g1->relate(g2, pattern) ) cout<<" 1\t";
769 else cout<<" 0\t";
771 // get the intersectionMatrix itself
772 im=g1->relate(g2);
773 delete im; // delete afterwards
775 // Geometry Collection is not a valid argument
776 catch (const IllegalArgumentException& exc) {
777 cout<<" X\t";
779 catch (const std::exception& exc) {
780 cerr<<exc.what()<<endl;
783 cout<<endl;
786 /////////////////////////////////////////////
787 // EQUALS
788 /////////////////////////////////////////////
790 cout<<endl;
791 cout<<" EQUALS ";
792 for (unsigned int i=0; i<geoms->size(); i++) {
793 cout<<"\t["<<i<<"]";
795 cout<<endl;
796 for (unsigned int i=0; i<geoms->size(); i++) {
797 Geometry *g1 = (*geoms)[i];
798 cout<<" ["<<i<<"]\t";
799 for (unsigned int j=0; j<geoms->size(); j++) {
800 Geometry *g2 = (*geoms)[j];
801 try {
802 if ( g1->equals(g2) ) cout<<" 1\t";
803 else cout<<" 0\t";
805 // Geometry Collection is not a valid argument
806 catch (const IllegalArgumentException& exc) {
807 cout<<" X\t";
809 catch (const std::exception& exc) {
810 cerr<<exc.what()<<endl;
813 cout<<endl;
816 /////////////////////////////////////////////
817 // EQUALS_EXACT
818 /////////////////////////////////////////////
820 cout<<endl;
821 cout<<"EQUALS_EXACT ";
822 for (unsigned int i=0; i<geoms->size(); i++) {
823 cout<<"\t["<<i<<"]";
825 cout<<endl;
826 for (unsigned int i=0; i<geoms->size(); i++) {
827 Geometry *g1 = (*geoms)[i];
828 cout<<" ["<<i<<"]\t";
829 for (unsigned int j=0; j<geoms->size(); j++) {
830 Geometry *g2 = (*geoms)[j];
831 try {
832 // second argument is a tolerance
833 if ( g1->equalsExact(g2, 0.5) ) cout<<" 1\t";
834 else cout<<" 0\t";
836 // Geometry Collection is not a valid argument
837 catch (const IllegalArgumentException& exc) {
838 cout<<" X\t";
840 catch (const std::exception& exc) {
841 cerr<<exc.what()<<endl;
844 cout<<endl;
847 /////////////////////////////////////////////
848 // IS_WITHIN_DISTANCE
849 /////////////////////////////////////////////
851 cout<<endl;
852 cout<<"IS_WITHIN_DIST";
853 for (unsigned int i=0; i<geoms->size(); i++) {
854 cout<<"\t["<<i<<"]";
856 cout<<endl;
857 for (unsigned int i=0; i<geoms->size(); i++) {
858 Geometry *g1 = (*geoms)[i];
859 cout<<" ["<<i<<"]\t";
860 for (unsigned int j=0; j<geoms->size(); j++) {
861 Geometry *g2 = (*geoms)[j];
862 try {
863 // second argument is the distance
864 if ( g1->isWithinDistance(g2,2) ) cout<<" 1\t";
865 else cout<<" 0\t";
867 // Geometry Collection is not a valid argument
868 catch (const IllegalArgumentException& exc) {
869 cout<<" X\t";
871 catch (const std::exception& exc) {
872 cerr<<exc.what()<<endl;
875 cout<<endl;
878 #endif // RELATIONAL_OPERATORS
880 #if COMBINATIONS
882 ////////////////////////////////////////////////////////////////////////
883 // COMBINATIONS
884 ////////////////////////////////////////////////////////////////////////
886 cout<<endl;
887 cout<<"-------------------------------------------------------------------------------"<<endl;
888 cout<<"COMBINATIONS"<<endl;
889 cout<<"-------------------------------------------------------------------------------"<<endl;
891 /////////////////////////////////////////////
892 // UNION
893 /////////////////////////////////////////////
895 // Make unions of all geoms
896 newgeoms = new vector<Geometry *>;
897 for (unsigned int i=0; i<geoms->size()-1; i++) {
898 Geometry *g1 = (*geoms)[i];
899 for (unsigned int j=i+1; j<geoms->size(); j++) {
900 Geometry *g2 = (*geoms)[j];
901 try {
902 Geometry *g3 = g1->Union(g2);
903 newgeoms->push_back(g3);
905 // It's illegal to union a collection ...
906 catch (const IllegalArgumentException& ill) {
907 //cerr <<ill.toString()<<"\n";
909 catch (const std::exception& exc) {
910 cerr<<exc.what()<<endl;
915 // Print all unions
916 cout<<endl<<"----- AND HERE ARE SOME UNION COMBINATIONS ------"<<endl;
917 wkt_print_geoms(newgeoms);
919 // Delete the resulting geoms
920 for (unsigned int i=0; i<newgeoms->size(); i++) {
921 delete (*newgeoms)[i];
923 delete newgeoms;
926 /////////////////////////////////////////////
927 // INTERSECTION
928 /////////////////////////////////////////////
930 // Compute intersection of adhiacent geometries
931 newgeoms = new vector<Geometry *>;
932 for (unsigned int i=0; i<geoms->size()-1; i++) {
933 Geometry *g1 = (*geoms)[i];
934 for (unsigned int j=i+1; j<geoms->size(); j++) {
935 Geometry *g2 = (*geoms)[j];
936 try {
937 Geometry *g3 = g1->intersection(g2);
938 newgeoms->push_back(g3);
940 // Collection are illegal as intersection argument
941 catch (const IllegalArgumentException& ill) {
942 //cerr <<ill.toString()<<"\n";
944 catch (const std::exception& exc) {
945 cerr<<exc.what()<<endl;
950 cout<<endl<<"----- HERE ARE SOME INTERSECTIONS COMBINATIONS ------"<<endl;
951 wkt_print_geoms(newgeoms);
953 // Delete the resulting geoms
954 for (unsigned int i=0; i<newgeoms->size(); i++) {
955 delete (*newgeoms)[i];
957 delete newgeoms;
959 /////////////////////////////////////////////
960 // DIFFERENCE
961 /////////////////////////////////////////////
963 // Compute difference of adhiacent geometries
964 newgeoms = new vector<Geometry *>;
965 for (unsigned int i=0; i<geoms->size()-1; i++) {
966 Geometry *g1 = (*geoms)[i];
967 for (unsigned int j=i+1; j<geoms->size(); j++) {
968 Geometry *g2 = (*geoms)[j];
969 try {
970 Geometry *g3 = g1->difference(g2);
971 newgeoms->push_back(g3);
973 // Collection are illegal as difference argument
974 catch (const IllegalArgumentException& ill) {
975 //cerr <<ill.toString()<<"\n";
977 catch (const std::exception& exc) {
978 cerr<<exc.what()<<endl;
983 cout<<endl<<"----- HERE ARE SOME DIFFERENCE COMBINATIONS ------"<<endl;
984 wkt_print_geoms(newgeoms);
986 // Delete the resulting geoms
987 for (unsigned int i=0; i<newgeoms->size(); i++) {
988 delete (*newgeoms)[i];
990 delete newgeoms;
992 /////////////////////////////////////////////
993 // SYMMETRIC DIFFERENCE
994 /////////////////////////////////////////////
996 // Compute symmetric difference of adhiacent geometries
997 newgeoms = new vector<Geometry *>;
998 for (unsigned int i=0; i<geoms->size()-1; i++) {
999 Geometry *g1 = (*geoms)[i];
1000 for (unsigned int j=i+1; j<geoms->size(); j++) {
1001 Geometry *g2 = (*geoms)[j];
1002 try {
1003 Geometry *g3 = g1->symDifference(g2);
1004 newgeoms->push_back(g3);
1006 // Collection are illegal as symdifference argument
1007 catch (const IllegalArgumentException& ill) {
1008 //cerr <<ill.toString()<<"\n";
1010 catch (const std::exception& exc) {
1011 cerr<<exc.what()<<endl;
1016 cout<<endl<<"----- HERE ARE SYMMETRIC DIFFERENCES ------"<<endl;
1017 wkt_print_geoms(newgeoms);
1019 // Delete the resulting geoms
1020 for (unsigned int i=0; i<newgeoms->size(); i++) {
1021 delete (*newgeoms)[i];
1023 delete newgeoms;
1025 #endif // COMBINATIONS
1027 #if LINEMERGE
1029 /////////////////////////////////////////////
1030 // LINEMERGE
1031 /////////////////////////////////////////////
1032 LineMerger lm;
1033 lm.add(geoms);
1034 vector<LineString *> *mls = lm.getMergedLineStrings();
1035 newgeoms = new vector<Geometry *>;
1036 for (unsigned int i=0; i<mls->size(); i++)
1037 newgeoms->push_back((*mls)[i]);
1038 delete mls;
1040 cout<<endl<<"----- HERE IS THE LINEMERGE OUTPUT ------"<<endl;
1041 wkt_print_geoms(newgeoms);
1043 // Delete the resulting geoms
1044 for (unsigned int i=0; i<newgeoms->size(); i++) {
1045 delete (*newgeoms)[i];
1047 delete newgeoms;
1049 #endif // LINEMERGE
1051 #if POLYGONIZE
1053 /////////////////////////////////////////////
1054 // POLYGONIZE
1055 /////////////////////////////////////////////
1056 Polygonizer plgnzr;
1057 plgnzr.add(geoms);
1058 vector<Polygon *> *polys = plgnzr.getPolygons();
1059 newgeoms = new vector<Geometry *>;
1060 for (unsigned int i=0; i<polys->size(); i++)
1061 newgeoms->push_back((*polys)[i]);
1062 delete polys;
1064 cout<<endl<<"----- HERE IS POLYGONIZE OUTPUT ------"<<endl;
1065 wkt_print_geoms(newgeoms);
1067 // Delete the resulting geoms
1068 for (unsigned int i=0; i<newgeoms->size(); i++) {
1069 delete (*newgeoms)[i];
1071 delete newgeoms;
1073 #endif // POLYGONIZE
1075 /////////////////////////////////////////////
1076 // CLEANUP
1077 /////////////////////////////////////////////
1079 // Delete base geometries
1080 for (unsigned int i=0; i<geoms->size(); i++) {
1081 delete (*geoms)[i];
1083 delete geoms;
1085 delete global_factory;
1089 main()
1091 cout<<"GEOS "<<geosversion()<<" ported from JTS "<<jtsport()<<endl;
1094 do_all();
1096 // All exception thrown by GEOS are subclasses of this
1097 // one, so this is a catch-all
1098 catch (const GEOSException& exc)
1100 cerr <<"GEOS Exception: "<<exc.what()<<"\n";
1101 exit(1);
1103 catch (const exception &e)
1105 cerr <<"Standard exception thrown: "<<e.what()<<endl;
1106 exit(1);
1108 // and this is a catch-all non standard ;)
1109 catch (...)
1111 cerr <<"unknown exception trown!\n";
1112 exit(1);
1115 // Unload is no more necessary
1116 //io::Unload::Release();
1118 exit(0);
1121 /**********************************************************************
1122 * $Log$
1123 * Revision 1.46 2006/04/09 11:07:54 mloskot
1124 * Small fixes in doc/example.cpp.
1126 * Revision 1.45 2006/04/04 08:16:46 strk
1127 * Changed GEOSException hierarchy to be derived from std::runtime_exception.
1128 * Removed the GEOSException::toString redundant method (use ::what() instead)
1130 * Revision 1.44 2006/03/28 15:19:22 strk
1131 * Added macros for sections skip (useful in debugging)
1133 * Revision 1.43 2006/03/15 18:44:51 strk
1134 * Bug #60 - Missing <cmath> header in some files
1136 * Revision 1.42 2006/03/06 21:27:39 strk
1137 * Cascading fixed after Unload definition moved to geos::io namespace
1139 * Revision 1.41 2006/03/06 19:40:46 strk
1140 * geos::util namespace. New GeometryCollection::iterator interface, many cleanups.
1142 * Revision 1.40 2006/03/06 15:23:14 strk
1143 * geos::io namespace
1145 * Revision 1.39 2006/03/03 10:46:21 strk
1146 * Removed 'using namespace' from headers, added missing headers in .cpp files, removed useless includes in headers (bug#46)
1148 * Revision 1.38 2006/02/19 19:46:49 strk
1149 * Packages <-> namespaces mapping for most GEOS internal code (uncomplete, but working). Dir-level libs for index/ subdirs.
1151 * Revision 1.37 2006/02/09 15:52:47 strk
1152 * GEOSException derived from std::exception; always thrown and cought by const ref.
1154 * Revision 1.36 2006/01/31 19:07:33 strk
1155 * - Renamed DefaultCoordinateSequence to CoordinateArraySequence.
1156 * - Moved GetNumGeometries() and GetGeometryN() interfaces
1157 * from GeometryCollection to Geometry class.
1158 * - Added getAt(int pos, Coordinate &to) funtion to CoordinateSequence class.
1159 * - Reworked automake scripts to produce a static lib for each subdir and
1160 * then link all subsystem's libs togheter
1161 * - Moved C-API in it's own top-level dir capi/
1162 * - Moved source/bigtest and source/test to tests/bigtest and test/xmltester
1163 * - Fixed PointLocator handling of LinearRings
1164 * - Changed CoordinateArrayFilter to reduce memory copies
1165 * - Changed UniqueCoordinateArrayFilter to reduce memory copies
1166 * - Added CGAlgorithms::isPointInRing() version working with
1167 * Coordinate::ConstVect type (faster!)
1168 * - Ported JTS-1.7 version of ConvexHull with big attention to
1169 * memory usage optimizations.
1170 * - Improved XMLTester output and user interface
1171 * - geos::geom::util namespace used for geom/util stuff
1172 * - Improved memory use in geos::geom::util::PolygonExtractor
1173 * - New ShortCircuitedGeometryVisitor class
1174 * - New operation/predicate package
1176 * Revision 1.35 2005/11/30 11:27:07 strk
1177 * catch std::exception by ref
1179 * Revision 1.34 2005/11/30 11:25:12 strk
1180 * includes cleanup
1182 * Revision 1.33 2005/09/27 16:20:43 strk
1183 * Reverted previous change, fixed the bug by turning WKBReader.factory
1184 * into a reference rather then a real object. ABI still breaks, but API
1185 * at least is safe (we didn't release any WKB-aware package so breaking
1186 * ABI is not a big deal at this stage).
1188 * Revision 1.32 2005/09/27 16:00:26 strk
1189 * Fixed bug in WKBReader destroying the GeometryFactory used in Geometry
1190 * construction. Changed it's definition to *require* a GeometryFactory
1191 * pointer parameter.
1193 * Revision 1.31 2005/09/26 08:17:19 strk
1194 * Removed memory leak from WKB tester
1196 * Revision 1.30 2005/09/03 21:26:42 strk
1197 * Reworked WKB I/O to avoid use of templates and make better use of STL
1199 * Revision 1.29 2005/07/11 12:17:26 strk
1200 * Commented out useless include
1202 * Revision 1.28 2005/04/29 16:36:28 strk
1203 * Made WKBReader use global_factory, for having WKB reads produce
1204 * same context of input geoms.
1206 * Revision 1.27 2005/04/29 15:34:20 strk
1207 * Typedef'ed biostringstream, preferred parameter for
1208 * WKB parser templates.
1209 * Added << operator for biostringstream.
1210 * Typedef'ed WKBWriter and WKBReader to be parametrized by
1211 * biostringstream.
1212 * Added WKBtest in doc/example.cpp
1214 * Revision 1.26 2004/12/08 13:54:43 strk
1215 * gcc warnings checked and fixed, general cleanups.
1217 * Revision 1.25 2004/10/13 10:03:02 strk
1218 * Added missing linemerge and polygonize operation.
1219 * Bug fixes and leaks removal from the newly added modules and
1220 * planargraph (used by them).
1221 * Some comments and indentation changes.
1223 * Revision 1.24 2004/07/22 16:58:01 strk
1224 * runtime version extractor functions split. geos::version() is now
1225 * geos::geosversion() and geos::jtsport()
1227 * Revision 1.23 2004/07/17 09:19:32 strk
1228 * added GEOS version report
1230 *********************************************************************/