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) {
00053 G_warning(_("Attempt to read points of nonexistent area"));
00054 return -1;
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))
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))
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;
00359
00360
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;
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
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;
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 }