OSRM: Find place on route after some elapsed time? - maps

For a given start and end point of a route, I want to know at which point on the route I will be after a certain amount of time.
E.g. given coordinates long_start, lat_start and long_end, lat_end, and taking the route that OSRM suggests, where will the car be after 2 minutes?
Is there a simple way to do this via the OSRM HTTP-API?

You can pass the option annotations=duration&overview=full to the route service and then use the routes[0].legs[0].annotations.durations array to find out at which coordinate you would be after a given time.
Pseudo-code:
sum = 0
index = 0
durations = routes[0].legs[0].annotations.durations
while index < durations.length and sum < max_duration
sum += durations[index]
index++
location = decodePolyline(routes[0].geometry)[index]

Related

subtract a value from an array efficiently in matlab

I have an 2-dim array representing the arrival times of photons in two channels, the array contains a line with the information about the arrival time and the other with the information about the timestamp
data = stream.getData();
timestamps = data.getTimestamps();
channels = data.getChannels();
timetags = [timestamps; channels];
t= [timetags];
I need a start-multiple stop measurments, so when there is a click in the channel 1 I need to subtract the timestamp for that click in every timestamp of channel 2, until the next click in channel 1 and so on. I used a for cicle for this:
for i=1:length(t)
if t(2,i)==1
t(1,i:end)=t(1,i:end)-t(1,i)
end
end
but it is quite slow. Is there a faster way to do that?
You can use t(2,:)==0 to create an array which is true on your condition, then t(1,:).*(t(2,:)==0) gives either 0 or the current timestamp when this is true.
Therefore, if t(2,:) is non-decreasing you should be able to do something like
t(1,:) = t(1,:) - cummax( t(1,:) .* (t(2,:)==0) );

Number of events in one array within w minutes after any event in a second array

I have two sorted arrays of unix time stamps (so integers representing times at which some events happen). Lets call the arrays ts1 and ts2. I want to find the number of events in ts1 that lie after w-minutes of any event in ts2. Let's say the method signature is (take the first and second arrays and window size then return number of events in ts1 that are within w minutes after any event in ts2):
critical_events(ts1,ts2,w)->int
Here are some test cases:
## Test cases.
ev = critical_events([.5,1.5,2.5],[1,2,3],.5)
print(ev==0)
ev = critical_events([1.4,1.4,2.7],[1,2,3],.5)
print(ev==2)
ev = critical_events([1.4,2.4,3.4],[1,2,3],.5)
print(ev==3)
I expect the length of the first array, n to be much larger than the length of the second one, m. Looking for efficient algorithms in terms of time and space and if possible, their average and worst case complexities in terms of n and m, time and space.
My attempt: instead of explaining my attempts, I'll just link to the code which should be self-explanatory (or at least better than what I can do in words): https://gist.github.com/ryu577/fdc22af4ed17d122a6aa25684597745b
You are showing them as sorted, so my assumption is they are (need to be for this to work).
Because your first array is much larger than your second, you need to take your second in a for loop.
I am using example test case 2:ev = critical_events([1.4,1.4,2.7],[1,2,3],.5)
Next you can use a binary search on the first element of ts2 + interval (1 + 0.5) = 1.5.
Your startIndex is 0 and endIndex is 2. So in first compare you take all elements.
Doing a binary search will result in index 2 in ts1. Note: Because you have equal element in your array, you need to go right until you get higher number. What you can tell now is that 2.7 (and all elements after if there where any) are the element what lies after 1.5. Count is ts2.lenght - foundindex.
Now you can set your start index to 2. because you know, all on the left of this index is smaller and will not lie after 1.5 sec.
You take element2 and do a binary search, you will find index 2 ( 2.5 < 2.7), again:
Count = Count + ts2.lenght - foundindex.
To my knowledge, this is the fastest method. I believe the speed is Log(n).m.

Find element in an array (matlab) with defined position (of time array)

I have one array that depends on another (i.e. I have the array of the tension (V) in function of the array of the time). I'd like to find the position of an element of the array of the tension at a particular moment of time (i.e. corresponding to a particular position of the time vector). How can I do that?
I have tried the following:
VMpzt = max(V);
%find the maximum value of the array of tensions
idxV = find(V == VMpzt);
%find the corresponding index
idxt = t(idxV);
%find the corresponding index of time vector
diff = 0.0048377328;
idxt2 = idxt-diff;
%in fact, I am interested at the index of time that corresponds to this particular position
Vmpzt = V(idxt2); %find the corresponding position of V array
doing so, I get the error
"Array indices must be positive integers or logical values."
idxt = t(idxV); %find the corresponding index of time vector
This line does not do what your comment suggests. It find the time at that index, not the index. You then subtract diff from it and try use it as an index but it isn't an index, it's a time. I think your variable names confused you. Try this:
[V_max, V_max_index] = max(V);
t_at_v_max = t(V_max_index); %find the TIME where V was max
diff = 0.0048377328;
t_desired = t_at_v_max - diff;
You now want the index where t equals t_desired. Because you are dealing with floating point numbers you can't just do find(t==t_desired) so instead we need to do this:
t_desired_index = find(abs(t-t_desired) < diff/1000); %1000 chosen arbitrarily, you might need to change it
and finally:
Vmpzt = V(t_desired_index );

Find specific date in a date array

I am working with a datetime array s constructed as follows:
ds = datetime(2010,01,01,'TimeZone','Europe/Berlin');
de = datetime(2030,01,01,'TimeZone','Europe/Berlin');
s = ds:hours(1):de;
I am using ismember function to find the first occurrence of a specific date in that array.
ind = ismember(s,specificDate);
startPlace = find(ind,1);
The two lines from above are called many times in my application and consume quite some time. It is clear to me that Matlab compares ALL dates from s with specificDate, even though I need only the first occurrence of specificDate in s. So to speed up the application it would be good if Matlab would stop comparing specificDate to s once the first match is found.
One solution would be to use a while loop, but with the while loop the application becomes even slower (I tried it).
Any idea how to work around this problem?
I'm not sure what your specific use-case is here, but with the step size between elements of s being one hour, your index is simply going to be the difference in hours between your specific date and the start date, plus one. No need to create or search through s in the first place:
startPlace = hours(specificDate-ds)+1;
And an example to test each solution:
specificDate = datetime(2017, 1, 1, 'TimeZone', 'Europe/Berlin'); % Sample date
ind = ismember(s, specificDate); % Compare to the whole vector
startPlace = find(ind, 1); % Find the index
isequal(startPlace, hours(specificDate-ds)+1) % Check equality of solutions
ans =
logical
1 % Same!
What you can do to save yourself some time is to convert the datetime to a datenum in such a case you will be comparing numbers rather than strings, which significantly accelerates your processing time, like this:
s_new = datenum(s);
ind = ismember(s_new,datenum(specificDate));
startPlace = find(ind,1);

Probability density function with large mu and sigma values?

I am using the following function :
pd=makedist('normal',mu,sigma);
y = pdf(pd,speed)
The size of mu and sigma is 50x1 and X size is 3000x1. passing one value of mu,sigma and speed at a time, I am getting the output. But how I can pass all these values at the same time so that at the end I will get a data set containing all y values?
I think I have to use a for loop but am unsure how to do it.
mu = rand(50,1);
sigma = rand(50,1);
speed = rand(3000,1);
y = zeros(numel(mu),numel(speed));
for k = 1:numel(mu)
pd = makedist('normal',mu(k),sigma(k));
y(k,:) = pdf(pd,speed); %store in for loop
end
By initialising the output one can easily double-loop to calculate all components. Your ouput is now indexed as y(mu/sigma,speed), thus the first index corresponds to the mu/sigma pair and the second to the speed entry used.

Resources