-
Notifications
You must be signed in to change notification settings - Fork 1
/
RoadNetwork.cs
149 lines (126 loc) · 6.71 KB
/
RoadNetwork.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Author: Clément Hardy
using Landis.Library.UniversalCohorts;
using Landis.Core;
using Landis.SpatialModeling;
using System.Collections.Generic;
using System.IO;
using Landis.Library.Metadata;
using System;
using System.Diagnostics;
using System.Linq;
namespace Landis.Extension.ForestRoadsSimulation
{
/// <summary>
/// Class used to contain several properties that record the state of the roads in the landscape,
/// and to initialize it properly.
/// </summary>
public class RoadNetwork
{
public static double costOfConstructionAndRepairsAtTimestep;
public static double costOfLastPath;
public static Site lastArrivalSiteOfDijkstraSearch;
public static List<FluxPath> fluxPathCatalogue;
public static Dictionary<Site, FluxPath> fluxPathDictionary;
/// <summary>
/// Initialy updates the status of being connected to a place where the harvested wood can flow to (sawmill, etc.) for each of the given roads.
/// It is different from the other updates, because it has to look at all of the sites, and not just the ones that changed status recently.
/// </summary>
/// <param name="ListOfSitesWithRoads">A list of sites with roads on them</param>
/// <returns>A list of sites that couldn't connect.</returns>
public static List<Site> UpdateConnectionToExitPointStatus()
{
Dictionary<Site, bool> dictonnaryOfSitesAlreadyChecked = new Dictionary<Site, bool>();
// First, we get all of the roads that correspond to exit points.
List<Site> sitesWithExitPoints = MapManager.GetSitesWithExitPoints(PlugIn.ModelCore);
PlugIn.ModelCore.UI.WriteLine(sitesWithExitPoints.Count + " sites with exit points detected.");
var progressBar = PlugIn.ModelCore.UI.CreateProgressMeter(sitesWithExitPoints.Count);
List<Site> listOfConnectedSites;
foreach (Site siteWithExit in sitesWithExitPoints)
{
// If the site hasn't been already checked
if (!dictonnaryOfSitesAlreadyChecked.ContainsKey(siteWithExit))
{
dictonnaryOfSitesAlreadyChecked[siteWithExit] = true;
SiteVars.RoadsInLandscape[siteWithExit].isConnectedToSawMill = true;
// We get all of the sites connected to this exit point
listOfConnectedSites = MapManager.GetAllConnectedRoads(siteWithExit);
// We defined each of them as checked and we update the connection status of those connected sites
foreach (Site siteConnected in listOfConnectedSites)
{
dictonnaryOfSitesAlreadyChecked[siteConnected] = true;
SiteVars.RoadsInLandscape[siteConnected].isConnectedToSawMill = true;
}
}
progressBar.IncrementWorkDone(1);
}
// To finish, we generate a list of sites that are not connected to an exit point.
List<Site> nonConnectedSites = new List<Site>();
foreach (Site siteWithRoad in MapManager.GetSitesWithRoads(PlugIn.ModelCore))
{
if (!dictonnaryOfSitesAlreadyChecked.ContainsKey(siteWithRoad)) { nonConnectedSites.Add(siteWithRoad); SiteVars.RoadsInLandscape[siteWithRoad].isConnectedToSawMill = false; }
}
return (nonConnectedSites);
}
/// <summary>
/// This function initialize the road network by checking if every road is connected one way or another to a place where the harvested wood can flow to (sawmill, etc.). If not, it construct the road.
/// </summary>
/// /// <param name="ModelCore">
/// The model's core framework.
/// </param>
/// /// <param name="heuristic">
/// The heuristic used to determine in which order the roads must be built by the least-cost path algorithm.
/// </param>
public static void Initialize(ICore ModelCore, string heuristic)
{
// We get all of the sites with a road on it
List<Site> listOfSitesWithRoads = MapManager.GetSitesWithRoads(ModelCore);
PlugIn.ModelCore.UI.WriteLine(listOfSitesWithRoads.Count + " sites with a road on them have been detected.");
// We check wich ones are connected to an exit point
ModelCore.UI.WriteLine(" Looking to see if the roads can go to a exit point (sawmill, main road network)...");
List<Site> listOfSitesThatCantConnect = UpdateConnectionToExitPointStatus();
// If there were sites that we couldn't not connect, we throw a warning the user
if (listOfSitesThatCantConnect.Count != 0)
{
ModelCore.UI.WriteLine(" FOREST ROADS SIMULATION WARNING : Roads that can't be connected to exit points (e.g. sawmills or main road network) have been detected in the input map.");
ModelCore.UI.WriteLine(" The extension will now try to create roads to link those roads that are not connected to places where the harvest wood can flow.");
PlugIn.ModelCore.UI.WriteLine(listOfSitesThatCantConnect.Count + " sites are in need of a connection to an exit point.");
ModelCore.UI.WriteLine(" Shuffling list of not connected sites with roads on them...");
// Then, we shuffle the list according to the heuristic given in the .txt parameter file.
listOfSitesThatCantConnect = MapManager.ShuffleAccordingToHeuristic(ModelCore, listOfSitesThatCantConnect, heuristic);
ModelCore.UI.WriteLine(" Building missing roads...");
var progressBar = PlugIn.ModelCore.UI.CreateProgressMeter(listOfSitesThatCantConnect.Count);
foreach (Site site in listOfSitesThatCantConnect)
{
// If the site has been updated and connected, no need to look at him.
if (!SiteVars.RoadsInLandscape[site].isConnectedToSawMill)
{
// ModelCore.UI.WriteLine(" Getting the connected neighbours...");
// Now, we get all of the roads that are connected to this one (and, implicitly, in need of being connected too)
List<Site> sitesConnectedToTheLonelySite = MapManager.GetAllConnectedRoads(site);
// ModelCore.UI.WriteLine(" Building the missing road...");
// We create a new road that will connect the given site to a road that is connected to a sawmill
DijkstraSearch.DijkstraLeastCostPathToClosestConnectedRoad(ModelCore, site, true);
// Now that it is connected, all of its connected neighbours will become automatically connected too.
foreach (Site connectedSite in sitesConnectedToTheLonelySite) SiteVars.RoadsInLandscape[connectedSite].isConnectedToSawMill = true;
}
progressBar.IncrementWorkDone(1);
}
}
// All the sites are now connected. Initialization of the road network is thus complete.
ModelCore.UI.WriteLine(" Initialization of the road network is now complete.");
}
/// <summary>
/// Function to reset the woodflux going through the roads for the current timestep.
/// </summary>
public static void RestTimestepWoodFluxData()
{
List<Site> listOfSitesWithRoads = MapManager.GetSitesWithRoads(PlugIn.ModelCore);
foreach (Site siteWithRoad in listOfSitesWithRoads)
{
SiteVars.RoadsInLandscape[siteWithRoad].timestepWoodFlux = 0;
}
fluxPathCatalogue.Clear();
fluxPathDictionary.Clear();
}
}
}