/// <summary>
/// Read the data file and parse into the list of samples.
/// </summary>
/// <returns>Number of samples parsed if successful; -ve for error code</returns>
protected int ParseGHCNv2()
{
OpenTemp.WriteLine(string.Format("Reading the data file '{0}'...", _dataFile)); // Open the file
StreamReader sr;
try
{
sr = new StreamReader(_dataFile, true);
OpenTemp.WriteLine(" File opened for reading");
}
catch (Exception ex)
{
OpenTemp.WriteLine(string.Format(" Exception thrown when opening file: {0}", ex.ToString()));
return -1;
}
if (sr == null)
{
OpenTemp.WriteLine(" Failed to open file (check that it exists and the path is correct)");
return -2;
}
// Parse one line at a time
int nLinesTotal = 0;
int nLinesParsed = 0;
int expectedLength = 76;
while (!sr.EndOfStream)
{
nLinesTotal++;
string line = sr.ReadLine();
if (line.Length != expectedLength)
{
OpenTemp.WriteLine(string.Format(" Line {0}: Wrong number of characters ({1}, expected {2})", nLinesTotal + 1, line.Length, expectedLength));
sr.Dispose();
return -4;
}
string countryStation = line.Substring(0, 11);
if (!_stations.ContainsKey(countryStation)) continue;
Station station = _stations[countryStation];
string seriesText = line.Substring(11, 1);
byte series;
bool seriesOk = byte.TryParse(seriesText, out series);
if (!seriesOk)
{
OpenTemp.WriteLine(string.Format(" Line {0}: Failed to parse series # {1}", nLinesTotal + 1, seriesText));
sr.Dispose();
return -5;
}
if (!station.ContainsSeries(series))
{
station.AddSeries(series);
}
SortedList<DateTime, float?> values = station.GetReadings(series);
int year = 0;
string yearString = line.Substring(12, 4);
bool yearOk = int.TryParse(yearString, out year);
if (!yearOk)
{
OpenTemp.WriteLine(string.Format(" Line {0}: Error parsing year '{1}'", nLinesTotal + 1, yearString));
sr.Dispose();
return -6;
}
// Loop over all months
for (int iMonth = 1; iMonth <= 12; iMonth++)
{
DateTime date = new DateTime(year, iMonth, 1);
// Parse value
short value = -9999;
string valueString = line.Substring(16 + (iMonth - 1) * 5, 5);
bool valueOk = short.TryParse(valueString, out value);
if (!valueOk)
{
OpenTemp.WriteLine(string.Format(" Line {0}: Failed to parse value '{1}'", nLinesTotal + 1, valueString));
sr.Dispose();
return -7;
}
// Store sample
try
{
if ((value > -1000) && (value < +1000))
{
values.Add(new DateTime(year, iMonth, 1), 0.1f * (float)value); // Convert from tenths to real degrees
}
else
{
values.Add(new DateTime(year, iMonth, 1), null); // No reading
}
}
catch
{
OpenTemp.WriteLine(string.Format(" DUPLICATE station year: Station {0}, Series {1}, Year {2}", countryStation, series, year));
break;
}
}
// Increment and continue
nLinesParsed++;
if ((nLinesTotal % 100000) == 0)
{
OpenTemp.WriteLine(string.Format(" Parsing progress: {0} of {1} lines parsed", nLinesParsed, nLinesTotal));
}
}
// Cleanup
sr.Dispose();
// Done
OpenTemp.WriteLine(string.Format(" Parsing finished: {0} of {1} lines parsed", nLinesParsed, nLinesTotal));
return 12*nLinesParsed;
}