GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
gv_quick.c
Go to the documentation of this file.
1 
22 #include <stdio.h>
23 #include <stdlib.h>
24 
25 #include <grass/gis.h>
26 #include <grass/gstypes.h>
27 
28 #include "rowcol.h"
29 
33 #define TFAST_PTS 800
34 
38 #define MFAST_LNS 400
39 
40 static geoline *copy_line(geoline *);
41 static geoline *thin_line(geoline *, float);
42 
51 static geoline *copy_line(geoline * gln)
52 {
53  geoline *newln;
54  int i, np;
55 
56  newln = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */
57  if (!newln) {
58  return (NULL);
59  }
60 
61  np = newln->npts = gln->npts;
62 
63  if (2 == (newln->dims = gln->dims)) {
64  newln->p2 = (Point2 *) G_calloc(np, sizeof(Point2)); /* G_fatal_error */
65  if (!newln->p2) {
66  return (NULL);
67  }
68 
69  for (i = 0; i < np; i++) {
70  newln->p2[i][X] = gln->p2[i][X];
71  newln->p2[i][Y] = gln->p2[i][Y];
72  }
73  }
74  else {
75  newln->p3 = (Point3 *) G_calloc(np, sizeof(Point3)); /* G_fatal_error */
76  if (!newln->p3) {
77  return (NULL);
78  }
79 
80  for (i = 0; i < np; i++) {
81  newln->p3[i][X] = gln->p3[i][X];
82  newln->p3[i][Y] = gln->p3[i][Y];
83  newln->p3[i][Z] = gln->p3[i][Z];
84  }
85  }
86 
87  newln->next = NULL;
88 
89  return (newln);
90 }
91 
92 
104 static geoline *thin_line(geoline * gln, float factor)
105 {
106  geoline *newln;
107  int i, nextp, targp;
108 
109  newln = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */
110  if (!newln) {
111  return (NULL);
112  }
113 
114  targp = (int)(gln->npts / factor);
115 
116  if (targp < 2) {
117  targp = 2;
118  }
119 
120  newln->npts = targp;
121 
122  if (2 == (newln->dims = gln->dims)) {
123  newln->p2 = (Point2 *) G_calloc(targp, sizeof(Point2)); /* G_fatal_error */
124  if (!newln->p2) {
125  return (NULL);
126  }
127 
128  for (i = 0; i < targp; i++) {
129  if (i == targp - 1) {
130  nextp = gln->npts - 1; /* avoid rounding error */
131  }
132  else {
133  nextp = (int)((i * (gln->npts - 1)) / (targp - 1));
134  }
135 
136  newln->p2[i][X] = gln->p2[nextp][X];
137  newln->p2[i][Y] = gln->p2[nextp][Y];
138  }
139  }
140  else {
141  newln->p3 = (Point3 *) G_calloc(targp, sizeof(Point3)); /* G_fatal_error */
142  if (!newln->p3) {
143  return (NULL);
144  }
145 
146  for (i = 0; i < targp; i++) {
147  if (i == targp - 1) {
148  nextp = gln->npts - 1; /* avoid rounding error */
149  }
150  else {
151  nextp = (int)((i * (gln->npts - 1)) / (targp - 1));
152  }
153 
154  newln->p3[i][X] = gln->p3[nextp][X];
155  newln->p3[i][Y] = gln->p3[nextp][Y];
156  newln->p3[i][Z] = gln->p3[nextp][Z];
157  }
158  }
159 
160  newln->next = NULL;
161 
162  return (newln);
163 }
164 
172 float gv_line_length(geoline * gln)
173 {
174  int n;
175  float length = 0.0;
176 
177  for (n = 0; n < gln->npts - 1; n++) {
178  if (gln->p2) {
179  length += GS_P2distance(gln->p2[n + 1], gln->p2[n]);
180  }
181  else {
182  length += GS_distance(gln->p3[n + 1], gln->p3[n]);
183  }
184  }
185 
186  return (length);
187 }
188 
196 int gln_num_points(geoline * gln)
197 {
198  int np = 0;
199  geoline *tln;
200 
201  for (tln = gln; tln; tln = tln->next) {
202  np += tln->npts;
203  }
204 
205  return (np);
206 }
207 
215 int gv_num_points(geovect * gv)
216 {
217  return (gln_num_points(gv->lines));
218 }
219 
220 
221 
232 int gv_decimate_lines(geovect * gv)
233 {
234  int T_pts, A_ppl, N_s;
235  float decim_factor, slength[MFAST_LNS], T_slength, A_slength;
236  geoline *gln, *prev;
237 
238  /* should check if already exists & free if != gv->lines */
239  if (TFAST_PTS > (T_pts = gv_num_points(gv))) {
240  gv->fastlines = gv->lines;
241 
242  return (1);
243  }
244 
245  N_s = 0;
246  T_slength = 0.0;
247  decim_factor = T_pts / TFAST_PTS;
248  A_ppl = T_pts / gv->n_lines; /* (int) Average points per line */
249 
250  prev = NULL;
251 
252  for (gln = gv->lines; gln; gln = gln->next) {
253  if (gln->npts > A_ppl) {
254  if (prev) {
255  prev->next = thin_line(gln, decim_factor);
256  prev = prev->next;
257  }
258  else {
259  prev = gv->fastlines = thin_line(gln, decim_factor);
260  }
261  }
262  else if (N_s < MFAST_LNS) {
263  T_slength += slength[N_s++] = gv_line_length(gln);
264  }
265  }
266 
267  A_slength = T_slength / N_s;
268  N_s = 0;
269 
270  for (gln = gv->lines; gln; gln = gln->next) {
271  if (gln->npts <= A_ppl) {
272  if (N_s < MFAST_LNS) {
273  if (slength[N_s++] > A_slength) {
274  if (prev) {
275  prev->next = copy_line(gln);
276  prev = prev->next;
277  }
278  else {
279  prev = gv->fastlines = copy_line(gln);
280  }
281  }
282  }
283  }
284  }
285 
286  G_debug(3, "Decimated lines have %d points.",
287  gln_num_points(gv->fastlines));
288 
289  return (1);
290 }
#define Y(x)
Definition: display/draw.c:246
#define X(y)
Definition: display/draw.c:248
#define TFAST_PTS
target number of desired points to represent entire file
Definition: gv_quick.c:33
float gv_line_length(geoline *gln)
Get line width.
Definition: gv_quick.c:172
int gv_decimate_lines(geovect *gv)
Decimate line.
Definition: gv_quick.c:232
int gln_num_points(geoline *gln)
Get number of line vertices.
Definition: gv_quick.c:196
int gv_num_points(geovect *gv)
Get number of points in vector.
Definition: gv_quick.c:215
int
Definition: g3dcolor.c:48
return NULL
Definition: dbfopen.c:1394
int G_debug(int level, const char *msg,...)
Print debugging message.
Definition: gis/debug.c:51
#define MFAST_LNS
max number of lines desired
Definition: gv_quick.c:38
float GS_distance(float *from, float *to)
Calculate distance.
Definition: GS_util.c:141
float GS_P2distance(float *from, float *to)
Calculate distance in plane.
Definition: GS_util.c:160
int n
Definition: dataquad.c:291