11 |
} |
} |
12 |
PySHPObject; |
PySHPObject; |
13 |
|
|
14 |
|
/* allocator |
15 |
|
*/ |
16 |
static PyObject* PySHPObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds) |
static PyObject* PySHPObject_new(PyTypeObject* type, PyObject* args, PyObject* kwds) |
17 |
{ |
{ |
18 |
PySHPObject* self; |
PySHPObject* self; |
21 |
return (PyObject*) self; |
return (PyObject*) self; |
22 |
} |
} |
23 |
|
|
24 |
|
/* deallocator |
25 |
|
*/ |
26 |
static void PySHPObject_dealloc(PySHPObject* self) |
static void PySHPObject_dealloc(PySHPObject* self) |
27 |
{ |
{ |
28 |
SHPDestroyObject(self->shpObject); |
SHPDestroyObject(self->shpObject); |
76 |
} |
} |
77 |
|
|
78 |
/* parts and part_types have to have the same lengths */ |
/* parts and part_types have to have the same lengths */ |
79 |
|
if (part_type_list == Py_None) |
80 |
|
{ |
81 |
|
Py_DECREF(part_type_list); |
82 |
|
part_type_list = NULL; |
83 |
|
} |
84 |
if (part_type_list) |
if (part_type_list) |
85 |
{ |
{ |
86 |
if (!PySequence_Check(parts)) |
if (!PySequence_Check(parts)) |
212 |
/* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */ |
/* A multipart shape. Usual for SHPT_ARC and SHPT_POLYGON */ |
213 |
|
|
214 |
result = PyList_New(object->nParts); |
result = PyList_New(object->nParts); |
215 |
if (!result) |
if (!result) |
216 |
return NULL; |
return NULL; |
217 |
|
|
218 |
for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; |
for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++) |
219 |
part_idx++) |
{ |
220 |
{ |
if (part_idx < object->nParts - 1) |
221 |
if (part_idx < object->nParts - 1) |
length = (object->panPartStart[part_idx + 1] |
222 |
length = (object->panPartStart[part_idx + 1] |
- object->panPartStart[part_idx]); |
223 |
- object->panPartStart[part_idx]); |
else |
224 |
else |
length = object->nVertices - object->panPartStart[part_idx]; |
225 |
length = object->nVertices - object->panPartStart[part_idx]; |
|
226 |
|
part = build_vertex_list(object, vertex_idx, length); |
227 |
part = build_vertex_list(object, vertex_idx, length); |
if (!part) |
228 |
if (!part) |
goto fail; |
|
goto fail; |
|
229 |
|
|
230 |
if (PyList_SetItem(result, part_idx, part) < 0) |
if (PyList_SetItem(result, part_idx, part) < 0) |
231 |
goto fail; |
goto fail; |
232 |
|
|
233 |
vertex_idx += length; |
vertex_idx += length; |
234 |
} |
} |
235 |
} |
} |
236 |
else |
else |
237 |
{ |
{ |
238 |
/* only one part. usual for SHPT_POINT */ |
/* only one part. usual for SHPT_POINT */ |
239 |
result = build_vertex_list(object, 0, object->nVertices); |
result = build_vertex_list(object, 0, object->nVertices); |
240 |
} |
} |
241 |
|
|
242 |
return result; |
return result; |
260 |
|
|
261 |
list = PyList_New(length); |
list = PyList_New(length); |
262 |
if (!list) |
if (!list) |
263 |
return NULL; |
return NULL; |
264 |
|
|
265 |
for (i = 0; i < length; i++, index++) |
for (i = 0; i < length; i++, index++) |
266 |
{ |
{ |
267 |
vertex = Py_BuildValue("dd", object->padfX[index], |
vertex = Py_BuildValue("dd", object->padfX[index], |
268 |
object->padfY[index]); |
object->padfY[index]); |
269 |
if (!vertex) |
if (!vertex) |
270 |
goto fail; |
goto fail; |
271 |
if (PyList_SetItem(list, i, vertex) < 0) |
if (PyList_SetItem(list, i, vertex) < 0) |
272 |
goto fail; |
goto fail; |
273 |
} |
} |
274 |
|
|
275 |
return list; |
return list; |
280 |
return NULL; |
return NULL; |
281 |
} |
} |
282 |
|
|
283 |
|
|
284 |
|
|
285 |
|
static PyObject* PySHPObject_part_types(PySHPObject* self) |
286 |
|
{ |
287 |
|
int i; |
288 |
|
PyObject* result = NULL; |
289 |
|
SHPObject* object = self->shpObject; |
290 |
|
|
291 |
|
if (object->nParts == 0 || object->panPartType == 0) |
292 |
|
{ |
293 |
|
Py_RETURN_NONE; |
294 |
|
} |
295 |
|
|
296 |
|
result = PyTuple_New(object->nParts); |
297 |
|
if (!result) return NULL; |
298 |
|
|
299 |
|
for (i = 0; i < object->nParts; ++i) |
300 |
|
{ |
301 |
|
/* PyTuple_SetItem steals a reference */ |
302 |
|
PyObject* part_type = PyInt_FromLong((long)object->panPartType[i]); |
303 |
|
if (!part_type || PyTuple_SetItem(result, i, part_type) < 0) goto fail; |
304 |
|
} |
305 |
|
return result; |
306 |
|
|
307 |
|
fail: |
308 |
|
Py_DECREF(result); |
309 |
|
return NULL; |
310 |
|
} |
311 |
|
|
312 |
|
|
313 |
|
|
314 |
static PyObject* PySHPObject_type(PySHPObject* self, void* closure) |
static PyObject* PySHPObject_type(PySHPObject* self, void* closure) |
315 |
{ |
{ |
316 |
return PyInt_FromLong(self->shpObject->nSHPType); |
return PyInt_FromLong(self->shpObject->nSHPType); |
317 |
} |
} |
318 |
|
|
319 |
|
|
320 |
|
|
321 |
static PyObject* PySHPObject_id(PySHPObject* self, void* closure) |
static PyObject* PySHPObject_id(PySHPObject* self, void* closure) |
322 |
{ |
{ |
323 |
return PyInt_FromLong(self->shpObject->nShapeId); |
return PyInt_FromLong(self->shpObject->nShapeId); |
324 |
} |
} |
325 |
|
|
326 |
|
|
327 |
|
|
328 |
|
/* return a string that can be feeded to eval() to reconstruct the object, |
329 |
|
* assuming a proper context |
330 |
|
*/ |
331 |
|
static PyObject* PySHPObject_repr(PySHPObject* self) |
332 |
|
{ |
333 |
|
PyObject* format = NULL; |
334 |
|
PyObject* args = NULL; |
335 |
|
PyObject* result = NULL; |
336 |
|
|
337 |
|
format = PyString_FromString("shapelib.SHPObject(%i, %i, %s, %s)"); |
338 |
|
if (!format) return NULL; |
339 |
|
|
340 |
|
args = Py_BuildValue("iiNN", |
341 |
|
self->shpObject->nSHPType, |
342 |
|
self->shpObject->nShapeId, |
343 |
|
PySHPObject_vertices(self), |
344 |
|
PySHPObject_part_types(self)); |
345 |
|
if (!args) |
346 |
|
{ |
347 |
|
Py_DECREF(format); |
348 |
|
return NULL; |
349 |
|
} |
350 |
|
|
351 |
|
result = PyString_Format(format, args); |
352 |
|
Py_DECREF(args); |
353 |
|
Py_DECREF(format); |
354 |
|
return result; |
355 |
|
} |
356 |
|
|
357 |
|
|
358 |
|
|
359 |
static PyMethodDef PySHPObject_methods[] = |
static PyMethodDef PySHPObject_methods[] = |
360 |
{ |
{ |
361 |
{"extents", (PyCFunction)PySHPObject_extents, METH_NOARGS, NULL}, |
{"extents", (PyCFunction)PySHPObject_extents, METH_NOARGS, NULL}, |
362 |
{"vertices", (PyCFunction)PySHPObject_vertices, METH_NOARGS, NULL}, |
{"vertices", (PyCFunction)PySHPObject_vertices, METH_NOARGS, NULL}, |
363 |
|
{"part_types", (PyCFunction)PySHPObject_part_types, METH_NOARGS, NULL}, |
364 |
{NULL} |
{NULL} |
365 |
}; |
}; |
366 |
|
|
383 |
} |
} |
384 |
PyShapeFile; |
PyShapeFile; |
385 |
|
|
386 |
|
/* allocator |
387 |
|
*/ |
388 |
static PyObject* PyShapeFile_new(PyTypeObject* type, PyObject* args, PyObject* kwds) |
static PyObject* PyShapeFile_new(PyTypeObject* type, PyObject* args, PyObject* kwds) |
389 |
{ |
{ |
390 |
PyShapeFile* self; |
PyShapeFile* self; |
393 |
return (PyObject*) self; |
return (PyObject*) self; |
394 |
} |
} |
395 |
|
|
396 |
|
/* constructor |
397 |
|
*/ |
398 |
static int PyShapeFile_init(PyShapeFile* self, PyObject* args, PyObject* kwds) |
static int PyShapeFile_init(PyShapeFile* self, PyObject* args, PyObject* kwds) |
399 |
{ |
{ |
400 |
char* file; |
char* file; |
417 |
Py_RETURN_NONE; |
Py_RETURN_NONE; |
418 |
} |
} |
419 |
|
|
420 |
|
/* destructor |
421 |
|
*/ |
422 |
static void PyShapeFile_dealloc(PyShapeFile* self) |
static void PyShapeFile_dealloc(PyShapeFile* self) |
423 |
{ |
{ |
424 |
PyShapeFile_close(self); |
PyShapeFile_close(self); |
486 |
return PyCObject_FromVoidPtr(self->handle, NULL); |
return PyCObject_FromVoidPtr(self->handle, NULL); |
487 |
} |
} |
488 |
|
|
489 |
|
static PyObject* PyShapeFile_repr(PyShapeFile* self) |
490 |
|
{ |
491 |
|
/* TODO: it would be nice to do something like "shapelib.ShapeFile(filename, mode)" instead */ |
492 |
|
return PyString_FromFormat("<shapelib.ShapeFile object at %p>", self->handle); |
493 |
|
} |
494 |
|
|
495 |
static PyMethodDef PyShapeFile_methods[] = |
static PyMethodDef PyShapeFile_methods[] = |
496 |
{ |
{ |
497 |
{"close", (PyCFunction)PyShapeFile_close, METH_NOARGS, "close the shape file" }, |
{"close", (PyCFunction)PyShapeFile_close, METH_NOARGS, "close the shape file" }, |