使用xml元素创建kml文件

时间:2013-03-15 10:46:44

标签: c# xml kml

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

  1. 为了在我的kml文件中包含以下行,在xml文件中添加kml元素的synatx是什么?

    <kml xmlns="http://www.opengis.net/kml/2.2">
    
  2. 我有一个点数组,我想形成一个线串。我怎么想用kml文件填充xml中的coordinates元素?。以下是我目前的代码。

  3. 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>
    

2 个答案:

答案 0 :(得分:3)

您可以像普通的XML文档一样创建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);

为您的文档设置基本结构,然后您需要做的就是添加每个地标(这最好通过循环完成)

    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中的LineStrings,但我怀疑这样做的代码将遵循以下内容:

    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,然后在将其分割成行字符串后迭代坐标。

答案 1 :(得分: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();