Search code examples
c#xmlkmlgmap.net

Reading kml file to get coordinates in c#


Okay, so I've been working on reading in a kml file that contains the coordinates of the boundary of every county/city in America. However, I've ran into some problems. Particularly, how to get the value of the NextNode and what to do when there is another element tag in the middle of an element's value.

Here is what the kml file looks like:

<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document id="root_doc">
<Schema name="gadm36_USA_2" id="gadm36_USA_2">
    <SimpleField name="NAME_0" type="string"></SimpleField>
    <SimpleField name="NAME_1" type="string"></SimpleField>
    <SimpleField name="NAME_2" type="string"></SimpleField>
</Schema>
<Folder><name>gadm36_USA_2</name>
  <Placemark>
    <Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
    <ExtendedData><SchemaData schemaUrl="#gadm36_USA_2">
        <SimpleData name="NAME_0">United States</SimpleData>
        <SimpleData name="NAME_1">Alabama</SimpleData>
        <SimpleData name="NAME_2">Autauga</SimpleData>
    </SchemaData></ExtendedData>
      <MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>-86.8189620971679,32.3402709960939 -86.8108367919922,32.3471298217775 -86.8097915649414,32.3535118103028 -86.8103485107422,32.3585205078126 -86.8158340454101,32.3703498840333 -86.8239974975586,32.3785285949708 -86.8310775756835,32.3839797973634 -86.83544921875,32.3912506103515 -86.8419876098633,32.3980712890626 -86.8452758789062,32.4044418334961 -86.8458633422851,32.4140090942383 -86.8447875976562,32.4167404174805 </coordinates></LinearRing></outerBoundaryIs></Polygon><Polygon><outerBoundaryIs><LinearRing><coordinates>-86.8426208496093,32.4181213378907 -86.8361129760742,32.4204101562501 -86.8296127319336,32.4227104187012 -86.8274383544922,32.4240798950195 -86.8263626098633,32.4259109497071 -86.8280029296875,32.4277305603028 -86.8307189941406,32.4295387268066 </coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry>
  </Placemark>

Note, this is not an actual example where these random element tags appear in the middle of the coordinates, the counties that have them typically have a massive coordinate list and from my experience if i go through the kml file and only use the values before the first element tags, it appears to map out the correct county boundaries

List<string> locationList = new List<string>();
var doc = XDocument.Load("gadm36_USA1.kml");
XNamespace ns = "http://www.opengis.net/kml/2.2";
var result = doc.Root.Descendants(ns + "Placemark");
foreach (XElement xmlInfo in result)
{
   var region = xmlInfo.Element(ns + "ExtendedData").Element(ns + "SchemaData").Value;
   //var country = region.Element(ns + "SimpleData").Value;
   //var state = region.Element(ns + "SimpleData");
   //var cityCounty = region.Element(ns + "SimpleData");
   locationList = xmlInfo.Element(ns + "MultiGeometry").Value.Split(' ').ToList();
   CountyCoordinates.Add(region, locationList);
}

So when i get to the variable "region", it groups all the element values together. For example it will say "United StatesAutaugaAlabama".

As for the coordinates, since there are these random element tags in the middle of the coordinate values, when i split the coordinates by " ", it gets screwed up when it hits these random element tags. (when it gets to that text in the middle of the coordinates the split will return '-86, 32 -86', instead of just '-86, 32') So, I'm essentially looking for help on how to read in the country, state, and county separately and how to properly read in the coordinates despite these random element tags.


Solution

  • I just tested with following a get results :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.Xml.Linq;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XDocument doc = XDocument.Load(FILENAME);
                XElement root = doc.Root;
                XNamespace ns = root.GetDefaultNamespace();
    
                List<XElement> simpleFields;
    
                List<XElement> extendedDatas = doc.Descendants(ns + "ExtendedData").ToList(); 
    
                foreach(XElement extendedData in extendedDatas)
                {
                    simpleFields = extendedData.Descendants(ns + "SimpleData").ToList(); 
                } 
            }
        }
    }