2

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

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

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

代码

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>

4

2 回答 2

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,然后在将它们拆分为行字符串后遍历坐标。

于 2013-03-15T10:56:13.767 回答
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();
于 2013-03-15T18:57:46.757 回答