2013-03-15 148 views
1

我想在c#中创建一个kml文件。现在我有两个问题:使用xml元素创建kml文件

  1. 什么是为了在我的KML文件下面的一行添加KML元素在XML文件中的synatx?

    <kml xmlns="http://www.opengis.net/kml/2.2"> 
    
  2. 我有一个点,我想形成一个线串的数组。我想如何在kml文件的xml中填充坐标元素?以下是我的代码到目前为止。

CODE

public void MakeKmlFile(string line) 
{ 
    CoordinateCollection coordinates = new CoordinateCollection(); 

    char[] delimiterLine = { '|' }; 
    char[] delimiterPoint = { ',' }; 
    string[] route = line.Split(delimiterLine); 

    foreach (string point in route) 
    { 
     string[] route_point = line.Split(delimiterPoint); 
     double lat = double.Parse(route_point[1]); 
     double lon = double.Parse(route_point[0]); 
     coordinates.Add(new Vector(lat, lon)); 
    } 

    XmlTextWriter writer = new XmlTextWriter("route.xml", System.Text.Encoding.UTF8); 
    writer.Formatting = Formatting.Indented; 
    writer.WriteStartElement("Document"); 
    writer.WriteStartElement("Folder"); 
    writer.WriteStartElement("name"); 
    writer.WriteString("route"); 
    writer.WriteEndElement(); 
    writer.WriteStartElement("Placemark"); 
    writer.WriteStartElement("Style"); 
    writer.WriteStartElement("LineStyle"); 
    writer.WriteStartElement("color"); 
    writer.WriteString("ff0000ff"); 
    writer.WriteEndElement(); 
    writer.WriteEndElement(); 
    writer.WriteStartElement("PolyStyle"); 
    writer.WriteStartElement("fill"); 
    writer.WriteString("2"); 
    writer.WriteEndElement(); 
    writer.WriteEndElement(); 
    writer.WriteEndElement(); 
    writer.WriteStartElement("LineString"); 
    writer.WriteStartElement("coordinates"); 

这是结果我得到:

<?xml version="1.0" encoding="utf-8"?> 
<kml xmlns="http://www.opengis.net/kml/2.2"> 
    <Document> 
    <Name>Points.kml</Name> 
    <Placemark /> 
    <Placemark /> 
    <Placemark /> 
    <Placemark /> 
    <Placemark /> 
    </Document> 

+0

注意PolyStyle填充元件具有1或0 => “2” 是无效的值。 – JasonM1 2013-03-15 19:13:56

回答

3

您可以创建KML文件就像一个正常的XML文档

XmlDocument xDoc = new XmlDocument(); 
    XmlDeclaration xDec = xDoc.CreateXmlDeclaration("1.0", "utf-8", null); 

    XmlElement rootNode = xDoc.CreateElement("kml"); 
    rootNode.SetAttribute("xmlns", @"http://www.opengis.net/kml/2.2"); 
    xDoc.InsertBefore(xDec, xDoc.DocumentElement); 
    xDoc.AppendChild(rootNode); 
    XmlElement docNode = xDoc.CreateElement("Document"); 
    rootNode.AppendChild(docNode); 

    XmlElement nameNodeMain = xDoc.CreateElement("Name"); 
    XmlText nameTextMain = xDoc.CreateTextNode("Points.kml"); 
    docNode.AppendChild(nameNodeMain); 
    nameNodeMain.AppendChild(nameTextMain); 

,设置了基本结构为您的文档,那么所有你需要做的就是添加每个地标(这最好是通过一个循环完成)

char[] delimiterLine = { '|' }; 
    char[] delimiterPoint = { ',' }; 
    string[] places = line.Split(delimiterLine); 
    for (int i = 0; i < places.length; i++) 
     { 
      string[] placeMark = places[i].split(delimiterPoint); 
      XmlElement placeNode = xDoc.CreateElement("Placemark"); 
      docNode.AppendChild(placeNode); 

      XmlElement nameNode = xDoc.CreateElement("Name"); 
      XmlText nameText = xDoc.CreateTextNode(placeMark[0]); 
      placeNode.AppendChild(nameNode); 
      nameNode.AppendChild(nameText); 

      XmlElement descNode = xDoc.CreateElement("Description"); 
      XmlText descText = xDoc.CreateTextNode(placeMark[1]); 
      placeNode.AppendChild(descNode); 
      descNode.AppendChild(descText); 

      XmlElement pointNode = xDoc.CreateElement("Point"); 
      placeNode.AppendChild(pointNode); 

      XmlElement coordNode = xDoc.CreateElement("coordinates"); 
      XmlText coordText = xDoc.CreateTextNode(string.Format("{0},{1}", placeMark[2], placeMark[3])); 
      pointNode.AppendChild(coordNode); 
      coordNode.AppendChild(coordText); 
     } 
     return xDoc; 

我还没有和路线]在KML工作过但我怀疑的代码做这将是沿着以下线路:

XmlDocument xDoc = new XmlDocument(); 
    XmlDeclaration xDec = xDoc.CreateXmlDeclaration("1.0", "utf-8", null); 

    XmlElement rootNode = xDoc.CreateElement("kml"); 
    rootNode.SetAttribute("xmlns", @"http://www.opengis.net/kml/2.2"); 
    xDoc.InsertBefore(xDec, xDoc.DocumentElement); 
    xDoc.AppendChild(rootNode); 
    XmlElement docNode = xDoc.CreateElement("Document"); 
    rootNode.AppendChild(docNode); 

    XmlElement nameNodeMain = xDoc.CreateElement("Name"); 
    XmlText nameTextMain = xDoc.CreateTextNode("Points.kml"); 
    docNode.AppendChild(nameNodeMain); 
    nameNodeMain.AppendChild(nameTextMain); 

XmlElement placeNode = xDoc.CreateElement("Placemark"); 
docNode.AppendChild(placeNode); 

XmlElement nameNode = xDoc.CreateElement("Name"); 
XmlText nameText = xDoc.CreateTextNode("Test line"); 
placeNode.AppendChild(nameNode); 
nameNode.AppendChild(nameText); 

XmlElement lineStringNode = xDoc.CreateElement("LineString"); 
placeNode.AppendChild(lineStringNode); 

XmlElement coordNode = xDoc.CreateElement("coordinates"); 

char[] delimiterLine = { '|' }; 
    char[] delimiterPoint = { ',' }; 
    string[] places = line.Split(delimiterLine); 
    for (int i = 0; i < places.length; i++) 
    { 
    string[] placeMark = places[i].split(delimiterPoint); 

    XmlText coordText = xDoc.CreateTextNode(string.Format("{0},{1}", placeMark[0], placeMark[1])); 
    pointNode.AppendChild(coordNode); 
    } 


coordNode.AppendChild(coordText); 

xDoc.Save("./KML/"); 

它主要涉及走动我以前的代码,并创造了每一个KML文件,然后在需要的主要内容单一的XmlElement迭代坐标在线串中分割它们之后。

+0

感谢您的回复。因为我想从一系列点中的线串元素结束,我怎样才能在每个循环的地标中去处理呢? @Donald Dunlop – 2013-03-15 11:01:30

+1

我假设你的线串的格式是“place | place | place”,每个“place”都是由place =“Name,Description,Latitude,Longitude”组成的。你的数组接收到Split(“|”),然后做一个for循环遍历该数组,并使用“,”字符分割每个元素。 – 2013-03-15 11:31:23

+0

我已经将foreach循环更改为for循环,该循环利用了线串的分割 – 2013-03-15 11:38:16

0

最直接的解决方案是标记路由(线串)并将坐标附加到字符串缓冲区中,然后将其作为值输出。不需要创建CoordinateCollection和单独的Vector对象。

注意:为了成为有效的KML,您必须首先输出经度值,然后用逗号(,)分隔纬度,在lon-lat值之间没有空白,并且空白必须将每个lon-lat对可选地与高度值。

以下是使用System.Xml.XmlTextWriter类C#溶液:

XmlTextWriter writer = new XmlTextWriter(...); 
    writer.WriteStartElement("kml", "http://www.opengis.net/kml/2.2"); 
    ... 
    writer.WriteStartElement("LineString"); 
    StringBuilder sb = new StringBuilder(); 
    foreach (string point in route) 
    { 
     string[] route_point = point.Split(delimiterPoint); 
     if (route_point.Length >= 2) 
     { 
      double lon = double.Parse(route_point[0]); 
      double lat = double.Parse(route_point[1]); 
      sb.Append(' ').Append(lon).Append(',').Append(lat); 
      // coordinates.Add(new Vector(lat, lon)); 
     } 
    } 
    writer.WriteStartElement("coordinates"); 
    writer.WriteValue(sb.ToString()); 
    writer.WriteEndElement(); // end coordinates 
    writer.WriteEndElement(); // end LineString 
    writer.WriteEndElement(); // end Placemark 
    ... 
    writer.Close();