GRASS Programmer's Manual  6.4.1(2011)
remove_duplicates.c
Go to the documentation of this file.
00001 
00020 #include <stdlib.h>
00021 #include <grass/gis.h>
00022 #include <grass/Vect.h>
00023 #include <grass/glocale.h>
00024 
00037 void
00038 Vect_remove_duplicates(struct Map_info *Map, int type, struct Map_info *Err)
00039 {
00040     struct line_pnts *APoints, *BPoints;
00041     struct line_cats *ACats, *BCats, *Cats;
00042     int i, j, c, atype, btype, bline;
00043     int nlines, nbcats_orig;
00044     BOUND_BOX ABox;
00045     struct ilist *List;
00046     int ndupl;
00047 
00048 
00049     APoints = Vect_new_line_struct();
00050     BPoints = Vect_new_line_struct();
00051     ACats = Vect_new_cats_struct();
00052     BCats = Vect_new_cats_struct();
00053     Cats = Vect_new_cats_struct();
00054     List = Vect_new_list();
00055 
00056     nlines = Vect_get_num_lines(Map);
00057 
00058     G_debug(1, "nlines =  %d", nlines);
00059     /* Go through all lines in vector, for each select lines which overlap MBR of
00060      *  this line and check if some of them is identical. If someone is identical
00061      *  remove current line. (In each step just one line is deleted)
00062      */
00063 
00064     ndupl = 0;
00065 
00066     for (i = 1; i <= nlines; i++) {
00067         G_percent(i, nlines, 1);
00068         if (!Vect_line_alive(Map, i))
00069             continue;
00070 
00071         atype = Vect_read_line(Map, APoints, ACats, i);
00072         if (!(atype & type))
00073             continue;
00074 
00075         Vect_line_box(APoints, &ABox);
00076         Vect_select_lines_by_box(Map, &ABox, type, List);
00077         G_debug(3, "  %d lines selected by box", List->n_values);
00078 
00079         for (j = 0; j < List->n_values; j++) {
00080             bline = List->value[j];
00081             G_debug(3, "  j = %d bline = %d", j, bline);
00082             if (i == bline)
00083                 continue;
00084 
00085             btype = Vect_read_line(Map, BPoints, BCats, bline);
00086 
00087             /* check for duplicates */
00088             if (!Vect_line_check_duplicate(APoints, BPoints, Vect_is_3d(Map)))
00089                 continue;
00090 
00091             /* Lines area identical -> remove current */
00092             if (Err) {
00093                 Vect_write_line(Err, atype, APoints, ACats);
00094             }
00095 
00096             Vect_delete_line(Map, i);
00097 
00098             /* Merge categories */
00099             nbcats_orig = BCats->n_cats;
00100 
00101             for (c = 0; c < ACats->n_cats; c++)
00102                 Vect_cat_set(BCats, ACats->field[c], ACats->cat[c]);
00103 
00104             if (BCats->n_cats > nbcats_orig) {
00105                 G_debug(4, "cats merged: n_cats %d -> %d", nbcats_orig,
00106                         BCats->n_cats);
00107                 Vect_rewrite_line(Map, bline, btype, BPoints, BCats);
00108             }
00109 
00110             ndupl++;
00111 
00112             break;              /* line was deleted -> take the next one */
00113         }
00114         nlines = Vect_get_num_lines(Map);       /* For future when lines with cats will be rewritten */
00115         G_debug(3, "nlines =  %d\n", nlines);
00116     }
00117 }
00118 
00128 int Vect_line_check_duplicate(const struct line_pnts *APoints,
00129                               const struct line_pnts *BPoints, int with_z)
00130 {
00131     int k;
00132     int npoints;
00133     int forw, backw;
00134 
00135     if (APoints->n_points != BPoints->n_points)
00136         return 0;
00137 
00138     npoints = APoints->n_points;
00139 
00140     /* Forward */
00141     forw = 1;
00142     for (k = 0; k < APoints->n_points; k++) {
00143         if (APoints->x[k] != BPoints->x[k] ||
00144             APoints->y[k] != BPoints->y[k] ||
00145             (with_z && APoints->z[k] != BPoints->z[k])) {
00146             forw = 0;
00147             break;
00148         }
00149     }
00150 
00151     /* Backward */
00152     backw = 1;
00153     for (k = 0; k < APoints->n_points; k++) {
00154         if (APoints->x[k] != BPoints->x[npoints - k - 1] ||
00155             APoints->y[k] != BPoints->y[npoints - k - 1] ||
00156             (with_z && APoints->z[k] != BPoints->z[npoints - k - 1])) {
00157             backw = 0;
00158             break;
00159         }
00160     }
00161 
00162     if (!forw && !backw)
00163         return 0;
00164 
00165     return 1;
00166 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines