C# 如何根据纬度和经度按半径搜索?

C# 如何根据纬度和经度按半径搜索?,c#,asp.net,linq-to-entities,C#,Asp.net,Linq To Entities,我想以指定半径显示基于纬度和经度的数据 例如: 我有一个记录,纬度55.0628,经度-162.3056,没有指定的州 如何使用实体到linq仅显示一个状态内的记录 如果我让佛罗里达州展示佛罗里达州的记录 Table Data id item latitude longitude 1 townhome 55.0628 -162.3056 T

我想以指定半径显示基于纬度和经度的数据

例如:

我有一个记录,纬度55.0628,经度-162.3056,没有指定的州

如何使用实体到linq仅显示一个状态内的记录

如果我让佛罗里达州展示佛罗里达州的记录

Table Data

id            item             latitude                 longitude
1             townhome          55.0628                 -162.3056


Table postal codes

id               state                 city            latitude            longitude
1                alaska                Akutan          54.143              -165.7854
2                Alabama               Huntsville      34.7448             -86.6704

我将执行尽可能接近实际数据的查询,这可能意味着绕过LINQ并调用存储过程

下面是一个SQL用户定义函数,我使用它来计算两个位置之间的距离。它利用了SQL Server 2008中引入的新地理位置功能

CREATE FUNCTION [dbo].[GetDistanceBetween]
(
    @Lat1 float,
    @Long1 float,
    @Lat2 float,
    @Long2 float
)
RETURNS float
AS
BEGIN

    DECLARE @RetVal float;
    SET @RetVal = ( SELECT geography::Point(@Lat1, @Long1, 4326).STDistance(geography::Point(@Lat2, @Long2, 4326)) / 1609.344 );

RETURN @RetVal;

END
函数以英里为单位返回距离,根据我的经验,它非常快。这显然取决于需要进行多少比较

您可以使用以下方式来调用它:

DECLARE @StartingLatitude FLOAT, @StartingLongitude FLOAT;
DECLARE @MaxDistance FLOAT = 50;

SELECT * FROM PostalCodes 
WHERE dbo.GetDistanceBetween(@StartingLatitude, @StartingLongitude, latitude, longitude) <= @MaxDistance;
select *
from zipcodes
where
    lat >= South
    and lat <= North
    and lon >= West
    and lon <= East
    -- and state = 'FL' -- use it optionally

要知道一个目的地在一个给定的较大区域内,你不仅需要有较大区域内一个点的坐标,还需要绘制出它的整个边界的坐标

如果你有这些数据,这就成了一个问题。我发现光线跟踪在SQL和C中都很容易实现,所以它是一个很好的函数,可以让Linq意识到,尽管我只在Linq2SQL而不是LINQ2实体中实现

如果只有中心点的坐标,可以使用STDistance找到最近的中心点。但是,这很容易将一个靠近较大国家边界的位置误认为是在较小国家,因为它比较大国家更靠近较小国家的中心


如果您确实这样做了,但是您没有使用SQL 2008,因此您可以通过对lat1-lat2*lat1-lat2+lng1-lng2*lng1-lng2进行排序来获得粗略的近似值。这给出了相对距离,就好像世界真的是一个矩形,就像墨卡托投影所显示的那样。这些点离赤道越远,误差就越大,因此美国各州可能可以接受,但加拿大省份则不行。

正确且最快的方法是从你的拉特-隆(lat-lon)邮政编码开始,找到给定距离半径的东、西、北和南点。请遵循相关公式。然后使用这些点从数据库中获取邮政编码;比如:

DECLARE @StartingLatitude FLOAT, @StartingLongitude FLOAT;
DECLARE @MaxDistance FLOAT = 50;

SELECT * FROM PostalCodes 
WHERE dbo.GetDistanceBetween(@StartingLatitude, @StartingLongitude, latitude, longitude) <= @MaxDistance;
select *
from zipcodes
where
    lat >= South
    and lat <= North
    and lon >= West
    and lon <= East
    -- and state = 'FL' -- use it optionally
现在,当直线继续进行距离计算时,在由东、北、西和南点定义的正方形内有所有zip记录,使用Tim代码,只保留半径内的记录。如果正方形中所有的点都有记录,那么大约22%会超出半径。
显然,如果您使用CTE,您只需一次查询就可以执行整个sql操作。

您的数据不足以给出准确的结果,但您可以计算到每个城市的距离,并选择最接近的一个。这很有趣,请您解释一下查询。@max此处的答案提供了更多详细信息:。这仍然是一个有效的答案,但您可能可以通过从框搜索开始,然后使用半径搜索对其进行修剪来进一步优化。