1 |
jan |
1611 |
/* 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 |
|
|
} |