## Copyright (C) 2018-2020 Philip Nienhuis ## ## This program is free software; you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . ## -*- texinfo -*- ## @deftypefn {} {@var{out} =} gpxread (@var{fname}) ## @deftypefnx {} {@var{out} =} gpxread (@var{fname}, @dots{}) ## Read data from a gpx file. ## ## Input argument @var{fname} (a character string) can be a valid file ## name or a valid URL. ## ## If no other input arguments are given gpxread will read all data in ## @var{fname} into one output struct @var{out}. The data to be read can ## be selected and/or limited by specifying one or more of the following ## optional property/value pairs (all case-insensitive): ## ## @itemize ## @item "FeatureType' ## This option (a mere "f" suffices) can be one of: ## @table @asis ## @item ## "WayPoint or simply "w": Read waypoints. ## @end item ## ## @item ## "Track" or "t": read tracks. ## @end item ## ## @item ## "Route" or "t": read routes. ## @end item ## ## @item ## "Auto" or "a" (default value): read all data. ## @end item ## @end table ## ## Multiple FeatureType property/value pairs can be specified. ## @end item ## ## @item "Index" ## The ensuing Index value should be a numeric value, or numeric vector, ## of indices of the features to be read. ## @end item ## @end itemize ## ## Output argument @var{out} is a struct array with field names Name, ## Lat, Lon, Ele, Time, and -in case of routes- Names. "Name" refers ## to the name of the waypoints, tracks or routes that have been read. ## "Lat", "Lon" and "Ele" refer to the latitude, longitude and elevation ## of the various features, in case of tracks field "Time" refers to ## the time of the trackpoint. In case of tracks and routes these are ## vectors, each element corresponding to one track point. For each ## individual track multiple track segments are separated by NaNs. For ## routes the field "Names" contains a cell array holding the names of ## the individual route points. "Time" fields for waypoints are ignored. ## ## Examples: ## ## @example ## A = gpxread ("trip2.gpx", "feature", "track", "index", 2); ## (which returns data from the second track in file "trip1.gpx") ## @end example ## ## @example ## B = gpxread ("trip2.gpx", "f", "t", "f", "r"); ## (which returns track and route data from file "trip2.gpx") ## @end example ## ## @end deftypefn ## Author: Philip Nienhuis ## Created: 2017-02-05 function [outp] = gpxread (fname, varargin) ## Input validation if (nargin < 1) print_usage (); elseif (! ischar (fname)) error ("gpread: file name expected for arg 1\n"); elseif (! isempty (cell2mat (cell2mat ... (regexp (fname, '(ftp://|http://|file://)', "tokens"))))) url = true; else [pth, fnm, ext] = fileparts (fname); if (isempty (ext)) fname = [fname ".gpx"]; endif url = false; endif if (nargin < 2) gtr = grt = gpt = 1; else gtr = grt = gpt = 0; endif if (mod (nargin, 2) != 1) error ("gpxread: insufficient nr. of input arguments\n"); endif idx = []; for ii=1:2:numel (varargin) if (ischar (varargin{ii}) && numel (varargin{ii}) > 0) switch lower (varargin{ii})(1) case "f" switch lower (varargin{ii+1})(1) case "t" gtr = 1; case "r" grt = 1; case "w" gpt = 1; case "a" gtr = grt = gpt = 1; otherwise error ("gpxread: unknown FeatureType '%s'", varargin{ii+1}); endswitch case "i" idx = varargin{ii+1}; if (! isnumeric (idx)) error ("gpxread: numeric value or vector expected for arg.# %d\n", ii+1); else idx = uint32 (idx); endif otherwise warning ("gpxread: unknown option '%s' - ignored\n", varargin{ii}); endswitch else error ("gpxread: wrong argument type for arg. %d - 'FeatureType' or \ 'Index' expected", ii+1); endif endfor if (url) ## Untested xml = urlread (fname); else fid = fopen (fname, "r"); if (fid < 0) error ("gpxread: couldn't open file %s\n", fname); endif xml = fread (fid, Inf, "char=>char")'; fclose (fid); endif outp = repmat (struct ("Type", "-", ... "Lat", [], ... "Lon", [], ... "Ele", [], ... "Time", [], ... "Name", "-"), 0, 1); if (gpt) ## (Try to) Read waypoints ptrnp = 'wpt lat="(.*?)" lon="(.*?)">.*?ele>(.*?)(.*?) size (wpts, 1)) = []; endif [outp(1:numel (idx)).Name] = deal (wpts(idx, 4){:}); [outp(1:numel (idx)).Type] = deal ("WayPoint"); [outp(1:numel (idx)).Lat] = deal (wpts(idx, 1){:}); [outp(1:numel (idx)).Lon] = deal (wpts(idx, 2){:}); [outp(1:numel (idx)).Ele] = deal (wpts(idx, 3){:}); endif endif if (gtr) ## Read tracks ptrnt1A = '(.*?).*?