2013-03-15 81 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();