[Gdal-dev] Re: Bugs in the bindings

Ari Jolma ari.jolma at tkk.fi
Tue Jun 27 09:20:21 EDT 2006


Charlie Savage wrote:
>> My problem is that the croak (even swig_croak) is probably a 
>> Perl-only solution, but I'll look into it more and post it as a bug 
>> -- that's an example of a general bindings bug or "undesirable feature".
>
> Ari - could you use SWIG_exception (see 
> http://www.swig.org/Doc1.3/SWIGDocumentation.html#Library_stl_exceptions). 
>  That's generic across SWIG bindings.  There is also a slightly 
> different version (whose name I can't remember, something like 
> SWIG_Error) in the unified type library.  It handles raising the 
> exception a little differently, so if SWIG_exception doesn't work then 
> maybe the other one will.

I fixed it with "CPLError(CE_Failure, err, "%s", OGRErrMessages(err));" 
which leads to an exception in %exceptions block in cpl_exceptions.i

_But_ I noticed that at least in Perl one needs "SWIG_exception_fail" 
instead of "SWIG_exception" in cpl_exceptions.i; I fixed this now with a 
#ifdef SWIGPERL for Perl but I don't know if this is a Swig bug or what. 
Could you confirm that Ruby works with SWIG_exception?

I removed the last two throws from the *.i files in include and updated 
the Perl wrappers.

>
>> BTW, my plans for the classes in Geo::GDAL namespace have escalated a 
>> bit (after reading Sean's and Charlie's posts on geos-devel). For 
>> example I intend to introduce Geo::GDAL::Point etc. classes and leave 
>> the Geometry class, whihc swig bindings provide, as a virtual class 
>> (not to instantiated by users).
>
> I've attached what I've done so far on Geos for you to take a look at. 
> Basically, create the "fake" classes just like Gdal already does.  
> Then take a look at the return typemap in the enclosed file - seems to 
> work fine.

I'm building the new class system completely without Swig, but on the 
top of the Swig-made modules...

>
> While on the subject - 2 other things:
>
> 1.  Can we remove all the language specifiers in the typemaps, which 
> are now deprecated by SWIG (you get lots of warning when running SWIG 
> on the gdal bindings now).

I don't get any warnings. Maybe I already did remove them for Perl. (I 
build only Perl interface)

>
> 2.  Feedback on the -fpic command line option I mentioned in  my last 
> email.  Its needed on SELinux enabled systems.

Hmm, you wrote "-fpic or -fPIC", Perl adds -fPIC, I added -fpic to 
CCFLAGS and that did not cause a failure in my test.pl so I left it there.

Ari

>
> Thanks,
>
> Charlie
> ------------------------------------------------------------------------
>
> %module geos
>
> %include "attribute.i"
> %include "exception.i"
> %include "std_string.i"
> %include "std_vector.i"
> %include "std_except.i"
> %include "factory.i"
>
> %{
> typedef struct GeosCoordinateSequence_t *GeosCoordinateSequence;
> typedef struct GeosGeometry_t *GeosGeometry;
> typedef struct GeosPoint_t *GeosPoint;
> typedef struct GeosLineString_t *GeosLineString;
> typedef struct GeosLinearRing_t *GeosLinearRing;
> typedef struct GeosPolygon_t *GeosPolygon;
> typedef struct GeosGeometryCollection_t *GeosGeometryCollection;
> typedef struct GeosMultiPoint_t *GeosMultiPoint;
> typedef struct GeosMultiLineString_t *GeosMultiLineString;
> typedef struct GeosMultiLinearRing_t *GeosMultiLinearRing;
> typedef struct GeosMultiPolygon_t *GeosMultiPolygon;
> %}
>
> // Constants from geos_c.h  sinc
> #define GEOS_VERSION_MAJOR 3
> #define GEOS_VERSION_MINOR 0
> #define GEOS_VERSION_PATCH 0rc1
> #define GEOS_VERSION "3.0.0rc1"
> #define GEOS_JTS_PORT "1.7.1"
>
> #define GEOS_CAPI_VERSION_MAJOR 1
> #define GEOS_CAPI_VERSION_MINOR 1
> #define GEOS_CAPI_VERSION_PATCH 1
> #define GEOS_CAPI_FIRST_INTERFACE GEOS_CAPI_VERSION_MAJOR 
> #define GEOS_CAPI_LAST_INTERFACE (GEOS_CAPI_VERSION_MAJOR+GEOS_CAPI_VERSION_MINOR)
> #define GEOS_CAPI_VERSION "3.0.0rc1-CAPI-1.1.1"
>
>
> /* Supported geometry types */
>
>     enum GEOSGeomTypes {
> 	GEOS_POINT,
> 	GEOS_LINESTRING,
> 	GEOS_LINEARRING,
> 	GEOS_POLYGON,
> 	GEOS_MULTIPOINT,
> 	GEOS_MULTILINESTRING,
> 	GEOS_MULTIPOLYGON,
> 	GEOS_GEOMETRYCOLLECTION
> };
>    
>
> %{ 
> #include "geos_c.h"
> //#include <sstream>
> %}
>
> /* ==============  Language Specific Files ============ */
>
> /* Import language specific SWIG files.  This allows each language
>    to define its own renames as well as any special functionality
>    such as language specific iterators for collections. Note 
>    that %include allows the included files to generate interface
>    wrapper code while %import does not.  Thus use %include since
>    this is an important feature (for example, Ruby needs it to #undef
>    the select macro) */
>
>
> #ifdef SWIGPYTHON
> //	%include ../python/python.i
> #endif
>
> #ifdef SWIGRUBY
> //	%include ../ruby/ruby.i
> #endif
>
>
>
> // ===  CoordinateSequence ===
>
> %rename (CoordinateSequence) GeosCoordinateSequence;
> class GeosCoordinateSequence
> {
> public:
> %extend
> {
>     GeosCoordinateSequence(size_t size, size_t dims)
>     {
>         return (GeosCoordinateSequence*) GEOSCoordSeq_create(size, dims);
>     }
>
>     GeosCoordinateSequence(const GeosCoordinateSequence& other)
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) other;
>         return (GeosCoordinateSequence*) GEOSCoordSeq_clone(coords);
>     }
>
>     ~GeosCoordinateSequence()
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         return GEOSCoordSeq_destroy(coords);
>     }
>
>     int setX(size_t idx, double val)
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         return GEOSCoordSeq_setX(coords, idx, val);
>     }
>
>     int setY(size_t idx, double val)
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         return GEOSCoordSeq_setY(coords, idx, val);
>     }
>
>     int setZ(size_t idx, double val)
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         return GEOSCoordSeq_setZ(coords, idx, val);
>     }
>
>     int setOrdinate(size_t idx, size_t dim, double val)
>     {
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         return GEOSCoordSeq_setOrdinate(coords, idx, dim, val);
>     }
>
>     double getX(size_t idx)
>     {
>         double result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getX(coords, idx, &result);
>         return result;
>     }
>
>     double getY(size_t idx)
>     {
>         double result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getY(coords, idx, &result);
>         return result;
>     }
>     
>     double getZ(size_t idx)
>     {
>         double result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getZ(coords, idx, &result);
>         return result;
>     }
>     
>     double getOrdinate(size_t idx, size_t dim)
>     {
>         double result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getOrdinate(coords, idx, dim, &result);
>         return result;
>     }
>
>     int getSize()
>     {
>         size_t result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getSize(coords, &result);
>         return result;
>     }
>
>     int getDimensions()
>     {
>         size_t result;
>         GEOSCoordSeq coords = (GEOSCoordSeq) self;
>         GEOSCoordSeq_getDimensions(coords, &result);
>         return result;
>     }
> }
> };
>
>
> // ===  Geometry ===
> %typemap(out) GeosGeometry 
> {
>     /* TestMe*/
>     GeosGeometry geom = result;
>     GEOSGeomTypes geomId = (GEOSGeomTypes)GEOSGeomTypeId((GEOSGeom) geom);
>
>     switch (geomId)
>     {
>     case GEOS_POINT:
>         $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), $descriptor(GeosPoint), 0 | $owner);
>         break;
> 	case GEOS_LINESTRING:
>         $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), $descriptor(GeosLineString), 0 | $owner);
>         break;
> 	case GEOS_LINEARRING:
>         $result = SWIG_NewPointerObj(SWIG_as_voidptr(result), $descriptor(GeosLinearRing), 0 | $owner);
>         break;
> /*	case GEOS_POLYGON:
>         break;
> 	case GEOS_MULTIPOINT:
>         break;
> 	case GEOS_MULTILINESTRING:
>         break;
> 	case GEOS_MULTIPOLYGON:
>         break;
> 	case GEOS_GEOMETRYCOLLECTION:
>         break;*/
>     }
> }
>
>
> /*    extern GEOSGeom GEOS_DLL GEOSPolygonize(const GEOSGeom geoms[],
> 	size_t ngeoms);
>
>
>     GeosGeometry *Polygonize(size_t ngeoms)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSPolygonize(g1, ngeoms);
>     }
> */
>
>
> %rename(Geometry) GeosGeometry;
> class GeosGeometry
> {
> private:
>     GeosGeometry();
> public:
> %extend
> {
>     ~GeosGeometry()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
>
>     char *geomType()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         return GEOSGeomType(geom);
>     }
>
>     int typeId()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         return GEOSGeomTypeId(geom);
>     }
>     
>     int getSRID()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         return GEOSGetSRID(geom);
>     }
>
>     void setSRID(int SRID)
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         return GEOSSetSRID(geom, SRID);
>     }
>
>     size_t getDimensions()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         return GEOSGeom_getDimensions(geom);
>     }
>
>     GeosGeometry *GEOSEnvelope()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSEnvelope(g1);
>     }
>
>     GeosGeometry *ConvexHull()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSConvexHull(g1);
>     }
>
>     GeosGeometry *Boundary()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSBoundary(g1);
>     }
>
>     GeosGeometry *PointOnSurface()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSPointOnSurface(g1);
>     }
>
>     GeosGeometry *LineMerge()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSLineMerge(g1);
>     }
>
>     GeosGeometry *GetCentroid()
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSGetCentroid(g1);
>     }
>
>     GeosGeometry *Intersection(GeosGeometry *other)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         const GEOSGeom g2 = (GEOSGeom) other;
>         return (GeosGeometry*) GEOSIntersection(g1, g2);
>     }
>
>     GeosGeometry *Difference(GeosGeometry *other)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         const GEOSGeom g2 = (GEOSGeom) other;
>         return (GeosGeometry*) GEOSDifference(g1, g2);
>     }
>
>     GeosGeometry *SymDifference(GeosGeometry *other)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         const GEOSGeom g2 = (GEOSGeom) other;
>         return (GeosGeometry*) GEOSSymDifference(g1, g2);
>     }
>
>     GeosGeometry *Union(GeosGeometry *other)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         const GEOSGeom g2 = (GEOSGeom) other;
>         return (GeosGeometry*) GEOSUnion(g1, g2);
>     }
>     
>     GeosGeometry *Relate(GeosGeometry *other)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         const GEOSGeom g2 = (GEOSGeom) other;
>         return (GeosGeometry*) GEOSRelate(g1, g2);
>     }
>
>     GeosGeometry *Buffer(double width, int quadsegs)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSBuffer(g1, width, quadsegs);
>     }
>
>     GeosGeometry *Simplify(double tolerance)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSSimplify(g1, tolerance);
>     }
>
>     GeosGeometry *TopologyPreserveSimplify(double tolerance)
>     {
>         const GEOSGeom g1 = (GEOSGeom) self;
>         return (GeosGeometry*) GEOSTopologyPreserveSimplify(g1, tolerance);
>     }
> }
> };
>
> %rename(Point) GeosPoint;
> class GeosPoint: public GeosGeometry
> {
> private:
>     GeosPoint();
>     GeosPoint(const GeosPoint&);
> public:
> %extend
> {
>     ~GeosPoint()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(LineString) GeosLineString;
> class GeosLineString: public GeosGeometry
> {
> private:
>     GeosLineString();
> public:
> %extend
> {
>     ~GeosLineString()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(LinearRing) GeosLinearRing;
> class GeosLinearRing: public GeosGeometry
> {
> private:
>     GeosLinearRing();
> public:
> %extend
> {
>     ~GeosLinearRing()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(Polygon) GeosPolygon;
> class GeosPolygon: public GeosGeometry
> {
> private:
>     GeosPolygon();
> public:
> %extend
> {
>     ~GeosPolygon()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(GeometryCollection) GeosGeometryCollection;
> class GeosGeometryCollection: public GeosGeometry
> {
> private:
>     GeosGeometryCollection();
> public:
> %extend
> {
>     ~GeosGeometryCollection()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(MultiPoint) GeosMultiPoint;
> class GeosMultiPoint: public GeosGeometryCollection
> {
> private:
>     GeosMultiPoint();
> public:
> %extend
> {
>     ~GeosMultiPoint()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(MultiLineString) GeosMultiLineString;
> class GeosMultiLineString: public GeosGeometryCollection
> {
> private:
>     GeosMultiLineString();
> public:
> %extend
> {
>     ~GeosMultiLineString()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(MultiLinearRing) GeosMultiLinearRing;
> class GeosMultiLinearRing: public GeosGeometryCollection
> {
> private:
>     GeosMultiLinearRing();
> public:
> %extend
> {
>     ~GeosMultiLinearRing()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> %rename(MultiPolygon) GeosMultiPolygon;
> class GeosMultiPolygon: public GeosGeometryCollection
> {
> private:
>     GeosMultiPolygon();
> public:
> %extend
> {
>     ~GeosMultiPolygon()
>     {
>         GEOSGeom geom = (GEOSGeom) self;
>         GEOSGeom_destroy(geom);
>     }
> }
> };
>
> // ==== Geometry Constructors ===========
>
> %newobject createPoint;
> %newobject createLineString;
> %newobject createLinearRing;
> %newobject createPolygon;
>
> %apply SWIGTYPE *DISOWN {GeosCoordinateSequence *s};
>
> %inline %{
> GeosPoint *createPoint(GeosCoordinateSequence *s)
> {
>     GEOSCoordSeq coords = (GEOSCoordSeq) s;
>     return (GeosPoint*) GEOSGeom_createPoint(coords);
> }
>
> GeosLinearRing *createLinearRing(GeosCoordinateSequence *s)
> {
>     GEOSCoordSeq coords = (GEOSCoordSeq) s;
>     return (GeosLinearRing*) GEOSGeom_createLinearRing(coords);
> }
>
> GeosLineString *createLineString(GeosCoordinateSequence *s)
> {
>     GEOSCoordSeq coords = (GEOSCoordSeq) s;
>     return (GeosLineString*) GEOSGeom_createLineString(coords);
> }
>
> GeosPolygon *createPolygon(GEOSGeom shell, GEOSGeom *holes, size_t nholes)
> {
>     return (GeosPolygon*) GEOSGeom_createPolygon(shell, holes, nholes);
> }
>
> %}
>
> %clear GeosCoordinateSequence *s;
>
> /*
> %newobject createCollection;
> GEOSGeom createCollection(int type, GEOSGeom *geoms, size_t ngeoms)
> {
>     return GEOSGeom_createCollection(type, geoms, ngeoms);
> }
> */
>
>
>
> // === Input/Output ===
> %newobject geomFromWKT;
> %newobject geomFromWKB;
>
> %inline %{
> GeosGeometry geomFromWKT(const char *wkt)
> {
>     return (GeosGeometry) GEOSGeomFromWKT(wkt);
> }
>
> char *geomToWKT(const GeosGeometry* g)
> {
>     const GEOSGeom geom = (const GEOSGeom) g;
>     return GEOSGeomToWKT(geom);
> }
>
> int setWKBOutputDims(int newDims)
> {
>     return GEOS_setWKBOutputDims(newDims);
> }
>
> GeosGeometry geomFromWKB(const unsigned char *wkb, size_t size)
> {
>     return (GeosGeometry) GEOSGeomFromWKB_buf(wkb, size);
> }
>
> unsigned char *geomToWKB(const GEOSGeom* g, size_t *size)
> {
>     const GEOSGeom geom = (const GEOSGeom) g;
>     return GEOSGeomToWKB_buf(geom, size);
> }
> %}
>   


-- 
Prof. Ari Jolma
Kartografia ja Geoinformatiikka / Cartography and Geoinformatics
Teknillinen Korkeakoulu / Helsinki University of Technology
tel: +358 9 451 3886 address: POBox 1200, 02015 TKK, Finland
Email: ari.jolma at tkk.fi URL: http://www.tkk.fi/~jolma




More information about the Gdal-dev mailing list