Click here to Skip to main content
14,643,165 members
Rate this:
Please Sign up or sign in to vote.
See more:
I have a few for loops to determine the distances between a selected location (in this code, 2 application settings) and a list of around 5000 other locations using the Haversine formula (in this code, a function named 'Formula' in a class file named 'Haversine'). The loop works how I want it to and is completely fine until it gets to the second last 'record' in the file at which point it stops and throws an error. I was wondering if anyone would help me fix it. The code is below but without the function as it is in a separate file.

static void Main(string[] args)
        {            
            XmlDocument SiteList = new XmlDocument();
            SiteList.Load("C:/Users/Henry/WeatherWatcher/Development/sitelist.xml");
            List<string> list = new List<string>();
            Console.WriteLine("HAVERSINE: BASE LA-" + Properties.Settings.Default.LATITUDE + "LO-" + Properties.Settings.Default.LONGITUDE);
            for (int x = 0; x < SiteList.SelectNodes("/Locations/Location/@id").Count; x++)
            {
                double ListLO = Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText);
                for (int y = 0; y < SiteList.SelectNodes("/Locations/Location/@latitude").Count; x++ )
                {

                    double ListLA = Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText);                    
                    string Item = Convert.ToString(Haversine.Formula(Convert.ToDouble(52.2802588), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), ListLA, ListLO) + "---" + SiteList.SelectNodes("/Locations/Location/@id")[x].InnerText);
                    Console.WriteLine(Item);
                    list.Add(Convert.ToString(Item.ToString()));
                    Console.WriteLine("");                    
                    //TOTAL_ 5363
                    Console.WriteLine(x);                  
                }
                Console.ReadKey();
            }
        }


The xml file it is reading is structured like this: (with one '<location'>
<?xml version="1.0" encoding="ISO-8859-1"?>
-<Locations>
    <Location name="Rosehearty Samos" longitude="-2.121" latitude="57.698" id="3094"/>
    <Location name="Strathallan" longitude="-3.729" latitude="56.326" id="3144"/>
    <Location name="Edinburgh/Gogarbank" longitude="-3.343" latitude="55.928" id="3166"/>

...
    <Location name="Rhossili Bay (Beach)" longitude="-4.2905" latitude="51.5707" id="354477"/>
    <Location name="Perranporth - Village (Beach)" longitude="-5.1535" latitude="50.3491" id="354541"/>
    <Location name="Perranuthnoe (Perran Sands) (Beach)" longitude="-5.4411" latitude="50.1121" id="354552"/>
</Locations>


The number of locations I want to process is 5363 (the total number in the file) however it stops and give an error leaving the console output as:
...
5359
87.7415106490408---354477

5360
218.280932624672---354541

5361
244.281295790985---354552

5362

What it should do is process all 5363 locations and display them then close. It hasn't processed the second last location and the whole of the last one giving the error:

System.NullReferenceException was unhandled
Object reference not set to an instance of an object.

I don't know what to do really so I was wondering if one of you could help get the loops working. I am writing is C# using MS VS2010. I hope this makes sense and thank you for any help.
Posted
Rate this:
Please Sign up or sign in to vote.

Solution 1

Maybe you could start replacing

for (int y = 0; y < SiteList.SelectNodes("/Locations/Location/@latitude").Count; x++ )


with

for (int y = 0; y < SiteList.SelectNodes("/Locations/Location/@latitude").Count; y++ )


It seems making more sense.
   
Comments
Henry Hunt 29-Aug-13 11:49am
   
Doesn't work because the y loop follows on from the x loop. After getting the longs using x it then gets the lats with y using x to tell it to count up the same amount as it did to get the longs if that makes any sense.
phil.o 29-Aug-13 11:51am
   
Then what is the point of the second for loop if you never use the y variable ?
The problem here is that you increase x twice ; I suspect the error you get is because SiteList.SelectNodes("/Locations/Location/@latitude")[x] becomes out of range, thus you get a NullReferenceException when you try to access the InnerText property.
You should rethink your algorithm, which seems incorrect.
Henry Hunt 29-Aug-13 13:23pm
   
I think I jump to asking for help after not trying for long enough myself! Solved it myself with this code:

static void Main(string[] args)
{
XmlDocument SiteList = new XmlDocument();
SiteList.Load("C:/Users/Henry/WeatherWatcher/Development/sitelist.xml");
List<string> FinalList = new List<string>();
for (int x = 0; x < SiteList.SelectNodes("/Locations/Location/@id").Count; x++)
{
for (x = 0; x < SiteList.SelectNodes("/Locations/Location/@latitude").Count; x++)
{
for (x = 0; x < SiteList.SelectNodes("/Locations/Location/@longitude").Count; x++)
{
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine("ID: " + SiteList.SelectNodes("Locations/Location/@id")[x].InnerText);
Console.WriteLine("LA: " + SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText);
Console.WriteLine("LO: " + SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText);
Console.WriteLine("HF: " + Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)));
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("AL: " + Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)) + "---" + SiteList.SelectNodes("/Locations/Location/@id")[x].InnerText);
FinalList.Add(Convert.ToString(Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)) + "---" + SiteList.SelectNodes("/Locations/Location/@id")[x].InnerText));
Console.WriteLine(Environment.NewLine);
}
}
}
foreach (object o in FinalList)
{
Console.WriteLine(o);
}
Console.ReadKey();
}
phil.o 30-Aug-13 2:47am
   
Wow, never tried to nest three for-loops with the same variable.
Anyway, if you solved it by yourself, and if I was of any help in that process, I'm glad.
Rate this:
Please Sign up or sign in to vote.

Solution 2

In below loop you incrementing x instead of y

for (int y = 0; y < SiteList.SelectNodes("/Locations/Location/@latitude").Count; x++ )
   
v2
Rate this:
Please Sign up or sign in to vote.

Solution 3

I solved it myself with this code after rethinking and rewriting the algorithm:

static void Main(string[] args)
        {
            XmlDocument SiteList = new XmlDocument();
            SiteList.Load("C:/Users/Henry/WeatherWatcher/Development/sitelist.xml");
            List<string> FinalList = new List<string>();
            for (int x = 0; x < SiteList.SelectNodes("/Locations/Location/@id").Count; x++)
            {               
                for (x = 0; x < SiteList.SelectNodes("/Locations/Location/@latitude").Count; x++)
                {
                    for (x = 0; x < SiteList.SelectNodes("/Locations/Location/@longitude").Count; x++)
                    {
                        Console.ForegroundColor = ConsoleColor.White;
                        Console.WriteLine("ID: " + SiteList.SelectNodes("Locations/Location/@id")[x].InnerText);
                        Console.WriteLine("LA: " + SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText);
                        Console.WriteLine("LO: " + SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText);                       
                        Console.WriteLine("HF: " + Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)));
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.WriteLine("AL: " + Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)) + "---" + SiteList.SelectNodes("/Locations/Location/@id")[x].InnerText);
                        FinalList.Add(Convert.ToString(Haversine.Formula(Convert.ToDouble(Properties.Settings.Default.LATITUDE), Convert.ToDouble(Properties.Settings.Default.LONGITUDE), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@latitude")[x].InnerText), Convert.ToDouble(SiteList.SelectNodes("/Locations/Location/@longitude")[x].InnerText)) + "---" + SiteList.SelectNodes("/Locations/Location/@id")[x].InnerText));
                        Console.WriteLine(Environment.NewLine);
                    }
                }               
            }
            foreach (object o in FinalList)
            {
                Console.WriteLine(o);
            }
            Console.ReadKey();
        }
</string></string>
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100