00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
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
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
00081 if ( cur_dist <= maxdist )
00082 return ( NList->value[node] );
00083 else
00084 return 0;
00085 }
00086
00101
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 )
00107
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
00149
00150
00151
00152
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
00163
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
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
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
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
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 ) {
00264 if ( current > 0 ) {
00265 if ( current_size == -1 ) {
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 {
00279 current = island;
00280 }
00281 }
00282 }
00283
00284 return current;
00285 }
00286