首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BigQuery的HAVERSINE距离?

BigQuery的HAVERSINE距离?
EN

Stack Overflow用户
提问于 2017-02-06 13:11:05
回答 2查看 7.3K关注 0票数 11

我正在寻找一种在BigQuery中获取HAVERSINE()的方法。例如,如何使最近的气象站到达任意点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-06 13:12:54

2018更新:BigQuery现在支持本地geo函数。

ST_DISTANCE:返回两个非空GEOGRAPHYs之间的最短距离(以米为单位)。

纽约与西雅图之间的距离:

代码语言:javascript
复制
#standardSQL
WITH geopoints AS (
  SELECT ST_GEOGPOINT(lon,lat) p, name, state
  FROM `bigquery-public-data.noaa_gsod.stations`  
)

SELECT ST_DISTANCE(
  (SELECT p FROM geopoints WHERE name='PORT AUTH DOWNTN MANHATTAN WA'),
  (SELECT p FROM geopoints WHERE name='SEATTLE')
)

3866381.55

遗留SQL解决方案(标准挂起):

代码语言:javascript
复制
SELECT lat, lon, name,
  (111.045 * DEGREES(ACOS(COS(RADIANS(40.73943)) * COS(RADIANS(lat)) * COS(RADIANS(-73.99585) - RADIANS(lon)) + SIN(RADIANS(40.73943)) * SIN(RADIANS(lat))))) AS distance
FROM [bigquery-public-data:noaa_gsod.stations]
HAVING distance>0
ORDER BY distance
LIMIT 4

(基于http://www.plumislandmedia.net/mysql/haversine-mysql-nearest-loc/)

票数 6
EN

Stack Overflow用户

发布于 2017-02-06 17:17:25

2019年更新: BigQuery现在有了一个本机ST_DISTANCE()函数,这个函数比Haversine更精确。

例如:

代码语言:javascript
复制
#standardSQL
CREATE TEMP FUNCTION RADIANS(x FLOAT64) AS (
  ACOS(-1) * x / 180
);
CREATE TEMP FUNCTION RADIANS_TO_KM(x FLOAT64) AS (
  111.045 * 180 * x / ACOS(-1)
);
CREATE TEMP FUNCTION HAVERSINE(lat1 FLOAT64, long1 FLOAT64,
                               lat2 FLOAT64, long2 FLOAT64) AS (
  RADIANS_TO_KM(
    ACOS(COS(RADIANS(lat1)) * COS(RADIANS(lat2)) *
         COS(RADIANS(long1) - RADIANS(long2)) +
         SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))))
);

SELECT
  lat,
  lon,
  name,
  HAVERSINE(40.73943, -73.99585, lat, lon) *1000 AS haversine_distance
  , ST_DISTANCE(
      ST_GEOGPOINT(-73.99585, 40.73943)
      , ST_GEOGPOINT(lon,lat)) bqgis_distance
FROM `bigquery-public-data.noaa_gsod.stations`
WHERE lat IS NOT NULL AND lon IS NOT NULL
ORDER BY 1 DESC
LIMIT 4;

使用标准SQL,您可以定义一个SQL函数来封装逻辑。例如,

代码语言:javascript
复制
#standardSQL
CREATE TEMP FUNCTION RADIANS(x FLOAT64) AS (
  ACOS(-1) * x / 180
);
CREATE TEMP FUNCTION RADIANS_TO_KM(x FLOAT64) AS (
  111.045 * 180 * x / ACOS(-1)
);
CREATE TEMP FUNCTION HAVERSINE(lat1 FLOAT64, long1 FLOAT64,
                               lat2 FLOAT64, long2 FLOAT64) AS (
  RADIANS_TO_KM(
    ACOS(COS(RADIANS(lat1)) * COS(RADIANS(lat2)) *
         COS(RADIANS(long1) - RADIANS(long2)) +
         SIN(RADIANS(lat1)) * SIN(RADIANS(lat2))))
);

SELECT
  lat,
  lon,
  name,
  HAVERSINE(40.73943, -73.99585, lat, lon) AS distance_in_km
FROM `bigquery-public-data.noaa_gsod.stations`
WHERE lat IS NOT NULL AND lon IS NOT NULL
ORDER BY distance_in_km
LIMIT 4;
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42068651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档