Label Routes based on GPS coordinates in R/MATLAB - matlab

I have three fixed points say A, B and C and several routes to commute between them, they can be in any order. Trip starts and ends at A. Image of routes, fixed points and reference points.
I have 1000s of GPS files in which I need to label the routes that were taken. The GPS files record Latitude, Longitude (in degrees), speed, distance traveled each second and cumulative distance.
I think of the following algorithm: Identify a reference point on each route at a fixed distance (say d) from each of point A, B and C. Now scan the GPS file for the first occurrence of either of Point A, B or C. Since its a GPS measurement, there may not be an exact point corresponding to A, B or C. So, we can find the first occurrence of a point within say 0.1 mile of either A, B or C.
Now start calculating the cumulative from Point A as we move towards B or C. when cumulative distance reaches close to d (again it may not be exactly d), we record coordinates of that point and find the reference point which is closest to it. The closest reference point will give me the route. I need to assign this route from start point to the second occurrence of either of A, B or C. For example, after traveling ā€˜dā€™ miles from either of A, B or C, we find that coordinate is closest to Point 3 in the Figure, we say that the route is BA. If the closest point is 2, then route is AB.
Now we go to second occurrence of A, B or C and then find a point after distance d and find a closest reference point to that point. Assign routes and so on.
Please help me with the code. Either R or MATLAB.

So, I wrote a code with a lot of for loops. It works well for me, no errors. Takes about 9 seconds to process a single file of 15000 rows and identify all 8 routes I need. So far so good. Just looking to find a more optimized program or a faster program. I am a beginner at programming.
gpsdata <- read.csv(file = filename, header = TRUE)
####lat and long of route start/end points
# Route Start Point: Routes A and C on Cates Avenue
cateslat = 35.781999
cateslon = -78.668252
#Route Mid: Intersection of AC13, Morning Dove Road
morlat = 35.882035
morlon = -78.645653
#Route End: RTP
rtplat = 35.895431
rtplon = -78.868958
}
#REFERENCE POINTS FOR ROUTE IDENTIFICATION ON EACH ROUTE
{
routea_lat = 35.795400
routea_lon = -78.641243
routec_lat = 35.821031
routec_lon = -78.687069
route1_lat = 35.913527
route1_lon = -78.714348
route3_lat = 35.922331
route3_lon = -78.842865
}
##### ROUTE START POINT TOLERANCE in miles
route_tol = 0.02
##### Reference POINT TOLERANCE for Identifying Routes (in miles)
ref_tol = 0.5
##Calculation Starts Here
n = length(gpsdata$Timestamp) ##File length
#Find point q where we first reach starting route (within 0.01 miles)
for (i in 1:n){
if((distm(c(gpsdata$Longitude[i], gpsdata$Latitude[i]),c(cateslon,
cateslat),fun = distHaversine)*0.000621371)<route_tol){
q=i
break
}
else
{
q=1
}
}
### First Route: Either A-Out or C-Out
for (i in q:n){
if((distm(c(gpsdata$Longitude[i], gpsdata$Latitude[i]),c(morlon, morlat),fun
= distHaversine)*0.000621371)<route_tol){
r=i
break
}
else
{
r=1
}
}
gpsdata1=gpsdata[(q+1):r,]
for (i in 1:length(gpsdata1$Timestamp)){
if((distm(c(gpsdata1$Longitude[i], gpsdata1$Latitude[i]),c(routea_lon,
routea_lat),fun = distHaversine)*0.000621371)<ref_tol){
gpsdata1$Route='A-Out'
break
} else if((distm(c(gpsdata1$Longitude[i],
gpsdata1$Latitude[i]),c(routec_lon, routec_lat),fun =
distHaversine)*0.000621371)<ref_tol){
gpsdata1$Route='C-Out'
break
} else{
gpsdata1$Route='Error-Check Data'
}
}
#Second Route: possibilities- 1-Out, 3-Out, A-In, C-In
#From Here we can either go back to Cates Avenue or go to RTP
for (i in r:n){
if((distm(c(gpsdata$Longitude[i], gpsdata$Latitude[i]),c(rtplon, rtplat),fun
= distHaversine)*0.000621371<route_tol) || +
(distm(c(gpsdata$Longitude[i], gpsdata$Latitude[i]),c(cateslon,
cateslat),fun = distHaversine)*0.000621371<route_tol)){
s=i
break
}
else
{
s=1
}
}
gpsdata2=gpsdata[(r+1):s,]
for (i in 1:length(gpsdata2$Timestamp)){
if((distm(c(gpsdata2$Longitude[i], gpsdata2$Latitude[i]),c(route1_lon,
route1_lat),fun = distHaversine)*0.000621371)<ref_tol){
gpsdata2$Route='1-Out'
break
} else if((distm(c(gpsdata2$Longitude[i],
gpsdata2$Latitude[i]),c(route3_lon, route3_lat),fun =
distHaversine)*0.000621371)<ref_tol){
gpsdata2$Route='3-Out'
break
} else if((distm(c(gpsdata2$Longitude[i],
gpsdata2$Latitude[i]),c(routea_lon, routea_lat),fun =
distHaversine)*0.000621371)<ref_tol){
gpsdata2$Route='A-In'
break
} else if((distm(c(gpsdata2$Longitude[i],
gpsdata2$Latitude[i]),c(routec_lon, routec_lat),fun =
distHaversine)*0.000621371)<ref_tol){
gpsdata2$Route='C-In'
break
} else{
gpsdata2$Route='Error-Check Data'
}
}

Related

AnyLogic findAll facility within certain distance from people and return best facility

I am trying to use findAll function that takes two arguments: collection, condition. My collection will be facilities (Pharma) but condition is based on population distance. After finding all, I want to choose best (service) one. So far, I fried following approach. But an error and probably on condition in findAll; saying method is not applicable.... Could anybody help with this? or any other ideas?
Pharma nearest = this.getNearestAgent(main.pharmas);
for (int i=0; i<main.people.size(); i++){
Person p = main.people.get(i);
if (p.getConnectionsNumber()>0){
List <Pharma> x = findAll(main.pharmas, p.agentsInRange(100));//[Problem is here]
Pharma y = top(x, s->s.serviceQuality);
return y;
}else{
return nearest;
}
}
The find all function in AnyLogic requires you to use a predicate as the second argument for find all.
As per the comments you need to use
x = findAll(main.pharmas,p -> p.agentsInRange(100))
You can read more about using predicates here - https://www.theanylogicmodeler.com/post/using-predicates-in-anylogic
Below is the code that solved my purpose. I wanted that there is a certain percentage of possibility that some people may go beyond the nearest facility for some reasons like better service quality.
Pharma nearest = this.getNearestAgent(main.pharmas);
if (this.getConnectionsNumber()>0){
List <Pharma> x = findAll(main.pharmas, l->l.distanceTo(this)<400);
Pharma y = top(x, s->s.serviceQuality);
if (randomTrue(0.4)){
return y;
}else{
return nearest;
}
}else{
return nearest;
}

type object "TimeDistance" has no attribute "time"

i'm trying to make a time distance calculator in which each object would represent a problem, or "implementation" of the formula, distance = speed * time(that might not be 100% correct, don't quote me.
anyway, the problem is that the compiler keeps throwing an error any time i try to run, saying that "time is not defined". I've made time a global variable within a try catch loop, so a little more clarity on what I've done wrong here.
the error is within the classmethod speedTime at line 28:
#key principle for this program: each object is a question, or instance of the equation d = s * t.
import time as t
class TimeDistance:
def init(self, speed, distance, time):
self.speed = speed
self.distance = distance = distance
self.time = time
#staticmethod
def gap():
print("====================================")
t.sleep(0.5)
#staticmethod
def typeMessage(): #type message that is displayed when the wrong type is entered
print("value is of wrong type. please enter either a whole or decimal number")
print(" ")
t.sleep(0.5)
#classmethod
def speedTime(cls): #get this method working for 6/11/17
loop = True
#we need try catch loops:
while(loop):
try:
global speed
speed = float(input("Enter the velocity in metres per second:"))
loop = False
except ValueError:
TimeDistance.typeMessage()
while(loop):
try:
global time#looks like scope is a problem.
time = float(input("Enter the time taken in seconds:"))
loop = False
except ValueError:
TimeDistance.typeMessage()
distance = speed * time
ob = TimeDistance(speed, distance, time)
print("The total distance travelled in kilometers is {0} km".format(ob.distance))
#classmethod
def distanceTime(cls): #don't worry about this untill
distance = float(input("enter the distance travelled in km:"))
while type(distance) != float:
TimeDistance.typeMessage()
distance = float(input())
speed = float(input("Enter the velocity in metres per second:"))
TimeDistance.speedTime()
side-note: is there anything wrong with declaring global variables in the way i did?

Merge Sort algorithm efficiency

I am currently taking an online algorithms course in which the teacher doesn't give code to solve the algorithm, but rather rough pseudo code. So before taking to the internet for the answer, I decided to take a stab at it myself.
In this case, the algorithm that we were looking at is merge sort algorithm. After being given the pseudo code we also dove into analyzing the algorithm for run times against n number of items in an array. After a quick analysis, the teacher arrived at 6nlog(base2)(n) + 6n as an approximate run time for the algorithm.
The pseudo code given was for the merge portion of the algorithm only and was given as follows:
C = output [length = n]
A = 1st sorted array [n/2]
B = 2nd sorted array [n/2]
i = 1
j = 1
for k = 1 to n
if A(i) < B(j)
C(k) = A(i)
i++
else [B(j) < A(i)]
C(k) = B(j)
j++
end
end
He basically did a breakdown of the above taking 4n+2 (2 for the declarations i and j, and 4 for the number of operations performed -- the for, if, array position assignment, and iteration). He simplified this, I believe for the sake of the class, to 6n.
This all makes sense to me, my question arises from the implementation that I am performing and how it effects the algorithms and some of the tradeoffs/inefficiencies it may add.
Below is my code in swift using a playground:
func mergeSort<T:Comparable>(_ array:[T]) -> [T] {
guard array.count > 1 else { return array }
let lowerHalfArray = array[0..<array.count / 2]
let upperHalfArray = array[array.count / 2..<array.count]
let lowerSortedArray = mergeSort(array: Array(lowerHalfArray))
let upperSortedArray = mergeSort(array: Array(upperHalfArray))
return merge(lhs:lowerSortedArray, rhs:upperSortedArray)
}
func merge<T:Comparable>(lhs:[T], rhs:[T]) -> [T] {
guard lhs.count > 0 else { return rhs }
guard rhs.count > 0 else { return lhs }
var i = 0
var j = 0
var mergedArray = [T]()
let loopCount = (lhs.count + rhs.count)
for _ in 0..<loopCount {
if j == rhs.count || (i < lhs.count && lhs[i] < rhs[j]) {
mergedArray.append(lhs[i])
i += 1
} else {
mergedArray.append(rhs[j])
j += 1
}
}
return mergedArray
}
let values = [5,4,8,7,6,3,1,2,9]
let sortedValues = mergeSort(values)
My questions for this are as follows:
Do the guard statements at the start of the merge<T:Comparable> function actually make it more inefficient? Considering we are always halving the array, the only time that it will hold true is for the base case and when there is an odd number of items in the array.
This to me seems like it would actually add more processing and give minimal return since the time that it happens is when we have halved the array to the point where one has no items.
Concerning my if statement in the merge. Since it is checking more than one condition, does this effect the overall efficiency of the algorithm that I have written? If so, the effects to me seems like they vary based on when it would break out of the if statement (e.g at the first condition or the second).
Is this something that is considered heavily when analyzing algorithms, and if so how do you account for the variance when it breaks out from the algorithm?
Any other analysis/tips you can give me on what I have written would be greatly appreciated.
You will very soon learn about Big-O and Big-Theta where you don't care about exact runtimes (believe me when I say very soon, like in a lecture or two). Until then, this is what you need to know:
Yes, the guards take some time, but it is the same amount of time in every iteration. So if each iteration takes X amount of time without the guard and you do n function calls, then it takes X*n amount of time in total. Now add in the guards who take Y amount of time in each call. You now need (X+Y)*n time in total. This is a constant factor, and when n becomes very large the (X+Y) factor becomes negligible compared to the n factor. That is, if you can reduce a function X*n to (X+Y)*(log n) then it is worthwhile to add the Y amount of work because you do fewer iterations in total.
The same reasoning applies to your second question. Yes, checking "if X or Y" takes more time than checking "if X" but it is a constant factor. The extra time does not vary with the size of n.
In some languages you only check the second condition if the first fails. How do we account for that? The simplest solution is to realize that the upper bound of the number of comparisons will be 3, while the number of iterations can be potentially millions with a large n. But 3 is a constant number, so it adds at most a constant amount of work per iteration. You can go into nitty-gritty details and try to reason about the distribution of how often the first, second and third condition will be true or false, but often you don't really want to go down that road. Pretend that you always do all the comparisons.
So yes, adding the guards might be bad for your runtime if you do the same number of iterations as before. But sometimes adding extra work in each iteration can decrease the number of iterations needed.

Looping in optimization

I have a dataset of 20 points which I need to enclose in an ellipse. I am trying to do this calculating a biggest distance between the center of ellipse and removing the farthest point, reconstructing a new ellipse and repeating the process again.
Here is the code:
P = [1.397100 0.934550
-0.708828 -3.993403
-0.775017 -0.167091
1.861729 -0.334958
-0.376357 -3.187580
0.294908 -0.765351
0.952188 -1.872313
0.524652 2.972442
0.889532 -0.331162
0.991093 0.278271
0.262071 0.078590
0.901017 0.320209
-0.797258 0.518452
-0.656796 0.268351
0.333667 0.601893
0.762157 0.613208
0.292147 -1.555187
0.122875 -0.860661
0.702863 -3.195442
-1.140430 -1.919686]'
t = 0.001;
K = convhulln(P');
K = unique(K(:));
Q = P(:,K);
[A , C] = MinVolEllipse(Q, t)
figure
plot(P(1,:),P(2,:),'*')
hold on
Ellipse_plot(A,C)
%Rule=size(P',1)
W=P'
v=C'
Cx=v(1)
Cy=v(2)
dist=sqrt((W(:,1)-Cx).^2+(W(:,2)-Cy).^2)
Remove=find(dist==max(dist(:)))
W(Remove,:)=[]
W=W'
Rule=size(W',1)
while Rule>5
W=W';
v=C';
Cx=v(1);
Cy=v(2);
dist=sqrt((W(:,1)-Cx).^2+(W(:,2)-Cy).^2);
Remove=find(dist==max(dist(:)));
W(Remove,:)=[];
W=W';
end
[A , C] = MinVolEllipse(W, t)
figure
plot(W(1,:),W(2,:),'*')
hold on
Ellipse_plot(A,C)
I understand that I did something wrong but now I'm stuck with "Busy" for about 10 minutes. How to properly loop the process?
Thanks!
You need to update the value of Rule
while Rule>5
W=W';
v=C';
Cx=v(1);
Cy=v(2);
dist=sqrt((W(:,1)-Cx).^2+(W(:,2)-Cy).^2);
Remove=find(dist==max(dist(:)));
W(Remove,:)=[];
W=W';
Rule=size(W',1)
end
As a separate point, you perform some redundant operation e.g. the first and the last line of you loop do the inverse operation. Maybe something like this: (Note the code is not tested)
while size(W,1)>5
dist=sqrt((W(:,1)-C(1)).^2+(W(:,2)-C(2)).^2);
% the second returned variable is the location
[~, Remove] = max(dist(:));
W(Remove,:)=[];
end

Minimum distance to plot points on UIMapview

my query is whats the minimum distance required to plot point on a UIMAPVIEW, so that they could be shown as distinct points.
For e.g., suppose if there are users in same apartment, their would be hardly any distance between their latitude-longitude. So how do i differentiate them !
There are usually two ways - one is clustering, which means you use a marker with a number that indicates how many underlying markers there are. When tapping on that, the user is then shown the separate markers (or a recursive zoom-in that splits the markers up more and more). Superpin (www.getsuperpin.com) is one example, but there are others out there.
Another approach is to actually offset the marker from its real location. For this, you need some kind of distribution algorithm that offsets it just enough - that is, set the markers as close together as possible while still giving them enough surface area to be seen/touched. For this, we use Fibonacci's Sunflower patten. What you'd have to do is identify all the Annotations that have the same coordinate, group them, and then draw each group in a sequence while offsetting one from the other - for ex. have some code that iterates along a spiral shape and drops down markers along that spiral.
Can put up sample code etc to help if you're wanting to go with the second approach, let me know.
EDIT: I found some code we wrote for this, but it's not objective C. Can you read it?
class SunFlower
{
static $SEED_RADIUS = 2;
static $SCALE_FACTOR = 4;
static $PI2 = 6.28318531; // PI * 2
static $PHI = 1.61803399; // (sqrt(5)+1) / 2
public static function calcPos($xc, $yc, $factor, $i)
{
$theta = $i * SunFlower::$PI2 / SunFlower::$PHI;
$r = sqrt($i) * $factor;
$x = $xc + $r * cos($theta);
$y = $yc - $r * sin($theta);
if ($i == 1) {
$y += ($factor * 0.5);
}
return array($x, $y);
}
}