Changeset 410
- Timestamp:
- 10/23/06 19:23:13 (2 years ago)
- Files:
-
- Quadtree/trunk/quadtree/_treemodule.c (modified) (4 diffs)
- Quadtree/trunk/tests/QuadTree.txt (modified) (2 diffs)
- Quadtree/trunk/tests/benchmarks.py (modified) (1 diff)
- Quadtree/trunk/tests/runtests (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
Quadtree/trunk/quadtree/_treemodule.c
r407 r410 41 41 Quadtree_add(Quadtree *self, PyObject *args) 42 42 { 43 int n; 43 int n, size; 44 PyObject *bounds=NULL; 44 45 double min[2], max[2]; 45 46 SHPObject *s; … … 49 50 double x[5], y[5]; 50 51 51 if (!PyArg_ParseTuple(args, "i(dddd)", &n, 52 &min[0], &min[1], &max[0], &max[1])) 53 return NULL; 54 52 if (!PyArg_ParseTuple(args, "iO", &n, &bounds)) 53 return NULL; 54 55 /* Check length of the bounds argument */ 56 if (!PySequence_Check(bounds)) 57 { 58 PyErr_SetString(PyExc_TypeError, "Bounds must be a sequence"); 59 return NULL; 60 } 61 62 size = (int) PySequence_Size(bounds); 63 if (size == 2) 64 { 65 min[0] = max[0] = PyFloat_AsDouble(PySequence_ITEM(bounds, 0)); 66 min[1] = max[1] = PyFloat_AsDouble(PySequence_ITEM(bounds, 1)); 67 } 68 else if (size == 4) 69 { 70 min[0] = PyFloat_AsDouble(PySequence_ITEM(bounds, 0)); 71 min[1] = PyFloat_AsDouble(PySequence_ITEM(bounds, 1)); 72 max[0] = PyFloat_AsDouble(PySequence_ITEM(bounds, 2)); 73 max[1] = PyFloat_AsDouble(PySequence_ITEM(bounds, 3)); 74 } 75 else 76 { 77 PyErr_Format(PyExc_TypeError, 78 "Bounds argument must be sequence of length 2 or 4, not %d", 79 size); 80 return NULL; 81 } 82 55 83 /* make shape vertices */ 56 84 x[0] = min[0]; … … 79 107 } 80 108 109 static PyObject * 110 Quadtree_prune(Quadtree *self) 111 { 112 SHPTreeTrimExtraNodes(self->tree); 113 Py_INCREF(Py_None); 114 return Py_None; 115 } 116 117 /* Tree structure */ 118 119 static void 120 QuadtreeNodeDump(SHPTreeNode *node, PyObject *nodelist) 121 { 122 int i; 123 PyObject *g=NULL, *ids=NULL, *bounds=NULL, *children=NULL; 124 125 g = PyDict_New(); 126 127 /* Save bounds */ 128 bounds = Py_BuildValue("(dddd)", 129 node->adfBoundsMin[0], node->adfBoundsMin[1], 130 node->adfBoundsMax[0], node->adfBoundsMax[1]); 131 PyDict_SetItemString(g, "bounds", bounds); 132 133 /* Save ids */ 134 ids = PyList_New(0); 135 for (i=0; i<node->nShapeCount; i++) 136 { 137 PyList_Append(ids, Py_BuildValue("i", node->panShapeIds[i])); 138 } 139 PyDict_SetItemString(g, "ids", ids); 140 141 /* Child nodes */ 142 children = PyList_New(0); 143 for (i=0; i<node->nSubNodes; i++) 144 { 145 if (node->apsSubNode[i] != NULL) 146 QuadtreeNodeDump(node->apsSubNode[i], children); 147 } 148 PyDict_SetItemString(g, "nodes", children); 149 150 /* Add g to the node list */ 151 PyList_Append(nodelist, g); 152 } 153 154 static PyObject * 155 Quadtree_struct(Quadtree *self) 156 { 157 PyObject *nodes=NULL; 158 nodes = PyList_New(0); 159 QuadtreeNodeDump(self->tree->psRoot, nodes); 160 return PyList_GetItem(nodes, 0); 161 } 81 162 82 163 static PyObject * … … 104 185 static PyMethodDef module_methods[] = { 105 186 {"add", (PyCFunction)Quadtree_add, METH_VARARGS, "Add an item to an index, specifying an integer id and a bounding box"}, 187 {"prune", (PyCFunction)Quadtree_prune, METH_NOARGS, "Remove unused nodes from the tree"}, 188 {"struct", (PyCFunction)Quadtree_struct, METH_NOARGS, "Return simple graph structure of the tree"}, 106 189 {"likely_intersection", (PyCFunction)Quadtree_intersection, METH_VARARGS, "Return an iterator over integer ids of items that are likely to intersect with the specified bounding box."}, 107 190 {NULL} Quadtree/trunk/tests/QuadTree.txt
r396 r410 7 7 >>> index = Quadtree((-180, -90, 180, 90), maxdepth=16) 8 8 9 Add 3 items9 Add 4 items, the last one a point 10 10 11 11 >>> index.add(0, [-106, 39, -105, 40]) 12 12 >>> index.add(1, (-100, 25, -95, 30)) 13 13 >>> index.add(2, (40, 50, 45, 55)) 14 >>> index.add(3, (-105, 33)) 15 16 Prune 17 18 >>> index.prune() 14 19 15 20 Find likely items 16 21 17 22 >>> [n for n in index.likely_intersection([-110, 30, -100, 45])] 18 [0, 1 ]23 [0, 1, 3] 19 24 >>> [n for n in index.likely_intersection([10, 40, 40.05, 60])] 20 25 [2] … … 26 31 >>> [n for n in index.likely_intersection([-110, 35, -108, 45])] 27 32 [0] 33 34 Tree structure 35 36 >>> tree = index.struct() 28 37 38 Visualize 39 40 >>> from quadtree.viz import render_graph 41 >>> render_graph(tree, 'quadtree.png') 42 43 Quadtree/trunk/tests/benchmarks.py
r399 r410 18 18 19 19 # Scatter points randomly in a 1x1 box 20 count = 100021 index_extent = [-180, -90, 180, 90]20 count = 50000 21 index_extent = (-180, -90, 180, 90) 22 22 points = [] 23 23 index = Quadtree(index_extent) 24 24 for i in xrange(count): 25 x = random.random()26 y = random.random()25 x = 360.0*(random.random()-0.5) 26 y = 180.0*(random.random()-0.5) 27 27 points.append(Point(x, y)) 28 index.add(i, [x, y, x, y])28 index.add(i, (x, y)) 29 29 30 bbox = [0.2, 0.3, 0.3, 0.4]30 bbox = (0.0, 50.0, 5.0, 55.0) 31 31 32 32 print count, "points" Quadtree/trunk/tests/runtests
r396 r410 1 1 #!/bin/sh 2 PYTHONPATH=/home/sean/Projects/ dev-packages python runalltests.py2 PYTHONPATH=/home/sean/Projects/PCL-trunk/dev-packages python runalltests.py 3 3
