C# 使用三角函数SQL Server

C# 使用三角函数SQL Server,c#,sql-server,C#,Sql Server,我有一个带有Dapper的WebApi项目,我有表产品: [Key] public int idProducts { get; set; } public string Name { get; set; } public float Latitude { get; set; } public float Longitude { get; set; } public int ProductsItems { get; set; } public decimal Price { get; set; }

我有一个带有Dapper的WebApi项目,我有表产品:

[Key]
public int idProducts { get; set; }
public string Name { get; set; }
public float Latitude { get; set; }
public float Longitude { get; set; }
public int ProductsItems { get; set; }
public decimal Price { get; set; }
我需要计算从A点到B点的距离,检查是否小于1km,我已经计算过了,但在C点

private static double distance(double lat1, double lon1, double lat2, double lon2, char unit)
    {
        double theta = lon1 - lon2;
        double dist = Math.Sin(deg2rad(lat1)) * 
            Math.Sin(deg2rad(lat2)) +
            Math.Cos(deg2rad(lat1)) * 
            Math.Cos(deg2rad(lat2)) * 
            Math.Cos(deg2rad(theta));
        dist = Math.Acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        dist = dist * 1.609344;
        return (dist);
    }
    private static double deg2rad(double deg)
    {
        return (deg * Math.PI / 180.0);
    }
    private static double rad2deg(double rad)
    {
        return (rad / Math.PI * 180.0);
    }
而布尔艾利斯=距离-8.157908,-34.931675,-8.164891,-34.919033,'K'<1

但那样的话,我就必须从产品中选择*,以列表的形式获取所有结果,并循环获取每个项目,检查从a到B的距离是否有效,是否不实用!我不习惯在涉及数学的问题上提出这样的问题

如何创建一个查询,在其中我可以从a点传递Lat和Long,并进行计算,然后只返回有效项的列表?

您可以在SQL Server中使用地理信息

范例


我应该补充一点,UDF的计算与Google地图的计算几乎不谋而合。

要稍微改进John的答案,您可以这样做:

CREATE TABLE YourTable (
    ID INT PRIMARY KEY
    , Lat FLOAT
    , Lon FLOAT
    , Location AS GEOGRAPHY::Point(Lat, Lon, 4326));

INSERT INTO YourTable (ID, Lat, Lon)
VALUES
    (1,-8.157908, -34.931675)
    , (2,-8.164891, -34.919033)
    , (3,-8.159999, -34.939999);
GO

CREATE FUNCTION GetCloserThanOneKilometer (
    @Lat FLOAT
    , @Lon FLOAT
    , @Distance FLOAT)
RETURNS TABLE 
AS
RETURN
SELECT *
FROM YourTable
WHERE GEOGRAPHY::Point(@Lat, @Lon, 4326).STDistance(Location) <= @Distance;

不能在数据库中将其作为查询处理吗?这可以很容易地用SQL重写。您还可以创建一个计算列来存储位置,而无需每次都计算该位置:这是类似的,但看看C中的这行,双距离双lat1,双lon1,双lat2,双lon2,字符单位lat1和lon1是我要通过语法传递的值,每次调用都会不同,lat2和lon2已经存储在这个表中,类似于检查Lat和Long PASS是否距离此表中的所有这些值小于1km,并仅返回有效值。@EvaldasBuinauskas非常正确,我应该指出这一点。我想要一个简单的例子。很好的改进。。。清晰、清晰的示例+1这正是我想要的!谢谢埃瓦尔达斯和约翰!
ID   Lat        Lng           Meters
1   -8.157908   -34.931675    0                   --<< Orgin/Fetch
3   -8.159999   -34.939999    946.007737339573    
CREATE Function [dbo].[udf-Geo-Meters](@Lat1 FLOAT, @Lng1 FLOAT, @Lat2 FLOAT, @Lng2 FLOAT)
Returns Float as
Begin
    Return ACOS(SIN(PI()*@Lat1/180.0)*SIN(PI()*@Lat2/180.0)+COS(PI()*@Lat1/180.0)*COS(PI()*@Lat2/180.0)*COS(PI()*@Lng2/180.0-PI()*@Lng1/180.0)) * 6371008.8
    -- 6.371 mean radius of earth in meters
End
CREATE TABLE YourTable (
    ID INT PRIMARY KEY
    , Lat FLOAT
    , Lon FLOAT
    , Location AS GEOGRAPHY::Point(Lat, Lon, 4326));

INSERT INTO YourTable (ID, Lat, Lon)
VALUES
    (1,-8.157908, -34.931675)
    , (2,-8.164891, -34.919033)
    , (3,-8.159999, -34.939999);
GO

CREATE FUNCTION GetCloserThanOneKilometer (
    @Lat FLOAT
    , @Lon FLOAT
    , @Distance FLOAT)
RETURNS TABLE 
AS
RETURN
SELECT *
FROM YourTable
WHERE GEOGRAPHY::Point(@Lat, @Lon, 4326).STDistance(Location) <= @Distance;
SELECT *
FROM GetCloserThanOneKilometer(-8.157908, -34.931675, 1000);
GO