find.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 <math.h>
00019 #include <grass/gis.h>
00020 #include <grass/Vect.h>
00021 
00022 #ifndef HUGE_VAL
00023 #define HUGE_VAL 9999999999999.0
00024 #endif
00025 
00035 int 
00036 Vect_find_node ( struct Map_info *Map,
00037                  double ux, double uy, double uz,
00038                  double maxdist, int with_z )
00039 {
00040     int i, nnodes, node;
00041     BOUND_BOX box;
00042     struct ilist *NList;
00043     double x, y, z;
00044     double cur_dist, dist;
00045 
00046     G_debug ( 3, "Vect_find_node() for %f %f %f maxdist = %f", ux, uy, uz, maxdist);
00047     NList = Vect_new_list ();
00048  
00049     /* Select all nodes in box */
00050     box.N = uy + maxdist;
00051     box.S = uy - maxdist;
00052     box.E = ux + maxdist;
00053     box.W = ux - maxdist;
00054     if (with_z) {
00055         box.T = uz + maxdist;
00056         box.B = uz - maxdist;
00057     } else {
00058         box.T = HUGE_VAL;
00059         box.B = -HUGE_VAL;
00060     }
00061         
00062     nnodes = Vect_select_nodes_by_box (Map, &box, NList);
00063     G_debug ( 3, " %d nodes in box", nnodes );
00064 
00065     if ( nnodes == 0 ) return 0;
00066 
00067     /* find nearest */
00068     cur_dist = PORT_DOUBLE_MAX;
00069     node = 0;
00070     for ( i = 0; i < nnodes; i++ ) {
00071         Vect_get_node_coor ( Map, NList->value[i], &x, &y, &z);
00072         dist = Vect_points_distance (  ux, uy, uz, x, y, z, with_z ); 
00073         if ( dist < cur_dist ) {
00074             cur_dist = dist;
00075             node = i;
00076         }
00077     }
00078     G_debug ( 3, "  nearest node %d in distance %f", NList->value[node], cur_dist );
00079 
00080     /* Check if in max distance */
00081     if ( cur_dist <= maxdist )
00082         return ( NList->value[node] );
00083     else
00084         return 0;
00085 }
00086 
00101 /* original dig_point_to_line() in grass50 */
00102 int 
00103 Vect_find_line ( struct Map_info *map,
00104                  double ux, double uy, double uz,
00105                  int type, double maxdist, int with_z,
00106                  int exclude ) /* If > 0 number of line which should be excluded from selection. */
00107                              /* May be useful if we need line neares to other one. Should be list? */
00108 {
00109   int choice;
00110   double new_dist;
00111   double cur_dist;
00112   int gotone;
00113   int i, line;
00114   static struct line_pnts *Points;
00115   static int first_time = 1;
00116   struct Plus_head *Plus;
00117   struct ilist *List;
00118   BOUND_BOX box;
00119   
00120   G_debug ( 3, "Vect_find_line() for %f %f %f type = %d maxdist = %f exclude = %d", 
00121                                      ux, uy, uz, type, maxdist, exclude);
00122     
00123   if (first_time) {
00124       Points = Vect_new_line_struct ();
00125       first_time = 0;
00126   }
00127   
00128   List = Vect_new_list ();
00129   
00130   Plus = &(map->plus);
00131   gotone = 0;
00132   choice = 0;
00133   cur_dist = HUGE_VAL;
00134 
00135   box.N = uy + maxdist; box.S = uy - maxdist;
00136   box.E = ux + maxdist; box.W = ux - maxdist;
00137   if ( with_z ) {
00138       box.T = uz + maxdist; box.B = uz - maxdist;
00139   } else {
00140       box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX;
00141   }
00142   
00143   Vect_select_lines_by_box ( map, &box, type, List );
00144   for (i = 0; i < List->n_values; i++) {
00145       line = List->value[i];
00146       if ( line == exclude ) continue;
00147 
00148       /* No more needed */
00149       /*
00150       Line = Plus->Line[line];  
00151       if ( Line == NULL ) continue;
00152       if ( !(type & Line->type) ) continue; 
00153       */
00154 
00155       Vect_read_line (map, Points, NULL, line);
00156       
00157       Vect_line_distance ( Points, ux, uy, uz, with_z, NULL, NULL, NULL, &new_dist, NULL, NULL);
00158       G_debug( 3, " line = %d distance = %f", line,  new_dist);
00159       if ((++gotone == 1) || (new_dist <= cur_dist)) {
00160           if (new_dist == cur_dist)
00161             {
00162               /* TODO */  
00163               /* choice = dig_center_check (map->Line, choice, a, ux, uy); */
00164               continue;
00165             }
00166           
00167           choice = line;
00168           cur_dist = new_dist;
00169        }
00170   }
00171   
00172   G_debug( 3, "min distance found = %f", cur_dist);
00173   if (cur_dist > maxdist)
00174       choice = 0;
00175 
00176   Vect_destroy_list ( List );
00177   return (choice);
00178 }
00179 
00189 /* original dig_point_to_area() in grass50 */
00190 int 
00191 Vect_find_area ( struct Map_info *Map, double x, double y)
00192 {
00193   int i, ret, area;
00194   static int first = 1;
00195   BOUND_BOX box;
00196   static struct ilist *List;
00197   
00198   G_debug ( 3, "Vect_find_area() x = %f y = %f", x, y );
00199   
00200   if ( first ) {
00201       List = Vect_new_list ();
00202       first = 0;
00203   }
00204   
00205   /* select areas by box */
00206   box.E = x; box.W = x; box.N = y; box.S = y; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX;
00207   Vect_select_areas_by_box (Map, &box, List);
00208   G_debug ( 3, "  %d areas selected by box", List->n_values );
00209   
00210   for (i = 0; i < List->n_values; i++) {
00211       area = List->value[i];
00212       ret = Vect_point_in_area (Map, area, x, y);
00213 
00214       G_debug ( 3, "    area = %d Vect_point_in_area() = %d", area, ret );
00215 
00216       if ( ret >= 1  )
00217           return ( area );
00218   }
00219   
00220   return 0;
00221 }
00222 
00234 /* original dig_point_to_area() in grass50 */
00235 int 
00236 Vect_find_island ( struct Map_info *Map, double x, double y)
00237 {
00238   int i, ret, island, current, current_size, size;
00239   static int first = 1;
00240   BOUND_BOX box;
00241   static struct ilist *List;
00242   static struct line_pnts *Points;
00243   
00244   G_debug ( 3, "Vect_find_island() x = %f y = %f", x, y );
00245   
00246   if ( first ) {
00247       List = Vect_new_list ();
00248       Points = Vect_new_line_struct ();
00249       first = 0;
00250   }
00251   
00252   /* select islands by box */
00253   box.E = x; box.W = x; box.N = y; box.S = y; box.T = PORT_DOUBLE_MAX; box.B = -PORT_DOUBLE_MAX;
00254   Vect_select_isles_by_box (Map, &box, List);
00255   G_debug ( 3, "  %d islands selected by box", List->n_values );
00256   
00257   current_size = -1;
00258   current = 0;
00259   for (i = 0; i < List->n_values; i++) {
00260       island = List->value[i];
00261       ret = Vect_point_in_island ( x, y, Map, island);
00262 
00263       if ( ret >= 1  ) { /* inside */
00264           if ( current > 0 ) { /* not first */
00265               if ( current_size == -1 ) { /* second */
00266                   G_begin_polygon_area_calculations();
00267                   Vect_get_isle_points (Map, current, Points);
00268                   current_size = G_area_of_polygon(Points->x, Points->y, Points->n_points);
00269               }
00270               
00271               Vect_get_isle_points (Map, island, Points);
00272               size = G_area_of_polygon(Points->x, Points->y, Points->n_points);
00273 
00274               if ( size < current_size ) {
00275                   current = island;
00276                   current_size = size;
00277               }
00278           } else { /* first */
00279               current = island;
00280           }
00281       }
00282   }
00283   
00284   return current;
00285 }
00286 

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