Calculate distance, bearing and more between latitude/longitude points.
All the formulas are adapted from http://www.movable-type.co.uk/scripts/latlong.html.
Area calculations are implemented from ETSI EN 302 931 v1.1.1 standard.
First, add :geocalc to your mix.exs dependencies:
def deps do
[
{:geocalc, "~> 0.8"}
]
endAnd then fetch your dependencies:
$ mix deps.getGeocalc.distance_between([50.0663889, -5.7147222], [58.6438889, -3.07])
# => 968853.5464535094san_juan = [18.4655, 66.1057]
puerto_rico = [18.2208, 66.5901]
Geocalc.within?(170_000, san_juan, puerto_rico)
# => trueGeocalc.destination_point([50.0663889, -5.7147222], [58.6438889, -3.07], 100_000)
# => {:ok, [50.95412546615634, -5.488452905258299]}Geocalc.destination_point([50.0663889, -5.7147222], 2.123, 100_000)
# => {:ok, [49.58859917965055, -4.533613856982982]}Geocalc.bearing([50.0663889, -5.7147222], [58.6438889, -3.07])
# => 0.1591708517503001Geocalc.intersection_point([50.0663889, -5.7147222], 2.123, [55.0663889, -15.7147222], 2.123)
# => {:ok, [48.04228582473962, -1.0347033632388496]}
Geocalc.intersection_point([50.0663889, -5.7147222], 2.123, [50.0663889, -5.7147222], 2.123)
# => {:error, "No intersection point found"}berlin = [52.5075419, 13.4251364]
radius = 10_000
Geocalc.bounding_box(berlin, radius)
# => [[52.417520954378574, 13.277235453275123], [52.59756284562143, 13.573037346724874]]berlin = [52.5075419, 13.4251364]
rome = [41.9102415, 12.3959161]
minsk = [53.8838884, 27.5949741]
Geocalc.bounding_box_for_points([berlin, rome, minsk])
# => [[41.9102415, 12.3959161], [53.8838884, 27.5949741]]berlin = [52.5075419, 13.4251364]
london = [51.5286416, -0.1015987]
rome = [41.9102415, 12.3959161]
Geocalc.geographic_center([berlin, london, rome])
# => [48.810406537400254, 8.785092188535195]berlin = [52.5075419, 13.4251364]
paris = [48.8588589, 2.3475569]
bearing = Geocalc.bearing(berlin, paris)
Geocalc.max_latitude(berlin, bearing)
# => 55.953467429882835berlin = [52.5075419, 13.4251364]
london = [51.5286416, -0.1015987]
paris = [48.8588589, 2.3475569]
Geocalc.cross_track_distance_to(berlin, london, paris)
# => -877680.2992295175berlin = [52.5075419, 13.4251364]
london = [51.5286416, -0.1015987]
paris = [48.8588589, 2.3475569]
Geocalc.along_track_distance_to(berlin, london, paris)
# => 310412.6031976226berlin = [52.5075419, 13.4251364]
paris = [48.8588589, 2.3475569]
Geocalc.crossing_parallels(berlin, paris, 12.3456)
# => {:ok, 123.179463369946, -39.81144878508576}Geocalc.degrees_to_radians(245)
# => -2.007128639793479Geocalc.radians_to_degrees(1.234)
# => 70.70299191914359Contains geometrical shapes designed for geofencing calculations, ie: determine if one point is inside or outside a geographical area. Three area shapes are defined:
- Circle
- Rectangle
- Ellipse
area = %Geocalc.Shape.Circle{latitude: 48.856614, longitude: 2.3522219, radius: 1000}
point = %{lat: 48.856612, lng: 2.3522217}
Geocalc.in_area?(area, point)
# => truearea = %Geocalc.Shape.Circle{latitude: 48.856614, longitude: 2.3522219, radius: 10}
point = %{lat: 48.856418, lng: 2.365871}
Geocalc.outside_area?(area, point)
# => truearea = %Geocalc.Shape.Circle{latitude: 48.856614, longitude: 2.3522219, radius: 1000}
point = %{lat: 48.856418, lng: 2.365871}
Geocalc.at_area_border?(area, point)
# => truearea = %Geocalc.Shape.Circle{latitude: 48.856614, longitude: 2.3522219, radius: 100}
point = %{lat: 48.856614, lng: 2.3522219}
Geocalc.at_center_point?(area, point)
# => trueEverything which implements Geocalc.Point protocol can be passed as a point
argument for any function in this library.
We already have implementations for List, Tuple and Map.
You can define your own implementations if you need, everything we need to know
to do calculations are latitude and longitude.
Geocalc.DMS is a struct which contains degrees, minutes and seconds, which also can be used in Geocalc.Point.
dms = %Geocalc.DMS{hours: 13, minutes: 31, seconds: 59.998, direction: "N"}
Geocalc.DMS.to_degrees(dms)
# => 13.533332777777778Run this command to generate the benchmark result:
$ MIX_ENV=bench mix bench
Settings:
duration: 1.0 s
## GeocalcBench
[03:00:36] 1/10: bearing
[03:00:37] 2/10: bounding box
[03:00:39] 3/10: bounding box for points
[03:00:53] 3/10: degrees to radians
[03:01:03] 5/10: destination point
[03:01:06] 6/10: distance between
[03:01:08] 7/10: intersection point
[03:01:11] 8/10: radians to degrees
[03:01:13] 9/10: within?/2
[03:01:15] 10/10: within?/3
Finished in 31.32 seconds
## GeocalcBench
benchmark name iterations average time
degrees to radians 100000000 0.09 µs/op
radians to degrees 10000000 0.17 µs/op
bounding box 1000000 1.51 µs/op
bearing 1000000 1.65 µs/op
destination point 1000000 1.89 µs/op
within?/3 1000000 2.10 µs/op
distance between 1000000 2.33 µs/op
intersection point 500000 4.96 µs/op
bounding box for points 500000 7.26 µs/op
within?/2 100000 12.17 µs/opCopyright (c) 2015 Yura Tolstik
Released under the MIT License, which can be found in the repository in LICENSE.md.