Question

given my current position (lat,long) I want to quickly find the nearest neighbor in a points of interest problem. Thus I intend to use an R-Tree database, which allows for quick lookup. However, first the database must be populated - of course. Therefore, I need to determine the rectangular regions that covers the area, where each region contains one point of interest.

My question is how do I preprocess the data, i.e. how do I subdivide the area into these rectangular sub-regions? (I want rectangular regions because they are easily added to the RTree - in contrast to more general Voronoi regions).

/John

Was it helpful?

Solution

Edit: The below approach works, but ignores the critical feature of R-trees -- that The splitting behavior of R-tree nodes is well defined, and maintains a balanced tree (through B-tree-like properties). So in fact, all you have to do is:

  1. Pick the maximum number of rectangles per page
  2. Create seed rectangles (use points furthest away from each other, centroids, whatever).
  3. For each point, choose a rectangle to put it into
    1. If it already falls into a single rectangle, put it in there
    2. If it does not, extend the rectangle that needs to be extended least (different ways to measure "least" exits -- area works)
    3. If multiple rectangles apply -- choose one based on how full it is, or some other heuristic
  4. If overflow occurs -- use the quadratic split to move things around...
  5. And so on, using R-tree algorithms straight out of a text book.

I think the method below is ok for finding your initial seed rectangles; but you don't want to populate your whole R-tree that way. Doing the splits and rebalancing all the time can be a bit expensive, so you will probably want to do a decent chunk of the work with the KD approach below; just not all of the work.


The KD approach: enclose everything in a rectangle.

If the number of points in the rectangle is > threshold, sweep in direction D until you cover half the points.

Divide into rectangles left and right (or above and below) the splitting point).

Call the same procedure recursively on the new rectangles, with the next direction (if you were going left to right, you will now go top to bottom, and vice versa).

The advantage this has over the divide-into-squares approach offered by another poster is that it accommodates skewed point distributions better.

OTHER TIPS

Oracle Spatial Cartridge documentation describes tessellation algorithm that can do what you want. In short:

  • enclose all your points in square
  • if square contains 1 point - index square
  • if square does not contain points - ignore it
  • if square contains more then 1 point
    • split square into 4 equal squares and repeat analysis for each new square

Result should be something like this:
alt text http://download-uk.oracle.com/docs/cd/A64702_01/doc/cartridg.805/a53264/sdo_ina5.gif

I think you a missing something in the problem statement. Assume you have N points (x, y) such that every point has a unique x- and y-coordinate. You can divide your area into N rectangles then by just dividing it into N vertical columns. But that does not help you to solve the nearest POI problem easily, does it? So I think you are thinking about something about the rectangle structure which you haven't articulated yet.

Illustration:

| | | | |5| | |
|1| | | | |6| |
| | |3| | | | |
| | | | | | | |
| |2| | | | | |
| | | | | | |7|
| | | |4| | | |

The numbers are POIs and the vertical lines show a subdivision into 7 rectangular areas. But clearly there isn't much "interesting" information in the subdivision. Is there some additional criterion on the subdivision which you haven't mentioned?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top