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

revision 2742 by bramz, Wed Mar 14 16:26:14 2007 UTC revision 2744 by bramz, Thu Mar 15 13:48:58 2007 UTC
# Line 9  typedef struct Line 9  typedef struct
9  }  }
10  SHPObjectObject;  SHPObjectObject;
11    
12    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  /* allocator
52   */   */
53  static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)  static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
# Line 47  static int shpobject_init(SHPObjectObjec Line 86  static int shpobject_init(SHPObjectObjec
86                    
87          double* xs = NULL;          double* xs = NULL;
88          double* ys = NULL;          double* ys = NULL;
89            double* zs = NULL;
90            double* ms = NULL;
91          int* part_starts = NULL;          int* part_starts = NULL;
92          int* part_types = NULL;          int* part_types = NULL;
93                    
94            PyObject* part;
95            int vertex_type;
96            int has_z;
97            int has_m;
98            
99          int i;          int i;
100          int return_code = -1;          int ok, return_code = -1;
101                    
102          /* first, unpack parameters */          /* first, unpack parameters */
103          if (kwds != NULL && PyDict_Size(kwds) > 0)          if (kwds != NULL && PyDict_Size(kwds) > 0)
# Line 59  static int shpobject_init(SHPObjectObjec Line 105  static int shpobject_init(SHPObjectObjec
105                  PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");                  PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
106                  return -1;                  return -1;
107          }          }
108          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;
109    
110            /* check parts */
111          if (!PySequence_Check(parts))          if (!PySequence_Check(parts))
112          {          {
113                  PyErr_SetString(PyExc_TypeError, "parts is not a sequence");                  PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
# Line 107  static int shpobject_init(SHPObjectObjec Line 154  static int shpobject_init(SHPObjectObjec
154                  num_vertices += PySequence_Length(part);                  num_vertices += PySequence_Length(part);
155                  Py_DECREF(part);                  Py_DECREF(part);
156          }          }
157            
158            
159            vertex_type = determine_vertex_type(type, &has_z, &has_m);
160    
161          /* allocate the memory for the various arrays and check for memory errors */          /* allocate the memory for the various arrays and check for memory errors */
162          xs = malloc(num_vertices * sizeof(double));          xs = malloc(num_vertices * sizeof(double));
163          ys = malloc(num_vertices * sizeof(double));          ys = malloc(num_vertices * sizeof(double));
164            zs = has_z ? malloc(num_vertices * sizeof(double)) : NULL;
165            ms = has_m ? malloc(num_vertices * sizeof(double)) : NULL;
166          part_starts = malloc(num_parts * sizeof(int));          part_starts = malloc(num_parts * sizeof(int));
167          part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;          part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
168    
169          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))
170          {          {
171                  PyErr_NoMemory();                  PyErr_NoMemory();
172                  goto exit;                  goto exit;
# Line 142  static int shpobject_init(SHPObjectObjec Line 194  static int shpobject_init(SHPObjectObjec
194          {          {
195                  int j, length;                  int j, length;
196                                    
197                  PyObject* part = PySequence_ITEM(parts, i);                  part = PySequence_ITEM(parts, i);
198                  length = PySequence_Length(part);                  length = PySequence_Length(part);
199                    if (length < 0) goto exit;
200                  part_starts[i] = part_start;                  part_starts[i] = part_start;
201    
202                  for (j = 0; j < length; ++j)                  for (j = 0; j < length; ++j)
203                  {                  {
204                          PyObject* vertex = PySequence_ITEM(part, j);                          PyObject* vertex = PySequence_ITEM(part, j);
205                          if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))                          switch (vertex_type)
206                          {                          {
207                                  PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");                          case vtXY:
208                                  Py_DECREF(vertex);                                  ok = PyArg_ParseTuple(vertex, "dd:__init__", xs + part_start + j, ys + part_start + j);
209                                  Py_DECREF(part);                                  break;
210                                  goto exit;                          case vtXYM:
211                                    ok = PyArg_ParseTuple(vertex, "ddd:__init__", xs + part_start + j, ys + part_start + j, ms + part_start + j);
212                                    break;
213                            case vtXYZM:
214                                    ms[part_start + j] = 0.;
215                                    ok = PyArg_ParseTuple(vertex, "ddd|d:__init__", xs + part_start + j, ys + part_start + j, zs + part_start + j,
216                                            ms + part_start + j);
217                                    break;
218                          }                          }
219                          Py_DECREF(vertex);                          Py_DECREF(vertex);
220                            if (!ok)
221                            {
222                                    PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
223                                    goto exit;
224                            }
225                  }                  }
226                  Py_DECREF(part);                  Py_DECREF(part);
227                    part = NULL;
228                  part_start += length;                  part_start += length;
229          }          }
230    
231          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);
232          return_code = 0;          return_code = 0;
233                    
234  exit:  exit:
235            Py_XDECREF(part);
236          free(xs);          free(xs);
237          free(ys);          free(ys);
238            free(zs);
239            free(ms);
240          free(part_starts);          free(part_starts);
241          free(part_types);          free(part_types);
242          return return_code;          return return_code;
# Line 195  static PyObject* shpobject_extents(SHPOb Line 264  static PyObject* shpobject_extents(SHPOb
264  * tuples.  * tuples.
265  */  */
266    
267  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);
268    
269  static PyObject* shpobject_vertices(SHPObjectObject* self)  static PyObject* shpobject_vertices(SHPObjectObject* self)
270  {  {
# Line 203  static PyObject* shpobject_vertices(SHPO Line 272  static PyObject* shpobject_vertices(SHPO
272          PyObject *part = NULL;          PyObject *part = NULL;
273          int part_idx, vertex_idx;          int part_idx, vertex_idx;
274          int length = 0;          int length = 0;
275            int vertex_type;
276            
277          SHPObject* object = self->shpObject;          SHPObject* object = self->shpObject;
278            vertex_type = determine_vertex_type(object->nSHPType, NULL, NULL);
279    
280          if (object->nParts > 0)          if (object->nParts > 0)
281          {          {
# Line 216  static PyObject* shpobject_vertices(SHPO Line 288  static PyObject* shpobject_vertices(SHPO
288                  for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)                  for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
289                  {                  {
290                          if (part_idx < object->nParts - 1)                          if (part_idx < object->nParts - 1)
291                          length = (object->panPartStart[part_idx + 1]                                  length = (object->panPartStart[part_idx + 1]
292                                  - object->panPartStart[part_idx]);                                          - object->panPartStart[part_idx]);
293                          else                          else
294                          length = object->nVertices - object->panPartStart[part_idx];                                  length = object->nVertices - object->panPartStart[part_idx];
295                                                    
296                          part = build_vertex_list(object, vertex_idx, length);                          part = build_vertex_list(object, vertex_idx, length, vertex_type);
297                          if (!part)                          if (!part) goto fail;
                         goto fail;  
298    
299                          if (PyList_SetItem(result, part_idx, part) < 0)                          if (PyList_SetItem(result, part_idx, part) < 0) goto fail;
                         goto fail;  
300    
301                          vertex_idx += length;                          vertex_idx += length;
302                  }                  }
# Line 234  static PyObject* shpobject_vertices(SHPO Line 304  static PyObject* shpobject_vertices(SHPO
304          else          else
305          {          {
306                  /* only one part. usual for SHPT_POINT */                  /* only one part. usual for SHPT_POINT */
307                  result = build_vertex_list(object, 0, object->nVertices);                  result = build_vertex_list(object, 0, object->nVertices, vertex_type);
308          }          }
309    
310          return result;          return result;
# Line 250  fail: Line 320  fail:
320  * index as a Python-list of tuples. Helper function for  * index as a Python-list of tuples. Helper function for
321  * SHPObject_vertices.  * SHPObject_vertices.
322  */  */
323  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)
324  {  {
325          int i;          int i;
326          PyObject * list;          PyObject * list;
# Line 262  static PyObject* build_vertex_list(SHPOb Line 332  static PyObject* build_vertex_list(SHPOb
332    
333          for (i = 0; i < length; i++, index++)          for (i = 0; i < length; i++, index++)
334          {          {
335                  vertex = Py_BuildValue("dd", object->padfX[index],                  switch (vertex_type)
336                                          object->padfY[index]);                  {
337                  if (!vertex)                  case vtXY:
338                          goto fail;                          vertex = Py_BuildValue("dd", object->padfX[index], object->padfY[index]);
339                  if (PyList_SetItem(list, i, vertex) < 0)                          break;                  
340                    case vtXYM:
341                            vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index],
342                                    object->padfM[index]);
343                    case vtXYZM:
344                            vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index],
345                                    object->padfZ[index], object->padfM[index]);
346                            break;                  
347                    default:
348                          goto fail;                          goto fail;
349          }                  }
350    
351                    if (!vertex || PyList_SetItem(list, i, vertex) < 0) goto fail;
352            }
353            
354          return list;          return list;
355    
356  fail:  fail:
         Py_XDECREF(vertex);  
357          Py_DECREF(list);          Py_DECREF(list);
358          return NULL;          return NULL;
359  }  }
# Line 356  static PyObject* shpobject_repr(SHPObjec Line 436  static PyObject* shpobject_repr(SHPObjec
436    
437  static struct PyMethodDef shpobject_methods[] =  static struct PyMethodDef shpobject_methods[] =
438  {  {
439          {"extents", (PyCFunction)shpobject_extents, METH_NOARGS, NULL},          {"extents", (PyCFunction)shpobject_extents, METH_NOARGS,
440          {"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS, NULL},                  "extents()\n"
441          {"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS, NULL},                  "returns ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)), the 4D bounding box of the SHPObject"},
442            {"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS,
443                    "vertices()\n"
444                    "returns [[(x, y, ...), ...], ...], a list of object parts, where each part is again a list of vertices.\n"
445                    "each vertex is a tuple of two to four doubles, depending on the object type."},
446            {"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS,
447                    "part_types()\n"
448                    "returns a tuple of integers, each integer indicating the type of the corresponding part in vertices()"},
449          {NULL}          {NULL}
450  };  };
451    
452  static struct PyGetSetDef shpobject_getsetters[] =  static struct PyGetSetDef shpobject_getsetters[] =
453  {  {
454          {"type", (getter)shpobject_type, NULL, NULL },          {"type", (getter)shpobject_type, NULL, "type of the object (read-only)" },
455          {"id", (getter)shpobject_id, NULL, NULL },          {"id", (getter)shpobject_id, NULL, "id of the object (read-only)" },
456          {NULL}          {NULL}
457  };  };
458    
# Line 410  static int shapefile_init(ShapeFileObjec Line 497  static int shapefile_init(ShapeFileObjec
497                  PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");                  PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
498                  return -1;                  return -1;
499          }          }
500          if (!PyArg_ParseTuple(args, "s|s", &file, &mode)) return -1;          if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
501                    
502          self->handle = SHPOpen(file, mode);          self->handle = SHPOpen(file, mode);
503          return self->handle ? 0 : -1;          return self->handle ? 0 : -1;
# Line 438  static PyObject* shapefile_read_object(S Line 525  static PyObject* shapefile_read_object(S
525          SHPObject* object;          SHPObject* object;
526          SHPObjectObject* result;          SHPObjectObject* result;
527                    
528          if (!PyArg_ParseTuple(args, "i", &index)) return NULL;          if (!PyArg_ParseTuple(args, "i:read_object", &index)) return NULL;
529                    
530          object = SHPReadObject(self->handle, index);              object = SHPReadObject(self->handle, index);    
531          if (!object)          if (!object)
# Line 462  static PyObject* shapefile_write_object( Line 549  static PyObject* shapefile_write_object(
549          int index, result;          int index, result;
550          PyObject* object;          PyObject* object;
551                    
552          if (!PyArg_ParseTuple(args, "iO", &index, &object)) return NULL;          if (!PyArg_ParseTuple(args, "iO:write_object", &index, &object)) return NULL;
553                    
554          if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))          if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))
555          {          {
# Line 492  static PyObject* shapefile_repr(ShapeFil Line 579  static PyObject* shapefile_repr(ShapeFil
579    
580  static struct PyMethodDef shapefile_methods[] =  static struct PyMethodDef shapefile_methods[] =
581  {  {
582          {"close", (PyCFunction)shapefile_close, METH_NOARGS, "close the shape file" },          {"close", (PyCFunction)shapefile_close, METH_NOARGS,
583          {"info", (PyCFunction)shapefile_info, METH_NOARGS,                  "close()\n"
584                  "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" },
585                  "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,
586          {"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS, "Return object number i" },                  "info()\n"
587          {"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS, "Write an object"},                  "returns (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)) with:\n"
588          {"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS, "Return the shapelib SHPHandle as a Python CObject"},                  "-num_shapes: the number of the objects in the file\n"
589                    "-type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n"
590                    "-(x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max): 4D bounding box of the data in the shape file" },
591            {"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS,
592                    "read_object(id)\n"
593                    "Return object indexed by id" },
594            {"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS,
595                    "write_object(id, object)\n"
596                    "Write an object at index id.\n"
597                    "If id == -1, the object is appended at the end of the shape file"},
598            {"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS,
599                    "cobject()\n"
600                    "Return the shapelib SHPHandle as a Python CObject"},
601          {NULL}          {NULL}
602  };  };
603    
# Line 522  static PyObject* shapelib_create(PyObjec Line 621  static PyObject* shapelib_create(PyObjec
621          int type;          int type;
622          ShapeFileObject* result;          ShapeFileObject* result;
623                    
624          if (!PyArg_ParseTuple(args, "si", &file, &type)) return NULL;          if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
625                    
626          result = PyObject_New(ShapeFileObject, &ShapeFileType);          result = PyObject_New(ShapeFileObject, &ShapeFileType);
627          if (!result)          if (!result)
# Line 558  static PyObject* shapelib_c_api(PyObject Line 657  static PyObject* shapelib_c_api(PyObject
657  static PyObject* shapelib_type_name(PyObject* module, PyObject* args)  static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
658  {  {
659          int type;          int type;
660          if (!PyArg_ParseTuple(args, "i", &type)) return NULL;          if (!PyArg_ParseTuple(args, "i:type_name", &type)) return NULL;
661          return PyString_FromString(SHPTypeName(type));          return PyString_FromString(SHPTypeName(type));
662  }  }
663    
664  static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)  static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
665  {  {
666          int type;          int type;
667          if (!PyArg_ParseTuple(args, "i", &type)) return NULL;          if (!PyArg_ParseTuple(args, "i:part_type_name", &type)) return NULL;
668          return PyString_FromString(SHPPartTypeName(type));          return PyString_FromString(SHPPartTypeName(type));
669  }  }
670    
671  static struct PyMethodDef shapelib_methods[] =  static struct PyMethodDef shapelib_methods[] =
672  {  {
673          {"open", (PyCFunction)shapelib_open, METH_VARARGS, "open a ShapeFile" },          {"open", (PyCFunction)shapelib_open, METH_VARARGS,
674          {"create", (PyCFunction)shapelib_create, METH_VARARGS, "create a ShapeFile" },                  "open(filename [, mode='rb'])\n"
675          {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, "get C API of shapelib" },                  "open a ShapeFile" },
676          {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, "return type as string" },          {"create", (PyCFunction)shapelib_create, METH_VARARGS,
677          {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, "return part type as string" },                  "create(filename, type)\n"
678                    "create a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" },
679            {"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS,
680                    "c_api()\n"
681                    "get C API of shapelib" },
682            {"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS,
683                    "type_name(type)\n"
684                    "return type as string" },
685            {"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS,
686                    "part_type_name(part_type)\n"
687                    "return part type as string" },
688          {NULL}          {NULL}
689  };  };
690    

Legend:
Removed from v.2742  
changed lines
  Added in v.2744

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26