0

我正在使用 C#、Asp.net、.net 2.0 版和 MSSQL 2005 中的“NearBy Properties”模块。我的要求是,

我将一个特定的Lat值传递Lan给 DB,它应该通过将传递Lat LanLat Lan值与已保存在 DB 中的值进行比较来获取我最近的 35 个属性。这可以在 SQL 部分本身中完成吗?

我可以通过以下Asp.net方式部分做到这一点

  1. 循环遍历 DataTable 中的所有行,然后
  2. 在 DataTable 中创建一个名为“Miles”的额外字段并将 Km 值插入其中,如下所示

    public decimal calcDistance(decimal latA, decimal longA, decimal latB, decimal longB)
    {
            double theDistance = (Math.Sin(DegreesToRadians(latA)) *
            Math.Sin(DegreesToRadians(latB)) +
            Math.Cos(DegreesToRadians(latA)) *
            Math.Cos(DegreesToRadians(latB)) *
            Math.Cos(DegreesToRadians(longA - longB)));
    
    return Convert.ToDecimal((RadiansToDegrees(Math.Acos(theDistance)))) * 69.09M * 1.6093M;
    }
    
  3. 然后使用“Miles”字段对 DataTable 进行排序,并从 DataTable 中获取前 35 行。

问题是,

我必须将所有数据库行提取到 asp 部分,然后执行 for 循环,然后进行排序,这会占用大量时间和资源,有什么办法可以在 SQL 部分本身中执行吗?

解决方案

我将@Bacon Bits 的答案调整为如下

SELECT PM.Id AS PropertyId,PM.Address,PM.PropertyImage,  ROUND((DEGREES(ACOS(SIN(RADIANS('9.98')) * SIN(RADIANS(PM.Latitude)) + COS(RADIANS('9.98')) * COS(RADIANS(PM.Latitude)) * COS(RADIANS(76.27999999999997 - PM.Longitude)))) * 69.09 * 1.6093),0) AS Miles 
FROM Tbl_PropertyMaster PM 
INNER JOIN dbo.Tbl_PropertyApproval AS PA  
ON PA.PropertyId = PM.Id 
WHERE PM.IsDeleted='False' AND PM.Enabled='True' and PA.Action='Approved' AND ROUND((DEGREES(ACOS(SIN(RADIANS('9.98')) * SIN(RADIANS(PM.Latitude)) + COS(RADIANS('9.98')) * COS(RADIANS(PM.Latitude)) * COS(RADIANS(76.27999999999997 - PM.Longitude)))) * 69.09 * 1.6093),0) < 1000 
ORDER BY Miles DESC
4

2 回答 2

0

创建一个标量函数,计算给定的两组 lan-lat 参数之间的距离(就像您在 asp.net 端所做的那样)。例子:

SELECT TOP 35 * FROM Table_1 ORDER BY dbo.calcDistance(field_latitude,field_longitude, param_lat,param_long) DESC;

我不知道如何计算给定两组 lang,lat 的距离。由您编写函数实现。你可以在这里这里使用

于 2013-01-25T07:24:01.820 回答
0

尝试以下用户定义函数,它是您提供给 TSQL 的函数的转换。这应该与 SQL Server 一样准确。查询应在 SQL Server 2005 及更高版本上运行。请注意,您可能应该评估两个静态值的乘积。我只是懒惰。

CREATE FUNCTION dbo.calcDistance (
    @latA AS NUMERIC(38, 35),
    @longA AS NUMERIC(38, 35),
    @latB AS NUMERIC(38, 35),
    @longB AS NUMERIC(38, 35)
    )
RETURNS NUMERIC(38, 35)
AS
BEGIN
    RETURN (DEGREES(ACOS(SIN(RADIANS(@latA)) * SIN(RADIANS(@latB)) + COS(RADIANS(@latA)) * COS(RADIANS(@latB)) * COS(RADIANS(@longA - @longB)))) * 69.09 * 1.6093)
END

SQLFiddle。我的示例使用测试中的位置和 Mangalore 的 Wikipedia 坐标。

于 2013-01-25T07:54:36.883 回答