/[thuban]/branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/thuban/libraries/pyshapelib/shapelib.i revision 1611 by jan, Tue Aug 19 21:24:20 2003 UTC branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c revision 2735 by bramz, Mon Mar 12 23:24:35 2007 UTC
# Line 1  Line 1 
1  /* SWIG (www.swig.org) interface file for shapelib  #include "shapefil.h"
2   *  #include "pyshapelib_common.h"
3   * At the moment (Dec 2000) this file is only useful to generate Python  #include "pyshapelib_api.h"
  * bindings. Invoke swig as follows:  
  *  
  *      swig -python -shadow shapelib.i  
  *  
  * to generate shapelib_wrap.c and shapelib.py. shapelib_wrap.c  
  * defines a bunch of Python-functions that wrap the appripriate  
  * shapelib functions and shapelib.py contains an object oriented  
  * wrapper around shapelib_wrap.c.  
  *  
  * Shapelib, and hence this module too, defines two types of objects,  
  * shapes and shapefiles.  
  */  
4    
5  %module shapelib  /* --- SHPObject ----------------------------------------------------------------------------------------------------- */
6    
7  /*  typedef struct
8   * First, a %{,%}-Block. These blocks are copied verbatim to the  {
9   * shapelib_wrap.c file and are not parsed by SWIG. This is the place to          PyObject_HEAD
10   * import headerfiles and define helper-functions that are needed by the          SHPObject* shpObject;
11   * automatically generated wrappers.  }
12   */  PySHPObject;
13    
14  %{  static PyObject* PySHPObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
15    {
16            PySHPObject* self;      
17            self = (PySHPObject*) type->tp_alloc(type, 0);
18            self->shpObject = NULL;
19            return (PyObject*) self;
20    }
21    
22  /* import the shapelib headefile. */  static void PySHPObject_dealloc(PySHPObject* self)
23  #include "shapefil.h"  {
24  #include "pyshapelib_api.h"          SHPDestroyObject(self->shpObject);
25                self->shpObject = NULL;
26  /*          self->ob_type->tp_free((PyObject*)self);
27   * Rename a few shapelib functions that are effectively methods with  }
28   * preprocessor macros so that they have the names that swig expects  
29   * (e.g. the destructor of SHPObject has to be called delete_SHPObject)  /* The constructor of SHPObject. parts is a list of lists of tuples
30   */  * describing the parts and their vertices just likethe output of the
31    * vertices() method. part_type_list is the list of part-types and may
32    * be NULL. For the meaning of the part-types and their default value
33    * see the Shaplib documentation.
34    */
35    static int PySHPObject_init(PySHPObject* self, PyObject* args, PyObject* kwds)
36    {
37            int type;
38            int id;
39            PyObject* parts = NULL;
40            PyObject* part_type_list = NULL;
41            
42            int num_parts;
43            int num_vertices;
44            int part_start;
45            
46            double* xs = NULL;
47            double* ys = NULL;
48            int* part_starts = NULL;
49            int* part_types = NULL;
50            
51            int i;
52            int return_code = -1;
53            
54            /* first, unpack parameters */
55            if (kwds != NULL && PyDict_Size(kwds) > 0)
56            {
57                    PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
58                    return -1;
59            }
60            if (!PyArg_ParseTuple(args, "iiO|O", &type, &id, &parts, &part_type_list)) return -1;
61    
62            if (!PySequence_Check(parts))
63            {
64                    PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
65                    return -1;
66            }
67            num_parts = PySequence_Length(parts);
68            if (num_parts < 0)
69            {
70                    PyErr_SetString(PyExc_TypeError, "cannot determine length of parts");
71                    return -1;
72            }
73            
74            /* parts and part_types have to have the same lengths */
75            if (part_type_list)
76            {
77                    if (!PySequence_Check(parts))
78                    {
79                            PyErr_SetString(PyExc_TypeError, "part_type_list is not a sequence");
80                            return -1;
81                    }
82                    if (PySequence_Length(part_type_list) != num_parts)
83                    {
84                            PyErr_SetString(PyExc_TypeError, "parts and part_types have to have the same lengths");
85                            return -1;
86                    }
87            }
88    
89            /* determine how many vertices there are altogether */
90            num_vertices = 0;
91            for (i = 0; i < num_parts; ++i)
92            {
93                    PyObject* part = PySequence_ITEM(parts, i);
94                    if (!PySequence_Check(part))
95                    {
96                            PyErr_SetString(PyExc_TypeError, "at least one item in parts is not a sequence");
97                            Py_DECREF(part);
98                            return -1;
99                    }
100                    num_vertices += PySequence_Length(part);
101                    Py_DECREF(part);
102            }
103    
104            /* allocate the memory for the various arrays and check for memory errors */
105            xs = malloc(num_vertices * sizeof(double));
106            ys = malloc(num_vertices * sizeof(double));
107            part_starts = malloc(num_parts * sizeof(int));
108            part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
109    
110            if (!xs || !ys || !part_starts || (part_type_list && !part_types))
111            {
112                    PyErr_NoMemory();
113                    goto exit;
114            }
115    
116            /* convert the part types */
117            if (part_type_list)
118            {
119                    for (i = 0; i < num_parts; i++)
120                    {
121                            PyObject* otype = PySequence_ITEM(part_type_list, i);
122                            part_types[i] = PyInt_AsLong(otype);
123                            Py_DECREF(otype);
124                            if (part_types[i] < 0)
125                            {
126                                    PyErr_SetString(PyExc_TypeError, "at least one item in part_type_list is not an integer or is negative");
127                                    goto exit;
128                            }
129                    }
130            }
131    
132            /* convert the list of parts */
133            part_start = 0;
134            for (i = 0; i < num_parts; ++i)
135            {
136                    int j, length;
137                    
138                    PyObject* part = PySequence_ITEM(parts, i);
139                    length = PySequence_Length(part);
140                    part_starts[i] = part_start;
141    
142                    for (j = 0; j < length; ++j)
143                    {
144                            PyObject* vertex = PySequence_ITEM(part, j);
145                            if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))
146                            {
147                                    PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");
148                                    Py_DECREF(vertex);
149                                    Py_DECREF(part);
150                                    goto exit;
151                            }
152                            Py_DECREF(vertex);
153                    }
154                    Py_DECREF(part);
155                    part_start += length;
156            }
157    
158            self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, NULL, NULL);
159            return_code = 0;
160            
161    exit:
162            free(xs);
163            free(ys);
164            free(part_starts);
165            free(part_types);
166            return return_code;
167    }
168    
 #define delete_SHPObject SHPDestroyObject  
       
169  /*  /*
170   * The extents() method of SHPObject.  * The extents() method of SHPObject.
171   *  *
172   * Return the extents as a tuple of two 4-element lists with the min.  * Return the extents as a tuple of two 4-element lists with the min.
173   * and max. values of x, y, z, m.  * and max. values of x, y, z, m.
174   */  */
175  static PyObject *  static PyObject* PySHPObject_extents(PySHPObject* self)
176  SHPObject_extents(SHPObject *object)  {
177  {          SHPObject* object = self->shpObject;
178      return Py_BuildValue("[dddd][dddd]",          return Py_BuildValue("(dddd)(dddd)",
179                           object->dfXMin, object->dfYMin, object->dfZMin,                          object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin,
180                           object->dfMMin,                          object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
                          object->dfXMax, object->dfYMax, object->dfZMax,  
                          object->dfMMax);  
181  }  }
182    
183    
184  /*  /*
185   * The vertices() method of SHPObject.  * The vertices() method of SHPObject.
186   *  *
187   * Return the x and y coords of the vertices as a list of lists of  * Return the x and y coords of the vertices as a list of lists of
188   * tuples.  * tuples.
189   */  */
190    
191  static PyObject* build_vertex_list(SHPObject *object, int index, int length);  static PyObject* build_vertex_list(SHPObject *object, int index, int length);
192    
193  static PyObject*  static PyObject* PySHPObject_vertices(PySHPObject* self)
 SHPObject_vertices(SHPObject *object)  
194  {  {
195      PyObject *result = NULL;          PyObject *result = NULL;
196      PyObject *part = NULL;          PyObject *part = NULL;
197      int part_idx, vertex_idx;          int part_idx, vertex_idx;
198      int length = 0;          int length = 0;
199            SHPObject* object = self->shpObject;
200    
201            if (object->nParts > 0)
202      if (object->nParts > 0)          {
203      {                  /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
         /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */  
204                    
205          result = PyList_New(object->nParts);                  result = PyList_New(object->nParts);
206          if (!result)          if (!result)
207              return NULL;                  return NULL;
208    
209          for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts;          for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts;
210               part_idx++)                  part_idx++)
211          {          {
212              if (part_idx < object->nParts - 1)                  if (part_idx < object->nParts - 1)
213                  length = (object->panPartStart[part_idx + 1]                  length = (object->panPartStart[part_idx + 1]
214                            - object->panPartStart[part_idx]);                          - object->panPartStart[part_idx]);
215              else                  else
216                  length = object->nVertices - object->panPartStart[part_idx];                  length = object->nVertices - object->panPartStart[part_idx];
217                                
218              part = build_vertex_list(object, vertex_idx, length);                  part = build_vertex_list(object, vertex_idx, length);
219              if (!part)                  if (!part)
220                  goto fail;                  goto fail;
221    
222              if (PyList_SetItem(result, part_idx, part) < 0)                  if (PyList_SetItem(result, part_idx, part) < 0)
223                  goto fail;                  goto fail;
224    
225              vertex_idx += length;                  vertex_idx += length;
226          }          }
227      }          }
228      else          else
229      {          {
230          /* only one part. usual for SHPT_POINT */          /* only one part. usual for SHPT_POINT */
231          result = build_vertex_list(object, 0, object->nVertices);          result = build_vertex_list(object, 0, object->nVertices);
232      }          }
233    
234      return result;          return result;
235    
236   fail:  fail:
237      Py_XDECREF(part);          Py_XDECREF(part);
238      Py_DECREF(result);          Py_DECREF(result);
239      return NULL;          return NULL;
240  }  }
241    
242    
243  /* Return the length coordinates of the shape object starting at vertex  /* Return the length coordinates of the shape object starting at vertex
244   * index as a Python-list of tuples. Helper function for  * index as a Python-list of tuples. Helper function for
245   * SHPObject_vertices.  * SHPObject_vertices.
246   */  */
247  static PyObject*  static PyObject* build_vertex_list(SHPObject *object, int index, int length)
248  build_vertex_list(SHPObject *object, int index, int length)  {
249  {          int i;
250      int i;          PyObject * list;
251      PyObject * list;          PyObject * vertex = NULL;
     PyObject * vertex = NULL;  
252    
253      list = PyList_New(length);          list = PyList_New(length);
254      if (!list)          if (!list)
255          return NULL;          return NULL;
256    
257      for (i = 0; i < length; i++, index++)          for (i = 0; i < length; i++, index++)
258      {          {
259          vertex = Py_BuildValue("dd", object->padfX[index],          vertex = Py_BuildValue("dd", object->padfX[index],
260                                 object->padfY[index]);                                  object->padfY[index]);
261          if (!vertex)          if (!vertex)
262              goto fail;                  goto fail;
263          if (PyList_SetItem(list, i, vertex) < 0)          if (PyList_SetItem(list, i, vertex) < 0)
264              goto fail;                  goto fail;
265      }          }
266    
267      return list;          return list;
268    
269   fail:  fail:
270      Py_XDECREF(vertex);          Py_XDECREF(vertex);
271      Py_DECREF(list);          Py_DECREF(list);
272      return NULL;          return NULL;
273  }  }
274    
275    static PyObject* PySHPObject_type(PySHPObject* self, void* closure)
276    {
277            return PyInt_FromLong(self->shpObject->nSHPType);
278    }
279    
280    static PyObject* PySHPObject_id(PySHPObject* self, void* closure)
281    {
282            return PyInt_FromLong(self->shpObject->nShapeId);
283    }
284    
285    static PyMethodDef PySHPObject_methods[] =
286    {
287            {"extents", (PyCFunction)PySHPObject_extents, METH_NOARGS, NULL},
288            {"vertices", (PyCFunction)PySHPObject_vertices, METH_NOARGS, NULL},
289            {NULL}
290    };
291    
292    static PyGetSetDef PySHPObject_getsetters[] =
293    {
294            {"type", (getter)PySHPObject_type, NULL, NULL },
295            {"id", (getter)PySHPObject_id, NULL, NULL },
296            {NULL}
297    };
298    
299  /* The constructor of SHPObject. parts is a list of lists of tuples  static PyTypeObject PySHPObjectType = PYSHAPELIB_DEFINE_TYPE(PySHPObject, "shapelib.SHPObject", 0);
  * describing the parts and their vertices just likethe output of the  
  * vertices() method. part_type_list is the list of part-types and may  
  * be NULL. For the meaning of the part-types and their default value  
  * see the Shaplib documentation.  
  */  
 SHPObject * new_SHPObject(int type, int id, PyObject * parts,  
                           PyObject * part_type_list)  
 {  
     /* arrays to hold thex and y coordinates of the  vertices */  
     double *xs = NULL, *ys = NULL;  
     /* number of all vertices of all parts */  
     int num_vertices;  
     /* number of parts in the list parts */  
     int num_parts;  
     /* start index of in xs and ys of the part currently worked on */  
     int part_start;  
     /* array of start indices in xs and ys as expected by shapelib */  
     int *part_starts = NULL;  
   
     /* generic counter */  
     int i;  
   
     /* array of part types. holds the converted content of  
      * part_type_list. Stays NULL of part_type_list is NULL  
      */  
     int *part_types = NULL;  
   
     /* temporary python objects referring to the the list items being  
      * worked on.  
      */  
     PyObject * part = NULL, *tuple = NULL;  
   
     /* The result object */  
     SHPObject *result;  
   
     num_parts = PySequence_Length(parts);  
     num_vertices = 0;  
   
     /* parts and part_types have to have the same lengths */  
     if (part_type_list  
         && PySequence_Length(part) != PySequence_Length(part_type_list))  
     {  
         PyErr_SetString(PyExc_TypeError,  
                         "parts and part_types have to have the same lengths");  
         return NULL;  
     }  
   
     /* determine how many vertices there are altogether */  
     for (i = 0; i < num_parts; i++)  
     {  
         PyObject * part = PySequence_GetItem(parts, i);  
         if (!part)  
             return NULL;  
         num_vertices += PySequence_Length(part);  
         Py_DECREF(part);  
     }  
   
     /* allocate the memory for the various arrays and check for memory  
        errors */  
     xs = malloc(num_vertices * sizeof(double));  
     ys = malloc(num_vertices * sizeof(double));  
     part_starts = malloc(num_parts * sizeof(int));  
     if (part_type_list)  
         part_types = malloc(num_parts * sizeof(int));  
   
     if (!xs || !ys || !part_starts || (part_type_list && !part_types))  
     {  
         PyErr_NoMemory();  
         goto fail;  
     }  
   
     /* convert the part types */  
     if (part_type_list)  
     {  
         for (i = 0; i < num_parts; i++)  
         {  
             PyObject * otype = PySequence_GetItem(part_type_list, i);  
             if (!otype)  
                 return NULL;  
             part_types[i] = PyInt_AsLong(otype);  
             Py_DECREF(otype);  
         }  
     }  
   
     /* convert the list of parts */  
     part_start = 0;  
     for (i = 0; i < num_parts; i++)  
     {  
         int j, length;  
300    
         part = PySequence_GetItem(parts, i);  
         length = PySequence_Length(part);  
         part_starts[i] = part_start;  
301    
302          for (j = 0; j < length; j++)  /* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
         {  
             tuple = PySequence_GetItem(part, j);  
             if (!tuple)  
                 goto fail;  
303    
304              if (!PyArg_ParseTuple(tuple, "dd", xs + part_start + j,  typedef struct
305                                    ys + part_start + j))  {
306              {          PyObject_HEAD
307                  goto fail;          SHPHandle handle;
             }  
             Py_DECREF(tuple);  
             tuple = NULL;  
         }  
         Py_DECREF(part);  
         part = NULL;  
         part_start += length;  
     }  
   
     result = SHPCreateObject(type, id, num_parts, part_starts, part_types,  
                              num_vertices, xs, ys, NULL, NULL);  
     free(xs);  
     free(ys);  
     free(part_starts);  
     free(part_types);  
     return result;  
   
  fail:  
     free(xs);  
     free(ys);  
     free(part_starts);  
     free(part_types);  
     Py_XDECREF(part);  
     Py_XDECREF(tuple);  
     return NULL;  
308  }  }
309    PyShapeFile;
310    
311  %}  static PyObject* PyShapeFile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
312    {
313            PyShapeFile* self;      
314            self = (PyShapeFile*) type->tp_alloc(type, 0);
315            self->handle = NULL;
316            return (PyObject*) self;
317    }
318    
319    static int PyShapeFile_init(PyShapeFile* self, PyObject* args, PyObject* kwds)
320    {
321            char* file;
322            char* mode = "rb";
323            if (kwds != NULL && PyDict_Size(kwds) > 0)
324            {
325                    PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
326                    return -1;
327            }
328            if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;
329            
330            self->handle = SHPOpen(file, mode);
331            return self->handle ? 0 : -1;
332    }
333    
334    static PyObject* PyShapeFile_close(PyShapeFile* self)
335    {
336            SHPClose(self->handle);
337            self->handle = NULL;
338            Py_RETURN_NONE;
339    }
340    
341  /*  static void PyShapeFile_dealloc(PyShapeFile* self)
342   * The SWIG Interface definition.  {
343   */          PyShapeFile_close(self);
344            self->ob_type->tp_free((PyObject*)self);
345    }
346    
347  /* include some common SWIG type definitions and standard exception  static PyObject* PyShapeFile_info(PyShapeFile* self)
348     handling code */  {
349  %include typemaps.i          SHPHandle handle = self->handle;
350  %include exception.i          return Py_BuildValue("ii(dddd)(dddd)",
351                            handle->nRecords, handle->nShapeType,
352                            handle->adBoundsMin[0], handle->adBoundsMin[1], handle->adBoundsMin[2], handle->adBoundsMin[3],
353                            handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
354    }
355    
356    static PyObject* PyShapeFile_read_object(PyShapeFile* self, PyObject* args)
357    {
358            int index;
359            SHPObject* object;
360            PySHPObject* result;
361            
362            if (!PyArg_ParseTuple(args, "i", &index)) return NULL;
363            
364            object = SHPReadObject(self->handle, index);    
365            if (!object)
366            {
367                    PyErr_SetString(PyExc_RuntimeError, "failed to read object");
368                    return NULL;
369            }
370            
371            result = PyObject_New(PySHPObject, &PySHPObjectType);
372            if (!result)
373            {
374                    return PyErr_NoMemory();
375            }
376            
377            result->shpObject = object;
378            return (PyObject*) result;
379    }
380    
381  /*  static PyObject* PyShapeFile_write_object(PyShapeFile* self, PyObject* args)
382   *  SHPObject -- Represents one shape  {
383   */          int index, result;
384            PyObject* object;
385            
386            if (!PyArg_ParseTuple(args, "iO", &index, &object)) return NULL;
387            
388            if (!PyObject_IsInstance(object, (PyObject*)&PySHPObjectType))
389            {
390                    PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
391                    return NULL;
392            }
393            
394            result = SHPWriteObject(self->handle, index, ((PySHPObject*)object)->shpObject);
395            if (result < 0)
396            {
397                    PyErr_SetString(PyExc_RuntimeError, "failed to write object");
398                    return NULL;
399            }
400            return PyInt_FromLong((long)result);
401    }
402    
403  /* Exception typemap for the SHPObject constructor. The constructor the  static PyObject* PyShapeFile_cobject(PyShapeFile* self)
404     the wrapper function defined above which returns NULL in case of  {
405     error. */          return PyCObject_FromVoidPtr(self->handle, NULL);
     
 %typemap(python,except) SHPObject*new_SHPObject {  
     $function;  
     if (PyErr_Occurred())  
         return NULL;  
406  }  }
407    
408  /* Define the SHPObject struct for SWIG. This has to have the same name  static PyMethodDef PyShapeFile_methods[] =
409   * as the underlying C-struct in shapfil.h, but we don't have to repeat  {
410   * all the fields here, only those we want to access directly, and we          {"close", (PyCFunction)PyShapeFile_close, METH_NOARGS, "close the shape file" },
411   * can define methods for the object oriented interface.          {"info", (PyCFunction)PyShapeFile_info, METH_NOARGS,
412   */                  "Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where NUM_SHAPES is the number of shapes in the file, TYPE is the "
413                    "shape type and MIN and MAX are 4-element tuples with the min. and max. values of the data." },
414  typedef struct {          {"read_object", (PyCFunction)PyShapeFile_read_object, METH_VARARGS, "Return object number i" },
415            {"write_object", (PyCFunction)PyShapeFile_write_object, METH_VARARGS, "Write an object"},
416      /* The shape object has two read-only attributes: */          {"cobject", (PyCFunction)PyShapeFile_cobject, METH_NOARGS, "Return the shapelib SHPHandle as a Python CObject"},
417            {NULL}
418      /* The type of the shape. In the c-struct defined the field is  };
      * called 'nSHPType' but for the python bindings 'type' is more  
      * appropriate.  
      */  
     %readonly %name(type) int nSHPType;  
   
     /* The id of the shape. Here 'id' is a better name than 'nShapeId'. */  
     %readonly %name(id) int nShapeId;  
   
     /* The methods */  
     %addmethods {  
   
         /* the constructor */  
         SHPObject(int type, int id, PyObject * parts,  
                   PyObject * part_types = NULL);  
   
         /* The destructor */  
         ~SHPObject();  
   
         /* extents and vertices correspond to the SHPObject_extents and  
          * SHPObject_vertices defined above  
          */  
         PyObject *extents();  
         PyObject *vertices();  
     }  
 } SHPObject;  
419    
420    static PyGetSetDef PyShapeFile_getsetters[] =
421    {
422            {NULL}
423    };
424    
425  /*  static PyTypeObject PyShapeFileType = PYSHAPELIB_DEFINE_TYPE(PyShapeFile, "shapelib.ShapeFile", 0);
  * ShapeFile --  Represents the shape file  
  */  
426    
427  /* Here we do things a little different. We define a new C-struct that  /* --- shapelib ------------------------------------------------------------------------------------------------------ */
  * holds the SHPHandle. This is mainly done so we can separate the  
  * close() method from the destructor but it also helps with exception  
  * handling.  
  *  
  * After the ShapeFile has been opened or created the handle is not  
  * NULL. The close() method closes the file and sets handle to NULL as  
  * an indicator that the file has been closed.  
  */  
   
 /* First, define the C-struct */  
 %{  
     typedef struct {  
         SHPHandle handle;  
     } ShapeFile;  
 %}  
428    
429  /* define and use some typemaps for the info() method whose  static PyObject* shapelib_open(PyObject* module, PyObject* args)
430   * C-implementation has four output parameters that are returned through  {
431   * pointers passed into the function. SWIG already has definitions for          return PyObject_CallObject((PyObject*)&PyShapeFileType, args);
  * common types such as int* and we can use those for the first two  
  * parameters:  
  */  
   
 %apply int * OUTPUT { int * output_entities }  
 %apply int * OUTPUT { int * output_type }  
   
 /* for the last two, the 4-element arrays of min- and max-values, we  
  * have to define our own typemaps:  
  */  
 %typemap (python,ignore) double * extents(double temp[4]) {  
     $target = temp;  
 }  
   
 %typemap (python,argout) double * extents {  
     PyObject * list = Py_BuildValue("[dddd]",  
                                     $source[0], $source[1],  
                                     $source[2], $source[3]);  
     $target = t_output_helper($target,list);  
 }  
   
 %apply double * extents { double * output_min_bounds }  
 %apply double * extents { double * output_max_bounds }  
   
 /* The first argument to the ShapeFile methods is a ShapeFile pointer.  
  * We have to check whether handle is not NULL in most methods but not  
  * all. In the destructor and the close method, it's OK for handle to be  
  * NULL. We achieve this by checking whether the preprocessor macro  
  * NOCHECK_$name is defined. SWIG replaces $name with the name of the  
  * function for which the code is inserted. In the %{,%}-block below we  
  * define the macros for the destructor and the close() method.  
  */  
   
   
 %typemap(python,check) ShapeFile *{  
     %#ifndef NOCHECK_$name  
     if (!$target || !$target->handle)  
         SWIG_exception(SWIG_TypeError, "shapefile already closed");  
     %#endif  
 }  
   
 %{  
 #define NOCHECK_delete_ShapeFile  
 #define NOCHECK_ShapeFile_close  
 %}  
   
 /* An exception handle for the constructor and the module level open()  
  * and create() functions.  
  *  
  * Annoyingly, we *have* to put braces around the SWIG_exception()  
  * calls, at least in the python case, because of the way the macro is  
  * written. Of course, always putting braces around the branches of an  
  * if-statement is often considered good practice.  
  */  
 %typemap(python,except) ShapeFile * {  
     $function;  
     if (!$source)  
     {  
         SWIG_exception(SWIG_MemoryError, "no memory");  
     }  
     else if (!$source->handle)  
     {  
         SWIG_exception(SWIG_IOError, "$name failed");  
     }  
432  }  }
433    
434    static PyObject* shapelib_create(PyObject* module, PyObject* args)
 /*  
  * The SWIG-version of the ShapeFile struct.  
  */  
   
 typedef struct  
435  {  {
436      /* Only methods and no attributes here: */          char* file;
437      %addmethods {          int type;
438            PyShapeFile* result;
439          /* The constructor. Takes two arguments, the filename and the          
440           * optinal mode which are passed through to SHPOpen (due to the          if (!PyArg_ParseTuple(args, "si", &file, &type)) return NULL;
441           * renaming trick)          
442           */          result = PyObject_New(PyShapeFile, &PyShapeFileType);
443          ShapeFile(char *file, char * mode = "rb") {          if (!result)
444              ShapeFile * self = malloc(sizeof(ShapeFile));          {
445              if (self)                  return PyErr_NoMemory();
                 self->handle = SHPOpen(file, mode);  
             return self;  
         }  
   
         /* The destructor. Equivalent to SHPClose */  
         ~ShapeFile() {  
             if (self->handle)  
                 SHPClose(self->handle);  
             free(self);  
         }  
   
         /* close the shape file and set handle to NULL */  
         void close() {  
             if (self->handle)  
             {  
                 SHPClose(self->handle);  
                 self->handle = NULL;  
             }  
         }  
   
         /* info() -- Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where  
          * NUM_SHAPES is the number of shapes in the file, TYPE is the  
          * shape type and MIN and MAX are 4-element lists with the min.  
          * and max. values of the data.  
          *  
          * The arguments of the underlying shapelib function SHPGetInfo  
          * are all output parameters. To tell SWIG this, we have defined  
          * some typemaps above  
          */  
         void info(int * output_entities, int * output_type,  
                   double * output_min_bounds, double *output_max_bounds) {  
             SHPGetInfo(self->handle, output_entities, output_type,  
                        output_min_bounds, output_max_bounds);  
         }  
   
         /* Return object number i */  
         %new SHPObject * read_object(int i) {  
             return SHPReadObject(self->handle, i);  
         }  
   
         /* Write an object */  
         int write_object(int iShape, SHPObject * psObject) {  
             return SHPWriteObject(self->handle, iShape, psObject);  
         }  
   
         /* Return the shapelib SHPHandle as a Python CObject */  
         PyObject * cobject() {  
             return PyCObject_FromVoidPtr(self->handle, NULL);  
446          }          }
447      }          
448            result->handle = SHPCreate(file, type);
449  } ShapeFile;          if (!result->handle)
450            {
451                    PyObject_Del((PyObject*)result);
452  /*                  PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
453   * Two module level functions, open() and create() that correspond to                  return NULL;
454   * SHPOpen and SHPCreate respectively. open() is equivalent to the          }
455   * ShapeFile constructor.          
456   */          return (PyObject*) result;
457    }
458  %{          
459      ShapeFile * open_ShapeFile(const char *filename, const char * mode) {  static PyShapeLibAPI shapelib_the_api =
460          ShapeFile * self = malloc(sizeof(ShapeFile));  {
         if (self)  
             self->handle = SHPOpen(filename, mode);  
         return self;  
     }  
 %}  
   
 %name(open) %new ShapeFile *open_ShapeFile(const char *filename,  
                                            const char * mode = "rb");  
   
   
 %{  
     ShapeFile * create_ShapeFile(const char *filename, int type) {  
         ShapeFile * self = malloc(sizeof(ShapeFile));  
         if (self)  
             self->handle = SHPCreate(filename, type);  
         return self;  
     }  
 %}      
   
 %name(create) %new ShapeFile * create_ShapeFile(const char *filename,  
                                                 int type);  
       
   
 /* Module level function to expose some of the shapelib functions linked  
  * with the shapefile C-module to other Python extension modules. This  
  * is a kludge to make a Thuban extension work that reads shapes from  
  * shapefiles opened by the shapefile module.  
  */  
   
 %{  
     static PyShapeLibAPI the_api = {  
461          SHPReadObject,          SHPReadObject,
462          SHPDestroyObject,          SHPDestroyObject,
463          SHPCreateTree,          SHPCreateTree,
464          SHPDestroyTree,          SHPDestroyTree,
465          SHPTreeFindLikelyShapes          SHPTreeFindLikelyShapes
466      };  };
   
     PyObject * c_api() {  
         return PyCObject_FromVoidPtr(&the_api, NULL);  
     }  
 %}  
   
 PyObject * c_api();  
467    
468    static PyObject* shapelib_c_api(PyObject* module)
469    {
470            return PyCObject_FromVoidPtr(&shapelib_the_api, NULL);
471    }
472    
473  /*  static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
474   *  Module Level functions  {
475   */          int type;
476            if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
477  /* convert shapefile types to names */          return PyString_FromString(SHPTypeName(type));
478  %name(type_name) const char *SHPTypeName(int nSHPType);  }
 %name(part_type_name) const char *SHPPartTypeName(int nPartType);  
   
479    
480  /*  static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
481   * Finally, constants copied from shapefil.h  {
482   */          int type;
483            if (!PyArg_ParseTuple(args, "i", &type)) return NULL;
484            return PyString_FromString(SHPPartTypeName(type));
485    }
486    
487  /* -------------------------------------------------------------------- */  static PyMethodDef shapelib_methods[] =
488  /*      Shape types (nSHPType)                                          */  {
489  /* -------------------------------------------------------------------- */          {"open", (PyCFunction)shapelib_open, METH_VARARGS, "open a ShapeFile" },
490  #define SHPT_NULL       0          {"create", (PyCFunction)shapelib_create, METH_VARARGS, "create a ShapeFile" },
491  #define SHPT_POINT      1          {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, "get C API of shapelib" },
492  #define SHPT_ARC        3          {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, "return type as string" },
493  #define SHPT_POLYGON    5          {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, "return part type as string" },
494  #define SHPT_MULTIPOINT 8          {NULL}
495  #define SHPT_POINTZ     11  };
 #define SHPT_ARCZ       13  
 #define SHPT_POLYGONZ   15  
 #define SHPT_MULTIPOINTZ 18  
 #define SHPT_POINTM     21  
 #define SHPT_ARCM       23  
 #define SHPT_POLYGONM   25  
 #define SHPT_MULTIPOINTM 28  
 #define SHPT_MULTIPATCH 31  
   
   
 /* -------------------------------------------------------------------- */  
 /*      Part types - everything but SHPT_MULTIPATCH just uses           */  
 /*      SHPP_RING.                                                      */  
 /* -------------------------------------------------------------------- */  
   
 #define SHPP_TRISTRIP   0  
 #define SHPP_TRIFAN     1  
 #define SHPP_OUTERRING  2  
 #define SHPP_INNERRING  3  
 #define SHPP_FIRSTRING  4  
 #define SHPP_RING       5  
496    
497    PyMODINIT_FUNC initshapelib(void)
498    {
499            PyObject* module = Py_InitModule("shapelib", shapelib_methods);
500            if (!module) return;
501            
502            PYSHAPELIB_ADD_TYPE(PySHPObjectType, "SHPObject");
503            PYSHAPELIB_ADD_TYPE(PyShapeFileType, "ShapeFile");
504            
505            PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
506            PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);
507            PYSHAPELIB_ADD_CONSTANT(SHPT_ARC);
508            PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGON);
509            PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINT);
510            PYSHAPELIB_ADD_CONSTANT(SHPT_POINTZ);
511            PYSHAPELIB_ADD_CONSTANT(SHPT_ARCZ);
512            PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONZ);
513            PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTZ);
514            PYSHAPELIB_ADD_CONSTANT(SHPT_POINTM);
515            PYSHAPELIB_ADD_CONSTANT(SHPT_ARCM);
516            PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONM);
517            PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTM);
518            PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPATCH);
519            PYSHAPELIB_ADD_CONSTANT(SHPP_TRISTRIP);
520            PYSHAPELIB_ADD_CONSTANT(SHPP_TRIFAN);
521            PYSHAPELIB_ADD_CONSTANT(SHPP_OUTERRING);
522            PYSHAPELIB_ADD_CONSTANT(SHPP_INNERRING);
523            PYSHAPELIB_ADD_CONSTANT(SHPP_FIRSTRING);
524            PYSHAPELIB_ADD_CONSTANT(SHPP_RING);
525    }
526    

Legend:
Removed from v.1611  
changed lines
  Added in v.2735

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26