SafeDispatch/ReportsLibrary/Reports/CalcStops.cs

681 lines
29 KiB
C#
Raw Permalink Normal View History

2024-02-22 16:43:59 +00:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Windows.Forms;
//using MapGoogle;
using SafeMobileLib;
//using MapPoint;
//using AxMapPoint;
namespace ReportsLibrary
{
public class CalcStops
{
public ArrayList Positions = new ArrayList();
public ArrayList StopsList = new ArrayList();
ArrayList IndexRemove = new ArrayList();
//SMdb_access smdbObj;
double delta;
Double stopreflat;
Double stopreflng;
Int64 stoptime;
int startidx = 0;
int count = -1;
Boolean stopset = false;
Boolean first;
int idxread;
Int64 zone1OUTtime;
Double startlat;
Double startlng;
Int32 entertime, exittime;
int startcount;
private Boolean CalcAddr;
struct IndexCut
{
public int IndCut;
public Int32 LastTime;
}
public CalcStops(Boolean CalcAddrParam)
{
CalcAddr = CalcAddrParam;
}
public void get_position(ArrayList ListIN)
{
if (ListIN != null)
foreach (PositionData obj in ListIN)
Positions.Add(new PositionData(obj.Lat, obj.Lng, obj.Address, obj.TimeGMT, obj.Type, obj.Speed));
}
public static double GetAverage(ArrayList Values)
{
double mean = 0;
foreach (double average in Values)
{ mean += average; }
if (Values.Count != 0) mean /= Values.Count;
return mean;
}
public static ArrayList LATAver = new ArrayList();
public static ArrayList LNGAver = new ArrayList();
public void calculate_zone()
{
delta = StaticMembers.Delta1 * 0.00001;//0.0007;
if (Positions.Count > 0)
{
stopreflat = ((PositionData)Positions[0]).Lat;
stopreflng = ((PositionData)Positions[0]).Lng;
stoptime = ((PositionData)Positions[0]).TimeGMT;
startidx = 0;
count = -1;
stopset = false;
PositionData prevobj = null;
PositionData obj = null;
// long timeToCompare = 0;
while (count < (Positions.Count - 1))
{
count++;
obj = (PositionData)Positions[count];
((PositionData)Positions[count]).Type = car_state_e.CAR_RUNNING;
if (prevobj == null || (obj.TimeGMT - prevobj.TimeGMT) > (((VehicleForReports)StaticMembers.vehicleHT[StaticMembers.NameReport]).gps_interval * 4.1)) // 10 mins //!!modif this
{
if (!stopset)
{
((PositionData)Positions[count]).Type = car_state_e.CAR_START;
if (prevobj != null && prevobj.Type == car_state_e.CAR_RUNNING)
{
((PositionData)Positions[count - 1]).Type = car_state_e.CAR_STOP;
}
LATAver.Clear();
LNGAver.Clear();
stopreflat = ((PositionData)Positions[count]).Lat;
stopreflng = ((PositionData)Positions[count]).Lng;
LATAver.Add(stopreflat);
LNGAver.Add(stopreflng);
stoptime = ((PositionData)Positions[count]).TimeGMT;
startidx = count + 1;
prevobj = obj;
continue;
}
}
if (((obj.Lat < (stopreflat + delta)) && (obj.Lat > (stopreflat - delta))) && ((obj.Lng < (stopreflng + delta)) && (obj.Lng > (stopreflng - delta))))
{
if (!stopset)
{
if (obj.TimeGMT > (stoptime + ((VehicleForReports)StaticMembers.vehicleHT[StaticMembers.NameReport]).gps_interval * 4.1)) //4.1 sa lipsesca 4 semnale GPS si un pic
{
stopset = true;
for (int i = startidx; i <= count; i++)
{
if (startidx > 0 &&
((PositionData)Positions[startidx - 1]).Type == car_state_e.CAR_START)
((PositionData)Positions[i]).Type = car_state_e.CAR_START;
else
((PositionData)Positions[i]).Type = car_state_e.CAR_STOP;
LATAver.Add(((PositionData)Positions[i]).Lat);
LNGAver.Add(((PositionData)Positions[i]).Lng);
//stopreflat = (stopreflat+((PositionData)Positions[i]).Lat)/2;
//stopreflng = (stopreflng + ((PositionData)Positions[i]).Lng) / 2;
}
stopreflat = GetAverage(LATAver);
stopreflng = GetAverage(LNGAver);
}
}
else
{
if (startidx > 0 &&
((PositionData)Positions[startidx - 1]).Type == car_state_e.CAR_START)
((PositionData)Positions[count]).Type = car_state_e.CAR_START;
else
((PositionData)Positions[count]).Type = car_state_e.CAR_STOP;
//stopreflat = (stopreflat + ((PositionData)Positions[count]).Lat) / 2;
//stopreflng = (stopreflng + ((PositionData)Positions[count]).Lng) / 2;
LATAver.Add(((PositionData)Positions[count]).Lat);
LNGAver.Add(((PositionData)Positions[count]).Lng);
stopreflat = GetAverage(LATAver);
stopreflng = GetAverage(LNGAver);
}
prevobj = obj;
}
else
{
Int32 step = 0;
Boolean stay = true;
while ((step < 6) && (stay))
{
step++;
if ((count + step + 1) < Positions.Count)
{
if ((((((PositionData)Positions[count + step]).Lat < (stopreflat + delta))
&& (((PositionData)Positions[count + step]).Lat > (stopreflat - delta)))
&& ((((PositionData)Positions[count + step]).Lng < (stopreflng + delta))
&& (((PositionData)Positions[count + step]).Lng > (stopreflng - delta)))) &&
(((((PositionData)Positions[count + step + 1]).Lat < (stopreflat + delta))
&& (((PositionData)Positions[count + step + 1]).Lat > (stopreflat - delta)))
&& ((((PositionData)Positions[count + step + 1]).Lng < (stopreflng + delta))
&& (((PositionData)Positions[count + step + 1]).Lng > (stopreflng - delta)))))
{
if (stopset)
{
if (startidx > 0 &&
((PositionData)Positions[startidx - 1]).Type == car_state_e.CAR_START)
{
((PositionData)Positions[count]).Type = car_state_e.CAR_START;
for (int i = 1; i <= step; i++)
((PositionData)Positions[count + i]).Type = car_state_e.CAR_START;
}
else
{
((PositionData)Positions[count]).Type = car_state_e.CAR_STOP;
//((PositionData)Positions[count + 1]).Type = car_state_e.CAR_STOP;
for (int i = 1; i <= step; i++)
((PositionData)Positions[count + i]).Type = car_state_e.CAR_STOP;
}
}
else
{
//((PositionData)Positions[count + 1]).Type = car_state_e.CAR_RUNNING;
for (int i = 1; i <= step; i++)
((PositionData)Positions[count + i]).Type = car_state_e.CAR_RUNNING;
}
count = count + step;
stay = false;
}
else stay = true;
}
else stay = false;
}
if (stay)
{
stopreflat = obj.Lat;
stopreflng = obj.Lng;
stoptime = obj.TimeGMT;
startidx = count;
stopset = false;
prevobj = obj;
}
}
}
}
// make the last pos a stop
if (count != -1)
if (((PositionData)Positions[Positions.Count - 1]).Type == car_state_e.CAR_RUNNING)
((PositionData)Positions[Positions.Count - 1]).Type = car_state_e.CAR_STOP;
}
public Double calcDistance(Int32 start, Int32 stop)
{
PositionData prevobj = null;
Double totalDistance = 0;
foreach (PositionData obj in Positions)
{
if ((obj.TimeGMT >= start) && (obj.TimeGMT <= stop))
{
if (prevobj != null)
{
DistanceCalc tmp = new DistanceCalc(prevobj.Lat, prevobj.Lng, obj.Lat, obj.Lng);
totalDistance += tmp.GetDistance();
}
prevobj = obj;
}
}
return totalDistance;
}
public void calc_zone_with_delta2()
{
first = false;
idxread = 0;
zone1OUTtime = 0;
if (Positions.Count != 0) zone1OUTtime = ((PositionData)Positions[0]).TimeGMT;
startlat = 0;
startlng = 0;
count = -1;
delta = StaticMembers.Delta2 * 0.00001;//0.001;
//test filtrat CAR_STOP CAR_START CAR_STOP BEFORE
try
{
for (int i = 0; i < Positions.Count; i++)
{
if (((PositionData)(Positions[i])).Type == car_state_e.CAR_STOP)
{
if (((i + 1) < Positions.Count) && (((PositionData)(Positions[i + 1])).Type == car_state_e.CAR_START))
{
Int32 Step = i + 2;
car_state_e typeFind = car_state_e.CAR_START;
while ((Step < Positions.Count) && (typeFind == car_state_e.CAR_START))
{
if (((PositionData)(Positions[Step])).Type == car_state_e.CAR_RUNNING) typeFind = car_state_e.CAR_RUNNING;
else if (((PositionData)(Positions[Step])).Type == car_state_e.CAR_STOP) typeFind = car_state_e.CAR_STOP;
Step++;
}
if (typeFind == car_state_e.CAR_STOP)
{
for (int j = (i + 1); j < (Step - 1); j++)
((PositionData)(Positions[j])).Type = car_state_e.CAR_STOP;
}
}
}
}
for (int i = 0; i < Positions.Count; i++)
{
if (((PositionData)(Positions[i])).Type == car_state_e.CAR_RUNNING)
{
if (((i + 1) < Positions.Count) && (((PositionData)(Positions[i + 1])).Type == car_state_e.CAR_START))
{
if (((i + 2) < Positions.Count) && (((PositionData)(Positions[i + 2])).Type == car_state_e.CAR_RUNNING))
{
((PositionData)(Positions[i + 1])).Type = car_state_e.CAR_RUNNING;
}
}
}
}
}
catch (Exception ex)
{
SM.Debug("Error on CAR_STOP CAR_START CAR_STOP filter" + ex.ToString());
}
foreach (PositionData obj in Positions)
{
count++;
//if ((obj.type == car_state_e.CAR_STOP || obj.type == car_state_e.CAR_START) && (!first))
if ((obj.Type == car_state_e.CAR_STOP) && (!first))
{
//if ((obj.TimeGMT - zone1OUTtime) < (((Vehicle)MainForm2.vehicleHT[MainForm2.NameReport]).gps_interval * 4.1)) //300
//{
if (((obj.Lat > (startlat - delta)) && (obj.Lat < (startlat + delta))) && ((obj.Lng > (startlng - delta)) && (obj.Lng < (startlng + delta))))
{
for (int i = idxread; i < count; i++)
((PositionData)Positions[i]).Type = obj.Type;
}
//}
startlat = obj.Lat;
startlng = obj.Lng;
first = true;
}
//if ((obj.type == car_state_e.CAR_STOP || obj.type == car_state_e.CAR_START) && (first))
if ((obj.Type == car_state_e.CAR_STOP) && (first))
{
zone1OUTtime = obj.TimeGMT;
}
if ((obj.Type == car_state_e.CAR_RUNNING) && (first))
{
first = false;
idxread = count;
}
}
//test filtrat CAR_STOP CAR_START CAR_STOP AFTER
try
{
for (int i = 0; i < Positions.Count; i++)
{
if (((PositionData)(Positions[i])).Type == car_state_e.CAR_STOP)
{
if (((i + 1) < Positions.Count) && (((PositionData)(Positions[i + 1])).Type == car_state_e.CAR_START))
{
Int32 Step = i + 2;
car_state_e typeFind = car_state_e.CAR_START;
while ((Step < Positions.Count) && (typeFind == car_state_e.CAR_START))
{
if (((PositionData)(Positions[Step])).Type == car_state_e.CAR_RUNNING) typeFind = car_state_e.CAR_RUNNING;
else if (((PositionData)(Positions[Step])).Type == car_state_e.CAR_STOP) typeFind = car_state_e.CAR_STOP;
Step++;
}
if (typeFind == car_state_e.CAR_STOP)
{
for (int j = (i + 1); j < (Step - 1); j++)
((PositionData)(Positions[j])).Type = car_state_e.CAR_STOP;
}
}
}
}
}
catch (Exception ex)
{
SM.Debug("Error on CAR_STOP CAR_START CAR_STOP filter" + ex.Message);
}
}
public Stops Create_new_Stop(int StartCount, int StopCount, ArrayList Positions, Int32 EnterTime, Int32 ExitTime, car_state_e type)
{
ArrayList ListOfAddress = new ArrayList();
ArrayList ListLat = new ArrayList();
ArrayList ListLng = new ArrayList();
Double LatMed = 0;
Double LngMed = 0;
String Address = "";
for (int i = StartCount; i < StopCount; i++)
{
ListLat.Add(((PositionData)Positions[i]).Lat);
ListLng.Add(((PositionData)Positions[i]).Lng);
Address = ((PositionData)Positions[i]).Address;
}
for (int i = StartCount; i < StopCount; i++)
{
LatMed = LatMed + ((PositionData)Positions[i]).Lat;
LngMed = LngMed + ((PositionData)Positions[i]).Lng;
}
if ((StopCount - StartCount) > 1)
{
LatMed = LatMed / (StopCount - StartCount);
LngMed = LngMed / (StopCount - StartCount);
}
Stops stop = new Stops();
StaticMembers.AddrCnt++;
stop.name = StaticMembers.AddrCnt.ToString();
stop.start = EnterTime;
stop.stop = ExitTime;
stop.lat = LatMed;
stop.lng = LngMed;
stop.type = type;
stop.address = Address;
return stop;
}
public void create_stop_list()
{
Boolean valBool = false;
Boolean NotInsertStop = false;
entertime = 0;
exittime = 0;
count = -1;
startcount = 0;
StopsList.Clear();
car_state_e type = car_state_e.CAR_RUNNING;
car_state_e addtype = car_state_e.CAR_RUNNING;
try
{
foreach (PositionData obj in Positions)
{
count++;
if (obj.Type != car_state_e.CAR_RUNNING)
{
if (obj.Type != type)
{
if (valBool == true)
{ // if 2 different states one after another (ex: stop, start, r, r, .. )
if (addtype == car_state_e.CAR_STOP)
{
StopsList.Add(Create_new_Stop(startcount, count, Positions, entertime, exittime, addtype));
NotInsertStop = false;
}
else
NotInsertStop = true;
entertime = obj.TimeGMT;
startcount = count;
addtype = obj.Type;
}
else
valBool = true;
}
valBool = true;
}
else valBool = false;
type = obj.Type;
if (valBool)
{
if (entertime == 0)
{
entertime = obj.TimeGMT;
startcount = count;
addtype = obj.Type;
}
}
else
{
if (entertime != 0)
{
if (!NotInsertStop)
{
StopsList.Add(Create_new_Stop(startcount, count, Positions, entertime, exittime, addtype));
entertime = 0;
}
}
if (obj.Type == car_state_e.CAR_RUNNING)
{
exittime = 0;
NotInsertStop = false;
}
}
exittime = obj.TimeGMT;
}
// enter the last zone
if (entertime != 0)
{
StopsList.Add(Create_new_Stop(startcount, count + 1, Positions, entertime, exittime, addtype));
}
delta = StaticMembers.Delta1 * 0.00001;
foreach (Stops obj in StopsList)
{
int cont = -1;
foreach (PositionData obj2 in Positions)
{ cont++; if (obj2.TimeGMT == obj.start) break; }
int step = cont;
Boolean stay = true;
while ((step > 0) && (stay))
{
step--;
if ((((((PositionData)Positions[step]).Lat < (obj.lat + delta)) && (((PositionData)Positions[step]).Lat > (obj.lat - delta)))
&& ((((PositionData)Positions[step]).Lng < (obj.lng + delta)) && (((PositionData)Positions[step]).Lng > (obj.lng - delta)))) && (((PositionData)Positions[step]).Type == car_state_e.CAR_RUNNING))
{
obj.start = ((PositionData)Positions[step]).TimeGMT;
((PositionData)Positions[step]).Type = car_state_e.CAR_START;
}
else stay = false;
}
cont = -1;
foreach (PositionData obj2 in Positions)
{ cont++; if (obj2.TimeGMT == obj.stop) break; }
step = cont;
stay = true;
while ((step < (Positions.Count - 1)) && (stay))
{
step++;
if ((((((PositionData)Positions[step]).Lat < (obj.lat + delta)) && (((PositionData)Positions[step]).Lat > (obj.lat - delta)))
&& ((((PositionData)Positions[step]).Lng < (obj.lng + delta)) && (((PositionData)Positions[step]).Lng > (obj.lng - delta)))) && (((PositionData)Positions[step]).Type == car_state_e.CAR_RUNNING))
{
obj.stop = ((PositionData)Positions[step]).TimeGMT;
((PositionData)Positions[step]).Type = car_state_e.CAR_STOP;
}
else stay = false;
}
}
}
catch (Exception ex)
{
throw new ArgumentException("Error on create StopList:" + ex.ToString());
}
}
public ArrayList create_stop_list_EON(Int32 IdleTime)
{
entertime = 0;
exittime = 0;
count = -1;
startcount = -1;
Double latmed = 0;
Double lngmed = 0;
//uint limittime = 120; // un minut jumatate
long limittime = 30; // jumate un minut jumatate
long oldtime = 0;
Int32 intDiff = 0;
Double stepdist = 0.00030;
StopsList.Clear();
car_state_e addtype = car_state_e.CAR_STOP;
try
{
//smdbObj = new SMdb_access(MainForm2.mssqlbool);
// smdbObj.InitConnection(m_server, m_dbname, m_user, m_password);
//caluculate time between to message for a good detection of idle
ArrayList TmpTime = new ArrayList();
Boolean first = false;
foreach (PositionData obj in Positions)
{
if (!first) first = true;
else
{
intDiff = (Int32)(obj.TimeGMT - oldtime);
Boolean findloc = false;
foreach (Time_And_Type obj2 in TmpTime)
{
if (((obj2.timeGMT * 0.9) <= intDiff) && ((obj2.timeGMT * 1.1) >= intDiff))
{
findloc = true;
obj2.type++;
break;
}
}
if (!findloc)
{
Time_And_Type tmp = new Time_And_Type();
tmp.timeGMT = intDiff;
tmp.type = 1;
TmpTime.Add(tmp);
}
}
oldtime = obj.TimeGMT;
}
int max = 0;
foreach (Time_And_Type obj in TmpTime)
{
if (obj.type > max) { limittime = obj.timeGMT; max = obj.type; }
}
foreach (PositionData obj in Positions)
{
count++; // astept 3.2
//if (((obj.timeGMT - exittime) < (limittime*3.2)) && (Math.Abs(obj.lat - latmed) < stepdist) && (Math.Abs(obj.lng - lngmed) < stepdist))
//if (((obj.timeGMT - exittime) < (limittime * 2.5)) && (obj.speed < 5))
if (((obj.TimeGMT - exittime) < (limittime * 2.5)) && (obj.Speed < 5) && (Math.Abs(obj.Lat - latmed) < stepdist) && (Math.Abs(obj.Lng - lngmed) < stepdist))
{
if (startcount == -1)
{
startcount = count - 1;
entertime = exittime;
}
latmed = Math.Min(obj.Lat, latmed) + Math.Abs(obj.Lat - latmed);
lngmed = Math.Min(obj.Lng, lngmed) + Math.Abs(obj.Lng - lngmed);
}
else
{
if (startcount != -1)
if ((exittime - entertime) >= (IdleTime * 60)) //was count+1
StopsList.Add(Create_new_Stop(startcount, count, Positions, entertime, exittime, addtype));
startcount = -1;
entertime = obj.TimeGMT;
latmed = obj.Lat;
lngmed = obj.Lng;
}
exittime = obj.TimeGMT;
} // end foreach
// enter the last zone
if (startcount != -1)
if ((exittime - entertime) >= (IdleTime * 60))
StopsList.Add(Create_new_Stop(startcount, count + 1, Positions, entertime, exittime, addtype));
}
catch (Exception ex)
{
throw new ArgumentException("Error on creta EON:" + ex.ToString());
}
return StopsList;
}
public void StartStopCalc()
{
IndexRemove.Clear();
int contStop = -1;
String lastAddr = "";
IndexCut tmpCut;
foreach (Stops obj in StopsList)
{
contStop++;
if (obj.type != car_state_e.CAR_START && (obj.name != null) && obj.name.CompareTo(lastAddr) == 0)
{ // delete the stop with the same address (stop address == final stop address)
tmpCut = new IndexCut();
tmpCut.IndCut = contStop;
tmpCut.LastTime = obj.stop;
IndexRemove.Add(tmpCut);
}
lastAddr = obj.name;
}
int countUndo = -1;
foreach (IndexCut obj in IndexRemove)
{
countUndo++;
((Stops)(StopsList[obj.IndCut - countUndo - 1])).stop = obj.LastTime;
StopsList.RemoveAt(obj.IndCut - countUndo);
}
}
public void StartStopCalcPosition()
{
count = -1;
Int32 countChange = -1;
Int32 countToRemove = -1;
Boolean BeginRemove = false;
car_state_e oldType = car_state_e.CAR_STOP;
if (Positions.Count != 0) oldType = ((PositionData)Positions[0]).Type;
if (oldType == car_state_e.CAR_STOP) countToRemove = 0;
foreach (PositionData obj in Positions)
{
count++;
if (oldType != obj.Type)
{
oldType = obj.Type;
if (obj.Type == car_state_e.CAR_STOP)
{
countToRemove++;
BeginRemove = false;
foreach (IndexCut obj2 in IndexRemove)
if (obj2.IndCut == countToRemove) BeginRemove = true;
oldType = car_state_e.CAR_STOP;
if (BeginRemove)
{
for (int i = countChange; i < count; i++)
((PositionData)Positions[i]).Type = car_state_e.CAR_STOP;
}
}
countChange = count;
}
}
}
}
public class Time_And_Type
{
public long timeGMT;
public Int32 type;
}
}