[Thuban-commits] r2743 - branches/WIP-pyshapelib-bramz/libraries/pyshapelib
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Mar 14 21:53:53 CET 2007
Author: bramz
Date: 2007-03-14 21:53:53 +0100 (Wed, 14 Mar 2007)
New Revision: 2743
Modified:
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
Log:
added support for shapetypes with Z and M values in shapelib
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-03-14 16:26:14 UTC (rev 2742)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-03-14 20:53:53 UTC (rev 2743)
@@ -1,5 +1,9 @@
2007-03-14 Bram de Greve <bram.degreve at intec.ugent.be>
+ * shapelibmodule.c: added support for shapetypes with Z and M values
+
+2007-03-14 Bram de Greve <bram.degreve at intec.ugent.be>
+
* dbflibmodule.c, dbflib.i: replaced dbflib.i by dbflibmodule.c to use
hand-crafted Python bindings instead of SWIG generated ones
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c 2007-03-14 16:26:14 UTC (rev 2742)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c 2007-03-14 20:53:53 UTC (rev 2743)
@@ -9,6 +9,45 @@
}
SHPObjectObject;
+enum {
+ vtXY,
+ vtXYM,
+ vtXYZM,
+ vtInvalid
+} VertexType;
+
+int determine_vertex_type(int shape_type, int* has_z, int* has_m)
+{
+ switch (shape_type)
+ {
+ case SHPT_POINT:
+ case SHPT_ARC:
+ case SHPT_POLYGON:
+ case SHPT_MULTIPOINT:
+ if (has_z) *has_z = 0;
+ if (has_m) *has_m = 0;
+ return vtXY;
+ case SHPT_POINTM:
+ case SHPT_ARCM:
+ case SHPT_POLYGONM:
+ case SHPT_MULTIPOINTM:
+ if (has_z) *has_z = 0;
+ if (has_m) *has_m = 1;
+ case SHPT_POINTZ:
+ case SHPT_ARCZ:
+ case SHPT_POLYGONZ:
+ case SHPT_MULTIPOINTZ:
+ case SHPT_MULTIPATCH:
+ if (has_z) *has_z = 1;
+ if (has_m) *has_m = 1;
+ return vtXYZM;
+ default:
+ if (has_z) *has_z = 0;
+ if (has_m) *has_m = 0;
+ return vtInvalid;
+ }
+}
+
/* allocator
*/
static PyObject* shpobject_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
@@ -47,11 +86,18 @@
double* xs = NULL;
double* ys = NULL;
+ double* zs = NULL;
+ double* ms = NULL;
int* part_starts = NULL;
int* part_types = NULL;
+ PyObject* part;
+ int vertex_type;
+ int has_z;
+ int has_m;
+
int i;
- int return_code = -1;
+ int ok, return_code = -1;
/* first, unpack parameters */
if (kwds != NULL && PyDict_Size(kwds) > 0)
@@ -61,6 +107,7 @@
}
if (!PyArg_ParseTuple(args, "iiO|O", &type, &id, &parts, &part_type_list)) return -1;
+ /* check parts */
if (!PySequence_Check(parts))
{
PyErr_SetString(PyExc_TypeError, "parts is not a sequence");
@@ -107,14 +154,19 @@
num_vertices += PySequence_Length(part);
Py_DECREF(part);
}
+
+
+ vertex_type = determine_vertex_type(type, &has_z, &has_m);
/* allocate the memory for the various arrays and check for memory errors */
xs = malloc(num_vertices * sizeof(double));
ys = malloc(num_vertices * sizeof(double));
+ zs = has_z ? malloc(num_vertices * sizeof(double)) : NULL;
+ ms = has_m ? malloc(num_vertices * sizeof(double)) : NULL;
part_starts = malloc(num_parts * sizeof(int));
part_types = part_type_list ? malloc(num_parts * sizeof(int)) : 0;
- if (!xs || !ys || !part_starts || (part_type_list && !part_types))
+ if (!xs || !ys || (has_z && !zs) || (has_m && !ms) || !part_starts || (part_type_list && !part_types))
{
PyErr_NoMemory();
goto exit;
@@ -142,32 +194,49 @@
{
int j, length;
- PyObject* part = PySequence_ITEM(parts, i);
+ part = PySequence_ITEM(parts, i);
length = PySequence_Length(part);
+ if (length < 0) goto exit;
part_starts[i] = part_start;
for (j = 0; j < length; ++j)
{
PyObject* vertex = PySequence_ITEM(part, j);
- if (!PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j))
+ switch (vertex_type)
{
- PyErr_SetString(PyExc_TypeError, "at least one part contains an vertex that's not a tuple of two doubles");
- Py_DECREF(vertex);
- Py_DECREF(part);
+ case vtXY:
+ ok = PyArg_ParseTuple(vertex, "dd", xs + part_start + j, ys + part_start + j);
+ break;
+ case vtXYM:
+ ok = PyArg_ParseTuple(vertex, "ddd", 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", xs + part_start + j, ys + part_start + j, zs + part_start + j,
+ ms + part_start + j);
+ break;
+ }
+ Py_DECREF(vertex);
+ if (!ok)
+ {
+ PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
goto exit;
}
- Py_DECREF(vertex);
}
Py_DECREF(part);
+ part = NULL;
part_start += length;
}
- self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, NULL, NULL);
+ self->shpObject = SHPCreateObject(type, id, num_parts, part_starts, part_types, num_vertices, xs, ys, zs, ms);
return_code = 0;
exit:
+ Py_XDECREF(part);
free(xs);
free(ys);
+ free(zs);
+ free(ms);
free(part_starts);
free(part_types);
return return_code;
@@ -195,7 +264,7 @@
* tuples.
*/
-static PyObject* build_vertex_list(SHPObject *object, int index, int length);
+static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type);
static PyObject* shpobject_vertices(SHPObjectObject* self)
{
@@ -203,7 +272,10 @@
PyObject *part = NULL;
int part_idx, vertex_idx;
int length = 0;
+ int vertex_type;
+
SHPObject* object = self->shpObject;
+ vertex_type = determine_vertex_type(object->nSHPType, NULL, NULL);
if (object->nParts > 0)
{
@@ -216,17 +288,15 @@
for (part_idx = 0, vertex_idx = 0; part_idx < object->nParts; part_idx++)
{
if (part_idx < object->nParts - 1)
- length = (object->panPartStart[part_idx + 1]
- - object->panPartStart[part_idx]);
+ length = (object->panPartStart[part_idx + 1]
+ - object->panPartStart[part_idx]);
else
- length = object->nVertices - object->panPartStart[part_idx];
+ length = object->nVertices - object->panPartStart[part_idx];
- part = build_vertex_list(object, vertex_idx, length);
- if (!part)
- goto fail;
+ part = build_vertex_list(object, vertex_idx, length, vertex_type);
+ if (!part) goto fail;
- if (PyList_SetItem(result, part_idx, part) < 0)
- goto fail;
+ if (PyList_SetItem(result, part_idx, part) < 0) goto fail;
vertex_idx += length;
}
@@ -234,7 +304,7 @@
else
{
/* only one part. usual for SHPT_POINT */
- result = build_vertex_list(object, 0, object->nVertices);
+ result = build_vertex_list(object, 0, object->nVertices, vertex_type);
}
return result;
@@ -250,7 +320,7 @@
* index as a Python-list of tuples. Helper function for
* SHPObject_vertices.
*/
-static PyObject* build_vertex_list(SHPObject *object, int index, int length)
+static PyObject* build_vertex_list(SHPObject *object, int index, int length, int vertex_type)
{
int i;
PyObject * list;
@@ -262,18 +332,28 @@
for (i = 0; i < length; i++, index++)
{
- vertex = Py_BuildValue("dd", object->padfX[index],
- object->padfY[index]);
- if (!vertex)
+ switch (vertex_type)
+ {
+ case vtXY:
+ vertex = Py_BuildValue("dd", object->padfX[index], object->padfY[index]);
+ break;
+ case vtXYM:
+ vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index],
+ object->padfM[index]);
+ case vtXYZM:
+ vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index],
+ object->padfZ[index], object->padfM[index]);
+ break;
+ default:
goto fail;
- if (PyList_SetItem(list, i, vertex) < 0)
- goto fail;
+ }
+
+ if (!vertex || PyList_SetItem(list, i, vertex) < 0) goto fail;
}
-
+
return list;
fail:
- Py_XDECREF(vertex);
Py_DECREF(list);
return NULL;
}
More information about the Thuban-commits
mailing list