问题
Given this the scenario:
- We have the order of 1,000,000 points around the world, specified by longitude and latitude;
- We have a circle c based on a point pc (specified by longitude and latitude) and a radius rc
- 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:
Store the locations as longitude latitude floats and perform the calculations in C#.
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
回答1:
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.
回答2:
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?
来源:https://stackoverflow.com/questions/10211579/how-to-determine-n-locations-inside-a-circle-efficiently