none
c# knowing where/how to put a foreach loop while writing kml files RRS feed

  • Question

  • Hi -

    I figured out how to write a KML file using static information. I can use variables if I only am writing one location in my KML file.

    Not sure how best to describe this:

    I need help of taking the following code and knowing where to put a foreach loop to iterate through the information from a file. I keep getting errors because of the placement of ")"'. 

    Here is my code using static values. I want to pull from a file with a foreach loop. My trouble is the placement of ")" in and outside of the foreach loop. 

    using System;
    using System.IO;
    using System.Xml.Linq;
    
    namespace XML_Test_03
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("\n");
    
                XNamespace n = "http://earth.google.com/kml/2.2";
                XElement kmldoc = new XElement(n + "kml", new XElement(n + "Document",
                    new XElement(n + "name", "HeatMap01"),
    
                    new XElement(n + "Placemark", new XAttribute("id", "1"),
                    new XElement(n + "name", "Baltimore, MD"),
                    new XElement(n + "description", "Desciption of Baltimore"),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", "-76.61218,39.29038,0"))),
    
                    new XElement(n + "Placemark", new XAttribute("id", "2"),
                    new XElement(n + "name", "Washington DC"),
                    new XElement(n + "description", "Desciption of Washington DC"),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", "-77.03687,38.90719,0"))),
    
                    new XElement(n + "Placemark", new XAttribute("id", "3"),
                    new XElement(n + "name", "Annapolis, MD"),
                    new XElement(n + "description", "Desciption of Annapolis, MD"),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", "-76.4921829,38.9784453,0"))),
    
                    new XElement(n + "Placemark", new XAttribute("id", "3"),
                    new XElement(n + "name", "Mt. Airy, MD"),
                    new XElement(n + "description", "Desciption of Mt. Airy, MD"),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", "-77.154704,39.3762145,0")))));
    
                Console.WriteLine("\n" + kmldoc);
    
                File.WriteAllText(@"c:\tmp\test-kml03.kml", kmldoc.ToString());
    
            }
        }
    }
    

    Thank you -
    Keith

    Sunday, January 26, 2020 4:43 PM

Answers

  • Without using the XElements I got this to work - I would love to figure out the XElement - but I am glad this works.

    using System;
    using System.IO;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    
    namespace kml_foreach_02
    {
        class Program
        {
            static void Main(string[] args)
            {
                var jsonf1 = (@"C:\tmp\test_fields.json");
                int count = 0;
                int count_me = 0;
    
                string jsonF = System.IO.File.ReadAllText(jsonf1);
                var RootObjects = JsonConvert.DeserializeObject<List<ipdata_parser>>(jsonF);
    
                Console.WriteLine("<kml xmlns=\"http://earth.google.com/kml/2.2\">");
                Console.WriteLine("  <Document>");
                Console.WriteLine("    <name>HeatMap01</name>");
    
                //string id = "1";
                //string ip = "1.1.1.1";
                //string desc = "United States";
                //string cords = "-76.61218,39.29038,0";
    
                //IList<string> list = new List<string>(ip.Split(new string[] { "," }, StringSplitOptions.None));
    
                foreach (var rootObject in RootObjects)
                {
                    count++;
                    Console.WriteLine("    <Placemark id =\"" + count + "\">");
                    Console.WriteLine("      <name>" + rootObject.ip + "</name>");
                    Console.WriteLine("      <description>" + rootObject.country_name + "</description>");
                    Console.WriteLine("      <Point>");
                    Console.WriteLine("        <coordinates>" + rootObject.longitude + "," + rootObject.latitude + "," + 0 + "</coordinates>");
                    Console.WriteLine("      </Point>");
                    Console.WriteLine("    </Placemark>");
                }           
    
                Console.WriteLine("  </Document>");
                Console.WriteLine("</kml>");
    
                using (StreamWriter sw = File.CreateText(@"c:\tmp\write.kml"))
                {
                    sw.WriteLine("<kml xmlns=\"http://earth.google.com/kml/2.2\">");
                    sw.WriteLine("  <Document>");
                    sw.WriteLine("    <name>HeatMap01</name>");
    
                    foreach (var rootObject in RootObjects)
                    {
                        count_me++;
                        sw.WriteLine("    <Placemark id =\"" + count + "\">");
                        sw.WriteLine("      <name>" + rootObject.ip + "</name>");
                        sw.WriteLine("      <description>" + rootObject.country_name + "</description>");
                        sw.WriteLine("      <Point>");
                        sw.WriteLine("        <coordinates>" + rootObject.longitude + "," + rootObject.latitude + "," + 0 + "</coordinates>");
                        sw.WriteLine("      </Point>");
                        sw.WriteLine("    </Placemark>");
                    }
    
                    sw.WriteLine("  </Document>");
                    sw.WriteLine("</kml>");
                }
    
            }
    
            public class ipdata_parser
            {
                public string ip { get; set; }
                public string is_eu { get; set; }
                public string city { get; set; }
                public string region { get; set; }
                public string region_code { get; set; }
                public string country_name { get; set; }
                public string continent_code { get; set; }
                public string reporter { get; set; }
                public string latitude { get; set; }
                public string longitude { get; set; }
                public string asn { get; set; }
                public string organisation { get; set; }
                public string postal { get; set; }
                public string calling_code { get; set; }
                public string flag { get; set; }
                public string emoji_flag { get; set; }
                public string emoji_unicode { get; set; }
                public string carrier { get; set; }
                public string languages { get; set; }
                public string currency { get; set; }
                public string time_zone { get; set; }
                public string threat { get; set; }
                public string count { get; set; }
            }
        }
    }
    

    • Marked as answer by studysession Monday, January 27, 2020 3:04 AM
    Sunday, January 26, 2020 9:36 PM

All replies


  • I figured out how to write a KML file using static information. I can use variables if I only am writing one location in my KML file.


    I need help of taking the following code and knowing where to put a foreach loop to iterate through the information from a file. I keep getting errors because of the placement of ")"'. 

    Here is my code using static values. I want to pull from a file with a foreach loop. My trouble is the placement of ")" in and outside of the foreach loop. 

    If you show us the code you have tried using a loop we might be able to see
    something minor that will fix the problem. As it is, it looks like you just want
    someone to write the code for you. You'll learn more about programming
    in C# by using your own code as much as possible.

    Showing the format of the file you are trying to read and some of its contents
    will also reduce wasted time and effort.

    - Wayne

    Sunday, January 26, 2020 6:09 PM
  • Yes - sorry - still trying to figure out what is needed when I post a question. Here is the test code that I cannot get working and the JSON file I am pulling attributes from.

    Test file with the foreach loop but cannot figure out:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml.Linq;
    using Newtonsoft.Json;
    
    namespace KML_test04
    {
        class Program
        {
            static void Main(string[] args)
            {
                var file1Fields = (@"C:\tmp\test_fields.json");
                int count = 0;
    
                string jsonF = System.IO.File.ReadAllText(file1Fields);
                var RootObjects = JsonConvert.DeserializeObject<List<ipdata_parser>>(jsonF);
    
                XNamespace n = "http://earth.google.com/kml/2.2";
                XElement kmldoc = new XElement(n + "kml", new XElement(n + "Document",
                    new XElement(n + "name", "HeatMap01")));
    
                foreach (var rootObject in RootObjects)
                {
                    count++;
                    
                    new XElement(n + "Placemark", new XAttribute("id", count),
                    new XElement(n + "name", rootObject.ip),
                    new XElement(n + "description", rootObject.country_name),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", rootObject.longitude + "," + rootObject.latitude,0)));
                }
    
                Console.WriteLine(kmldoc);            
    
            }
    
            public class ipdata_parser
            {
                public string ip { get; set; }
                public string is_eu { get; set; }
                public string city { get; set; }
                public string region { get; set; }
                public string region_code { get; set; }
                public string country_name { get; set; }
                public string continent_code { get; set; }
                public string reporter { get; set; }
                public string latitude { get; set; }
                public string longitude { get; set; }
                public string asn { get; set; }
                public string organisation { get; set; }
                public string postal { get; set; }
                public string calling_code { get; set; }
                public string flag { get; set; }
                public string emoji_flag { get; set; }
                public string emoji_unicode { get; set; }
                public string carrier { get; set; }
                public string languages { get; set; }
                public string currency { get; set; }
                public string time_zone { get; set; }
                public string threat { get; set; }
                public string count { get; set; }
            }
        }
    }

    I used static values to create this - However this is the expect output format:

    <kml xmlns="http://earth.google.com/kml/2.2">
      <Document>
        <name>HeatMap01</name>
        <Placemark id="1">
          <name>Baltimore, MD</name>
          <description>Desciption of Baltimore</description>
          <Point>
            <coordinates>-76.61218,39.29038,0</coordinates>
          </Point>
        </Placemark>
        <Placemark id="2">
          <name>Washington DC</name>
          <description>Desciption of Washington DC</description>
          <Point>
            <coordinates>-77.03687,38.90719,0</coordinates>
          </Point>
        </Placemark>
        <Placemark id="3">
          <name>Annapolis, MD</name>
          <description>Desciption of Annapolis, MD</description>
          <Point>
            <coordinates>-76.4921829,38.9784453,0</coordinates>
          </Point>
        </Placemark>
        <Placemark id="3">
          <name>Mt. Airy, MD</name>
          <description>Desciption of Mt. Airy, MD</description>
          <Point>
            <coordinates>-77.154704,39.3762145,0</coordinates>
          </Point>
        </Placemark>
      </Document>
    </kml>

    Thank you - Keith






    Sunday, January 26, 2020 6:24 PM
  • It has 4 entries like this but wont let me post them all to the forum without an error. The file I will ultimately use has hundreds of entries.

    [
      {
        "ip": "1.1.1.1",
        "latitude": -33.494,
        "longitude": 143.2104
      },
      {
        "ip": "2.2.2.2",
        "latitude": 48.8582,
        "longitude": 2.3387
      },
      {
        "ip": "8.8.8.8",
        "latitude": 37.751,
        "longitude": -97.822
      }
    ]

    Sunday, January 26, 2020 6:29 PM
  • It has 4 entries like this but wont let me post them all to the forum without an error. 


    When you want to share a data file (or source code, etc.) with participants
    in these forums, you can post the file(s) on a file sharing service such as
    Microsoft's Onedrive. The latter is free and you can use the same userid and 
    password that you use for these forums. You can post a link to the file in a
    message here so that those who are interested can retrieve it for examination
    and testing, etc. Of course you can always delete that file or invalidate the 
    sharing link whenever you want later.

    - Wayne

    Sunday, January 26, 2020 6:47 PM
  • Hope this works -
    Here is a link to the JSON file:

    my json file

    Thank you - Keith


    Sunday, January 26, 2020 7:07 PM


  • Test file with the foreach loop but cannot figure out:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Xml.Linq;
    using Newtonsoft.Json;
    
    namespace KML_test04
    {
        class Program
        {
            static void Main(string[] args)
            {
                var file1Fields = (@"C:\tmp\test_fields.json");
                int count = 0;
    
                string jsonF = System.IO.File.ReadAllText(file1Fields);
                var RootObjects = JsonConvert.DeserializeObject<List<ipdata_parser>>(jsonF);
    
                XNamespace n = "http://earth.google.com/kml/2.2";
                XElement kmldoc = new XElement(n + "kml", new XElement(n + "Document",
                    new XElement(n + "name", "HeatMap01")));
    
                foreach (var rootObject in RootObjects)
                {
                    count++;
                    
                    new XElement(n + "Placemark", new XAttribute("id", count),
                    new XElement(n + "name", rootObject.ip),
                    new XElement(n + "description", rootObject.country_name),
                    new XElement(n + "Point",
                    new XElement(n + "coordinates", rootObject.longitude + "," + rootObject.latitude,0)));
                }
    
     

    It's fairly clear that the way you were trying to do it will not work as
    there is no document context for the new XElements being created.

    As I don't have Newtonsoft.Json installed and have no need nor inclination to
    do so, or to study the API for it, I'm not well positioned to suggest code
    changes using it. Someone who is using or has used that package will be best
    equipped to give a quick and certain code example to do what you want. In this
    case and context since you are following a code suggestion made in your earlier
    thread, Timon may be the one most likely to be able to offer corrected code
    based on actual past experience. I expect that will be forthcoming in due course.

    - Wayne

    Sunday, January 26, 2020 8:18 PM
  • Still trying - The Point element is not correct but this is really close to what I am looking for:

    using System;
    using System.Collections.Generic;
    using System.Xml.Linq;
    //using Newtonsoft.Json;
    
    namespace kml_foreach_01
    {
        class Program
        {
            static void Main(string[] args)
            {
                //string tags = "tag1,tag2,tag3,tag4";
                string ip = "1.1.1.1";
                string desc = "United States";
                string cords = "-76.61218,39.29038,0";
    
                IList<string> list = new List<string>(ip.Split(new string[] { "," }, StringSplitOptions.None));
                XElement elem = new XElement("Document");
    
                foreach (var item in list)
                {
                    XElement childElement = new XElement("Placemark", new XAttribute("id", "1"),
                    new XElement("name", ip),
                    new XElement("description", desc),
                    new XElement("Point"),
                    new XElement("coordinates", cords));
    
                    //XAttribute attribute = new XAttribute("ref", item);
                    //childElement.Add(attribute);
    
                    elem.Add(childElement);
                }
                Console.WriteLine(elem);
            }
        }
    }
    
    
    

    Sunday, January 26, 2020 9:04 PM
  • Without using the XElements I got this to work - I would love to figure out the XElement - but I am glad this works.

    using System;
    using System.IO;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    
    namespace kml_foreach_02
    {
        class Program
        {
            static void Main(string[] args)
            {
                var jsonf1 = (@"C:\tmp\test_fields.json");
                int count = 0;
                int count_me = 0;
    
                string jsonF = System.IO.File.ReadAllText(jsonf1);
                var RootObjects = JsonConvert.DeserializeObject<List<ipdata_parser>>(jsonF);
    
                Console.WriteLine("<kml xmlns=\"http://earth.google.com/kml/2.2\">");
                Console.WriteLine("  <Document>");
                Console.WriteLine("    <name>HeatMap01</name>");
    
                //string id = "1";
                //string ip = "1.1.1.1";
                //string desc = "United States";
                //string cords = "-76.61218,39.29038,0";
    
                //IList<string> list = new List<string>(ip.Split(new string[] { "," }, StringSplitOptions.None));
    
                foreach (var rootObject in RootObjects)
                {
                    count++;
                    Console.WriteLine("    <Placemark id =\"" + count + "\">");
                    Console.WriteLine("      <name>" + rootObject.ip + "</name>");
                    Console.WriteLine("      <description>" + rootObject.country_name + "</description>");
                    Console.WriteLine("      <Point>");
                    Console.WriteLine("        <coordinates>" + rootObject.longitude + "," + rootObject.latitude + "," + 0 + "</coordinates>");
                    Console.WriteLine("      </Point>");
                    Console.WriteLine("    </Placemark>");
                }           
    
                Console.WriteLine("  </Document>");
                Console.WriteLine("</kml>");
    
                using (StreamWriter sw = File.CreateText(@"c:\tmp\write.kml"))
                {
                    sw.WriteLine("<kml xmlns=\"http://earth.google.com/kml/2.2\">");
                    sw.WriteLine("  <Document>");
                    sw.WriteLine("    <name>HeatMap01</name>");
    
                    foreach (var rootObject in RootObjects)
                    {
                        count_me++;
                        sw.WriteLine("    <Placemark id =\"" + count + "\">");
                        sw.WriteLine("      <name>" + rootObject.ip + "</name>");
                        sw.WriteLine("      <description>" + rootObject.country_name + "</description>");
                        sw.WriteLine("      <Point>");
                        sw.WriteLine("        <coordinates>" + rootObject.longitude + "," + rootObject.latitude + "," + 0 + "</coordinates>");
                        sw.WriteLine("      </Point>");
                        sw.WriteLine("    </Placemark>");
                    }
    
                    sw.WriteLine("  </Document>");
                    sw.WriteLine("</kml>");
                }
    
            }
    
            public class ipdata_parser
            {
                public string ip { get; set; }
                public string is_eu { get; set; }
                public string city { get; set; }
                public string region { get; set; }
                public string region_code { get; set; }
                public string country_name { get; set; }
                public string continent_code { get; set; }
                public string reporter { get; set; }
                public string latitude { get; set; }
                public string longitude { get; set; }
                public string asn { get; set; }
                public string organisation { get; set; }
                public string postal { get; set; }
                public string calling_code { get; set; }
                public string flag { get; set; }
                public string emoji_flag { get; set; }
                public string emoji_unicode { get; set; }
                public string carrier { get; set; }
                public string languages { get; set; }
                public string currency { get; set; }
                public string time_zone { get; set; }
                public string threat { get; set; }
                public string count { get; set; }
            }
        }
    }
    

    • Marked as answer by studysession Monday, January 27, 2020 3:04 AM
    Sunday, January 26, 2020 9:36 PM
  • Hi studysession,

    I am glad you have got your solution. We appreciated you shared us your solution. And we also hope you can mark it as an answer. By marking a post as Answered, you help others find the answer faster.

    Regards,

    Kyle


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, January 27, 2020 2:44 AM