GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
qtree.c
Go to the documentation of this file.
1 
2 /*-
3  * Written by H. Mitasova, I. Kosinovsky, D. Gerdes Fall 1993
4  * University of Illinois
5  * US Army Construction Engineering Research Lab
6  * Copyright 1993, H. Mitasova (University of Illinois),
7  * I. Kosinovsky, (USA-CERL), and D.Gerdes (USA-CERL)
8  *
9  * updated by Mitasova Nov. 96, no changes necessary
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <math.h>
15 
16 #include <grass/dataquad.h>
17 #include <grass/qtree.h>
18 
19 struct multfunc
20  *MT_functions_new(int (*compare) (struct triple *, struct quaddata *),
21  struct quaddata **(*divide_data) (struct quaddata *,
22  int, double),
23  int (*add_data) (struct triple *, struct quaddata *,
24  double),
25  int (*intersect) (struct quaddata *, struct quaddata *),
26  int (*division_check) (struct quaddata *, int),
27  int (*get_points) (struct quaddata *, struct quaddata *,
28  int))
29 /* Initializes FUNCTIONS structure with given arguments */
30 {
31  struct multfunc *functions;
32  if (!(functions = (struct multfunc *)malloc(sizeof(struct multfunc)))) {
33  return NULL;
34  }
35  functions->compare = compare;
36  functions->divide_data = divide_data;
37  functions->add_data = add_data;
38  functions->intersect = intersect;
39  functions->division_check = division_check;
40  functions->get_points = get_points;
41  return functions;
42 }
43 
45  struct multfunc *functions, double dmin,
46  int kmax)
47 /*Initializes TREE_INFO using given arguments */
48 {
49  struct tree_info *info;
50  if (!(info = (struct tree_info *)malloc(sizeof(struct tree_info)))) {
51  return NULL;
52  }
53  info->root = root;
54  info->functions = functions;
55  info->dmin = dmin;
56  info->kmax = kmax;
57  return info;
58 }
59 
61  struct multtree **leafs, struct multtree *parent,
62  int multant)
63 /*Initializes TREE using given arguments */
64 {
65  struct multtree *tree;
66  if (!(tree = (struct multtree *)malloc(sizeof(struct multtree)))) {
67  return NULL;
68  }
69  tree->data = data;
70  tree->leafs = leafs;
71  tree->parent = parent;
72  tree->multant = multant;
73  return tree;
74 }
75 
76 
77 
78 int MT_insert(struct triple *point,
79  struct tree_info *info, struct multtree *tree, int n_leafs)
80 /*First checks for dividing cond. (if n_points>=KMAX) and TREE is a leaf
81  by calling one of tree's functions (division_check()).
82  If TREE is not a leaf (is a node) uses function compare to determine
83  into which "son" we need to insert the point and calls MT_insert()
84  with this son as a n argument.
85  If TREE is a leaf but we don't need to divide it (n_points<KMAX) then
86  calls function add_data(POINT) to add POINT to the data of TREE and
87  returns the result of add_data() (which returns 1 if the point is
88  inserted and 0 if its ignored (when its too dense)).
89  If Division_check returns true, calls MT_divide(TREE) and then calls
90  insert_quad() to insert the POINT into divided TREE and returns the
91  result of MT_divide(). */
92 {
93  int j = 0, i, k, comp;
94 
95  if (tree == NULL) {
96  fprintf(stderr, "insert: tree is NULL\n");
97  return -5;
98  }
99  if (tree->data == NULL) {
100  fprintf(stderr, "insert: tree->data is NULL\n");
101  return -5;
102  }
103  i = info->functions->division_check(tree->data, info->kmax);
104  if (i <= 0) {
105  if (i == -1) {
106  comp = info->functions->compare(point, tree->data);
107  if ((comp < 1) || (comp > n_leafs))
108  return -3;
109  j = MT_insert(point, info, tree->leafs[comp - 1], n_leafs);
110  }
111  else {
112  if (i == 0) {
113  j = info->functions->add_data(point, tree->data, info->dmin);
114  }
115  }
116  }
117  else {
118  k = MT_divide(info, tree, n_leafs);
119  if (k == 1)
120  j = MT_insert(point, info, tree, n_leafs);
121  if (k == -3) {
122  static int once = 0;
123 
124  if (!once) {
125  fprintf(stderr, "Point out of range!\n");
126  once = 1;
127  }
128  }
129  if (k < 0)
130  return k;
131 
132  }
133  return j;
134 }
135 
136 
137 int MT_divide(struct tree_info *info, struct multtree *tree, int n_leafs)
138 /* Divides the tree by calling one of tree's functions (divide_data())
139  and returns the result of divide_data() */
140 {
141  int i;
142  struct quaddata **datas;
143  struct multtree *par;
144  struct multtree **leafs;
145 
146  datas = info->functions->divide_data(tree->data, info->kmax, info->dmin);
147  if (datas == NULL) {
148  fprintf(stderr, "datas is NULL\n");
149  return -7;
150  }
151  par = tree;
152  leafs = (struct multtree **)malloc(sizeof(struct multtree *) * n_leafs);
153  for (i = 1; i <= n_leafs; i++) {
154  leafs[i - 1] = MT_tree_new(datas[i], NULL, par, i);
155  }
156  tree->leafs = leafs;
157  return 1;
158 }
159 
160 
161 
162 
163 
164 
165 int MT_region_data(struct tree_info *info, struct multtree *tree, struct quaddata *data, int MAX, /* max number of points we can add (KMAX2) */
166  int n_leafs)
167  /* Gets points inside the region defined by DATA from TREE and
168  adds them to DATA. If the number of eligible
169  point is more than MAX returns MAX+1 othervise returns number of points added
170  to DATA.
171  Uses tree's functions intersect() to find leafs that intersect given region
172  and get_points() to get points from such leafs. */
173 {
174  int n = 0, j;
175 
176  if (tree == NULL) {
177  fprintf(stderr, "MT_region_data: tree is NULL\n");
178  return n;
179  }
180  if (tree->data == NULL) {
181  fprintf(stderr, "MT_region_data: data is NULL\n");
182  return n;
183  }
184  if (info->functions->intersect(data, tree->data)) {
185  if (tree->leafs != NULL) {
186  for (j = 0; j < n_leafs; j++) {
187  if ((n =
188  n + MT_region_data(info, tree->leafs[j], data, MAX - n,
189  n_leafs)) > MAX)
190  return n;
191  }
192  }
193  else {
194  n = info->functions->get_points(data, tree->data, MAX);
195  }
196  return n;
197  }
198  return 0;
199 }
def info
Display an informational message using g.message -i
Definition: core.py:339
int(* intersect)()
Definition: qtree.h:25
struct tree_info * MT_tree_info_new(struct multtree *root, struct multfunc *functions, double dmin, int kmax)
Definition: qtree.c:44
int(* get_points)()
Definition: qtree.h:27
int(* compare)()
Definition: qtree.h:22
struct quaddata **(* divide_data)()
Definition: qtree.h:23
DCELL dmin
Definition: g3dcolor.c:53
struct quaddata * data
Definition: qtree.h:40
double dmin
Definition: qtree.h:33
tuple data
void * malloc(YYSIZE_T)
struct multfunc * MT_functions_new(int(*compare)(struct triple *, struct quaddata *), struct quaddata **(*divide_data)(struct quaddata *, int, double), int(*add_data)(struct triple *, struct quaddata *, double), int(*intersect)(struct quaddata *, struct quaddata *), int(*division_check)(struct quaddata *, int), int(*get_points)(struct quaddata *, struct quaddata *, int))
Definition: qtree.c:20
int(* add_data)()
Definition: qtree.h:24
struct multtree * MT_tree_new(struct quaddata *data, struct multtree **leafs, struct multtree *parent, int multant)
Definition: qtree.c:60
struct multfunc * functions
Definition: qtree.h:32
Definition: qtree.h:20
return NULL
Definition: dbfopen.c:1394
int kmax
Definition: qtree.h:34
int MT_region_data(struct tree_info *info, struct multtree *tree, struct quaddata *data, int MAX, int n_leafs)
Definition: qtree.c:165
#define MAX(a, b)
int MT_insert(struct triple *point, struct tree_info *info, struct multtree *tree, int n_leafs)
Definition: qtree.c:78
Definition: qtree.h:38
struct multtree * parent
Definition: qtree.h:42
struct multtree * root
Definition: qtree.h:35
int(* division_check)()
Definition: qtree.h:26
int MT_divide(struct tree_info *info, struct multtree *tree, int n_leafs)
Definition: qtree.c:137
int n
Definition: dataquad.c:291
struct multtree ** leafs
Definition: qtree.h:41
int multant
Definition: qtree.h:43