/[thuban]/branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.i
ViewVC logotype

Contents of /branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelib.i

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26