GRASS Programmer's Manual
6.4.1(2011)
|
00001 00021 #include <stdlib.h> 00022 #include <grass/gis.h> 00023 #include <grass/Vect.h> 00024 #include <grass/glocale.h> 00025 00036 int 00037 Vect_get_area_points(struct Map_info *Map, 00038 int area, struct line_pnts *BPoints) 00039 { 00040 int i, line, aline, dir; 00041 struct Plus_head *Plus; 00042 P_AREA *Area; 00043 static int first_time = 1; 00044 static struct line_pnts *Points; 00045 00046 G_debug(3, "Vect_get_area_points(): area = %d", area); 00047 BPoints->n_points = 0; 00048 00049 Plus = &(Map->plus); 00050 Area = Plus->Area[area]; 00051 00052 if (Area == NULL) { /* dead area */ 00053 G_warning(_("Attempt to read points of nonexistent area")); 00054 return -1; /* error , because we should not read dead areas */ 00055 } 00056 00057 if (first_time == 1) { 00058 Points = Vect_new_line_struct(); 00059 first_time = 0; 00060 } 00061 00062 G_debug(3, " n_lines = %d", Area->n_lines); 00063 for (i = 0; i < Area->n_lines; i++) { 00064 line = Area->lines[i]; 00065 aline = abs(line); 00066 G_debug(3, " append line(%d) = %d", i, line); 00067 00068 if (0 > Vect_read_line(Map, Points, NULL, aline)) { 00069 G_fatal_error("Cannot read line %d", aline); 00070 } 00071 00072 G_debug(3, " line n_points = %d", Points->n_points); 00073 00074 if (line > 0) 00075 dir = GV_FORWARD; 00076 else 00077 dir = GV_BACKWARD; 00078 00079 Vect_append_points(BPoints, Points, dir); 00080 if (i != (Area->n_lines - 1)) /* all but not last */ 00081 BPoints->n_points--; 00082 G_debug(3, " area n_points = %d", BPoints->n_points); 00083 } 00084 00085 return (BPoints->n_points); 00086 } 00087 00097 int 00098 Vect_get_isle_points(struct Map_info *Map, 00099 int isle, struct line_pnts *BPoints) 00100 { 00101 int i, line, aline, dir; 00102 struct Plus_head *Plus; 00103 P_ISLE *Isle; 00104 static int first_time = 1; 00105 static struct line_pnts *Points; 00106 00107 G_debug(3, "Vect_get_isle_points(): isle = %d", isle); 00108 BPoints->n_points = 0; 00109 00110 Plus = &(Map->plus); 00111 Isle = Plus->Isle[isle]; 00112 00113 if (first_time == 1) { 00114 Points = Vect_new_line_struct(); 00115 first_time = 0; 00116 } 00117 00118 G_debug(3, " n_lines = %d", Isle->n_lines); 00119 for (i = 0; i < Isle->n_lines; i++) { 00120 line = Isle->lines[i]; 00121 aline = abs(line); 00122 G_debug(3, " append line(%d) = %d", i, line); 00123 00124 if (0 > Vect_read_line(Map, Points, NULL, aline)) { 00125 G_fatal_error(_("Unable to read line %d"), aline); 00126 } 00127 00128 G_debug(3, " line n_points = %d", Points->n_points); 00129 00130 if (line > 0) 00131 dir = GV_FORWARD; 00132 else 00133 dir = GV_BACKWARD; 00134 00135 Vect_append_points(BPoints, Points, dir); 00136 if (i != (Isle->n_lines - 1)) /* all but not last */ 00137 BPoints->n_points--; 00138 G_debug(3, " isle n_points = %d", BPoints->n_points); 00139 } 00140 00141 return (BPoints->n_points); 00142 } 00143 00153 int Vect_get_area_centroid(struct Map_info *Map, int area) 00154 { 00155 struct Plus_head *Plus; 00156 P_AREA *Area; 00157 00158 G_debug(3, "Vect_get_area_centroid(): area = %d", area); 00159 00160 Plus = &(Map->plus); 00161 Area = Plus->Area[area]; 00162 00163 if (Area == NULL) 00164 G_fatal_error(_("Attempt to read topo for dead area (%d)"), area); 00165 00166 return (Area->centroid); 00167 } 00168 00178 int 00179 Vect_get_area_boundaries(struct Map_info *Map, int area, struct ilist *List) 00180 { 00181 int i, line; 00182 struct Plus_head *Plus; 00183 P_AREA *Area; 00184 00185 G_debug(3, "Vect_get_area_boundaries(): area = %d", area); 00186 00187 Vect_reset_list(List); 00188 00189 Plus = &(Map->plus); 00190 Area = Plus->Area[area]; 00191 00192 if (Area == NULL) 00193 G_fatal_error(_("Attempt to read topo for dead area (%d)"), area); 00194 00195 for (i = 0; i < Area->n_lines; i++) { 00196 line = Area->lines[i]; 00197 Vect_list_append(List, line); 00198 } 00199 00200 return (List->n_values); 00201 } 00202 00212 int 00213 Vect_get_isle_boundaries(struct Map_info *Map, int isle, struct ilist *List) 00214 { 00215 int i, line; 00216 struct Plus_head *Plus; 00217 P_ISLE *Isle; 00218 00219 G_debug(3, "Vect_get_isle_boundaries(): isle = %d", isle); 00220 00221 Vect_reset_list(List); 00222 00223 Plus = &(Map->plus); 00224 Isle = Plus->Isle[isle]; 00225 00226 if (Isle == NULL) 00227 G_fatal_error("Attempt to read topo for dead isle (%d)", isle); 00228 00229 for (i = 0; i < Isle->n_lines; i++) { 00230 line = Isle->lines[i]; 00231 Vect_list_append(List, line); 00232 } 00233 00234 return (List->n_values); 00235 } 00236 00246 int Vect_get_area_num_isles(struct Map_info *Map, int area) 00247 { 00248 struct Plus_head *Plus; 00249 P_AREA *Area; 00250 00251 G_debug(3, "Vect_get_area_num_isles(): area = %d", area); 00252 00253 Plus = &(Map->plus); 00254 Area = Plus->Area[area]; 00255 00256 if (Area == NULL) 00257 G_fatal_error(_("Attempt to read topo for dead area (%d)"), area); 00258 00259 G_debug(3, " n_isles = %d", Area->n_isles); 00260 00261 return (Area->n_isles); 00262 00263 } 00264 00275 int Vect_get_area_isle(struct Map_info *Map, int area, int isle) 00276 { 00277 struct Plus_head *Plus; 00278 P_AREA *Area; 00279 00280 G_debug(3, "Vect_get_area_isle(): area = %d isle = %d", area, isle); 00281 00282 Plus = &(Map->plus); 00283 Area = Plus->Area[area]; 00284 00285 if (Area == NULL) 00286 G_fatal_error(_("Attempt to read topo for dead area (%d)"), area); 00287 00288 G_debug(3, " -> isle = %d", Area->isles[isle]); 00289 00290 return (Area->isles[isle]); 00291 } 00292 00302 int Vect_get_isle_area(struct Map_info *Map, int isle) 00303 { 00304 struct Plus_head *Plus; 00305 P_ISLE *Isle; 00306 00307 G_debug(3, "Vect_get_isle_area(): isle = %d", isle); 00308 00309 Plus = &(Map->plus); 00310 Isle = Plus->Isle[isle]; 00311 00312 if (Isle == NULL) 00313 G_fatal_error(_("Attempt to read topo for dead isle (%d)"), isle); 00314 00315 G_debug(3, " -> area = %d", Isle->area); 00316 00317 return (Isle->area); 00318 } 00319 00320 00328 double Vect_area_perimeter(struct line_pnts *Points) 00329 { 00330 return Vect_line_length(Points); 00331 } 00332 00333 00344 int Vect_point_in_area(struct Map_info *Map, int area, double x, double y) 00345 { 00346 int i, isle; 00347 struct Plus_head *Plus; 00348 P_AREA *Area; 00349 int poly; 00350 00351 Plus = &(Map->plus); 00352 Area = Plus->Area[area]; 00353 if (Area == NULL) 00354 return 0; 00355 00356 poly = Vect_point_in_area_outer_ring(x, y, Map, area); 00357 if (poly == 0) 00358 return 0; /* includes area boundary (poly == 2), OK? */ 00359 00360 /* check if in islands */ 00361 for (i = 0; i < Area->n_isles; i++) { 00362 isle = Area->isles[i]; 00363 poly = Vect_point_in_island(x, y, Map, isle); 00364 if (poly >= 1) 00365 return 0; /* excludes island boundary (poly == 2), OK? */ 00366 } 00367 00368 return 1; 00369 } 00370 00379 double Vect_get_area_area(struct Map_info *Map, int area) 00380 { 00381 struct Plus_head *Plus; 00382 P_AREA *Area; 00383 struct line_pnts *Points; 00384 double size; 00385 int i; 00386 static int first_time = 1; 00387 00388 G_debug(3, "Vect_get_area_area(): area = %d", area); 00389 00390 if (first_time == 1) { 00391 G_begin_polygon_area_calculations(); 00392 first_time = 0; 00393 } 00394 00395 Points = Vect_new_line_struct(); 00396 Plus = &(Map->plus); 00397 Area = Plus->Area[area]; 00398 00399 Vect_get_area_points(Map, area, Points); 00400 size = G_area_of_polygon(Points->x, Points->y, Points->n_points); 00401 00402 /* substructing island areas */ 00403 for (i = 0; i < Area->n_isles; i++) { 00404 Vect_get_isle_points(Map, Area->isles[i], Points); 00405 size -= G_area_of_polygon(Points->x, Points->y, Points->n_points); 00406 } 00407 00408 Vect_destroy_line_struct(Points); 00409 00410 G_debug(3, " area = %f", size); 00411 00412 return (size); 00413 } 00414 00425 int Vect_get_area_cats(struct Map_info *Map, int area, struct line_cats *Cats) 00426 { 00427 int centroid; 00428 00429 Vect_reset_cats(Cats); 00430 00431 centroid = Vect_get_area_centroid(Map, area); 00432 if (centroid > 0) { 00433 Vect_read_line(Map, NULL, Cats, centroid); 00434 } 00435 else { 00436 return 1; /* no centroid */ 00437 } 00438 00439 00440 return 0; 00441 } 00442 00453 int Vect_get_area_cat(struct Map_info *Map, int area, int field) 00454 { 00455 int i; 00456 static struct line_cats *Cats = NULL; 00457 00458 if (!Cats) 00459 Cats = Vect_new_cats_struct(); 00460 else 00461 Vect_reset_cats(Cats); 00462 00463 if (Vect_get_area_cats(Map, area, Cats) == 1 || Cats->n_cats == 0) { 00464 return -1; 00465 } 00466 00467 for (i = 0; i < Cats->n_cats; i++) { 00468 if (Cats->field[i] == field) { 00469 return Cats->cat[i]; 00470 } 00471 } 00472 00473 return -1; 00474 }