private static int GetMaxTripId(InsertConfig.GpsCorrection correction)
        {
            int tripid = -1;

            if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
            {
                tripid = TripsSpeedLPF005MMDao.GetMaxTripId() + 1;
            }
            else if (correction == InsertConfig.GpsCorrection.MapMatching)
            {
                tripid = TripsMMDao.GetMaxTripId() + 1;
            }
            else if (correction == InsertConfig.GpsCorrection.Normal)
            {
                tripid = TripsDao.GetMaxTripId() + 1;
            }
            else if (correction == InsertConfig.GpsCorrection.DopplerSpeed)
            {
                tripid = TripsDopplerDao.GetMaxTripId() + 1;
            }
            else if (correction == InsertConfig.GpsCorrection.DopplerNotMM)
            {
                tripid = TripsDopplerNotMMDao.GetMaxTripId() + 1;
            }
            return(tripid);
        }
        public static void InsertEcolog(InsertDatum datum, MainWindowViewModel.UpdateTextDelegate updateTextDelegate, InsertConfig.GpsCorrection correction, out int count)
        {
            count = 0;
            var tripsTable = TripsDao.Get(datum);
            //int i = 1;

            //foreach (DataRow row in tripsTable.Rows)
            //{
            //    updateTextDelegate($"Insetring ECOLOG ... , {i} / {tripsTable.Rows.Count}");
            //    LogWritter.WriteLog(LogWritter.LogMode.Ecolog, $"Insetring ECOLOG... , { i} / { tripsTable.Rows.Count}, Datum: {datum}");
            //    var ecologTable = HagimotoEcologCalculator.CalcEcolog(row, datum, correction);
            //    EcologDao.Insert(ecologTable);

            //    i++;
            //}
            int t = 0;

            Parallel.For(0, tripsTable.Rows.Count, i =>
            {
                if (tripsTable.Rows[i][(TripsDao.ColumnConsumedEnergy)] == DBNull.Value)
                {
                    updateTextDelegate($"Insetring ECOLOG ... , {i + 1} / {tripsTable.Rows.Count}");
                    LogWritter.WriteLog(LogWritter.LogMode.Ecolog, $"Insetring ECOLOG... , { i} / { tripsTable.Rows.Count}, Datum: {datum}");
                    var ecologTable = HagimotoEcologCalculator.CalcEcolog(tripsTable.Rows[i], datum, correction);
                    EcologDao.Insert(ecologTable);
                    t++;
                }
            });
            count = t;
            TripsDao.UpdateConsumedEnergy();
        }
示例#3
0
        public static void InsertCorrectedGps(InsertDatum datum, InsertConfig.GpsCorrection correction)
        {
            var tripsTable = TripsDao.Get(datum);

            foreach (DataRow tripsRow in tripsTable.Rows)
            {
                DataTable gpsRawTable =
                    AndroidGpsRawDao.Get(tripsRow.Field <DateTime>(TripsDao.ColumnStartTime),
                                         tripsRow.Field <DateTime>(TripsDao.ColumnEndTime), datum);
                if (gpsRawTable.Rows.Count == 0)
                {
                    return;
                }
                DataTable correctedGpsTable = DataTableUtil.GetCorrectedGpsTable();

                #region インデックスが 0 の場合
                DataRow firstRow = correctedGpsTable.NewRow();
                CopyRawDataToCorrectedRow(firstRow, gpsRawTable.Rows[0]);
                firstRow.SetField(CorrectedGpsDao.ColumnDistanceDifference, 0);
                //firstRow.SetField(CorrectedGpsDao.ColumnSpeed, 0);
                firstRow.SetField(CorrectedGpsDao.ColumnHeading, 0);
                var meshAndAltitude = AltitudeCalculator.GetInstance().CalcAltitude(
                    gpsRawTable.Rows[0].Field <double>(CorrectedGpsDao.ColumnLatitude),
                    gpsRawTable.Rows[0].Field <double>(CorrectedGpsDao.ColumnLongitude));

                firstRow.SetField(CorrectedGpsDao.ColumnTerrainAltitude, meshAndAltitude.Item2);



                var linkAndTheta = LinkMatcher.GetInstance().MatchLink(
                    firstRow.Field <double>(CorrectedGpsDao.ColumnLatitude),
                    firstRow.Field <double>(CorrectedGpsDao.ColumnLongitude),
                    0f, tripsRow.Field <string>(TripsDao.ColumnTripDirection), datum);

                firstRow.SetField(CorrectedGpsDao.ColumnLinkId, linkAndTheta.Item1);
                firstRow.SetField(CorrectedGpsDao.ColumnRoadTheta, linkAndTheta.Item2);

                correctedGpsTable.Rows.Add(firstRow);
                #endregion

                for (int i = 1; i < gpsRawTable.Rows.Count - 1; i++)
                {
                    DataRow row = correctedGpsTable.NewRow();

                    CopyRawDataToCorrectedRow(row, gpsRawTable.Rows[i]);

                    // 距離の算出
                    row.SetField(CorrectedGpsDao.ColumnDistanceDifference, DistanceCalculator.CalcDistance(
                                     gpsRawTable.Rows[i - 1].Field <double>(AndroidGpsRawDao.ColumnLatitude),
                                     gpsRawTable.Rows[i - 1].Field <double>(AndroidGpsRawDao.ColumnLongitude),
                                     gpsRawTable.Rows[i].Field <double>(AndroidGpsRawDao.ColumnLatitude),
                                     gpsRawTable.Rows[i].Field <double>(AndroidGpsRawDao.ColumnLongitude)));

                    meshAndAltitude = AltitudeCalculator.GetInstance().CalcAltitude(
                        gpsRawTable.Rows[i].Field <double>(CorrectedGpsDao.ColumnLatitude),
                        gpsRawTable.Rows[i].Field <double>(CorrectedGpsDao.ColumnLongitude));

                    row.SetField(CorrectedGpsDao.ColumnTerrainAltitude, meshAndAltitude.Item2);



                    // 速度の算出
                    //row.SetField(CorrectedGpsDao.ColumnSpeed, SpeedCalculator.CalcSpeed(
                    //    gpsRawTable.Rows[i - 1].Field<double>(AndroidGpsRawDao.ColumnLatitude),
                    //    gpsRawTable.Rows[i - 1].Field<double>(AndroidGpsRawDao.ColumnLongitude),
                    //    gpsRawTable.Rows[i - 1].Field<DateTime>(AndroidGpsRawDao.ColumnJst),
                    //    gpsRawTable.Rows[i + 1].Field<double>(AndroidGpsRawDao.ColumnLatitude),
                    //    gpsRawTable.Rows[i + 1].Field<double>(AndroidGpsRawDao.ColumnLongitude),
                    //    gpsRawTable.Rows[i + 1].Field<DateTime>(AndroidGpsRawDao.ColumnJst),
                    //    gpsRawTable.Rows[i].Field<double>(AndroidGpsRawDao.ColumnLatitude),
                    //    gpsRawTable.Rows[i].Field<double>(AndroidGpsRawDao.ColumnLongitude)));

                    //速度が1km以上になったらHEADINGを更新する(停止時に1つ1つ計算するとHEADINDが暴れるため)
                    if (row.Field <Single?>(CorrectedGpsDao.ColumnSpeed) > 1.0)
                    {
                        row.SetField(CorrectedGpsDao.ColumnHeading, HeadingCalculator.CalcHeading(
                                         gpsRawTable.Rows[i - 1].Field <double>(AndroidGpsRawDao.ColumnLatitude),
                                         gpsRawTable.Rows[i - 1].Field <double>(AndroidGpsRawDao.ColumnLongitude),
                                         gpsRawTable.Rows[i].Field <double>(AndroidGpsRawDao.ColumnLatitude),
                                         gpsRawTable.Rows[i].Field <double>(AndroidGpsRawDao.ColumnLongitude)));
                    }
                    else
                    {
                        row.SetField(CorrectedGpsDao.ColumnHeading, correctedGpsTable.Rows[i - 1].Field <double>(CorrectedGpsDao.ColumnHeading));
                    }

                    linkAndTheta = LinkMatcher.GetInstance().MatchLink(
                        row.Field <double>(CorrectedGpsDao.ColumnLatitude),
                        row.Field <double>(CorrectedGpsDao.ColumnLongitude),
                        Convert.ToSingle(row.Field <double>(CorrectedGpsDao.ColumnHeading))
                        , tripsRow.Field <string>(TripsDao.ColumnTripDirection), datum
                        );

                    row.SetField(CorrectedGpsDao.ColumnLinkId, linkAndTheta.Item1);
                    row.SetField(CorrectedGpsDao.ColumnRoadTheta, linkAndTheta.Item2);
                    correctedGpsTable.Rows.Add(row);
                }

                #region インデックスが最後の場合
                DataRow lastRow = correctedGpsTable.NewRow();
                CopyRawDataToCorrectedRow(lastRow, gpsRawTable.Rows[gpsRawTable.Rows.Count - 1]);
                lastRow.SetField(CorrectedGpsDao.ColumnDistanceDifference, 0);
                lastRow.SetField(CorrectedGpsDao.ColumnSpeed, 0);
                lastRow.SetField(CorrectedGpsDao.ColumnHeading, 0);

                meshAndAltitude = AltitudeCalculator.GetInstance().CalcAltitude(
                    gpsRawTable.Rows[gpsRawTable.Rows.Count - 1].Field <double>(CorrectedGpsDao.ColumnLatitude),
                    gpsRawTable.Rows[gpsRawTable.Rows.Count - 1].Field <double>(CorrectedGpsDao.ColumnLongitude));

                lastRow.SetField(CorrectedGpsDao.ColumnTerrainAltitude, meshAndAltitude.Item2);



                linkAndTheta = LinkMatcher.GetInstance().MatchLink(
                    firstRow.Field <double>(CorrectedGpsDao.ColumnLatitude),
                    firstRow.Field <double>(CorrectedGpsDao.ColumnLongitude),
                    0f, tripsRow.Field <string>(TripsDao.ColumnTripDirection), datum);

                lastRow.SetField(CorrectedGpsDao.ColumnLinkId, linkAndTheta.Item1);
                lastRow.SetField(CorrectedGpsDao.ColumnRoadTheta, linkAndTheta.Item2);

                correctedGpsTable.Rows.Add(lastRow);

                #endregion

                // ファイルごとの挿入なので主キー違反があっても挿入されないだけ
                if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)//速度にローパスフィルタを適用
                {
                    DataTable correctedGpsSpeedLPFTable = LowPassFilter.speedLowPassFilter(correctedGpsTable, 0.05);
                    CorrectedGpsSpeedLPF005MMDao.Insert(correctedGpsSpeedLPFTable);
                }
                else if (correction == InsertConfig.GpsCorrection.MapMatching)
                {
                    CorrectedGPSMMDao.Insert(correctedGpsTable);
                }
                else
                {
                    CorrectedGpsDao.Insert(correctedGpsTable);
                }
            }
        }
        public static void InsertTrip(InsertDatum datum, InsertConfig.GpsCorrection correction, bool isCheckedSightseeingInsert)
        {
            LogWritter.WriteLog(LogWritter.LogMode.Trip, $"TRIP挿入開始, DRIVER_ID: {datum.DriverId}, CAR_ID: {datum.CarId}, SENSOR_ID: {datum.SensorId}");
            var tripsRawTable = new DataTable();

            if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
            {
                tripsRawTable = TripsRawSpeedLPF005MMDao.Get(datum);
                TripsSpeedLPF005MMDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else if (correction == InsertConfig.GpsCorrection.MapMatching)
            {
                tripsRawTable = TripsRawMMDao.Get(datum);
                TripsMMDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else if (correction == InsertConfig.GpsCorrection.Normal)
            {
                tripsRawTable = TripsRawDao.Get(datum);
                TripsDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else if (correction == InsertConfig.GpsCorrection.DopplerSpeed)
            {
                tripsRawTable = TripsRawDopplerDao.Get(datum);
                TripsDopplerDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else if (correction == InsertConfig.GpsCorrection.DopplerNotMM)
            {
                tripsRawTable = TripsRawDopplerNotMMDao.Get(datum);
                TripsDopplerNotMMDao.DeleteTrips();
            }


            LogWritter.WriteLog(LogWritter.LogMode.Trip, $"挿入対象のRAWデータ: {tripsRawTable.Rows.Count}");


            for (int i = 0; i < tripsRawTable.Rows.Count; i++)
            {
                DataTable tripsTable = DataTableUtil.GetTripsTable();


                // 観光オプションによるインサート処理はあらかじめ切り分ける。
                if (isCheckedSightseeingInsert)
                {
                    InsertSightSeeingTrip(tripsRawTable, tripsTable, datum, i, correction);
                }

                // 自宅出発
                else if (IsHome(tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude),
                                tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude),
                                tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime),
                                datum))
                {
                    InsertOutwardTrip(tripsRawTable, tripsTable, datum, i, correction);
                }
                // YNU出発
                else if (IsYnu(tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude),
                               tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude)))
                {
                    InsertHomewardTrip(tripsRawTable, tripsTable, datum, i, correction);
                }

                // 1トリップごとなので主キー違反があっても挿入されないだけ
                if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
                {
                    TripsSpeedLPF005MMDao.Insert(tripsTable);
                }
                else if (correction == InsertConfig.GpsCorrection.MapMatching)
                {
                    TripsMMDao.Insert(tripsTable);
                }
                else if (correction == InsertConfig.GpsCorrection.Normal)
                {
                    TripsDao.Insert(tripsTable);
                }
                else if (correction == InsertConfig.GpsCorrection.DopplerSpeed)
                {
                    if (tripsTable.Rows.Count != 0)
                    {
                        var gpsCorrectedTable = CorrectedGPSDopplerDao.GetNormalized(
                            tripsTable.Rows[0].Field <DateTime>(TripsDopplerDao.ColumnStartTime),
                            tripsTable.Rows[0].Field <DateTime>(TripsDopplerDao.ColumnEndTime),
                            datum);
                        if (gpsCorrectedTable.Rows.Count != 0)
                        {
                            TripsDopplerDao.Insert(tripsTable);
                        }
                    }
                }
                else if (correction == InsertConfig.GpsCorrection.DopplerNotMM)
                {
                    if (tripsTable.Rows.Count != 0)
                    {
                        var gpsCorrectedTable = CorrectedGpsDopplerNotMMDao.GetNormalized(
                            tripsTable.Rows[0].Field <DateTime>(TripsDopplerDao.ColumnStartTime),
                            tripsTable.Rows[0].Field <DateTime>(TripsDopplerDao.ColumnEndTime),
                            datum);
                        if (gpsCorrectedTable.Rows.Count != 0)
                        {
                            TripsDopplerNotMMDao.Insert(tripsTable);
                        }
                    }
                }
            }
        }
        /*
         *  InsertSightSeeingTrip()
         *  観光用トリップを挿入するためのメソッド
         *  YNU出発と観光地出発の2種類があることに注意が必要になる。
         */
        private static void InsertSightSeeingTrip(DataTable tripsRawTable, DataTable tripsTable, InsertDatum datum, int startIndex, InsertConfig.GpsCorrection correction)
        {
            // InsertHomewardTripと同じような処理を記述
            // tripのスタートのtripsRawのインデックスをstartIndex
            // 現在注目しているtripsRawのインデックスをcurrentIndex
            int currentIndex = startIndex;

            // tripChangeFlagはループを抜けるためのフラグ
            // このフラグが立つと、異なるトリップに到達したことを示す
            bool tripChangeFlag = false;

            // TripsRawを結合してTripsを生成する。
            while (currentIndex < tripsRawTable.Rows.Count && tripChangeFlag == false)
            {
                // スタートがynuか観光地 かつ ゴールがynuか観光地
                // でもynuからynuのトリップは考えない

                // スタート,ゴールがynuであるか
                bool isStartYnu = IsYnu(tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLatitude),
                                        tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLongitude));
                bool isEndYnu = IsYnu(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLatitude),
                                      tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLongitude));
                // スタートゴールが観光地であるか
                bool isStartSightseeingSpot = IsSightseeing(tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLatitude),
                                                            tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLongitude));
                bool isEndSightseeingSpot = IsSightseeing(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLatitude),
                                                          tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLongitude));
                // スタートゴールが自宅であるか
                bool isStartHome = IsHome(tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLatitude),
                                          tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLongitude),
                                          tripsRawTable.Rows[startIndex].Field <DateTime>(TripsRawDao.ColumnStartTime),
                                          datum);
                bool isEndHome = IsHome(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLatitude),
                                        tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLongitude),
                                        tripsRawTable.Rows[currentIndex].Field <DateTime>(TripsRawDao.ColumnEndTime),
                                        datum);

                // YNU  to YNUは排除
                if (isStartYnu && isEndYnu)
                {
                    LogWritter.WriteLog(LogWritter.LogMode.Trip, "YNU⇒YNUトリップなので挿入しません。"
                                        + ConvertRowToString(tripsRawTable.Rows[startIndex],
                                                             tripsRawTable.Rows[currentIndex]));
                    tripChangeFlag = true;
                }
                // 自宅 to 自宅 も排除
                else if (isStartHome && isEndHome)
                {
                    LogWritter.WriteLog(LogWritter.LogMode.Trip, "Home⇒Homeトリップなので挿入しません。"
                                        + ConvertRowToString(tripsRawTable.Rows[startIndex],
                                                             tripsRawTable.Rows[currentIndex]));
                    tripChangeFlag = true;
                }
                // 候補地 to 候補地のトリップを挿入
                else if ((isStartYnu || isStartSightseeingSpot || isStartHome) &&
                         (isEndYnu || isEndSightseeingSpot || isEndHome))
                {
                    var row = tripsTable.NewRow();
                    row.SetField(TripsDao.ColumnTripId, GetMaxTripId(correction));
                    row.SetField(TripsDao.ColumnDriverId, tripsRawTable.Rows[startIndex].Field <int>(TripsRawDao.ColumnDriverId));
                    row.SetField(TripsDao.ColumnCarId, tripsRawTable.Rows[startIndex].Field <int>(TripsRawDao.ColumnCarId));
                    row.SetField(TripsDao.ColumnSensorId, tripsRawTable.Rows[startIndex].Field <int>(TripsRawDao.ColumnSensorId));
                    row.SetField(TripsDao.ColumnStartTime, tripsRawTable.Rows[startIndex].Field <DateTime>(TripsRawDao.ColumnStartTime));
                    row.SetField(TripsDao.ColumnEndTime, tripsRawTable.Rows[currentIndex].Field <DateTime>(TripsRawDao.ColumnEndTime));
                    row.SetField(TripsDao.ColumnStartLatitude, tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLatitude));
                    row.SetField(TripsDao.ColumnStartLongitude, tripsRawTable.Rows[startIndex].Field <double>(TripsRawDao.ColumnStartLongitude));
                    row.SetField(TripsDao.ColumnEndLatitude, tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLatitude));
                    row.SetField(TripsDao.ColumnEndLongitude, tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnEndLongitude));
                    row.SetField(TripsDao.ColumnTripDirection, "tourism");

                    TimeSpan span = tripsRawTable.Rows[currentIndex].Field <DateTime>(TripsRawDao.ColumnEndTime)
                                    - tripsRawTable.Rows[startIndex].Field <DateTime>(TripsRawDao.ColumnStartTime);

                    if (span.TotalHours > 12)
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "別々のトリップを結合する可能性があるので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[startIndex],
                                                                 tripsRawTable.Rows[currentIndex]));
                        break;
                    }

                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching &&
                        !TripsSpeedLPF005MMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching &&
                             !TripsMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.Normal &&
                             !TripsDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.DopplerSpeed &&
                             !TripsDopplerDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.DopplerNotMM && !TripsDopplerNotMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "既にこのトリップは挿入されているので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[startIndex],
                                                                 tripsRawTable.Rows[currentIndex]));
                    }

                    tripChangeFlag = true;
                }

                currentIndex++;
                if (currentIndex == tripsRawTable.Rows.Count || tripChangeFlag)
                {
                    break;
                }

                // YNUにも観光地にも自宅にも到着しないまま、開始地点がYNUか観光地か自宅になった場合
                if (IsYnu(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLatitude),
                          tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLongitude)) ||
                    IsSightseeing(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLongitude),
                                  tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLongitude)) ||
                    IsHome(tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLatitude),
                           tripsRawTable.Rows[currentIndex].Field <double>(TripsRawDao.ColumnStartLongitude),
                           tripsRawTable.Rows[currentIndex].Field <DateTime>(TripsRawDao.ColumnStartTime),
                           datum)
                    )
                {
                    tripChangeFlag = true;
                    LogWritter.WriteLog(LogWritter.LogMode.Trip, "YNUor自宅or観光地⇒?トリップなので挿入しません "
                                        + ConvertRowToString(tripsRawTable.Rows[startIndex], tripsRawTable.Rows[currentIndex]));
                }
            }
        }
        private static void InsertHomewardTrip(DataTable tripsRawTable, DataTable tripsTable, InsertDatum datum, int i, InsertConfig.GpsCorrection correction)
        {
            int  j = i;
            bool tripChangeFlag = false;

            // TripsRaw を結合して Trips を生成するループ
            while (j < tripsRawTable.Rows.Count && tripChangeFlag == false)
            {
                // YNU ⇒ 自宅
                if (IsHome(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude),
                           tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude),
                           tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime),
                           datum))
                {
                    var row = tripsTable.NewRow();
                    row.SetField(TripsDao.ColumnTripId, GetMaxTripId(correction));
                    row.SetField(TripsDao.ColumnDriverId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnDriverId));
                    row.SetField(TripsDao.ColumnCarId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnCarId));
                    row.SetField(TripsDao.ColumnSensorId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnSensorId));
                    row.SetField(TripsDao.ColumnStartTime, tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime));
                    row.SetField(TripsDao.ColumnEndTime, tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime));
                    row.SetField(TripsDao.ColumnStartLatitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude));
                    row.SetField(TripsDao.ColumnStartLongitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude));
                    row.SetField(TripsDao.ColumnEndLatitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude));
                    row.SetField(TripsDao.ColumnEndLongitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude));
                    row.SetField(TripsDao.ColumnTripDirection, "homeward");

                    TimeSpan span = tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime)
                                    - tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime);

                    if (span.TotalHours > 12)
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "別々のトリップを結合する可能性があるので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                        break;
                    }

                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching && !TripsSpeedLPF005MMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching && !TripsMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.Normal && !TripsDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.DopplerSpeed && !TripsDopplerDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.DopplerNotMM && !TripsDopplerNotMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "既にこのトリップは挿入されているので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                    }

                    tripChangeFlag = true;
                }

                // YNU ⇒ YNU
                else if (IsYnu(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude),
                               tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude)))
                {
                    LogWritter.WriteLog(LogWritter.LogMode.Trip, "YNU⇒YNUトリップなので挿入しません "
                                        + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));

                    // Trip の挿入は行わない
                    // ループの初期化
                    tripChangeFlag = true;
                }

                j++;

                // YNU ⇒ ?
                if (j < tripsRawTable.Rows.Count && tripChangeFlag != true)
                {
                    // 自宅にも、学校にも到着しないまま、開始地点が自宅か学校になった場合
                    if (IsHome(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnStartLatitude),
                               tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnStartLongitude),
                               tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnStartTime), datum) ||
                        IsYnu(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnStartLatitude), tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnStartLongitude)))
                    {
                        tripChangeFlag = true;
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "YNU⇒?トリップなので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                    }
                }
            }
        }
        //TRIP_DIRECTION = 'other' のインサート
        private static void InsertOtherTrip(DataTable tripsRawTable, DataTable tripsTable, InsertDatum datum, int i, InsertConfig.GpsCorrection correction)
        {
            int  j = i;
            bool tripChangeFlag = false;

            // TripsRaw を結合して Trips を生成するループ
            while (j < tripsRawTable.Rows.Count && tripChangeFlag == false)
            {
                // その他登録地点 ⇒ その他登録地点
                if (IsOther(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude), tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude)))
                {
                    var row = tripsTable.NewRow();
                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsSpeedLPF005MMDao.GetMaxTripId() + 1);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsMMDao.GetMaxTripId() + 1);
                    }
                    else
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsDao.GetMaxTripId() + 1);
                    }
                    row.SetField(TripsDao.ColumnDriverId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnDriverId));
                    row.SetField(TripsDao.ColumnCarId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnCarId));
                    row.SetField(TripsDao.ColumnSensorId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnSensorId));
                    row.SetField(TripsDao.ColumnStartTime, tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime));
                    row.SetField(TripsDao.ColumnEndTime, tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime));
                    row.SetField(TripsDao.ColumnStartLatitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude));
                    row.SetField(TripsDao.ColumnStartLongitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude));
                    row.SetField(TripsDao.ColumnEndLatitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude));
                    row.SetField(TripsDao.ColumnEndLongitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude));
                    row.SetField(TripsDao.ColumnTripDirection, "other");

                    TimeSpan span = tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime)
                                    - tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime);

                    if (span.TotalHours > 12)
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "別々のトリップを結合する可能性があるので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                        break;
                    }

                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching && !TripsSpeedLPF005MMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching && !TripsMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.Normal && !TripsDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "既にこのトリップは挿入されているので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                    }

                    tripChangeFlag = true;
                }


                // その他登録地点 ⇒ YNU
                if (IsYnu(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude), tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude)))
                {
                    var row = tripsTable.NewRow();
                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsSpeedLPF005MMDao.GetMaxTripId() + 1);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsMMDao.GetMaxTripId() + 1);
                    }
                    else
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsDao.GetMaxTripId() + 1);
                    }
                    row.SetField(TripsDao.ColumnDriverId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnDriverId));
                    row.SetField(TripsDao.ColumnCarId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnCarId));
                    row.SetField(TripsDao.ColumnSensorId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnSensorId));
                    row.SetField(TripsDao.ColumnStartTime, tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime));
                    row.SetField(TripsDao.ColumnEndTime, tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime));
                    row.SetField(TripsDao.ColumnStartLatitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude));
                    row.SetField(TripsDao.ColumnStartLongitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude));
                    row.SetField(TripsDao.ColumnEndLatitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude));
                    row.SetField(TripsDao.ColumnEndLongitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude));
                    row.SetField(TripsDao.ColumnTripDirection, "other");

                    TimeSpan span = tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime)
                                    - tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime);

                    if (span.TotalHours > 12)
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "別々のトリップを結合する可能性があるので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                        break;
                    }

                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching && !TripsSpeedLPF005MMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching && !TripsMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.Normal && !TripsDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "既にこのトリップは挿入されているので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                    }

                    tripChangeFlag = true;
                }

                //その他登録地点 ⇒ 自宅
                else if (IsHome(tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude),
                                tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude),
                                tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime),
                                datum))
                {
                    var row = tripsTable.NewRow();
                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsSpeedLPF005MMDao.GetMaxTripId() + 1);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching)
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsMMDao.GetMaxTripId() + 1);
                    }
                    else
                    {
                        row.SetField(TripsDao.ColumnTripId, TripsDao.GetMaxTripId() + 1);
                    }
                    row.SetField(TripsDao.ColumnDriverId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnDriverId));
                    row.SetField(TripsDao.ColumnCarId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnCarId));
                    row.SetField(TripsDao.ColumnSensorId, tripsRawTable.Rows[i].Field <int>(TripsRawDao.ColumnSensorId));
                    row.SetField(TripsDao.ColumnStartTime, tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime));
                    row.SetField(TripsDao.ColumnEndTime, tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime));
                    row.SetField(TripsDao.ColumnStartLatitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude));
                    row.SetField(TripsDao.ColumnStartLongitude, tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude));
                    row.SetField(TripsDao.ColumnEndLatitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLatitude));
                    row.SetField(TripsDao.ColumnEndLongitude, tripsRawTable.Rows[j].Field <double>(TripsRawDao.ColumnEndLongitude));
                    row.SetField(TripsDao.ColumnTripDirection, "other");

                    TimeSpan span = tripsRawTable.Rows[j].Field <DateTime>(TripsRawDao.ColumnEndTime)
                                    - tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime);

                    if (span.TotalHours > 12)
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "別々のトリップを結合する可能性があるので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                        break;
                    }

                    if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching && !TripsSpeedLPF005MMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.MapMatching && !TripsMMDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else if (correction == InsertConfig.GpsCorrection.Normal && !TripsDao.IsExsistsTrip(row))
                    {
                        tripsTable.Rows.Add(row);
                    }
                    else
                    {
                        LogWritter.WriteLog(LogWritter.LogMode.Trip, "既にこのトリップは挿入されているので挿入しません "
                                            + ConvertRowToString(tripsRawTable.Rows[i], tripsRawTable.Rows[j]));
                    }

                    tripChangeFlag = true;
                }


                j++;
            }
        }
        public static void InsertTrip(InsertDatum datum, InsertConfig.GpsCorrection correction)
        {
            LogWritter.WriteLog(LogWritter.LogMode.Trip, $"TRIP挿入開始, DRIVER_ID: {datum.DriverId}, CAR_ID: {datum.CarId}, SENSOR_ID: {datum.SensorId}");
            var tripsRawTable = new DataTable();

            if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
            {
                tripsRawTable = TripsRawSpeedLPF005MMDao.Get(datum);
                TripsSpeedLPF005MMDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else if (correction == InsertConfig.GpsCorrection.MapMatching)
            {
                tripsRawTable = TripsRawMMDao.Get(datum);
                TripsMMDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }
            else
            {
                tripsRawTable = TripsRawDao.Get(datum);
                TripsDao.DeleteTrips(); //途中中断された際に作成したトリップを削除
            }


            LogWritter.WriteLog(LogWritter.LogMode.Trip, $"挿入対象のRAWデータ: {tripsRawTable.Rows.Count}");


            for (int i = 0; i < tripsRawTable.Rows.Count; i++)
            {
                DataTable tripsTable = DataTableUtil.GetTripsTable();

                // 自宅出発
                if (IsHome(tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude),
                           tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude),
                           tripsRawTable.Rows[i].Field <DateTime>(TripsRawDao.ColumnStartTime),
                           datum))
                {
                    InsertOutwardTrip(tripsRawTable, tripsTable, datum, i, correction);
                }
                // YNU出発
                else if (IsYnu(tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude),
                               tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude)))
                {
                    InsertHomewardTrip(tripsRawTable, tripsTable, datum, i, correction);
                }

                //自宅・YNU以外出発
                else if (IsOther(tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLatitude),
                                 tripsRawTable.Rows[i].Field <double>(TripsRawDao.ColumnStartLongitude)))
                {
                    InsertOtherTrip(tripsRawTable, tripsTable, datum, i, correction);
                }

                // 1トリップごとなので主キー違反があっても挿入されないだけ
                if (correction == InsertConfig.GpsCorrection.SpeedLPFMapMatching)
                {
                    TripsSpeedLPF005MMDao.Insert(tripsTable);
                }
                else if (correction == InsertConfig.GpsCorrection.MapMatching)
                {
                    TripsMMDao.Insert(tripsTable);
                }
                else
                {
                    TripsDao.Insert(tripsTable);
                }
            }
        }