area.c

Go to the documentation of this file.
00001 /*
00002 ****************************************************************************
00003 *
00004 * MODULE:       Vector library 
00005 *               
00006 * AUTHOR(S):    Original author CERL, probably Dave Gerdes or Mike Higgins.
00007 *               Update to GRASS 5.7 Radim Blazek and David D. Gray.
00008 *
00009 * PURPOSE:      Higher level functions for reading/writing/manipulating vectors.
00010 *
00011 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00012 *
00013 *               This program is free software under the GNU General Public
00014 *               License (>=v2). Read the file COPYING that comes with GRASS
00015 *               for details.
00016 *
00017 *****************************************************************************/
00018 #include <stdlib.h>
00019 #include <grass/gis.h>
00020 #include <grass/Vect.h>
00021 
00031 int 
00032 Vect_get_area_points (
00033                        struct Map_info *Map,
00034                        int area,
00035                        struct line_pnts *BPoints)
00036 {
00037   int i, line, aline, dir;
00038   struct Plus_head *Plus;
00039   P_AREA *Area;
00040   static int first_time = 1;
00041   static struct line_pnts *Points;
00042   
00043   G_debug ( 3, "Vect_get_area_points(): area = %d", area );     
00044   BPoints->n_points = 0;
00045 
00046   Plus = &(Map->plus);
00047   Area = Plus->Area[area];
00048 
00049   if ( Area == NULL ) { /* dead area */
00050       G_warning ("Attempt to read points of nonexisting area" ); 
00051       return -1;      /* error , because we should not read dead areas */
00052   }
00053   
00054   if (first_time == 1){
00055       Points = Vect_new_line_struct (); 
00056       first_time = 0;
00057   }
00058 
00059   G_debug ( 3, "  n_lines = %d", Area->n_lines );       
00060   for (i = 0; i < Area->n_lines; i++)
00061     {
00062       line = Area->lines[i];
00063       aline = abs (line);
00064       G_debug ( 3, "  append line(%d) = %d", i, line ); 
00065 
00066       if (0 > Vect_read_line (Map, Points, NULL, aline)) {
00067           G_fatal_error ( "Cannot read line %d",  aline );
00068       }
00069       
00070       G_debug ( 3, "  line n_points = %d", Points->n_points );  
00071 
00072       if ( line > 0 )
00073           dir = GV_FORWARD;
00074       else 
00075           dir = GV_BACKWARD;
00076 
00077       Vect_append_points ( BPoints, Points, dir);  
00078       if ( i != (Area->n_lines - 1) ) /* all but not last */
00079          BPoints->n_points--; 
00080       G_debug ( 3, "  area n_points = %d", BPoints->n_points ); 
00081     }
00082 
00083   return (BPoints->n_points);
00084 }
00085 
00095 int 
00096 Vect_get_isle_points (
00097                        struct Map_info *Map,
00098                        int isle,
00099                        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     {
00121       line = Isle->lines[i];
00122       aline = abs (line);
00123       G_debug ( 3, "  append line(%d) = %d", i, line ); 
00124 
00125       if (0 > Vect_read_line (Map, Points, NULL, aline)) {
00126           G_fatal_error ( "Cannot read line %d",  aline );
00127       }
00128       
00129       G_debug ( 3, "  line n_points = %d", Points->n_points );  
00130 
00131       if ( line > 0 )
00132           dir = GV_FORWARD;
00133       else 
00134           dir = GV_BACKWARD;
00135 
00136       Vect_append_points ( BPoints, Points, dir);  
00137       if ( i != (Isle->n_lines - 1) ) /* all but not last */
00138          BPoints->n_points--; 
00139       G_debug ( 3, "  isle n_points = %d", BPoints->n_points ); 
00140     }
00141 
00142   return (BPoints->n_points);
00143 }
00144 
00153 int 
00154 Vect_get_area_centroid (
00155                        struct Map_info *Map,
00156                        int area )
00157 {
00158   struct Plus_head *Plus;
00159   P_AREA *Area;
00160   
00161   G_debug ( 3, "Vect_get_area_centroid(): area = %d", area );   
00162 
00163   Plus = &(Map->plus);
00164   Area = Plus->Area[area];
00165 
00166   if ( Area == NULL ) G_fatal_error ( "Attempt to read topo for dead area (%d)", area);
00167   
00168   return ( Area->centroid );
00169 }
00170 
00180 int 
00181 Vect_get_area_boundaries (
00182                        struct Map_info *Map,
00183                        int area,
00184                        struct ilist *List )
00185 {
00186   int i, line;
00187   struct Plus_head *Plus;
00188   P_AREA *Area;
00189   
00190   G_debug ( 3, "Vect_get_area_boundaries(): area = %d", area ); 
00191 
00192   Vect_reset_list ( List );
00193   
00194   Plus = &(Map->plus);
00195   Area = Plus->Area[area];
00196 
00197   if ( Area == NULL ) G_fatal_error ( "Attempt to read topo for dead area (%d)", area);
00198 
00199   for (i = 0; i < Area->n_lines; i++) {
00200       line = Area->lines[i];
00201       Vect_list_append ( List, line );
00202   }
00203    
00204   return ( List->n_values );
00205 }
00206 
00218 int 
00219 Vect_get_isle_boundaries (
00220                        struct Map_info *Map,
00221                        int isle,
00222                        struct ilist *List )
00223 {
00224   int i, line;
00225   struct Plus_head *Plus;
00226   P_ISLE *Isle;
00227   
00228   G_debug ( 3, "Vect_get_isle_boundaries(): isle = %d", isle ); 
00229 
00230   Vect_reset_list ( List );
00231   
00232   Plus = &(Map->plus);
00233   Isle = Plus->Isle[isle];
00234 
00235   if ( Isle == NULL ) G_fatal_error ( "Attempt to read topo for dead isle (%d)", isle);
00236 
00237   for (i = 0; i < Isle->n_lines; i++) {
00238       line = Isle->lines[i];
00239       Vect_list_append ( List, line );
00240   }
00241    
00242   return ( List->n_values );
00243 }
00244 
00253 int 
00254 Vect_get_area_num_isles (
00255                        struct Map_info *Map,
00256                        int area )
00257 {
00258   struct Plus_head *Plus;
00259   P_AREA *Area;
00260   
00261   G_debug ( 3, "Vect_get_area_num_isles(): area = %d", area );  
00262 
00263   Plus = &(Map->plus);
00264   Area = Plus->Area[area];
00265   
00266   if ( Area == NULL ) G_fatal_error ( "Attempt to read topo for dead area (%d)", area);
00267   
00268   G_debug ( 3, "  n_isles = %d", Area->n_isles );       
00269   
00270   return ( Area->n_isles );
00271 
00272 }
00273 
00283 int 
00284 Vect_get_area_isle (
00285                        struct Map_info *Map,
00286                        int area,
00287                        int isle)
00288 {
00289   struct Plus_head *Plus;
00290   P_AREA *Area;
00291   
00292   G_debug ( 3, "Vect_get_area_isle(): area = %d isle = %d", area, isle );       
00293 
00294   Plus = &(Map->plus);
00295   Area = Plus->Area[area];
00296   
00297   if ( Area == NULL ) G_fatal_error ( "Attempt to read topo for dead area (%d)", area);
00298 
00299   G_debug ( 3, "  -> isle = %d", Area->isles[isle] );   
00300   
00301   return ( Area->isles[isle] );
00302 }
00303 
00311 int 
00312 Vect_get_isle_area ( struct Map_info *Map, int isle)
00313 {
00314   struct Plus_head *Plus;
00315   P_ISLE *Isle;
00316   
00317   G_debug ( 3, "Vect_get_isle_area(): isle = %d", isle );       
00318 
00319   Plus = &(Map->plus);
00320   Isle = Plus->Isle[isle];
00321   
00322   if ( Isle == NULL ) G_fatal_error ( "Attempt to read topo for dead isle (%d)", isle);
00323 
00324   G_debug ( 3, "  -> area = %d", Isle->area );  
00325   
00326   return ( Isle->area );
00327 }
00328 
00329 
00337 double 
00338 Vect_area_perimeter ( struct line_pnts *Points )
00339 {
00340   return Vect_line_length ( Points );
00341 }
00342 
00343 
00353 int 
00354 Vect_point_in_area (
00355                        struct Map_info *Map,
00356                        int area,
00357                        double x, double y)
00358 {
00359   int    i, isle;
00360   struct Plus_head *Plus;
00361   P_AREA *Area;
00362   int poly;
00363   
00364   Plus = &(Map->plus);
00365   Area = Plus->Area[area];
00366   if ( Area == NULL ) return 0;
00367 
00368   poly = Vect_point_in_area_outer_ring ( x, y, Map, area);
00369   if ( poly == 0) return 0; /* includes area boundary (poly == 2), OK? */
00370 
00371   /* check if in islands */
00372   for (i = 0; i < Area->n_isles; i++) {
00373       isle = Area->isles[i];
00374       poly = Vect_point_in_island ( x, y, Map, isle);
00375       if (poly >= 1) return 0; /* excludes island boundary (poly == 2), OK? */
00376   }
00377 
00378   return 1;
00379 }
00380 
00390 double 
00391 Vect_get_area_area (
00392                        struct Map_info *Map,
00393                        int area)
00394 {
00395   struct Plus_head *Plus;
00396   P_AREA *Area;
00397   struct line_pnts * Points;
00398   double size;
00399   int i;
00400   static int first_time = 1;
00401   
00402   G_debug ( 3, "Vect_get_area_area(): area = %d", area );       
00403 
00404   if (first_time == 1) {
00405       G_begin_polygon_area_calculations();
00406       first_time = 0;
00407   }
00408 
00409   Points = Vect_new_line_struct();
00410   Plus = &(Map->plus);
00411   Area = Plus->Area[area];
00412  
00413   Vect_get_area_points(Map, area, Points);
00414   size = G_area_of_polygon(Points->x, Points->y, Points->n_points);
00415 
00416   /* substructing island areas */
00417   for(i = 0; i < Area->n_isles; i++) {
00418       Vect_get_isle_points(Map, Area->isles[i], Points);
00419       size -= G_area_of_polygon(Points->x, Points->y, Points->n_points);
00420   }
00421   
00422   Vect_destroy_line_struct(Points);
00423   
00424   G_debug ( 3, "    area = %f", size ); 
00425   
00426   return ( size );
00427 }
00428 
00436 int
00437 Vect_get_area_cats ( struct Map_info *Map, int area, struct line_cats *Cats ) 
00438 {
00439     int centroid;
00440 
00441     Vect_reset_cats ( Cats );
00442     
00443     centroid = Vect_get_area_centroid ( Map, area );
00444     if( centroid > 0 ) {
00445         Vect_read_line (Map, NULL, Cats, centroid );
00446     } else {
00447         return 1; /* no centroid */
00448     }
00449     
00450      
00451     return 0;
00452 }
00453 
00461 int
00462 Vect_get_area_cat ( struct Map_info *Map, int area, int field ) 
00463 {
00464     int i;
00465     static struct line_cats *Cats = NULL;
00466 
00467     if ( !Cats ) 
00468         Cats = Vect_new_cats_struct();
00469     else
00470         Vect_reset_cats ( Cats );
00471 
00472     if ( Vect_get_area_cats ( Map, area, Cats ) == 1 || Cats->n_cats == 0) {
00473         return -1;
00474     }
00475     
00476     for ( i = 0; i < Cats->n_cats; i++ ) {
00477         if ( Cats->field[i] == field ) {
00478             return Cats->cat[i];
00479         }
00480     }
00481      
00482     return -1;
00483 }
00484 

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5