代码改变世界

闲话动态KML

2010-12-21 16:06  MichaelYin  阅读(2470)  评论(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文件进行注册。

image

在项目里面新建了一个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.