1 |
/* Copyright (c) 2001, 2002 by Intevation GmbH |
2 |
* Authors: |
3 |
* Bernhard Herzog <[email protected]> |
4 |
* |
5 |
* This program is free software under the GPL (>=v2) |
6 |
* Read the file COPYING coming with Thuban for details. |
7 |
*/ |
8 |
|
9 |
/* Python wrapper for the shapelib SHPTree */ |
10 |
|
11 |
#include <Python.h> |
12 |
#include <shapefil.h> |
13 |
|
14 |
#include "pyshapelib_api.h" |
15 |
|
16 |
PyShapeLibAPI * api; |
17 |
|
18 |
typedef struct { |
19 |
PyObject_HEAD |
20 |
SHPTree * tree; |
21 |
} SHPTreeObject; |
22 |
|
23 |
extern PyTypeObject SHPTreeType; |
24 |
|
25 |
#define SHPTree_Check(v) ((v)->ob_type == &SHPTreeType) |
26 |
|
27 |
/* Create a new python wrapper object from a SHPTree pointer */ |
28 |
static PyObject * |
29 |
SHPTreeObject_FromSHPTree(SHPTree* tree) |
30 |
{ |
31 |
SHPTreeObject * self = PyObject_NEW(SHPTreeObject, &SHPTreeType); |
32 |
if (!self) |
33 |
return NULL; |
34 |
|
35 |
self->tree = tree; |
36 |
|
37 |
return (PyObject *)self; |
38 |
} |
39 |
|
40 |
/* Deallocate the SHPTree wrapper. */ |
41 |
static void |
42 |
shptree_dealloc(SHPTreeObject * self) |
43 |
{ |
44 |
api->SHPDestroyTree(self->tree); |
45 |
PyMem_DEL(self); |
46 |
} |
47 |
|
48 |
/* Return the repr of the wrapper */ |
49 |
static PyObject * |
50 |
shptree_repr(SHPTreeObject * self) |
51 |
{ |
52 |
char buf[1000]; |
53 |
sprintf(buf, "<SHPTree at %xul>", (unsigned long)self); |
54 |
return PyString_FromString(buf); |
55 |
} |
56 |
|
57 |
static PyObject * |
58 |
shptree_find_shapes(SHPTreeObject * self, PyObject * args) |
59 |
{ |
60 |
double min[4] = {0, 0, 0, 0}; |
61 |
double max[4] = {0, 0, 0, 0}; |
62 |
int count, idx; |
63 |
int * ids; |
64 |
PyObject * list = NULL, *temp = NULL; |
65 |
|
66 |
if (!PyArg_ParseTuple(args, "(dd)(dd)", min + 0, min + 1, |
67 |
max + 0, max + 1)) |
68 |
return NULL; |
69 |
|
70 |
ids = api->SHPTreeFindLikelyShapes(self->tree, min, max, &count); |
71 |
|
72 |
list = PyList_New(count); |
73 |
if (!list) |
74 |
goto fail; |
75 |
|
76 |
/* Turn the returned array of indices into a python list of ints. */ |
77 |
for (idx = 0; idx < count; idx++) |
78 |
{ |
79 |
temp = PyInt_FromLong(ids[idx]); |
80 |
if (!temp) |
81 |
goto fail; |
82 |
|
83 |
if (PyList_SetItem(list, idx, temp) == -1) |
84 |
{ |
85 |
/* temp's refcount has already be decreased. Set temp to |
86 |
* NULL so that the fail code doesn't do it again |
87 |
*/ |
88 |
temp = NULL; |
89 |
goto fail; |
90 |
} |
91 |
} |
92 |
|
93 |
free(ids); |
94 |
return list; |
95 |
|
96 |
fail: |
97 |
free(ids); |
98 |
Py_XDECREF(list); |
99 |
Py_XDECREF(temp); |
100 |
return NULL; |
101 |
} |
102 |
|
103 |
|
104 |
static struct PyMethodDef shptree_methods[] = { |
105 |
{"find_shapes", (PyCFunction)shptree_find_shapes, METH_VARARGS}, |
106 |
{NULL, NULL} |
107 |
}; |
108 |
|
109 |
static PyObject * |
110 |
shptree_getattr(PyObject * self, char * name) |
111 |
{ |
112 |
return Py_FindMethod(shptree_methods, self, name); |
113 |
} |
114 |
|
115 |
|
116 |
PyTypeObject SHPTreeType = { |
117 |
PyObject_HEAD_INIT(NULL) |
118 |
0, |
119 |
"SHPTree", |
120 |
sizeof(SHPTreeObject), |
121 |
0, |
122 |
(destructor)shptree_dealloc, /*tp_dealloc*/ |
123 |
(printfunc)NULL, /*tp_print*/ |
124 |
shptree_getattr, /*tp_getattr*/ |
125 |
0, /*tp_setattr*/ |
126 |
0, /*tp_compare*/ |
127 |
(reprfunc)shptree_repr, /*tp_repr*/ |
128 |
0, /*tp_as_number*/ |
129 |
0, /*tp_as_sequence*/ |
130 |
0, /*tp_as_mapping*/ |
131 |
0, /*tp_hash*/ |
132 |
0, /*tp_call*/ |
133 |
0, /*tp_str*/ |
134 |
0, /*tp_getattro*/ |
135 |
0, /*tp_setattro*/ |
136 |
0, /*tp_as_buffer*/ |
137 |
}; |
138 |
|
139 |
|
140 |
|
141 |
static PyObject * |
142 |
shptree_from_shapefile(PyObject * self, PyObject * args) |
143 |
{ |
144 |
SHPTree * tree; |
145 |
SHPHandle handle; |
146 |
PyObject * cobject; |
147 |
int dimension, max_depth; |
148 |
|
149 |
if (!PyArg_ParseTuple(args, "O!ii", &PyCObject_Type, &cobject, |
150 |
&dimension, &max_depth)) |
151 |
return NULL; |
152 |
|
153 |
handle = PyCObject_AsVoidPtr(cobject); |
154 |
|
155 |
tree = api->SHPCreateTree(handle, dimension, max_depth, NULL, NULL); |
156 |
|
157 |
/* apparently SHPCreateTree doesn't do any error checking, so we |
158 |
* have to assume that tree is valid at this point. */ |
159 |
return SHPTreeObject_FromSHPTree(tree); |
160 |
} |
161 |
|
162 |
|
163 |
static PyMethodDef module_functions[] = { |
164 |
{"SHPTree", shptree_from_shapefile, METH_VARARGS}, |
165 |
{ NULL, NULL } |
166 |
}; |
167 |
|
168 |
|
169 |
void |
170 |
initshptree() |
171 |
{ |
172 |
SHPTreeType.ob_type = &PyType_Type; |
173 |
|
174 |
Py_InitModule("shptree", module_functions); |
175 |
PYSHAPELIB_IMPORT_API(api); |
176 |
} |