[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