diff --git a/DaySim.Framework/Core/Configuration.cs b/DaySim.Framework/Core/Configuration.cs index 30748f21..6a795295 100644 --- a/DaySim.Framework/Core/Configuration.cs +++ b/DaySim.Framework/Core/Configuration.cs @@ -2200,6 +2200,12 @@ public sealed class Configuration { [XmlAttribute] public double COMPASS_AutoParkAndRideLotCapacitySizeWeight { get; set; } = 1; + public double COMPASS_BikeParkAndRideAccessCapacitySizeWeight { get; set; } = 1; + public double COMPASS_BikeParkAndRideEgressCapacitySizeWeight { get; set; } = 1; + public double COMPASS_BikeParkAndRideAccessAnnualCostDivisor { get; set; } = 200; + public double COMPASS_BikeParkAndRideEgressAnnualCostDivisor { get; set; } = 200; + public bool COMPASS_IncludeAutoParkAndRideLotCapacityEffectInModeChoice { get; set; } = false; + public bool COMPASS_IncludeBikeParkAndRideLotCapacityEffectInModeChoice { get; set; } = false; [XmlAttribute] public int COMPASS_MaximumTerminalsToSearchWalk { get; set; } = 10; diff --git a/DaySim.Framework/Persistence/ExporterFactory.cs b/DaySim.Framework/Persistence/ExporterFactory.cs index 42bff8e6..3aac9fa2 100644 --- a/DaySim.Framework/Persistence/ExporterFactory.cs +++ b/DaySim.Framework/Persistence/ExporterFactory.cs @@ -73,8 +73,10 @@ private static void GenerateMethodCode(ILGenerator il, Type type, char delimiter il.Emit(OpCodes.Callvirt, typeof(StreamWriter).GetMethod("Write", new[] { typeof(int) })); } else if (properties[i].PropertyType == typeof(bool)) { il.Emit(OpCodes.Callvirt, typeof(StreamWriter).GetMethod("Write", new[] { typeof(bool) })); + } else if (properties[i].PropertyType == typeof(long)) { + il.Emit(OpCodes.Callvirt, typeof(StreamWriter).GetMethod("Write", new[] { typeof(long) })); } else { - throw new NotSupportedException("Unsupported type. Valid types are double, int, and bool."); + throw new NotSupportedException("Unsupported type. Valid types are double, int, long and bool."); } if (i == properties.Length - 1) { @@ -90,4 +92,4 @@ private static void GenerateMethodCode(ILGenerator il, Type type, char delimiter il.Emit(OpCodes.Ret); } } -} \ No newline at end of file +} diff --git a/DaySim/DomainModels/Actum/Models/Interfaces/IActumTrip.cs b/DaySim/DomainModels/Actum/Models/Interfaces/IActumTrip.cs index c83fdaab..897853aa 100644 --- a/DaySim/DomainModels/Actum/Models/Interfaces/IActumTrip.cs +++ b/DaySim/DomainModels/Actum/Models/Interfaces/IActumTrip.cs @@ -10,6 +10,7 @@ namespace DaySim.DomainModels.Actum.Models.Interfaces { public interface IActumTrip : ITrip { //JLB20160323 + long TripId { get; set; } int TourMode { get; set; } @@ -52,6 +53,5 @@ public interface IActumTrip : ITrip { int AutoType { get; set; } int AutoOccupancy { get; set; } - } } diff --git a/DaySim/DomainModels/Actum/Models/Trip.cs b/DaySim/DomainModels/Actum/Models/Trip.cs index 0b8c9481..c910cfe8 100644 --- a/DaySim/DomainModels/Actum/Models/Trip.cs +++ b/DaySim/DomainModels/Actum/Models/Trip.cs @@ -6,6 +6,7 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. using System.Runtime.InteropServices; +using System.IO; using DaySim.DomainModels.Actum.Models.Interfaces; using DaySim.Framework.Factories; using DaySim.Framework.Persistence; @@ -15,6 +16,9 @@ namespace DaySim.DomainModels.Actum.Models { [Factory(Factory.PersistenceFactory, Category = Category.Model, DataType = DataType.Actum)] public sealed class Trip : DomainModels.Default.Models.Trip, IActumTrip { + [ColumnName("trip_id")] + public long TripId { get; set; } + [ColumnName("tourmode")] public int TourMode { get; set; } diff --git a/DaySim/DomainModels/Actum/Wrappers/TripWrapper.cs b/DaySim/DomainModels/Actum/Wrappers/TripWrapper.cs index d6519d5f..9cf6b6b1 100644 --- a/DaySim/DomainModels/Actum/Wrappers/TripWrapper.cs +++ b/DaySim/DomainModels/Actum/Wrappers/TripWrapper.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; +using System.IO; using DaySim.ChoiceModels.H; using DaySim.DomainModels.Actum.Models.Interfaces; using DaySim.DomainModels.Actum.Wrappers.Interfaces; @@ -64,6 +65,11 @@ public int AutoOccupancy { set => _trip.AutoOccupancy = value; } + public long TripId { + get => _trip.TripId; + set => _trip.TripId = value; + } + public int TourMode { get => _trip.TourMode; set => _trip.TourMode = value; @@ -439,6 +445,8 @@ public override void HUpdateTripValues() { TravelDistance = modeImpedance.PathDistance; PathType = modeImpedance.PathType; + TripId = (long)Id; + if (TripId < 0) { TripId += 4294967295L; }; TourMode = Tour.Mode; IActumHouseholdWrapper household = (IActumHouseholdWrapper) Household; @@ -675,6 +683,8 @@ public void HPTBikeDriveTransitTourUpdateTripValues() { TravelDistance = Tour.TravelDistanceForPTBikeTour / 2.0; PathType = Tour.PathType; + TripId = (long)Id; + if (TripId < 0) { TripId += 4294967295L; }; TourMode = Tour.Mode; bool parkAndRide = (TourMode == Global.Settings.Modes.CarParkRideWalk || TourMode == Global.Settings.Modes.CarParkRideBike || TourMode == Global.Settings.Modes.CarParkRideShare); diff --git a/DaySim/PathTypeModels/PathTypeModel_Actum.cs b/DaySim/PathTypeModels/PathTypeModel_Actum.cs index b4bc1c23..fdb8b87f 100644 --- a/DaySim/PathTypeModels/PathTypeModel_Actum.cs +++ b/DaySim/PathTypeModels/PathTypeModel_Actum.cs @@ -1001,10 +1001,16 @@ private void RunStopAreaGeneralTransitModel(int skimMode, int accessMode, int eg accessTerminalParcelID = parkAndRideParcel.Id; accessTerminalZoneID = (int)parkAndRideParcel.ZoneKey; WalkBikePath accessPath = GetWalkBikePath(accessMode, pathTypeAccEgr, votValue, useZones, _outboundTime, _returnTime, 0, 0, originParcelUsed, parkAndRideParcel); - double parkingCost = node.CostDaily; + double parkingCost = node.CostAnnual / Global.Configuration.COMPASS_BikeParkAndRideAccessAnnualCostDivisor; + parkCapacitySizeTerm = Math.Log(Math.Max(node.Capacity, 1.0E-30)) * Global.Configuration.COMPASS_BikeParkAndRideAccessCapacitySizeWeight; accessTime = accessPath.Time * roundTripFactor; accessCost = parkingCost; + accessPath.Utility += parkingCost * _tourCostCoefficient; accessUtility = accessPath.Utility * roundTripFactor; + if (Global.Configuration.COMPASS_IncludeBikeParkAndRideLotCapacityEffectInModeChoice) { + accessUtility = accessUtility + parkCapacitySizeTerm; + parkCapacitySizeTerm = 0; + } } else if (sovAccess) { int nodeId = Global.ParcelToAutoParkAndRideNodeIds[indexAccess]; ParkAndRideNodeWrapper node = autoParkAndRideNodes.First(x => x.ZoneId == nodeId); @@ -1045,7 +1051,12 @@ private void RunStopAreaGeneralTransitModel(int skimMode, int accessMode, int eg accessTime = accessPath.Time * roundTripFactor; accessCost = accessPath.Cost + parkingCost; + accessPath.Utility += parkingCost * _tourCostCoefficient; accessUtility = accessPath.Utility * roundTripFactor; + if (Global.Configuration.COMPASS_IncludeAutoParkAndRideLotCapacityEffectInModeChoice) { + accessUtility = accessUtility + parkCapacitySizeTerm; + parkCapacitySizeTerm = 0; + } } else if (hovAccess || shareAccess) { accessTerminalKey = Global.ParcelToAutoKissAndRideTerminalKeys[indexAccess]; accessTerminalIndex = Global.ParcelToAutoKissAndRideTerminalIndices[indexAccess]; @@ -1109,9 +1120,16 @@ private void RunStopAreaGeneralTransitModel(int skimMode, int accessMode, int eg egressTerminalParcelID = parkAndRideParcel.Id; egressTerminalZoneID = (int)parkAndRideParcel.ZoneKey; WalkBikePath egressPath = GetWalkBikePath(egressMode, pathTypeAccEgr, votValue, useZones, _outboundTime, _returnTime, 0, 0, parkAndRideParcel, destinationParcelUsed); + double parkingCost = node.CostAnnual / Global.Configuration.COMPASS_BikeParkAndRideEgressAnnualCostDivisor; + parkCapacitySizeTerm += Math.Log(Math.Max(node.Capacity, 1.0E-30)) * Global.Configuration.COMPASS_BikeParkAndRideEgressCapacitySizeWeight; egressTime = egressPath.Time * roundTripFactor; - egressCost = 0; + egressCost = parkingCost; + egressPath.Utility += parkingCost * _tourCostCoefficient; egressUtility = egressPath.Utility * roundTripFactor; + if (Global.Configuration.COMPASS_IncludeBikeParkAndRideLotCapacityEffectInModeChoice) { + accessUtility = accessUtility + parkCapacitySizeTerm; + parkCapacitySizeTerm = 0; + } } else if (shareEgress) { egressTerminalKey = Global.ParcelToAutoKissAndRideTerminalKeys[indexEgress]; egressTerminalIndex = Global.ParcelToAutoKissAndRideTerminalIndices[indexEgress]; @@ -1584,6 +1602,19 @@ private TransitPath GetTransitPath(int skimMode, int pathType, double votValue, path.Cost += fare; } } + //mb code for bike on board fare + if (skimMode == Global.Settings.Modes.BikeOnTransit) { + varname = commuter ? "bikefare-co" : "bikefare"; + skimValue = + ImpedanceRoster.GetValue(varname, skimMode, pathType, votValue, outboundTime, originZoneId, destinationZoneId); + path.Cost += skimValue.Variable; + + if (_returnTime > 0) { + skimValue = + ImpedanceRoster.GetValue(varname, skimMode, pathType, votValue, returnTime, destinationZoneId, originZoneId); + path.Cost += skimValue.Variable; + } + } path.Utility = path.GenTime * _tourTimeCoefficient + path.Cost * _tourCostCoefficient;