defmodule LocationSimulator.Gpx do
@moduledoc """
`Gpx` is a module that provides functions for parsing GPX file.
"""
import SweetXml
## Public functions ##
def read_gpx(file) do
parse_gpx(file)
end
def read_string_gpx(content) do
parse_gpx_content(content)
end
## Private functions ##
defp parse_gpx(file) do
case File.read(file) do
{:ok, content} ->
parse_gpx_content(content)
{:error, reason} ->
raise "cannot read file #{inspect file}, reason: #{inspect reason}"
end
end
defp parse_gpx_content(content) do
content
|> parse()
|> xpath(~x"//trkseg/trkpt"l)
|> Enum.map(&parse_gpx_point/1)
end
defp parse_gpx_point(xml_el) do
# ele should be 0 in case xml file has no 'ele' tag
ele =
try do
xml_el |> xpath(~x"./ele/text()"f)
catch
:error, {:badmatch, _} -> 0
end
%LocationSimulator.Gpx.GpsPoint{
lat: xml_el |> xpath(~x"./@lat"f) ,
lon: xml_el |> xpath(~x"./@lon"f),
ele: ele,
time: xml_el |> xpath(~x"./time/text()"s) |> parse_datetime()
}
end
defp parse_datetime(str) do
case NaiveDateTime.from_iso8601(str) do
{:ok, datetime} -> datetime
{:error, _seasion} -> nil
end
end
end