[GRASS-SVN] r50087 - grass/trunk/vector/v.clean
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Jan 7 08:51:55 EST 2012
Author: mmetz
Date: 2012-01-07 05:51:55 -0800 (Sat, 07 Jan 2012)
New Revision: 50087
Added:
grass/trunk/vector/v.clean/split.c
Log:
v.clean: new helper tool for tool=break
Added: grass/trunk/vector/v.clean/split.c
===================================================================
--- grass/trunk/vector/v.clean/split.c (rev 0)
+++ grass/trunk/vector/v.clean/split.c 2012-01-07 13:51:55 UTC (rev 50087)
@@ -0,0 +1,141 @@
+/****************************************************************
+ *
+ * MODULE: v.clean
+ *
+ * AUTHOR(S): Markus Metz
+ *
+ * PURPOSE: Split lines - helper tool for breaking lines
+ *
+ * COPYRIGHT: (C) 2012 by the GRASS Development Team
+ *
+ * This program is free software under the
+ * GNU General Public License (>=v2).
+ * Read the file COPYING that comes with GRASS
+ * for details.
+ *
+ ***************************************************************/
+#include <stdlib.h>
+#include <math.h>
+#include <grass/gis.h>
+#include <grass/vector.h>
+#include <grass/glocale.h>
+
+int split_line(struct Map_info *Map, int otype, struct line_pnts *Points,
+ struct line_cats *Cats, struct Map_info *Err, double split_distance);
+
+/* split lines
+ * threshold is determined automatically
+ * returns number of split points */
+int split_lines(struct Map_info *Map, int otype, struct Map_info *Err)
+{
+ int line, nlines, n_split_lines, n_splits_total, type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ double area_size, split_distance;
+ struct bound_box box;
+
+ nlines = Vect_get_num_lines(Map);
+ n_split_lines = 0;
+ for (line = 1; line <= nlines; line++) {
+ type = Vect_get_line_type(Map, line);
+ if ((type & otype) && (type & GV_LINES))
+ n_split_lines++;
+ }
+
+ if (n_split_lines < 50)
+ return 0;
+
+ Vect_get_map_box(Map, &box);
+ area_size = sqrt((box.E - box.W) * (box.N - box.S));
+
+ split_distance = area_size / log(n_split_lines);
+ /* divisor is the handle: increase divisor to decrease split_distance */
+ split_distance = split_distance / 10.;
+ G_debug(1, "area size: %f", area_size);
+ G_debug(1, "split distance: %f", split_distance);
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ n_splits_total = 0;
+ for (line = 1; line <= nlines; line++) {
+ int n_splits;
+
+ type = Vect_get_line_type(Map, line);
+ if (!((type & otype) && (type & GV_LINES)))
+ continue;
+
+ Vect_read_line(Map, Points, Cats, line);
+
+ /* can't split boundaries with only 2 vertices */
+ if (Points->n_points < 3)
+ continue;
+
+ n_splits = split_line(Map, type, Points, Cats, Err, split_distance);
+
+ if (n_splits)
+ Vect_delete_line(Map, line);
+
+ n_splits_total += n_splits;
+ }
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+
+ G_verbose_message(_("Line splits: %d"), n_splits_total);
+
+ return n_splits_total;
+}
+
+/* split a line using split_distance
+ * returns number of split points */
+int split_line(struct Map_info *Map, int otype, struct line_pnts *Points,
+ struct line_cats *Cats, struct Map_info *Err, double split_distance)
+{
+ int i, n_segs = 0;
+ double dist = 0., seg_dist, dx, dy;
+ struct line_pnts *OutPoints;
+
+ /* don't write zero length boundaries */
+ Vect_line_prune(Points);
+ if (Points->n_points < 2)
+ return 0;
+
+ /* can't split boundaries with only 2 vertices */
+ if (Points->n_points == 2) {
+ Vect_write_line(Map, otype, Points, Cats);
+ return 0;
+ }
+
+ OutPoints = Vect_new_line_struct();
+ Vect_append_point(OutPoints, Points->x[0], Points->y[0], Points->z[0]);
+ Vect_append_point(OutPoints, Points->x[1], Points->y[1], Points->z[1]);
+ dx = Points->x[1] - Points->x[0];
+ dy = Points->y[1] - Points->y[0];
+ dist = sqrt(dx * dx + dy * dy);
+
+ /* trying to keep line length smaller than split_distance
+ * alternative, less code: write line as soon as split_distance is exceeded */
+ for (i = 2; i < Points->n_points; i++) {
+ dx = Points->x[i] - Points->x[i - 1];
+ dy = Points->y[i] - Points->y[i - 1];
+ seg_dist = sqrt(dx * dx + dy * dy);
+ dist += seg_dist;
+ if (dist > split_distance) {
+ Vect_write_line(Map, otype, OutPoints, Cats);
+ Vect_reset_line(OutPoints);
+ dist = seg_dist;
+ Vect_append_point(OutPoints, Points->x[i - 1], Points->y[i - 1],
+ Points->z[i - 1]);
+ n_segs++;
+ }
+ Vect_append_point(OutPoints, Points->x[i], Points->y[i],
+ Points->z[i]);
+ }
+ /* write out remaining line points only when original line was split */
+ if (n_segs)
+ Vect_write_line(Map, otype, OutPoints, Cats);
+
+ Vect_destroy_line_struct(OutPoints);
+
+ return n_segs;
+}
Property changes on: grass/trunk/vector/v.clean/split.c
___________________________________________________________________
Added: svn:mime-type
+ text/x-csrc
Added: svn:eol-style
+ native
More information about the grass-commit
mailing list