[GRASS-SVN] r54165 - grass/trunk/vector/v.overlay
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Dec 3 10:20:33 PST 2012
Author: mmetz
Date: 2012-12-03 10:20:33 -0800 (Mon, 03 Dec 2012)
New Revision: 54165
Modified:
grass/trunk/vector/v.overlay/area_area.c
grass/trunk/vector/v.overlay/line_area.c
grass/trunk/vector/v.overlay/local.h
grass/trunk/vector/v.overlay/main.c
Log:
v.overlay: use tmp vector
Modified: grass/trunk/vector/v.overlay/area_area.c
===================================================================
--- grass/trunk/vector/v.overlay/area_area.c 2012-12-03 15:34:03 UTC (rev 54164)
+++ grass/trunk/vector/v.overlay/area_area.c 2012-12-03 18:20:33 UTC (rev 54165)
@@ -3,7 +3,7 @@
*
* MODULE: v.overlay
*
- * AUTHOR(S): Radim Blazek
+ * AUTHOR(S): Radim Blazek, Markus Metz
*
******************************************************************************/
#include <stdlib.h>
@@ -18,22 +18,19 @@
/* for ilist qsort'ing and bsearch'ing */
static int cmp_int(const void *a, const void *b)
{
- int ai = *(int *)a;
- int bi = *(int *)b;
-
- return (ai < bi ? -1 : (ai > bi));
+ return (*(int *)a - *(int *)b);
}
-int area_area(struct Map_info *In, int *field, struct Map_info *Out,
- struct field_info *Fi, dbDriver * driver, int operator,
- int *ofield, ATTRIBUTES * attr, struct ilist *BList, double snap)
+int area_area(struct Map_info *In, int *field, struct Map_info *Tmp,
+ struct Map_info *Out, struct field_info *Fi,
+ dbDriver * driver, int operator, int *ofield,
+ ATTRIBUTES * attr, struct ilist *BList, double snap)
{
int ret, input, line, nlines, area, nareas;
int in_area, in_centr, out_cat;
struct line_pnts *Points;
struct line_cats *Cats;
CENTR *Centr;
- char *Del;
char buf[1000];
dbString stmt;
int nmodif;
@@ -53,7 +50,7 @@
G_message(_("Snapping boundaries with %g ..."), snap);
- /* snap boundaries in B to boundaries in A
+ /* snap boundaries in B to boundaries in A,
* not modifying boundaries in A */
if (BList->n_values > 1)
@@ -63,16 +60,16 @@
nlines = BList->n_values;
for (i = 0; i < nlines; i++) {
line = BList->value[i];
- Vect_read_line(Out, Points, Cats, line);
+ Vect_read_line(Tmp, Points, Cats, line);
/* select lines by box */
- Vect_get_line_box(Out, line, &box);
+ Vect_get_line_box(Tmp, line, &box);
box.E += snap;
box.W -= snap;
box.N += snap;
box.S -= snap;
box.T = 0.0;
box.B = 0.0;
- Vect_select_lines_by_box(Out, &box, GV_BOUNDARY, boxlist);
+ Vect_select_lines_by_box(Tmp, &box, GV_BOUNDARY, boxlist);
if (boxlist->n_values > 0) {
Vect_reset_list(reflist);
@@ -86,10 +83,10 @@
}
/* snap bline to alines */
- if (Vect_snap_line(Out, reflist, Points, snap, 0, NULL, NULL)) {
+ if (Vect_snap_line(Tmp, reflist, Points, snap, 0, NULL, NULL)) {
/* rewrite bline*/
- Vect_delete_line(Out, line);
- ret = Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
+ Vect_delete_line(Tmp, line);
+ ret = Vect_write_line(Tmp, GV_BOUNDARY, Points, Cats);
G_ilist_add(BList, ret);
snapped_lines++;
G_debug(3, "line %d snapped", line);
@@ -102,70 +99,71 @@
G_verbose_message(_("%d boundaries snapped"), snapped_lines);
}
- /* same procedure like for v.in.ogr
+ /* same procedure like for v.in.ogr:
* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
* are created. We must call Vect_break_lines(), Vect_remove_duplicates()
* and Vect_clean_small_angles_at_nodes() until no more small dangles are found */
do {
G_message(_("Breaking lines..."));
- Vect_break_lines_list(Out, NULL, BList, GV_BOUNDARY, NULL);
+ Vect_break_lines_list(Tmp, NULL, BList, GV_BOUNDARY, NULL);
/* Probably not necessary for LINE x AREA */
G_message(_("Removing duplicates..."));
- Vect_remove_duplicates(Out, GV_BOUNDARY, NULL);
+ Vect_remove_duplicates(Tmp, GV_BOUNDARY, NULL);
G_message(_("Cleaning boundaries at nodes..."));
nmodif =
- Vect_clean_small_angles_at_nodes(Out, GV_BOUNDARY, NULL);
+ Vect_clean_small_angles_at_nodes(Tmp, GV_BOUNDARY, NULL);
} while (nmodif > 0);
/* ?: May be result of Vect_break_lines() + Vect_remove_duplicates() any dangle or bridge?
* In that case, calls to Vect_remove_dangles() and Vect_remove_bridges() would be also necessary */
G_set_verbose(0);
- Vect_build_partial(Out, GV_BUILD_AREAS);
+ /* should be fast, be silent */
+ Vect_build_partial(Tmp, GV_BUILD_AREAS);
G_set_verbose(verbose);
- nlines = Vect_get_num_lines(Out);
+ nlines = Vect_get_num_lines(Tmp);
ret = 0;
for (line = 1; line <= nlines; line++) {
- if (!Vect_line_alive(Out, line))
+ if (!Vect_line_alive(Tmp, line))
continue;
- if (Vect_get_line_type(Out, line) == GV_BOUNDARY) {
+ if (Vect_get_line_type(Tmp, line) == GV_BOUNDARY) {
int left, rite;
- Vect_get_line_areas(Out, line, &left, &rite);
+ Vect_get_line_areas(Tmp, line, &left, &rite);
if (left == 0 || rite == 0) {
+ /* invalid boundary */
ret = 1;
break;
}
}
}
if (ret) {
- Vect_remove_dangles(Out, GV_BOUNDARY, -1, NULL);
- Vect_remove_bridges(Out, NULL, NULL, NULL);
+ Vect_remove_dangles(Tmp, GV_BOUNDARY, -1, NULL);
+ Vect_remove_bridges(Tmp, NULL, NULL, NULL);
}
G_set_verbose(0);
- Vect_build_partial(Out, GV_BUILD_NONE);
- Vect_build_partial(Out, GV_BUILD_BASE);
+ Vect_build_partial(Tmp, GV_BUILD_NONE);
+ Vect_build_partial(Tmp, GV_BUILD_BASE);
G_set_verbose(verbose);
G_message(_("Merging lines..."));
- Vect_merge_lines(Out, GV_BOUNDARY, NULL, NULL);
+ Vect_merge_lines(Tmp, GV_BOUNDARY, NULL, NULL);
/* Attach islands */
G_message(_("Attaching islands..."));
- Vect_build_partial(Out, GV_BUILD_NONE);
- Vect_build_partial(Out, GV_BUILD_ATTACH_ISLES);
+ /* can take some time, show messages */
+ Vect_build_partial(Tmp, GV_BUILD_ATTACH_ISLES);
-
/* Calculate new centroids for all areas */
- nareas = Vect_get_num_areas(Out);
+ nareas = Vect_get_num_areas(Tmp);
Centr = (CENTR *) G_malloc((nareas + 1) * sizeof(CENTR)); /* index from 1 ! */
for (area = 1; area <= nareas; area++) {
ret =
- Vect_get_point_in_area(Out, area, &(Centr[area].x),
+ Vect_get_point_in_area(Tmp, area, &(Centr[area].x),
&(Centr[area].y));
if (ret < 0) {
G_warning(_("Cannot calculate area centroid"));
@@ -365,30 +363,30 @@
}
}
+ Vect_write_line(Tmp, GV_CENTROID, Points, Cats);
Vect_write_line(Out, GV_CENTROID, Points, Cats);
}
- /* Build topology and remove boundaries with area without centroid on both sides */
- G_message(_("Attaching centroids..."));
- Vect_build_partial(Out, GV_BUILD_ALL);
+ G_set_verbose(0);
+ /* should be fast, be silent */
+ Vect_build_partial(Tmp, GV_BUILD_CENTROIDS);
+ G_set_verbose(verbose);
+ /* Copy valid boundaries to final output */
+ nlines = Vect_get_num_lines(Tmp);
- /* Create a list of lines to be deleted */
- nlines = Vect_get_num_lines(Out);
- Del = (char *)G_calloc(nlines + 1, sizeof(char)); /* index from 1 ! */
-
for (line = 1; line <= nlines; line++) {
int i, ltype, side[2], centr[2];
G_percent(line, nlines, 1); /* must be before any continue */
- if (!Vect_line_alive(Out, line))
+ if (!Vect_line_alive(Tmp, line))
continue;
- ltype = Vect_read_line(Out, NULL, NULL, line);
+ ltype = Vect_read_line(Tmp, Points, Cats, line);
if (!(ltype & GV_BOUNDARY))
continue;
- Vect_get_line_areas(Out, line, &side[0], &side[1]);
+ Vect_get_line_areas(Tmp, line, &side[0], &side[1]);
for (i = 0; i < 2; i++) {
if (side[i] == 0) { /* This should not happen ! */
@@ -400,29 +398,18 @@
area = side[i];
}
else { /* island */
- area = Vect_get_isle_area(Out, abs(side[i]));
+ area = Vect_get_isle_area(Tmp, abs(side[i]));
}
if (area > 0)
- centr[i] = Vect_get_area_centroid(Out, area);
+ centr[i] = Vect_get_area_centroid(Tmp, area);
else
centr[i] = 0;
}
- if (!centr[0] && !centr[1])
- Del[line] = 1;
+ if (centr[0] || centr[1])
+ Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
}
- /* Delete boundaries */
- G_set_verbose(0);
- Vect_build_partial(Out, GV_BUILD_NONE);
- Vect_build_partial(Out, GV_BUILD_BASE);
- G_set_verbose(verbose);
- for (line = 1; line <= nlines; line++) {
- if (Del[line])
- Vect_delete_line(Out, line);
- }
- G_free(Del);
-
return 0;
}
Modified: grass/trunk/vector/v.overlay/line_area.c
===================================================================
--- grass/trunk/vector/v.overlay/line_area.c 2012-12-03 15:34:03 UTC (rev 54164)
+++ grass/trunk/vector/v.overlay/line_area.c 2012-12-03 18:20:33 UTC (rev 54165)
@@ -2,7 +2,7 @@
*
* MODULE: v.overlay
*
- * AUTHOR(S): Radim Blazek
+ * AUTHOR(S): Radim Blazek, Markus Metz
*
******************************************************************************/
#include <stdlib.h>
@@ -49,9 +49,10 @@
return Cats->n_cats;
}
-int line_area(struct Map_info *In, int *field, struct Map_info *Out,
- struct field_info *Fi, dbDriver * driver, int operator,
- int *ofield, ATTRIBUTES * attr, struct ilist *BList)
+int line_area(struct Map_info *In, int *field, struct Map_info *Tmp,
+ struct Map_info *Out, struct field_info *Fi,
+ dbDriver * driver, int operator, int *ofield,
+ ATTRIBUTES * attr, struct ilist *BList)
{
int line, nlines, ncat;
struct line_pnts *Points;
@@ -67,11 +68,11 @@
db_init_string(&stmt);
G_message(_("Breaking lines..."));
- Vect_break_lines_list(Out, NULL, BList, GV_LINE | GV_BOUNDARY, NULL);
+ Vect_break_lines_list(Tmp, NULL, BList, GV_LINE | GV_BOUNDARY, NULL);
G_message(_("Merging lines..."));
- Vect_merge_lines(Out, GV_LINE, NULL, NULL);
+ Vect_merge_lines(Tmp, GV_LINE, NULL, NULL);
- nlines = Vect_get_num_lines(Out);
+ nlines = Vect_get_num_lines(Tmp);
/* Warning!: cleaning process (break) creates new vertices which are usually slightly
* moved (RE), to compare such new vertex with original input is a problem?
@@ -87,13 +88,12 @@
G_percent(line, nlines, 1); /* must be before any continue */
- if (!Vect_line_alive(Out, line))
+ if (!Vect_line_alive(Tmp, line))
continue;
- ltype = Vect_read_line(Out, Points, Cats, line);
+ ltype = Vect_read_line(Tmp, Points, Cats, line);
if (ltype == GV_BOUNDARY) { /* No more needed */
- Vect_delete_line(Out, line);
continue;
}
@@ -112,8 +112,9 @@
*/
/* Note/TODO: the test done is quite simple, check the point in the middle of segment.
- * If the line overpals the boundary, the result may be both outside and inside
+ * If the line overlaps the boundary, the result may be both outside and inside
* this should be solved (check angles?)
+ * This should not happen if Vect_break_lines_list() works correctly
*/
G_debug(3, "line = %d", line);
@@ -239,11 +240,8 @@
}
}
- Vect_rewrite_line(Out, line, ltype, Points, OCats);
+ Vect_write_line(Out, ltype, Points, OCats);
}
- else {
- Vect_delete_line(Out, line);
- }
}
return 0;
Modified: grass/trunk/vector/v.overlay/local.h
===================================================================
--- grass/trunk/vector/v.overlay/local.h 2012-12-03 15:34:03 UTC (rev 54164)
+++ grass/trunk/vector/v.overlay/local.h 2012-12-03 18:20:33 UTC (rev 54165)
@@ -30,9 +30,11 @@
ATTR *find_attr(ATTRIBUTES * attributes, int cat);
-int area_area(struct Map_info *In, int *field, struct Map_info *Out,
- struct field_info *Fi, dbDriver * driver, int operator,
- int *ofield, ATTRIBUTES * attr, struct ilist *BList, double snap_thresh);
-int line_area(struct Map_info *In, int *field, struct Map_info *Out,
- struct field_info *Fi, dbDriver * driver, int operator,
- int *ofield, ATTRIBUTES * attr, struct ilist *BList);
+int area_area(struct Map_info *In, int *field, struct Map_info *Tmp,
+ struct Map_info *Out, struct field_info *Fi,
+ dbDriver * driver, int operator, int *ofield,
+ ATTRIBUTES * attr, struct ilist *BList, double snap_thresh);
+int line_area(struct Map_info *In, int *field, struct Map_info *Tmp,
+ struct Map_info *Out, struct field_info *Fi,
+ dbDriver * driver, int operator, int *ofield,
+ ATTRIBUTES * attr, struct ilist *BList);
Modified: grass/trunk/vector/v.overlay/main.c
===================================================================
--- grass/trunk/vector/v.overlay/main.c 2012-12-03 15:34:03 UTC (rev 54164)
+++ grass/trunk/vector/v.overlay/main.c 2012-12-03 18:20:33 UTC (rev 54165)
@@ -22,7 +22,8 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-
+#include <sys/types.h>
+#include <unistd.h>
#include <grass/gis.h>
#include <grass/dbmi.h>
#include <grass/vector.h>
@@ -39,7 +40,8 @@
struct Option *in_opt[2], *out_opt, *type_opt[2], *field_opt[2],
*ofield_opt, *operator_opt, *snap_opt;
struct Flag *table_flag;
- struct Map_info In[2], Out;
+ struct Map_info In[2], Out, Tmp;
+ char *tmpname;
struct line_pnts *Points, *Points2;
struct line_cats *Cats;
struct ilist *BList;
@@ -181,6 +183,9 @@
Vect_set_map_name(&Out, "Output from v.overlay");
Vect_set_person(&Out, G_whoami());
Vect_hist_command(&Out);
+
+ G_asprintf(&tmpname, "%s_tmp_%d", out_opt->answer, getpid());
+ Vect_open_new(&Tmp, tmpname, WITHOUT_Z);
/* Create dblinks */
if (ofield[0] > 0) {
@@ -212,7 +217,7 @@
BList = Vect_new_list();
verbose = G_verbose();
G_set_verbose(0);
- Vect_build_partial(&Out, GV_BUILD_BASE);
+ Vect_build_partial(&Tmp, GV_BUILD_BASE);
G_set_verbose(verbose);
for (input = 0; input < 2; input++) {
int ncats, index, nlines_out, newline;
@@ -269,7 +274,7 @@
Points->z[v]);
}
- newline = Vect_write_line(&Out, ltype, Points2, Cats);
+ newline = Vect_write_line(&Tmp, ltype, Points2, Cats);
if (input == 1)
G_ilist_add(BList, newline);
@@ -277,13 +282,16 @@
}
}
else {
- newline = Vect_write_line(&Out, ltype, Points, Cats);
+ newline = Vect_write_line(&Tmp, ltype, Points, Cats);
if (input == 1)
G_ilist_add(BList, newline);
}
nlines_out++;
}
if (nlines_out == 0) {
+ Vect_close(&Tmp);
+ Vect_delete(tmpname);
+ Vect_close(&Out);
Vect_delete(out_opt->answer);
G_fatal_error(_("No %s features found in vector map <%s>. Verify '%s' parameter."),
type_opt[input]->answer, Vect_get_full_name(&(In[input])),
@@ -538,16 +546,18 @@
/* AREA x AREA */
if (type[0] == GV_AREA) {
- area_area(In, field, &Out, Fi, driver, operator, ofield, attr, BList, snap_thresh);
+ area_area(In, field, &Tmp, &Out, Fi, driver, operator, ofield, attr, BList, snap_thresh);
}
else { /* LINE x AREA */
- line_area(In, field, &Out, Fi, driver, operator, ofield, attr, BList);
+ line_area(In, field, &Tmp, &Out, Fi, driver, operator, ofield, attr, BList);
}
+
+ Vect_close(&Tmp);
+ Vect_delete(tmpname);
- G_message(_("Rebuilding topology..."));
- Vect_build_partial(&Out, GV_BUILD_NONE);
+ /* Build topology to show the final result and prepare for Vect_close() */
+ G_message(_("Building topology..."));
Vect_build(&Out);
- /* Build topology to show the final result and prepare for Vect_close() */
if (driver) {
/* Close table */
More information about the grass-commit
mailing list