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 "gis.h"
00020 #include "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 
00338 int 
00339 Vect_point_in_area (
00340                        struct Map_info *Map,
00341                        int area,
00342                        double x, double y)
00343 {
00344   int    i, isle;
00345   struct Plus_head *Plus;
00346   P_AREA *Area;
00347   int poly;
00348   
00349   Plus = &(Map->plus);
00350   Area = Plus->Area[area];
00351   if ( Area == NULL ) return 0;
00352 
00353   poly = Vect_point_in_area_outer_ring ( x, y, Map, area);
00354   if ( poly == 0) return 0; /* includes area boundary (poly == 2), OK? */
00355 
00356   /* check if in islands */
00357   for (i = 0; i < Area->n_isles; i++) {
00358       isle = Area->isles[i];
00359       poly = Vect_point_in_island ( x, y, Map, isle);
00360       if (poly >= 1) return 0; /* excludes island boundary (poly == 2), OK? */
00361   }
00362 
00363   return 1;
00364 }
00365 
00375 double 
00376 Vect_get_area_area (
00377                        struct Map_info *Map,
00378                        int area)
00379 {
00380   struct Plus_head *Plus;
00381   P_AREA *Area;
00382   struct line_pnts * Points;
00383   double size;
00384   int i;
00385   static int first_time = 1;
00386   
00387   G_debug ( 3, "Vect_get_area_area(): area = %d", area );       
00388 
00389   if (first_time == 1) {
00390       G_begin_polygon_area_calculations();
00391       first_time = 0;
00392   }
00393 
00394   Points = Vect_new_line_struct();
00395   Plus = &(Map->plus);
00396   Area = Plus->Area[area];
00397  
00398   Vect_get_area_points(Map, area, Points);
00399   size = G_area_of_polygon(Points->x, Points->y, Points->n_points);
00400 
00401   /* substructing island areas */
00402   for(i = 0; i < Area->n_isles; i++) {
00403       Vect_get_isle_points(Map, Area->isles[i], Points);
00404       size -= G_area_of_polygon(Points->x, Points->y, Points->n_points);
00405   }
00406   
00407   Vect_destroy_line_struct(Points);
00408   
00409   G_debug ( 3, "    area = %f", size ); 
00410   
00411   return ( size );
00412 }
00413 
00421 int
00422 Vect_get_area_cats ( struct Map_info *Map, int area, struct line_cats *Cats ) 
00423 {
00424     int centroid;
00425 
00426     Vect_reset_cats ( Cats );
00427     
00428     centroid = Vect_get_area_centroid ( Map, area );
00429     if( centroid > 0 ) {
00430         Vect_read_line (Map, NULL, Cats, centroid );
00431     } else {
00432         return 1; /* no centroid */
00433     }
00434     
00435      
00436     return 0;
00437 }
00438 
00446 int
00447 Vect_get_area_cat ( struct Map_info *Map, int area, int field ) 
00448 {
00449     int i;
00450     static struct line_cats *Cats = NULL;
00451 
00452     if ( !Cats ) 
00453         Cats = Vect_new_cats_struct();
00454     else
00455         Vect_reset_cats ( Cats );
00456 
00457     if ( Vect_get_area_cats ( Map, area, Cats ) == 1 || Cats->n_cats == 0) {
00458         return -1;
00459     }
00460     
00461     for ( i = 0; i < Cats->n_cats; i++ ) {
00462         if ( Cats->field[i] == field ) {
00463             return Cats->cat[i];
00464         }
00465     }
00466      
00467     return -1;
00468 }
00469 

Generated on Sat Jul 22 22:05:56 2006 for GRASS by  doxygen 1.4.7