Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closest Point on a Map

I am making a program where you can click on a map to see a "close-up view" of the area around it, such as on Google Maps.

When a user clicks on the map, it gets the X and Y coordinate of where they clicked.

Let's assume that I have an array of booleans of where these close-up view pictures are:

public static boolean[][] view_set=new boolean[Map.width][Map.height];
//The array of where pictures are.  The map has a width of 3313, and a height of 3329.

The program searches through a folder, where images are named to where the X and Y coordinate of where it was taken on the map. The folder contains the following images (and more, but I'll only list five):

2377,1881.jpg, 2384,1980.jpg, 2389,1923.jpg, 2425,1860.jpg, 2475,1900.jpg

This means that:

view_set[2377][1881]=true;
view_set[2384][1980]=true;
view_set[2389][1923]=true;
view_set[2425][1860]=true;
view_set[2475][1900]=true;

If a user clicks at the X and Y of, for example, 2377,1882, then I need the program to figure out which image is closest (the answer in this case would be 2377,1881).

Any help would be appreciated, Thanks.

like image 654
Runis Avatar asked Aug 18 '11 18:08

Runis


People also ask

How do you find the closest point to a set of points?

The closest pair is the minimum of the closest pairs within each half and the closest pair between the two halves. To split the point set in two, we find the x-median of the points and use that as a pivot. Finding the closest pair of points in each half is subproblem that is solved recursively.

How do you measure distance on a map?

If the scale is a verbal statement (i.e. "1 inch equals 1 mile"), determine the distance by simply measuring it with a ruler. For example, if the scale says 1 inch = 1 mile, then for every inch between the two points on the map, the real distance on the ground is that number in miles.


1 Answers

Your boolean[][] is not a good datastructure for this problem, at least if it is not really dense (e.g. normally a point with close-up view is available in the surrounding 3×3 or maybe 5×5 square).

You want a 2-D-map with nearest-neighbor search. A useful data structure for this goal is the QuadTree. This is a tree of degree 4, used to represent spatial data. (I'm describing here the "Region QuadTree with point data".)

Basically, it divides a rectangle in four about equal size rectangles, and subdivides each of the rectangles further if there is more than one point in it.

So a node in your tree is one of these:

  • a empty leaf node (corresponding to a rectangle without points in it)
  • a leaf node containing exactly one point (corresponding to a rectangle with one point in it)
  • a inner node with four child nodes (corresponding to a rectangle with more than one point in it)

(In implementations, we can replace empty leaf nodes with a null-pointer in its parent.)

To find a point (or "the node a point would be in"), we start at the root node, look if our point is north/south/east/west of the dividing point, and go to the corresponding child node. We continue this until we arrive at some leaf node.

  • For adding a new point, we either wind up with an empty node - then we can put the new point here. If we end up at a node with already a point in it, create four child nodes (by splitting the rectangle) and add both points to the appropriate child node. (This might be the same, then repeat recursively.)

  • For the nearest-neighbor search, we will either wind up with an empty node - then we back up one level, and look at the other child nodes of this parent (comparing each distance). If we reach a child node with one point in it, we measure the distance of our search point to this point. If it is smaller than the distance to the edges or the node, we are done. Otherwise we will have to look at the points in the neighboring nodes, too, and compare the results here, taking the minimum. (We will have to look at at most four points, I think.)

  • For removal, after finding a point, we make its node empty. If the parent node now contains only one point, we replace it by a one-point leaf node.

The search and adding/removing are in O(depth) time complexity, where the maximum depth is limited by log((map length+width)/minimal distance of two points in your structure), and average depth is depending on the distribution of the points (e.g. the average distance to the next point), more or less.

Space needed is depending on number of points and average depth of the tree.

There are some variants of this data structure (for example splitting a node only when there are more than X points in it, or splitting not necessarily in the middle), to optimize the space usage and avoid too large depths of the tree.

like image 181
Paŭlo Ebermann Avatar answered Sep 29 '22 17:09

Paŭlo Ebermann