闲话动态KML
2010-12-21 16:06 MichaelYin 阅读(2499) 评论(4) 编辑 收藏 举报最近在Google Map开发中开发中用到了动态生成KML在地图中动态显示数据,下面来简单的把其中的知识点讲一下。
KML是一种采用XML 语法与格式的语言,它被用来描述地理信息,如点,线,多边形等等,可以被Google map和Google Earth等软件识别并显示。我们可以在Google Earth把我们感兴趣的一些地点标识出来,然后生成KML文件,通过分享这个文件来让别人在Google map或者google earth中看到我们标注的信息。下面是一个简单的KML文件。
<?xml version="1.0" encoding="UTF-8"?> <kml xmlns="http://www.opengis.net/kml/2.2"> <Placemark> <name>Simple placemark</name> <description>Attached to the ground. Intelligently places itself at the height of the underlying terrain.</description> <Point> <coordinates>-122.0822035425683,37.42228990140251,0</coordinates> </Point> </Placemark> </kml>
Placemark标识地图上的标记,name和description是名字和描述,coordinates是具体的经纬度,这只是一个很简单的KML文件,具体的KML标记可以去KML Reference查看Google的官方文档。
Google map支持将KML文件读取将数据进行转换后显示在Map上,由于KML文件必须是外网可以访问的,而开发调试时在本机上完成,所以这里采用了一个折中的办法,在程序中先生成kml文件,然后将生成的kml文件上传到服务器,然后将相应的url改成kml文件的地址。在这里还需要注意的是有些服务器是默认是不支持kml文件的,所以我们需要对kml文件进行注册。
在项目里面新建了一个ashx,在ProcessRequest方法里面生成KML文件,在这里生成的模型采用的是流模型。贴出部分代码
context.Response.Clear(); context.Response.ContentType = "text/xml"; context.Response.Charset = "utf-8"; context.Response.AddHeader("Content-Disposition", "attachment; filename=" + "Test.kml"); using (XmlTextWriter data = new XmlTextWriter(context.Response.OutputStream, System.Text.Encoding.UTF8)) { //设置输出的缩进 data.Formatting = Formatting.Indented; data.WriteStartDocument(); data.WriteStartElement("kml"); data.WriteAttributeString("xmlns", "http://www.opengis.net/kml/2.2"); data.WriteStartElement("Document"); data.WriteElementString("name", "name"); data.WriteElementString("description", "description");
生成部分和一般的生成XML文件类似,没有太多需要注意的地方。
Google map读取KML文件后会在地图上显示出来,但是到这里的时候我遇到了一个问题,由于Google map采用了缓存,我修改了KML文件点击页面进行刷新似乎数据还是刚才的数据,而没有读取最新的kml来生成地图,而这个缓存我自己并不能控制,找了一下,园子里好像也没有人提到类似问题,后来在Google 上搜到了一个管用的方法。在脚本中请求KML的url后面跟上一个随机数,比如像这样
var mykmlurl = 'http://********/files/Test.kml?key=' + Math.random();
这样每次都是读取的最新的数据了.
加载kml数据后,地图为了显示所有的kml中的数据,原先设置的center和zoom会失效,这时通过设置KmlLayer的preserveViewport可以解决这个问题。
参考资料
How to Dynamically refresh / reload a KML layer in OpenLayers.