[Gdal-dev] Re: Bugs in the bindings

Charlie Savage cfis at interserv.com
Mon Jun 26 16:44:54 EDT 2006


> 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.

> 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.

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).

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

Thanks,

Charlie
-------------- next part --------------
%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);
}
%}


More information about the Gdal-dev mailing list