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         if (!Vect_line_alive(Map, i))
00068             continue;
00069 
00070         atype = Vect_read_line(Map, APoints, ACats, i);
00071         if (!(atype & type))
00072             continue;
00073 
00074         Vect_line_box(APoints, &ABox);
00075         Vect_select_lines_by_box(Map, &ABox, type, List);
00076         G_debug(3, "  %d lines selected by box", List->n_values);
00077 
00078         for (j = 0; j < List->n_values; j++) {
00079             bline = List->value[j];
00080             G_debug(3, "  j = %d bline = %d", j, bline);
00081             if (i == bline)
00082                 continue;
00083 
00084             btype = Vect_read_line(Map, BPoints, BCats, bline);
00085 
00086             /* check for duplicates */
00087             if (!Vect_line_check_duplicate(APoints, BPoints, Vect_is_3d(Map)))
00088                 continue;
00089 
00090             /* Lines area identical -> remove current */
00091             if (Err) {
00092                 Vect_write_line(Err, atype, APoints, ACats);
00093             }
00094 
00095             Vect_delete_line(Map, i);
00096 
00097             /* Merge categories */
00098             nbcats_orig = BCats->n_cats;
00099 
00100             for (c = 0; c < ACats->n_cats; c++)
00101                 Vect_cat_set(BCats, ACats->field[c], ACats->cat[c]);
00102 
00103             if (BCats->n_cats > nbcats_orig) {
00104                 G_debug(4, "cats merged: n_cats %d -> %d", nbcats_orig,
00105                         BCats->n_cats);
00106                 Vect_rewrite_line(Map, bline, btype, BPoints, BCats);
00107             }
00108 
00109             ndupl++;
00110 
00111             break;              /* line was deleted -> take the next one */
00112         }
00113         nlines = Vect_get_num_lines(Map);       /* For future when lines with cats will be rewritten */
00114         G_debug(3, "nlines =  %d\n", nlines);
00115     }
00116 }
00117 
00127 int Vect_line_check_duplicate(const struct line_pnts *APoints,
00128                               const struct line_pnts *BPoints, int with_z)
00129 {
00130     int k;
00131     int npoints;
00132     int forw, backw;
00133 
00134     if (APoints->n_points != BPoints->n_points)
00135         return 0;
00136 
00137     npoints = APoints->n_points;
00138 
00139     /* Forward */
00140     forw = 1;
00141     for (k = 0; k < APoints->n_points; k++) {
00142         if (APoints->x[k] != BPoints->x[k] ||
00143             APoints->y[k] != BPoints->y[k] ||
00144             (with_z && APoints->z[k] != BPoints->z[k])) {
00145             forw = 0;
00146             break;
00147         }
00148     }
00149 
00150     /* Backward */
00151     backw = 1;
00152     for (k = 0; k < APoints->n_points; k++) {
00153         if (APoints->x[k] != BPoints->x[npoints - k - 1] ||
00154             APoints->y[k] != BPoints->y[npoints - k - 1] ||
00155             (with_z && APoints->z[k] != BPoints->z[npoints - k - 1])) {
00156             backw = 0;
00157             break;
00158         }
00159     }
00160 
00161     if (!forw && !backw)
00162         return 0;
00163 
00164     return 1;
00165 }
Generated on Tue Apr 6 13:28:10 2010 for GRASS Programmer's Manual by  doxygen 1.6.3