protected override void RunActualProcess() { SqlConnection.RecreateTable <OutgoingCommuterEntry>(Stage.Houses, Constants.PresentSlice); SqlConnection.RecreateTable <CarDistanceEntry>(Stage.Houses, Constants.PresentSlice); var dbHouses = SqlConnection.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice).Database; var dbRaw = SqlConnection.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice).Database; var occupants = dbHouses.Fetch <Occupant>(); var outGoings = dbRaw.Fetch <OutgoingCommuter>(); if (occupants.Count == 0) { throw new Exception("No occupants found"); } var entries = new List <OutgoingCommuterEntry>(); foreach (var commuter in outGoings) { for (var i = 0; i < commuter.Erwerbstätige; i++) { var oce = new OutgoingCommuterEntry { CommuterGuid = Guid.NewGuid().ToString() }; var method = Services.Rnd.NextDouble(); if (method < 0.52) { oce.CommuntingMethod = CommuntingMethod.Car; } else { oce.CommuntingMethod = CommuntingMethod.PublicTransport; } oce.DistanceInKm = commuter.Entfernung; oce.WorkCity = commuter.Arbeitsgemeinde; oce.WorkKanton = commuter.Arbeitskanton; entries.Add(oce); } } dbHouses.BeginTransaction(); //HashSet<string> usedHouseholdIDs = new HashSet<string>(); //oce.CommuniterDistanceInKm = commuter.Entfernung + 27.39; //freizeit km nach mikromobilitätszensus, 12.05 auto-km/tag/person, 0.44 autos pro person = 27.39 km/tag var potentialOccupants = occupants.Where(x => x.Age > 18 && x.Age < 65).ToList(); var cars = dbHouses.Fetch <Car>(); var householdGuidsWithCar = cars.Select(x => x.HouseholdGuid).ToList(); var occupantsWithCar = potentialOccupants.Where(x => householdGuidsWithCar.Contains(x.HouseholdGuid)).ToList(); var occupantsWithoutCar = potentialOccupants.Where(x => !occupantsWithCar.Contains(x)).ToList(); //List<CarDistanceEntry> cdes = new List<CarDistanceEntry>(); List <Car> availableCars = cars.ToList(); while (entries.Count > 0) { OutgoingCommuterEntry ogce = entries[0]; entries.RemoveAt(0); Occupant oc = null; if (ogce.CommuntingMethod == CommuntingMethod.Car) { Car myCar = null; while (myCar == null) { oc = occupantsWithCar[Services.Rnd.Next(occupantsWithCar.Count)]; occupantsWithCar.Remove(oc); myCar = availableCars.FirstOrDefault(x => x.HouseholdGuid == oc.HouseholdGuid); } availableCars.Remove(myCar); CarDistanceEntry cd = new CarDistanceEntry(oc.HouseGuid, oc.HouseholdGuid, myCar.CarGuid, ogce.DistanceInKm, 27.4); //cdes.Add(cd); dbHouses.Save(cd); } else { if (occupantsWithoutCar.Count > 0) { oc = occupantsWithoutCar[Services.Rnd.Next(occupantsWithoutCar.Count)]; occupantsWithoutCar.Remove(oc); } else { oc = occupantsWithCar[Services.Rnd.Next(occupantsWithCar.Count)]; occupantsWithCar.Remove(oc); } } ogce.HouseholdGuid = oc.HouseholdGuid; ogce.HouseGuid = oc.HouseGuid; ogce.CommuterGuid = Guid.NewGuid().ToString(); dbHouses.Save(ogce); } foreach (Car car in availableCars) { CarDistanceEntry cd = new CarDistanceEntry(car.HouseGuid, car.HouseholdGuid, car.CarGuid, 0, 27.4); dbHouses.Save(cd); } dbHouses.CompleteTransaction(); }
protected override void RunActualProcess() { var dbHouses = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice); var dbHousesPersistence = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Houses, Constants.PresentSlice, DatabaseCode.Persistence); dbHousesPersistence.CreateTableIfNotExists <PersistentOutgoingCommuterEntry>(); dbHouses.RecreateTable <OutgoingCommuterEntry>(); dbHouses.RecreateTable <CarDistanceEntry>(); var dbRaw = Services.SqlConnectionPreparer.GetDatabaseConnection(Stage.Raw, Constants.PresentSlice); var outGoings = dbRaw.Fetch <OutgoingCommuterSummary>(); var households = dbHouses.Fetch <Household>(); var residents = households.SelectMany(x => x.Occupants).ToList().AsReadOnly(); if (residents.Count == 0) { throw new Exception("No occupants found"); } var persistentOutgoingCommuters = dbHousesPersistence.Fetch <PersistentOutgoingCommuterEntry>(); var cars = dbHouses.Fetch <Car>(); var householdGuids = households.Select(x => x.Guid).ToList(); foreach (var car in cars) { if (!householdGuids.Contains(car.HouseholdGuid)) { throw new FlaException("car with invalid household guid"); } } if (cars.Count < 1000) { throw new FlaException("Not a single car was loaded"); } Debug("total planned commuters before persistence: " + outGoings.Sum(x => x.Erwerbstätige)); int idx = 0; int deletecount = 0; dbHouses.BeginTransaction(); dbHousesPersistence.BeginTransaction(); foreach (var persistentOutgoingCommuterEntry in persistentOutgoingCommuters) { var household = households.FirstOrDefault(x => x.HouseholdKey == persistentOutgoingCommuterEntry.HouseholdKey); if (household == null) { dbHousesPersistence.Delete(persistentOutgoingCommuterEntry); continue; } Car car = cars.FirstOrDefault(x => x.HouseholdGuid == household.Guid); if (car == null && persistentOutgoingCommuterEntry.CommuntingMethod == CommuntingMethod.Car) { Debug("deleted inconsistent commuter " + deletecount++); dbHousesPersistence.Delete(persistentOutgoingCommuterEntry); continue; } OutgoingCommuterEntry ogce = new OutgoingCommuterEntry(Guid.NewGuid().ToString(), household.Guid, persistentOutgoingCommuterEntry.DistanceInKm, persistentOutgoingCommuterEntry.CommuntingMethod, persistentOutgoingCommuterEntry.WorkCity, persistentOutgoingCommuterEntry.WorkKanton, household.HouseGuid); dbHouses.Save(ogce); var outgoing = outGoings.Single(x => x.Arbeitsgemeinde == persistentOutgoingCommuterEntry.WorkCity && x.Arbeitskanton == persistentOutgoingCommuterEntry.WorkKanton); outgoing.Erwerbstätige--; if (outgoing.Erwerbstätige < 0) { throw new FlaException("Negative workers"); } if (car != null) { //bus & bahn cars.Remove(car); CarDistanceEntry cde = new CarDistanceEntry(household.HouseGuid, household.Guid, car.Guid, persistentOutgoingCommuterEntry.DistanceInKm, 27.4, household.OriginalISNs, household.FinalIsn, household.HausAnschlussGuid, Guid.NewGuid().ToString(), "Car " + (idx++), car.CarType); dbHouses.Save(cde); } } dbHouses.CompleteTransaction(); dbHousesPersistence.CompleteTransaction(); Debug("total planned commuters after persistence: " + outGoings.Sum(x => x.Erwerbstätige)); var outgoingCommuters = new List <OutgoingCommuterEntry>(); foreach (var commuter in outGoings) { for (var i = 0; i < commuter.Erwerbstätige; i++) { var oce = new OutgoingCommuterEntry { CommuterGuid = Guid.NewGuid().ToString() }; var method = Services.Rnd.NextDouble(); if (method < 0.52) { oce.CommuntingMethod = CommuntingMethod.Car; } else { oce.CommuntingMethod = CommuntingMethod.PublicTransport; } oce.DistanceInKm = commuter.Entfernung; oce.WorkCity = commuter.Arbeitsgemeinde; oce.WorkKanton = commuter.Arbeitskanton; outgoingCommuters.Add(oce); } } //freizeit km nach mikromobilitätszensus, 12.05 auto-km/tag/person, 0.44 autos pro person = 27.39 km/tag var potentialResidents = residents.Where(x => x.Age > 18 && x.Age < 65).ToList(); var householdGuidsWithCar = cars.Select(x => x.HouseholdGuid).ToList(); var potentialResidentsWithCar = potentialResidents.Where(x => householdGuidsWithCar.Contains(x.HouseholdGuid)).ToList(); var potentialResidentsWithoutCar = potentialResidents.Where(x => !potentialResidentsWithCar.Contains(x)).ToList(); List <Car> availableCars = cars.ToList(); //assign the commuters List <OutgoingCommuterEntry> processedOutgoingCommuters = new List <OutgoingCommuterEntry>(); dbHouses.BeginTransaction(); while (outgoingCommuters.Count > 0) { OutgoingCommuterEntry ogce = outgoingCommuters[0]; processedOutgoingCommuters.Add(ogce); outgoingCommuters.RemoveAt(0); Occupant occupant = null; if (ogce.CommuntingMethod == CommuntingMethod.Car) { Car myCar = null; while (myCar == null) { occupant = potentialResidentsWithCar[Services.Rnd.Next(potentialResidentsWithCar.Count)]; potentialResidentsWithCar.Remove(occupant); myCar = availableCars.FirstOrDefault(x => x.HouseholdGuid == occupant.HouseholdGuid); } availableCars.Remove(myCar); Household hh = households.FirstOrDefault(x => x.Guid == occupant.HouseholdGuid); if (hh == null) { throw new FlaException("No household for " + ogce.HouseholdGuid); } CarDistanceEntry cd = new CarDistanceEntry(occupant.HouseGuid, occupant.HouseholdGuid, myCar.Guid, ogce.DistanceInKm, 27.4, hh.OriginalISNs, hh.FinalIsn, hh.HausAnschlussGuid, Guid.NewGuid().ToString(), (idx++).ToString(), myCar.CarType); dbHouses.Save(cd); } else { if (potentialResidentsWithoutCar.Count > 0) { occupant = potentialResidentsWithoutCar[Services.Rnd.Next(potentialResidentsWithoutCar.Count)]; potentialResidentsWithoutCar.Remove(occupant); } else { occupant = potentialResidentsWithCar[Services.Rnd.Next(potentialResidentsWithCar.Count)]; potentialResidentsWithCar.Remove(occupant); } } ogce.HouseholdGuid = occupant.HouseholdGuid; ogce.HouseGuid = occupant.HouseGuid; ogce.CommuterGuid = Guid.NewGuid().ToString(); } //the other cars are only used for freizeit / shopping / etc foreach (Car car in availableCars) { Household hh = households.Single(x => x.Guid == car.HouseholdGuid); CarDistanceEntry cd = new CarDistanceEntry(car.HouseGuid, car.HouseholdGuid, car.Guid, 0, 27.4, hh.OriginalISNs, hh.FinalIsn, hh.HausAnschlussGuid, Guid.NewGuid().ToString(), "Car " + (idx++), car.CarType); dbHouses.Save(cd); } foreach (var entry in processedOutgoingCommuters) { if (string.IsNullOrWhiteSpace(entry.HouseholdGuid)) { throw new FlaException("Household guid was empty"); } var household = households.Single(x => x.Guid == entry.HouseholdGuid); PersistentOutgoingCommuterEntry poce = new PersistentOutgoingCommuterEntry(household.HouseholdKey, entry.DistanceInKm, entry.CommuntingMethod, entry.WorkCity, entry.WorkKanton); dbHousesPersistence.Save(poce); dbHouses.Save(entry); } dbHousesPersistence.CompleteTransaction(); dbHouses.CompleteTransaction(); }