# nextrain / src / nextrain / utils.clj

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77``` ```(ns nextrain.utils) (defonce origin [40.7599573, -73.9921683]) (defonce ny_penn [40.750046, -73.992358]) (defonce pton [40.343398, -74.659872]) (defonce ^Double earth-radius 6371.01) (defonce cos #(Math/cos %)) (defonce acos #(Math/acos %)) (defonce sin #(Math/sin %)) (defonce radian #(Math/toRadians %)) (defonce degree #(Math/toDegrees %)) (defonce sqrt #(Math/sqrt %)) (defonce atan2 #(Math/atan2 % %2)) (defonce pow #(Math/pow % %2)) (defn haversine-dist [[src-lat src-lon] [dest-lat dest-lon]] (let [dlat (radian (- dest-lat src-lat)) dlon (radian (- dest-lon src-lon)) h-dlat (/ dlat 2) h-dlon (/ dlon 2) a (+ (pow (sin h-dlat) 2) ( * (cos (radian src-lat)) (cos (radian dest-lat)) (pow (sin h-dlon) 2))) c (* 2 (atan2 (sqrt a) (sqrt (- 1 a))))] (* earth-radius c))) (defn distance "A simplified and less accurate way of calculating distance between two points. http://www.movable-type.co.uk/scripts/latlong.html" [[src-lat src-lon] [dest-lat dest-lon]] (let [a (* (sin (radian src-lat)) (sin (radian dest-lat))) b (* (cos (radian src-lat)) (cos (radian dest-lat)) (cos (- (radian dest-lon) (radian src-lon)))) d (acos (+ a b))] (* d earth-radius))) (defn- wgs84-earth-radius [lat] (let [wgs84-a 6378137.0 wgs84-b 6356752.3 an (* (pow wgs84-a 2) (cos lat)) bn (* (pow wgs84-b 2) (sin lat)) ad (* wgs84-a (cos lat)) bd (* wgs84-b (sin lat)) n (+ (pow an 2) (pow bn 2)) d (+ (pow ad 2) (pow bd 2))] (sqrt (/ n d)))) (defn bounding-box "A less accurate way to find a bounding box. http://janmatuschek.de/LatitudeLongitudeBoundingCoordinates http://stackoverflow.com/questions/238260/how-to-calculate-the-bounding-box-for-a-given-lat-lng-location" [[dlat dlon] halfside] (let [lat (radian dlat) lon (radian dlon) radius (wgs84-earth-radius lat) pradius (* radius (cos lat)) lat-min (- lat (/ halfside radius)) lat-max (+ lat (/ halfside radius)) lon-min (- lon (/ halfside pradius)) lon-max (+ lon (/ halfside pradius))] [[(degree lat-min) (degree lon-min)] [(degree lat-max) (degree lon-max)]])) ```