function splits2tcx(in_file,splits)
% om een extra neutralisatie-post in mee te nemen die niet in de splits zat, voeg een
% +0:17 (of andere tijd) toe op de plaats.
% gpsbabel = 'c:\localdata\bin\gpsbabel\gpsbabel.exe'
% CHECK various splits strings
force_tcx_conversion = 1; % force gpsbabel to convert tcx to tcx (to fix for example Android Garmin Uploader files)
if nargin support for %s files not yet implemented.\n',fe);
end
if nok
error('err-> conversion to .tcx file failed');
else
fprintf('done.\n'); % JHH
end
end
fprintf('** acquiring splits **\n');
if nargin0) % absolute times
if splits(1)~=splits(end)
warning('I expected the total time (1st data point) to be equal to the finish time (last data point). Netralized leg compensation?');
end
splittimes = [0 splits(2:end)];
else % relative times
splittimes = [0 cumsum(splits)];
end
fprintf('** using split times: "%s" **\n',reshape(strvcat(m2ms(splittimes'/60,1)',' '),1,[]));
fprintf('** reading tcx file: "%s" **\n',tcx_file);
t = []; tp = [];
d = []; dp = [];
ll = []; lp = [];
[fid,err] = fopen(tcx_file,'r');
if fid failed opening file "%s" for reading, with error: %s',tcx_file,err);
end
arm = 0;
while ~feof(fid)
l = fgetl(fid);
hms = sscanf(l,'%*[^<]<time>%*[^T]T%d:%d:%dZ</time>');
if ~isempty(hms)
t(max(length(d),size(ll,1))+1) = [60*60 60 1]*hms;
tp(max(length(d),size(ll,1))+1) = ftell(fid);
arm = 1;
else
dm = sscanf(l,'%*[^<]%f');
if arm && ~isempty(dm)
d(length(t)) = dm;
dp(length(t)) = ftell(fid);
if length(d)>length(t)
l
elseif length(d)<length(t)
l
end
arm = 0;
else
la = sscanf(l,'%*[^<]%f');
if arm && ~isempty(la)
ll(length(t),1) = la;
lp(length(t)) = ftell(fid);
else
lo = sscanf(l,'%*[^<]%f');
if arm && ~isempty(lo)
ll(length(t),2) = lo;
else
ls = sscanf(l,'%*[^<]');
if ~isempty(ls)
arm = 0;
end
end
end
end
end
end
if arm % last timepoint has no location or distance
if ~isempty(d)
t = t(1:length(d));
elseif ~isempty(ll)
t = t(1:size(ll,1));
end
end
findmin = inline('min(find(a(:)==min(a(:))))','a');
if ~isempty(d)
fprintf('%d timestamps; %d distances; %d splits; %d gaps\n',length(t),length(d),length(find(diff(t)==0)),length(find(diff(t)>1)));
else
fprintf('%d timestamps; %d distances; %d splits; %d gaps\n',length(t),length(ll),length(find(diff(t)==0)),length(find(diff(t)>1)));
end
lapsplit = find(diff(t)==0);
t(lapsplit) = [];
ll(lapsplit,:) = [];
if ~isempty(d)
d(lapsplit) = [];
dd = diff(d);
else
[x,y] = deg2utm(ll(:,1),ll(:,2));
dd = sqrt(sum(diff([x y]).^2,2));
end
dd = dd(:).';
if 1
%%
dt = diff(t);
if any(dt>1)
fprintf('missing track-points at: \n%s',sprintf('%d:%02d : %d [s]\n',[round(m2ms((t(find(diff(t)>1))-t(1))/60)).';dt(dt>1)]));
% if any(diff(t)>2)
% error('only solves single missing points');
% end
for ii = fliplr(find(dt>1))
dd(1:end+dt(ii)-1) = [dd(1:ii-1) repmat(dd(ii)/dt(ii),1,dt(ii)) dd(ii+1:end)];
end
t = t(1):t(end);
% t1(cumsum([1 (diff(t)>1)+1])) = t;
% d1(cumsum([1 (diff(t)>1)+1])) = dd;
% d1(find(~t1)) = d1(find(~t1)-1)/2;
% d1(find(~t1)-1) = d1(find(~t1));
% t1(~t1) = t1(find(~t1)-1);
end
% comb = repmat(round(splittimes),2,1)+repmat([1:2]',1,length(splittimes));
% window(comb(:)) = 1;
% xc = xcorr(window,dd);
% those = length(xc)-length(dd)-[0:length(dd)-splittimes(end)];
% xcdt = detrend(xc(those),'linear',ceil(length(those)/2));
% %plot(xcdt)
% offset = findmin(xcdt);
% figure(12345);
% s1=subplot(211);plot(dd);line(offset,0,'marker','o','color','r');line(offset+splittimes,0,'marker','s','color','g');
% s2=subplot(212);plot(xc(those));line(offset,xc(those(offset)),'marker','o','color','r');
% set(s2,'xlim',get(s1,'xlim'));
%%
m = 2;
comb = repmat(round(splittimes),m,1)+repmat([1:m]',1,length(splittimes));
window = [];
window(comb(:)) = 1;
if length(window)>length(dd)
dd = [zeros(1,2*(length(window)-length(dd))) dd zeros(1,2*(length(window)-length(dd)))];
end
xc = xcorr(window,dd);
those = length(xc)-length(dd)-[0:length(dd)-splittimes(end)];
xcdt = detrend(xc(those),'linear',ceil(length(those)/2));
%plot(xcdt)
offset = findmin(xcdt)+floor(m/2)
figure(12345);
s1=subplot(2,4,1:4);plot(dd*3600/1000);line(offset,0,'marker','o','color','r');line(offset+splittimes,0,'marker','s','color','g');
s2=subplot(2,4,5:6);plot([1:length(those)],xc(those));line(offset-floor(m/2),xc(those(offset-floor(m/2))),'marker','o','color','r');
n = 20;
x=reshape(offset+repmat(0*splittimes(:)',2*n+2,1)+repmat([-n:n nan]',1,length(splittimes)),1,[]);
y=reshape(offset+repmat(splittimes(:)',2*n+2,1)+repmat([-n:n nan]',1,length(splittimes)),1,[]);
s3=subplot(2,4,[7 8]);plot(x,dd(min(max(y,1),length(dd))));line(offset,0,'marker','s','color','r');
%%
else
%%
[b,a] = butter(2,0.9);
dd = filtfilt(b,a,dd);
for ii = 1:(t(end)-t(1))-splittimes(end)+1
td(ii) = 0;
ti = ii+(1:splittimes(end))-1;
for jj = 1:length(splittimes)
deze(jj) = findmin(abs((t(ti)-t(1))-splittimes(jj)));
td(ii) = td(ii)+dd(deze(jj));
end
end
offset = t(max(find(abs(td)==min(abs(td)))))-t(1);
%%
end
s = sprintf('Estimated offset of GPS (nr of seconds the GPS was started before the splittimer): %0.1f [s]',offset);
fprintf('%s\n',s);
new_offset = inputdlg(strvcat(s,'Keep this value, or enter a different offset (based on the graphs):'),'Corect estimated offset',1,{sprintf('%0.1f',offset)});
drawnow;
if ~isempty(new_offset{1}),
if isempty(str2num(new_offset{1}))
error('err-> invalid value: "%s"',new_offset{1});
end
offset = str2num(new_offset{1});
s3=subplot(2,4,[7 8]);
line(offset,0,'marker','s','color','m');
end
t_sync = t-t(1)-offset;
for jj = 1:length(splittimes)
splittimes_sync(jj) = t_sync(findmin(abs(t_sync-splittimes(jj))));
end
splittimes_abs = splittimes_sync+t(1)+offset;
fprintf('** finished reading tcx file **\n');
frewind(fid);
[fp,fn,fe] = fileparts(in_file);
outfile = fullfile(fp,[fn '_splits.tcx']);
fprintf('** writing output file: "%s" **\n',outfile);
fod = fopen(outfile,'w');
[fod,err] = fopen(outfile,'w');
if fod failed opening file "%s" for writing, with error: %s',outfile,err);
end
distance_offset = 0;
phase = 0;
% phases:
% 0 header
% 1 first track header, until first point to be included
% 2 first trackpoints being included
% 3 other trackpoints being included
% 4 buffering last point of current lap
% 5 obsolete lap header
% 6 last trackpoint writing
% 7 trackpoints after last trackpoint
% 8 trailer
trackpointbuffer = {};
lap = 0;
while ~feof(fid)
l = fgets(fid);
if phase==0
lp = sscanf(l,'%*[^<]<Lap%s'); % StartTime=%s');
if ~isempty(lp) && phase==0
phase = 1;
% do not parse from here
end
else
lp = sscanf(l,'%*[^<]%c');
if ~isempty(lp) && phase>0
phase = 8;
% do parse trailer from here
else
lp = sscanf(l,'%*[^<]<Creator%s'); if ~isempty(lp) && phase>0
phase = 8;
% do parse trailer from here
end
end
end
if any(phase==[2 3 4])
lp = sscanf(l,'%*[^<]%c');
if ~isempty(lp)
if any(phase==[2 3]) % not if phase is 4, since then already a lap was included here
phase = 5;
% do not parse from here, until next lap started
elseif phase==4 % buffered, but continue including lap
phase = 3; % continue writing; lap is OK here
trackpointbuffer = {};
lap = lap+1;
end
end
end
laptext = [0 0];
if any(phase==[4 5 6])
lp = sscanf(l,'%*[^<]%c');
if ~isempty(lp)
if phase==6
% last point passed, no output anymore except trailer
phase = 7;
fprintf(fod,l);
l = '';
laptext = [0 1];
elseif phase==4
% copying last trackpoint for new track
% inlude lap split
fprintf(fod,l);
laptext = [1 1]; % implicitly include trackpointbuffer
elseif phase==5
% skip first trackpoint after lap, since it is identical
phase = 3;
l = '';
end
end
end
hms = sscanf(l,'%*[^<]<time>%*[^T]T%d:%d:%dZ</time>');
if ~isempty(hms)
timestr = sscanf(l,'%*[^<]<time>%[^Z]Z</time>');
if [60*60 60 1]*hms>=splittimes_abs(1) && phase=splittimes_abs(end) && phase=splittimes_abs(lap+1) && phase%f');
if ~isempty(lp)
if phase==2
distance_offset = lp;
end
l = sprintf(' %0.7f\n',lp-distance_offset);
end
end
if laptext(2)
fprintf(fod,' \n');
fprintf(fod,' \n');
end
if laptext(1)
lap = lap+1;
fprintf(fod,' \n',timestr);
fprintf(fod,' %0.7f\n',diff(splittimes_abs(lap+[0:1])));
fprintf(fod,' Active\n');
fprintf(fod,' Manual\n');
fprintf(fod,' \n');
fprintf(fod,' \n');
end
if phase==4
if all(laptext)
fprintf(fod,'%s',trackpointbuffer{:});
trackpointbuffer = {};
phase = 3;
else
trackpointbuffer{end+1} = l;
end
end
if any(phase==[0 2 3 4 6 8])
fprintf(fod,'%s',l);
end
end
fclose(fod);
fclose(fid);
fclose('all');
fprintf('** finished successfully: splits were included in tcx file **\n');
function times = readtimes(in)
times = [];
offset = 0;
for ii = 1:length(in)
this = sscanf(in{ii},'%d%*[.:]%d%*[.:]%d');
if length(this)==2
if in{ii}(1)=='+'
offset = offset+[60 1]*this;
times(end+1) = times(end)+offset;
else
times(end+1) = [60 1]*this+offset;
end
elseif length(this)==3
if in{ii}(1)=='+'
offset = offset+[60*60 60 1]*this;
times(end+1) = times(end)+offset;
else
times(end+1) = [60*60 60 1]*this+offset;
end
end
end
% function strs = split(str,sep,include,num)
% % SPLIT - split a string in substrings by separator
% matches = [1 strfind(str,sep)+1 length(str)+2];
% for ii = 1:length(matches)-1
% strs{ii} = str(matches(ii)+(ii>1)*(size(sep,2)-1):matches(ii+1)-2);
% end
function [x,y,utmzone] = deg2utm(Lat,Lon)
% -------------------------------------------------------------------------
% [x,y,utmzone] = deg2utm(Lat,Lon)
%
% Description: Function to convert lat/lon vectors into UTM coordinates (WGS84).
% Some code has been extracted from UTM.m function by Gabriel Ruiz Martinez.
%
% Inputs:
% Lat: Latitude vector. Degrees. +ddd.ddddd WGS84
% Lon: Longitude vector. Degrees. +ddd.ddddd WGS84
%
% Outputs:
% x, y , utmzone. See example
%
% Example 1:
% Lat=[40.3154333; 46.283900; 37.577833; 28.645650; 38.855550; 25.061783];
% Lon=[-3.4857166; 7.8012333; -119.95525; -17.759533; -94.7990166; 121.640266];
% [x,y,utmzone] = deg2utm(Lat,Lon);
% fprintf('%7.0f ',x)
% 458731 407653 239027 230253 343898 362850
% fprintf('%7.0f ',y)
% 4462881 5126290 4163083 3171843 4302285 2772478
% utmzone =
% 30 T
% 32 T
% 11 S
% 28 R
% 15 S
% 51 R
%
% Example 2: If you have Lat/Lon coordinates in Degrees, Minutes and Seconds
% LatDMS=[40 18 55.56; 46 17 2.04];
% LonDMS=[-3 29 8.58; 7 48 4.44];
% Lat=dms2deg(mat2dms(LatDMS)); %convert into degrees
% Lon=dms2deg(mat2dms(LonDMS)); %convert into degrees
% [x,y,utmzone] = deg2utm(Lat,Lon)
%
% Author:
% Rafael Palacios
% Universidad Pontificia Comillas
% Madrid, Spain
% Version: Apr/06, Jun/06, Aug/06, Aug/06
% Aug/06: fixed a problem (found by Rodolphe Dewarrat) related to southern
% hemisphere coordinates.
% Aug/06: corrected m-Lint warnings
%-------------------------------------------------------------------------
% Argument checking
%
error(nargchk(2, 2, nargin)); %2 arguments required
n1=length(Lat);
n2=length(Lon);
if (n1~=n2)
error('Lat and Lon vectors should have the same length');
end
% Memory pre-allocation
%
x=zeros(n1,1);
y=zeros(n1,1);
utmzone(n1,:)='60 X';
% Main Loop
%
for i=1:n1
la=Lat(i);
lo=Lon(i);
sa = 6378137.000000 ; sb = 6356752.314245;
%e = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sa;
e2 = ( ( ( sa ^ 2 ) - ( sb ^ 2 ) ) ^ 0.5 ) / sb;
e2cuadrada = e2 ^ 2;
c = ( sa ^ 2 ) / sb;
%alpha = ( sa - sb ) / sa; %f
%ablandamiento = 1 / alpha; % 1/f
lat = la * ( pi / 180 );
lon = lo * ( pi / 180 );
Huso = fix( ( lo / 6 ) + 31);
S = ( ( Huso * 6 ) - 183 );
deltaS = lon - ( S * ( pi / 180 ) );
if (la<-72), Letra='C';
elseif (la<-64), Letra='D';
elseif (la<-56), Letra='E';
elseif (la<-48), Letra='F';
elseif (la<-40), Letra='G';
elseif (la<-32), Letra='H';
elseif (la<-24), Letra='J';
elseif (la<-16), Letra='K';
elseif (la<-8), Letra='L';
elseif (la<0), Letra='M';
elseif (la<8), Letra='N';
elseif (la<16), Letra='P';
elseif (la<24), Letra='Q';
elseif (la<32), Letra='R';
elseif (la<40), Letra='S';
elseif (la<48), Letra='T';
elseif (la<56), Letra='U';
elseif (la<64), Letra='V';
elseif (la<72), Letra='W';
else Letra='X';
end
a = cos(lat) * sin(deltaS);
epsilon = 0.5 * log( ( 1 + a) / ( 1 - a ) );
nu = atan( tan(lat) / cos(deltaS) ) - lat;
v = ( c / ( ( 1 + ( e2cuadrada * ( cos(lat) ) ^ 2 ) ) ) ^ 0.5 ) * 0.9996;
ta = ( e2cuadrada / 2 ) * epsilon ^ 2 * ( cos(lat) ) ^ 2;
a1 = sin( 2 * lat );
a2 = a1 * ( cos(lat) ) ^ 2;
j2 = lat + ( a1 / 2 );
j4 = ( ( 3 * j2 ) + a2 ) / 4;
j6 = ( ( 5 * j4 ) + ( a2 * ( cos(lat) ) ^ 2) ) / 3;
alfa = ( 3 / 4 ) * e2cuadrada;
beta = ( 5 / 3 ) * alfa ^ 2;
gama = ( 35 / 27 ) * alfa ^ 3;
Bm = 0.9996 * c * ( lat - alfa * j2 + beta * j4 - gama * j6 );
xx = epsilon * v * ( 1 + ( ta / 3 ) ) + 500000;
yy = nu * v * ( 1 + ta ) + Bm;
if (yy<0)
yy=9999999+yy;
end
x(i)=xx;
y(i)=yy;
utmzone(i,:)=sprintf('%02d %c',Huso,Letra);
end
function ms = m2ms(m,textout)
% min to min:sec
% if second argument is true, then text is output
if nargin1 && ~~textout)
if any(ms(:,1)>=60)
f = '%d:%02d';
hms = [floor(ms(:,1)/60) mod(ms,60)];
else
f = '%02d';
hms = ms;
end
if any(abs(m*60-round(m*60))>1e-3)
f = [f ':%06.3f'];
else
f = [f ':%02.0f'];
end
if ~nargout
fprintf([f '\n'],hms.');
clear ms;
else
ms = num2str(hms,f);
end
end |