[GRASS-SVN] r56252 - grass/trunk/vector/v.generalize
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue May 14 07:44:32 PDT 2013
Author: mmetz
Date: 2013-05-14 07:44:32 -0700 (Tue, 14 May 2013)
New Revision: 56252
Modified:
grass/trunk/vector/v.generalize/main.c
grass/trunk/vector/v.generalize/operators.h
grass/trunk/vector/v.generalize/point.c
grass/trunk/vector/v.generalize/point.h
grass/trunk/vector/v.generalize/smoothing.c
Log:
v.generalize: add loop support
Modified: grass/trunk/vector/v.generalize/main.c
===================================================================
--- grass/trunk/vector/v.generalize/main.c 2013-05-14 13:35:52 UTC (rev 56251)
+++ grass/trunk/vector/v.generalize/main.c 2013-05-14 14:44:32 UTC (rev 56252)
@@ -54,13 +54,14 @@
struct Option *angle_thresh_opt, *degree_thresh_opt,
*closeness_thresh_opt;
struct Option *betweeness_thresh_opt;
- struct Flag *notab_flag;
+ struct Flag *notab_flag, *loop_support_flag;
int with_z;
int total_input, total_output; /* Number of points in the input/output map respectively */
double thresh, alpha, beta, reduction, slide, angle_thresh;
double degree_thresh, closeness_thresh, betweeness_thresh;
int method;
int look_ahead, iterations;
+ int loop_support;
int layer;
int n_lines;
int simplification, mask_type;
@@ -225,6 +226,10 @@
where_opt = G_define_standard_option(G_OPT_DB_WHERE);
where_opt->guisection = _("Selection");
+ loop_support_flag = G_define_flag();
+ loop_support_flag->key = 'l';
+ loop_support_flag->description = _("Loop support");
+
notab_flag = G_define_standard_flag(G_FLG_V_TABLE);
notab_flag->description = _("Do not copy attributes");
notab_flag->guisection = _("Attributes");
@@ -447,6 +452,20 @@
/* copy points */
Vect_reset_line(Points);
Vect_append_points(Points, APoints, GV_FORWARD);
+
+ loop_support = 0;
+ if (loop_support_flag->answer) {
+ int n1, n2;
+
+ Vect_get_line_nodes(&Out, i, &n1, &n2);
+ if (n1 == n2) {
+ if (Vect_get_node_n_lines(&Out, n1) == 2) {
+ if (abs(Vect_get_node_line(&Out, n1, 0)) == i &&
+ abs(Vect_get_node_line(&Out, n1, 1)) == i)
+ loop_support = 1;
+ }
+ }
+ }
for (iter = 0; iter < iterations; iter++) {
switch (method) {
@@ -470,7 +489,7 @@
boyle(Points, look_ahead, with_z);
break;
case SLIDING_AVERAGING:
- sliding_averaging(Points, slide, look_ahead, with_z);
+ sliding_averaging(Points, slide, look_ahead, loop_support, with_z);
break;
case DISTANCE_WEIGHTING:
distance_weighting(Points, slide, look_ahead, with_z);
@@ -487,6 +506,7 @@
}
}
+ if (method != SLIDING_AVERAGING || loop_support == 0){
/* safety check, BUG in method if not passed */
if (APoints->x[0] != Points->x[0] ||
APoints->y[0] != Points->y[0] ||
@@ -498,6 +518,8 @@
APoints->z[APoints->n_points - 1] != Points->z[Points->n_points - 1])
G_fatal_error(_("Method '%s' did not preserve last point"), method_opt->answer);
+ }
+
Vect_line_prune(Points);
/* oversimplified line */
Modified: grass/trunk/vector/v.generalize/operators.h
===================================================================
--- grass/trunk/vector/v.generalize/operators.h 2013-05-14 13:35:52 UTC (rev 56251)
+++ grass/trunk/vector/v.generalize/operators.h 2013-05-14 14:44:32 UTC (rev 56252)
@@ -12,7 +12,7 @@
/* smoothing.c */
int boyle(struct line_pnts *Points, int look_ahead, int with_z);
int sliding_averaging(struct line_pnts *Points, double slide, int look_ahead,
- int with_z);
+ int loop_support, int with_z);
int distance_weighting(struct line_pnts *Points, double slide, int look_ahead,
int with_z);
int chaiken(struct line_pnts *Points, double thresh, int with_z);
Modified: grass/trunk/vector/v.generalize/point.c
===================================================================
--- grass/trunk/vector/v.generalize/point.c 2013-05-14 13:35:52 UTC (rev 56251)
+++ grass/trunk/vector/v.generalize/point.c 2013-05-14 14:44:32 UTC (rev 56252)
@@ -63,6 +63,21 @@
return;
}
+inline void point_assign_loop(struct line_pnts *Points, int index, int with_z,
+ POINT * res)
+{
+ index = index % Points->n_points;
+ res->x = Points->x[index];
+ res->y = Points->y[index];
+ if (with_z) {
+ res->z = Points->z[index];
+ }
+ else {
+ res->z = 0;
+ }
+ return;
+}
+
inline void point_scalar(POINT a, double k, POINT * res)
{
res->x = a.x * k;
Modified: grass/trunk/vector/v.generalize/point.h
===================================================================
--- grass/trunk/vector/v.generalize/point.h 2013-05-14 13:35:52 UTC (rev 56251)
+++ grass/trunk/vector/v.generalize/point.h 2013-05-14 14:44:32 UTC (rev 56252)
@@ -50,6 +50,12 @@
*/
extern inline void point_assign(struct line_pnts *Points, int index,
int with_z, POINT * res);
+/* assign point Points[index] to the res
+ * if with z = 0 then res.z = 0
+ * loop to infinite
+ */
+extern inline void point_assign_loop(struct line_pnts *Points, int index,
+ int with_z, POINT * res);
/* res = k * a */
extern inline void point_scalar(POINT a, double k, POINT * res);
Modified: grass/trunk/vector/v.generalize/smoothing.c
===================================================================
--- grass/trunk/vector/v.generalize/smoothing.c 2013-05-14 13:35:52 UTC (rev 56251)
+++ grass/trunk/vector/v.generalize/smoothing.c 2013-05-14 14:44:32 UTC (rev 56252)
@@ -25,6 +25,8 @@
#include "point.h"
#include "matrix.h"
+/* TODO: add loop support where possible */
+
/* boyle's forward looking algorithm
* return the number of points in the result = Points->n_points
*/
@@ -70,18 +72,31 @@
/* mcmaster's sliding averaging algorithm. Return the number of points
* in the output line. This equals to the number of points in the
* input line */
-int sliding_averaging(struct line_pnts *Points, double slide, int look_ahead,
- int with_z)
+
+int sliding_averaging(struct line_pnts *Points, double slide, int look_ahead,
+ int loop_support, int with_z)
{
int n, half, i;
double sc;
POINT p, tmp, s;
POINT *res;
+ int is_loop, count;
+ is_loop=0;
n = Points->n_points;
half = look_ahead / 2;
+
+ count = n - half;
+ /* is it loop ?*/
+ if (Points->x[0] == Points->x[n-1]
+ && Points->y[0] == Points->y[n-1]
+ && (Points->z[0] == Points->z[n-1] || with_z == 0) && loop_support){
+ is_loop = 1;
+ count = n + half;
+ }
+
if (look_ahead % 2 == 0) {
G_fatal_error(_("Look ahead parameter must be odd"));
return n;
@@ -90,7 +105,7 @@
if (look_ahead >= n || look_ahead == 1)
return n;
- res = G_malloc(sizeof(POINT) * n);
+ res = G_malloc(sizeof(POINT) * (n + half));
if (!res) {
G_fatal_error(_("Out of memory"));
return n;
@@ -105,29 +120,37 @@
}
/* and calculate the average of remaining points */
- for (i = half; i + half < n; i++) {
- point_assign(Points, i, with_z, &s);
+ for (i = half; i < count; i++) {
+ point_assign_loop(Points, i, with_z, &s);
point_scalar(s, 1.0 - slide, &s);
point_scalar(p, sc * slide, &tmp);
point_add(tmp, s, &res[i]);
- if (i + half + 1 < n) {
- point_assign(Points, i - half, with_z, &tmp);
+ if ((i + half + 1 < n) || is_loop ) {
+ point_assign_loop(Points, i - half, with_z, &tmp);
point_subtract(p, tmp, &p);
- point_assign(Points, i + half + 1, with_z, &tmp);
+ point_assign_loop(Points, i + half + 1, with_z, &tmp);
point_add(p, tmp, &p);
}
}
- for (i = half; i + half < n; i++) {
+ for (i = half; i < count; i++) {
Points->x[i] = res[i].x;
Points->y[i] = res[i].y;
Points->z[i] = res[i].z;
}
+ if (is_loop) {
+ for (i = 0; i < half; i++) {
+ Points->x[i] = res[n + i - 1].x;
+ Points->y[i] = res[n + i - 1].y;
+ Points->z[i] = res[n + i - 1].z;
+ }
+ }
+
G_free(res);
+
return Points->n_points;
-
}
/* mcmaster's distance weighting algorithm. Return the number
More information about the grass-commit
mailing list