[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