[Thuban-commits] r2745 - branches/WIP-pyshapelib-bramz/libraries/pyshapelib
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Mar 15 23:27:02 CET 2007
Author: bramz
Date: 2007-03-15 23:27:02 +0100 (Thu, 15 Mar 2007)
New Revision: 2745
Modified:
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pytest.py
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shptreemodule.c
Log:
Added FTLogical support to dbflib. Accept None as no-data for M values. Added name and mode keywords to mimic Python's file behaviour where appropriate. Added unpack_vertex() to lift some load of shpobject_init().
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/ChangeLog 2007-03-15 22:27:02 UTC (rev 2745)
@@ -1,5 +1,31 @@
2007-03-15 Bram de Greve <bram.degreve at intec.ugent.be>
+ * shapelib.c: When creating measured shapes (XYM), treat M value
+ value as optional (defaults to zero). Similar for
+ 3D shapes (XYZM), threat both the Z and M value as options
+ (both default to zero). When M values are to be given,
+ None is accepted as "no-data" value, and is stored as zero
+ (ESRI shapefile specs define any M value smaller than 1e-38
+ as no-data). Added an unpack_vertex() function to lift some
+ of the load of shpobject_init. Fixed a missing break and
+ PyMem_Free in build_vertex_list(), shapefile_init() and
+ shapelib_create().
+
+ * dbflibmodule.c: Added support for the FTLogical field type.
+
+ * shapelibmodule.c, dbflibmodule.c: Added 'name' and 'mode'
+ keywords for ShapeFile and DBFFile constructors and the module's
+ open() function, similiar to Python's file(). Reformatted
+ the doc strings to have a standard look and feel when parsed
+ through pydoc.
+
+ * shapelib_common.h: added no-data constants.
+
+ * pytest.py: Added tests for multipatch shapefile with XYZM values.
+ Added tests for FTLogical field.
+
+2007-03-15 Bram de Greve <bram.degreve at intec.ugent.be>
+
* shapelibmodule.c, dbflibmodule.c: added some Unicode support for the
filenames (no internal encoding for DBFFile yet). It now should similar
Unicode support Python's file() (concerning the filename, that is).
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/dbflibmodule.c 2007-03-15 22:27:02 UTC (rev 2745)
@@ -38,13 +38,9 @@
{
char* file;
char* mode = "rb";
- if (kwds != NULL && PyDict_Size(kwds) > 0)
- {
- PyErr_Format(PyExc_TypeError, "dbflib.DBFFile.__init__ takes no keyword arguments");
- return -1;
- }
-
- if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
+ static char *kwlist[] = {"name", "mode", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:__init__", kwlist,
+ Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
self->handle = DBFOpen(file, mode);
PyMem_Free(file);
@@ -142,26 +138,38 @@
{
case FTString:
temp = DBFReadStringAttribute(handle, record, field);
- if (!temp)
- {
- PyErr_Format(PyExc_IOError,
- "Can't read value for row %d column %d",
- record, field);
- return NULL;
- }
- return PyString_FromString(temp);
+ if (temp) return PyString_FromString(temp);
case FTInteger:
return PyInt_FromLong((long)DBFReadIntegerAttribute(handle, record, field));
case FTDouble:
return PyFloat_FromDouble(DBFReadDoubleAttribute(handle, record, field));
+
+ case FTLogical:
+ temp = DBFReadLogicalAttribute(handle, record, field);
+ if (temp)
+ {
+ switch (temp[0])
+ {
+ case 'F':
+ case 'N':
+ Py_RETURN_FALSE;
+ case 'T':
+ case 'Y':
+ Py_RETURN_TRUE;
+ }
+ }
+ break;
default:
PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
return NULL;
}
}
+
+ PyErr_Format(PyExc_IOError, "Can't read value for row %d column %d", record, field);
+ return NULL;
}
@@ -247,16 +255,11 @@
char * string_value;
int int_value;
double double_value;
+ int logical_value;
if (value == Py_None)
{
- if (!DBFWriteNULLAttribute(handle, record, field))
- {
- PyErr_Format(PyExc_IOError,
- "can't write NULL field %d of record %d",
- field, record);
- return 0;
- }
+ if (DBFWriteNULLAttribute(handle, record, field)) return 1;
}
else
{
@@ -265,38 +268,26 @@
case FTString:
string_value = PyString_AsString(value);
if (!string_value) return 0;
- if (!DBFWriteStringAttribute(handle, record, field, string_value))
- {
- PyErr_Format(PyExc_IOError,
- "can't write field %d of record %d",
- field, record);
- return 0;
- }
+ if (DBFWriteStringAttribute(handle, record, field, string_value)) return 1;
break;
case FTInteger:
int_value = PyInt_AsLong(value);
if (int_value == -1 && PyErr_Occurred()) return 0;
- if (!DBFWriteIntegerAttribute(handle, record, field, int_value))
- {
- PyErr_Format(PyExc_IOError,
- "can't write field %d of record %d",
- field, record);
- return 0;
- }
+ if (DBFWriteIntegerAttribute(handle, record, field, int_value)) return 1;
break;
case FTDouble:
double_value = PyFloat_AsDouble(value);
if (double_value == -1 && PyErr_Occurred()) return 0;
- if (!DBFWriteDoubleAttribute(handle, record, field, double_value))
- {
- PyErr_Format(PyExc_IOError,
- "can't write field %d of record %d",
- field, record);
- return 0;
- }
+ if (DBFWriteDoubleAttribute(handle, record, field, double_value)) return 1;
break;
+
+ case FTLogical:
+ logical_value = PyObject_IsTrue(value);
+ if (logical_value == -1) return 0;
+ if (DBFWriteLogicalAttribute(handle, record, field, logical_value ? 'T' : 'F')) return 1;
+ break;
default:
PyErr_Format(PyExc_TypeError, "Invalid field data type %d", type);
@@ -304,7 +295,8 @@
}
}
- return 1;
+ PyErr_Format(PyExc_IOError, "can't write field %d of record %d", field, record);
+ return 0;
}
@@ -422,45 +414,47 @@
static struct PyMethodDef dbffile_methods[] =
{
{"close", (PyCFunction)dbffile_close, METH_NOARGS,
- "close()\n"
- "close DBFFile"},
+ "close() -> None\n\n"
+ "closes DBFFile"},
{"field_count", (PyCFunction)dbffile_field_count, METH_NOARGS,
- "field_count()\n"
+ "field_count() -> integer\n\n"
"returns number of fields currently defined"},
{"record_count", (PyCFunction)dbffile_record_count, METH_NOARGS,
- "record_count()\n"
+ "record_count() -> integer\n\n"
"returns number of records that currently exist"},
{"field_info", (PyCFunction)dbffile_field_info, METH_VARARGS,
- "field_info(field_index)\n"
- "returns info of a field as a tuple (type, name, width, decimals) with:\n"
- "-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"
- "-name: the name of the field as a string\n"
- "-width: the width of the field as a number of characters\n"
- "-decimals: the number of decimal digits" },
+ "field_info(field_index) -> (type, name, width, decimals)\n\n"
+ "returns info of a field as a tuple with:\n"
+ "- type: the type of the field corresponding to the integer value of one "
+ " of the constants FTString, FTInteger, ...\n"
+ "- name: the name of the field as a string\n"
+ "- width: the width of the field as a number of characters\n"
+ "- decimals: the number of decimal digits" },
{"add_field", (PyCFunction)dbffile_add_field, METH_VARARGS,
- "add_field(type, name, width, decimals)\n"
+ "add_field(type, name, width, decimals) -> field_index\n\n"
"adds a new field and returns field index if successful\n"
- "-type: the type of the field corresponding to the integer value of one of the constants FTString, FTInteger, ...\n"
- "-name: the name of the field as a string\n"
- "-width: the width of the field as a number of characters\n"
- "-decimals: the number of decimal digits" },
+ "- type: the type of the field corresponding to the integer value of one "
+ " of the constants FTString, FTInteger, ...\n"
+ "- name: the name of the field as a string\n"
+ "- width: the width of the field as a number of characters\n"
+ "- decimals: the number of decimal digits" },
{"read_attribute", (PyCFunction)dbffile_read_attribute, METH_VARARGS,
- "read_attribute(record_index, field_index)\n"
- "return the value of one field of a record"},
+ "read_attribute(record_index, field_index) -> value\n\n"
+ "returns the value of one field of a record"},
{"read_record", (PyCFunction)dbffile_read_record, METH_VARARGS,
- "read_record(record_index)\n"
- "return an entire record as a dict of field names and values"},
+ "read_record(record_index) -> dict\n\n"
+ "returns an entire record as a dictionary of field names and values"},
{"write_field", (PyCFunction)dbffile_write_field, METH_VARARGS,
"write_field(record_index, field_index, new_value)\n"
- "write a single field of a record"},
+ "writes a single field of a record"},
{"write_record", (PyCFunction)dbffile_write_record, METH_VARARGS,
- "write_record(record_index, record)\n"
- "write an entire record as a dict or a sequence\n"
- "record can either be a dictionary in which case the keys are used as field names, "
+ "write_record(record_index, record) -> record_index\n\n"
+ "Writes an entire record as a dict or a sequence, and return index of record\n"
+ "Record can either be a dictionary in which case the keys are used as field names, "
"or a sequence that must have an item for every field (length = field_count())"},
#if HAVE_UPDATE_HEADER
{"commit", (PyCFunction)dbffile_read_record, METH_NOARGS,
- "commit()"},
+ "commit() -> None"},
#endif
{NULL}
};
@@ -516,10 +510,10 @@
static struct PyMethodDef dbflib_methods[] =
{
{"open", (PyCFunction)dbflib_open, METH_VARARGS,
- "open(filename [, mode])\n"
- "open a DBFFile" },
+ "open(name [, mode]) -> DBFFile\n\n"
+ "opens a DBFFile" },
{"create", (PyCFunction)dbflib_create, METH_VARARGS,
- "create(filename)\n"
+ "create(name) -> DBFFile\n\n"
"create a DBFFile" },
{NULL}
};
@@ -536,6 +530,7 @@
PYSHAPELIB_ADD_CONSTANT(FTString);
PYSHAPELIB_ADD_CONSTANT(FTInteger);
PYSHAPELIB_ADD_CONSTANT(FTDouble);
+ PYSHAPELIB_ADD_CONSTANT(FTLogical);
PYSHAPELIB_ADD_CONSTANT(FTInvalid);
PyModule_AddIntConstant(module, "_have_commit", HAVE_UPDATE_HEADER);
}
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pyshapelib_common.h 2007-03-15 22:27:02 UTC (rev 2745)
@@ -72,4 +72,7 @@
PyModule_AddObject(module, name, (PyObject*)&type); \
}
+#define PYSHAPELIB_NO_DATA_LIMIT 1e-38
+#define PYSHAPELIB_NO_DATA 0
+
#endif
\ No newline at end of file
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pytest.py
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pytest.py 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/pytest.py 2007-03-15 22:27:02 UTC (rev 2745)
@@ -4,8 +4,6 @@
# The the shapefile module
#
-print "--- testing shapelib ---"
-
def test_shpobject(obj):
# The vertices method returns the shape as a list of lists of tuples.
print "vertices:", obj.vertices()
@@ -112,10 +110,67 @@
print tree.find_shapes(minima[:2], maxima[:2])
+print "--- testing shapelib ---"
+
make_shapefile("testfile")
read_shapefile("testfile")
#
+# Test MultiPatch shapefiles
+#
+
+def make_multipatch(filename):
+ print "\n* Creating multipatch ShapeFile"
+
+ # Create a shapefile with multipatches
+ outfile = shapelib.create(filename, shapelib.SHPT_MULTIPATCH)
+
+ # Create a quad as a triangle strip and as a triangle fan, in ONE object!
+ # Multipatch shapefiles use XYZM vertices, but you can get away with
+ # only specifying X and Y, Z and M are zero by default.
+ print "\nA triangle strip"
+ obj = shapelib.SHPObject(shapelib.SHPT_MULTIPATCH, 0,
+ [[(0, 0), (0, 10), (10, 0), (10, 10)],
+ [(20, 20), (20, 30), (30, 30), (30, 20)]],
+ [shapelib.SHPP_TRISTRIP, shapelib.SHPP_TRIFAN])
+ test_shpobject(obj)
+ outfile.write_object(-1, obj)
+
+ # A polygon as an Outer ring and inner ring, with XYZ coordinates
+ # and measure values M. Here we will use the part types to specify
+ # their particular type.
+ #
+ # You can have more than one polygon in a single Object, as long
+ # as you obey the following sequence: each polygon starts with an
+ # outer ring, followed by its holes as inner rings.
+ #
+ # None is also accepted as M value to specify no-data. The ESRI
+ # Shapefile specs define any M value smaller than 1e-38 as no-data.
+ # shapelib will store no-data as a zero.
+ #
+ # If you don't need the M value, you can leave it out and use triples
+ # as vertices instead. For the first half of the inner ring,
+ # we used None to specify no-data. In the second half, we just
+ # omitted it.
+ #
+ print "\nA polygon as outer ring and inner ring with XYZM coordinates"
+ obj = shapelib.SHPObject(shapelib.SHPT_MULTIPATCH, 1,
+ [[(0, 0, 0, 35.3), (0, 40, 10, 15.4), (40, 40, 20, 9.5), (40, 0, 10, 24.6), (0, 0, 0, 31.8)],
+ [(10, 10, 5, None), (20, 10, 10, None), (20, 20, 15), (10, 20, 10, 20),(10, 10, 5)]],
+ [shapelib.SHPP_OUTERRING, shapelib.SHPP_INNERRING])
+ test_shpobject(obj)
+ outfile.write_object(-1, obj)
+
+ # close the file.
+ outfile.close()
+
+
+print "--- testing multipatch ---"
+
+make_multipatch("multipatch")
+read_shapefile("multipatch")
+
+#
# Test the DBF file module.
#
@@ -127,14 +182,15 @@
dbf.add_field("NAME", dbflib.FTString, 20, 0)
dbf.add_field("INT", dbflib.FTInteger, 10, 0)
dbf.add_field("FLOAT", dbflib.FTDouble, 10, 4)
+ dbf.add_field("BOOL", dbflib.FTLogical, 1, 0)
def add_dbf_records(file):
# add some records to file
dbf = dbflib.open(file, "r+b")
# Records can be added as a dictionary...
- dbf.write_record(0, {'NAME': "Weatherwax", "INT":1, "FLOAT":3.1415926535})
+ dbf.write_record(0, {'NAME': "Weatherwax", "INT":1, "FLOAT":3.1415926535, "BOOL":True})
# ... or as a sequence
- dbf.write_record(1, ("Ogg", 2, -1000.1234))
+ dbf.write_record(1, ("Ogg", 2, -1000.1234, False))
def list_dbf(file):
# print the contents of a dbf file to stdout
@@ -143,12 +199,14 @@
format = ""
for i in range(dbf.field_count()):
type, name, len, decc = dbf.field_info(i)
- if type == 0:
+ if type == dbflib.FTString:
format = format + " %%(%s)%ds" % (name, len)
- elif type == 1:
+ elif type == dbflib.FTInteger:
format = format + " %%(%s)%dd" % (name, len)
- elif type == 2:
+ elif type == dbflib.FTDouble:
format = format + " %%(%s)%dg" % (name, len)
+ elif type == dbflib.FTLogical:
+ format = format + " %%(%s)s" % name
print format
for i in range(dbf.record_count()):
print format % dbf.read_record(i)
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shapelibmodule.c 2007-03-15 22:27:02 UTC (rev 2745)
@@ -67,6 +67,9 @@
self->ob_type->tp_free((PyObject*)self);
}
+static int unpack_vertex(PyObject* vertex, int vertex_type,
+ double* xs, double* ys, double* zs, double* ms, int offset);
+
/* The constructor of SHPObject. parts is a list of lists of tuples
* describing the parts and their vertices just likethe output of the
* vertices() method. part_type_list is the list of part-types and may
@@ -97,7 +100,7 @@
int has_m;
int i;
- int ok, return_code = -1;
+ int return_code = -1;
/* first, unpack parameters */
if (kwds != NULL && PyDict_Size(kwds) > 0)
@@ -202,26 +205,13 @@
for (j = 0; j < length; ++j)
{
PyObject* vertex = PySequence_ITEM(part, j);
- 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)
- {
+ Py_DECREF(vertex);
PyErr_SetString(PyExc_TypeError, "at least one vertex is of the wrong format");
goto exit;
}
+ Py_DECREF(vertex);
}
Py_DECREF(part);
part = NULL;
@@ -242,6 +232,71 @@
return return_code;
}
+/* helper for shpobject_init. Unpacks vertices
+ */
+static int unpack_vertex(PyObject* vertex, int vertex_type,
+ double* xs, double* ys, double* zs, double* ms, int offset)
+{
+ int ok;
+ PyObject* m_object;
+ PyObject *err_type, *err_value, *err_traceback;
+
+ switch (vertex_type)
+ {
+ case vtXY:
+ return PyArg_ParseTuple(vertex, "dd:__init__", xs + offset, ys + offset);
+
+ case vtXYM:
+ ms[offset] = PYSHAPELIB_NO_DATA;
+ ok = PyArg_ParseTuple(vertex, "dd|d:__init__", xs + offset, ys + offset, ms + offset);
+ if (!ok)
+ {
+ /* maybe they specified None as M value */
+ PyErr_Fetch(&err_type, &err_value, &err_traceback);
+ ok = PyArg_ParseTuple(vertex, "ddO:__init__", xs + offset, ys + offset, &m_object);
+ if (ok && m_object == Py_None)
+ {
+ Py_XDECREF(err_type);
+ Py_XDECREF(err_value);
+ Py_XDECREF(err_traceback);
+ }
+ else
+ {
+ PyErr_Restore(err_type, err_value, err_traceback);
+ }
+ }
+ return ok;
+
+ case vtXYZM:
+ zs[offset] = 0.;
+ ms[offset] = PYSHAPELIB_NO_DATA;
+ ok = PyArg_ParseTuple(vertex, "dd|dd:__init__", xs + offset, ys + offset,
+ zs + offset, ms + offset);
+ if (!ok)
+ {
+ /* maybe they specified None as M value */
+ PyErr_Fetch(&err_type, &err_value, &err_traceback);
+ ok = PyArg_ParseTuple(vertex, "dddO:__init__", xs + offset, ys + offset,
+ zs + offset, &m_object);
+ if (ok && m_object == Py_None)
+ {
+ Py_XDECREF(err_type);
+ Py_XDECREF(err_value);
+ Py_XDECREF(err_traceback);
+ }
+ else
+ {
+ PyErr_Restore(err_type, err_value, err_traceback);
+ }
+ }
+ return ok;
+
+ default:
+ PyErr_SetString(PyExc_NotImplementedError, "vertex type not implemented");
+ return 0;
+ }
+}
+
/*
* The extents() method of SHPObject.
*
@@ -340,6 +395,7 @@
case vtXYM:
vertex = Py_BuildValue("ddd", object->padfX[index], object->padfY[index],
object->padfM[index]);
+ break;
case vtXYZM:
vertex = Py_BuildValue("dddd", object->padfX[index], object->padfY[index],
object->padfZ[index], object->padfM[index]);
@@ -437,15 +493,16 @@
static struct PyMethodDef shpobject_methods[] =
{
{"extents", (PyCFunction)shpobject_extents, METH_NOARGS,
- "extents()\n"
- "returns ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)), the 4D bounding box of the SHPObject"},
+ "extents() -> ((x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n"
+ "returns the 4D bounding box of the SHPObject"},
{"vertices", (PyCFunction)shpobject_vertices, METH_NOARGS,
- "vertices()\n"
- "returns [[(x, y, ...), ...], ...], a list of object parts, where each part is again a list of vertices.\n"
- "each vertex is a tuple of two to four doubles, depending on the object type."},
+ "vertices() -> [[(x, y, ...), ...], ...]\n\n"
+ "Returns a list of object parts, where each part is again a list of vertices. "
+ "Each vertex is a tuple of two to four doubles, depending on the object type."},
{"part_types", (PyCFunction)shpobject_part_types, METH_NOARGS,
- "part_types()\n"
- "returns a tuple of integers, each integer indicating the type of the corresponding part in vertices()"},
+ "part_types() -> tuple\n\n"
+ "returns a tuple of integers, each integer indicating the type of the "
+ "corresponding part in vertices()"},
{NULL}
};
@@ -492,14 +549,13 @@
{
char* file;
char* mode = "rb";
- if (kwds != NULL && PyDict_Size(kwds) > 0)
- {
- PyErr_Format(PyExc_TypeError, "shapelib.ShapeFile.__init__ takes no keyword arguments");
- return -1;
- }
- if (!PyArg_ParseTuple(args, "et|s:__init__", Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
+ static char *kwlist[] = {"name", "mode", NULL};
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|s:__init__", kwlist,
+ Py_FileSystemDefaultEncoding, &file, &mode)) return -1;
self->handle = SHPOpen(file, mode);
+ PyMem_Free(file);
+
return self->handle ? 0 : -1;
}
@@ -580,23 +636,23 @@
static struct PyMethodDef shapefile_methods[] =
{
{"close", (PyCFunction)shapefile_close, METH_NOARGS,
- "close()\n"
+ "close() -> None\n\n"
"close the shape file" },
{"info", (PyCFunction)shapefile_info, METH_NOARGS,
- "info()\n"
- "returns (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max)) with:\n"
- "-num_shapes: the number of the objects in the file\n"
- "-type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n"
- "-(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" },
+ "info() -> (num_shapes, type, (x_min, y_min, z_min, m_min), (x_max, y_max, z_max, m_max))\n\n"
+ "returns info about ShapeFile with:\n"
+ "- num_shapes: the number of the objects in the file\n"
+ "- type: the type of the shape file (SHPT_POINT, SHPT_POLYGON, ...)\n"
+ "- (x_min, ...), (x_max, ...): 4D bounding box of the data in the shape file" },
{"read_object", (PyCFunction)shapefile_read_object, METH_VARARGS,
- "read_object(id)\n"
- "Return object indexed by id" },
+ "read_object(id) -> SHPObject\n\n"
+ "Returns shape indexed by id" },
{"write_object", (PyCFunction)shapefile_write_object, METH_VARARGS,
- "write_object(id, object)\n"
- "Write an object at index id.\n"
- "If id == -1, the object is appended at the end of the shape file"},
+ "write_object(id, object) -> id\n\n"
+ "Write an object at index id, and returns id."
+ "If id == -1, the object is appended at the end of the shape file."},
{"cobject", (PyCFunction)shapefile_cobject, METH_NOARGS,
- "cobject()\n"
+ "cobject() -> CObject\n\n"
"Return the shapelib SHPHandle as a Python CObject"},
{NULL}
};
@@ -626,10 +682,13 @@
result = PyObject_New(ShapeFileObject, &ShapeFileType);
if (!result)
{
+ PyMem_Free(file);
return PyErr_NoMemory();
}
result->handle = SHPCreate(file, type);
+ PyMem_Free(file);
+
if (!result->handle)
{
PyObject_Del((PyObject*)result);
@@ -671,19 +730,19 @@
static struct PyMethodDef shapelib_methods[] =
{
{"open", (PyCFunction)shapelib_open, METH_VARARGS,
- "open(filename [, mode='rb'])\n"
- "open a ShapeFile" },
+ "open(name [, mode='rb']) -> ShapeFile\n\n"
+ "opens a ShapeFile" },
{"create", (PyCFunction)shapelib_create, METH_VARARGS,
- "create(filename, type)\n"
- "create a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" },
+ "create(name, type) -> ShapeFile\n\n"
+ "creates a ShapeFile of a certain type (one of SHPT_POINT, SHPT_POLYGON)" },
{"c_api", (PyCFunction)shapelib_c_api, METH_NOARGS,
- "c_api()\n"
- "get C API of shapelib" },
+ "c_api() -> CObject\n\n"
+ "get C API of shapelib as a CObject" },
{"type_name", (PyCFunction)shapelib_type_name, METH_VARARGS,
- "type_name(type)\n"
+ "type_name(type) -> string\n\n"
"return type as string" },
{"part_type_name", (PyCFunction)shapelib_part_type_name, METH_VARARGS,
- "part_type_name(part_type)\n"
+ "part_type_name(part_type) -> string\n\n"
"return part type as string" },
{NULL}
};
Modified: branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shptreemodule.c
===================================================================
--- branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shptreemodule.c 2007-03-15 13:48:58 UTC (rev 2744)
+++ branches/WIP-pyshapelib-bramz/libraries/pyshapelib/shptreemodule.c 2007-03-15 22:27:02 UTC (rev 2745)
@@ -166,8 +166,11 @@
};
-void
-initshptree()
+#ifdef NDEBUG
+PyMODINIT_FUNC initshptree(void)
+#else
+PyMODINIT_FUNC initshptree_d(void)
+#endif
{
SHPTreeType.ob_type = &PyType_Type;
More information about the Thuban-commits
mailing list