67 |
self->ob_type->tp_free((PyObject*)self); |
self->ob_type->tp_free((PyObject*)self); |
68 |
} |
} |
69 |
|
|
70 |
|
static int unpack_vertex(PyObject* vertex, int vertex_type, |
71 |
|
double* xs, double* ys, double* zs, double* ms, int offset); |
72 |
|
|
73 |
/* The constructor of SHPObject. parts is a list of lists of tuples |
/* The constructor of SHPObject. parts is a list of lists of tuples |
74 |
* describing the parts and their vertices just likethe output of the |
* describing the parts and their vertices just likethe output of the |
75 |
* vertices() method. part_type_list is the list of part-types and may |
* vertices() method. part_type_list is the list of part-types and may |
100 |
int has_m; |
int has_m; |
101 |
|
|
102 |
int i; |
int i; |
103 |
int ok, return_code = -1; |
int return_code = -1; |
104 |
|
|
105 |
/* first, unpack parameters */ |
/* first, unpack parameters */ |
106 |
if (kwds != NULL && PyDict_Size(kwds) > 0) |
if (kwds != NULL && PyDict_Size(kwds) > 0) |
205 |
for (j = 0; j < length; ++j) |
for (j = 0; j < length; ++j) |
206 |
{ |
{ |
207 |
PyObject* vertex = PySequence_ITEM(part, j); |
PyObject* vertex = PySequence_ITEM(part, j); |
208 |
switch (vertex_type) |
if (!unpack_vertex(vertex, vertex_type, xs, ys, zs, ms, part_start + j)) |
|
{ |
|
|
case vtXY: |
|
|
ok = PyArg_ParseTuple(vertex, "dd:__init__", xs + part_start + j, ys + part_start + j); |
|
|
break; |
|
|
case vtXYM: |
|
|
ok = PyArg_ParseTuple(vertex, "ddd:__init__", xs + part_start + j, ys + part_start + j, ms + part_start + j); |
|
|
break; |
|
|
case vtXYZM: |
|
|
ms[part_start + j] = 0.; |
|
|
ok = PyArg_ParseTuple(vertex, "ddd|d:__init__", xs + part_start + j, ys + part_start + j, zs + part_start + j, |
|
|
ms + part_start + j); |
|
|
break; |
|
|
} |
|
|
Py_DECREF(vertex); |
|
|
if (!ok) |
|
209 |
{ |
{ |
210 |
|
Py_DECREF(vertex); |
211 |
PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format"); |
PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format"); |
212 |
goto exit; |
goto exit; |
213 |
} |
} |
214 |
|
Py_DECREF(vertex); |
215 |
} |
} |
216 |
Py_DECREF(part); |
Py_DECREF(part); |
217 |
part = NULL; |
part = NULL; |
232 |
return return_code; |
return return_code; |
233 |
} |
} |
234 |
|
|
235 |
|
/* helper for shpobject_init. Unpacks vertices |
236 |
|
*/ |
237 |
|
static int unpack_vertex(PyObject* vertex, int vertex_type, |
238 |
|
double* xs, double* ys, double* zs, double* ms, int offset) |
239 |
|
{ |
240 |
|
int ok; |
241 |
|
PyObject* m_object; |
242 |
|
PyObject *err_type, *err_value, *err_traceback; |
243 |
|
|
244 |
|
switch (vertex_type) |
245 |
|
{ |
246 |
|
case vtXY: |
247 |
|
return PyArg_ParseTuple(vertex, "dd:__init__", xs + offset, ys + offset); |
248 |
|
|
249 |
|
case vtXYM: |
250 |
|
ms[offset] = PYSHAPELIB_NO_DATA; |
251 |
|
ok = PyArg_ParseTuple(vertex, "dd|d:__init__", xs + offset, ys + offset, ms + offset); |
252 |
|
if (!ok) |
253 |
|
{ |
254 |
|
/* maybe they specified None as M value */ |
255 |
|
PyErr_Fetch(&err_type, &err_value, &err_traceback); |
256 |
|
ok = PyArg_ParseTuple(vertex, "ddO:__init__", xs + offset, ys + offset, &m_object); |
257 |
|
if (ok && m_object == Py_None) |
258 |
|
{ |
259 |
|
Py_XDECREF(err_type); |
260 |
|
Py_XDECREF(err_value); |
261 |
|
Py_XDECREF(err_traceback); |
262 |
|
} |
263 |
|
else |
264 |
|
{ |
265 |
|
PyErr_Restore(err_type, err_value, err_traceback); |
266 |
|
} |
267 |
|
} |
268 |
|
return ok; |
269 |
|
|
270 |
|
case vtXYZM: |
271 |
|
zs[offset] = 0.; |
272 |
|
ms[offset] = PYSHAPELIB_NO_DATA; |
273 |
|
ok = PyArg_ParseTuple(vertex, "dd|dd:__init__", xs + offset, ys + offset, |
274 |
|
zs + offset, ms + offset); |
275 |
|
if (!ok) |
276 |
|
{ |
277 |
|
/* maybe they specified None as M value */ |
278 |
|
PyErr_Fetch(&err_type, &err_value, &err_traceback); |
279 |
|
ok = PyArg_ParseTuple(vertex, "dddO:__init__", xs + offset, ys + offset, |
280 |
|
zs + offset, &m_object); |
281 |
|
if (ok && m_object == Py_None) |
282 |
|
{ |
283 |
|
Py_XDECREF(err_type); |
284 |
|
Py_XDECREF(err_value); |
285 |
|
Py_XDECREF(err_traceback); |
286 |
|
} |
287 |
|
else |
288 |
|
{ |
289 |
|
PyErr_Restore(err_type, err_value, err_traceback); |
290 |
|
} |
291 |
|
} |
292 |
|
return ok; |
293 |
|
|
294 |
|
default: |
295 |
|
PyErr_SetString(PyExc_NotImplementedError, "vertex type not implemented"); |
296 |
|
return 0; |
297 |
|
} |
298 |
|
} |
299 |
|
|
300 |
/* |
/* |
301 |
* The extents() method of SHPObject. |
* The extents() method of SHPObject. |
302 |
* |
* |
395 |
case vtXYM: |
case vtXYM: |
396 |
vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index], |
vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index], |
397 |
object->padfM[index]); |
object->padfM[index]); |
398 |
|
break; |
399 |
case vtXYZM: |
case vtXYZM: |
400 |
vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index], |
vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index], |
401 |
object->padfZ[index], object->padfM[index]); |
object->padfZ[index], object->padfM[index]); |
493 |
static struct PyMethodDef shpobject_methods[] = |
static struct PyMethodDef shpobject_methods[] = |
494 |
{ |
{ |
495 |
{"extents", (PyCFunction)shpobject_extents, METH_NOARGS, |
{"extents", (PyCFunction)shpobject_extents, METH_NOARGS, |
496 |
"extents()\n" |
"extents() -> ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n" |
497 |
"returns ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)), the 4D bounding box of the SHPObject"}, |
"returns the 4D bounding box of the SHPObject"}, |
498 |
{"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS, |
{"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS, |
499 |
"vertices()\n" |
"vertices() -> [[(x, y, ...), ...], ...]\n\n" |
500 |
"returns [[(x, y, ...), ...], ...], a list of object parts, where each part is again a list of vertices.\n" |
"Returns a list of object parts, where each part is again a list of vertices. " |
501 |
"each vertex is a tuple of two to four doubles, depending on the object type."}, |
"Each vertex is a tuple of two to four doubles, depending on the object type."}, |
502 |
{"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS, |
{"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS, |
503 |
"part_types()\n" |
"part_types() -> tuple\n\n" |
504 |
"returns a tuple of integers, each integer indicating the type of the corresponding part in vertices()"}, |
"returns a tuple of integers, each integer indicating the type of the " |
505 |
|
"corresponding part in vertices()"}, |
506 |
{NULL} |
{NULL} |
507 |
}; |
}; |
508 |
|
|
547 |
*/ |
*/ |
548 |
static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds) |
static int shapefile_init(ShapeFileObject* self, PyObject* args, PyObject* kwds) |
549 |
{ |
{ |
550 |
char* file; |
char* file = NULL; |
551 |
char* mode = "rb"; |
char* mode = "rb"; |
552 |
if (kwds != NULL && PyDict_Size(kwds) > 0) |
static char *kwlist[] = {"name", "mode", NULL}; |
553 |
|
|
554 |
|
SHPClose(self->handle); |
555 |
|
self->handle = NULL; |
556 |
|
|
557 |
|
#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES) |
558 |
|
if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ |
559 |
|
PyObject *wfile; |
560 |
|
if (PyArg_ParseTupleAndKeywords(args, kwds, "U|s:ShapeFile", kwlist, &wfile, &mode)) |
561 |
|
{ |
562 |
|
PyObject *wmode = PyUnicode_DecodeASCII(mode, strlen(mode), NULL); |
563 |
|
if (!wmode) return -1; |
564 |
|
self->handle = SHPOpenW(PyUnicode_AS_UNICODE(wfile), PyUnicode_AS_UNICODE(wmode)); |
565 |
|
Py_DECREF(wmode); |
566 |
|
if (!self->handle) |
567 |
|
{ |
568 |
|
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile); |
569 |
|
return -1; |
570 |
|
} |
571 |
|
} |
572 |
|
else |
573 |
|
{ |
574 |
|
/* Drop the argument parsing error as narrow |
575 |
|
strings are also valid. */ |
576 |
|
PyErr_Clear(); |
577 |
|
} |
578 |
|
} |
579 |
|
#endif |
580 |
|
|
581 |
|
if (!self->handle) |
582 |
{ |
{ |
583 |
PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments"); |
if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:ShapeFile", kwlist, |
584 |
return -1; |
Py_FileSystemDefaultEncoding, &file, &mode)) return -1; |
585 |
|
self->handle = SHPOpen(file, mode); |
586 |
|
|
587 |
|
if (!self->handle) |
588 |
|
{ |
589 |
|
PyErr_SetFromErrnoWithFilename(PyExc_IOError, file); |
590 |
|
PyMem_Free(file); |
591 |
|
return -1; |
592 |
|
} |
593 |
|
|
594 |
|
PyMem_Free(file); |
595 |
} |
} |
596 |
if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1; |
|
597 |
|
return 0; |
|
self->handle = SHPOpen(file, mode); |
|
|
return self->handle ? 0 : -1; |
|
598 |
} |
} |
599 |
|
|
600 |
|
|
601 |
|
|
602 |
static PyObject* shapefile_close(ShapeFileObject* self) |
static PyObject* shapefile_close(ShapeFileObject* self) |
603 |
{ |
{ |
604 |
SHPClose(self->handle); |
SHPClose(self->handle); |
606 |
Py_RETURN_NONE; |
Py_RETURN_NONE; |
607 |
} |
} |
608 |
|
|
609 |
|
|
610 |
|
|
611 |
static PyObject* shapefile_info(ShapeFileObject* self) |
static PyObject* shapefile_info(ShapeFileObject* self) |
612 |
{ |
{ |
613 |
SHPHandle handle = self->handle; |
SHPHandle handle = self->handle; |
617 |
handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]); |
handle->adBoundsMax[0], handle->adBoundsMax[1], handle->adBoundsMax[2], handle->adBoundsMax[3]); |
618 |
} |
} |
619 |
|
|
620 |
|
|
621 |
|
|
622 |
static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args) |
static PyObject* shapefile_read_object(ShapeFileObject* self, PyObject* args) |
623 |
{ |
{ |
624 |
int index; |
int index; |
644 |
return (PyObject*) result; |
return (PyObject*) result; |
645 |
} |
} |
646 |
|
|
647 |
|
|
648 |
|
|
649 |
static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args) |
static PyObject* shapefile_write_object(ShapeFileObject* self, PyObject* args) |
650 |
{ |
{ |
651 |
int index, result; |
int index, result; |
682 |
static struct PyMethodDef shapefile_methods[] = |
static struct PyMethodDef shapefile_methods[] = |
683 |
{ |
{ |
684 |
{"close", (PyCFunction)shapefile_close, METH_NOARGS, |
{"close", (PyCFunction)shapefile_close, METH_NOARGS, |
685 |
"close()\n" |
"close() -> None\n\n" |
686 |
"close the shape file" }, |
"close the shape file" }, |
687 |
{"info", (PyCFunction)shapefile_info, METH_NOARGS, |
{"info", (PyCFunction)shapefile_info, METH_NOARGS, |
688 |
"info()\n" |
"info() -> (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n" |
689 |
"returns (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)) with:\n" |
"returns info about ShapeFile with:\n" |
690 |
"-num_shapes: the number of the objects in the file\n" |
"- num_shapes: the number of the objects in the file\n" |
691 |
"-type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n" |
"- type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n" |
692 |
"-(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" }, |
"- (x_min, ...), (x_max, ...): 4D bounding box of the data in the shape file" }, |
693 |
{"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS, |
{"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS, |
694 |
"read_object(id)\n" |
"read_object(id) -> SHPObject\n\n" |
695 |
"Return object indexed by id" }, |
"Returns shape indexed by id" }, |
696 |
{"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS, |
{"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS, |
697 |
"write_object(id, object)\n" |
"write_object(id, object) -> id\n\n" |
698 |
"Write an object at index id.\n" |
"Write an object at index id, and returns id." |
699 |
"If id == -1, the object is appended at the end of the shape file"}, |
"If id == -1, the object is appended at the end of the shape file."}, |
700 |
{"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS, |
{"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS, |
701 |
"cobject()\n" |
"cobject() -> CObject\n\n" |
702 |
"Return the shapelib SHPHandle as a Python CObject"}, |
"Return the shapelib SHPHandle as a Python CObject"}, |
703 |
{NULL} |
{NULL} |
704 |
}; |
}; |
722 |
char* file; |
char* file; |
723 |
int type; |
int type; |
724 |
ShapeFileObject* result; |
ShapeFileObject* result; |
725 |
|
SHPHandle handle = NULL; |
726 |
|
int wideargument = 0; |
727 |
|
|
728 |
|
#if defined(SHPAPI_HAS_WIDE) && defined(Py_WIN_WIDE_FILENAMES) |
729 |
|
if (GetVersion() < 0x80000000) { /* On NT, so wide API available */ |
730 |
|
PyObject *wfile; |
731 |
|
if (PyArg_ParseTuple(args, "Ui:create", &wfile, &type)) |
732 |
|
{ |
733 |
|
wideargument = 1; |
734 |
|
handle = SHPCreateW(PyUnicode_AS_UNICODE(wfile), type); |
735 |
|
if (!handle) |
736 |
|
{ |
737 |
|
PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, wfile); |
738 |
|
return NULL; |
739 |
|
} |
740 |
|
} |
741 |
|
else |
742 |
|
{ |
743 |
|
/* Drop the argument parsing error as narrow |
744 |
|
strings are also valid. */ |
745 |
|
PyErr_Clear(); |
746 |
|
} |
747 |
|
} |
748 |
|
#endif |
749 |
|
|
750 |
if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL; |
if (!handle) |
751 |
|
{ |
752 |
|
if (!PyArg_ParseTuple(args, "eti:create", Py_FileSystemDefaultEncoding, &file, &type)) return NULL; |
753 |
|
handle = SHPCreate(file, type); |
754 |
|
if (!handle) |
755 |
|
{ |
756 |
|
PyErr_SetFromErrnoWithFilename(PyExc_IOError, file); |
757 |
|
PyMem_Free(file); |
758 |
|
return NULL; |
759 |
|
} |
760 |
|
PyMem_Free(file); |
761 |
|
} |
762 |
|
|
763 |
result = PyObject_New(ShapeFileObject, &ShapeFileType); |
result = PyObject_New(ShapeFileObject, &ShapeFileType); |
764 |
if (!result) |
if (!result) |
765 |
{ |
{ |
766 |
|
SHPClose(handle); |
767 |
return PyErr_NoMemory(); |
return PyErr_NoMemory(); |
768 |
} |
} |
769 |
|
|
770 |
result->handle = SHPCreate(file, type); |
result->handle = handle; |
|
if (!result->handle) |
|
|
{ |
|
|
PyObject_Del((PyObject*)result); |
|
|
PyErr_SetString(PyExc_RuntimeError, "Failed to create ShapeFile"); |
|
|
return NULL; |
|
|
} |
|
|
|
|
771 |
return (PyObject*) result; |
return (PyObject*) result; |
772 |
} |
} |
773 |
|
|
802 |
static struct PyMethodDef shapelib_methods[] = |
static struct PyMethodDef shapelib_methods[] = |
803 |
{ |
{ |
804 |
{"open", (PyCFunction)shapelib_open, METH_VARARGS, |
{"open", (PyCFunction)shapelib_open, METH_VARARGS, |
805 |
"open(filename [, mode='rb'])\n" |
"open(name [, mode='rb']) -> ShapeFile\n\n" |
806 |
"open a ShapeFile" }, |
"opens a ShapeFile" }, |
807 |
{"create", (PyCFunction)shapelib_create, METH_VARARGS, |
{"create", (PyCFunction)shapelib_create, METH_VARARGS, |
808 |
"create(filename, type)\n" |
"create(name, type) -> ShapeFile\n\n" |
809 |
"create a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" }, |
"creates a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" }, |
810 |
{"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, |
{"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS, |
811 |
"c_api()\n" |
"c_api() -> CObject\n\n" |
812 |
"get C API of shapelib" }, |
"get C API of shapelib as a CObject" }, |
813 |
{"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, |
{"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS, |
814 |
"type_name(type)\n" |
"type_name(type) -> string\n\n" |
815 |
"return type as string" }, |
"return type as string" }, |
816 |
{"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, |
{"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS, |
817 |
"part_type_name(part_type)\n" |
"part_type_name(part_type) -> string\n\n" |
818 |
"return part type as string" }, |
"return part type as string" }, |
819 |
{NULL} |
{NULL} |
820 |
}; |
}; |