Permalink
Please sign in to comment.
Browse files
Merge pull request #44 from xapix-io/feature/geo-functions
Rewamp custom functions
- Loading branch information...
Showing
with
201 additions
and 63 deletions.
- +2 −2 .circleci/config.yml
- +1 −0 base64/deps.edn
- +17 −28 src/axel_f/functions/convert.cljc → base64/src/axel_f/base64.cljc
- +3 −1 deps.edn
- +1 −0 geo/deps.edn
- +61 −0 geo/src/axel_f/geo.cljc
- +3 −0 json/deps.edn
- +41 −0 json/src/axel_f/json.cljc
- +1 −1 pom.xml
- +1 −1 release-js/package.json
- +3 −1 src/axel_f/api.cljs
- +1 −1 src/axel_f/core.cljc
- +18 −0 test/axel_f/base64_test.cljc
- +3 −28 test/axel_f/converter_test.cljc
- +27 −0 test/axel_f/geo_test.cljc
- +18 −0 test/axel_f/json_test.cljc
@@ -0,0 +1 @@ | |||
{:paths ["src"]} |
@@ -0,0 +1 @@ | |||
{:paths ["src"]} |
@@ -0,0 +1,61 @@ | |||
(ns axel-f.geo | |||
(:require [axel-f.macros :refer [def-excel-fn]] | |||
#?(:cljs [goog.math :as math]))) | |||
|
|||
(def earth-radius 6371.0) | |||
|
|||
(defn to-radians | |||
"Converts an angle measured in degrees to an approximately | |||
equivalent angle measured in radians." | |||
[x] | |||
#?(:clj (Math/toRadians x) | |||
:cljs (math/toRadians x))) | |||
|
|||
(defn asin | |||
"Returns the arc sine of `x`." | |||
[x] | |||
#?(:clj (Math/asin x) | |||
:cljs (.asin js/Math x))) | |||
|
|||
(defn sin | |||
"Returns the sine of `x`." | |||
[x] | |||
#?(:clj (Math/sin x) | |||
:cljs (.sin js/Math x))) | |||
|
|||
(defn cos | |||
"Returns the cosine of `x`." | |||
[x] | |||
#?(:clj (Math/cos x) | |||
:cljs (.cos js/Math x))) | |||
|
|||
(defn sqrt | |||
"Returns the square root of `x`." | |||
[x] | |||
#?(:clj (Math/sqrt x) | |||
:cljs (.sqrt js/Math x))) | |||
|
|||
(defn distance | |||
"Returns the distance from `point-1` to `point-2`, in km using the | |||
Haversine formula." | |||
[[lat-1 lon-1] [lat-2 lon-2]] | |||
(let [d-lat (to-radians (- lat-2 lat-1)) | |||
d-lon (to-radians (- lon-2 lon-1)) | |||
lat-1 (to-radians lat-1) | |||
lat-2 (to-radians lat-2) | |||
a (+ (* (sin (/ d-lat 2)) | |||
(sin (/ d-lat 2))) | |||
(* (sin (/ d-lon 2)) | |||
(sin (/ d-lon 2)) | |||
(cos lat-1) | |||
(cos lat-2)))] | |||
(* earth-radius 2 (asin (sqrt a))))) | |||
|
|||
(def-excel-fn geo.distance | |||
"Calculate the distance for the path described as a list of geo points | |||
Each point must a tuple of two or three float numbers." | |||
{:args [{:desc "List of points. Each point must be a tuple of latitude and longitude"}]} | |||
[points] | |||
(->> points | |||
(partition 2 1) | |||
(reduce #(+ %1 (apply distance %2)) 0))) |
@@ -0,0 +1,3 @@ | |||
{:deps {cheshire {:mvn/version "5.8.1"}} | |||
|
|||
:paths ["src"]} |
@@ -0,0 +1,41 @@ | |||
(ns axel-f.json | |||
(:require [axel-f.macros #?(:clj :refer :cljs :refer-macros) [def-excel-fn] :as m] | |||
#?(:clj [cheshire.core :as json]))) | |||
|
|||
(defn json-encode [to-encode] | |||
#?(:clj | |||
(json/generate-string to-encode) | |||
:cljs | |||
(js/JSON.stringify (clj->js to-encode)))) | |||
|
|||
(defn json-decode [to-decode] | |||
#?(:clj | |||
(json/parse-string to-decode) | |||
:cljs | |||
(js->clj (js/JSON.parse to-decode)))) | |||
|
|||
(def-excel-fn json.encode | |||
"Returns a JSON-encoding String for the given object." | |||
{:args [{:desc "Object to be encoded"}]} | |||
[obj] | |||
(json-encode obj)) | |||
|
|||
(def-excel-fn jsonencode | |||
"Returns a JSON-encoding String for the given object." | |||
{:args [{:desc "Object to be encoded"}] | |||
:deprecated true} | |||
[obj] | |||
((m/find-impl "JSON.ENCODE") obj)) | |||
|
|||
(def-excel-fn json.decode | |||
"Returns an object corresponding to the given JSON-encoded string." | |||
{:args [{:desc "JSON-encoded string to be decoded"}]} | |||
[s] | |||
(json-decode s)) | |||
|
|||
(def-excel-fn jsondecode | |||
"Returns an object corresponding to the given JSON-encoded string." | |||
{:args [{:desc "JSON-encoded string to be decoded"}] | |||
:deprecated true} | |||
[s] | |||
((m/find-impl "JSON.DECODE") s)) |
@@ -0,0 +1,18 @@ | |||
(ns axel-f.base64-test | |||
(:require #?(:clj [clojure.test :as t] | |||
:cljs [cljs.test :as t :include-macros true]) | |||
[axel-f.core :as af] | |||
[axel-f.base64 :as sut])) | |||
|
|||
(t/deftest base64 | |||
(t/testing "Encode string" | |||
(t/is (= "cXdl" (sut/base64-encode "qwe")))) | |||
|
|||
(t/testing "Decode string" | |||
(t/is (= "qwe" (sut/base64-decode "cXdl"))))) | |||
|
|||
(t/deftest BASE64ENCODE | |||
(t/is (= "cXdl" (af/run "BASE64.ENCODE('qwe')")))) | |||
|
|||
(t/deftest BASE64DECODE | |||
(t/is (= "qwe" (af/run "BASE64.DECODE('cXdl')")))) |
@@ -0,0 +1,27 @@ | |||
(ns axel-f.geo-test | |||
(:require #?(:clj [clojure.test :as t] | |||
:cljs [cljs.test :as t :include-macros true]) | |||
[axel-f.core :as af] | |||
[axel-f.geo :as sut])) | |||
|
|||
(t/deftest to-radians | |||
(t/are [deg rad] (= (sut/to-radians deg) rad) | |||
0 0.0 | |||
0.0 0.0 | |||
90 1.5707963267948966 | |||
180 3.141592653589793 ;; ~= Pi | |||
)) | |||
|
|||
(t/deftest distance | |||
(t/testing "Calculate distance for given path" | |||
(t/are [path dist] (= (af/run "GEO.DISTANCE(_)" path) dist) | |||
[[55.751244 37.618423] ;; Moscow | |||
[52.520008 13.404954] ;; Berlin | |||
] | |||
1608.8794097160353 | |||
|
|||
[[13.736717 100.523186] ;; Bangkok | |||
[55.751244 37.618423] ;; Moscow | |||
[52.520008 13.404954] ;; Berlin | |||
] | |||
8676.241667937587))) |
@@ -0,0 +1,18 @@ | |||
(ns axel-f.json-test | |||
(:require #?(:clj [clojure.test :as t] | |||
:cljs [cljs.test :as t :include-macros true]) | |||
[axel-f.core :as af] | |||
[axel-f.json :as sut])) | |||
|
|||
(t/deftest json | |||
(t/testing "Encode object" | |||
(t/is (= "{\"foo\":1}" (sut/json-encode {:foo 1})))) | |||
|
|||
(t/testing "Decode string" | |||
(t/is (= {"foo" 1} (sut/json-decode "{\"foo\":1}"))))) | |||
|
|||
(t/deftest JSONENCODE | |||
(t/is (= "{\"foo\":1}" (af/run "JSON.ENCODE(_)" {:foo 1})))) | |||
|
|||
(t/deftest JSONDECODE | |||
(t/is (= {"foo" 1} (af/run "JSON.DECODE('{\"foo\":1}')")))) |
0 comments on commit
19d6625