简体   繁体   中英

How to determine n locations inside a circle efficiently?

Given this the scenario:

  1. We have the order of 1,000,000 points around the world, specified by longitude and latitude;
  2. We have a circle c based on a point pc (specified by longitude and latitude) and a radius rc
  3. We want to efficiently determine which of the points are in the circle

I'm developing in C# and the locations stored in SQL server 2008.

So as I see it I have these 3 options:

  1. Store the locations as longitude latitude floats and perform the calculations in C#.

  2. Store the locations as geographical data types and perform the calculations in SQL server 2008 like this:

     CREATE TABLE UserLocations [UserId] [bigint] NOT NULL, [CurrentLocation] [geography] NOT NULL ALTER PROCEDURE sp_GetCurrentUsersInRange @userPoint geography, @RangeInMeters int AS BEGIN select UserId from UserLocations where @userPoint.STDistance(CurrentLocation) <= @RangeInMeters and UserId <> @userId END 

    Disadvantages: problems using geographical data with LinqToSQL and LinqToEntities.

    Advantages: using dbms processing power over large data, and usage of the SQL Server spatial index.

3.Using some web service such as google's geolocation and calculation services. So far I didn't find such web service.

Which is the most efficient in your opinion? Please justify your answer.

Thank you

My naive approach would be to define a lat/long bounding box around the point pc and select from the database using BETWEEN on those box coordinates. Statistically around 79% of the points passing that test will be within the circle. A simple check in the code will weed out the ones outside the circle.

I say naive because I'm not familiar with the geometry capabilities of SQL Server.

An alternate to using a geometric circle, you could SELECT all records within a certain distance (using STDistance) from the circle's center. But I don't know whether or not it would be faster or slower than the intersection solution you have listed.

If the 100,000 points are static, you could probably code something in C#, loading the list into memory and using bounding boxes to minimize the usage of the distance calculation (ie, Haversine). It would probably be faster because you're minimizing I/O.

However, if the points are not static (or you have them stored in SQL Server), I'd opt for using SQL Server, it's a lot easier. You'd definitely want to create the proper spatial indices. SQL Server's spacial indexing is pretty good, you may find that it can even out-perform the in-memory solution I listed above.

I haven't used LINQ for this type of work, I usually do it old-school with a SqlConnection and a Reader. I have read that LINQ mixed with Spatials is a problem.

I don't know about Google, do they have such a web service?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM