如何返回给定半径的结果集

时间:2013-06-11 18:07:53

标签: sql sql-server

我有以下SQL(SQL Server),它在大多数情况下都有效。问题是我真的在创造一个正方形,而不是一个真正的圆形。我的目标是通过一个有纬度和长度的城市和州,然后找到该长度在100英里范围内的所有城市。纬度和经度存储在DB中,因此我的所有值都在那里。我只需要一种更精确的方法。这是我到目前为止的代码:

ALTER PROCEDURE [dbo].[sp_StoresByZipArea] (@zip nvarchar(5), @Radius float)  AS

DECLARE @LatRange float
DECLARE @LongRange float
DECLARE @LowLatitude float
DECLARE @HighLatitude  float
DECLARE @LowLongitude  float
DECLARE @HighLongitude  float

DECLARE @istartlat  float
DECLARE @istartlong  float

SELECT @iStartlat=Latitude, @iStartLong=Longitude from zipcodes where zipcode=@ZIP

SELECT @LatRange = @Radius / ((6076 / 5280) * 60)
SELECT @LongRange = @Radius / (((cos((@iStartLat * 3.141592653589 / 180)) * 6076.) /  5280.) * 60)

SELECT @LowLatitude = @istartlat - @LatRange
SELECT @HighLatitude = @istartlat + @LatRange
SELECT @LowLongitude = @istartlong - @LongRange
SELECT @HighLongitude = @istartlong + @LongRange

/** Now you can create a SQL statement which limits the recordset of cities in this manner:  **/

SELECT * FROM ZipCodes
 WHERE (Latitude <= @HighLatitude) AND (Latitude >= @LowLatitude) AND (Longitude >= @LowLongitude) AND (Longitude <= @HighLongitude)

3 个答案:

答案 0 :(得分:2)

不确定这是否有帮助,但我认为这里有错误:

SELECT @LatRange = @Radius / ((6076 / 5280) * 60)

(6076/5280)部分将始终评估为1。

答案 1 :(得分:2)

我过去曾用过大圆距离来做这件事。下面的实现告诉你两个不同点之间的距离,可以用来做你所说的:

create function dbo.GreatCircleDistance
    (
    @Latitude1  float,
    @Longitude1 float,
    @Latitude2  float,
    @Longitude2 float
    )
returns float
as
/*
FUNCTION: dbo.GreatCircleDistance

    Computes the Great Circle distance in kilometers
    between two points on the Earth using the
    Haversine formula distance calculation.

Input Parameters:
    @Longitude1 - Longitude in degrees of point 1
    @Latitude1  - Latitude  in degrees of point 1
    @Longitude2 - Longitude in degrees of point 2
    @Latitude2  - Latitude  in degrees of point 2

*/
begin
declare @radius float

declare @lon1  float
declare @lon2  float
declare @lat1  float
declare @lat2  float

declare @a float
declare @distance float

-- Sets average radius of Earth in Kilometers
set @radius = 6371.0E

-- Convert degrees to radians
set @lon1 = radians( @Longitude1 )
set @lon2 = radians( @Longitude2 )
set @lat1 = radians( @Latitude1 )
set @lat2 = radians( @Latitude2 )

set @a = sqrt(square(sin((@lat2-@lat1)/2.0E)) + 
    (cos(@lat1) * cos(@lat2) * square(sin((@lon2-@lon1)/2.0E))) )

set @distance =
    @radius * ( 2.0E *asin(case when 1.0E < @a then 1.0E else @a end ))

return @distance

end

答案 2 :(得分:0)

此功能适用于SQL Server 2012及更高版本的收件箱。见Query Spatial Data for Nearest Neighbor

DECLARE @g geography;  
DECLARE @h geography;  
-- SRID 4326 specifies the use of WGS 84 coordinate system (same as GPS)
SET @g = geography::STGeomFromText('POINT(-122.360 47.656)', 4326);  
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326); 

-- Returns 995 meters 
SELECT @g.STDistance(@h);