[GRASS-SVN] r44957 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Jan 11 13:09:46 EST 2011
Author: mmetz
Date: 2011-01-11 10:09:46 -0800 (Tue, 11 Jan 2011)
New Revision: 44957
Modified:
grass/trunk/lib/vector/Vlib/find.c
Log:
optimize Vect_find_area()
Modified: grass/trunk/lib/vector/Vlib/find.c
===================================================================
--- grass/trunk/lib/vector/Vlib/find.c 2011-01-11 18:01:10 UTC (rev 44956)
+++ grass/trunk/lib/vector/Vlib/find.c 2011-01-11 18:09:46 UTC (rev 44957)
@@ -24,6 +24,26 @@
#define HUGE_VAL 9999999999999.0
#endif
+
+/* for qsort */
+
+typedef struct {
+ int i;
+ double size;
+} BOX_SIZE;
+
+static int sort_by_size(const void *a, const void *b)
+{
+ BOX_SIZE *as = (BOX_SIZE *)a;
+ BOX_SIZE *bs = (BOX_SIZE *)b;
+
+ if (as->size < bs->size)
+ return -1;
+ else
+ return (as->size > bs->size);
+}
+
+
/*!
* \brief Find the nearest node.
*
@@ -250,12 +270,16 @@
static int first = 1;
struct bound_box box;
static struct ilist *List;
+ static BOX_SIZE *size_list;
+ static int alloc_size_list = 0;
G_debug(3, "Vect_find_area() x = %f y = %f", x, y);
if (first) {
List = Vect_new_list();
first = 0;
+ alloc_size_list = 10;
+ size_list = G_malloc(alloc_size_list * sizeof(BOX_SIZE));
}
/* select areas by box */
@@ -268,8 +292,30 @@
Vect_select_areas_by_box(Map, &box, List);
G_debug(3, " %d areas selected by box", List->n_values);
+ /* sort areas by size, the smallest is likely to be the nearest */
+ if (alloc_size_list < List->n_values) {
+ alloc_size_list = List->n_values;
+ size_list = G_realloc(size_list, alloc_size_list * sizeof(BOX_SIZE));
+ }
+
for (i = 0; i < List->n_values; i++) {
- area = List->value[i];
+ size_list[i].i = area = List->value[i];
+ Vect_get_area_box(Map, area, &box);
+ size_list[i].size = (box.N - box.S) * (box.E - box.W);
+ }
+
+ if (List->n_values == 2) {
+ /* simple swap */
+ if (size_list[1].size < size_list[0].size) {
+ size_list[0].i = List->value[1];
+ size_list[1].i = List->value[0];
+ }
+ }
+ else if (List->n_values > 2)
+ qsort(size_list, List->n_values, sizeof(BOX_SIZE), sort_by_size);
+
+ for (i = 0; i < List->n_values; i++) {
+ area = size_list[i].i;
ret = Vect_point_in_area(Map, area, x, y);
G_debug(3, " area = %d Vect_point_in_area() = %d", area, ret);
More information about the grass-commit
mailing list