您的位置:首页 > 编程语言 > C#

用C#生成KML路径文件(上篇)

2015-08-08 17:47 615 查看
接前面一篇日志《在google地图上显示路线》,我们觉得替换官方KML文件中的坐标值的做法太low了,因此在这篇文章会介绍如何用C#自动生成google map engine所支持的kml文件。

让我们再来回顾一下上一篇所提到的用于生成路径的官方KML文件。为了方便阅读,下面的版本是缩减过后的。

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>Paths</name>
<description>Examples of paths.</description>
<Style id="yellowLineGreenPoly">
<LineStyle>
<color>7f00ffff</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7f00ff00</color>
</PolyStyle>
</Style>
<Placemark>
<name>Absolute Extruded</name>
<description>Transparent green wall with yellow outlines</description>
<styleUrl>#yellowLineGreenPoly</styleUrl>
<LineString>
<extrude>1</extrude>
<tessellate>1</tessellate>
<altitudeMode>absolute</altitudeMode>
<coordinates> -112.2550785337791,36.07954952145647,2357
-112.2549277039738,36.08117083492122,2357
</coordinates>
</LineString>
</Placemark>
</Document>
</kml>

将上面的kml文件用KML Notepad打开可以看到该文件中所有节点的树形关系,如下图



在上图中,我们可以很明显的看到这个文件中所有元素相互之间的关系。我们将以这种关系为基础,由下往上依次建立对应的类,首先是LineString类,该类包含extrude,tessellate,altitudeMode,以及coordinates四个元素,其中coordinates中将会存放路径的一系列坐标值:

public class KmlLineString
{
public string extrude { get; set; }

public string tessellate{get;set;}

public string altitudeMode { get; set; }

private string _coordinates;

public string coordinates
{
get
{
return _coordinates;
}
set
{
_coordinates=value;
}
}

// constructor
public KmlLineString()
{
}

public KmlLineString(KmlLine line)
{
extrude = "1";
altitudeMode = "absolute";
tessellate = "1";
_coordinates = line.ToString();
}

public KmlLineString(string tessel, KmlLine line)
{
extrude = "1";
altitudeMode = "absolute";
tessellate = tessel;
_coordinates = line.ToString();
}
}


注意到上面的代码中实际上还包含另外一个KmlLine类,而Kml类依赖于另一个KmlPoint类,因为直线是由一系列的点所组成。其代码如下:

public class KmlLine
{
private List<KmlPoint> pointList;

public KmlLine()
{
pointList = new List<KmlPoint>();
}

public void Add(KmlPoint point)
{
pointList.Add(point);
}

public override string ToString()
{
string rtn = string.Empty;
foreach (KmlPoint point in pointList)
rtn += point.ToString() + " ";
return rtn;
}

public class KmlPoint
{
public double B;
public double L;
public double H;

public KmlPoint()
{
}

public KmlPoint(double b, double l, double h)
{
B = b;
L = l;
H = h;
}

public override string ToString()
{
return L.ToString("F6") + "," + B.ToString("F6") + "," + H.ToString("F2");
}
}
}



接下来是Placemark类,由树形图可以看到,该类除了包含name,description,和styleUrl元素之外,还包含一个LineString类对象。代码如下:

public class KmlPlacemark
{
[XmlElement("name")]
public string Name { get; set; }

private string _description;
[XmlElement("description")]
public XmlNode Description { get; set; }

[XmlElement("styleUrl")]
public string StyleUrl { get; set; }

[XmlElement("ExtendedData")]
public string ExtendedData { get; set; }

[XmlElement("LineString")]
public KmlLineString LineString { get; set; }
}
到这里我们已经可以很轻松地写出其他类的代码了,如下:
public class KmlStyle
{
public readonly static string[,] styleTable ={
{"green","7fFFFF00","2"},
{"red",  "7f0000FF","2"},
{"blue", "7fFF0000","2"},
{"black","50000014","2"}
};

[XmlAttribute("id")]
public string ID { get; set; }

[XmlElement("LineStyle")]
public kmlLineStyle lineStyle{get;set;}

// constructor
public KmlStyle()
{
}

public KmlStyle(string id, string color, string width)
{
ID=id;
lineStyle=new kmlLineStyle(color,width);
}

public static List<KmlStyle> getStyleList()
{
List<KmlStyle> rtn = new List<KmlStyle>();
for (int i = 0; i < styleTable.GetLength(0); i++)
{
KmlStyle style= new KmlStyle(styleTable[i,0], styleTable[i,1], styleTable[i,2]);
rtn.Add(style);
}
return rtn;
}

// inner class
public class kmlLineStyle
{
[XmlElement("color")]
public string Color { get; set; }

[XmlElement("width")]
public string Width { get; set; }

public kmlLineStyle()
{
}

public kmlLineStyle(string color, string width)
{
Color=color;
Width=width;
}
}

public class kmlPolyStyle
{
[XmlElement("color")]
public string Color { get; set; }
}
}

注意在Style类中,我们包含了一个静态的样式表,其中有自定义的红,蓝,绿,黑四种颜色。

public class KmlDocument
{
[XmlElement("name")]
public string Name { get; set; }

private string _description;
[XmlElement("description")]
public XmlNode Description{ get; set; }

[XmlElement("Style")]
public List<KmlStyle> styles { get; set; }

public KmlDocument()
{
}

public KmlDocument(string name, string description, List<KmlFolder> folderList)
{
4000
Name = name;
//Description =string.Format(@"<![CDATA[{0}]]>", description);
_description = description;
folders = folderList;
styles = KmlStyle.getStyleList();
}
}


最后一层是根元素Kml类

[XmlRoot("kml",Namespace="http://www.opengis.net/kml/2.2")]
public class Kml
{
[XmlElement("Document")]
public KmlDocument document { get; set; }
}


在定义好这些类之后,接下来,我们采用System.XML.Serialization命名空间下的XmlSerializer来生成KML文件,使用方法如下:
using (FileStream fs = new FileStream(KmlFileName, FileMode.Create, FileAccess.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8))
{
XmlSerializer serializer = new XmlSerializer(this.GetType());
serializer.Serialize(sw, this);
}
}


最后写一个简单的静态方法用于测试,该方法仅包含两个点。感兴趣的读者可以在KmlLine类中添加新的方法以显示更多的坐标值

public static void Test()
{
KmlPoint p1 = new KmlPoint(36.07954952145647, -112.2550785337791, 2357);
KmlPoint p2 = new KmlPoint(36.08117083492122, -112.2549277039738, 2357);
KmlLine lines = new KmlLine();
lines.Add(p1);
lines.Add(p2);

KmlLineString lineString = new KmlLineString(lines);
KmlPlacemark placeMark = new KmlPlacemark("nmea route", "for test", "red", lines);
KmlDocument document = new KmlDocument("20150808", "test", placeMark);
Kml kml = new Kml(document);
kml.GenerateKmlFile("test.kml");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c# kml 谷歌地图