From 250eb00e5838adfe1e9fd187e3052810883116a6 Mon Sep 17 00:00:00 2001 From: Bastien Boutonnet Date: Sat, 27 Feb 2021 13:21:13 +0100 Subject: [PATCH] add unit argument and apply conversion for kms multiply instead of divide and move logic in core macro rename things a bit update readme --- README.md | 6 ++++-- macros/geo/haversine_distance.sql | 16 +++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f5d96b344..9fa96b6f2 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ Usage: --- ### Date/Time #### date_spine ([source](macros/datetime/date_spine.sql)) -This macro returns the sql required to build a date spine. The spine will include the `start_date` (if it is aligned to the `datepart`), but it will not include the `end_date`. +This macro returns the sql required to build a date spine. The spine will include the `start_date` (if it is aligned to the `datepart`), but it will not include the `end_date`. Usage: ``` @@ -111,9 +111,11 @@ Usage: #### haversine_distance ([source](macros/geo/haversine_distance.sql)) This macro calculates the [haversine distance](http://daynebatten.com/2015/09/latitude-longitude-distance-sql/) between a pair of x/y coordinates. +Optionally takes a `unit` string parameter ('km' or 'mi') which defaults to miles (imperial system). + Usage: ``` -{{ dbt_utils.haversine_distance(lat1=,lon1=,lat2=,lon2=) }} +{{ dbt_utils.haversine_distance(lat1=,lon1=,lat2=,lon2=, unit='mi') }} ``` --- ### Schema Tests diff --git a/macros/geo/haversine_distance.sql b/macros/geo/haversine_distance.sql index ed6c8281a..8680e2eee 100644 --- a/macros/geo/haversine_distance.sql +++ b/macros/geo/haversine_distance.sql @@ -3,17 +3,23 @@ This calculates the distance between two sets of latitude and longitude. The formula is from the following blog post: http://daynebatten.com/2015/09/latitude-longitude-distance-sql/ -The arguments should be float type. +The arguments should be float type. #} -{% macro haversine_distance(lat1,lon1,lat2,lon2) -%} - {{ return(adapter.dispatch('haversine_distance', packages = dbt_utils._get_utils_namespaces())(lat1,lon1,lat2,lon2)) }} +{% macro haversine_distance(lat1,lon1,lat2,lon2,unit='mi') -%} + {{ return(adapter.dispatch('haversine_distance', packages = dbt_utils._get_utils_namespaces())(lat1,lon1,lat2,lon2,unit)) }} {% endmacro %} -{% macro default__haversine_distance(lat1,lon1,lat2,lon2) -%} +{% macro default__haversine_distance(lat1,lon1,lat2,lon2,unit='km') -%} +{# vanilla macro is in miles #} + {% set conversion = '' %} +{% if unit == 'km' %} +{# we multiply miles result to get it in kms #} + {% set conversion = '* 1.60934' %} +{% endif %} 2 * 3961 * asin(sqrt((sin(radians(({{lat2}} - {{lat1}}) / 2))) ^ 2 + cos(radians({{lat1}})) * cos(radians({{lat2}})) * - (sin(radians(({{lon2}} - {{lon1}}) / 2))) ^ 2)) + (sin(radians(({{lon2}} - {{lon1}}) / 2))) ^ 2)) {{conversion_rate}} {%- endmacro %}