root/MGET/Branches/Jason/Libraries/geos-3.3.2/capi/geos_ts_c.cpp @ 891

Revision 891, 138.1 KB (checked in by jjr8, 17 months ago)

* Incremented build number.
* Added Libraries/geos-3.3.2

Line 
1/************************************************************************
2 *
3 * $Id: geos_ts_c.cpp 3322 2011-05-03 02:27:00Z sgillies $
4 *
5 * C-Wrapper for GEOS library
6 *
7 * Copyright (C) 2010 2011 Sandro Santilli <strk@keybit.net>
8 * Copyright (C) 2005-2006 Refractions Research Inc.
9 *
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.
14 *
15 * Author: Sandro Santilli <strk@refractions.net>
16 * Thread Safety modifications: Chuck Thibert <charles.thibert@ingres.com>
17 *
18 ***********************************************************************/
19
20#include <geos/platform.h>  // for FINITE
21#include <geos/geom/Geometry.h>
22#include <geos/geom/prep/PreparedGeometry.h>
23#include <geos/geom/prep/PreparedGeometryFactory.h>
24#include <geos/geom/GeometryCollection.h>
25#include <geos/geom/Polygon.h>
26#include <geos/geom/Point.h>
27#include <geos/geom/MultiPoint.h>
28#include <geos/geom/MultiLineString.h>
29#include <geos/geom/MultiPolygon.h>
30#include <geos/geom/LinearRing.h>
31#include <geos/geom/LineString.h>
32#include <geos/geom/PrecisionModel.h>
33#include <geos/geom/GeometryFactory.h>
34#include <geos/geom/CoordinateSequenceFactory.h>
35#include <geos/geom/Coordinate.h>
36#include <geos/geom/IntersectionMatrix.h>
37#include <geos/geom/Envelope.h>
38#include <geos/index/strtree/STRtree.h>
39#include <geos/index/ItemVisitor.h>
40#include <geos/io/WKTReader.h>
41#include <geos/io/WKBReader.h>
42#include <geos/io/WKTWriter.h>
43#include <geos/io/WKBWriter.h>
44#include <geos/algorithm/distance/DiscreteHausdorffDistance.h>
45#include <geos/algorithm/CGAlgorithms.h>
46#include <geos/algorithm/BoundaryNodeRule.h>
47#include <geos/simplify/DouglasPeuckerSimplifier.h>
48#include <geos/simplify/TopologyPreservingSimplifier.h>
49#include <geos/operation/valid/IsValidOp.h>
50#include <geos/operation/polygonize/Polygonizer.h>
51#include <geos/operation/linemerge/LineMerger.h>
52#include <geos/operation/overlay/OverlayOp.h>
53#include <geos/operation/union/CascadedPolygonUnion.h>
54#include <geos/operation/buffer/BufferOp.h>
55#include <geos/operation/buffer/BufferParameters.h>
56#include <geos/operation/buffer/BufferBuilder.h>
57#include <geos/operation/relate/RelateOp.h>
58#include <geos/operation/sharedpaths/SharedPathsOp.h>
59#include <geos/linearref/LengthIndexedLine.h>
60#include <geos/geom/BinaryOp.h>
61#include <geos/util/IllegalArgumentException.h>
62#include <geos/util/UniqueCoordinateArrayFilter.h>
63#include <geos/util/Machine.h>
64#include <geos/version.h>
65
66// This should go away
67#include <cmath> // finite
68#include <cstddef>
69#include <cstdio>
70#include <cstdlib>
71#include <cstring>
72#include <fstream>
73#include <iostream>
74#include <sstream>
75#include <string>
76#include <memory>
77
78#ifdef _MSC_VER
79#pragma warning(disable : 4099)
80#endif
81
82// Some extra magic to make type declarations in geos_c.h work -
83// for cross-checking of types in header.
84#define GEOSGeometry geos::geom::Geometry
85#define GEOSPreparedGeometry geos::geom::prep::PreparedGeometry
86#define GEOSCoordSequence geos::geom::CoordinateSequence
87#define GEOSBufferParams geos::operation::buffer::BufferParameters
88#define GEOSSTRtree geos::index::strtree::STRtree
89#define GEOSWKTReader_t geos::io::WKTReader
90#define GEOSWKTWriter_t geos::io::WKTWriter
91#define GEOSWKBReader_t geos::io::WKBReader
92#define GEOSWKBWriter_t geos::io::WKBWriter
93
94#include "geos_c.h"
95
96// Intentional, to allow non-standard C elements like C99 functions to be
97// imported through C++ headers of C library, like <cmath>.
98using namespace std;
99
100/// Define this if you want operations triggering Exceptions to
101/// be printed.
102/// (will use the NOTIFY channel - only implemented for GEOSUnion so far)
103///
104#undef VERBOSE_EXCEPTIONS
105
106#include <geos/export.h>
107
108
109// import the most frequently used definitions globally
110using geos::geom::Geometry;
111using geos::geom::LineString;
112using geos::geom::Polygon;
113using geos::geom::CoordinateSequence;
114using geos::geom::GeometryFactory;
115
116using geos::io::WKTReader;
117using geos::io::WKTWriter;
118using geos::io::WKBReader;
119using geos::io::WKBWriter;
120
121using geos::operation::overlay::OverlayOp;
122using geos::operation::overlay::overlayOp;
123using geos::operation::geounion::CascadedPolygonUnion;
124using geos::operation::buffer::BufferParameters;
125using geos::operation::buffer::BufferBuilder;
126using geos::util::IllegalArgumentException;
127using geos::algorithm::distance::DiscreteHausdorffDistance;
128
129typedef std::auto_ptr<Geometry> GeomAutoPtr;
130
131typedef struct GEOSContextHandleInternal
132{
133    const GeometryFactory *geomFactory;
134    GEOSMessageHandler NOTICE_MESSAGE;
135    GEOSMessageHandler ERROR_MESSAGE;
136    int WKBOutputDims;
137    int WKBByteOrder;
138    int initialized;
139} GEOSContextHandleInternal_t;
140
141// CAPI_ItemVisitor is used internally by the CAPI STRtree
142// wrappers. It's defined here just to keep it out of the
143// extern "C" block.
144class CAPI_ItemVisitor : public geos::index::ItemVisitor {
145    GEOSQueryCallback callback;
146    void *userdata;
147  public:
148    CAPI_ItemVisitor (GEOSQueryCallback cb, void *ud)
149        : ItemVisitor(), callback(cb), userdata(ud) {};
150    void visitItem (void *item) { callback(item, userdata); };
151};
152
153
154//## PROTOTYPES #############################################
155
156extern "C" const char GEOS_DLL *GEOSjtsport();
157extern "C" char GEOS_DLL *GEOSasText(Geometry *g1);
158
159namespace { // anonymous
160
161char* gstrdup_s(const char* str, const std::size_t size)
162{
163    char* out = static_cast<char*>(std::malloc(size + 1));
164    if (0 != out)
165    {
166        // as no strlen call necessary, memcpy may be faster than strcpy
167        std::memcpy(out, str, size + 1);
168    }
169
170    assert(0 != out);
171   
172    // we haven't been checking allocation before ticket #371
173    if (0 == out)
174    {
175        throw(std::runtime_error("Failed to allocate memory for duplicate string"));
176    }
177
178    return out;
179}
180
181char* gstrdup(std::string const& str)
182{
183    return gstrdup_s(str.c_str(), str.size());
184}
185
186} // namespace anonymous
187
188extern "C" {
189
190GEOSContextHandle_t
191initGEOS_r(GEOSMessageHandler nf, GEOSMessageHandler ef)
192{
193    GEOSContextHandleInternal_t *handle = 0;
194    void *extHandle = 0;
195
196    extHandle = std::malloc(sizeof(GEOSContextHandleInternal_t));
197    if (0 != extHandle)
198    {
199        handle = static_cast<GEOSContextHandleInternal_t*>(extHandle);
200        handle->NOTICE_MESSAGE = nf;
201        handle->ERROR_MESSAGE = ef;
202        handle->geomFactory = GeometryFactory::getDefaultInstance();
203        handle->WKBOutputDims = 2;
204        handle->WKBByteOrder = getMachineByteOrder();
205        handle->initialized = 1;
206    }
207
208    return static_cast<GEOSContextHandle_t>(extHandle);
209}
210
211GEOSMessageHandler
212GEOSContext_setNoticeHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf)
213{
214    GEOSMessageHandler f;
215    GEOSContextHandleInternal_t *handle = 0;
216    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
217    if ( 0 == handle->initialized )
218    {
219        return NULL;
220    }
221
222    f = handle->NOTICE_MESSAGE;
223    handle->NOTICE_MESSAGE = nf;
224
225    return f;
226}
227
228GEOSMessageHandler
229GEOSContext_setErrorHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf)
230{
231    GEOSMessageHandler f;
232    GEOSContextHandleInternal_t *handle = 0;
233    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
234    if ( 0 == handle->initialized )
235    {
236        return NULL;
237    }
238
239    f = handle->ERROR_MESSAGE;
240    handle->ERROR_MESSAGE = nf;
241
242    return f;
243}
244
245void
246finishGEOS_r(GEOSContextHandle_t extHandle)
247{
248    // Fix up freeing handle w.r.t. malloc above
249    std::free(extHandle);
250    extHandle = NULL;
251}
252
253void
254GEOSFree_r (GEOSContextHandle_t extHandle, void* buffer)
255{
256    assert(0 != extHandle);
257
258    std::free(buffer);
259}
260
261//-----------------------------------------------------------
262// relate()-related functions
263//  return 0 = false, 1 = true, 2 = error occured
264//-----------------------------------------------------------
265
266char
267GEOSDisjoint_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
268{
269    if ( 0 == extHandle )
270    {
271        return 2;
272    }
273
274    GEOSContextHandleInternal_t *handle = 0;
275    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
276    if ( handle->initialized == 0 )
277    {
278        return 2;
279    }
280
281    try
282    {
283        bool result = g1->disjoint(g2);
284        return result;
285    }
286
287    // TODO: mloskot is going to replace these double-catch block
288    // with a macro to remove redundant code in this and
289    // following functions.
290    catch (const std::exception &e)
291    {
292        handle->ERROR_MESSAGE("%s", e.what());
293    }
294    catch (...)
295    {
296        handle->ERROR_MESSAGE("Unknown exception thrown");
297    }
298
299    return 2;
300}
301
302char
303GEOSTouches_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
304{
305    if ( 0 == extHandle )
306    {
307        return 2;
308    }
309
310    GEOSContextHandleInternal_t *handle = 0;
311    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
312    if ( 0 == handle->initialized )
313    {
314        return 2;
315    }
316
317    try
318    {
319        bool result = g1->touches(g2);
320        return result;
321    }
322    catch (const std::exception &e)
323    {
324        handle->ERROR_MESSAGE("%s", e.what());
325    }
326    catch (...)
327    {
328        handle->ERROR_MESSAGE("Unknown exception thrown");
329    }
330   
331    return 2;
332}
333
334char
335GEOSIntersects_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
336{
337    if ( 0 == extHandle )
338    {
339        return 2;
340    }
341
342    GEOSContextHandleInternal_t *handle = 0;
343    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
344    if ( 0 == handle->initialized )
345    {
346        return 2;
347    }
348
349    try
350    {
351        bool result = g1->intersects(g2);
352        return result;
353    }
354    catch (const std::exception &e)
355    {
356        handle->ERROR_MESSAGE("%s", e.what());
357    }
358    catch (...)
359    {
360        handle->ERROR_MESSAGE("Unknown exception thrown");
361    }
362   
363    return 2;
364}
365
366char
367GEOSCrosses_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
368{
369    if ( 0 == extHandle )
370    {
371        return 2;
372    }
373
374    GEOSContextHandleInternal_t *handle = 0;
375    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
376    if ( 0 == handle->initialized )
377    {
378        return 2;
379    }
380
381    try
382    {
383        bool result = g1->crosses(g2);
384        return result;
385    }
386    catch (const std::exception &e)
387    {
388        handle->ERROR_MESSAGE("%s", e.what());
389    }
390    catch (...)
391    {
392        handle->ERROR_MESSAGE("Unknown exception thrown");
393    }
394   
395    return 2;
396}
397
398char
399GEOSWithin_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
400{
401    if ( 0 == extHandle )
402    {
403        return 2;
404    }
405
406    GEOSContextHandleInternal_t *handle = 0;
407    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
408    if ( 0 == handle->initialized )
409    {
410        return 2;
411    }
412
413    try
414    {
415        bool result = g1->within(g2);
416        return result;
417    }
418    catch (const std::exception &e)
419    {
420        handle->ERROR_MESSAGE("%s", e.what());
421    }
422    catch (...)
423    {
424        handle->ERROR_MESSAGE("Unknown exception thrown");
425    }
426   
427    return 2;
428}
429
430// call g1->contains(g2)
431// returns 0 = false
432//         1 = true
433//         2 = error was trapped
434char
435GEOSContains_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
436{
437    if ( 0 == extHandle )
438    {
439        return 2;
440    }
441
442    GEOSContextHandleInternal_t *handle = 0;
443    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
444    if ( 0 == handle->initialized )
445    {
446        return 2;
447    }
448
449    try
450    {
451        bool result = g1->contains(g2);
452        return result;
453    }
454    catch (const std::exception &e)
455    {
456        handle->ERROR_MESSAGE("%s", e.what());
457    }
458    catch (...)
459    {
460        handle->ERROR_MESSAGE("Unknown exception thrown");
461    }
462   
463    return 2;
464}
465
466char
467GEOSOverlaps_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
468{
469    if ( 0 == extHandle )
470    {
471        return 2;
472    }
473
474    GEOSContextHandleInternal_t *handle = 0;
475    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
476    if ( 0 == handle->initialized )
477    {
478        return 2;
479    }
480
481    try
482    {
483        bool result = g1->overlaps(g2);
484        return result;
485    }
486    catch (const std::exception &e)
487    {
488        handle->ERROR_MESSAGE("%s", e.what());
489    }
490    catch (...)
491    {
492        handle->ERROR_MESSAGE("Unknown exception thrown");
493    }
494   
495    return 2;
496}
497
498char
499GEOSCovers_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
500{
501    if ( 0 == extHandle )
502    {
503        return 2;
504    }
505
506    GEOSContextHandleInternal_t *handle = 0;
507    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
508    if ( 0 == handle->initialized )
509    {
510        return 2;
511    }
512
513    try
514    {
515        bool result = g1->covers(g2);
516        return result;
517    }
518    catch (const std::exception &e)
519    {
520        handle->ERROR_MESSAGE("%s", e.what());
521    }
522    catch (...)
523    {
524        handle->ERROR_MESSAGE("Unknown exception thrown");
525    }
526   
527    return 2;
528}
529
530char
531GEOSCoveredBy_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
532{
533    if ( 0 == extHandle )
534    {
535        return 2;
536    }
537
538    GEOSContextHandleInternal_t *handle = 0;
539    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
540    if ( 0 == handle->initialized )
541    {
542        return 2;
543    }
544
545    try
546    {
547        bool result = g1->coveredBy(g2);
548        return result;
549    }
550    catch (const std::exception &e)
551    {
552        handle->ERROR_MESSAGE("%s", e.what());
553    }
554    catch (...)
555    {
556        handle->ERROR_MESSAGE("Unknown exception thrown");
557    }
558   
559    return 2;
560}
561
562
563//-------------------------------------------------------------------
564// low-level relate functions
565//------------------------------------------------------------------
566
567char
568GEOSRelatePattern_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, const char *pat)
569{
570    if ( 0 == extHandle )
571    {
572        return 2;
573    }
574
575    GEOSContextHandleInternal_t *handle = 0;
576    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
577    if ( 0 == handle->initialized )
578    {
579        return 2;
580    }
581
582    try
583    {
584        std::string s(pat);
585        bool result = g1->relate(g2, s);
586        return result;
587    }
588    catch (const std::exception &e)
589    {
590        handle->ERROR_MESSAGE("%s", e.what());
591    }
592    catch (...)
593    {
594        handle->ERROR_MESSAGE("Unknown exception thrown");
595    }
596   
597    return 2;
598}
599
600char
601GEOSRelatePatternMatch_r(GEOSContextHandle_t extHandle, const char *mat,
602                           const char *pat)
603{
604    if ( 0 == extHandle )
605    {
606        return 2;
607    }
608
609    GEOSContextHandleInternal_t *handle = 0;
610    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
611    if ( 0 == handle->initialized )
612    {
613        return 2;
614    }
615
616    try
617    {
618        using geos::geom::IntersectionMatrix;
619
620        std::string m(mat);
621        std::string p(pat);
622        IntersectionMatrix im(m);
623
624        bool result = im.matches(p);
625        return result;
626    }
627    catch (const std::exception &e)
628    {
629        handle->ERROR_MESSAGE("%s", e.what());
630    }
631    catch (...)
632    {
633        handle->ERROR_MESSAGE("Unknown exception thrown");
634    }
635   
636    return 2;
637}
638
639char *
640GEOSRelate_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
641{
642    if ( 0 == extHandle )
643    {
644        return NULL;
645    }
646
647    GEOSContextHandleInternal_t *handle = 0;
648    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
649    if ( 0 == handle->initialized )
650    {
651        return NULL;
652    }
653
654    try
655    {
656        using geos::geom::IntersectionMatrix;
657
658        IntersectionMatrix* im = g1->relate(g2);
659        if (0 == im)
660        {
661            return 0;
662        }
663       
664        char *result = gstrdup(im->toString());
665
666        delete im;
667        im = 0;
668
669        return result;
670    }
671    catch (const std::exception &e)
672    {
673        handle->ERROR_MESSAGE("%s", e.what());
674    }
675    catch (...)
676    {
677        handle->ERROR_MESSAGE("Unknown exception thrown");
678    }
679   
680    return NULL;
681}
682
683char *
684GEOSRelateBoundaryNodeRule_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, int bnr)
685{
686    if ( 0 == extHandle )
687    {
688        return NULL;
689    }
690
691    GEOSContextHandleInternal_t *handle = 0;
692    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
693    if ( 0 == handle->initialized )
694    {
695        return NULL;
696    }
697
698    try
699    {
700        using geos::operation::relate::RelateOp;
701        using geos::geom::IntersectionMatrix;
702        using geos::algorithm::BoundaryNodeRule;
703
704        IntersectionMatrix* im;
705        switch (bnr) {
706          case GEOSRELATE_BNR_MOD2: /* same as OGC */
707            im = RelateOp::relate(g1, g2,
708              BoundaryNodeRule::MOD2_BOUNDARY_RULE);
709            break;
710          case GEOSRELATE_BNR_ENDPOINT:
711            im = RelateOp::relate(g1, g2,
712              BoundaryNodeRule::ENDPOINT_BOUNDARY_RULE);
713            break;
714          case GEOSRELATE_BNR_MULTIVALENT_ENDPOINT:
715            im = RelateOp::relate(g1, g2,
716              BoundaryNodeRule::MULTIVALENT_ENDPOINT_BOUNDARY_RULE);
717            break;
718          case GEOSRELATE_BNR_MONOVALENT_ENDPOINT:
719            im = RelateOp::relate(g1, g2,
720              BoundaryNodeRule::MONOVALENT_ENDPOINT_BOUNDARY_RULE);
721            break;
722          default:
723            handle->ERROR_MESSAGE("Invalid boundary node rule %d", bnr);
724            return 0;
725            break;
726        }
727
728        if (0 == im) return 0;
729       
730        char *result = gstrdup(im->toString());
731
732        delete im;
733        im = 0;
734
735        return result;
736    }
737    catch (const std::exception &e)
738    {
739        handle->ERROR_MESSAGE("%s", e.what());
740    }
741    catch (...)
742    {
743        handle->ERROR_MESSAGE("Unknown exception thrown");
744    }
745   
746    return NULL;
747}
748
749
750
751//-----------------------------------------------------------------
752// isValid
753//-----------------------------------------------------------------
754
755
756char
757GEOSisValid_r(GEOSContextHandle_t extHandle, const Geometry *g1)
758{
759    if ( 0 == extHandle )
760    {
761        return 2;
762    }
763
764    GEOSContextHandleInternal_t *handle = 0;
765    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
766    if ( 0 == handle->initialized )
767    {
768        return 2;
769    }
770
771    try
772    {
773        using geos::operation::valid::IsValidOp;
774        using geos::operation::valid::TopologyValidationError;
775
776        IsValidOp ivo(g1);
777        TopologyValidationError *err = ivo.getValidationError();
778        if ( err )
779        {
780           handle->NOTICE_MESSAGE("%s", err->toString().c_str());
781           return 0;
782        }
783        else
784        {
785           return 1;
786        }
787    }
788    catch (const std::exception &e)
789    {
790        handle->ERROR_MESSAGE("%s", e.what());
791    }
792    catch (...)
793    {
794        handle->ERROR_MESSAGE("Unknown exception thrown");
795    }
796   
797    return 2;
798}
799
800char *
801GEOSisValidReason_r(GEOSContextHandle_t extHandle, const Geometry *g1)
802{
803    if ( 0 == extHandle )
804    {
805        return NULL;
806    }
807
808    GEOSContextHandleInternal_t *handle = 0;
809    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
810    if ( 0 == handle->initialized )
811    {
812        return NULL;
813    }
814
815    try
816    {
817        using geos::operation::valid::IsValidOp;
818        using geos::operation::valid::TopologyValidationError;
819
820        char* result = 0;
821        char const* const validstr = "Valid Geometry";
822
823        IsValidOp ivo(g1);
824        TopologyValidationError *err = ivo.getValidationError();
825        if (0 != err)
826        {
827            std::ostringstream ss;
828            ss.precision(15);
829            ss << err->getCoordinate();
830            const std::string errloc = ss.str();
831            std::string errmsg(err->getMessage());
832            errmsg += "[" + errloc + "]";
833            result = gstrdup(errmsg);
834        }
835        else
836        {
837            result = gstrdup(std::string(validstr));
838        }
839
840        return result;
841    }
842    catch (const std::exception &e)
843    {
844        handle->ERROR_MESSAGE("%s", e.what());
845    }
846    catch (...)
847    {
848        handle->ERROR_MESSAGE("Unknown exception thrown");
849    }
850
851    return 0;
852}
853
854char
855GEOSisValidDetail_r(GEOSContextHandle_t extHandle, const Geometry *g,
856        int flags, char** reason, Geometry ** location)
857{
858    if ( 0 == extHandle )
859    {
860        return 0;
861    }
862
863    GEOSContextHandleInternal_t *handle = 0;
864    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
865    if ( 0 == handle->initialized )
866    {
867        return 0;
868    }
869
870    try
871    {
872        using geos::operation::valid::IsValidOp;
873        using geos::operation::valid::TopologyValidationError;
874
875        IsValidOp ivo(g);
876        if ( flags & GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE ) {
877                ivo.setSelfTouchingRingFormingHoleValid(true);
878        }
879        TopologyValidationError *err = ivo.getValidationError();
880        if (0 != err)
881        {
882          if ( location ) {
883            *location = handle->geomFactory->createPoint(err->getCoordinate());
884          }
885          if ( reason ) {
886            std::string errmsg(err->getMessage());
887            *reason = gstrdup(errmsg);
888          }
889          return 0;
890        }
891
892        if ( location ) *location = 0;
893        if ( reason ) *reason = 0;
894        return 1; /* valid */
895
896    }
897    catch (const std::exception &e)
898    {
899        handle->ERROR_MESSAGE("%s", e.what());
900    }
901    catch (...)
902    {
903        handle->ERROR_MESSAGE("Unknown exception thrown");
904    }
905
906    return 2; /* exception */
907}
908
909//-----------------------------------------------------------------
910// general purpose
911//-----------------------------------------------------------------
912
913char
914GEOSEquals_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
915{
916    if ( 0 == extHandle )
917    {
918        return 2;
919    }
920
921    GEOSContextHandleInternal_t *handle = 0;
922    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
923    if ( 0 == handle->initialized )
924    {
925        return 2;
926    }
927
928    try
929    {
930        bool result = g1->equals(g2);
931        return result;
932    }
933    catch (const std::exception &e)
934    {
935        handle->ERROR_MESSAGE("%s", e.what());
936    }
937    catch (...)
938    {
939        handle->ERROR_MESSAGE("Unknown exception thrown");
940    }
941
942    return 2;
943}
944
945char
946GEOSEqualsExact_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double tolerance)
947{
948    if ( 0 == extHandle )
949    {
950        return 2;
951    }
952
953    GEOSContextHandleInternal_t *handle = 0;
954    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
955    if ( 0 == handle->initialized )
956    {
957        return 2;
958    }
959
960    try
961    {
962        bool result = g1->equalsExact(g2, tolerance);
963        return result;
964    }
965    catch (const std::exception &e)
966    {
967        handle->ERROR_MESSAGE("%s", e.what());
968    }
969    catch (...)
970    {
971        handle->ERROR_MESSAGE("Unknown exception thrown");
972    }
973   
974    return 2;
975}
976
977int
978GEOSDistance_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double *dist)
979{
980    assert(0 != dist);
981
982    if ( 0 == extHandle )
983    {
984        return 0;
985    }
986
987    GEOSContextHandleInternal_t *handle = 0;
988    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
989    if ( 0 == handle->initialized )
990    {
991        return 0;
992    }
993
994    try
995    {
996        *dist = g1->distance(g2);
997        return 1;
998    }
999    catch (const std::exception &e)
1000    {
1001        handle->ERROR_MESSAGE("%s", e.what());
1002    }
1003    catch (...)
1004    {
1005        handle->ERROR_MESSAGE("Unknown exception thrown");
1006    }
1007   
1008    return 0;
1009}
1010
1011int
1012GEOSHausdorffDistance_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double *dist)
1013{
1014    assert(0 != dist);
1015
1016    if ( 0 == extHandle )
1017    {
1018        return 0;
1019    }
1020
1021    GEOSContextHandleInternal_t *handle = 0;
1022    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1023    if ( 0 == handle->initialized )
1024    {
1025        return 0;
1026    }
1027
1028    try
1029    {
1030        *dist = DiscreteHausdorffDistance::distance(*g1, *g2);
1031        return 1;
1032    }
1033    catch (const std::exception &e)
1034    {
1035        handle->ERROR_MESSAGE("%s", e.what());
1036    }
1037    catch (...)
1038    {
1039        handle->ERROR_MESSAGE("Unknown exception thrown");
1040    }
1041   
1042    return 0;
1043}
1044
1045int
1046GEOSHausdorffDistanceDensify_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double densifyFrac, double *dist)
1047{
1048    assert(0 != dist);
1049
1050    if ( 0 == extHandle )
1051    {
1052        return 0;
1053    }
1054
1055    GEOSContextHandleInternal_t *handle = 0;
1056    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1057    if ( 0 == handle->initialized )
1058    {
1059        return 0;
1060    }
1061
1062    try
1063    {
1064        *dist = DiscreteHausdorffDistance::distance(*g1, *g2, densifyFrac);
1065        return 1;
1066    }
1067    catch (const std::exception &e)
1068    {
1069        handle->ERROR_MESSAGE("%s", e.what());
1070    }
1071    catch (...)
1072    {
1073        handle->ERROR_MESSAGE("Unknown exception thrown");
1074    }
1075   
1076    return 0;
1077}
1078
1079int
1080GEOSArea_r(GEOSContextHandle_t extHandle, const Geometry *g, double *area)
1081{
1082    assert(0 != area);
1083
1084    if ( 0 == extHandle )
1085    {
1086        return 0;
1087    }
1088
1089    GEOSContextHandleInternal_t *handle = 0;
1090    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1091    if ( 0 == handle->initialized )
1092    {
1093        return 0;
1094    }
1095
1096    try
1097    {
1098        *area = g->getArea();
1099        return 1;
1100    }
1101    catch (const std::exception &e)
1102    {
1103        handle->ERROR_MESSAGE("%s", e.what());
1104    }
1105    catch (...)
1106    {
1107        handle->ERROR_MESSAGE("Unknown exception thrown");
1108    }
1109   
1110    return 0;
1111}
1112
1113int
1114GEOSLength_r(GEOSContextHandle_t extHandle, const Geometry *g, double *length)
1115{
1116    assert(0 != length);
1117
1118    if ( 0 == extHandle )
1119    {
1120        return 2;
1121    }
1122
1123    GEOSContextHandleInternal_t *handle = 0;
1124    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1125    if ( 0 == handle->initialized )
1126    {
1127        return 0;
1128    }
1129
1130    try
1131    {
1132        *length = g->getLength();
1133        return 1;
1134    }
1135    catch (const std::exception &e)
1136    {
1137        handle->ERROR_MESSAGE("%s", e.what());
1138    }
1139    catch (...)
1140    {
1141        handle->ERROR_MESSAGE("Unknown exception thrown");
1142    }
1143   
1144    return 0;
1145}
1146
1147Geometry *
1148GEOSGeomFromWKT_r(GEOSContextHandle_t extHandle, const char *wkt)
1149{
1150    if ( 0 == extHandle )
1151    {
1152        return NULL;
1153    }
1154
1155    GEOSContextHandleInternal_t *handle = 0;
1156    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1157    if ( 0 == handle->initialized )
1158    {
1159        return NULL;
1160    }
1161
1162    try
1163    {
1164        const std::string wktstring(wkt);
1165        WKTReader r(static_cast<GeometryFactory const*>(handle->geomFactory));
1166
1167        Geometry *g = r.read(wktstring);
1168        return g;
1169    }
1170    catch (const std::exception &e)
1171    {
1172        handle->ERROR_MESSAGE("%s", e.what());
1173    }
1174    catch (...)
1175    {
1176        handle->ERROR_MESSAGE("Unknown exception thrown");
1177    }
1178   
1179    return NULL;
1180}
1181
1182char *
1183GEOSGeomToWKT_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1184{
1185    if ( 0 == extHandle )
1186    {
1187        return NULL;
1188    }
1189
1190    GEOSContextHandleInternal_t *handle = 0;
1191    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1192    if ( 0 == handle->initialized )
1193    {
1194        return NULL;
1195    }
1196
1197    try
1198    {
1199
1200        char *result = gstrdup(g1->toString());
1201        return result;
1202    }
1203    catch (const std::exception &e)
1204    {
1205        handle->ERROR_MESSAGE("%s", e.what());
1206    }
1207    catch (...)
1208    {
1209        handle->ERROR_MESSAGE("Unknown exception thrown");
1210    }
1211    return NULL;
1212}
1213
1214// Remember to free the result!
1215unsigned char *
1216GEOSGeomToWKB_buf_r(GEOSContextHandle_t extHandle, const Geometry *g, size_t *size)
1217{
1218    assert(0 != size);
1219
1220    if ( 0 == extHandle )
1221    {
1222        return NULL;
1223    }
1224
1225    GEOSContextHandleInternal_t *handle = 0;
1226    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1227    if ( 0 == handle->initialized )
1228    {
1229        return NULL;
1230    }
1231
1232    using geos::io::WKBWriter;
1233    try
1234    {
1235        int byteOrder = static_cast<int>(handle->WKBByteOrder);
1236        WKBWriter w(handle->WKBOutputDims, byteOrder);
1237        std::ostringstream os(std::ios_base::binary);
1238        w.write(*g, os);
1239        std::string wkbstring(os.str());
1240        const std::size_t len = wkbstring.length();
1241
1242        unsigned char* result = 0;
1243        result = static_cast<unsigned char*>(std::malloc(len));
1244        if (0 != result)
1245        {
1246            std::memcpy(result, wkbstring.c_str(), len);
1247            *size = len;
1248        }
1249        return result;
1250    }
1251    catch (const std::exception &e)
1252    {
1253        handle->ERROR_MESSAGE("%s", e.what());
1254    }
1255    catch (...)
1256    {
1257        handle->ERROR_MESSAGE("Unknown exception thrown");
1258    }
1259   
1260    return NULL;
1261}
1262
1263Geometry *
1264GEOSGeomFromWKB_buf_r(GEOSContextHandle_t extHandle, const unsigned char *wkb, size_t size)
1265{
1266    if ( 0 == extHandle )
1267    {
1268        return NULL;
1269    }
1270
1271    GEOSContextHandleInternal_t *handle = 0;
1272    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1273    if ( 0 == handle->initialized )
1274    {
1275        return NULL;
1276    }
1277
1278    using geos::io::WKBReader;
1279    try
1280    {
1281        std::string wkbstring(reinterpret_cast<const char*>(wkb), size); // make it binary !
1282        WKBReader r(*(static_cast<GeometryFactory const*>(handle->geomFactory)));
1283        std::istringstream is(std::ios_base::binary);
1284        is.str(wkbstring);
1285        is.seekg(0, std::ios::beg); // rewind reader pointer
1286        Geometry *g = r.read(is);
1287        return g;
1288    }
1289    catch (const std::exception &e)
1290    {
1291        handle->ERROR_MESSAGE("%s", e.what());
1292    }
1293    catch (...)
1294    {
1295        handle->ERROR_MESSAGE("Unknown exception thrown");
1296    }
1297   
1298    return NULL;
1299}
1300
1301/* Read/write wkb hex values.  Returned geometries are
1302   owned by the caller.*/
1303unsigned char *
1304GEOSGeomToHEX_buf_r(GEOSContextHandle_t extHandle, const Geometry *g, size_t *size)
1305{
1306    if ( 0 == extHandle )
1307    {
1308        return NULL;
1309    }
1310
1311    GEOSContextHandleInternal_t *handle = 0;
1312    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1313    if ( 0 == handle->initialized )
1314    {
1315        return NULL;
1316    }
1317
1318    using geos::io::WKBWriter;
1319    try
1320    {
1321        int byteOrder = static_cast<int>(handle->WKBByteOrder);
1322        WKBWriter w(handle->WKBOutputDims, byteOrder);
1323        std::ostringstream os(std::ios_base::binary);
1324        w.writeHEX(*g, os);
1325        std::string hexstring(os.str());
1326
1327        char *result = gstrdup(hexstring);
1328        if (0 != result)
1329        {
1330            *size = hexstring.length();
1331        }
1332
1333        return reinterpret_cast<unsigned char*>(result);
1334    }
1335    catch (const std::exception &e)
1336    {
1337        handle->ERROR_MESSAGE("%s", e.what());
1338    }
1339    catch (...)
1340    {
1341        handle->ERROR_MESSAGE("Unknown exception thrown");
1342    }
1343   
1344    return NULL;
1345}
1346
1347Geometry *
1348GEOSGeomFromHEX_buf_r(GEOSContextHandle_t extHandle, const unsigned char *hex, size_t size)
1349{
1350    if ( 0 == extHandle )
1351    {
1352        return NULL;
1353    }
1354
1355    GEOSContextHandleInternal_t *handle = 0;
1356    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1357    if ( 0 == handle->initialized )
1358    {
1359        return NULL;
1360    }
1361
1362    using geos::io::WKBReader;
1363    try
1364    {
1365        std::string hexstring(reinterpret_cast<const char*>(hex), size);
1366        WKBReader r(*(static_cast<GeometryFactory const*>(handle->geomFactory)));
1367        std::istringstream is(std::ios_base::binary);
1368        is.str(hexstring);
1369        is.seekg(0, std::ios::beg); // rewind reader pointer
1370
1371        Geometry *g = r.readHEX(is);
1372        return g;
1373    }
1374    catch (const std::exception &e)
1375    {
1376        handle->ERROR_MESSAGE("%s", e.what());
1377    }
1378    catch (...)
1379    {
1380        handle->ERROR_MESSAGE("Unknown exception thrown");
1381    }
1382   
1383    return NULL;
1384}
1385
1386char
1387GEOSisEmpty_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1388{
1389    if ( 0 == extHandle )
1390    {
1391        return 2;
1392    }
1393
1394    GEOSContextHandleInternal_t *handle = 0;
1395    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1396    if ( 0 == handle->initialized )
1397    {
1398        return 2;
1399    }
1400
1401    try
1402    {
1403        return g1->isEmpty();
1404    }
1405    catch (const std::exception &e)
1406    {
1407        handle->ERROR_MESSAGE("%s", e.what());
1408    }
1409    catch (...)
1410    {
1411        handle->ERROR_MESSAGE("Unknown exception thrown");
1412    }
1413   
1414    return 2;
1415}
1416
1417char
1418GEOSisSimple_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1419{
1420    if ( 0 == extHandle )
1421    {
1422        return 2;
1423    }
1424
1425    GEOSContextHandleInternal_t *handle = 0;
1426    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1427    if ( 0 == handle->initialized )
1428    {
1429        return 2;
1430    }
1431
1432    try
1433    {
1434        return g1->isSimple();
1435    }
1436    catch (const std::exception &e)
1437    {
1438        handle->ERROR_MESSAGE("%s", e.what());
1439        return 2;
1440    }
1441
1442    catch (...)
1443    {
1444        handle->ERROR_MESSAGE("Unknown exception thrown");
1445        return 2;
1446    }
1447}
1448
1449char
1450GEOSisRing_r(GEOSContextHandle_t extHandle, const Geometry *g)
1451{
1452    if ( 0 == extHandle )
1453    {
1454        return 2;
1455    }
1456
1457    GEOSContextHandleInternal_t *handle = 0;
1458    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1459    if ( 0 == handle->initialized )
1460    {
1461        return 2;
1462    }
1463
1464    try
1465    {
1466        const LineString *ls = dynamic_cast<const LineString *>(g);
1467        if ( ls ) {
1468            return (ls->isRing());
1469        } else {
1470            return 0;
1471        }
1472    }
1473    catch (const std::exception &e)
1474    {
1475        handle->ERROR_MESSAGE("%s", e.what());
1476        return 2;
1477    }
1478
1479    catch (...)
1480    {
1481        handle->ERROR_MESSAGE("Unknown exception thrown");
1482        return 2;
1483    }
1484}
1485
1486
1487
1488//free the result of this
1489char *
1490GEOSGeomType_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1491{
1492    if ( 0 == extHandle )
1493    {
1494        return NULL;
1495    }
1496
1497    GEOSContextHandleInternal_t *handle = 0;
1498    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1499    if ( 0 == handle->initialized )
1500    {
1501        return NULL;
1502    }
1503
1504    try
1505    {
1506        std::string s = g1->getGeometryType();
1507
1508        char *result = gstrdup(s);
1509        return result;
1510    }
1511    catch (const std::exception &e)
1512    {
1513        handle->ERROR_MESSAGE("%s", e.what());
1514    }
1515    catch (...)
1516    {
1517        handle->ERROR_MESSAGE("Unknown exception thrown");
1518    }
1519   
1520    return NULL;
1521}
1522
1523// Return postgis geometry type index
1524int
1525GEOSGeomTypeId_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1526{
1527    if ( 0 == extHandle )
1528    {
1529        return -1;
1530    }
1531
1532    GEOSContextHandleInternal_t *handle = 0;
1533    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1534    if ( 0 == handle->initialized )
1535    {
1536        return -1;
1537    }
1538
1539    try
1540    {
1541        return g1->getGeometryTypeId();
1542    }
1543    catch (const std::exception &e)
1544    {
1545        handle->ERROR_MESSAGE("%s", e.what());
1546    }
1547    catch (...)
1548    {
1549        handle->ERROR_MESSAGE("Unknown exception thrown");
1550    }
1551   
1552    return -1;
1553}
1554
1555//-------------------------------------------------------------------
1556// GEOS functions that return geometries
1557//-------------------------------------------------------------------
1558
1559Geometry *
1560GEOSEnvelope_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1561{
1562    if ( 0 == extHandle )
1563    {
1564        return NULL;
1565    }
1566
1567    GEOSContextHandleInternal_t *handle = 0;
1568    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1569    if ( 0 == handle->initialized )
1570    {
1571        return NULL;
1572    }
1573
1574    try
1575    {
1576        Geometry *g3 = g1->getEnvelope();
1577        return g3;
1578    }
1579    catch (const std::exception &e)
1580    {
1581        handle->ERROR_MESSAGE("%s", e.what());
1582    }
1583    catch (...)
1584    {
1585        handle->ERROR_MESSAGE("Unknown exception thrown");
1586    }
1587   
1588    return NULL;
1589}
1590
1591Geometry *
1592GEOSIntersection_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
1593{
1594    if ( 0 == extHandle )
1595    {
1596        return NULL;
1597    }
1598
1599    GEOSContextHandleInternal_t *handle = 0;
1600    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1601    if ( 0 == handle->initialized )
1602    {
1603        return NULL;
1604    }
1605
1606    try
1607    {
1608        GeomAutoPtr g3(BinaryOp(g1, g2, overlayOp(OverlayOp::opINTERSECTION)));
1609        return g3.release();
1610
1611        // XXX: old version
1612        //Geometry *g3 = g1->intersection(g2);
1613        //return g3;
1614    }
1615    catch (const std::exception &e)
1616    {
1617        handle->ERROR_MESSAGE("%s", e.what());
1618    }
1619    catch (...)
1620    {
1621        handle->ERROR_MESSAGE("Unknown exception thrown");
1622    }
1623   
1624    return NULL;
1625}
1626
1627Geometry *
1628GEOSBuffer_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadrantsegments)
1629{
1630    if ( 0 == extHandle )
1631    {
1632        return NULL;
1633    }
1634
1635    GEOSContextHandleInternal_t *handle = 0;
1636    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1637    if ( 0 == handle->initialized )
1638    {
1639        return NULL;
1640    }
1641
1642    try
1643    {
1644        Geometry *g3 = g1->buffer(width, quadrantsegments);
1645        return g3;
1646    }
1647    catch (const std::exception &e)
1648    {
1649        handle->ERROR_MESSAGE("%s", e.what());
1650    }
1651    catch (...)
1652    {
1653        handle->ERROR_MESSAGE("Unknown exception thrown");
1654    }
1655   
1656    return NULL;
1657}
1658
1659Geometry *
1660GEOSBufferWithStyle_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int endCapStyle, int joinStyle, double mitreLimit)
1661{
1662    using geos::operation::buffer::BufferParameters;
1663    using geos::operation::buffer::BufferOp;
1664    using geos::util::IllegalArgumentException;
1665
1666    if ( 0 == extHandle )
1667    {
1668        return NULL;
1669    }
1670
1671    GEOSContextHandleInternal_t *handle = 0;
1672    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1673    if ( 0 == handle->initialized )
1674    {
1675        return NULL;
1676    }
1677
1678    try
1679    {
1680        BufferParameters bp;
1681        bp.setQuadrantSegments(quadsegs);
1682
1683        if ( endCapStyle > BufferParameters::CAP_SQUARE )
1684        {
1685                throw IllegalArgumentException("Invalid buffer endCap style");
1686        }
1687        bp.setEndCapStyle(
1688                static_cast<BufferParameters::EndCapStyle>(endCapStyle)
1689        );
1690
1691        if ( joinStyle > BufferParameters::JOIN_BEVEL )
1692        {
1693                throw IllegalArgumentException("Invalid buffer join style");
1694        }
1695        bp.setJoinStyle(
1696                static_cast<BufferParameters::JoinStyle>(joinStyle)
1697        );
1698        bp.setMitreLimit(mitreLimit);
1699        BufferOp op(g1, bp);
1700        Geometry *g3 = op.getResultGeometry(width);
1701        return g3;
1702    }
1703    catch (const std::exception &e)
1704    {
1705        handle->ERROR_MESSAGE("%s", e.what());
1706    }
1707    catch (...)
1708    {
1709        handle->ERROR_MESSAGE("Unknown exception thrown");
1710    }
1711   
1712    return NULL;
1713}
1714
1715Geometry *
1716GEOSOffsetCurve_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int joinStyle, double mitreLimit)
1717{
1718    if ( 0 == extHandle ) return NULL;
1719
1720    GEOSContextHandleInternal_t *handle = 0;
1721    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1722    if ( 0 == handle->initialized ) return NULL;
1723
1724    try
1725    {
1726        BufferParameters bp;
1727        bp.setEndCapStyle( BufferParameters::CAP_FLAT );
1728        bp.setQuadrantSegments(quadsegs);
1729
1730        if ( joinStyle > BufferParameters::JOIN_BEVEL )
1731        {
1732            throw IllegalArgumentException("Invalid buffer join style");
1733        }
1734        bp.setJoinStyle(
1735            static_cast<BufferParameters::JoinStyle>(joinStyle)
1736            );
1737        bp.setMitreLimit(mitreLimit);
1738
1739        bool isLeftSide = true;
1740        if ( width < 0 ) {
1741          isLeftSide = false;
1742          width = -width;
1743        }
1744        BufferBuilder bufBuilder (bp);
1745        Geometry *g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide);
1746
1747        return g3;
1748    }
1749    catch (const std::exception &e)
1750    {
1751        handle->ERROR_MESSAGE("%s", e.what());
1752    }
1753    catch (...)
1754    {
1755        handle->ERROR_MESSAGE("Unknown exception thrown");
1756    }
1757   
1758    return NULL;
1759}
1760
1761/* @deprecated in 3.3.0 */
1762Geometry *
1763GEOSSingleSidedBuffer_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int joinStyle, double mitreLimit, int leftSide)
1764{
1765    if ( 0 == extHandle ) return NULL;
1766
1767    GEOSContextHandleInternal_t *handle = 0;
1768    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1769    if ( 0 == handle->initialized ) return NULL;
1770
1771    try
1772    {
1773        BufferParameters bp;
1774        bp.setEndCapStyle( BufferParameters::CAP_FLAT );
1775        bp.setQuadrantSegments(quadsegs);
1776
1777        if ( joinStyle > BufferParameters::JOIN_BEVEL )
1778        {
1779            throw IllegalArgumentException("Invalid buffer join style");
1780        }
1781        bp.setJoinStyle(
1782            static_cast<BufferParameters::JoinStyle>(joinStyle)
1783            );
1784        bp.setMitreLimit(mitreLimit);
1785
1786        bool isLeftSide = leftSide == 0 ? false : true;
1787        BufferBuilder bufBuilder (bp);
1788        Geometry *g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide);
1789
1790        return g3;
1791    }
1792    catch (const std::exception &e)
1793    {
1794        handle->ERROR_MESSAGE("%s", e.what());
1795    }
1796    catch (...)
1797    {
1798        handle->ERROR_MESSAGE("Unknown exception thrown");
1799    }
1800   
1801    return NULL;
1802}
1803
1804Geometry *
1805GEOSConvexHull_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1806{
1807    if ( 0 == extHandle )
1808    {
1809        return NULL;
1810    }
1811
1812    GEOSContextHandleInternal_t *handle = 0;
1813    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1814    if ( 0 == handle->initialized )
1815    {
1816        return NULL;
1817    }
1818
1819    try
1820    {
1821        Geometry *g3 = g1->convexHull();
1822        return g3;
1823    }
1824    catch (const std::exception &e)
1825    {
1826        handle->ERROR_MESSAGE("%s", e.what());
1827    }
1828    catch (...)
1829    {
1830        handle->ERROR_MESSAGE("Unknown exception thrown");
1831    }
1832   
1833    return NULL;
1834}
1835
1836Geometry *
1837GEOSDifference_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
1838{
1839    if ( 0 == extHandle )
1840    {
1841        return NULL;
1842    }
1843
1844    GEOSContextHandleInternal_t *handle = 0;
1845    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1846    if ( 0 == handle->initialized )
1847    {
1848        return NULL;
1849    }
1850
1851    try
1852    {
1853        GeomAutoPtr g3(BinaryOp(g1, g2, overlayOp(OverlayOp::opDIFFERENCE)));
1854        return g3.release();
1855
1856        // XXX: old version
1857        //Geometry *g3 = g1->difference(g2);
1858        //return g3;
1859    }
1860    catch (const std::exception &e)
1861    {
1862        handle->ERROR_MESSAGE("%s", e.what());
1863    }
1864    catch (...)
1865    {
1866        handle->ERROR_MESSAGE("Unknown exception thrown");
1867    }
1868   
1869    return NULL;
1870}
1871
1872Geometry *
1873GEOSBoundary_r(GEOSContextHandle_t extHandle, const Geometry *g1)
1874{
1875    if ( 0 == extHandle )
1876    {
1877        return NULL;
1878    }
1879
1880    GEOSContextHandleInternal_t *handle = 0;
1881    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1882    if ( 0 == handle->initialized )
1883    {
1884        return NULL;
1885    }
1886
1887    try
1888    {
1889        Geometry *g3 = g1->getBoundary();
1890        return g3;
1891    }
1892    catch (const std::exception &e)
1893    {
1894        handle->ERROR_MESSAGE("%s", e.what());
1895    }
1896    catch (...)
1897    {
1898        handle->ERROR_MESSAGE("Unknown exception thrown");
1899    }
1900   
1901    return NULL;
1902}
1903
1904Geometry *
1905GEOSSymDifference_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
1906{
1907    if ( 0 == extHandle )
1908    {
1909        return NULL;
1910    }
1911
1912    GEOSContextHandleInternal_t *handle = 0;
1913    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1914    if ( 0 == handle->initialized )
1915    {
1916        return NULL;
1917    }
1918
1919    try
1920    {
1921        GeomAutoPtr g3 = BinaryOp(g1, g2, overlayOp(OverlayOp::opSYMDIFFERENCE));
1922        return g3.release();
1923        //Geometry *g3 = g1->symDifference(g2);
1924        //return g3;
1925    }
1926    catch (const std::exception &e)
1927    {
1928        handle->ERROR_MESSAGE("%s", e.what());
1929        return NULL;
1930    }
1931
1932    catch (...)
1933    {
1934        handle->ERROR_MESSAGE("Unknown exception thrown");
1935        return NULL;
1936    }
1937}
1938
1939Geometry *
1940GEOSUnion_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2)
1941{
1942    if ( 0 == extHandle )
1943    {
1944        return NULL;
1945    }
1946
1947    GEOSContextHandleInternal_t *handle = 0;
1948    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1949    if ( 0 == handle->initialized )
1950    {
1951        return NULL;
1952    }
1953
1954    try
1955    {
1956        GeomAutoPtr g3 = BinaryOp(g1, g2, overlayOp(OverlayOp::opUNION));
1957        return g3.release();
1958
1959        // XXX: old version
1960        //Geometry *g3 = g1->Union(g2);
1961        //return g3;
1962    }
1963    catch (const std::exception &e)
1964    {
1965#if VERBOSE_EXCEPTIONS
1966        std::ostringstream s;
1967        s << "Exception on GEOSUnion with following inputs:" << std::endl;
1968        s << "A: "<<g1->toString() << std::endl;
1969        s << "B: "<<g2->toString() << std::endl;
1970        handle->NOTICE_MESSAGE("%s", s.str().c_str());
1971#endif // VERBOSE_EXCEPTIONS
1972        handle->ERROR_MESSAGE("%s", e.what());
1973    }
1974    catch (...)
1975    {
1976        handle->ERROR_MESSAGE("Unknown exception thrown");
1977    }
1978   
1979    return NULL;
1980}
1981
1982Geometry *
1983GEOSUnaryUnion_r(GEOSContextHandle_t extHandle, const Geometry *g)
1984{
1985    if ( 0 == extHandle )
1986    {
1987        return NULL;
1988    }
1989
1990    GEOSContextHandleInternal_t *handle = 0;
1991    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
1992    if ( 0 == handle->initialized )
1993    {
1994        return NULL;
1995    }
1996
1997    try
1998    {
1999        GeomAutoPtr g3 ( g->Union() );
2000        return g3.release();
2001    }
2002    catch (const std::exception &e)
2003    {
2004#if VERBOSE_EXCEPTIONS
2005        std::ostringstream s;
2006        s << "Exception on GEOSUnaryUnion with following inputs:" << std::endl;
2007        s << "A: "<<g1->toString() << std::endl;
2008        s << "B: "<<g2->toString() << std::endl;
2009        handle->NOTICE_MESSAGE("%s", s.str().c_str());
2010#endif // VERBOSE_EXCEPTIONS
2011        handle->ERROR_MESSAGE("%s", e.what());
2012    }
2013    catch (...)
2014    {
2015        handle->ERROR_MESSAGE("Unknown exception thrown");
2016    }
2017   
2018    return NULL;
2019}
2020
2021Geometry *
2022GEOSUnionCascaded_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2023{
2024    if ( 0 == extHandle )
2025    {
2026        return NULL;
2027    }
2028
2029    GEOSContextHandleInternal_t *handle = 0;
2030    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2031    if ( 0 == handle->initialized )
2032    {
2033        return NULL;
2034    }
2035
2036    try
2037    {
2038        const geos::geom::MultiPolygon *p = dynamic_cast<const geos::geom::MultiPolygon *>(g1);
2039        if ( ! p )
2040        {
2041            handle->ERROR_MESSAGE("Invalid argument (must be a MultiPolygon)");
2042            return NULL;
2043        }
2044
2045        using geos::operation::geounion::CascadedPolygonUnion;
2046        return CascadedPolygonUnion::Union(p);
2047    }
2048    catch (const std::exception &e)
2049    {
2050        handle->ERROR_MESSAGE("%s", e.what());
2051    }
2052    catch (...)
2053    {
2054        handle->ERROR_MESSAGE("Unknown exception thrown");
2055    }
2056   
2057    return NULL;
2058}
2059
2060Geometry *
2061GEOSPointOnSurface_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2062{
2063    if ( 0 == extHandle )
2064    {
2065        return NULL;
2066    }
2067
2068    GEOSContextHandleInternal_t *handle = 0;
2069    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2070    if ( 0 == handle->initialized )
2071    {
2072        return NULL;
2073    }
2074
2075    try
2076    {
2077        Geometry *ret = g1->getInteriorPoint();
2078        if ( ! ret )
2079        {
2080            const GeometryFactory* gf = handle->geomFactory;
2081            // return an empty collection
2082            return gf->createGeometryCollection();
2083        }
2084        return ret;
2085    }
2086    catch (const std::exception &e)
2087    {
2088        handle->ERROR_MESSAGE("%s", e.what());
2089    }
2090    catch (...)
2091    {
2092        handle->ERROR_MESSAGE("Unknown exception thrown");
2093    }
2094   
2095    return NULL;
2096}
2097
2098//-------------------------------------------------------------------
2099// memory management functions
2100//------------------------------------------------------------------
2101
2102void
2103GEOSGeom_destroy_r(GEOSContextHandle_t extHandle, Geometry *a)
2104{
2105    GEOSContextHandleInternal_t *handle = 0;
2106
2107    // FIXME: mloskot: Does this try-catch around delete means that
2108    // destructors in GEOS may throw? If it does, this is a serious
2109    // violation of "never throw an exception from a destructor" principle
2110
2111    try
2112    {
2113        delete a;
2114    }
2115    catch (const std::exception &e)
2116    {
2117        if ( 0 == extHandle )
2118        {
2119            return;
2120        }
2121
2122        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2123        if ( 0 == handle->initialized )
2124        {
2125            return;
2126        }
2127
2128        handle->ERROR_MESSAGE("%s", e.what());
2129    }
2130    catch (...)
2131    {
2132        if ( 0 == extHandle )
2133        {
2134            return;
2135        }
2136
2137        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2138        if ( 0 == handle->initialized )
2139        {
2140            return;
2141        }
2142
2143        handle->ERROR_MESSAGE("Unknown exception thrown");
2144    }
2145}
2146
2147void
2148GEOSSetSRID_r(GEOSContextHandle_t extHandle, Geometry *g, int srid)
2149{
2150    assert(0 != g);
2151
2152    if ( 0 == extHandle )
2153    {
2154        return;
2155    }
2156
2157    GEOSContextHandleInternal_t *handle = 0;
2158    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2159    if ( 0 == handle->initialized )
2160    {
2161        return;
2162    }
2163
2164    g->setSRID(srid);
2165}
2166
2167
2168int
2169GEOSGetNumCoordinates_r(GEOSContextHandle_t extHandle, const Geometry *g)
2170{
2171    assert(0 != g);
2172
2173    if ( 0 == extHandle )
2174    {
2175        return -1;
2176    }
2177
2178    GEOSContextHandleInternal_t *handle = 0;
2179    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2180    if ( 0 == handle->initialized )
2181    {
2182        return -1;
2183    }
2184
2185    try
2186    {
2187        return static_cast<int>(g->getNumPoints());
2188    }
2189    catch (const std::exception &e)
2190    {
2191        handle->ERROR_MESSAGE("%s", e.what());
2192    }
2193    catch (...)
2194    {
2195        handle->ERROR_MESSAGE("Unknown exception thrown");
2196    }
2197   
2198    return -1;
2199}
2200
2201/*
2202 * Return -1 on exception, 0 otherwise.
2203 * Converts Geometry to normal form (or canonical form).
2204 */
2205int
2206GEOSNormalize_r(GEOSContextHandle_t extHandle, Geometry *g)
2207{
2208    assert(0 != g);
2209
2210    if ( 0 == extHandle )
2211    {
2212        return -1;
2213    }
2214
2215    GEOSContextHandleInternal_t *handle = 0;
2216    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2217    if ( 0 == handle->initialized )
2218    {
2219        return -1;
2220    }
2221
2222    try
2223    {
2224        g->normalize();
2225        return 0; // SUCCESS
2226    }
2227    catch (const std::exception &e)
2228    {
2229        handle->ERROR_MESSAGE("%s", e.what());
2230    }
2231    catch (...)
2232    {
2233        handle->ERROR_MESSAGE("Unknown exception thrown");
2234    }
2235   
2236    return -1;
2237}
2238
2239int
2240GEOSGetNumInteriorRings_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2241{
2242    if ( 0 == extHandle )
2243    {
2244        return -1;
2245    }
2246
2247    GEOSContextHandleInternal_t *handle = 0;
2248    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2249    if ( 0 == handle->initialized )
2250    {
2251        return -1;
2252    }
2253
2254    try
2255    {
2256        const Polygon *p = dynamic_cast<const Polygon *>(g1);
2257        if ( ! p )
2258        {
2259            handle->ERROR_MESSAGE("Argument is not a Polygon");
2260            return -1;
2261        }
2262        return static_cast<int>(p->getNumInteriorRing());
2263    }
2264    catch (const std::exception &e)
2265    {
2266        handle->ERROR_MESSAGE("%s", e.what());
2267    }
2268    catch (...)
2269    {
2270        handle->ERROR_MESSAGE("Unknown exception thrown");
2271    }
2272   
2273    return -1;
2274}
2275
2276
2277// returns -1 on error and 1 for non-multi geometries
2278int
2279GEOSGetNumGeometries_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2280{
2281    if ( 0 == extHandle )
2282    {
2283        return -1;
2284    }
2285
2286    GEOSContextHandleInternal_t *handle = 0;
2287    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2288    if ( 0 == handle->initialized )
2289    {
2290        return -1;
2291    }
2292
2293    try
2294    {
2295        return static_cast<int>(g1->getNumGeometries());
2296    }
2297    catch (const std::exception &e)
2298    {
2299        handle->ERROR_MESSAGE("%s", e.what());
2300    }
2301    catch (...)
2302    {
2303        handle->ERROR_MESSAGE("Unknown exception thrown");
2304    }
2305   
2306    return -1;
2307}
2308
2309
2310/*
2311 * Call only on GEOMETRYCOLLECTION or MULTI*.
2312 * Return a pointer to the internal Geometry.
2313 */
2314const Geometry *
2315GEOSGetGeometryN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n)
2316{
2317    if ( 0 == extHandle )
2318    {
2319        return NULL;
2320    }
2321
2322    GEOSContextHandleInternal_t *handle = 0;
2323    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2324    if ( 0 == handle->initialized )
2325    {
2326        return NULL;
2327    }
2328
2329    try
2330    {
2331        return g1->getGeometryN(n);
2332    }
2333    catch (const std::exception &e)
2334    {
2335        handle->ERROR_MESSAGE("%s", e.what());
2336    }
2337    catch (...)
2338    {
2339        handle->ERROR_MESSAGE("Unknown exception thrown");
2340    }
2341   
2342    return NULL;
2343}
2344
2345/*
2346 * Call only on LINESTRING
2347 * Returns NULL on exception
2348 */
2349Geometry *
2350GEOSGeomGetPointN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n)
2351{
2352    if ( 0 == extHandle )
2353    {
2354        return NULL;
2355    }
2356
2357    GEOSContextHandleInternal_t *handle = 0;
2358    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2359    if ( 0 == handle->initialized )
2360    {
2361        return NULL;
2362    }
2363
2364    try
2365    {
2366        using geos::geom::LineString;
2367        const LineString *ls = dynamic_cast<const LineString *>(g1);
2368        if ( ! ls )
2369        {
2370                handle->ERROR_MESSAGE("Argument is not a LineString");
2371                return NULL;
2372        }
2373        return ls->getPointN(n);
2374    }
2375    catch (const std::exception &e)
2376    {
2377        handle->ERROR_MESSAGE("%s", e.what());
2378    }
2379    catch (...)
2380    {
2381        handle->ERROR_MESSAGE("Unknown exception thrown");
2382    }
2383
2384    return NULL;
2385}
2386
2387/*
2388 * Call only on LINESTRING
2389 */
2390Geometry *
2391GEOSGeomGetStartPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2392{
2393    if ( 0 == extHandle )
2394    {
2395        return NULL;
2396    }
2397
2398    GEOSContextHandleInternal_t *handle = 0;
2399    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2400    if ( 0 == handle->initialized )
2401    {
2402        return NULL;
2403    }
2404
2405    try
2406    {
2407        using geos::geom::LineString;
2408        const LineString *ls = dynamic_cast<const LineString *>(g1);
2409        if ( ! ls )
2410        {
2411                handle->ERROR_MESSAGE("Argument is not a LineString");
2412                return NULL;
2413        }
2414        return ls->getStartPoint();
2415    }
2416    catch (const std::exception &e)
2417    {
2418        handle->ERROR_MESSAGE("%s", e.what());
2419    }
2420    catch (...)
2421    {
2422        handle->ERROR_MESSAGE("Unknown exception thrown");
2423    }
2424
2425    return NULL;
2426}
2427
2428/*
2429 * Call only on LINESTRING
2430 */
2431Geometry *
2432GEOSGeomGetEndPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2433{
2434    if ( 0 == extHandle )
2435    {
2436        return NULL;
2437    }
2438
2439    GEOSContextHandleInternal_t *handle = 0;
2440    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2441    if ( 0 == handle->initialized )
2442    {
2443        return NULL;
2444    }
2445
2446    try
2447    {
2448        using geos::geom::LineString;
2449        const LineString *ls = dynamic_cast<const LineString *>(g1);
2450        if ( ! ls )
2451        {
2452                handle->ERROR_MESSAGE("Argument is not a LineString");
2453                return NULL;
2454        }
2455        return ls->getEndPoint();
2456    }
2457    catch (const std::exception &e)
2458    {
2459        handle->ERROR_MESSAGE("%s", e.what());
2460    }
2461    catch (...)
2462    {
2463        handle->ERROR_MESSAGE("Unknown exception thrown");
2464    }
2465
2466    return NULL;
2467}
2468
2469/*
2470 * Call only on LINESTRING
2471 * return 2 on exception, 1 on true, 0 on false
2472 */
2473char
2474GEOSisClosed_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2475{
2476    if ( 0 == extHandle )
2477    {
2478        return 2;
2479    }
2480
2481    GEOSContextHandleInternal_t *handle = 0;
2482    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2483    if ( 0 == handle->initialized )
2484    {
2485        return 2;
2486    }
2487
2488    try
2489    {
2490        using geos::geom::LineString;
2491        const LineString *ls = dynamic_cast<const LineString *>(g1);
2492        if ( ! ls )
2493        {
2494                handle->ERROR_MESSAGE("Argument is not a LineString");
2495                return 2;
2496        }
2497        return ls->isClosed();
2498    }
2499    catch (const std::exception &e)
2500    {
2501        handle->ERROR_MESSAGE("%s", e.what());
2502    }
2503    catch (...)
2504    {
2505        handle->ERROR_MESSAGE("Unknown exception thrown");
2506    }
2507
2508    return 2;
2509}
2510
2511/*
2512 * Call only on LINESTRING
2513 * return 0 on exception, otherwise 1
2514 */
2515int
2516GEOSGeomGetLength_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *length)
2517{
2518    if ( 0 == extHandle )
2519    {
2520        return 0;
2521    }
2522
2523    GEOSContextHandleInternal_t *handle = 0;
2524    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2525    if ( 0 == handle->initialized )
2526    {
2527        return 0;
2528    }
2529
2530    try
2531    {
2532        using geos::geom::LineString;
2533        const LineString *ls = dynamic_cast<const LineString *>(g1);
2534        if ( ! ls )
2535        {
2536                handle->ERROR_MESSAGE("Argument is not a LineString");
2537                return 0;
2538        }
2539        *length = ls->getLength();
2540        return 1;
2541    }
2542    catch (const std::exception &e)
2543    {
2544        handle->ERROR_MESSAGE("%s", e.what());
2545    }
2546    catch (...)
2547    {
2548        handle->ERROR_MESSAGE("Unknown exception thrown");
2549    }
2550
2551    return 0;
2552}
2553
2554/*
2555 * Call only on LINESTRING
2556 */
2557int
2558GEOSGeomGetNumPoints_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2559{
2560    if ( 0 == extHandle )
2561    {
2562        return -1;
2563    }
2564
2565    GEOSContextHandleInternal_t *handle = 0;
2566    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2567    if ( 0 == handle->initialized )
2568    {
2569        return -1;
2570    }
2571
2572    try
2573    {
2574        using geos::geom::LineString;
2575                const LineString *ls = dynamic_cast<const LineString *>(g1);
2576                if ( ! ls )
2577                {
2578                        handle->ERROR_MESSAGE("Argument is not a LineString");
2579                        return -1;
2580                }
2581                return ls->getNumPoints();
2582    }
2583    catch (const std::exception &e)
2584    {
2585        handle->ERROR_MESSAGE("%s", e.what());
2586    }
2587    catch (...)
2588    {
2589        handle->ERROR_MESSAGE("Unknown exception thrown");
2590    }
2591
2592    return -1;
2593}
2594
2595/*
2596 * For POINT
2597 * returns 0 on exception, otherwise 1
2598 */
2599int
2600GEOSGeomGetX_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *x)
2601{
2602    if ( 0 == extHandle )
2603    {
2604        return 0;
2605    }
2606
2607    GEOSContextHandleInternal_t *handle = 0;
2608    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2609    if ( 0 == handle->initialized )
2610    {
2611        return 0;
2612    }
2613
2614    try
2615    {
2616        using geos::geom::Point;
2617        const Point *po = dynamic_cast<const Point *>(g1);
2618        if ( ! po )
2619        {
2620                handle->ERROR_MESSAGE("Argument is not a Point");
2621                return 0;
2622        }
2623        *x = po->getX();
2624        return 1;
2625    }
2626    catch (const std::exception &e)
2627    {
2628        handle->ERROR_MESSAGE("%s", e.what());
2629    }
2630    catch (...)
2631    {
2632        handle->ERROR_MESSAGE("Unknown exception thrown");
2633    }
2634
2635    return 0;
2636}
2637
2638/*
2639 * For POINT
2640 * returns 0 on exception, otherwise 1
2641 */
2642int
2643GEOSGeomGetY_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *y)
2644{
2645    if ( 0 == extHandle )
2646    {
2647        return 0;
2648    }
2649
2650    GEOSContextHandleInternal_t *handle = 0;
2651    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2652    if ( 0 == handle->initialized )
2653    {
2654        return 0;
2655    }
2656
2657    try
2658    {
2659        using geos::geom::Point;
2660        const Point *po = dynamic_cast<const Point *>(g1);
2661        if ( ! po )
2662        {
2663                handle->ERROR_MESSAGE("Argument is not a Point");
2664                return 0;
2665        }
2666        *y = po->getY();
2667        return 1;
2668    }
2669    catch (const std::exception &e)
2670    {
2671        handle->ERROR_MESSAGE("%s", e.what());
2672    }
2673    catch (...)
2674    {
2675        handle->ERROR_MESSAGE("Unknown exception thrown");
2676    }
2677
2678    return 0;
2679}
2680
2681/*
2682 * Call only on polygon
2683 * Return a copy of the internal Geometry.
2684 */
2685const Geometry *
2686GEOSGetExteriorRing_r(GEOSContextHandle_t extHandle, const Geometry *g1)
2687{
2688    if ( 0 == extHandle )
2689    {
2690        return NULL;
2691    }
2692
2693    GEOSContextHandleInternal_t *handle = 0;
2694    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2695    if ( 0 == handle->initialized )
2696    {
2697        return NULL;
2698    }
2699
2700    try
2701    {
2702        const Polygon *p = dynamic_cast<const Polygon *>(g1);
2703        if ( ! p )
2704        {
2705            handle->ERROR_MESSAGE("Invalid argument (must be a Polygon)");
2706            return NULL;
2707        }
2708        return p->getExteriorRing();
2709    }
2710    catch (const std::exception &e)
2711    {
2712        handle->ERROR_MESSAGE("%s", e.what());
2713    }
2714    catch (...)
2715    {
2716        handle->ERROR_MESSAGE("Unknown exception thrown");
2717    }
2718   
2719    return NULL;
2720}
2721
2722/*
2723 * Call only on polygon
2724 * Return a pointer to internal storage, do not destroy it.
2725 */
2726const Geometry *
2727GEOSGetInteriorRingN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n)
2728{
2729    if ( 0 == extHandle )
2730    {
2731        return NULL;
2732    }
2733
2734    GEOSContextHandleInternal_t *handle = 0;
2735    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2736    if ( 0 == handle->initialized )
2737    {
2738        return NULL;
2739    }
2740
2741    try
2742    {
2743        const Polygon *p = dynamic_cast<const Polygon *>(g1);
2744        if ( ! p )
2745        {
2746            handle->ERROR_MESSAGE("Invalid argument (must be a Polygon)");
2747            return NULL;
2748        }
2749        return p->getInteriorRingN(n);
2750    }
2751    catch (const std::exception &e)
2752    {
2753        handle->ERROR_MESSAGE("%s", e.what());
2754    }
2755    catch (...)
2756    {
2757        handle->ERROR_MESSAGE("Unknown exception thrown");
2758    }
2759   
2760    return NULL;
2761}
2762
2763Geometry *
2764GEOSGetCentroid_r(GEOSContextHandle_t extHandle, const Geometry *g)
2765{
2766    if ( 0 == extHandle )
2767    {
2768        return NULL;
2769    }
2770
2771    GEOSContextHandleInternal_t *handle = 0;
2772    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2773    if ( 0 == handle->initialized )
2774    {
2775        return NULL;
2776    }
2777
2778    try
2779    {
2780        Geometry *ret = g->getCentroid();
2781        if (0 == ret)
2782        {
2783            const GeometryFactory *gf = handle->geomFactory;
2784            return gf->createGeometryCollection();
2785        }
2786        return ret;
2787    }
2788    catch (const std::exception &e)
2789    {
2790        handle->ERROR_MESSAGE("%s", e.what());
2791    }
2792    catch (...)
2793    {
2794        handle->ERROR_MESSAGE("Unknown exception thrown");
2795    }
2796   
2797    return NULL;
2798}
2799
2800Geometry *
2801GEOSGeom_createEmptyCollection_r(GEOSContextHandle_t extHandle, int type)
2802{
2803    if ( 0 == extHandle )
2804    {
2805        return NULL;
2806    }
2807
2808    GEOSContextHandleInternal_t *handle = 0;
2809    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2810    if ( 0 == handle->initialized )
2811    {
2812        return NULL;
2813    }
2814
2815#ifdef GEOS_DEBUG
2816    char buf[256];
2817    sprintf(buf, "createCollection: requested type %d, ngeoms: %d",
2818            type, ngeoms);
2819    handle->NOTICE_MESSAGE("%s", buf);// TODO: Can handle->NOTICE_MESSAGE format that directly?
2820#endif
2821
2822    try
2823    {
2824        const GeometryFactory* gf = handle->geomFactory;
2825
2826        Geometry *g = 0;
2827        switch (type)
2828        {
2829            case GEOS_GEOMETRYCOLLECTION:
2830                g = gf->createGeometryCollection();
2831                break;
2832            case GEOS_MULTIPOINT:
2833                g = gf->createMultiPoint();
2834                break;
2835            case GEOS_MULTILINESTRING:
2836                g = gf->createMultiLineString();
2837                break;
2838            case GEOS_MULTIPOLYGON:
2839                g = gf->createMultiPolygon();
2840                break;
2841            default:
2842                handle->ERROR_MESSAGE("Unsupported type request for GEOSGeom_createEmptyCollection_r");
2843                g = 0;
2844               
2845        }
2846       
2847        return g;
2848    }
2849    catch (const std::exception &e)
2850    {
2851        handle->ERROR_MESSAGE("%s", e.what());
2852    }
2853    catch (...)
2854    {
2855        handle->ERROR_MESSAGE("Unknown exception thrown");
2856    }
2857
2858    return 0;
2859}
2860
2861Geometry *
2862GEOSGeom_createCollection_r(GEOSContextHandle_t extHandle, int type, Geometry **geoms, unsigned int ngeoms)
2863{
2864    if ( 0 == extHandle )
2865    {
2866        return NULL;
2867    }
2868
2869    GEOSContextHandleInternal_t *handle = 0;
2870    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2871    if ( 0 == handle->initialized )
2872    {
2873        return NULL;
2874    }
2875
2876#ifdef GEOS_DEBUG
2877    char buf[256];
2878    sprintf(buf, "PostGIS2GEOS_collection: requested type %d, ngeoms: %d",
2879            type, ngeoms);
2880    handle->NOTICE_MESSAGE("%s", buf);// TODO: Can handle->NOTICE_MESSAGE format that directly?
2881#endif
2882
2883    try
2884    {
2885        const GeometryFactory* gf = handle->geomFactory;
2886        std::vector<Geometry*>* vgeoms = new std::vector<Geometry*>(geoms, geoms + ngeoms);
2887
2888        Geometry *g = 0;
2889        switch (type)
2890        {
2891            case GEOS_GEOMETRYCOLLECTION:
2892                g = gf->createGeometryCollection(vgeoms);
2893                break;
2894            case GEOS_MULTIPOINT:
2895                g = gf->createMultiPoint(vgeoms);
2896                break;
2897            case GEOS_MULTILINESTRING:
2898                g = gf->createMultiLineString(vgeoms);
2899                break;
2900            case GEOS_MULTIPOLYGON:
2901                g = gf->createMultiPolygon(vgeoms);
2902                break;
2903            default:
2904                handle->ERROR_MESSAGE("Unsupported type request for PostGIS2GEOS_collection");
2905                g = 0;
2906               
2907        }
2908       
2909        return g;
2910    }
2911    catch (const std::exception &e)
2912    {
2913        handle->ERROR_MESSAGE("%s", e.what());
2914    }
2915    catch (...)
2916    {
2917        handle->ERROR_MESSAGE("Unknown exception thrown");
2918    }
2919
2920    return 0;
2921}
2922
2923Geometry *
2924GEOSPolygonize_r(GEOSContextHandle_t extHandle, const Geometry * const * g, unsigned int ngeoms)
2925{
2926    if ( 0 == extHandle )
2927    {
2928        return 0;
2929    }
2930
2931    GEOSContextHandleInternal_t *handle = 0;
2932    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
2933    if ( 0 == handle->initialized )
2934    {
2935        return 0;
2936    }
2937
2938    Geometry *out = 0;
2939
2940    try
2941    {
2942        // Polygonize
2943        using geos::operation::polygonize::Polygonizer;
2944        Polygonizer plgnzr;
2945        for (std::size_t i = 0; i < ngeoms; ++i)
2946        {
2947            plgnzr.add(g[i]);
2948        }
2949
2950#if GEOS_DEBUG
2951        handle->NOTICE_MESSAGE("geometry vector added to polygonizer");
2952#endif
2953
2954        std::vector<Polygon*> *polys = plgnzr.getPolygons();
2955        assert(0 != polys);
2956
2957#if GEOS_DEBUG
2958        handle->NOTICE_MESSAGE("output polygons got");
2959#endif
2960
2961        // We need a vector of Geometry pointers, not Polygon pointers.
2962        // STL vector doesn't allow transparent upcast of this
2963        // nature, so we explicitly convert.
2964        // (it's just a waste of processor and memory, btw)
2965        //
2966        // XXX mloskot: Why not to extent GeometryFactory to accept
2967        // vector of polygons or extend Polygonizer to return list of Geometry*
2968        // or add a wrapper which semantic is similar to:
2969        // std::vector<as_polygon<Geometry*> >
2970        std::vector<Geometry*> *polyvec = new std::vector<Geometry *>(polys->size());
2971       
2972        for (std::size_t i = 0; i < polys->size(); ++i)
2973        {
2974            (*polyvec)[i] = (*polys)[i];
2975        }
2976        delete polys;
2977        polys = 0;
2978
2979        const GeometryFactory *gf = handle->geomFactory;
2980
2981        // The below takes ownership of the passed vector,
2982        // so we must *not* delete it
2983        out = gf->createGeometryCollection(polyvec);
2984    }
2985    catch (const std::exception &e)
2986    {
2987        handle->ERROR_MESSAGE("%s", e.what());
2988    }
2989    catch (...)
2990    {
2991        handle->ERROR_MESSAGE("Unknown exception thrown");
2992    }
2993
2994    return out;
2995}
2996
2997Geometry *
2998GEOSPolygonizer_getCutEdges_r(GEOSContextHandle_t extHandle, const Geometry * const * g, unsigned int ngeoms)
2999{
3000    if ( 0 == extHandle )
3001    {
3002        return 0;
3003    }
3004
3005    GEOSContextHandleInternal_t *handle = 0;
3006    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3007    if ( 0 == handle->initialized )
3008    {
3009        return 0;
3010    }
3011
3012    Geometry *out = 0;
3013
3014    try
3015    {
3016        // Polygonize
3017        using geos::operation::polygonize::Polygonizer;
3018        Polygonizer plgnzr;
3019        for (std::size_t i = 0; i < ngeoms; ++i)
3020        {
3021            plgnzr.add(g[i]);
3022        }
3023
3024#if GEOS_DEBUG
3025        handle->NOTICE_MESSAGE("geometry vector added to polygonizer");
3026#endif
3027
3028        const std::vector<const LineString *>& lines = plgnzr.getCutEdges();
3029
3030#if GEOS_DEBUG
3031        handle->NOTICE_MESSAGE("output polygons got");
3032#endif
3033
3034        // We need a vector of Geometry pointers, not Polygon pointers.
3035        // STL vector doesn't allow transparent upcast of this
3036        // nature, so we explicitly convert.
3037        // (it's just a waste of processor and memory, btw)
3038        // XXX mloskot: See comment for GEOSPolygonize_r
3039        std::vector<Geometry*> *linevec = new std::vector<Geometry *>(lines.size());
3040
3041        for (std::size_t i = 0, n=lines.size(); i < n; ++i)
3042        {
3043            (*linevec)[i] = lines[i]->clone();
3044        }
3045
3046        const GeometryFactory *gf = handle->geomFactory;
3047
3048        // The below takes ownership of the passed vector,
3049        // so we must *not* delete it
3050        out = gf->createGeometryCollection(linevec);
3051    }
3052    catch (const std::exception &e)
3053    {
3054        handle->ERROR_MESSAGE("%s", e.what());
3055    }
3056    catch (...)
3057    {
3058        handle->ERROR_MESSAGE("Unknown exception thrown");
3059    }
3060
3061    return out;
3062}
3063
3064Geometry *
3065GEOSPolygonize_full_r(GEOSContextHandle_t extHandle, const Geometry* g,
3066        Geometry** cuts, Geometry** dangles, Geometry** invalid)
3067{
3068    if ( 0 == extHandle )
3069    {
3070        return 0;
3071    }
3072
3073    GEOSContextHandleInternal_t *handle = 0;
3074    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3075    if ( 0 == handle->initialized )
3076    {
3077        return 0;
3078    }
3079
3080    try
3081    {
3082        // Polygonize
3083        using geos::operation::polygonize::Polygonizer;
3084        Polygonizer plgnzr;
3085        for (std::size_t i = 0; i <g->getNumGeometries(); ++i)
3086        {
3087            plgnzr.add(g->getGeometryN(i));
3088        }
3089
3090#if GEOS_DEBUG
3091        handle->NOTICE_MESSAGE("geometry vector added to polygonizer");
3092#endif
3093        const GeometryFactory *gf = handle->geomFactory;
3094
3095        if ( cuts ) {
3096
3097                const std::vector<const LineString *>& lines = plgnzr.getCutEdges();
3098                std::vector<Geometry*> *linevec = new std::vector<Geometry *>(lines.size());
3099                for (std::size_t i = 0, n=lines.size(); i < n; ++i)
3100                {
3101                    (*linevec)[i] = lines[i]->clone();
3102                }
3103
3104                // The below takes ownership of the passed vector,
3105                // so we must *not* delete it
3106                *cuts = gf->createGeometryCollection(linevec);
3107        }
3108
3109        if ( dangles ) {
3110
3111                const std::vector<const LineString *>& lines = plgnzr.getDangles();
3112                std::vector<Geometry*> *linevec = new std::vector<Geometry *>(lines.size());
3113                for (std::size_t i = 0, n=lines.size(); i < n; ++i)
3114                {
3115                    (*linevec)[i] = lines[i]->clone();
3116                }
3117
3118                // The below takes ownership of the passed vector,
3119                // so we must *not* delete it
3120                *dangles = gf->createGeometryCollection(linevec);
3121        }
3122
3123        if ( invalid ) {
3124
3125                const std::vector<LineString *>& lines = plgnzr.getInvalidRingLines();
3126                std::vector<Geometry*> *linevec = new std::vector<Geometry *>(lines.size());
3127                for (std::size_t i = 0, n=lines.size(); i < n; ++i)
3128                {
3129                    (*linevec)[i] = lines[i]->clone();
3130                }
3131
3132                // The below takes ownership of the passed vector,
3133                // so we must *not* delete it
3134                *invalid = gf->createGeometryCollection(linevec);
3135        }
3136
3137        std::vector<Polygon*> *polys = plgnzr.getPolygons();
3138        std::vector<Geometry*> *polyvec = new std::vector<Geometry *>(polys->size());
3139        for (std::size_t i = 0; i < polys->size(); ++i)
3140        {
3141            (*polyvec)[i] = (*polys)[i];
3142        }
3143        delete polys;
3144
3145        return gf->createGeometryCollection(polyvec);
3146
3147    }
3148    catch (const std::exception &e)
3149    {
3150        handle->ERROR_MESSAGE("%s", e.what());
3151        return 0;
3152    }
3153    catch (...)
3154    {
3155        handle->ERROR_MESSAGE("Unknown exception thrown");
3156        return 0;
3157    }
3158}
3159
3160Geometry *
3161GEOSLineMerge_r(GEOSContextHandle_t extHandle, const Geometry *g)
3162{
3163    if ( 0 == extHandle )
3164    {
3165        return 0;
3166    }
3167
3168    GEOSContextHandleInternal_t *handle = 0;
3169    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3170    if ( 0 == handle->initialized )
3171    {
3172        return 0;
3173    }
3174
3175    Geometry *out = 0;
3176
3177    try
3178    {
3179        using geos::operation::linemerge::LineMerger;
3180        LineMerger lmrgr;
3181        lmrgr.add(g);
3182
3183        std::vector<LineString *>* lines = lmrgr.getMergedLineStrings();
3184        assert(0 != lines);
3185
3186#if GEOS_DEBUG
3187        handle->NOTICE_MESSAGE("output lines got");
3188#endif
3189
3190        std::vector<Geometry *>*geoms = new std::vector<Geometry *>(lines->size());
3191        for (std::vector<Geometry *>::size_type i = 0; i < lines->size(); ++i)
3192        {
3193            (*geoms)[i] = (*lines)[i];
3194        }
3195        delete lines;
3196        lines = 0;
3197
3198        const GeometryFactory *gf = handle->geomFactory;
3199        out = gf->buildGeometry(geoms);
3200
3201        // XXX: old version
3202        //out = gf->createGeometryCollection(geoms);
3203    }
3204    catch (const std::exception &e)
3205    {
3206        handle->ERROR_MESSAGE("%s", e.what());
3207    }
3208    catch (...)
3209    {
3210        handle->ERROR_MESSAGE("Unknown exception thrown");
3211    }
3212
3213    return out;
3214}
3215
3216int
3217GEOSGetSRID_r(GEOSContextHandle_t extHandle, const Geometry *g)
3218{
3219    assert(0 != g);
3220
3221    if ( 0 == extHandle )
3222    {
3223        return 0;
3224    }
3225
3226    GEOSContextHandleInternal_t *handle = 0;
3227    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3228    if ( 0 == handle->initialized )
3229    {
3230        return 0;
3231    }
3232
3233    try
3234    {
3235        return g->getSRID();
3236    }
3237    catch (const std::exception &e)
3238    {
3239        handle->ERROR_MESSAGE("%s", e.what());
3240    }
3241    catch (...)
3242    {
3243        handle->ERROR_MESSAGE("Unknown exception thrown");
3244    }
3245   
3246    return 0;
3247}
3248
3249const char* GEOSversion()
3250{
3251    return GEOS_CAPI_VERSION;
3252}
3253
3254const char* GEOSjtsport()
3255{
3256    return GEOS_JTS_PORT;
3257}
3258
3259char
3260GEOSHasZ_r(GEOSContextHandle_t extHandle, const Geometry *g)
3261{
3262    assert(0 != g);
3263
3264    if ( 0 == extHandle )
3265    {
3266        return -1;
3267    }
3268
3269    GEOSContextHandleInternal_t *handle = 0;
3270    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3271    if ( 0 == handle->initialized )
3272    {
3273        return -1;
3274    }
3275
3276    if (g->isEmpty())
3277    {
3278        return false;
3279    }
3280    assert(0 != g->getCoordinate());
3281
3282    double az = g->getCoordinate()->z;
3283    //handle->ERROR_MESSAGE("ZCoord: %g", az);
3284
3285    return static_cast<char>(FINITE(az));
3286}
3287
3288int
3289GEOS_getWKBOutputDims_r(GEOSContextHandle_t extHandle)
3290{
3291    if ( 0 == extHandle )
3292    {
3293        return -1;
3294    }
3295
3296    GEOSContextHandleInternal_t *handle = 0;
3297    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3298    if ( 0 == handle->initialized )
3299    {
3300        return -1;
3301    }
3302
3303    return handle->WKBOutputDims;
3304}
3305
3306int
3307GEOS_setWKBOutputDims_r(GEOSContextHandle_t extHandle, int newdims)
3308{
3309    if ( 0 == extHandle )
3310    {
3311        return -1;
3312    }
3313
3314    GEOSContextHandleInternal_t *handle = 0;
3315    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3316    if ( 0 == handle->initialized )
3317    {
3318        return -1;
3319    }
3320
3321    if ( newdims < 2 || newdims > 3 )
3322    {
3323        handle->ERROR_MESSAGE("WKB output dimensions out of range 2..3");
3324    }
3325
3326    const int olddims = handle->WKBOutputDims;
3327    handle->WKBOutputDims = newdims;
3328
3329    return olddims;
3330}
3331
3332int
3333GEOS_getWKBByteOrder_r(GEOSContextHandle_t extHandle)
3334{
3335    if ( 0 == extHandle )
3336    {
3337        return -1;
3338    }
3339
3340    GEOSContextHandleInternal_t *handle = 0;
3341    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3342    if ( 0 == handle->initialized )
3343    {
3344        return -1;
3345    }
3346
3347    return handle->WKBByteOrder;
3348}
3349
3350int
3351GEOS_setWKBByteOrder_r(GEOSContextHandle_t extHandle, int byteOrder)
3352{
3353    if ( 0 == extHandle )
3354    {
3355        return -1;
3356    }
3357
3358    GEOSContextHandleInternal_t *handle = 0;
3359    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3360    if ( 0 == handle->initialized )
3361    {
3362        return -1;
3363    }
3364
3365    const int oldByteOrder = handle->WKBByteOrder;
3366    handle->WKBByteOrder = byteOrder;
3367
3368    return oldByteOrder;
3369}
3370
3371
3372CoordinateSequence *
3373GEOSCoordSeq_create_r(GEOSContextHandle_t extHandle, unsigned int size, unsigned int dims)
3374{
3375    if ( 0 == extHandle )
3376    {
3377        return NULL;
3378    }
3379
3380    GEOSContextHandleInternal_t *handle = 0;
3381    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3382    if ( 0 == handle->initialized )
3383    {
3384        return NULL;
3385    }
3386
3387    try
3388    {
3389        const GeometryFactory *gf = handle->geomFactory;
3390        return gf->getCoordinateSequenceFactory()->create(size, dims);
3391    }
3392    catch (const std::exception &e)
3393    {
3394        handle->ERROR_MESSAGE("%s", e.what());
3395    }
3396    catch (...)
3397    {
3398        handle->ERROR_MESSAGE("Unknown exception thrown");
3399    }
3400   
3401    return NULL;
3402}
3403
3404int
3405GEOSCoordSeq_setOrdinate_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs,
3406                           unsigned int idx, unsigned int dim, double val)
3407{
3408    assert(0 != cs);
3409    if ( 0 == extHandle )
3410    {
3411        return 0;
3412    }
3413
3414    GEOSContextHandleInternal_t *handle = 0;
3415    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3416    if ( 0 == handle->initialized )
3417    {
3418        return 0;
3419    }
3420
3421    try
3422    {
3423        cs->setOrdinate(static_cast<int>(idx), static_cast<int>(dim), val);
3424        return 1;
3425    }
3426    catch (const std::exception &e)
3427    {
3428        handle->ERROR_MESSAGE("%s", e.what());
3429    }
3430    catch (...)
3431    {
3432        handle->ERROR_MESSAGE("Unknown exception thrown");
3433    }
3434   
3435    return 0;
3436}
3437
3438int
3439GEOSCoordSeq_setX_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val)
3440{
3441    return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 0, val);
3442}
3443
3444int
3445GEOSCoordSeq_setY_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val)
3446{
3447    return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 1, val);
3448}
3449
3450int
3451GEOSCoordSeq_setZ_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val)
3452{
3453    return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 2, val);
3454}
3455
3456CoordinateSequence *
3457GEOSCoordSeq_clone_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs)
3458{
3459    assert(0 != cs);
3460
3461    if ( 0 == extHandle )
3462    {
3463        return NULL;
3464    }
3465
3466    GEOSContextHandleInternal_t *handle = 0;
3467    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3468    if ( 0 == handle->initialized )
3469    {
3470        return NULL;
3471    }
3472
3473    try
3474    {
3475        return cs->clone();
3476    }
3477    catch (const std::exception &e)
3478    {
3479        handle->ERROR_MESSAGE("%s", e.what());
3480    }
3481    catch (...)
3482    {
3483        handle->ERROR_MESSAGE("Unknown exception thrown");
3484    }
3485   
3486    return NULL;
3487}
3488
3489int
3490GEOSCoordSeq_getOrdinate_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs,
3491                           unsigned int idx, unsigned int dim, double *val)
3492{
3493    assert(0 != cs);
3494    assert(0 != val);
3495
3496    if ( 0 == extHandle )
3497    {
3498        return 0;
3499    }
3500
3501    GEOSContextHandleInternal_t *handle = 0;
3502    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3503    if ( 0 == handle->initialized )
3504    {
3505        return 0;
3506    }
3507
3508    try
3509    {
3510        double d = cs->getOrdinate(static_cast<int>(idx), static_cast<int>(dim));
3511        *val = d;
3512
3513        return 1;
3514    }
3515    catch (const std::exception &e)
3516    {
3517        handle->ERROR_MESSAGE("%s", e.what());
3518    }
3519    catch (...)
3520    {
3521        handle->ERROR_MESSAGE("Unknown exception thrown");
3522    }
3523   
3524    return 0;
3525}
3526
3527int
3528GEOSCoordSeq_getX_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val)
3529{
3530    return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 0, val);
3531}
3532
3533int
3534GEOSCoordSeq_getY_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val)
3535{
3536    return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 1, val);
3537}
3538
3539int
3540GEOSCoordSeq_getZ_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val)
3541{
3542    return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 2, val);
3543}
3544
3545int
3546GEOSCoordSeq_getSize_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs, unsigned int *size)
3547{
3548    assert(0 != cs);
3549    assert(0 != size);
3550
3551    if ( 0 == extHandle )
3552    {
3553        return 0;
3554    }
3555
3556    GEOSContextHandleInternal_t *handle = 0;
3557    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3558    if ( 0 == handle->initialized )
3559    {
3560        return 0;
3561    }
3562
3563    try
3564    {
3565        const std::size_t sz = cs->getSize();
3566        *size = static_cast<unsigned int>(sz);
3567        return 1;
3568    }
3569    catch (const std::exception &e)
3570    {
3571        handle->ERROR_MESSAGE("%s", e.what());
3572    }
3573    catch (...)
3574    {
3575        handle->ERROR_MESSAGE("Unknown exception thrown");
3576    }
3577   
3578    return 0;
3579}
3580
3581int
3582GEOSCoordSeq_getDimensions_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs, unsigned int *dims)
3583{
3584    assert(0 != cs);
3585    assert(0 != dims);
3586
3587    if ( 0 == extHandle )
3588    {
3589        return 0;
3590    }
3591
3592    GEOSContextHandleInternal_t *handle = 0;
3593    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3594    if ( 0 == handle->initialized )
3595    {
3596        return 0;
3597    }
3598
3599    try
3600    {
3601        const std::size_t dim = cs->getDimension();
3602        *dims = static_cast<unsigned int>(dim);
3603
3604        return 1;
3605    }
3606    catch (const std::exception &e)
3607    {
3608        handle->ERROR_MESSAGE("%s", e.what());
3609    }
3610
3611    catch (...)
3612    {
3613        handle->ERROR_MESSAGE("Unknown exception thrown");
3614    }
3615   
3616    return 0;
3617}
3618
3619void
3620GEOSCoordSeq_destroy_r(GEOSContextHandle_t extHandle, CoordinateSequence *s)
3621{
3622    GEOSContextHandleInternal_t *handle = 0;
3623
3624    try
3625    {
3626        delete s;
3627    }
3628    catch (const std::exception &e)
3629    {
3630        if ( 0 == extHandle )
3631        {
3632            return;
3633        }
3634
3635        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3636        if ( 0 == handle->initialized )
3637        {
3638            return;
3639        }
3640
3641        handle->ERROR_MESSAGE("%s", e.what());
3642    }
3643    catch (...)
3644    {
3645        if ( 0 == extHandle )
3646        {
3647            return;
3648        }
3649
3650        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3651        if ( 0 == handle->initialized )
3652        {
3653            return;
3654        }
3655
3656        handle->ERROR_MESSAGE("Unknown exception thrown");
3657    }
3658}
3659
3660const CoordinateSequence *
3661GEOSGeom_getCoordSeq_r(GEOSContextHandle_t extHandle, const Geometry *g)
3662{
3663    if ( 0 == extHandle )
3664    {
3665        return 0;
3666    }
3667
3668    GEOSContextHandleInternal_t *handle = 0;
3669    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3670    if ( 0 == handle->initialized )
3671    {
3672        return 0;
3673    }
3674
3675    try
3676    {
3677        using geos::geom::Point;
3678
3679        const LineString *ls = dynamic_cast<const LineString *>(g);
3680        if ( ls )
3681        {
3682            return ls->getCoordinatesRO();
3683        }
3684
3685        const Point *p = dynamic_cast<const Point *>(g);
3686        if ( p )
3687        {
3688            return p->getCoordinatesRO();
3689        }
3690
3691        handle->ERROR_MESSAGE("Geometry must be a Point or LineString");
3692        return 0;
3693    }
3694    catch (const std::exception &e)
3695    {
3696        handle->ERROR_MESSAGE("%s", e.what());
3697    }
3698    catch (...)
3699    {
3700        handle->ERROR_MESSAGE("Unknown exception thrown");
3701    }
3702   
3703    return 0;
3704}
3705
3706Geometry *
3707GEOSGeom_createEmptyPoint_r(GEOSContextHandle_t extHandle)
3708{
3709    if ( 0 == extHandle )
3710    {
3711        return NULL;
3712    }
3713
3714    GEOSContextHandleInternal_t *handle = 0;
3715    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3716    if ( 0 == handle->initialized )
3717    {
3718        return NULL;
3719    }
3720
3721    try
3722    {
3723        const GeometryFactory *gf = handle->geomFactory;
3724        return gf->createPoint();
3725    }
3726    catch (const std::exception &e)
3727    {
3728        handle->ERROR_MESSAGE("%s", e.what());
3729    }
3730    catch (...)
3731    {
3732        handle->ERROR_MESSAGE("Unknown exception thrown");
3733    }
3734   
3735    return NULL;
3736}
3737
3738Geometry *
3739GEOSGeom_createPoint_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs)
3740{
3741    if ( 0 == extHandle )
3742    {
3743        return 0;
3744    }
3745
3746    GEOSContextHandleInternal_t *handle = 0;
3747    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3748    if ( 0 == handle->initialized )
3749    {
3750        return 0;
3751    }
3752
3753    try
3754    {
3755        const GeometryFactory *gf = handle->geomFactory;
3756        return gf->createPoint(cs);
3757    }
3758    catch (const std::exception &e)
3759    {
3760        handle->ERROR_MESSAGE("%s", e.what());
3761    }
3762    catch (...)
3763    {
3764        handle->ERROR_MESSAGE("Unknown exception thrown");
3765    }
3766
3767    return 0;
3768}
3769
3770Geometry *
3771GEOSGeom_createLinearRing_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs)
3772{
3773    if ( 0 == extHandle )
3774    {
3775        return NULL;
3776    }
3777
3778    GEOSContextHandleInternal_t *handle = 0;
3779    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3780    if ( 0 == handle->initialized )
3781    {
3782        return NULL;
3783    }
3784
3785    try
3786    {
3787        const GeometryFactory *gf = handle->geomFactory;
3788
3789        return gf->createLinearRing(cs);
3790    }
3791    catch (const std::exception &e)
3792    {
3793        handle->ERROR_MESSAGE("%s", e.what());
3794    }
3795    catch (...)
3796    {
3797        handle->ERROR_MESSAGE("Unknown exception thrown");
3798    }
3799   
3800    return NULL;
3801}
3802
3803Geometry *
3804GEOSGeom_createEmptyLineString_r(GEOSContextHandle_t extHandle)
3805{
3806    if ( 0 == extHandle )
3807    {
3808        return NULL;
3809    }
3810
3811    GEOSContextHandleInternal_t *handle = 0;
3812    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3813    if ( 0 == handle->initialized )
3814    {
3815        return NULL;
3816    }
3817
3818    try
3819    {
3820        const GeometryFactory *gf = handle->geomFactory;
3821
3822        return gf->createLineString();
3823    }
3824    catch (const std::exception &e)
3825    {
3826        handle->ERROR_MESSAGE("%s", e.what());
3827    }
3828    catch (...)
3829    {
3830        handle->ERROR_MESSAGE("Unknown exception thrown");
3831    }
3832   
3833    return NULL;
3834}
3835
3836Geometry *
3837GEOSGeom_createLineString_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs)
3838{
3839    if ( 0 == extHandle )
3840    {
3841        return NULL;
3842    }
3843
3844    GEOSContextHandleInternal_t *handle = 0;
3845    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3846    if ( 0 == handle->initialized )
3847    {
3848        return NULL;
3849    }
3850
3851    try
3852    {
3853        const GeometryFactory *gf = handle->geomFactory;
3854
3855        return gf->createLineString(cs);
3856    }
3857    catch (const std::exception &e)
3858    {
3859        handle->ERROR_MESSAGE("%s", e.what());
3860    }
3861    catch (...)
3862    {
3863        handle->ERROR_MESSAGE("Unknown exception thrown");
3864    }
3865   
3866    return NULL;
3867}
3868
3869Geometry *
3870GEOSGeom_createEmptyPolygon_r(GEOSContextHandle_t extHandle)
3871{
3872    if ( 0 == extHandle )
3873    {
3874        return NULL;
3875    }
3876
3877    GEOSContextHandleInternal_t *handle = 0;
3878    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3879    if ( 0 == handle->initialized )
3880    {
3881        return NULL;
3882    }
3883
3884    try
3885    {
3886        const GeometryFactory *gf = handle->geomFactory;
3887        return gf->createPolygon();
3888    }
3889    catch (const std::exception &e)
3890    {
3891        handle->ERROR_MESSAGE("%s", e.what());
3892    }
3893    catch (...)
3894    {
3895        handle->ERROR_MESSAGE("Unknown exception thrown");
3896    }
3897   
3898    return NULL;
3899}
3900
3901Geometry *
3902GEOSGeom_createPolygon_r(GEOSContextHandle_t extHandle, Geometry *shell, Geometry **holes, unsigned int nholes)
3903{
3904    // FIXME: holes must be non-nullptr or may be nullptr?
3905    //assert(0 != holes);
3906
3907    if ( 0 == extHandle )
3908    {
3909        return NULL;
3910    }
3911
3912    GEOSContextHandleInternal_t *handle = 0;
3913    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3914    if ( 0 == handle->initialized )
3915    {
3916        return NULL;
3917    }
3918
3919    try
3920    {
3921        using geos::geom::LinearRing;
3922       
3923        std::vector<Geometry *> *vholes = new std::vector<Geometry *>(holes, holes + nholes);
3924
3925        LinearRing *nshell = dynamic_cast<LinearRing *>(shell);
3926        if ( ! nshell )
3927        {
3928            handle->ERROR_MESSAGE("Shell is not a LinearRing");
3929            return NULL;
3930        }
3931        const GeometryFactory *gf = handle->geomFactory;
3932
3933        return gf->createPolygon(nshell, vholes);
3934    }
3935    catch (const std::exception &e)
3936    {
3937        handle->ERROR_MESSAGE("%s", e.what());
3938    }
3939    catch (...)
3940    {
3941        handle->ERROR_MESSAGE("Unknown exception thrown");
3942    }
3943   
3944    return NULL;
3945}
3946
3947Geometry *
3948GEOSGeom_clone_r(GEOSContextHandle_t extHandle, const Geometry *g)
3949{
3950    assert(0 != g);
3951
3952    if ( 0 == extHandle )
3953    {
3954        return NULL;
3955    }
3956
3957    GEOSContextHandleInternal_t *handle = 0;
3958    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3959    if ( 0 == handle->initialized )
3960    {
3961        return NULL;
3962    }
3963
3964    try
3965    {
3966        return g->clone();
3967    }
3968    catch (const std::exception &e)
3969    {
3970        handle->ERROR_MESSAGE("%s", e.what());
3971    }
3972    catch (...)
3973    {
3974        handle->ERROR_MESSAGE("Unknown exception thrown");
3975    }
3976   
3977    return NULL;
3978}
3979
3980int
3981GEOSGeom_getDimensions_r(GEOSContextHandle_t extHandle, const Geometry *g)
3982{
3983    if ( 0 == extHandle )
3984    {
3985        return 0;
3986    }
3987
3988    GEOSContextHandleInternal_t *handle = 0;
3989    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
3990    if ( 0 == handle->initialized )
3991    {
3992        return 0;
3993    }
3994
3995    try
3996    {
3997        return (int) g->getDimension();
3998    }
3999    catch (const std::exception &e)
4000    {
4001        handle->ERROR_MESSAGE("%s", e.what());
4002    }
4003    catch (...)
4004    {
4005        handle->ERROR_MESSAGE("Unknown exception thrown");
4006    }
4007   
4008    return 0;
4009}
4010
4011int
4012GEOSGeom_getCoordinateDimension_r(GEOSContextHandle_t extHandle, const Geometry *g)
4013{
4014    if ( 0 == extHandle )
4015    {
4016        return 0;
4017    }
4018
4019    GEOSContextHandleInternal_t *handle = 0;
4020    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4021    if ( 0 == handle->initialized )
4022    {
4023        return 0;
4024    }
4025
4026    try
4027    {
4028        return g->getCoordinateDimension();
4029    }
4030    catch (const std::exception &e)
4031    {
4032        handle->ERROR_MESSAGE("%s", e.what());
4033    }
4034    catch (...)
4035    {
4036        handle->ERROR_MESSAGE("Unknown exception thrown");
4037    }
4038   
4039    return 0;
4040}
4041
4042Geometry *
4043GEOSSimplify_r(GEOSContextHandle_t extHandle, const Geometry *g1, double tolerance)
4044{
4045    if ( 0 == extHandle )
4046    {
4047        return NULL;
4048    }
4049
4050    GEOSContextHandleInternal_t *handle = 0;
4051    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4052    if ( 0 == handle->initialized )
4053    {
4054        return NULL;
4055    }
4056
4057    try
4058    {
4059        using namespace geos::simplify;
4060        Geometry::AutoPtr g(DouglasPeuckerSimplifier::simplify(g1, tolerance));
4061        return g.release();
4062    }
4063    catch (const std::exception &e)
4064    {
4065        handle->ERROR_MESSAGE("%s", e.what());
4066    }
4067    catch (...)
4068    {
4069        handle->ERROR_MESSAGE("Unknown exception thrown");
4070    }
4071   
4072    return NULL;
4073}
4074
4075Geometry *
4076GEOSTopologyPreserveSimplify_r(GEOSContextHandle_t extHandle, const Geometry *g1, double tolerance)
4077{
4078    if ( 0 == extHandle )
4079    {
4080        return NULL;
4081    }
4082
4083    GEOSContextHandleInternal_t *handle = 0;
4084    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4085    if ( 0 == handle->initialized )
4086    {
4087        return NULL;
4088    }
4089
4090    try
4091    {
4092        using namespace geos::simplify;
4093        Geometry::AutoPtr g(TopologyPreservingSimplifier::simplify(g1, tolerance));
4094        return g.release();
4095    }
4096    catch (const std::exception &e)
4097    {
4098        handle->ERROR_MESSAGE("%s", e.what());
4099    }
4100    catch (...)
4101    {
4102        handle->ERROR_MESSAGE("Unknown exception thrown");
4103    }
4104   
4105    return NULL;
4106}
4107
4108
4109/* WKT Reader */
4110WKTReader *
4111GEOSWKTReader_create_r(GEOSContextHandle_t extHandle)
4112{
4113    if ( 0 == extHandle )
4114    {
4115        return NULL;
4116    }
4117
4118    GEOSContextHandleInternal_t *handle = 0;
4119    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4120    if ( 0 == handle->initialized )
4121    {
4122        return NULL;
4123    }
4124
4125    try
4126    {
4127        using geos::io::WKTReader;
4128        return new WKTReader((GeometryFactory*)handle->geomFactory);
4129    }
4130    catch (const std::exception &e)
4131    {
4132        handle->ERROR_MESSAGE("%s", e.what());
4133    }
4134    catch (...)
4135    {
4136        handle->ERROR_MESSAGE("Unknown exception thrown");
4137    }
4138   
4139    return NULL;
4140}
4141
4142void
4143GEOSWKTReader_destroy_r(GEOSContextHandle_t extHandle, WKTReader *reader)
4144{
4145    GEOSContextHandleInternal_t *handle = 0;
4146
4147    try
4148    {
4149        delete reader;
4150    }
4151    catch (const std::exception &e)
4152    {
4153        if ( 0 == extHandle )
4154        {
4155            return;
4156        }
4157
4158        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4159        if ( 0 == handle->initialized )
4160        {
4161            return;
4162        }
4163
4164        handle->ERROR_MESSAGE("%s", e.what());
4165    }
4166    catch (...)
4167    {
4168        if ( 0 == extHandle )
4169        {
4170            return;
4171        }
4172
4173        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4174        if ( 0 == handle->initialized )
4175        {
4176            return;
4177        }
4178
4179        handle->ERROR_MESSAGE("Unknown exception thrown");
4180    }
4181}
4182
4183
4184Geometry*
4185GEOSWKTReader_read_r(GEOSContextHandle_t extHandle, WKTReader *reader, const char *wkt)
4186{
4187    assert(0 != reader);
4188
4189    if ( 0 == extHandle )
4190    {
4191        return 0;
4192    }
4193
4194    GEOSContextHandleInternal_t *handle = 0;
4195    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4196    if ( 0 == handle->initialized )
4197    {
4198        return 0;
4199    }
4200
4201    try
4202    {
4203        const std::string wktstring(wkt);
4204        Geometry *g = reader->read(wktstring);
4205        return g;
4206    }
4207    catch (const std::exception &e)
4208    {
4209        handle->ERROR_MESSAGE("%s", e.what());
4210    }
4211    catch (...)
4212    {
4213        handle->ERROR_MESSAGE("Unknown exception thrown");
4214    }
4215   
4216    return 0;
4217}
4218
4219/* WKT Writer */
4220WKTWriter *
4221GEOSWKTWriter_create_r(GEOSContextHandle_t extHandle)
4222{
4223    if ( 0 == extHandle )
4224    {
4225        return 0;
4226    }
4227
4228    GEOSContextHandleInternal_t *handle = 0;
4229    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4230    if ( 0 == handle->initialized )
4231    {
4232        return 0;
4233    }
4234
4235    try
4236    {
4237        using geos::io::WKTWriter;
4238        return new WKTWriter();
4239    }
4240    catch (const std::exception &e)
4241    {
4242        handle->ERROR_MESSAGE("%s", e.what());
4243    }
4244    catch (...)
4245    {
4246        handle->ERROR_MESSAGE("Unknown exception thrown");
4247    }
4248   
4249    return 0;
4250}
4251
4252void
4253GEOSWKTWriter_destroy_r(GEOSContextHandle_t extHandle, WKTWriter *Writer)
4254{
4255
4256    GEOSContextHandleInternal_t *handle = 0;
4257
4258    try
4259    {
4260        delete Writer;
4261    }
4262    catch (const std::exception &e)
4263    {
4264        if ( 0 == extHandle )
4265        {
4266            return;
4267        }
4268
4269        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4270        if ( 0 == handle->initialized )
4271        {
4272            return;
4273        }
4274
4275        handle->ERROR_MESSAGE("%s", e.what());
4276    }
4277    catch (...)
4278    {
4279        if ( 0 == extHandle )
4280        {
4281            return;
4282        }
4283
4284        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4285        if ( 0 == handle->initialized )
4286        {
4287            return;
4288        }
4289
4290        handle->ERROR_MESSAGE("Unknown exception thrown");
4291    }
4292}
4293
4294
4295char*
4296GEOSWKTWriter_write_r(GEOSContextHandle_t extHandle, WKTWriter *writer, const Geometry *geom)
4297{
4298    assert(0 != writer);
4299
4300    if ( 0 == extHandle )
4301    {
4302        return NULL;
4303    }
4304
4305    GEOSContextHandleInternal_t *handle = 0;
4306    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4307    if ( 0 == handle->initialized )
4308    {
4309        return NULL;
4310    }
4311
4312    try
4313    {
4314        std::string sgeom(writer->write(geom));
4315        char *result = gstrdup(sgeom);
4316        return result;
4317    }
4318    catch (const std::exception &e)
4319    {
4320        handle->ERROR_MESSAGE("%s", e.what());
4321    }
4322    catch (...)
4323    {
4324        handle->ERROR_MESSAGE("Unknown exception thrown");
4325    }
4326   
4327    return NULL;
4328}
4329
4330void
4331GEOSWKTWriter_setTrim_r(GEOSContextHandle_t extHandle, WKTWriter *writer, char trim)
4332{
4333    assert(0 != writer);
4334
4335    if ( 0 == extHandle )
4336    {
4337        return;
4338    }
4339
4340    GEOSContextHandleInternal_t *handle = 0;
4341    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4342    if ( 0 == handle->initialized )
4343    {
4344        return;
4345    }
4346
4347    writer->setTrim(0 != trim);
4348}
4349
4350void
4351GEOSWKTWriter_setRoundingPrecision_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int precision)
4352{
4353    assert(0 != writer);
4354
4355    if ( 0 == extHandle )
4356    {
4357        return;
4358    }
4359
4360    GEOSContextHandleInternal_t *handle = 0;
4361    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4362    if ( 0 == handle->initialized )
4363    {
4364        return;
4365    }
4366
4367    writer->setRoundingPrecision(precision);
4368}
4369
4370void
4371GEOSWKTWriter_setOutputDimension_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int dim)
4372{
4373    assert(0 != writer);
4374
4375    if ( 0 == extHandle )
4376    {
4377        return;
4378    }
4379
4380    GEOSContextHandleInternal_t *handle = 0;
4381    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4382    if ( 0 == handle->initialized )
4383    {
4384        return;
4385    }
4386
4387    try
4388    {
4389        writer->setOutputDimension(dim);
4390    }
4391    catch (const std::exception &e)
4392    {
4393        handle->ERROR_MESSAGE("%s", e.what());
4394    }
4395    catch (...)
4396    {
4397        handle->ERROR_MESSAGE("Unknown exception thrown");
4398    }
4399}
4400
4401int
4402GEOSWKTWriter_getOutputDimension_r(GEOSContextHandle_t extHandle, WKTWriter *writer)
4403{
4404    assert(0 != writer);
4405
4406    if ( 0 == extHandle )
4407    {
4408        return -1;
4409    }
4410
4411    GEOSContextHandleInternal_t *handle = 0;
4412    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4413    if ( 0 == handle->initialized )
4414    {
4415        return -1;
4416    }
4417
4418    int  dim = -1;
4419
4420    try
4421    {
4422        dim = writer->getOutputDimension();
4423    }
4424    catch (const std::exception &e)
4425    {
4426        handle->ERROR_MESSAGE("%s", e.what());
4427    }
4428    catch (...)
4429    {
4430        handle->ERROR_MESSAGE("Unknown exception thrown");
4431    }
4432
4433    return dim;
4434}
4435
4436void
4437GEOSWKTWriter_setOld3D_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int useOld3D)
4438{
4439    assert(0 != writer);
4440
4441    if ( 0 == extHandle )
4442    {
4443        return;
4444    }
4445
4446    GEOSContextHandleInternal_t *handle = 0;
4447    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4448    if ( 0 == handle->initialized )
4449    {
4450        return;
4451    }
4452
4453    writer->setOld3D(0 != useOld3D);
4454}
4455
4456/* WKB Reader */
4457WKBReader *
4458GEOSWKBReader_create_r(GEOSContextHandle_t extHandle)
4459{
4460    if ( 0 == extHandle )
4461    {
4462        return NULL;
4463    }
4464
4465    GEOSContextHandleInternal_t *handle = 0;
4466    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4467    if ( 0 == handle->initialized )
4468    {
4469        return NULL;
4470    }
4471
4472    using geos::io::WKBReader;
4473    try
4474    {
4475        return new WKBReader(*(GeometryFactory*)handle->geomFactory);
4476    }
4477    catch (const std::exception &e)
4478    {
4479        handle->ERROR_MESSAGE("%s", e.what());
4480    }
4481    catch (...)
4482    {
4483        handle->ERROR_MESSAGE("Unknown exception thrown");
4484    }
4485   
4486    return NULL;
4487}
4488
4489void
4490GEOSWKBReader_destroy_r(GEOSContextHandle_t extHandle, WKBReader *reader)
4491{
4492    GEOSContextHandleInternal_t *handle = 0;
4493
4494    try
4495    {
4496        delete reader;
4497    }
4498    catch (const std::exception &e)
4499    {
4500        if ( 0 == extHandle )
4501        {
4502            return;
4503        }
4504
4505        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4506        if ( 0 == handle->initialized )
4507        {
4508            return;
4509        }
4510
4511        handle->ERROR_MESSAGE("%s", e.what());
4512    }
4513    catch (...)
4514    {
4515        if ( 0 == extHandle )
4516        {
4517            return;
4518        }
4519
4520        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4521        if ( 0 == handle->initialized )
4522        {
4523            return;
4524        }
4525
4526        handle->ERROR_MESSAGE("Unknown exception thrown");
4527    }
4528}
4529
4530
4531Geometry*
4532GEOSWKBReader_read_r(GEOSContextHandle_t extHandle, WKBReader *reader, const unsigned char *wkb, size_t size)
4533{
4534    assert(0 != reader);
4535    assert(0 != wkb);
4536
4537    if ( 0 == extHandle )
4538    {
4539        return 0;
4540    }
4541
4542    GEOSContextHandleInternal_t *handle = 0;
4543    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4544    if ( 0 == handle->initialized )
4545    {
4546        return 0;
4547    }
4548
4549    try
4550    {
4551        std::string wkbstring(reinterpret_cast<const char*>(wkb), size); // make it binary !
4552        std::istringstream is(std::ios_base::binary);
4553        is.str(wkbstring);
4554        is.seekg(0, std::ios::beg); // rewind reader pointer
4555       
4556        Geometry *g = reader->read(is);
4557        return g;
4558    }
4559    catch (const std::exception &e)
4560    {
4561        handle->ERROR_MESSAGE("%s", e.what());
4562    }
4563    catch (...)
4564    {
4565        handle->ERROR_MESSAGE("Unknown exception thrown");
4566    }
4567   
4568    return 0;
4569}
4570
4571Geometry*
4572GEOSWKBReader_readHEX_r(GEOSContextHandle_t extHandle, WKBReader *reader, const unsigned char *hex, size_t size)
4573{
4574    assert(0 != reader);
4575    assert(0 != hex);
4576   
4577    if ( 0 == extHandle )
4578    {
4579        return 0;
4580    }
4581
4582    GEOSContextHandleInternal_t *handle = 0;
4583    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4584    if ( 0 == handle->initialized )
4585    {
4586        return 0;
4587    }
4588
4589    try
4590    {
4591        std::string hexstring(reinterpret_cast<const char*>(hex), size);
4592        std::istringstream is(std::ios_base::binary);
4593        is.str(hexstring);
4594        is.seekg(0, std::ios::beg); // rewind reader pointer
4595
4596        Geometry *g = reader->readHEX(is);
4597        return g;
4598    }
4599    catch (const std::exception &e)
4600    {
4601        handle->ERROR_MESSAGE("%s", e.what());
4602    }
4603    catch (...)
4604    {
4605        handle->ERROR_MESSAGE("Unknown exception thrown");
4606    }
4607   
4608    return 0;
4609}
4610
4611/* WKB Writer */
4612WKBWriter *
4613GEOSWKBWriter_create_r(GEOSContextHandle_t extHandle)
4614{
4615    if ( 0 == extHandle )
4616    {
4617        return NULL;
4618    }
4619
4620    GEOSContextHandleInternal_t *handle = 0;
4621    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4622    if ( 0 == handle->initialized )
4623    {
4624        return NULL;
4625    }
4626
4627    try
4628    {
4629        using geos::io::WKBWriter;
4630        return new WKBWriter();
4631    }
4632    catch (const std::exception &e)
4633    {
4634        handle->ERROR_MESSAGE("%s", e.what());
4635    }
4636    catch (...)
4637    {
4638        handle->ERROR_MESSAGE("Unknown exception thrown");
4639    }
4640   
4641    return NULL;
4642}
4643
4644void
4645GEOSWKBWriter_destroy_r(GEOSContextHandle_t extHandle, WKBWriter *Writer)
4646{
4647    GEOSContextHandleInternal_t *handle = 0;
4648
4649    try
4650    {
4651        delete Writer;
4652    }
4653    catch (const std::exception &e)
4654    {
4655        if ( 0 == extHandle )
4656        {
4657            return;
4658        }
4659
4660        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4661        if ( 0 == handle->initialized )
4662        {
4663            return;
4664        }
4665
4666        handle->ERROR_MESSAGE("%s", e.what());
4667    }
4668    catch (...)
4669    {
4670        if ( 0 == extHandle )
4671        {
4672            return;
4673        }
4674
4675        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4676        if ( 0 == handle->initialized )
4677        {
4678            return;
4679        }
4680
4681        handle->ERROR_MESSAGE("Unknown exception thrown");
4682    }
4683}
4684
4685
4686/* The caller owns the result */
4687unsigned char*
4688GEOSWKBWriter_write_r(GEOSContextHandle_t extHandle, WKBWriter *writer, const Geometry *geom, size_t *size)
4689{
4690    assert(0 != writer);
4691    assert(0 != geom);
4692    assert(0 != size);
4693
4694    if ( 0 == extHandle )
4695    {
4696        return NULL;
4697    }
4698
4699    GEOSContextHandleInternal_t *handle = 0;
4700    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4701    if ( 0 == handle->initialized )
4702    {
4703        return NULL;
4704    }
4705
4706    try
4707    {
4708        std::ostringstream os(std::ios_base::binary);
4709        writer->write(*geom, os);
4710        std::string wkbstring(os.str());
4711        const std::size_t len = wkbstring.length();
4712
4713        unsigned char *result = NULL;
4714        result = (unsigned char*) std::malloc(len);
4715        std::memcpy(result, wkbstring.c_str(), len);
4716        *size = len;
4717        return result;
4718    }
4719    catch (const std::exception &e)
4720    {
4721        handle->ERROR_MESSAGE("%s", e.what());
4722    }
4723    catch (...)
4724    {
4725        handle->ERROR_MESSAGE("Unknown exception thrown");
4726    }
4727    return NULL;
4728}
4729
4730/* The caller owns the result */
4731unsigned char*
4732GEOSWKBWriter_writeHEX_r(GEOSContextHandle_t extHandle, WKBWriter *writer, const Geometry *geom, size_t *size)
4733{
4734    assert(0 != writer);
4735    assert(0 != geom);
4736    assert(0 != size);
4737
4738    if ( 0 == extHandle )
4739    {
4740        return NULL;
4741    }
4742
4743    GEOSContextHandleInternal_t *handle = 0;
4744    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4745    if ( 0 == handle->initialized )
4746    {
4747        return NULL;
4748    }
4749
4750    try
4751    {
4752        std::ostringstream os(std::ios_base::binary);
4753        writer->writeHEX(*geom, os);
4754        std::string wkbstring(os.str());
4755        const std::size_t len = wkbstring.length();
4756
4757        unsigned char *result = NULL;
4758        result = (unsigned char*) std::malloc(len);
4759        std::memcpy(result, wkbstring.c_str(), len);
4760        *size = len;
4761        return result;
4762    }
4763    catch (const std::exception &e)
4764    {
4765        handle->ERROR_MESSAGE("%s", e.what());
4766    }
4767    catch (...)
4768    {
4769        handle->ERROR_MESSAGE("Unknown exception thrown");
4770    }
4771
4772    return NULL;
4773}
4774
4775int
4776GEOSWKBWriter_getOutputDimension_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer)
4777{
4778    assert(0 != writer);
4779   
4780    if ( 0 == extHandle )
4781    {
4782        return 0;
4783    }
4784
4785    int ret = 0;
4786
4787    GEOSContextHandleInternal_t *handle = 0;
4788    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4789    if ( 0 != handle->initialized )
4790    {
4791        try
4792        {
4793            ret = writer->getOutputDimension();
4794        }
4795        catch (...)
4796        {
4797            handle->ERROR_MESSAGE("Unknown exception thrown");
4798        }
4799    }
4800
4801    return ret;
4802}
4803
4804void
4805GEOSWKBWriter_setOutputDimension_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, int newDimension)
4806{
4807    assert(0 != writer);
4808
4809    if ( 0 == extHandle )
4810    {
4811        return;
4812    }
4813
4814    GEOSContextHandleInternal_t *handle = 0;
4815    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4816    if ( 0 != handle->initialized )
4817    {
4818        try
4819        {
4820            writer->setOutputDimension(newDimension);
4821        }
4822        catch (const std::exception &e)
4823        {
4824            handle->ERROR_MESSAGE("%s", e.what());
4825        }
4826        catch (...)
4827        {
4828            handle->ERROR_MESSAGE("Unknown exception thrown");
4829        }
4830    }
4831}
4832
4833int
4834GEOSWKBWriter_getByteOrder_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer)
4835{
4836    assert(0 != writer);
4837
4838    if ( 0 == extHandle )
4839    {
4840        return 0;
4841    }
4842
4843    int ret = 0;
4844
4845    GEOSContextHandleInternal_t *handle = 0;
4846    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4847    if ( 0 != handle->initialized )
4848    {
4849        try
4850        {
4851            ret = writer->getByteOrder();
4852        }
4853
4854        catch (...)
4855        {
4856            handle->ERROR_MESSAGE("Unknown exception thrown");
4857        }
4858    }
4859
4860    return ret;
4861}
4862
4863void
4864GEOSWKBWriter_setByteOrder_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, int newByteOrder)
4865{
4866    assert(0 != writer);
4867
4868    if ( 0 == extHandle )
4869    {
4870        return;
4871    }
4872
4873    GEOSContextHandleInternal_t *handle = 0;
4874    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4875    if ( 0 != handle->initialized )
4876    {
4877        try
4878        {
4879            writer->setByteOrder(newByteOrder);
4880        }
4881        catch (const std::exception &e)
4882        {
4883            handle->ERROR_MESSAGE("%s", e.what());
4884        }
4885        catch (...)
4886        {
4887            handle->ERROR_MESSAGE("Unknown exception thrown");
4888        }
4889    }
4890}
4891
4892char
4893GEOSWKBWriter_getIncludeSRID_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer)
4894{
4895    assert(0 != writer);
4896
4897    if ( 0 == extHandle )
4898    {
4899        return -1;
4900    }
4901
4902    int ret = -1;
4903
4904    GEOSContextHandleInternal_t *handle = 0;
4905    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4906    if ( 0 != handle->initialized )
4907    {
4908        try
4909        {
4910            int srid = writer->getIncludeSRID();
4911            ret = static_cast<char>(srid);
4912        }
4913        catch (...)
4914        {
4915            handle->ERROR_MESSAGE("Unknown exception thrown");
4916        }
4917    }
4918   
4919    return static_cast<char>(ret);
4920}
4921
4922void
4923GEOSWKBWriter_setIncludeSRID_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, const char newIncludeSRID)
4924{
4925    assert(0 != writer);
4926
4927    if ( 0 == extHandle )
4928    {
4929        return;
4930    }
4931
4932    GEOSContextHandleInternal_t *handle = 0;
4933    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4934    if ( 0 != handle->initialized )
4935    {
4936        try
4937        {
4938            writer->setIncludeSRID(newIncludeSRID);
4939        }
4940        catch (...)
4941        {
4942            handle->ERROR_MESSAGE("Unknown exception thrown");
4943        }
4944    }
4945}
4946
4947
4948//-----------------------------------------------------------------
4949// Prepared Geometry
4950//-----------------------------------------------------------------
4951
4952const geos::geom::prep::PreparedGeometry*
4953GEOSPrepare_r(GEOSContextHandle_t extHandle, const Geometry *g)
4954{
4955    if ( 0 == extHandle )
4956    {
4957        return 0;
4958    }
4959
4960    GEOSContextHandleInternal_t *handle = 0;
4961    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
4962    if ( 0 == handle->initialized )
4963    {
4964        return 0;
4965    }
4966
4967    const geos::geom::prep::PreparedGeometry* prep = 0;
4968
4969    try
4970    {
4971        prep = geos::geom::prep::PreparedGeometryFactory::prepare(g);
4972    }
4973    catch (const std::exception &e)
4974    {
4975        handle->ERROR_MESSAGE("%s", e.what());
4976    }
4977    catch (...)
4978    {
4979        handle->ERROR_MESSAGE("Unknown exception thrown");
4980    }
4981   
4982    return prep;
4983}
4984
4985void
4986GEOSPreparedGeom_destroy_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *a)
4987{
4988    GEOSContextHandleInternal_t *handle = 0;
4989
4990    try
4991    {
4992        delete a;
4993    }
4994    catch (const std::exception &e)
4995    {
4996        if ( 0 == extHandle )
4997        {
4998            return;
4999        }
5000
5001        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5002        if ( 0 == handle->initialized )
5003        {
5004            return;
5005        }
5006
5007        handle->ERROR_MESSAGE("%s", e.what());
5008    }
5009    catch (...)
5010    {
5011        if ( 0 == extHandle )
5012        {
5013            return;
5014        }
5015
5016        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5017        if ( 0 == handle->initialized )
5018        {
5019            return;
5020        }
5021
5022        handle->ERROR_MESSAGE("Unknown exception thrown");
5023    }
5024}
5025
5026char
5027GEOSPreparedContains_r(GEOSContextHandle_t extHandle,
5028        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5029{
5030    assert(0 != pg);
5031    assert(0 != g);
5032
5033    if ( 0 == extHandle )
5034    {
5035        return 2;
5036    }
5037
5038    GEOSContextHandleInternal_t *handle = 0;
5039    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5040    if ( 0 == handle->initialized )
5041    {
5042        return 2;
5043    }
5044
5045    try
5046    {
5047        bool result = pg->contains(g);
5048        return result;
5049    }
5050    catch (const std::exception &e)
5051    {
5052        handle->ERROR_MESSAGE("%s", e.what());
5053    }
5054    catch (...)
5055    {
5056        handle->ERROR_MESSAGE("Unknown exception thrown");
5057    }
5058   
5059    return 2;
5060}
5061
5062char
5063GEOSPreparedContainsProperly_r(GEOSContextHandle_t extHandle,
5064        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5065{
5066    assert(0 != pg);
5067    assert(0 != g);
5068
5069    if ( 0 == extHandle )
5070    {
5071        return 2;
5072    }
5073
5074    GEOSContextHandleInternal_t *handle = 0;
5075    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5076    if ( 0 == handle->initialized )
5077    {
5078        return 2;
5079    }
5080
5081    try
5082    {
5083        bool result = pg->containsProperly(g);
5084        return result;
5085    }
5086    catch (const std::exception &e)
5087    {
5088        handle->ERROR_MESSAGE("%s", e.what());
5089    }
5090    catch (...)
5091    {
5092        handle->ERROR_MESSAGE("Unknown exception thrown");
5093    }
5094   
5095    return 2;
5096}
5097
5098char
5099GEOSPreparedCoveredBy_r(GEOSContextHandle_t extHandle,
5100        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5101{
5102    assert(0 != pg);
5103    assert(0 != g);
5104
5105    if ( 0 == extHandle )
5106    {
5107        return 2;
5108    }
5109
5110    GEOSContextHandleInternal_t *handle = 0;
5111    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5112    if ( 0 == handle->initialized )
5113    {
5114        return 2;
5115    }
5116
5117    try
5118    {
5119        bool result = pg->coveredBy(g);
5120        return result;
5121    }
5122    catch (const std::exception &e)
5123    {
5124        handle->ERROR_MESSAGE("%s", e.what());
5125    }
5126    catch (...)
5127    {
5128        handle->ERROR_MESSAGE("Unknown exception thrown");
5129    }
5130   
5131    return 2;
5132}
5133
5134char
5135GEOSPreparedCovers_r(GEOSContextHandle_t extHandle,
5136        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5137{
5138    assert(0 != pg);
5139    assert(0 != g);
5140
5141    if ( 0 == extHandle )
5142    {
5143        return 2;
5144    }
5145
5146    GEOSContextHandleInternal_t *handle = 0;
5147    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5148    if ( 0 == handle->initialized )
5149    {
5150        return 2;
5151    }
5152
5153    try
5154    {
5155        bool result = pg->covers(g);
5156        return result;
5157    }
5158    catch (const std::exception &e)
5159    {
5160        handle->ERROR_MESSAGE("%s", e.what());
5161    }
5162    catch (...)
5163    {
5164        handle->ERROR_MESSAGE("Unknown exception thrown");
5165    }
5166   
5167    return 2;
5168}
5169
5170char
5171GEOSPreparedCrosses_r(GEOSContextHandle_t extHandle,
5172        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5173{
5174    assert(0 != pg);
5175    assert(0 != g);
5176
5177    if ( 0 == extHandle )
5178    {
5179        return 2;
5180    }
5181
5182    GEOSContextHandleInternal_t *handle = 0;
5183    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5184    if ( 0 == handle->initialized )
5185    {
5186        return 2;
5187    }
5188
5189    try
5190    {
5191        bool result = pg->crosses(g);
5192        return result;
5193    }
5194    catch (const std::exception &e)
5195    {
5196        handle->ERROR_MESSAGE("%s", e.what());
5197    }
5198    catch (...)
5199    {
5200        handle->ERROR_MESSAGE("Unknown exception thrown");
5201    }
5202   
5203    return 2;
5204}
5205
5206char
5207GEOSPreparedDisjoint_r(GEOSContextHandle_t extHandle,
5208        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5209{
5210    assert(0 != pg);
5211    assert(0 != g);
5212
5213    if ( 0 == extHandle )
5214    {
5215        return 2;
5216    }
5217
5218    GEOSContextHandleInternal_t *handle = 0;
5219    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5220    if ( 0 == handle->initialized )
5221    {
5222        return 2;
5223    }
5224
5225    try
5226    {
5227        bool result = pg->disjoint(g);
5228        return result;
5229    }
5230    catch (const std::exception &e)
5231    {
5232        handle->ERROR_MESSAGE("%s", e.what());
5233    }
5234    catch (...)
5235    {
5236        handle->ERROR_MESSAGE("Unknown exception thrown");
5237    }
5238   
5239    return 2;
5240}
5241
5242char
5243GEOSPreparedIntersects_r(GEOSContextHandle_t extHandle,
5244        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5245{
5246    assert(0 != pg);
5247    assert(0 != g);
5248
5249    if ( 0 == extHandle )
5250    {
5251        return 2;
5252    }
5253
5254    GEOSContextHandleInternal_t *handle = 0;
5255    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5256    if ( 0 == handle->initialized )
5257    {
5258        return 2;
5259    }
5260
5261    try
5262    {
5263        bool result = pg->intersects(g);
5264        return result;
5265    }
5266    catch (const std::exception &e)
5267    {
5268        handle->ERROR_MESSAGE("%s", e.what());
5269    }
5270    catch (...)
5271    {
5272        handle->ERROR_MESSAGE("Unknown exception thrown");
5273    }
5274   
5275    return 2;
5276}
5277
5278char
5279GEOSPreparedOverlaps_r(GEOSContextHandle_t extHandle,
5280        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5281{
5282    assert(0 != pg);
5283    assert(0 != g);
5284
5285    if ( 0 == extHandle )
5286    {
5287        return 2;
5288    }
5289
5290    GEOSContextHandleInternal_t *handle = 0;
5291    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5292    if ( 0 == handle->initialized )
5293    {
5294        return 2;
5295    }
5296
5297    try
5298    {
5299        bool result = pg->overlaps(g);
5300        return result;
5301    }
5302    catch (const std::exception &e)
5303    {
5304        handle->ERROR_MESSAGE("%s", e.what());
5305    }
5306    catch (...)
5307    {
5308        handle->ERROR_MESSAGE("Unknown exception thrown");
5309    }
5310   
5311    return 2;
5312}
5313
5314char
5315GEOSPreparedTouches_r(GEOSContextHandle_t extHandle,
5316        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5317{
5318    assert(0 != pg);
5319    assert(0 != g);
5320
5321    if ( 0 == extHandle )
5322    {
5323        return 2;
5324    }
5325
5326    GEOSContextHandleInternal_t *handle = 0;
5327    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5328    if ( 0 == handle->initialized )
5329    {
5330        return 2;
5331    }
5332
5333    try
5334    {
5335        bool result = pg->touches(g);
5336        return result;
5337    }
5338    catch (const std::exception &e)
5339    {
5340        handle->ERROR_MESSAGE("%s", e.what());
5341    }
5342    catch (...)
5343    {
5344        handle->ERROR_MESSAGE("Unknown exception thrown");
5345    }
5346   
5347    return 2;
5348}
5349
5350char
5351GEOSPreparedWithin_r(GEOSContextHandle_t extHandle,
5352        const geos::geom::prep::PreparedGeometry *pg, const Geometry *g)
5353{
5354    assert(0 != pg);
5355    assert(0 != g);
5356
5357    if ( 0 == extHandle )
5358    {
5359        return 2;
5360    }
5361
5362    GEOSContextHandleInternal_t *handle = 0;
5363    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5364    if ( 0 == handle->initialized )
5365    {
5366        return 2;
5367    }
5368
5369    try
5370    {
5371        bool result = pg->within(g);
5372        return result;
5373    }
5374    catch (const std::exception &e)
5375    {
5376        handle->ERROR_MESSAGE("%s", e.what());
5377    }
5378    catch (...)
5379    {
5380        handle->ERROR_MESSAGE("Unknown exception thrown");
5381    }
5382   
5383    return 2;
5384}
5385
5386//-----------------------------------------------------------------
5387// STRtree
5388//-----------------------------------------------------------------
5389
5390geos::index::strtree::STRtree *
5391GEOSSTRtree_create_r(GEOSContextHandle_t extHandle,
5392                                  size_t nodeCapacity)
5393{
5394    if ( 0 == extHandle )
5395    {
5396        return 0;
5397    }
5398
5399    GEOSContextHandleInternal_t *handle = 0;
5400    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5401    if ( 0 == handle->initialized )
5402    {
5403        return 0;
5404    }
5405
5406    geos::index::strtree::STRtree *tree = 0;
5407
5408    try
5409    {
5410        tree = new geos::index::strtree::STRtree(nodeCapacity);
5411    }
5412    catch (const std::exception &e)
5413    {
5414        handle->ERROR_MESSAGE("%s", e.what());
5415    }
5416    catch (...)
5417    {
5418        handle->ERROR_MESSAGE("Unknown exception thrown");
5419    }
5420   
5421    return tree;
5422}
5423
5424void
5425GEOSSTRtree_insert_r(GEOSContextHandle_t extHandle,
5426                     geos::index::strtree::STRtree *tree,
5427                     const geos::geom::Geometry *g,
5428                     void *item)
5429{
5430    GEOSContextHandleInternal_t *handle = 0;
5431    assert(tree != 0);
5432    assert(g != 0);
5433
5434    try
5435    {
5436        tree->insert(g->getEnvelopeInternal(), item);
5437    }
5438    catch (const std::exception &e)
5439    {
5440        if ( 0 == extHandle )
5441        {
5442            return;
5443        }
5444
5445        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5446        if ( 0 == handle->initialized )
5447        {
5448            return;
5449        }
5450
5451        handle->ERROR_MESSAGE("%s", e.what());
5452    }
5453    catch (...)
5454    {
5455        if ( 0 == extHandle )
5456        {
5457            return;
5458        }
5459
5460        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5461        if ( 0 == handle->initialized )
5462        {
5463            return;
5464        }
5465
5466        handle->ERROR_MESSAGE("Unknown exception thrown");
5467    }
5468}
5469
5470void
5471GEOSSTRtree_query_r(GEOSContextHandle_t extHandle,
5472                    geos::index::strtree::STRtree *tree,
5473                    const geos::geom::Geometry *g,
5474                    GEOSQueryCallback callback,
5475                    void *userdata)
5476{
5477    GEOSContextHandleInternal_t *handle = 0;
5478    assert(tree != 0);
5479    assert(g != 0);
5480    assert(callback != 0);
5481
5482    try
5483    {
5484        CAPI_ItemVisitor visitor(callback, userdata);
5485        tree->query(g->getEnvelopeInternal(), visitor);
5486    }
5487    catch (const std::exception &e)
5488    {
5489        if ( 0 == extHandle )
5490        {
5491            return;
5492        }
5493
5494        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5495        if ( 0 == handle->initialized )
5496        {
5497            return;
5498        }
5499
5500        handle->ERROR_MESSAGE("%s", e.what());
5501    }
5502    catch (...)
5503    {
5504        if ( 0 == extHandle )
5505        {
5506            return;
5507        }
5508
5509        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5510        if ( 0 == handle->initialized )
5511        {
5512            return;
5513        }
5514
5515        handle->ERROR_MESSAGE("Unknown exception thrown");
5516    }
5517}
5518
5519void
5520GEOSSTRtree_iterate_r(GEOSContextHandle_t extHandle,
5521                    geos::index::strtree::STRtree *tree,
5522                    GEOSQueryCallback callback,
5523                    void *userdata)
5524{
5525    GEOSContextHandleInternal_t *handle = 0;
5526    assert(tree != 0);
5527    assert(callback != 0);
5528
5529    try
5530    {
5531        CAPI_ItemVisitor visitor(callback, userdata);
5532        tree->iterate(visitor);
5533    }
5534    catch (const std::exception &e)
5535    {
5536        if ( 0 == extHandle )
5537        {
5538            return;
5539        }
5540
5541        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5542        if ( 0 == handle->initialized )
5543        {
5544            return;
5545        }
5546
5547        handle->ERROR_MESSAGE("%s", e.what());
5548    }
5549    catch (...)
5550    {
5551        if ( 0 == extHandle )
5552        {
5553            return;
5554        }
5555
5556        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5557        if ( 0 == handle->initialized )
5558        {
5559            return;
5560        }
5561
5562        handle->ERROR_MESSAGE("Unknown exception thrown");
5563    }
5564}
5565
5566char
5567GEOSSTRtree_remove_r(GEOSContextHandle_t extHandle,
5568                     geos::index::strtree::STRtree *tree,
5569                     const geos::geom::Geometry *g,
5570                     void *item)
5571{
5572    assert(0 != tree);
5573    assert(0 != g);
5574
5575    if ( 0 == extHandle )
5576    {
5577        return 2;
5578    }
5579
5580    GEOSContextHandleInternal_t *handle = 0;
5581    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5582    if ( 0 == handle->initialized )
5583    {
5584        return 2;
5585    }
5586
5587    try
5588    {
5589        bool result = tree->remove(g->getEnvelopeInternal(), item);
5590        return result;
5591    }
5592    catch (const std::exception &e)
5593    {
5594        handle->ERROR_MESSAGE("%s", e.what());
5595    }
5596    catch (...)
5597    {
5598        handle->ERROR_MESSAGE("Unknown exception thrown");
5599    }
5600   
5601    return 2;
5602}
5603
5604void
5605GEOSSTRtree_destroy_r(GEOSContextHandle_t extHandle,
5606                      geos::index::strtree::STRtree *tree)
5607{
5608    GEOSContextHandleInternal_t *handle = 0;
5609
5610    try
5611    {
5612        delete tree;
5613    }
5614    catch (const std::exception &e)
5615    {
5616        if ( 0 == extHandle )
5617        {
5618            return;
5619        }
5620
5621        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5622        if ( 0 == handle->initialized )
5623        {
5624            return;
5625        }
5626
5627        handle->ERROR_MESSAGE("%s", e.what());
5628    }
5629    catch (...)
5630    {
5631        if ( 0 == extHandle )
5632        {
5633            return;
5634        }
5635
5636        handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5637        if ( 0 == handle->initialized )
5638        {
5639            return;
5640        }
5641
5642        handle->ERROR_MESSAGE("Unknown exception thrown");
5643    }
5644}
5645
5646double
5647GEOSProject_r(GEOSContextHandle_t extHandle,
5648              const Geometry *g,
5649              const Geometry *p)
5650{
5651    if ( 0 == extHandle ) return -1.0;
5652    GEOSContextHandleInternal_t *handle =
5653        reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5654    if ( handle->initialized == 0 ) return -1.0;
5655
5656    const geos::geom::Point* point = dynamic_cast<const geos::geom::Point*>(p);
5657    if (!point) {
5658        handle->ERROR_MESSAGE("third argument of GEOSProject_r must be Point*");
5659        return -1.0;
5660    }
5661
5662    const geos::geom::Coordinate* inputPt = p->getCoordinate();
5663
5664    try {
5665        return geos::linearref::LengthIndexedLine(g).project(*inputPt);
5666    } catch (const std::exception &e) {
5667        handle->ERROR_MESSAGE("%s", e.what());
5668        return -1.0;
5669    } catch (...) {
5670        handle->ERROR_MESSAGE("Unknown exception thrown");
5671        return -1.0;
5672    }
5673}
5674
5675
5676Geometry*
5677GEOSInterpolate_r(GEOSContextHandle_t extHandle, const Geometry *g, double d)
5678{
5679    if ( 0 == extHandle ) return 0;
5680    GEOSContextHandleInternal_t *handle =
5681        reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5682    if ( handle->initialized == 0 ) return 0;
5683
5684    try {
5685        geos::linearref::LengthIndexedLine lil(g);
5686        geos::geom::Coordinate coord = lil.extractPoint(d);
5687        const GeometryFactory *gf = handle->geomFactory;
5688        Geometry* point = gf->createPoint(coord);
5689        return point;
5690    } catch (const std::exception &e) {
5691        handle->ERROR_MESSAGE("%s", e.what());
5692        return 0;
5693    } catch (...) {
5694        handle->ERROR_MESSAGE("Unknown exception thrown");
5695        return 0;
5696    }
5697}
5698
5699
5700double
5701GEOSProjectNormalized_r(GEOSContextHandle_t extHandle, const Geometry *g,
5702                        const Geometry *p)
5703{
5704
5705    double length;
5706    GEOSLength_r(extHandle, g, &length);
5707    return GEOSProject_r(extHandle, g, p) / length;
5708}
5709
5710
5711Geometry*
5712GEOSInterpolateNormalized_r(GEOSContextHandle_t extHandle, const Geometry *g,
5713                            double d)
5714{
5715    double length;
5716    GEOSLength_r(extHandle, g, &length);
5717    return GEOSInterpolate_r(extHandle, g, d * length);
5718}
5719
5720GEOSGeometry*
5721GEOSGeom_extractUniquePoints_r(GEOSContextHandle_t extHandle,
5722                              const GEOSGeometry* g)
5723{
5724    if ( 0 == extHandle ) return 0;
5725    GEOSContextHandleInternal_t *handle = 0;
5726    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5727    if ( handle->initialized == 0 ) return 0;
5728
5729    using namespace geos::geom;
5730    using namespace geos::util;
5731
5732    try
5733    {
5734
5735    /* 1: extract points */
5736    std::vector<const Coordinate*> coords;
5737    UniqueCoordinateArrayFilter filter(coords);
5738    g->apply_ro(&filter);
5739
5740    /* 2: for each point, create a geometry and put into a vector */
5741    std::vector<Geometry*>* points = new std::vector<Geometry*>();
5742    points->reserve(coords.size());
5743    const GeometryFactory* factory = g->getFactory();
5744    for (std::vector<const Coordinate*>::iterator it=coords.begin(),
5745                                             itE=coords.end();
5746                                             it != itE; ++it)
5747    {
5748        Geometry* point = factory->createPoint(*(*it));
5749        points->push_back(point);
5750    }
5751
5752    /* 3: create a multipoint */
5753    return factory->createMultiPoint(points);
5754
5755    }
5756    catch (const std::exception &e)
5757    {
5758        handle->ERROR_MESSAGE("%s", e.what());
5759        return 0;
5760    }
5761    catch (...)
5762    {
5763        handle->ERROR_MESSAGE("Unknown exception thrown");
5764        return 0;
5765    }
5766}
5767
5768int GEOSOrientationIndex_r(GEOSContextHandle_t extHandle,
5769        double Ax, double Ay, double Bx, double By, double Px, double Py)
5770{
5771    GEOSContextHandleInternal_t *handle = 0;
5772
5773    using geos::geom::Coordinate;
5774    using geos::algorithm::CGAlgorithms;
5775
5776    if ( 0 == extHandle )
5777    {
5778        return 2;
5779    }
5780
5781    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5782    if ( 0 == handle->initialized )
5783    {
5784        return 2;
5785    }
5786
5787    try
5788    {
5789        Coordinate A(Ax, Ay);
5790        Coordinate B(Bx, By);
5791        Coordinate P(Px, Py);
5792        return CGAlgorithms::orientationIndex(A, B, P);
5793    }
5794    catch (const std::exception &e)
5795    {
5796        handle->ERROR_MESSAGE("%s", e.what());
5797        return 2;
5798    }
5799    catch (...)
5800    {
5801        handle->ERROR_MESSAGE("Unknown exception thrown");
5802        return 2;
5803    }
5804}
5805
5806GEOSGeometry *
5807GEOSSharedPaths_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g1, const GEOSGeometry* g2)
5808{
5809    using namespace geos::operation::sharedpaths;
5810
5811    if ( 0 == extHandle ) return 0;
5812    GEOSContextHandleInternal_t *handle =
5813      reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5814    if ( handle->initialized == 0 ) return 0;
5815
5816    SharedPathsOp::PathList forw, back;
5817    try {
5818      SharedPathsOp::sharedPathsOp(*g1, *g2, forw, back);
5819    }
5820    catch (const std::exception &e)
5821    {
5822        SharedPathsOp::clearEdges(forw);
5823        SharedPathsOp::clearEdges(back);
5824        handle->ERROR_MESSAGE("%s", e.what());
5825        return 0;
5826    }
5827    catch (...)
5828    {
5829        SharedPathsOp::clearEdges(forw);
5830        SharedPathsOp::clearEdges(back);
5831        handle->ERROR_MESSAGE("Unknown exception thrown");
5832        return 0;
5833    }
5834
5835    // Now forw and back have the geoms we want to use to construct
5836    // our output GeometryCollections...
5837
5838    const GeometryFactory* factory = g1->getFactory();
5839    size_t count;
5840
5841    std::auto_ptr< std::vector<Geometry*> > out1(
5842      new std::vector<Geometry*>()
5843    );
5844    count = forw.size();
5845    out1->reserve(count);
5846    for (size_t i=0; i<count; ++i) {
5847        out1->push_back(forw[i]);
5848    }
5849    std::auto_ptr<Geometry> out1g (
5850      factory->createMultiLineString(out1.release())
5851    );
5852
5853    std::auto_ptr< std::vector<Geometry*> > out2(
5854      new std::vector<Geometry*>()
5855    );
5856    count = back.size();
5857    out2->reserve(count);
5858    for (size_t i=0; i<count; ++i) {
5859        out2->push_back(back[i]);
5860    }
5861    std::auto_ptr<Geometry> out2g (
5862      factory->createMultiLineString(out2.release())
5863    );
5864
5865    std::auto_ptr< std::vector<Geometry*> > out(
5866      new std::vector<Geometry*>()
5867    );
5868    out->reserve(2);
5869    out->push_back(out1g.release());
5870    out->push_back(out2g.release());
5871
5872    std::auto_ptr<Geometry> outg (
5873      factory->createGeometryCollection(out.release())
5874    );
5875
5876    return outg.release();
5877
5878}
5879
5880GEOSGeometry *
5881GEOSSnap_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g1,
5882           const GEOSGeometry* g2, double tolerance)
5883{
5884    using namespace geos::operation::overlay::snap;
5885
5886    if ( 0 == extHandle ) return 0;
5887    GEOSContextHandleInternal_t *handle =
5888      reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5889    if ( handle->initialized == 0 ) return 0;
5890
5891    try{
5892      GeometrySnapper snapper( *g1 );
5893      std::auto_ptr<Geometry> ret = snapper.snapTo(*g2, tolerance);
5894      return ret.release();
5895    }
5896    catch (const std::exception &e)
5897    {
5898        handle->ERROR_MESSAGE("%s", e.what());
5899        return 0;
5900    }
5901    catch (...)
5902    {
5903        handle->ERROR_MESSAGE("Unknown exception thrown");
5904        return 0;
5905    }
5906}
5907
5908BufferParameters *
5909GEOSBufferParams_create_r(GEOSContextHandle_t extHandle)
5910{
5911    if ( 0 == extHandle ) return NULL;
5912
5913    GEOSContextHandleInternal_t *handle = 0;
5914    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5915    if ( 0 == handle->initialized ) return NULL;
5916
5917    try
5918    {
5919        BufferParameters *p = new BufferParameters();
5920        return p;
5921    }
5922    catch (const std::exception &e)
5923    {
5924        handle->ERROR_MESSAGE("%s", e.what());
5925    }
5926    catch (...)
5927    {
5928        handle->ERROR_MESSAGE("Unknown exception thrown");
5929    }
5930
5931    return 0;
5932}
5933
5934void
5935GEOSBufferParams_destroy_r(GEOSContextHandle_t extHandle, BufferParameters* p)
5936{
5937  delete p;     
5938}
5939
5940int
5941GEOSBufferParams_setEndCapStyle_r(GEOSContextHandle_t extHandle,
5942  GEOSBufferParams* p, int style)
5943{
5944    if ( 0 == extHandle ) return 0;
5945
5946    GEOSContextHandleInternal_t *handle = 0;
5947    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5948    if ( 0 == handle->initialized ) return 0;
5949
5950    try
5951    {
5952        if ( style > BufferParameters::CAP_SQUARE )
5953        {
5954                throw IllegalArgumentException("Invalid buffer endCap style");
5955        }
5956        p->setEndCapStyle(static_cast<BufferParameters::EndCapStyle>(style));
5957        return 1;
5958    }
5959    catch (const std::exception &e)
5960    {
5961        handle->ERROR_MESSAGE("%s", e.what());
5962    }
5963    catch (...)
5964    {
5965        handle->ERROR_MESSAGE("Unknown exception thrown");
5966    }
5967
5968    return 0;
5969}
5970
5971int
5972GEOSBufferParams_setJoinStyle_r(GEOSContextHandle_t extHandle,
5973  GEOSBufferParams* p, int style)
5974{
5975    if ( 0 == extHandle ) return 0;
5976
5977    GEOSContextHandleInternal_t *handle = 0;
5978    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
5979    if ( 0 == handle->initialized ) return 0;
5980
5981    try
5982    {
5983        if ( style > BufferParameters::JOIN_BEVEL ) {
5984                throw IllegalArgumentException("Invalid buffer join style");
5985        }
5986        p->setJoinStyle(static_cast<BufferParameters::JoinStyle>(style));
5987        return 1;
5988    }
5989    catch (const std::exception &e)
5990    {
5991        handle->ERROR_MESSAGE("%s", e.what());
5992    }
5993    catch (...)
5994    {
5995        handle->ERROR_MESSAGE("Unknown exception thrown");
5996    }
5997
5998    return 0;
5999}
6000
6001int
6002GEOSBufferParams_setMitreLimit_r(GEOSContextHandle_t extHandle,
6003  GEOSBufferParams* p, double limit)
6004{
6005    if ( 0 == extHandle ) return 0;
6006
6007    GEOSContextHandleInternal_t *handle = 0;
6008    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
6009    if ( 0 == handle->initialized ) return 0;
6010
6011    try
6012    {
6013        p->setMitreLimit(limit);
6014        return 1;
6015    }
6016    catch (const std::exception &e)
6017    {
6018        handle->ERROR_MESSAGE("%s", e.what());
6019    }
6020    catch (...)
6021    {
6022        handle->ERROR_MESSAGE("Unknown exception thrown");
6023    }
6024
6025    return 0;
6026}
6027
6028int
6029GEOSBufferParams_setQuadrantSegments_r(GEOSContextHandle_t extHandle,
6030  GEOSBufferParams* p, int segs)
6031{
6032    if ( 0 == extHandle ) return 0;
6033
6034    GEOSContextHandleInternal_t *handle = 0;
6035    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
6036    if ( 0 == handle->initialized ) return 0;
6037
6038    try
6039    {
6040        p->setQuadrantSegments(segs);
6041        return 1;
6042    }
6043    catch (const std::exception &e)
6044    {
6045        handle->ERROR_MESSAGE("%s", e.what());
6046    }
6047    catch (...)
6048    {
6049        handle->ERROR_MESSAGE("Unknown exception thrown");
6050    }
6051
6052    return 0;
6053}
6054
6055int
6056GEOSBufferParams_setSingleSided_r(GEOSContextHandle_t extHandle,
6057  GEOSBufferParams* p, int ss)
6058{
6059    if ( 0 == extHandle ) return 0;
6060
6061    GEOSContextHandleInternal_t *handle = 0;
6062    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
6063    if ( 0 == handle->initialized ) return 0;
6064
6065    try
6066    {
6067        p->setSingleSided( (ss != 0) );
6068        return 1;
6069    }
6070    catch (const std::exception &e)
6071    {
6072        handle->ERROR_MESSAGE("%s", e.what());
6073    }
6074    catch (...)
6075    {
6076        handle->ERROR_MESSAGE("Unknown exception thrown");
6077    }
6078
6079    return 0;
6080}
6081
6082Geometry *
6083GEOSBufferWithParams_r(GEOSContextHandle_t extHandle, const Geometry *g1, const BufferParameters* bp, double width)
6084{
6085    using geos::operation::buffer::BufferOp;
6086
6087    if ( 0 == extHandle ) return NULL;
6088
6089    GEOSContextHandleInternal_t *handle = 0;
6090    handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle);
6091    if ( 0 == handle->initialized ) return NULL;
6092
6093    try
6094    {
6095        BufferOp op(g1, *bp);
6096        Geometry *g3 = op.getResultGeometry(width);
6097        return g3;
6098    }
6099    catch (const std::exception &e)
6100    {
6101        handle->ERROR_MESSAGE("%s", e.what());
6102    }
6103    catch (...)
6104    {
6105        handle->ERROR_MESSAGE("Unknown exception thrown");
6106    }
6107   
6108    return NULL;
6109}
6110
6111} /* extern "C" */
6112
Note: See TracBrowser for help on using the browser.