20070916

OpenTemp._MeshUSALower48()


        /// <summary>
        /// Generate a mesh of the USA lower 48.
        /// </summary>
        /// <returns>Number of mesh regions if successful; -ve for error code</returns>
        protected int _MeshUSALower48()
        {
            OpenTemp.WriteLine(string.Format("Generating mesh for the USA lower 48..."));
            // Define the perimter points
            // (points obtained from drawing the perimiter in Google Earth and parsing the KML file)
            PointF[] points = new PointF[111];
            int iPoint = 0;
            points[iPoint].X = -122.799f; points[iPoint].Y = 49f; iPoint++;
            points[iPoint].X = -122.758f; points[iPoint].Y = 47.166f; iPoint++;
            points[iPoint].X = -122.92f; points[iPoint].Y = 48.053f; iPoint++;
            points[iPoint].X = -124.641f; points[iPoint].Y = 48.226f; iPoint++;
            points[iPoint].X = -123.983f; points[iPoint].Y = 46.284f; iPoint++;
            points[iPoint].X = -124.269f; points[iPoint].Y = 42.051f; iPoint++;
            points[iPoint].X = -124.315f; points[iPoint].Y = 40.391f; iPoint++;
            points[iPoint].X = -122.305f; points[iPoint].Y = 37.157f; iPoint++;
            points[iPoint].X = -120.561f; points[iPoint].Y = 34.563f; iPoint++;
            points[iPoint].X = -118.464f; points[iPoint].Y = 33.971f; iPoint++;
            points[iPoint].X = -117.129f; points[iPoint].Y = 32.593f; iPoint++;
            points[iPoint].X = -114.738f; points[iPoint].Y = 32.719f; iPoint++;
            points[iPoint].X = -114.805f; points[iPoint].Y = 32.488f; iPoint++;
            points[iPoint].X = -110.992f; points[iPoint].Y = 31.296f; iPoint++;
            points[iPoint].X = -108.176f; points[iPoint].Y = 31.294f; iPoint++;
            points[iPoint].X = -108.17f; points[iPoint].Y = 31.805f; iPoint++;
            points[iPoint].X = -106.427f; points[iPoint].Y = 31.768f; iPoint++;
            points[iPoint].X = -104.887f; points[iPoint].Y = 30.546f; iPoint++;
            points[iPoint].X = -104.48f; points[iPoint].Y = 29.601f; iPoint++;
            points[iPoint].X = -103.153f; points[iPoint].Y = 28.972f; iPoint++;
            points[iPoint].X = -102.659f; points[iPoint].Y = 29.731f; iPoint++;
            points[iPoint].X = -101.421f; points[iPoint].Y = 29.775f; iPoint++;
            points[iPoint].X = -99.543f; points[iPoint].Y = 27.593f; iPoint++;
            points[iPoint].X = -99.078f; points[iPoint].Y = 26.403f; iPoint++;
            points[iPoint].X = -97.691f; points[iPoint].Y = 26.008f; iPoint++;
            points[iPoint].X = -97.407f; points[iPoint].Y = 25.834f; iPoint++;
            points[iPoint].X = -97.145f; points[iPoint].Y = 25.944f; iPoint++;
            points[iPoint].X = -97.38f; points[iPoint].Y = 27.001f; iPoint++;
            points[iPoint].X = -97.164f; points[iPoint].Y = 27.683f; iPoint++;
            points[iPoint].X = -96.331f; points[iPoint].Y = 28.391f; iPoint++;
            points[iPoint].X = -94.743f; points[iPoint].Y = 29.311f; iPoint++;
            points[iPoint].X = -93.831f; points[iPoint].Y = 29.659f; iPoint++;
            points[iPoint].X = -92.273f; points[iPoint].Y = 29.522f; iPoint++;
            points[iPoint].X = -90.747f; points[iPoint].Y = 29.061f; iPoint++;
            points[iPoint].X = -89.839f; points[iPoint].Y = 29.305f; iPoint++;
            points[iPoint].X = -89.309f; points[iPoint].Y = 28.976f; iPoint++;
            points[iPoint].X = -89.079f; points[iPoint].Y = 29.226f; iPoint++;
            points[iPoint].X = -89.576f; points[iPoint].Y = 29.498f; iPoint++;
            points[iPoint].X = -89.427f; points[iPoint].Y = 30.137f; iPoint++;
            points[iPoint].X = -87.71f; points[iPoint].Y = 30.212f; iPoint++;
            points[iPoint].X = -86.243f; points[iPoint].Y = 30.33f; iPoint++;
            points[iPoint].X = -85.298f; points[iPoint].Y = 29.639f; iPoint++;
            points[iPoint].X = -84.21f; points[iPoint].Y = 30.072f; iPoint++;
            points[iPoint].X = -82.675f; points[iPoint].Y = 28.854f; iPoint++;
            points[iPoint].X = -82.693f; points[iPoint].Y = 27.45f; iPoint++;
            points[iPoint].X = -81.68f; points[iPoint].Y = 25.911f; iPoint++;
            points[iPoint].X = -81.082f; points[iPoint].Y = 25.109f; iPoint++;
            points[iPoint].X = -80.36f; points[iPoint].Y = 25.239f; iPoint++;
            points[iPoint].X = -80.032f; points[iPoint].Y = 26.798f; iPoint++;
            points[iPoint].X = -80.549f; points[iPoint].Y = 28.413f; iPoint++;
            points[iPoint].X = -81.438f; points[iPoint].Y = 30.695f; iPoint++;
            points[iPoint].X = -80.637f; points[iPoint].Y = 32.287f; iPoint++;
            points[iPoint].X = -79.198f; points[iPoint].Y = 33.116f; iPoint++;
            points[iPoint].X = -78.749f; points[iPoint].Y = 33.753f; iPoint++;
            points[iPoint].X = -78.03f; points[iPoint].Y = 33.89f; iPoint++;
            points[iPoint].X = -77.09f; points[iPoint].Y = 34.644f; iPoint++;
            points[iPoint].X = -76.524f; points[iPoint].Y = 34.656f; iPoint++;
            points[iPoint].X = -75.722f; points[iPoint].Y = 35.704f; iPoint++;
            points[iPoint].X = -76.004f; points[iPoint].Y = 36.895f; iPoint++;
            points[iPoint].X = -75.036f; points[iPoint].Y = 38.439f; iPoint++;
            points[iPoint].X = -74.243f; points[iPoint].Y = 39.562f; iPoint++;
            points[iPoint].X = -73.965f; points[iPoint].Y = 40.476f; iPoint++;
            points[iPoint].X = -71.931f; points[iPoint].Y = 41f; iPoint++;
            points[iPoint].X = -73.57f; points[iPoint].Y = 40.944f; iPoint++;
            points[iPoint].X = -71.566f; points[iPoint].Y = 41.323f; iPoint++;
            points[iPoint].X = -69.922f; points[iPoint].Y = 41.632f; iPoint++;
            points[iPoint].X = -70.187f; points[iPoint].Y = 42.075f; iPoint++;
            points[iPoint].X = -70.1f; points[iPoint].Y = 41.816f; iPoint++;
            points[iPoint].X = -70.524f; points[iPoint].Y = 41.804f; iPoint++;
            points[iPoint].X = -70.946f; points[iPoint].Y = 42.439f; iPoint++;
            points[iPoint].X = -70.213f; points[iPoint].Y = 43.625f; iPoint++;
            points[iPoint].X = -66.879f; points[iPoint].Y = 44.794f; iPoint++;
            points[iPoint].X = -67.396f; points[iPoint].Y = 45.143f; iPoint++;
            points[iPoint].X = -67.441f; points[iPoint].Y = 45.569f; iPoint++;
            points[iPoint].X = -67.815f; points[iPoint].Y = 45.669f; iPoint++;
            points[iPoint].X = -67.786f; points[iPoint].Y = 47.055f; iPoint++;
            points[iPoint].X = -68.276f; points[iPoint].Y = 47.361f; iPoint++;
            points[iPoint].X = -68.919f; points[iPoint].Y = 47.182f; iPoint++;
            points[iPoint].X = -69.065f; points[iPoint].Y = 47.269f; iPoint++;
            points[iPoint].X = -69.054f; points[iPoint].Y = 47.426f; iPoint++;
            points[iPoint].X = -69.269f; points[iPoint].Y = 47.434f; iPoint++;
            points[iPoint].X = -70.018f; points[iPoint].Y = 46.641f; iPoint++;
            points[iPoint].X = -70.694f; points[iPoint].Y = 45.393f; iPoint++;
            points[iPoint].X = -71.571f; points[iPoint].Y = 44.993f; iPoint++;
            points[iPoint].X = -74.783f; points[iPoint].Y = 44.976f; iPoint++;
            points[iPoint].X = -76.457f; points[iPoint].Y = 44.097f; iPoint++;
            points[iPoint].X = -76.813f; points[iPoint].Y = 43.656f; iPoint++;
            points[iPoint].X = -78.651f; points[iPoint].Y = 43.617f; iPoint++;
            points[iPoint].X = -79.172f; points[iPoint].Y = 43.441f; iPoint++;
            points[iPoint].X = -78.938f; points[iPoint].Y = 42.84f; iPoint++;
            points[iPoint].X = -80.058f; points[iPoint].Y = 42.366f; iPoint++;
            points[iPoint].X = -81.215f; points[iPoint].Y = 42.228f; iPoint++;
            points[iPoint].X = -82.411f; points[iPoint].Y = 41.667f; iPoint++;
            points[iPoint].X = -82.668f; points[iPoint].Y = 41.648f; iPoint++;
            points[iPoint].X = -83.047f; points[iPoint].Y = 41.854f; iPoint++;
            points[iPoint].X = -83.112f; points[iPoint].Y = 42.259f; iPoint++;
            points[iPoint].X = -82.538f; points[iPoint].Y = 42.634f; iPoint++;
            points[iPoint].X = -82.111f; points[iPoint].Y = 43.595f; iPoint++;
            points[iPoint].X = -82.486f; points[iPoint].Y = 45.331f; iPoint++;
            points[iPoint].X = -83.59f; points[iPoint].Y = 45.795f; iPoint++;
            points[iPoint].X = -84.766f; points[iPoint].Y = 46.6f; iPoint++;
            points[iPoint].X = -84.841f; points[iPoint].Y = 46.871f; iPoint++;
            points[iPoint].X = -88.364f; points[iPoint].Y = 48.285f; iPoint++;
            points[iPoint].X = -89.363f; points[iPoint].Y = 47.973f; iPoint++;
            points[iPoint].X = -91.249f; points[iPoint].Y = 48.051f; iPoint++;
            points[iPoint].X = -92.989f; points[iPoint].Y = 48.585f; iPoint++;
            points[iPoint].X = -93.744f; points[iPoint].Y = 48.5f; iPoint++;
            points[iPoint].X = -94.623f; points[iPoint].Y = 48.712f; iPoint++;
            points[iPoint].X = -94.809f; points[iPoint].Y = 49.286f; iPoint++;
            points[iPoint].X = -95.14f; points[iPoint].Y = 49.368f; iPoint++;
            points[iPoint].X = -95.199f; points[iPoint].Y = 49f; iPoint++;

            // Define the graphics path
            _regionGraphicsPath = new GraphicsPath();
            _regionGraphicsPath.AddLines(points);
            _regionGraphicsPath.CloseAllFigures();

            // Generate a list of rectangles that are contained by the perimeter
            RectangleF bounds = _regionGraphicsPath.GetBounds();
            for (float longitude = (float)Math.Floor(bounds.Left) - 0.5f * _cellSize;
                longitude <= (float)Math.Ceiling(bounds.Right) + 0.5f * _cellSize;
                longitude += _cellSize)
            {
                for (float latitude = (float)Math.Floor(bounds.Top) - 0.5f * _cellSize;
                    latitude <= (float)Math.Ceiling(bounds.Bottom) + 0.5f * _cellSize;
                    latitude += _cellSize)
                {
                    if (_regionGraphicsPath.IsVisible(longitude, latitude))
                    {
                        _cells.Add(new Cell(latitude, longitude, _cellSize, _cellSize));
                    }
                }
            }

            // Sanity check: are all stations contained in the mesh?
            foreach (Station station in _stations.Values)
            {
                if (!_regionGraphicsPath.IsVisible(station.Longitude, station.Latitude))
                {
                    OpenTemp.WriteLine(string.Format("  Station {0}{1} is not contained in the mesh", station.Country, station.StationID));
                }
            }

            // Define stations that can affect every cell
            foreach (Cell cell in _cells)
            {
                int nStations = cell.DefineStations(_stations.Values, _averagingRadius);
                if (nStations < 3)
                {
                    OpenTemp.WriteLine(string.Format("  Cell at <{0:F2}, {1:F2}> is affected by {2} stations (prefer at least 3)", cell.Latitude, cell.Longitude, nStations));
                }
            }
            // Log
            OpenTemp.WriteLine(string.Format("  Mesh generation finished: {0} mesh squares", _cells.Count));
            // Cleanup and return
            _regionGraphicsPath.Dispose();
            return _cells.Count;
        }

20070916
Code Review

Comments Off

Permalink

Code Review

First things first. The code base needs to be reviewed and validated for accuracy.

A link to a summary page for every version of the code will be placed here. The summary page will include links to pages with source code. Code review should be done on those pages:

First Release (Sept 16, 2007)

20070916
Code Review

Comments (3)

Permalink

20070916 - First Release

This was the first release of the source code. It was initially uploaded to a file hosting site, but is now available here:

20070916 - OpenTemp Source Code

It is a C# project created in Microsoft Visual Studio 2005. It requires the Microsoft .Net Framework v2.0. (The easiest way to get it is with Windows Update or Microsoft Update).

If you want to play with the code, you should consider downloading Microsoft Visual C# 2005 Express. It’s free.

The code is implemented in three files. Use the links below to discuss the code:

Cell.cs
Station.cs
OpenTemp.cs

I would like to break it up into smaller files but that can wait until later.

20070916
Code Review

Comments (8)

Permalink

Cell.cs

// =====
// Copyright 2007 John Van Vliet, all rights reserved
// Here's my simple license, soon to be replaced by a proper license.
// What you can do:
// - read the code
// - play with the code
// - run the code
// - modify the code
// What you can't do:
// - re-publish the original code or any modified versions
// =====
using System;
using System.Collections.Generic;
using System.Text;

namespace OpenTemp
{
    /// <summary>
    /// Definition of a single station and its weight in determining the temperature for this cell.
    /// </summary>
    struct CellStation
    {
        internal float weight;
        internal Station station;
    }

    /// <summary>
    /// Definition of a single cell on the earth's surface
    /// </summary>
    class Cell
    { Continue Reading »

20070916
Code Review

Comments Off

Permalink

Station.cs

// =====
// Copyright 2007 John Van Vliet, all rights reserved
// Here's my simple license, soon to be replaced by a proper license.
// What you can do:
// - read the code
// - play with the code
// - run the code
// - modify the code
// What you can't do:
// - re-publish the original code or any modified versions
// =====
using System;
using System.Collections.Generic;
using System.Text;

namespace OpenTemp
{
    class Station
    { Continue Reading »

20070916
Code Review

Comments (2)

Permalink

OpenTemp.cs

This page contains the main body and utility methods of OpenTemp.cs
Use the links below for the input methods:

ParseStations()
ParseGHCNv2()

Use the links below for the analysis methods:

CalculateMonthlyAverages()
CalculateSeriesOffsets()
_MeshUSALower48()

Use these links for the ouput methods:

WriteStationResults()
WriteCellStationResults()
WriteCellInfo()
WriteSeriesOffsets()
WriteMonthlyResults()
WriteYearlyResults()

// ===== Continue Reading »

20070916
Code Review

Comments Off

Permalink

OpenTemp.ParseStations()

        /// <summary>
        /// Read the sttaions file and parse into the list of stations.
        /// </summary>
        /// <remarks>The stations file should be a CSV format with one line per station.
        /// Each line should consist of the station ID (including the country code), the latitude, and the longitude.</remarks>
        /// <returns>Number of stations if successful; -ve for error code</returns>
        protected int ParseStations()
        {
            OpenTemp.WriteLine(string.Format("Reading the stations file '{0}'...", _stationsFile));
            // Open the file
            StreamReader sr;
            try
            {
                sr = new StreamReader(_stationsFile, 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(string.Format("  Failed to open file (check that it exists and the path is correct)"));
                return -2;
            }
            // Parse one line at a time
            int nLines = 1;
            while (!sr.EndOfStream)
            {
                nLines++;

                string line = sr.ReadLine();
                if (line.Length == 0) continue;
                string[] entries = line.Split(',');
                if (entries.Length != 3)
                {
                    OpenTemp.WriteLine(string.Format("  Line {0}: Wrong number of entries ({1}, expected {2})", nLines, entries.Length, 3));
                    sr.Dispose();
                    return -3;
                }
                string countryStation = entries[0];
                if (!_stations.ContainsKey(countryStation))
                {
                    float latitude = float.Parse(entries[1]);       // TODO: Add error handling
                    float longitude = float.Parse(entries[2]);      // TODO: Add error handling
                    _stations.Add(countryStation, new Station(countryStation, longitude, latitude));
                }
                Station station = _stations[countryStation];

                // Increment and continue
                if ((nLines % 100) == 0)
                {
                    OpenTemp.WriteLine(string.Format("  {0} stations parsed", nLines));
                }
            }

            // Cleanup
            sr.Dispose();

            // Done
            OpenTemp.WriteLine(string.Format("  Parsing finished: {0} stations parsed", nLines));
            return nLines;
        }

20070916
Code Review

Comments (7)

Permalink

OpenTemp.ParseGHCNv2()

        /// <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;
        }

20070916
Code Review

Comments Off

Permalink

OpenTemp.WriteStationResults()

        /// <summary>
        /// Write the station results to a data file in CSV format.
        /// </summary>
        /// <returns>0 if successful; -ve for error code</returns>
        protected int WriteStationResults()
        {
            OpenTemp.WriteLine(string.Format("Writing the station results file '{0}'...", _outputStationFile));
            // Open the file
            StreamWriter sw;
            try
            {
                sw = new StreamWriter(_outputStationFile, false);      // Overwrite (do not append)
                OpenTemp.WriteLine("  File opened for writing");
            }
            catch (Exception ex)
            {
                OpenTemp.WriteLine(string.Format("  Exception thrown when opening file:  {0}", ex.ToString()));
                return -1;
            }
            if (sw == null)
            {
                OpenTemp.WriteLine("  Failed to open file (check that it exists and the path is correct)");
                return -2;
            }
            // Write header
            sw.Write("YEAR,MONTH");
            foreach (string countryStation in _stations.Keys)
            {
                sw.Write(",");
                sw.Write(countryStation);
            }
            sw.WriteLine();

            // Write one line at a time (starting in 1880)
            DateTime date = new DateTime(1880, 1, 1);
            DateTime today = DateTime.Today;
            int nMonths = 0;
            while (date < today)
            {
                // Any values for this month?
                int nValues = 0;
                foreach (Station station in _stations.Values)
                {
                    foreach (byte series in station.SeriesNumbers)
                    {
                        SortedList<DateTime, float?> values = station.GetReadings(series);
                        if (values.ContainsKey(date))
                        {
                            if (values[date].HasValue) nValues++;
                        }
                    }
                }

                // Write output if values found
                if (nValues > 0)
                {
                    // Write month label
                    sw.Write(date.ToString("yyyy"));
                    sw.Write(",");
                    sw.Write(date.ToString("MM"));

                    // Write values for this month
                    foreach (Station station in _stations.Values)
                    {
                        foreach (byte series in station.SeriesNumbers)
                        {
                            sw.Write(",");
                            SortedList<DateTime, float?> values = station.GetReadings(series);
                            if (values.ContainsKey(date))
                            {
                                if (!values[date].HasValue) continue;
                                sw.Write(string.Format("{0:F2}", values[date].Value));
                            }
                        }
                    }
                    sw.WriteLine();
                    nMonths++;
                }

                // Next month
                date = date.AddMonths(1);
            }

            // Done
            sw.Close();

            // Done
            OpenTemp.WriteLine(string.Format("  Writing finished: {0} months written", nMonths));
            return 0;
        }

20070916
Code Review

Comments (5)

Permalink

OpenTemp.WriteCellStationResults()

        /// <summary>
        /// Write the cell-station restuls to a data file in CSV format (stations that can affect each cell).
        /// </summary>
        /// <returns>0 if successful; -ve for error code</returns>
        protected int WriteCellStationResults()
        {
            OpenTemp.WriteLine(string.Format("Writing the cell-station results file '{0}'...", _outputCellStationsFile));
            // Open the file
            StreamWriter sw;
            try
            {
                sw = new StreamWriter(_outputCellStationsFile, false);      // Overwrite (do not append)
                OpenTemp.WriteLine("  File opened for writing");
            }
            catch (Exception ex)
            {
                OpenTemp.WriteLine(string.Format("  Exception thrown when opening file:  {0}", ex.ToString()));
                return -1;
            }
            if (sw == null)
            {
                OpenTemp.WriteLine("  Failed to open file (check that it exists and the path is correct)");
                return -2;
            }
            // Write header
            sw.Write("CELL_LAT, CELL_LONG");
            foreach (Station station in _stations.Values)
            {
                sw.Write(string.Format(", {0}{1}_LAT, {0}{1}_LONG, {0}{1}_WEIGHT", station.Country, station.StationID));
            }
            sw.WriteLine();

            // Write station locations
            sw.Write(", ");
            foreach (Station station in _stations.Values)
            {
                sw.Write(string.Format(", {0:F2}, {1:F2}, ", station.Latitude, station.Longitude));
            }
            sw.WriteLine();

            // Write cell location and cell-station weights
            foreach (Cell cell in _cells)
            {
                sw.Write(string.Format("{0:F2}, {1:F2}", cell.Latitude, cell.Longitude));
                foreach (Station station in _stations.Values)
                {
                    sw.Write(", , ");
                    float weight = -1.0f;
                    foreach (CellStation cs in cell.Stations)
                    {
                        if (cs.station.Equals(station))
                        {
                            weight = cs.weight;
                            break;
                        }
                    }
                    if (weight >= 0.0f)
                    {
                        sw.Write(string.Format(", {0:F3}", weight));
                    }
                    else
                    {
                        sw.Write(", ");
                    }
                }
                sw.WriteLine();
            }

            // Done
            sw.Close();

            // Done
            OpenTemp.WriteLine(string.Format("  Writing finished: {0} cells written", _cells.Count));
            return 0;
        }

20070916
Code Review

Comments (1)

Permalink