/** * vu_get_tz_at_location: * * @vc: Position for which the time zone is desired * * Returns: TimeZone string of the nearest known location. String may be NULL. * * Use the k-d tree method (http://en.wikipedia.org/wiki/Kd-tree) to quickly retreive * the nearest location to the given position. */ gchar* vu_get_tz_at_location ( const VikCoord* vc ) { gchar *tz = NULL; if ( !vc || !kd ) return tz; struct LatLon ll; vik_coord_to_latlon ( vc, &ll ); double pt[2] = { ll.lat, ll.lon }; gdouble nearest; if ( !a_settings_get_double(VIK_SETTINGS_NEAREST_TZ_FACTOR, &nearest) ) nearest = 1.0; struct kdres *presults = kd_nearest_range ( kd, pt, nearest ); while( !kd_res_end( presults ) ) { double pos[2]; gchar *ans = (gchar*)kd_res_item ( presults, pos ); // compute the distance of the current result from the pt double dist = sqrt( dist_sq( pt, pos, 2 ) ); if ( dist < nearest ) { //printf( "NEARER node at (%.3f, %.3f, %.3f) is %.3f away is %s\n", pos[0], pos[1], pos[2], dist, ans ); nearest = dist; tz = ans; } kd_res_next ( presults ); } g_debug ( "TZ lookup found %d results - picked %s", kd_res_size(presults), tz ); kd_res_free ( presults ); return tz; }
int main(int argc, char **argv) { int i, num_pts = DEF_NUM_PTS; void *ptree; char *data, *pch; struct kdres *presults; double pos[3], dist; double pt[3] = { 0, 0, 1 }; double radius = 10; if(argc > 1 && isdigit(argv[1][0])) { num_pts = atoi(argv[1]); } if(!(data = malloc(num_pts))) { perror("malloc failed"); return 1; } srand( time(0) ); /* create a k-d tree for 3-dimensional points */ ptree = kd_create( 3 ); /* add some random nodes to the tree (assert nodes are successfully inserted) */ for( i=0; i<num_pts; i++ ) { data[i] = 'a' + i; assert( 0 == kd_insert3( ptree, rd(), rd(), rd(), &data[i] ) ); } /* find points closest to the origin and within distance radius */ presults = kd_nearest_range( ptree, pt, radius ); /* print out all the points found in results */ printf( "found %d results:\n", kd_res_size(presults) ); while( !kd_res_end( presults ) ) { /* get the data and position of the current result item */ pch = (char*)kd_res_item( presults, pos ); /* compute the distance of the current result from the pt */ dist = sqrt( dist_sq( pt, pos, 3 ) ); /* print out the retrieved data */ printf( "node at (%.3f, %.3f, %.3f) is %.3f away and has data=%c\n", pos[0], pos[1], pos[2], dist, *pch ); /* go to the next entry */ kd_res_next( presults ); } /* free our tree, results set, and other allocated memory */ free( data ); kd_res_free( presults ); kd_free( ptree ); return 0; }
// Takes a kdres set and returns a list of nodes GSList *opttree_kdtree_to_gslist (state_t * state, kdres_t *kdres) { GSList *node_list = NULL; kd_res_rewind (kdres); while (!kd_res_end(kdres)) { node_t * node_curr = kd_res_item_data (kdres); node_list = g_slist_prepend (node_list, node_curr); kd_res_next (kdres); } return node_list; }
// Find the nearest neighbor in the tree node_t* opttree_find_nearest_neighbor (opttree_t *self, state_t *state_from) { node_t *min_node = NULL; kdres_t *kdres = kd_nearest (self->kdtree, optsystem_get_state_key (self->optsys, state_from)); if (kd_res_end (kdres)) { printf ("ERROR: No nearest neighbors\n"); exit(1); } min_node = kd_res_item_data (kdres); kd_res_free (kdres); return min_node; }
int32_t PhotonMap::SelectNNearestPhotons(kdtree *map, PhotonPos *pp, const Vector &pos, float radius, int32_t n) { kdres *result = kd_nearest_range3f(map, pos.x, pos.y, pos.z, radius); Vector ppos; int nNow = 0; while ( !kd_res_end(result) ) { Photon *photon = (Photon *) kd_res_itemf(result, &(ppos.x)); float d = (ppos - pos).LengthSquared(); if ( nNow < n ) { pp[nNow++] = PhotonPos(photon, ppos, d); if ( nNow == n ) make_heap(pp, pp + n); } else { pop_heap(pp, pp + n); pp[n - 1] = PhotonPos(photon, ppos, d); push_heap(pp, pp + n); } kd_res_next(result); } kd_res_free(result); return nNow; }
int main(int argc, char **argv) { int i,j, vcount = 10; int tot_count = 101; void *kd[tot_count], *set[tot_count]; unsigned int msec, start; /* if(argc > 1 && isdigit(argv[1][0])) { vcount = atoi(argv[1]); } */ printf("inserting random vectors... "); /* Creating Trees correspinding to each age group */ for (i=0;i<tot_count;i++) kd[i]=kd_create(3); start = get_msec(); /* Reading Input File */ FILE *file; char *line = NULL; size_t len = 0; char read; file=fopen(argv[1], "r"); if (file == NULL) return 1; int a; double b; double c; double d; /* Inseting the person's co-ordinates and age in the respective trees */ while ((read = getline(&line, &len, file)) != -1) { convert(line, &a, &b, &c, &d); assert(kd_insert3(kd[a], b, c, d, 0) == 0); } if (line) free(line); msec = get_msec() - start; printf("%.3f sec\n", (float)msec / 1000.0); start = get_msec(); double lat, longitude, latitude; /** printf("range query returned %d items in %.5f sec\n", kd_res_size(set[0]), (float)msec / 1000.0); **/ int reqd_dist,index , ind; while(1){ printf("Enter How many top places you want\n"); scanf("%d",&reqd_dist); int counter = 0; int initial_radius = 100; printf("Enter the age of the person\n"); scanf("%d",&index); printf("Enter the co-ordinates of a person \n"); scanf("%f %f",&longitude,&latitude); double a_x, a_y,a_z; coordinates_to_lat(longitude, latitude, &a_x,&a_y,&a_z); int starting_index[101] ={0}; /* Copmuter Science */ int loop_break = 0; int end_index = index + sqrt(reqd_dist); if(end_index >= 101) end_index = 100; while(counter <= reqd_dist){ for (i=index ; i<= end_index ; i++){ set[i] = kd_nearest_range3(kd[i], a_x, a_y,a_z, initial_radius); /*printf("After %d\n",kd_res_size(set[i])); */ } /* TODO :: change sqrt(reqd_dist) to something else...... */ for(ind = index; ind <= end_index; ind++){ double x = 1, y = 1, z = 1; a = 1; while(starting_index[ind]){ kd_res_next(set[ind]); starting_index[ind]-=1; } while(a){ kd_res_item3(set[ind], &x, &y, &z); /*printf("%f %f %f\n",x,y,z);*/ lat_to_coordinates(x, y, z, &lat, &longitude); printf("%d %0.2f %0.2f\n",ind,lat, longitude); counter += 1; int val = kd_res_end(set[ind]); if(val == 1){ a = 0; break; } else{ a = kd_res_next(set[ind]); /*printf("%d\n",a);*/ } if(counter >= reqd_dist){ loop_break = 1; break; } } if(loop_break ==1) break; } for (i=index ; i<= end_index;i++){ starting_index[i] = kd_res_size(set[i]); } if(loop_break ==1) break; initial_radius += initial_radius; } } msec = get_msec() - start; /* for(i=1;i<tot_count;i++){ kd_res_free(set[i]); kd_free(kd[i]); } */ /** printf("range query returned %d items in %.5f sec\n", kd_res_size(set[i]), (float)msec / 1000.0); **/ /* printf("range query returned %d items in %.5f sec\n", kd_res_size(set), (float)msec / 1000.0); kd_res_free(set); kd_free(kd); */ return 0; }