[GRASS-SVN] r63307 - grass/trunk/vector/v.proj
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Nov 30 23:46:23 PST 2014
Author: mmetz
Date: 2014-11-30 23:46:23 -0800 (Sun, 30 Nov 2014)
New Revision: 63307
Modified:
grass/trunk/vector/v.proj/main.c
Log:
v.proj: add line densification
Modified: grass/trunk/vector/v.proj/main.c
===================================================================
--- grass/trunk/vector/v.proj/main.c 2014-12-01 00:44:13 UTC (rev 63306)
+++ grass/trunk/vector/v.proj/main.c 2014-12-01 07:46:23 UTC (rev 63307)
@@ -44,15 +44,16 @@
const char *gbase;
char date[40], mon[4];
struct GModule *module;
- struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt;
+ struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt, *smax;
struct Key_Value *in_proj_keys, *in_unit_keys;
struct Key_Value *out_proj_keys, *out_unit_keys;
- struct line_pnts *Points;
+ struct line_pnts *Points, *Points2;
struct line_cats *Cats;
struct Map_info Map;
struct Map_info Out_Map;
struct bound_box src_box, tgt_box;
int nowrap = 0, recommend_nowrap = 0;
+ double lmax;
struct
{
struct Flag *list; /* list files in source location */
@@ -99,6 +100,15 @@
ibaseopt->key_desc = "path";
ibaseopt->guisection = _("Source");
+ smax = G_define_option();
+ smax->key = "smax";
+ smax->type = TYPE_DOUBLE;
+ smax->required = NO;
+ smax->answer = "10000";
+ smax->label = _("Maximum segment length in meters in output vector map");
+ smax->description = _("Increases accuracy of reprojected shapes, disable with smax=0");
+ smax->guisection = _("Target");
+
omapopt = G_define_standard_option(G_OPT_V_OUTPUT);
omapopt->required = NO;
omapopt->description = _("Name for output vector map (default: input)");
@@ -157,9 +167,15 @@
if (!ibaseopt->answer && strcmp(iloc_name, G_location()) == 0)
G_fatal_error(_("Input and output locations can not be the same"));
+ lmax = atof(smax->answer);
+ if (lmax < 0)
+ lmax = 0;
+
Out_proj = G_projection();
if (Out_proj == PROJECTION_LL && flag.wrap->answer)
nowrap = 1;
+
+ G_begin_distance_calculations();
/* Change the location here and then come back */
@@ -259,6 +275,7 @@
/* Initialize the Point / Cat structure */
Points = Vect_new_line_struct();
+ Points2 = Vect_new_line_struct();
Cats = Vect_new_cats_struct();
/* test if latlon wrapping to -180,180 should be disabled */
@@ -384,6 +401,10 @@
sprintf(date, "%s %d %d", mon, day, yr);
Vect_set_date(&Out_Map, date);
+ /* line densification works only with vector topology */
+ if (Map.format != GV_FORMAT_NATIVE)
+ lmax = 0;
+
/* Cycle through all lines */
Vect_rewind(&Map);
i = 0;
@@ -399,14 +420,84 @@
G_fatal_error(_("Reading input vector map"));
if (type == -2)
break;
- if (pj_do_transform(Points->n_points, Points->x, Points->y,
- flag.transformz->answer ? Points->z : NULL,
- &info_in, &info_out) < 0) {
- G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
- Vect_get_full_name(&Map), ilocopt->answer);
+
+ Vect_line_prune(Points);
+ if (lmax > 0 && (type & GV_LINES) && Points->n_points > 1) {
+ double x1, y1, z1, x2, y2, z2;
+ double dx, dy, dz;
+ double l;
+ int i, n;
+
+ Vect_reset_line(Points2);
+ for (i = 0; i < Points->n_points - 1; i++) {
+ x1 = Points->x[i];
+ y1 = Points->y[i];
+ z1 = Points->z[i];
+ n = i + 1;
+ x2 = Points->x[n];
+ y2 = Points->y[n];
+ z2 = Points->z[n];
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ dz = z2 - z1;
+
+ if (pj_do_transform(1, &x1, &y1,
+ flag.transformz->answer ? &z1 : NULL,
+ &info_in, &info_out) < 0) {
+ G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
+ Vect_get_full_name(&Map), ilocopt->answer);
+ }
+
+ if (pj_do_transform(1, &x2, &y2,
+ flag.transformz->answer ? &z2 : NULL,
+ &info_in, &info_out) < 0) {
+ G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
+ Vect_get_full_name(&Map), ilocopt->answer);
+ }
+
+ Vect_append_point(Points2, x1, y1, z1);
+
+ l = G_distance(x1, y1, x2, y2);
+
+ if (l > lmax) {
+ int j;
+ double x, y, z;
+
+ x1 = Points->x[i];
+ y1 = Points->y[i];
+ z1 = Points->z[i];
+
+ n = ceil(l / lmax);
+
+ for (j = 1; j < n; j++) {
+ x = x1 + dx * j / n;
+ y = y1 + dy * j / n;
+ z = z1 + dz * j / n;
+
+ if (pj_do_transform(1, &x, &y,
+ flag.transformz->answer ? &z : NULL,
+ &info_in, &info_out) < 0) {
+ G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
+ Vect_get_full_name(&Map), ilocopt->answer);
+ }
+ Vect_append_point(Points2, x, y, z);
+ }
+ }
+ }
+ Vect_append_point(Points2, x2, y2, z2);
+ Vect_write_line(&Out_Map, type, Points2, Cats); /* write line */
}
+ else {
+ if (pj_do_transform(Points->n_points, Points->x, Points->y,
+ flag.transformz->answer ? Points->z : NULL,
+ &info_in, &info_out) < 0) {
+ G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"),
+ Vect_get_full_name(&Map), ilocopt->answer);
+ }
- Vect_write_line(&Out_Map, type, Points, Cats); /* write line */
+ Vect_write_line(&Out_Map, type, Points, Cats); /* write line */
+ }
} /* end lines section */
G_progress(1, 1);
More information about the grass-commit
mailing list