GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
gv_quick.c
Go to the documentation of this file.
1/*!
2 \file lib/ogsf/gv_quick.c
3
4 \brief OGSF library -
5
6 GRASS OpenGL gsurf OGSF Library
7
8 Trying some stuff to draw a quick version of a vector map, to represent
9 it when doing interactive translations.
10
11 (C) 1999-2008 by the GRASS Development Team
12
13 This program is free software under the
14 GNU General Public License (>=v2).
15 Read the file COPYING that comes with GRASS
16 for details.
17
18 \author Bill Brown, USACERL (December 1993)
19 \author Doxygenized by Martin Landa <landa.martin gmail.com> (May 2008)
20 */
21
22#include <stdio.h>
23#include <stdlib.h>
24
25#include <grass/gis.h>
26#include <grass/ogsf.h>
27
28#include "rowcol.h"
29
30/*!
31 \brief target number of desired points to represent entire file
32 */
33#define TFAST_PTS 800
34
35/*!
36 \brief max number of lines desired
37 */
38#define MFAST_LNS 400
39
40static geoline *copy_line(geoline *);
41static geoline *thin_line(geoline *, float);
42
43/*!
44 \brief Copy line
45
46 \param gln source line (geoline)
47
48 \return pointer to geoline struct
49 \return on failure
50 */
51static geoline *copy_line(geoline *gln)
52{
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/*!
93 \brief Thin line
94
95 For now, just eliminate points at regular interval
96
97 \param gln line (geoline)
98 \param factor
99
100 \return pointer to geoline struct
101 \return NULL on failure
102 */
103static geoline *thin_line(geoline *gln, float factor)
104{
105 geoline *newln;
106 int i, nextp, targp;
107
108 newln = (geoline *)G_malloc(sizeof(geoline)); /* G_fatal_error */
109 if (!newln) {
110 return (NULL);
111 }
112
113 targp = (int)(gln->npts / factor);
114
115 if (targp < 2) {
116 targp = 2;
117 }
118
119 newln->npts = targp;
120
121 if (2 == (newln->dims = gln->dims)) {
122 newln->p2 =
123 (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 =
142 (Point3 *)G_calloc(targp, sizeof(Point3)); /* G_fatal_error */
143 if (!newln->p3) {
144 return (NULL);
145 }
146
147 for (i = 0; i < targp; i++) {
148 if (i == targp - 1) {
149 nextp = gln->npts - 1; /* avoid rounding error */
150 }
151 else {
152 nextp = (int)((i * (gln->npts - 1)) / (targp - 1));
153 }
154
155 newln->p3[i][X] = gln->p3[nextp][X];
156 newln->p3[i][Y] = gln->p3[nextp][Y];
157 newln->p3[i][Z] = gln->p3[nextp][Z];
158 }
159 }
160
161 newln->next = NULL;
162
163 return (newln);
164}
165
166/*!
167 \brief Get line width
168
169 \param gln line (geoline)
170
171 \return line width
172 */
174{
175 int n;
176 float length = 0.0;
177
178 for (n = 0; n < gln->npts - 1; n++) {
179 if (gln->p2) {
180 length += GS_P2distance(gln->p2[n + 1], gln->p2[n]);
181 }
182 else {
183 length += GS_distance(gln->p3[n + 1], gln->p3[n]);
184 }
185 }
186
187 return (length);
188}
189
190/*!
191 \brief Get number of line vertices
192
193 \param gln line (geoline)
194
195 \return number of vertices
196 */
198{
199 int np = 0;
200 geoline *tln;
201
202 for (tln = gln; tln; tln = tln->next) {
203 np += tln->npts;
204 }
205
206 return (np);
207}
208
209/*!
210 \brief Get number of points in vector
211
212 \param gv vector (geovect)
213
214 \return number of points
215 */
217{
218 return (gln_num_points(gv->lines));
219}
220
221/*!
222 \brief Decimate line
223
224 strategy here: if line has more than average number of points, decimate
225 by eliminating points, otherwise decimate by eliminating shorter lines
226
227 \param gv vector (geovect)
228
229 \return
230 */
232{
233 int T_pts, A_ppl, N_s;
235 geoline *gln, *prev;
236
237 /* should check if already exists & free if != gv->lines */
238 if (TFAST_PTS > (T_pts = gv_num_points(gv))) {
239 gv->fastlines = gv->lines;
240
241 return (1);
242 }
243
244 N_s = 0;
245 T_slength = 0.0;
247 A_ppl = T_pts / gv->n_lines; /* (int) Average points per line */
248
249 prev = NULL;
250
251 for (gln = gv->lines; gln; gln = gln->next) {
252 if (gln->npts > A_ppl) {
253 if (prev) {
254 prev->next = thin_line(gln, decim_factor);
255 prev = prev->next;
256 }
257 else {
258 prev = gv->fastlines = thin_line(gln, decim_factor);
259 }
260 }
261 else if (N_s < MFAST_LNS) {
263 }
264 }
265
267 N_s = 0;
268
269 for (gln = gv->lines; gln; gln = gln->next) {
270 if (gln->npts <= A_ppl) {
271 if (N_s < MFAST_LNS) {
272 if (slength[N_s++] > A_slength) {
273 if (prev) {
274 prev->next = copy_line(gln);
275 prev = prev->next;
276 }
277 else {
278 prev = gv->fastlines = copy_line(gln);
279 }
280 }
281 }
282 }
283 }
284
285 G_debug(3, "Decimated lines have %d points.",
286 gln_num_points(gv->fastlines));
287
288 return (1);
289}
#define NULL
Definition ccmath.h:32
#define G_calloc(m, n)
Definition defs/gis.h:140
#define G_malloc(n)
Definition defs/gis.h:139
int G_debug(int, const char *,...) __attribute__((format(printf
float GS_P2distance(float *, float *)
Calculate distance in plane.
Definition gs_util.c:160
float GS_distance(float *, float *)
Calculate distance.
Definition gs_util.c:141
#define TFAST_PTS
target number of desired points to represent entire file
Definition gv_quick.c:33
#define MFAST_LNS
max number of lines desired
Definition gv_quick.c:38
float gv_line_length(geoline *gln)
Get line width.
Definition gv_quick.c:173
int gln_num_points(geoline *gln)
Get number of line vertices.
Definition gv_quick.c:197
int gv_num_points(geovect *gv)
Get number of points in vector.
Definition gv_quick.c:216
int gv_decimate_lines(geovect *gv)
Decimate line.
Definition gv_quick.c:231
OGSF header file (structures)
#define X
Definition ogsf.h:140
float Point2[2]
Definition ogsf.h:206
float Point3[3]
Definition ogsf.h:205
#define Z
Definition ogsf.h:142
#define Y
Definition ogsf.h:141
Line instance.
Definition ogsf.h:352
struct g_line * next
Definition ogsf.h:368
Vector map (lines)
Definition ogsf.h:372