大圆距离公式:T-SQL

9

我有一个包含许多不同地址的表格。我需要一个存储过程,能够选择该表格中距离传入的纬度/经度数值指定距离范围内的地址。

以下是我的表格示例:

- messageId
- lat (float)
- long (float)

Proc会传入另一组纬度/经度坐标对(都是float类型),以及一个距离值(int类型)

我找到了此链接http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81360,可以计算实际公式,但我无法修改它以便在proc表单中通过整个地址列表并仅给出距离(我传入的)小于或等于指定距离的地址Id

我能在这里得到任何帮助吗?

谢谢!

3个回答

6

SQL Server 2008

使用空间函数STDistance返回以米为单位的距离

geography::Point(@lat1, @lon1, 4326).STDistance(geography::Point(@lat2, @lon2, 4326))


4326是WGS82地理点的SRID。除非您计划使用与标准GPS纬度/经度不同的坐标系,否则您始终应该使用4326。 - tidwall
如果我创建了一个计算列,将其存储为地理位置,用于插入纬度/经度,然后只在存储过程中创建另一个点,会怎样呢? - slandau
那会很好。这个想法是为了避免不必要地生成地理点。 - tidwall
明白了。我相信它会存储为浮点数?所以我只需创建一个浮点列,并根据我插入的纬度/经度进行计算。我仍然需要在过程中生成另一个点,但要将其切成两半。 - slandau
geography 类型与标准的 float 类型不同。它针对地理公式进行了优化,因此大小相对较大(22字节),而与2个浮点数(16字节)相比。 - tidwall
显示剩余2条评论

2
我实际上之前为了这个目的写了一篇简短的博客文章(博客文章链接)。基本上,我的问题是:
SELECT
  Name,
  Address,
  City,
  State,
  Latitude,
  Longitude,
  (
    ACOS(
      COS(@center_latitude * (PI()/180)) *
      COS(@center_longitude * (PI()/180)) *
      COS(Latitude * (PI()/180)) *
      COS(Longitude * (PI()/180)) +
      COS(@center_latitude * (PI()/180)) *
      SIN(@center_longitude * (PI()/180)) *
      COS(Latitude * (PI()/180)) *
      SIN(Longitude * (PI()/180)) +
      SIN(@center_latitude * (PI()/180)) *
      SIN(Latitude * (PI()/180))
    ) *
    (
      (@equatorial_radius * @polar_radius) /
      (
        SQRT(
          (@equatorial_radius * @equatorial_radius) -
          (
            (
              (@equatorial_radius * @equatorial_radius) -
              (@polar_radius * @polar_radius)
            ) *
            (
              COS(@center_latitude) *
              COS(@center_latitude)
            )
          )
        )
      )
    )
  ) AS Miles
FROM
  Places
WHERE
  Miles <= @search_radius

给定中心纬度、中心经度和搜索半径,你就可以了。 (赤道和极半径的参数可以硬编码,当然。)
所有这些数学都应该考虑到地球的曲率、赤道处的膨胀等因素。

当我在WHERE从句中运行时,出现了错误。它说“无效的列名-Miles”。 - slandau
@slandau:有趣。我认为应该能行,因为所有数学相关的列都被命名为“Miles”别名。但是经过进一步的研究,我想T-SQL不喜欢这样做。(我可能在以前的MySQL里使用过它,已经有一段时间了)。你可以尝试把它放在派生表中。参见: https://dev59.com/vXVC5IYBdhLWcg3wixs0 - David
有没有办法在计算中使用表格中的经度/纬度,但不将它们作为结果集的一部分返回? - slandau
@slandau:只需从SELECT子句中删除它们即可解决问题。 - David

0

你可以直接在存储过程中使用该函数... 我在想:

CREATE PROCEDURE [FindPlaces](@lat float, @long float, @min_dist float) 
AS
select messageId from yourtable where dbo.F_GREAT_CIRCLE_DISTANCE(@lat, @long, lat, long)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接