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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2744 - (hide annotations)
Thu Mar 15 13:48:58 2007 UTC (17 years, 11 months ago) by bramz
File MIME type: text/plain
File size: 18428 byte(s)
shapelibmodule.c, dbflibmodule.c: added some Unicode support for the filenames (no internal encoding for DBFFile yet).  It now should similar Unicode support Python's file() (concerning the filename, that is).
1 bramz 2735 #include "pyshapelib_common.h"
2 jan 1611
3 bramz 2735 /* --- SHPObject ----------------------------------------------------------------------------------------------------- */
4 jan 1611
5 bramz 2735 typedef struct
6     {
7     PyObject_HEAD
8     SHPObject* shpObject;
9     }
10 bramz 2742 SHPObjectObject;
11 jan 1611
12 bramz 2743 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 bramz 2741 /* allocator
52     */
53 bramz 2742 static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
54 bramz 2735 {
55 bramz 2742 SHPObjectObject* self;
56     self = (SHPObjectObject*) type->tp_alloc(type, 0);
57 bramz 2735 self->shpObject = NULL;
58     return (PyObject*) self;
59     }
60 jan 1611
61 bramz 2741 /* deallocator
62     */
63 bramz 2742 static void shpobject_dealloc(SHPObjectObject* self)
64 bramz 2735 {
65     SHPDestroyObject(self->shpObject);
66     self->shpObject = NULL;
67     self->ob_type->tp_free((PyObject*)self);
68     }
69 jan 1611
70 bramz 2735 /* The constructor of SHPObject. parts is a list of lists of tuples
71     * describing the parts and their vertices just likethe output of the
72     * vertices() method. part_type_list is the list of part-types and may
73     * be NULL. For the meaning of the part-types and their default value
74     * see the Shaplib documentation.
75     */
76 bramz 2742 static int shpobject_init(SHPObjectObject* self, PyObject* args, PyObject* kwds)
77 bramz 2735 {
78     int type;
79     int id;
80     PyObject* parts = NULL;
81     PyObject* part_type_list = NULL;
82    
83     int num_parts;
84     int num_vertices;
85     int part_start;
86    
87     double* xs = NULL;
88     double* ys = NULL;
89 bramz 2743 double* zs = NULL;
90     double* ms = NULL;
91 bramz 2735 int* part_starts = NULL;
92     int* part_types = NULL;
93    
94 bramz 2743 PyObject* part;
95     int vertex_type;
96     int has_z;
97     int has_m;
98    
99 bramz 2735 int i;
100 bramz 2743 int ok, return_code = -1;
101 bramz 2735
102     /* first, unpack parameters */
103     if (kwds != NULL && PyDict_Size(kwds) > 0)
104     {
105     PyErr_Format(PyExc_TypeError, "shapelib.SHPObject.__init__ takes no keyword arguments");
106     return -1;
107     }
108 bramz 2744 if (!PyArg_ParseTuple(args, "iiO|O:__init__", &type, &id, &parts, &part_type_list)) return -1;
109 bramz 2735
110 bramz 2743 /* check parts */
111 bramz 2735 if (!PySequence_Check(parts))
112     {
113     PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
114     return -1;
115     }
116     num_parts = PySequence_Length(parts);
117     if (num_parts < 0)
118     {
119     PyErr_SetString(PyExc_TypeError, "cannot determine length of parts");
120     return -1;
121     }
122    
123     /* parts and part_types have to have the same lengths */
124 bramz 2741 if (part_type_list == Py_None)
125     {
126     Py_DECREF(part_type_list);
127     part_type_list = NULL;
128     }
129 bramz 2735 if (part_type_list)
130     {
131     if (!PySequence_Check(parts))
132     {
133     PyErr_SetString(PyExc_TypeError, "part_type_list is not a sequence");
134     return -1;
135     }
136     if (PySequence_Length(part_type_list) != num_parts)
137     {
138     PyErr_SetString(PyExc_TypeError, "parts and part_types have to have the same lengths");
139     return -1;
140     }
141     }
142    
143     /* determine how many vertices there are altogether */
144     num_vertices = 0;
145     for (i = 0; i < num_parts; ++i)
146     {
147     PyObject* part = PySequence_ITEM(parts, i);
148     if (!PySequence_Check(part))
149     {
150     PyErr_SetString(PyExc_TypeError, "at least one item in parts is not a sequence");
151     Py_DECREF(part);
152     return -1;
153     }
154     num_vertices += PySequence_Length(part);
155     Py_DECREF(part);
156     }
157 bramz 2743
158    
159     vertex_type = determine_vertex_type(type, &has_z, &has_m);
160 bramz 2735
161     /* allocate the memory for the various arrays and check for memory errors */
162     xs = malloc(num_vertices * sizeof(double));
163     ys = malloc(num_vertices * sizeof(double));
164 bramz 2743 zs = has_z ? malloc(num_vertices * sizeof(double)) : NULL;
165     ms = has_m ? malloc(num_vertices * sizeof(double)) : NULL;
166 bramz 2735 part_starts = malloc(num_parts * sizeof(int));
167     part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
168    
169 bramz 2743 if (!xs || !ys || (has_z && !zs) || (has_m && !ms) || !part_starts || (part_type_list && !part_types))
170 bramz 2735 {
171     PyErr_NoMemory();
172     goto exit;
173     }
174    
175     /* convert the part types */
176     if (part_type_list)
177     {
178     for (i = 0; i < num_parts; i++)
179     {
180     PyObject* otype = PySequence_ITEM(part_type_list, i);
181     part_types[i] = PyInt_AsLong(otype);
182     Py_DECREF(otype);
183     if (part_types[i] < 0)
184     {
185     PyErr_SetString(PyExc_TypeError, "at least one item in part_type_list is not an integer or is negative");
186     goto exit;
187     }
188     }
189     }
190    
191     /* convert the list of parts */
192     part_start = 0;
193     for (i = 0; i < num_parts; ++i)
194     {
195     int j, length;
196    
197 bramz 2743 part = PySequence_ITEM(parts, i);
198 bramz 2735 length = PySequence_Length(part);
199 bramz 2743 if (length < 0) goto exit;
200 bramz 2735 part_starts[i] = part_start;
201    
202     for (j = 0; j < length; ++j)
203     {
204     PyObject* vertex = PySequence_ITEM(part, j);
205 bramz 2743 switch (vertex_type)
206 bramz 2735 {
207 bramz 2743 case vtXY:
208 bramz 2744 ok = PyArg_ParseTuple(vertex, "dd:__init__", xs + part_start + j, ys + part_start + j);
209 bramz 2743 break;
210     case vtXYM:
211 bramz 2744 ok = PyArg_ParseTuple(vertex, "ddd:__init__", xs + part_start + j, ys + part_start + j, ms + part_start + j);
212 bramz 2743 break;
213     case vtXYZM:
214     ms[part_start + j] = 0.;
215 bramz 2744 ok = PyArg_ParseTuple(vertex, "ddd|d:__init__", xs + part_start + j, ys + part_start + j, zs + part_start + j,
216 bramz 2743 ms + part_start + j);
217     break;
218     }
219     Py_DECREF(vertex);
220     if (!ok)
221     {
222     PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
223 bramz 2735 goto exit;
224     }
225     }
226     Py_DECREF(part);
227 bramz 2743 part = NULL;
228 bramz 2735 part_start += length;
229     }
230    
231 bramz 2743 self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, zs, ms);
232 bramz 2735 return_code = 0;
233    
234     exit:
235 bramz 2743 Py_XDECREF(part);
236 bramz 2735 free(xs);
237     free(ys);
238 bramz 2743 free(zs);
239     free(ms);
240 bramz 2735 free(part_starts);
241     free(part_types);
242     return return_code;
243     }
244    
245 jan 1611 /*
246 bramz 2735 * The extents() method of SHPObject.
247     *
248     * Return the extents as a tuple of two 4-element lists with the min.
249     * and max. values of x, y, z, m.
250     */
251 bramz 2742 static PyObject* shpobject_extents(SHPObjectObject* self)
252 jan 1611 {
253 bramz 2735 SHPObject* object = self->shpObject;
254     return Py_BuildValue("(dddd)(dddd)",
255     object->dfXMin, object->dfYMin, object->dfZMin, object->dfMMin,
256     object->dfXMax, object->dfYMax, object->dfZMax, object->dfMMax);
257 jan 1611 }
258    
259    
260     /*
261 bramz 2735 * The vertices() method of SHPObject.
262     *
263     * Return the x and y coords of the vertices as a list of lists of
264     * tuples.
265     */
266 jan 1611
267 bramz 2743 static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type);
268 jan 1611
269 bramz 2742 static PyObject* shpobject_vertices(SHPObjectObject* self)
270 jan 1611 {
271 bramz 2735 PyObject *result = NULL;
272     PyObject *part = NULL;
273     int part_idx, vertex_idx;
274     int length = 0;
275 bramz 2743 int vertex_type;
276    
277 bramz 2735 SHPObject* object = self->shpObject;
278 bramz 2743 vertex_type = determine_vertex_type(object->nSHPType, NULL, NULL);
279 jan 1611
280 bramz 2735 if (object->nParts > 0)
281     {
282     /* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */
283 jan 1611
284 bramz 2735 result = PyList_New(object->nParts);
285 bramz 2741 if (!result)
286     return NULL;
287 jan 1611
288 bramz 2741 for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
289     {
290     if (part_idx < object->nParts - 1)
291 bramz 2743 length = (object->panPartStart[part_idx + 1]
292     - object->panPartStart[part_idx]);
293 bramz 2741 else
294 bramz 2743 length = object->nVertices - object->panPartStart[part_idx];
295 bramz 2741
296 bramz 2743 part = build_vertex_list(object, vertex_idx, length, vertex_type);
297     if (!part) goto fail;
298 jan 1611
299 bramz 2743 if (PyList_SetItem(result, part_idx, part) < 0) goto fail;
300 jan 1611
301 bramz 2741 vertex_idx += length;
302     }
303 jan 1611 }
304 bramz 2735 else
305     {
306 bramz 2741 /* only one part. usual for SHPT_POINT */
307 bramz 2743 result = build_vertex_list(object, 0, object->nVertices, vertex_type);
308 bramz 2735 }
309 jan 1611
310 bramz 2735 return result;
311 jan 1611
312 bramz 2735 fail:
313     Py_XDECREF(part);
314     Py_DECREF(result);
315     return NULL;
316 jan 1611 }
317    
318    
319     /* Return the length coordinates of the shape object starting at vertex
320 bramz 2735 * index as a Python-list of tuples. Helper function for
321     * SHPObject_vertices.
322     */
323 bramz 2743 static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type)
324 jan 1611 {
325 bramz 2735 int i;
326     PyObject * list;
327     PyObject * vertex = NULL;
328 jan 1611
329 bramz 2735 list = PyList_New(length);
330     if (!list)
331 bramz 2741 return NULL;
332 jan 1611
333 bramz 2735 for (i = 0; i < length; i++, index++)
334     {
335 bramz 2743 switch (vertex_type)
336     {
337     case vtXY:
338     vertex = Py_BuildValue("dd", object->padfX[index], object->padfY[index]);
339     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 bramz 2741 goto fail;
349 bramz 2743 }
350    
351     if (!vertex || PyList_SetItem(list, i, vertex) < 0) goto fail;
352 bramz 2735 }
353 bramz 2743
354 bramz 2735 return list;
355 jan 1611
356 bramz 2735 fail:
357     Py_DECREF(list);
358     return NULL;
359 jan 1611 }
360    
361 bramz 2741
362    
363 bramz 2742 static PyObject* shpobject_part_types(SHPObjectObject* self)
364 bramz 2741 {
365     int i;
366     PyObject* result = NULL;
367     SHPObject* object = self->shpObject;
368    
369     if (object->nParts == 0 || object->panPartType == 0)
370     {
371     Py_RETURN_NONE;
372     }
373    
374     result = PyTuple_New(object->nParts);
375     if (!result) return NULL;
376    
377     for (i = 0; i < object->nParts; ++i)
378     {
379     /* PyTuple_SetItem steals a reference */
380     PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]);
381     if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail;
382     }
383     return result;
384    
385     fail:
386     Py_DECREF(result);
387     return NULL;
388     }
389    
390    
391    
392 bramz 2742 static PyObject* shpobject_type(SHPObjectObject* self, void* closure)
393 bramz 2735 {
394     return PyInt_FromLong(self->shpObject->nSHPType);
395     }
396 jan 1611
397 bramz 2741
398    
399 bramz 2742 static PyObject* shpobject_id(SHPObjectObject* self, void* closure)
400 bramz 2735 {
401     return PyInt_FromLong(self->shpObject->nShapeId);
402     }
403 jan 1611
404 bramz 2741
405    
406     /* return a string that can be feeded to eval() to reconstruct the object,
407     * assuming a proper context
408     */
409 bramz 2742 static PyObject* shpobject_repr(SHPObjectObject* self)
410 bramz 2741 {
411     PyObject* format = NULL;
412     PyObject* args = NULL;
413     PyObject* result = NULL;
414    
415     format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)");
416     if (!format) return NULL;
417    
418     args = Py_BuildValue("iiNN",
419     self->shpObject->nSHPType,
420     self->shpObject->nShapeId,
421 bramz 2742 shpobject_vertices(self),
422     shpobject_part_types(self));
423 bramz 2741 if (!args)
424     {
425     Py_DECREF(format);
426     return NULL;
427     }
428    
429     result = PyString_Format(format, args);
430     Py_DECREF(args);
431     Py_DECREF(format);
432     return result;
433     }
434    
435    
436    
437 bramz 2742 static struct PyMethodDef shpobject_methods[] =
438 bramz 2735 {
439 bramz 2744 {"extents", (PyCFunction)shpobject_extents, METH_NOARGS,
440     "extents()\n"
441     "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 bramz 2735 {NULL}
450     };
451 jan 1611
452 bramz 2742 static struct PyGetSetDef shpobject_getsetters[] =
453 jan 1611 {
454 bramz 2744 {"type", (getter)shpobject_type, NULL, "type of the object (read-only)" },
455     {"id", (getter)shpobject_id, NULL, "id of the object (read-only)" },
456 bramz 2735 {NULL}
457     };
458 jan 1611
459 bramz 2742 static PyTypeObject SHPObjectType = PYSHAPELIB_DEFINE_TYPE(SHPObjectObject, shpobject, "shapelib.SHPObject", 0);
460 jan 1611
461    
462 bramz 2735 /* --- ShapeFile ----------------------------------------------------------------------------------------------------- */
463 jan 1611
464 bramz 2735 typedef struct
465     {
466     PyObject_HEAD
467     SHPHandle handle;
468     }
469 bramz 2742 ShapeFileObject;
470 jan 1611
471 bramz 2741 /* allocator
472     */
473 bramz 2742 static PyObject* shapefile_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
474 bramz 2735 {
475 bramz 2742 ShapeFileObject* self;
476     self = (ShapeFileObject*) type->tp_alloc(type, 0);
477 bramz 2735 self->handle = NULL;
478     return (PyObject*) self;
479     }
480 jan 1611
481 bramz 2742 /* destructor
482     */
483     static void shapefile_dealloc(ShapeFileObject* self)
484     {
485     SHPClose(self->handle);
486     self->ob_type->tp_free((PyObject*)self);
487     }
488    
489 bramz 2741 /* constructor
490     */
491 bramz 2742 static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds)
492 bramz 2735 {
493     char* file;
494     char* mode = "rb";
495     if (kwds != NULL && PyDict_Size(kwds) > 0)
496     {
497     PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
498     return -1;
499     }
500 bramz 2744 if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
501 bramz 2735
502     self->handle = SHPOpen(file, mode);
503     return self->handle ? 0 : -1;
504     }
505 jan 1611
506 bramz 2742 static PyObject* shapefile_close(ShapeFileObject* self)
507 bramz 2735 {
508     SHPClose(self->handle);
509     self->handle = NULL;
510     Py_RETURN_NONE;
511     }
512 jan 1611
513 bramz 2742 static PyObject* shapefile_info(ShapeFileObject* self)
514 bramz 2735 {
515     SHPHandle handle = self->handle;
516     return Py_BuildValue("ii(dddd)(dddd)",
517     handle->nRecords, handle->nShapeType,
518     handle->adBoundsMin[0], handle->adBoundsMin[1], handle->adBoundsMin[2], handle->adBoundsMin[3],
519     handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]);
520     }
521 jan 1611
522 bramz 2742 static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args)
523 bramz 2735 {
524     int index;
525     SHPObject* object;
526 bramz 2742 SHPObjectObject* result;
527 bramz 2735
528 bramz 2744 if (!PyArg_ParseTuple(args, "i:read_object", &index)) return NULL;
529 bramz 2735
530     object = SHPReadObject(self->handle, index);
531     if (!object)
532 jan 1611 {
533 bramz 2735 PyErr_SetString(PyExc_RuntimeError, "failed to read object");
534 jan 1611 return NULL;
535     }
536 bramz 2735
537 bramz 2742 result = PyObject_New(SHPObjectObject, &SHPObjectType);
538 bramz 2735 if (!result)
539 jan 1611 {
540 bramz 2735 return PyErr_NoMemory();
541 jan 1611 }
542 bramz 2735
543     result->shpObject = object;
544     return (PyObject*) result;
545 jan 1611 }
546    
547 bramz 2742 static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args)
548 bramz 2735 {
549     int index, result;
550     PyObject* object;
551    
552 bramz 2744 if (!PyArg_ParseTuple(args, "iO:write_object", &index, &object)) return NULL;
553 bramz 2735
554 bramz 2742 if (!PyObject_IsInstance(object, (PyObject*)&SHPObjectType))
555 bramz 2735 {
556     PyErr_SetString(PyExc_TypeError, "object is not a SHPObject");
557     return NULL;
558     }
559    
560 bramz 2742 result = SHPWriteObject(self->handle, index, ((SHPObjectObject*)object)->shpObject);
561 bramz 2735 if (result < 0)
562     {
563     PyErr_SetString(PyExc_RuntimeError, "failed to write object");
564     return NULL;
565     }
566     return PyInt_FromLong((long)result);
567 jan 1611 }
568    
569 bramz 2742 static PyObject* shapefile_cobject(ShapeFileObject* self)
570 bramz 2735 {
571     return PyCObject_FromVoidPtr(self->handle, NULL);
572 jan 1611 }
573    
574 bramz 2742 static PyObject* shapefile_repr(ShapeFileObject* self)
575 bramz 2741 {
576     /* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */
577     return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle);
578     }
579    
580 bramz 2742 static struct PyMethodDef shapefile_methods[] =
581 bramz 2735 {
582 bramz 2744 {"close", (PyCFunction)shapefile_close, METH_NOARGS,
583     "close()\n"
584     "close the shape file" },
585     {"info", (PyCFunction)shapefile_info, METH_NOARGS,
586     "info()\n"
587     "returns (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)) with:\n"
588     "-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 bramz 2735 {NULL}
602     };
603 jan 1611
604 bramz 2742 static struct PyGetSetDef shapefile_getsetters[] =
605 bramz 2735 {
606     {NULL}
607     };
608 jan 1611
609 bramz 2742 static PyTypeObject ShapeFileType = PYSHAPELIB_DEFINE_TYPE(ShapeFileObject, shapefile, "shapelib.ShapeFile", 0);
610 jan 1611
611 bramz 2735 /* --- shapelib ------------------------------------------------------------------------------------------------------ */
612 jan 1611
613 bramz 2735 static PyObject* shapelib_open(PyObject* module, PyObject* args)
614     {
615 bramz 2742 return PyObject_CallObject((PyObject*)&ShapeFileType, args);
616 jan 1611 }
617    
618 bramz 2735 static PyObject* shapelib_create(PyObject* module, PyObject* args)
619 jan 1611 {
620 bramz 2735 char* file;
621     int type;
622 bramz 2742 ShapeFileObject* result;
623 bramz 2735
624 bramz 2744 if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL;
625 bramz 2735
626 bramz 2742 result = PyObject_New(ShapeFileObject, &ShapeFileType);
627 bramz 2735 if (!result)
628     {
629     return PyErr_NoMemory();
630 jan 1611 }
631 bramz 2735
632     result->handle = SHPCreate(file, type);
633     if (!result->handle)
634     {
635     PyObject_Del((PyObject*)result);
636     PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile");
637     return NULL;
638 jan 1611 }
639 bramz 2735
640     return (PyObject*) result;
641     }
642    
643     static PyShapeLibAPI shapelib_the_api =
644     {
645 jan 1611 SHPReadObject,
646     SHPDestroyObject,
647     SHPCreateTree,
648     SHPDestroyTree,
649     SHPTreeFindLikelyShapes
650 bramz 2735 };
651 jan 1611
652 bramz 2735 static PyObject* shapelib_c_api(PyObject* module)
653     {
654     return PyCObject_FromVoidPtr(&shapelib_the_api, NULL);
655     }
656 jan 1611
657 bramz 2735 static PyObject* shapelib_type_name(PyObject* module, PyObject* args)
658     {
659     int type;
660 bramz 2744 if (!PyArg_ParseTuple(args, "i:type_name", &type)) return NULL;
661 bramz 2735 return PyString_FromString(SHPTypeName(type));
662     }
663 jan 1611
664 bramz 2735 static PyObject* shapelib_part_type_name(PyObject* module, PyObject* args)
665     {
666     int type;
667 bramz 2744 if (!PyArg_ParseTuple(args, "i:part_type_name", &type)) return NULL;
668 bramz 2735 return PyString_FromString(SHPPartTypeName(type));
669     }
670 jan 1611
671 bramz 2742 static struct PyMethodDef shapelib_methods[] =
672 bramz 2735 {
673 bramz 2744 {"open", (PyCFunction)shapelib_open, METH_VARARGS,
674     "open(filename [, mode='rb'])\n"
675     "open a ShapeFile" },
676     {"create", (PyCFunction)shapelib_create, METH_VARARGS,
677     "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 bramz 2735 {NULL}
689     };
690 jan 1611
691 bramz 2735 PyMODINIT_FUNC initshapelib(void)
692     {
693     PyObject* module = Py_InitModule("shapelib", shapelib_methods);
694     if (!module) return;
695    
696 bramz 2742 PYSHAPELIB_ADD_TYPE(SHPObjectType, "SHPObject");
697     PYSHAPELIB_ADD_TYPE(ShapeFileType, "ShapeFile");
698 bramz 2735
699     PYSHAPELIB_ADD_CONSTANT(SHPT_NULL);
700     PYSHAPELIB_ADD_CONSTANT(SHPT_POINT);
701     PYSHAPELIB_ADD_CONSTANT(SHPT_ARC);
702     PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGON);
703     PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINT);
704     PYSHAPELIB_ADD_CONSTANT(SHPT_POINTZ);
705     PYSHAPELIB_ADD_CONSTANT(SHPT_ARCZ);
706     PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONZ);
707     PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTZ);
708     PYSHAPELIB_ADD_CONSTANT(SHPT_POINTM);
709     PYSHAPELIB_ADD_CONSTANT(SHPT_ARCM);
710     PYSHAPELIB_ADD_CONSTANT(SHPT_POLYGONM);
711     PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPOINTM);
712     PYSHAPELIB_ADD_CONSTANT(SHPT_MULTIPATCH);
713     PYSHAPELIB_ADD_CONSTANT(SHPP_TRISTRIP);
714     PYSHAPELIB_ADD_CONSTANT(SHPP_TRIFAN);
715     PYSHAPELIB_ADD_CONSTANT(SHPP_OUTERRING);
716     PYSHAPELIB_ADD_CONSTANT(SHPP_INNERRING);
717     PYSHAPELIB_ADD_CONSTANT(SHPP_FIRSTRING);
718     PYSHAPELIB_ADD_CONSTANT(SHPP_RING);
719     }
720 jan 1611

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26