/[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

branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.c revision 2735 by bramz, Mon Mar 12 23:24:35 2007 UTC branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c revision 2749 by bramz, Thu Mar 22 19:03:27 2007 UTC
# Line 1  Line 1 
 #include "shapefil.h"  
1  #include "pyshapelib_common.h"  #include "pyshapelib_common.h"
 #include "pyshapelib_api.h"  
2    
3  /* --- SHPObject ----------------------------------------------------------------------------------------------------- */  /* --- SHPObject ----------------------------------------------------------------------------------------------------- */
4    
# Line 9  typedef struct Line 7  typedef struct
7          PyObject_HEAD          PyObject_HEAD
8          SHPObject* shpObject;          SHPObject* shpObject;
9  }  }
10  PySHPObject;  SHPObjectObject;
11    
12  static PyObject* PySHPObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)  enum {
13            vtXY,
14            vtXYM,
15            vtXYZM,
16            vtInvalid
17    } VertexType;
18    
19    int determine_vertex_type(int shape_type, int* has_z, int* has_m)
20    {
21            switch (shape_type)
22            {
23            case SHPT_POINT:
24            case SHPT_ARC:
25            case SHPT_POLYGON:
26            case SHPT_MULTIPOINT:
27                    if (has_z) *has_z = 0;
28                    if (has_m) *has_m = 0;
29                    return vtXY;
30            case SHPT_POINTM:
31            case SHPT_ARCM:
32            case SHPT_POLYGONM:
33            case SHPT_MULTIPOINTM:
34                    if (has_z) *has_z = 0;
35                    if (has_m) *has_m = 1;
36            case SHPT_POINTZ:
37            case SHPT_ARCZ:
38            case SHPT_POLYGONZ:
39            case SHPT_MULTIPOINTZ:
40            case SHPT_MULTIPATCH:
41                    if (has_z) *has_z = 1;
42                    if (has_m) *has_m = 1;
43                    return vtXYZM;
44            default:
45                    if (has_z) *has_z = 0;
46                    if (has_m) *has_m = 0;
47                    return vtInvalid;
48            }
49    }
50            
51    /* allocator
52     */
53    static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
54  {  {
55          PySHPObject* self;                SHPObjectObject* self;  
56          self = (PySHPObject*) type->tp_alloc(type, 0);          self = (SHPObjectObject*) type->tp_alloc(type, 0);
57          self->shpObject = NULL;          self->shpObject = NULL;
58          return (PyObject*) self;          return (PyObject*) self;
59  }  }
60    
61  static void PySHPObject_dealloc(PySHPObject* self)  /* deallocator
62     */
63    static void shpobject_dealloc(SHPObjectObject* self)
64  {  {
65          SHPDestroyObject(self->shpObject);          SHPDestroyObject(self->shpObject);
66          self->shpObject = NULL;          self->shpObject = NULL;
67          self->ob_type->tp_free((PyObject*)self);          self->ob_type->tp_free((PyObject*)self);
68  }  }
69    
70    static int unpack_vertex(PyObject* vertex, int vertex_type,
71                    double* xs, double* ys, double* zs, double* ms, int offset);
72    
73  /* The constructor of SHPObject. parts is a list of lists of tuples  /* The constructor of SHPObject. parts is a list of lists of tuples
74  * describing the parts and their vertices just likethe output of the  * describing the parts and their vertices just likethe output of the
75  * vertices() method. part_type_list is the list of part-types and may  * vertices() method. part_type_list is the list of part-types and may
76  * be NULL. For the meaning of the part-types and their default value  * be NULL. For the meaning of the part-types and their default value
77  * see the Shaplib documentation.  * see the Shaplib documentation.
78  */  */
79  static int PySHPObject_init(PySHPObject* self, PyObject* args, PyObject* kwds)  static int shpobject_init(SHPObjectObject* self, PyObject* args, PyObject* kwds)
80  {  {
81          int type;          int type;
82          int id;          int id;
# Line 45  static int PySHPObject_init(PySHPObject* Line 89  static int PySHPObject_init(PySHPObject*
89                    
90          double* xs = NULL;          double* xs = NULL;
91          double* ys = NULL;          double* ys = NULL;
92            double* zs = NULL;
93            double* ms = NULL;
94          int* part_starts = NULL;          int* part_starts = NULL;
95          int* part_types = NULL;          int* part_types = NULL;
96                    
97            PyObject* part;
98            int vertex_type;
99            int has_z;
100            int has_m;
101            
102          int i;          int i;
103          int return_code = -1;          int return_code = -1;
104                    
# Line 57  static int PySHPObject_init(PySHPObject* Line 108  static int PySHPObject_init(PySHPObject*
108                  PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");                  PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
109                  return -1;                  return -1;
110          }          }
111          if (!PyArg_ParseTuple(args, "iiO|O", &type, &id, &parts, &part_type_list)) return -1;          if (!PyArg_ParseTuple(args, "iiO|O:__init__", &type, &id, &parts, &part_type_list)) return -1;
112    
113            /* check parts */
114          if (!PySequence_Check(parts))          if (!PySequence_Check(parts))
115          {          {
116                  PyErr_SetString(PyExc_TypeError, "parts is not a sequence");                  PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
# Line 72  static int PySHPObject_init(PySHPObject* Line 124  static int PySHPObject_init(PySHPObject*
124          }          }
125                    
126          /* parts and part_types have to have the same lengths */          /* parts and part_types have to have the same lengths */
127            if (part_type_list == Py_None)
128            {
129                    Py_DECREF(part_type_list);
130                    part_type_list = NULL;
131            }
132          if (part_type_list)          if (part_type_list)
133          {          {
134                  if (!PySequence_Check(parts))                  if (!PySequence_Check(parts))
# Line 100  static int PySHPObject_init(PySHPObject* Line 157  static int PySHPObject_init(PySHPObject*
157                  num_vertices += PySequence_Length(part);                  num_vertices += PySequence_Length(part);
158                  Py_DECREF(part);                  Py_DECREF(part);
159          }          }
160            
161            
162            vertex_type = determine_vertex_type(type, &has_z, &has_m);
163    
164          /* allocate the memory for the various arrays and check for memory errors */          /* allocate the memory for the various arrays and check for memory errors */
165          xs = malloc(num_vertices * sizeof(double));          xs = malloc(num_vertices * sizeof(double));
166          ys = malloc(num_vertices * sizeof(double));          ys = malloc(num_vertices * sizeof(double));
167            zs = has_z ? malloc(num_vertices * sizeof(double)) : NULL;
168            ms = has_m ? malloc(num_vertices * sizeof(double)) : NULL;
169          part_starts = malloc(num_parts * sizeof(int));          part_starts = malloc(num_parts * sizeof(int));
170          part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;          part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
171    
172          if (!xs || !ys || !part_starts || (part_type_list && !part_types))          if (!xs || !ys || (has_z && !zs) || (has_m && !ms) || !part_starts || (part_type_list && !part_types))
173          {          {
174                  PyErr_NoMemory();                  PyErr_NoMemory();
175                  goto exit;                  goto exit;
# Line 135  static int PySHPObject_init(PySHPObject* Line 197  static int PySHPObject_init(PySHPObject*
197          {          {
198                  int j, length;                  int j, length;
199                                    
200                  PyObject* part = PySequence_ITEM(parts, i);                  part = PySequence_ITEM(parts, i);
201                  length = PySequence_Length(part);                  length = PySequence_Length(part);
202                    if (length < 0) goto exit;
203                  part_starts[i] = part_start;                  part_starts[i] = part_start;
204    
205                  for (j = 0; j < length; ++j)                  for (j = 0; j < length; ++j)
206                  {                  {
207                          PyObject* vertex = PySequence_ITEM(part, j);                          PyObject* vertex = PySequence_ITEM(part, j);
208                          if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))                          if (!unpack_vertex(vertex, vertex_type, xs, ys, zs, ms, part_start + j))
209                          {                          {
                                 PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");  
210                                  Py_DECREF(vertex);                                  Py_DECREF(vertex);
211                                  Py_DECREF(part);                                  PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
212                                  goto exit;                                  goto exit;
213                          }                          }
214                          Py_DECREF(vertex);                          Py_DECREF(vertex);
215                  }                  }
216                  Py_DECREF(part);                  Py_DECREF(part);
217                    part = NULL;
218                  part_start += length;                  part_start += length;
219          }          }
220    
221          self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, NULL, NULL);          self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, zs, ms);
222          return_code = 0;          return_code = 0;
223                    
224  exit:  exit:
225            Py_XDECREF(part);
226          free(xs);          free(xs);
227          free(ys);          free(ys);
228            free(zs);
229            free(ms);
230          free(part_starts);          free(part_starts);
231          free(part_types);          free(part_types);
232          return return_code;          return return_code;
233  }  }
234    
235    /* helper for shpobject_init. Unpacks vertices
236     */
237    static int unpack_vertex(PyObject* vertex, int vertex_type,
238                    double* xs, double* ys, double* zs, double* ms, int offset)
239    {
240            int ok;
241            PyObject* m_object;
242            PyObject *err_type, *err_value, *err_traceback;
243    
244            switch (vertex_type)
245            {
246            case vtXY:
247                    return PyArg_ParseTuple(vertex, "dd:__init__", xs + offset, ys + offset);
248    
249            case vtXYM:
250                    ms[offset] = PYSHAPELIB_NO_DATA;
251                    ok = PyArg_ParseTuple(vertex, "dd|d:__init__", xs + offset, ys + offset, ms + offset);
252                    if (!ok)
253                    {
254                            /* maybe they specified None as M value */
255                            PyErr_Fetch(&err_type, &err_value, &err_traceback);
256                            ok = PyArg_ParseTuple(vertex, "ddO:__init__", xs + offset, ys + offset, &m_object);
257                            if (ok && m_object == Py_None)
258                            {
259                                    Py_XDECREF(err_type);
260                                    Py_XDECREF(err_value);
261                                    Py_XDECREF(err_traceback);
262                            }
263                            else
264                            {
265                                    PyErr_Restore(err_type, err_value, err_traceback);
266                            }
267                    }
268                    return ok;
269    
270            case vtXYZM:
271                    zs[offset] = 0.;
272                    ms[offset] = PYSHAPELIB_NO_DATA;
273                    ok = PyArg_ParseTuple(vertex, "dd|dd:__init__", xs + offset, ys + offset,
274                                    zs + offset, ms + offset);
275                    if (!ok)
276                    {
277                            /* maybe they specified None as M value */
278                            PyErr_Fetch(&err_type, &err_value, &err_traceback);
279                            ok = PyArg_ParseTuple(vertex, "dddO:__init__", xs + offset, ys + offset,
280                                            zs + offset, &m_object);
281                            if (ok && m_object == Py_None)
282                            {
283                                    Py_XDECREF(err_type);
284                                    Py_XDECREF(err_value);
285                                    Py_XDECREF(err_traceback);
286                            }
287                            else
288                            {
289                                    PyErr_Restore(err_type, err_value, err_traceback);
290                            }
291                    }
292                    return ok;
293    
294            default:
295                    PyErr_SetString(PyExc_NotImplementedError, "vertex type not implemented");
296                    return 0;
297            }
298    }
299    
300  /*  /*
301  * The extents() method of SHPObject.  * The extents() method of SHPObject.
302  *  *
303  * 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.
304  * and max. values of x, y, z, m.  * and max. values of x, y, z, m.
305  */  */
306  static PyObject* PySHPObject_extents(PySHPObject* self)  static PyObject* shpobject_extents(SHPObjectObject* self)
307  {  {
308          SHPObject* object = self->shpObject;          SHPObject* object = self->shpObject;
309          return Py_BuildValue("(dddd)(dddd)",          return Py_BuildValue("(dddd)(dddd)",
# Line 188  static PyObject* PySHPObject_extents(PyS Line 319  static PyObject* PySHPObject_extents(PyS
319  * tuples.  * tuples.
320  */  */
321    
322  static PyObject* build_vertex_list(SHPObject *object, int index, int length);  static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type);
323    
324  static PyObject* PySHPObject_vertices(PySHPObject* self)  static PyObject* shpobject_vertices(SHPObjectObject* self)
325  {  {
326          PyObject *result = NULL;          PyObject *result = NULL;
327          PyObject *part = NULL;          PyObject *part = NULL;
328          int part_idx, vertex_idx;          int part_idx, vertex_idx;
329          int length = 0;          int length = 0;
330            int vertex_type;
331            
332          SHPObject* object = self->shpObject;          SHPObject* object = self->shpObject;
333            vertex_type = determine_vertex_type(object->nSHPType, NULL, NULL);
334    
335          if (object->nParts > 0)          if (object->nParts > 0)
336          {          {
337                  /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */                  /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
338                    
339                  result = PyList_New(object->nParts);                  result = PyList_New(object->nParts);
340          if (!result)                  if (!result)
341                  return NULL;                          return NULL;
342    
343          for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts;                  for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
344                  part_idx++)                  {
345          {                          if (part_idx < object->nParts - 1)
346                  if (part_idx < object->nParts - 1)                                  length = (object->panPartStart[part_idx + 1]
347                  length = (object->panPartStart[part_idx + 1]                                          - object->panPartStart[part_idx]);
348                          - object->panPartStart[part_idx]);                          else
349                  else                                  length = object->nVertices - object->panPartStart[part_idx];
350                  length = object->nVertices - object->panPartStart[part_idx];                          
351                                            part = build_vertex_list(object, vertex_idx, length, vertex_type);
352                  part = build_vertex_list(object, vertex_idx, length);                          if (!part) goto fail;
                 if (!part)  
                 goto fail;  
353    
354                  if (PyList_SetItem(result, part_idx, part) < 0)                          if (PyList_SetItem(result, part_idx, part) < 0) goto fail;
                 goto fail;  
355    
356                  vertex_idx += length;                          vertex_idx += length;
357          }                  }
358          }          }
359          else          else
360          {          {
361          /* only one part. usual for SHPT_POINT */                  /* only one part. usual for SHPT_POINT */
362          result = build_vertex_list(object, 0, object->nVertices);                  result = build_vertex_list(object, 0, object->nVertices, vertex_type);
363          }          }
364    
365          return result;          return result;
# Line 244  fail: Line 375  fail:
375  * index as a Python-list of tuples. Helper function for  * index as a Python-list of tuples. Helper function for
376  * SHPObject_vertices.  * SHPObject_vertices.
377  */  */
378  static PyObject* build_vertex_list(SHPObject *object, int index, int length)  static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type)
379  {  {
380          int i;          int i;
381          PyObject * list;          PyObject * list;
# Line 252  static PyObject* build_vertex_list(SHPOb Line 383  static PyObject* build_vertex_list(SHPOb
383    
384          list = PyList_New(length);          list = PyList_New(length);
385          if (!list)          if (!list)
386          return NULL;                  return NULL;
387    
388          for (i = 0; i < length; i++, index++)          for (i = 0; i < length; i++, index++)
389          {          {
390          vertex = Py_BuildValue("dd", object->padfX[index],                  switch (vertex_type)
391                                  object->padfY[index]);                  {
392          if (!vertex)                  case vtXY:
393                  goto fail;                          vertex = Py_BuildValue("dd", object->padfX[index], object->padfY[index]);
394          if (PyList_SetItem(list, i, vertex) < 0)                          break;                  
395                  goto fail;                  case vtXYM:
396          }                          vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index],
397                                    object->padfM[index]);
398                            break;
399                    case vtXYZM:
400                            vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index],
401                                    object->padfZ[index], object->padfM[index]);
402                            break;                  
403                    default:
404                            goto fail;
405                    }
406    
407                    if (!vertex || PyList_SetItem(list, i, vertex) < 0) goto fail;
408            }
409            
410          return list;          return list;
411    
412  fail:  fail:
         Py_XDECREF(vertex);  
413          Py_DECREF(list);          Py_DECREF(list);
414          return NULL;          return NULL;
415  }  }
416    
417  static PyObject* PySHPObject_type(PySHPObject* self, void* closure)  
418    
419    static PyObject* shpobject_part_types(SHPObjectObject* self)
420    {
421            int i;
422            PyObject* result = NULL;
423            SHPObject* object = self->shpObject;
424            
425            if (object->nParts == 0 || object->panPartType == 0)
426            {
427                    Py_RETURN_NONE;
428            }
429            
430            result = PyTuple_New(object->nParts);
431            if (!result) return NULL;
432            
433            for (i = 0; i < object->nParts; ++i)
434            {
435                    /* PyTuple_SetItem steals a reference */
436                    PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]);
437                    if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail;
438            }      
439            return result;
440            
441    fail:
442            Py_DECREF(result);
443            return NULL;
444    }
445    
446    
447    
448    static PyObject* shpobject_type(SHPObjectObject* self, void* closure)
449  {  {
450          return PyInt_FromLong(self->shpObject->nSHPType);          return PyInt_FromLong(self->shpObject->nSHPType);
451  }  }
452    
453  static PyObject* PySHPObject_id(PySHPObject* self, void* closure)  
454    
455    static PyObject* shpobject_id(SHPObjectObject* self, void* closure)
456  {  {
457          return PyInt_FromLong(self->shpObject->nShapeId);          return PyInt_FromLong(self->shpObject->nShapeId);
458  }  }
459    
460  static PyMethodDef PySHPObject_methods[] =  
461    
462    /* return a string that can be feeded to eval() to reconstruct the object,
463     * assuming a proper context
464     */
465    static PyObject* shpobject_repr(SHPObjectObject* self)
466    {
467            PyObject* format = NULL;
468            PyObject* args = NULL;
469            PyObject* result = NULL;
470            
471            format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)");
472            if (!format) return NULL;
473    
474            args = Py_BuildValue("iiNN",
475                    self->shpObject->nSHPType,
476                    self->shpObject->nShapeId,
477                    shpobject_vertices(self),
478                    shpobject_part_types(self));
479            if (!args)
480            {
481                    Py_DECREF(format);
482                    return NULL;
483            }
484            
485            result = PyString_Format(format, args);
486            Py_DECREF(args);
487            Py_DECREF(format);
488            return result;
489    }
490    
491    
492    
493    static struct PyMethodDef shpobject_methods[] =
494  {  {
495          {"extents", (PyCFunction)PySHPObject_extents, METH_NOARGS, NULL},          {"extents", (PyCFunction)shpobject_extents, METH_NOARGS,
496          {"vertices", (PyCFunction)PySHPObject_vertices, METH_NOARGS, NULL},                  "extents() -> ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n"
497                    "returns the 4D bounding box of the SHPObject"},
498            {"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS,
499                    "vertices() ->  [[(x, y, ...), ...], ...]\n\n"
500                    "Returns a list of object parts, where each part is again a list of vertices. "
501                    "Each vertex is a tuple of two to four doubles, depending on the object type."},
502            {"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS,
503                    "part_types() -> tuple\n\n"
504                    "returns a tuple of integers, each integer indicating the type of the "
505                    "corresponding part in vertices()"},
506          {NULL}          {NULL}
507  };  };
508    
509  static PyGetSetDef PySHPObject_getsetters[] =  static struct PyGetSetDef shpobject_getsetters[] =
510  {  {
511          {"type", (getter)PySHPObject_type, NULL, NULL },          {"type", (getter)shpobject_type, NULL, "type of the object (read-only)" },
512          {"id", (getter)PySHPObject_id, NULL, NULL },          {"id", (getter)shpobject_id, NULL, "id of the object (read-only)" },
513          {NULL}          {NULL}
514  };  };
515    
516  static PyTypeObject PySHPObjectType = PYSHAPELIB_DEFINE_TYPE(PySHPObject, "shapelib.SHPObject", 0);  static PyTypeObject SHPObjectType = PYSHAPELIB_DEFINE_TYPE(SHPObjectObject, shpobject, "shapelib.SHPObject", 0);
517    
518    
519  /* --- ShapeFile ----------------------------------------------------------------------------------------------------- */  /* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
# Line 306  typedef struct Line 523  typedef struct
523          PyObject_HEAD          PyObject_HEAD
524          SHPHandle handle;          SHPHandle handle;
525  }  }
526  PyShapeFile;  ShapeFileObject;
527    
528  static PyObject* PyShapeFile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)  /* allocator
529     */
530    static PyObject* shapefile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
531  {  {
532          PyShapeFile* self;                ShapeFileObject* self;  
533          self = (PyShapeFile*) type->tp_alloc(type, 0);          self = (ShapeFileObject*) type->tp_alloc(type, 0);
534          self->handle = NULL;          self->handle = NULL;
535          return (PyObject*) self;          return (PyObject*) self;
536  }  }
537    
538  static int PyShapeFile_init(PyShapeFile* self, PyObject* args, PyObject* kwds)  /* destructor
539    */
540    static void shapefile_dealloc(ShapeFileObject* self)
541    {
542            SHPClose(self->handle);
543            self->ob_type->tp_free((PyObject*)self);
544    }
545    
546    /* constructor
547     */
548    static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds)
549  {  {
550          char* file;          char* file;
551          char* mode = "rb";          char* mode = "rb";
552          if (kwds != NULL && PyDict_Size(kwds) > 0)          static char *kwlist[] = {"name", "mode", NULL};
553          {          if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:__init__", kwlist,
554                  PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");                  Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
                 return -1;  
         }  
         if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;  
555                    
556          self->handle = SHPOpen(file, mode);          self->handle = SHPOpen(file, mode);
557            if (!self->handle)
558            {
559                    PyErr_SetFromErrnoWithFilename(PyExc_IOError, file);
560            }
561    
562            PyMem_Free(file);
563          return self->handle ? 0 : -1;          return self->handle ? 0 : -1;
564  }  }
565    
566  static PyObject* PyShapeFile_close(PyShapeFile* self)  static PyObject* shapefile_close(ShapeFileObject* self)
567  {  {
568          SHPClose(self->handle);          SHPClose(self->handle);
569          self->handle = NULL;          self->handle = NULL;
570          Py_RETURN_NONE;          Py_RETURN_NONE;
571  }  }
572    
573  static void PyShapeFile_dealloc(PyShapeFile* self)  static PyObject* shapefile_info(ShapeFileObject* self)
 {  
         PyShapeFile_close(self);  
         self->ob_type->tp_free((PyObject*)self);  
 }  
   
 static PyObject* PyShapeFile_info(PyShapeFile* self)  
574  {  {
575          SHPHandle handle = self->handle;          SHPHandle handle = self->handle;
576          return Py_BuildValue("ii(dddd)(dddd)",          return Py_BuildValue("ii(dddd)(dddd)",
# Line 353  static PyObject* PyShapeFile_info(PyShap Line 579  static PyObject* PyShapeFile_info(PyShap
579                          handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);                          handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
580  }  }
581    
582  static PyObject* PyShapeFile_read_object(PyShapeFile* self, PyObject* args)  static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args)
583  {  {
584          int index;          int index;
585          SHPObject* object;          SHPObject* object;
586          PySHPObject* result;          SHPObjectObject* result;
587                    
588          if (!PyArg_ParseTuple(args, "i", &index)) return NULL;          if (!PyArg_ParseTuple(args, "i:read_object", &index)) return NULL;
589                    
590          object = SHPReadObject(self->handle, index);              object = SHPReadObject(self->handle, index);    
591          if (!object)          if (!object)
# Line 368  static PyObject* PyShapeFile_read_object Line 594  static PyObject* PyShapeFile_read_object
594                  return NULL;                  return NULL;
595          }          }
596                    
597          result = PyObject_New(PySHPObject, &PySHPObjectType);          result = PyObject_New(SHPObjectObject, &SHPObjectType);
598          if (!result)          if (!result)
599          {          {
600                  return PyErr_NoMemory();                  return PyErr_NoMemory();
# Line 378  static PyObject* PyShapeFile_read_object Line 604  static PyObject* PyShapeFile_read_object
604          return (PyObject*) result;          return (PyObject*) result;
605  }  }
606    
607  static PyObject* PyShapeFile_write_object(PyShapeFile* self, PyObject* args)  static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args)
608  {  {
609          int index, result;          int index, result;
610          PyObject* object;          PyObject* object;
611                    
612          if (!PyArg_ParseTuple(args, "iO", &index, &object)) return NULL;          if (!PyArg_ParseTuple(args, "iO:write_object", &index, &object)) return NULL;
613                    
614          if (!PyObject_IsInstance(object, (PyObject*)&PySHPObjectType))          if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))
615          {          {
616                  PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");                  PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
617                  return NULL;                  return NULL;
618          }          }
619                    
620          result = SHPWriteObject(self->handle, index, ((PySHPObject*)object)->shpObject);          result = SHPWriteObject(self->handle, index, ((SHPObjectObject*)object)->shpObject);
621          if (result < 0)          if (result < 0)
622          {          {
623                  PyErr_SetString(PyExc_RuntimeError, "failed to write object");                  PyErr_SetString(PyExc_RuntimeError, "failed to write object");
# Line 400  static PyObject* PyShapeFile_write_objec Line 626  static PyObject* PyShapeFile_write_objec
626          return PyInt_FromLong((long)result);          return PyInt_FromLong((long)result);
627  }  }
628    
629  static PyObject* PyShapeFile_cobject(PyShapeFile* self)  static PyObject* shapefile_cobject(ShapeFileObject* self)
630  {  {
631          return PyCObject_FromVoidPtr(self->handle, NULL);          return PyCObject_FromVoidPtr(self->handle, NULL);
632  }  }
633    
634  static PyMethodDef PyShapeFile_methods[] =  static PyObject* shapefile_repr(ShapeFileObject* self)
635    {
636            /* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */
637            return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle);
638    }
639    
640    static struct PyMethodDef shapefile_methods[] =
641  {  {
642          {"close", (PyCFunction)PyShapeFile_close, METH_NOARGS, "close the shape file" },          {"close", (PyCFunction)shapefile_close, METH_NOARGS,
643          {"info", (PyCFunction)PyShapeFile_info, METH_NOARGS,                  "close() -> None\n\n"
644                  "Return a tuple (NUM_SHAPES, TYPE, MIN, MAX) where NUM_SHAPES is the number of shapes in the file, TYPE is the "                  "close the shape file" },
645                  "shape type and MIN and MAX are 4-element tuples with the min. and max. values of the data." },          {"info", (PyCFunction)shapefile_info, METH_NOARGS,
646          {"read_object", (PyCFunction)PyShapeFile_read_object, METH_VARARGS, "Return object number i" },                  "info() -> (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n"
647          {"write_object", (PyCFunction)PyShapeFile_write_object, METH_VARARGS, "Write an object"},                  "returns info about ShapeFile with:\n"
648          {"cobject", (PyCFunction)PyShapeFile_cobject, METH_NOARGS, "Return the shapelib SHPHandle as a Python CObject"},                  "- num_shapes: the number of the objects in the file\n"
649                    "- type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n"
650                    "- (x_min, ...), (x_max, ...): 4D bounding box of the data in the shape file" },
651            {"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS,
652                    "read_object(id) -> SHPObject\n\n"
653                    "Returns shape indexed by id" },
654            {"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS,
655                    "write_object(id, object) -> id\n\n"
656                    "Write an object at index id, and returns id."
657                    "If id == -1, the object is appended at the end of the shape file."},
658            {"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS,
659                    "cobject() -> CObject\n\n"
660                    "Return the shapelib SHPHandle as a Python CObject"},
661          {NULL}          {NULL}
662  };  };
663    
664  static PyGetSetDef PyShapeFile_getsetters[] =  static struct PyGetSetDef shapefile_getsetters[] =
665  {  {
666          {NULL}          {NULL}
667  };  };
668    
669  static PyTypeObject PyShapeFileType = PYSHAPELIB_DEFINE_TYPE(PyShapeFile, "shapelib.ShapeFile", 0);  static PyTypeObject ShapeFileType = PYSHAPELIB_DEFINE_TYPE(ShapeFileObject, shapefile, "shapelib.ShapeFile", 0);
670    
671  /* --- shapelib ------------------------------------------------------------------------------------------------------ */  /* --- shapelib ------------------------------------------------------------------------------------------------------ */
672    
673  static PyObject* shapelib_open(PyObject* module, PyObject* args)  static PyObject* shapelib_open(PyObject* module, PyObject* args)
674  {  {
675          return PyObject_CallObject((PyObject*)&PyShapeFileType, args);          return PyObject_CallObject((PyObject*)&ShapeFileType, args);
676  }  }
677    
678  static PyObject* shapelib_create(PyObject* module, PyObject* args)  static PyObject* shapelib_create(PyObject* module, PyObject* args)
679  {  {
680          char* file;          char* file;
681          int type;          int type;
682          PyShapeFile* result;          ShapeFileObject* result;
683                    
684          if (!PyArg_ParseTuple(args, "si", &file, &type)) return NULL;          if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
685                    
686          result = PyObject_New(PyShapeFile, &PyShapeFileType);          result = PyObject_New(ShapeFileObject, &ShapeFileType);
687          if (!result)          if (!result)
688          {          {
689                    PyMem_Free(file);
690                  return PyErr_NoMemory();                  return PyErr_NoMemory();
691          }          }
692                    
693          result->handle = SHPCreate(file, type);          result->handle = SHPCreate(file, type);
694            PyMem_Free(file);
695            
696          if (!result->handle)          if (!result->handle)
697          {          {
698                  PyObject_Del((PyObject*)result);                  PyObject_Del((PyObject*)result);
# Line 473  static PyObject* shapelib_c_api(PyObject Line 720  static PyObject* shapelib_c_api(PyObject
720  static PyObject* shapelib_type_name(PyObject* module, PyObject* args)  static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
721  {  {
722          int type;          int type;
723          if (!PyArg_ParseTuple(args, "i", &type)) return NULL;          if (!PyArg_ParseTuple(args, "i:type_name", &type)) return NULL;
724          return PyString_FromString(SHPTypeName(type));          return PyString_FromString(SHPTypeName(type));
725  }  }
726    
727  static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)  static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
728  {  {
729          int type;          int type;
730          if (!PyArg_ParseTuple(args, "i", &type)) return NULL;          if (!PyArg_ParseTuple(args, "i:part_type_name", &type)) return NULL;
731          return PyString_FromString(SHPPartTypeName(type));          return PyString_FromString(SHPPartTypeName(type));
732  }  }
733    
734  static PyMethodDef shapelib_methods[] =  static struct PyMethodDef shapelib_methods[] =
735  {  {
736          {"open", (PyCFunction)shapelib_open, METH_VARARGS, "open a ShapeFile" },          {"open", (PyCFunction)shapelib_open, METH_VARARGS,
737          {"create", (PyCFunction)shapelib_create, METH_VARARGS, "create a ShapeFile" },                  "open(name [, mode='rb']) -> ShapeFile\n\n"
738          {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, "get C API of shapelib" },                  "opens a ShapeFile" },
739          {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, "return type as string" },          {"create", (PyCFunction)shapelib_create, METH_VARARGS,
740          {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, "return part type as string" },                  "create(name, type) -> ShapeFile\n\n"
741                    "creates a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" },
742            {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS,
743                    "c_api() -> CObject\n\n"
744                    "get C API of shapelib as a CObject" },
745            {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS,
746                    "type_name(type) -> string\n\n"
747                    "return type as string" },
748            {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS,
749                    "part_type_name(part_type) -> string\n\n"
750                    "return part type as string" },
751          {NULL}          {NULL}
752  };  };
753    
# Line 499  PyMODINIT_FUNC initshapelib(void) Line 756  PyMODINIT_FUNC initshapelib(void)
756          PyObject* module = Py_InitModule("shapelib", shapelib_methods);          PyObject* module = Py_InitModule("shapelib", shapelib_methods);
757          if (!module) return;          if (!module) return;
758                    
759          PYSHAPELIB_ADD_TYPE(PySHPObjectType, "SHPObject");          PYSHAPELIB_ADD_TYPE(SHPObjectType, "SHPObject");
760          PYSHAPELIB_ADD_TYPE(PyShapeFileType, "ShapeFile");          PYSHAPELIB_ADD_TYPE(ShapeFileType, "ShapeFile");
761                    
762          PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);          PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
763          PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);          PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26