GRASS Programmer's Manual
6.4.2(2012)
|
00001 00023 #include <string.h> 00024 #include <grass/Vect.h> 00025 #include <grass/glocale.h> 00026 00027 int Vect_overlay_and(struct Map_info *, int, struct ilist *, struct ilist *, 00028 struct Map_info *, int, struct ilist *, struct ilist *, 00029 struct Map_info *); 00030 00039 int Vect_overlay_str_to_operator(const char *str) 00040 { 00041 00042 if (strcmp(str, GV_ON_AND) == 0) 00043 return GV_O_AND; 00044 else if (strcmp(str, GV_ON_OVERLAP) == 0) 00045 return GV_O_OVERLAP; 00046 00047 return -1; 00048 } 00049 00064 int Vect_overlay(struct Map_info *AMap, int atype, struct ilist *AList, struct ilist *AAList, /* map A */ 00065 struct Map_info *BMap, int btype, struct ilist *BList, struct ilist *BAList, /* map B */ 00066 int operator, struct Map_info *OMap) 00067 { /* output map */ 00068 switch (operator) { 00069 case GV_O_AND: 00070 Vect_overlay_and(AMap, atype, AList, AAList, BMap, btype, BList, 00071 BAList, OMap); 00072 break; 00073 default: 00074 G_fatal_error("Vect_overlay(): %s", _("unknown operator")); 00075 } 00076 00077 return 0; 00078 } 00079 00101 int 00102 Vect_overlay_and(struct Map_info *AMap, int atype, struct ilist *AList, 00103 struct ilist *AAList, struct Map_info *BMap, int btype, 00104 struct ilist *BList, struct ilist *BAList, 00105 struct Map_info *OMap) 00106 { 00107 int i, j, k, node, line, altype, bltype, oltype, area, centr; 00108 struct line_pnts *Points; 00109 struct line_cats *ACats, *BCats, *OCats; 00110 struct ilist *AOList, *BOList; 00111 00112 /* TODO: support Lists */ 00113 00114 Points = Vect_new_line_struct(); 00115 ACats = Vect_new_cats_struct(); 00116 BCats = Vect_new_cats_struct(); 00117 OCats = Vect_new_cats_struct(); 00118 AOList = Vect_new_list(); 00119 BOList = Vect_new_list(); 00120 00121 /* TODO: support all types; at present only point x point, area x point and point x area supported */ 00122 if ((atype & GV_LINES) || (btype & GV_LINES)) 00123 G_warning(_("Overlay: line/boundary types not supported by AND operator")); 00124 00125 if ((atype & GV_AREA) && (btype & GV_AREA)) 00126 G_warning(_("Overlay: area x area types not supported by AND operator")); 00127 00128 /* TODO: more points in one node in one map */ 00129 00130 /* point x point: select all points with identical coordinates in both maps */ 00131 if ((atype & GV_POINTS) && (btype & GV_POINTS)) { /* both points and centroids */ 00132 G_debug(3, "overlay: AND: point x point"); 00133 for (i = 1; i <= Vect_get_num_lines(AMap); i++) { 00134 altype = Vect_read_line(AMap, Points, ACats, i); 00135 if (!(altype & GV_POINTS)) 00136 continue; 00137 00138 node = 00139 Vect_find_node(BMap, Points->x[0], Points->y[0], Points->z[0], 00140 0, 1); 00141 G_debug(3, "overlay: node = %d", node); 00142 if (node == 0) 00143 continue; 00144 00145 Vect_reset_cats(OCats); 00146 00147 for (j = 0; j < Vect_get_node_n_lines(BMap, node); j++) { 00148 line = Vect_get_node_line(BMap, node, j); 00149 bltype = Vect_read_line(BMap, NULL, BCats, line); 00150 if (!(bltype & GV_POINTS)) 00151 continue; 00152 00153 /* Identical points found -> write out */ 00154 /* TODO: do something if fields in ACats and BCats are identical */ 00155 for (k = 0; k < ACats->n_cats; k++) 00156 Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); 00157 00158 for (k = 0; k < BCats->n_cats; k++) 00159 Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); 00160 00161 /* TODO: what to do if one type is GV_POINT and second GV_CENTROID */ 00162 oltype = altype; 00163 Vect_write_line(OMap, oltype, Points, OCats); 00164 Vect_list_append(AOList, i); /* add to list of written lines */ 00165 Vect_list_append(BOList, line); 00166 break; 00167 } 00168 } 00169 } 00170 00171 /* TODO: check only labeled areas */ 00172 /* point x area: select points from A in areas in B */ 00173 if ((atype & GV_POINTS) && (btype & GV_AREA)) { /* both points and centroids */ 00174 G_debug(3, "overlay: AND: point x area"); 00175 00176 for (i = 1; i <= Vect_get_num_lines(AMap); i++) { 00177 altype = Vect_read_line(AMap, Points, ACats, i); 00178 if (!(altype & GV_POINTS)) 00179 continue; 00180 00181 area = Vect_find_area(BMap, Points->x[0], Points->y[0]); 00182 if (area == 0) 00183 continue; 00184 00185 Vect_reset_cats(OCats); 00186 00187 /* TODO: do something if fields in ACats and BCats are identical */ 00188 for (k = 0; k < ACats->n_cats; k++) 00189 Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); 00190 00191 centr = Vect_get_area_centroid(BMap, area); 00192 if (centr > 0) { 00193 bltype = Vect_read_line(BMap, NULL, BCats, centr); 00194 for (k = 0; k < BCats->n_cats; k++) 00195 Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); 00196 } 00197 00198 /* Check if not yet written */ 00199 if (!(Vect_val_in_list(AOList, i))) { 00200 Vect_write_line(OMap, altype, Points, OCats); 00201 Vect_list_append(AOList, i); 00202 } 00203 00204 } 00205 } 00206 /* area x point: select points from B in areas in A */ 00207 if ((btype & GV_POINTS) && (atype & GV_AREA)) { /* both points and centroids */ 00208 G_debug(3, "overlay: AND: area x point"); 00209 00210 for (i = 1; i <= Vect_get_num_lines(BMap); i++) { 00211 bltype = Vect_read_line(BMap, Points, BCats, i); 00212 if (!(bltype & GV_POINTS)) 00213 continue; 00214 00215 area = Vect_find_area(AMap, Points->x[0], Points->y[0]); 00216 if (area == 0) 00217 continue; 00218 00219 Vect_reset_cats(OCats); 00220 00221 /* TODO: do something if fields in ACats and BCats are identical */ 00222 for (k = 0; k < BCats->n_cats; k++) 00223 Vect_cat_set(OCats, BCats->field[k], BCats->cat[k]); 00224 00225 centr = Vect_get_area_centroid(AMap, area); 00226 if (centr > 0) { 00227 altype = Vect_read_line(AMap, NULL, ACats, centr); 00228 for (k = 0; k < ACats->n_cats; k++) 00229 Vect_cat_set(OCats, ACats->field[k], ACats->cat[k]); 00230 } 00231 00232 /* Check if not yet written */ 00233 if (!(Vect_val_in_list(BOList, i))) { 00234 Vect_write_line(OMap, bltype, Points, OCats); 00235 Vect_list_append(BOList, i); 00236 } 00237 00238 } 00239 } 00240 00241 return 0; 00242 }