在介绍动态标注前先介绍一个KML.它是GOOGLE EARTH的接口标准,后来被广泛应用,在行业里大家都遵循这个标准.这里查看KML说明.
        MAPEASY给出了象地图填加标注的方法.这段:
var marker = new Marker(coord.getPoint(), Marker.LARGE);
    alert(coord.x/1e16+":"+coord.y/1e16);
    map.addOverlay(marker);
    marker.setInfo("Hello! it's marker: <a href=\"http://www.3snews.net/\" target=\"_blank\">#" + marker.getId() + "</a>");
        但相对较简单,我们怎样把它封装成自己的组件呢
总体思路:利用任意页面从库里读取数据------>组织成KML格式输出到页面------>利用AJAX方法读到KML内容并解析-------->通过同步或异步的方式动态添加标注.
1.建一个用来组织KML文档的基类.包含KML的所有节点属性.(目前只解析了标注部分)
/**
* 解析xml的基类
*---------by zygao-----------
*  
*/


function Folder()  
{
  
    //文件夹名称
    this.name;
    //默认节点是否打开(0-1)
    this.open = 1;
    //存储Placemark对象的ArrayList
    this.placemarkList;

  
    this.getFolderName = function()
    {
  return this.name;
    }
  
    this.setFolderName = function(name)
    {
  this.name = name;
    }
  
    this.getOpen = function()
    {
  return this.open;
    }
  
    this.setOpen = function(open)
    {
  this.open = open;
    }  
  
  
    this.getPlacemarkListCount = function()
    {
  return this.placemarkList.size();
    }
  
    this.clearPlacemarkList = function()
    {
  this.placemarkList.remove();
    }
  
    this.createPlacemarkList = function()
    {
  this.placemarkList = new ArrayList();
    }
  
    this.addPlacemark = function(placemark)
    {
  this.placemarkList.add(placemark);
    }

}

/**
* 解析xml的基类
*---------by zygao-----------
*  
*/

function Placemark()  
{
    //标注的名称
    this.name = '';
    //点坐标信息(x,y,h)
    this.coordinates = '';
    //默认描述信息
    this.description =' ';
    //标注的缩放级别
    this.scale = 1.0;
    //标注的url
    this.href = '';
    //标注的高
    this.h = 0;
    //标注的宽
    this.w = 0;
    //阴影标注的url
    this.shadowhref = '';
    //阴影标注的高
    this.shadowh = 0;
    //阴影标注的宽
    this.shadoww = 0;

    this.getPlacemarkName=function()
    {
  return this.name;
    }

    this.getCoordinates=function()
    {
  return this.coordinates;
    }
  
    this.getDescription=function()
    {
  return this.description;
    }
  
    this.getScale=function()
    {
  return this.scale;
    }
  
  
    this.getHref=function()
    {
  return this.href;
    }
  
    this.getH=function()
    {
  if(this.scale)
  {
      return this.h*this.scale;
  }
  else
  {
      return this.h;
  }
    }
  
    this.getW=function()
    {
  if(this.scale)
  {
      return this.w*this.scale;
  }
  else
  {
      return this.w;
  }
    }
  
    this.getShadowHref=function()
    {
  return this.shadowhref;
    }
  
    this.getShadowH=function()
    {
  if(this.scale)
  {
      return this.shadowh*this.scale;
  }
  else
  {
      return this.shadowh;
  }
    }
  
    this.getShadowW=function()
    {
  if(this.scale)
  {
      return this.shadoww*this.scale;
  }
  else
  {
      return this.shadoww;
  }
    }
  
    this.setName = function(name)
    {
  this.name = name;
    }
  
    this.setDescription = function(description)
    {
  this.description = description;
    }
  
    this.setCoordinates = function(coordinates)
    {
  this.coordinates = coordinates;
    }
  
    this.setScale = function(scale)
    {
  if(scale=='')
  {
      this.scale = 1.0;
  }
  else
  {
      this.scale = scale;
  }
    }
  
    this.setHref = function(href)
    {
  if(href=='')
  {
      this.href = imgBaseDir + "marker_large.png";
  }
  else
  {
      this.href = href;
  }
    }
  
    this.setH = function(h)
    {
  if(h=='')
  {
      this.h = 34;
  }
  else
  {
      this.h = h;
  }
  
    }
  
    this.setW = function(w)
    {
  if(w=='')
  {
      this.w = 20;
  }
  else
  {
      this.w = w;
  }
  
    }
  
    this.setShadowHref = function(shadowhref)
    {
  if(shadowhref==''||shadowhref==null)
  {
      this.shadowhref = imgBaseDir + "marker_large_shadow.png";
  }
  else
  {
      this.shadowhref = shadowhref;
  }
    }
  
    this.setShadowH = function(shadowh)
    {
  if(shadowh==''||shadowh==null)
  {
      this.shadowh = 37;
  }
  else
  {
      this.shadowh = shadowh;
  }
  
    }
  
    this.setShadowW = function(shadoww)
    {
  if(shadoww==''||shadoww==null)
  {
      this.shadoww = 34;
  }
  else
  {
      this.shadoww = shadoww;
  }
  
    }
  


}
这里定义了两个类,一个是Folder,一个是Placemark.
对这两个类有什么不明白的地方可以参考KML说明
有了这个类我们就可以方便的读取KML的节点属性,而且对于新的节点我们只需要添加新的基类就行了.
 
2.定义一个AJAX类用来解析KML.
/**
* 地图数据控制接口
*---------by zygao-----------
* 利用ArrayList存储kml数据
*/

function AjaxXml(model) {

    this.xml;
    this.folderList = new ArrayList();
    //this.model = model;
  
    this.getFolderList = function()
    {
  return this.folderList;
    }
  
    this.getXml = function()
    {
  return this.xml;
    }
  
    /*
    *  读取xml串  
    *  参数1 输出流的地址
    *  参数2 是否异步 true=异步,false=同步
    */

    this.createXml = function(url,bool,markerType)  
    {
  var arr = url.split('.');
  var ext = arr[arr.length-1];
  if (ext == "kml" || ext == "xml")  
  {
      this.dissolutionXml(url);
  }
  else
  {
      //------------------------异步调用读取xml
      if(bool==true)
      {
    var xmlObj = null;
    if(window.XMLHttpRequest){
        xmlObj = new XMLHttpRequest();
    } else if(window.ActiveXObject){
        xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        return;
    }
    xmlObj.onreadystatechange = function()
    {
        if(xmlObj.readyState == 4)
        {
      this.xml = xmlObj.ResponseText;
      dissolutionXml(markerType);
        }
    }
    xmlObj.open ('get', url, true);
    xmlObj.send ('');
      }
      else
      {
    //------------------------同步调用读取xml
    var xmlObj = null;
    if(window.XMLHttpRequest){
        xmlObj = new XMLHttpRequest();
    } else if(window.ActiveXObject){
        xmlObj = new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        return;
    }
    xmlObj.open ('get', url, false);
    xmlObj.send ('');
    //XMLObj = xmlObj.ResponseXML;
    strResult = xmlObj.ResponseText;
    this.xml = strResult;
    this.dissolutionXml();
      }
  }
    }
  
    /*
    *  解析xml----同步
    */

    this.dissolutionXml = function(url)  
    {
  var XMLResult = new ActiveXObject("Microsoft.XMLDOM");
  XMLResult.async = false;
  if(url)XMLResult.load(url);else XMLResult.loadXML(this.xml);
  var folders = XMLResult.selectNodes("/kml/Document/Folder");
  if(folders)
  {
      for(var i=0;i<folders.length;i++)
      {
    var folder = new Folder();
    var _foldername = folders[i].selectSingleNode("name");
    var _open = folders[i].selectSingleNode("open");
    folder.setFolderName(_foldername.text);
    folder.setOpen(_open.text);
    var placemarks = folders[i].selectNodes("Placemark");
    if(placemarks)
    {
        folder.createPlacemarkList();
        for(var j=0;j<placemarks.length;j++)
        {
      var placemark = new Placemark();
      var nodelist = placemarks[j].childNodes;
      var _placemarkname = placemarks[j].selectSingleNode("name");
      var _description = placemarks[j].selectSingleNode("description");
      var _coordinates = placemarks[j].selectSingleNode("Point/coordinates");
      placemark.setName(_placemarkname.text);
      placemark.setDescription(_description.text);
      placemark.setCoordinates(_coordinates.text);
      var _iconstyle = placemarks[j].selectSingleNode("Style/IconStyle");
      if(_iconstyle)
      {
          var _scale = placemarks[j].selectSingleNode("Style/IconStyle/scale");
          if(_scale) placemark.setScale(_scale.text);
          var _href = placemarks[j].selectSingleNode("Style/IconStyle/Icon/href");
          if(_href) placemark.setHref(_href.text);
          var _h = placemarks[j].selectSingleNode("Style/IconStyle/Icon/h");
          if(_h) placemark.setH(_h.text);
          var _w = placemarks[j].selectSingleNode("Style/IconStyle/Icon/w");
          if(_w) placemark.setW(_w.text);
        
          var _shadowicon = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon");
          if(_shadowicon)
          {
        var _shadowhref = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/href");
        if(_shadowhref) placemark.setShadowHref(_shadowhref.text);
        var _shadowh = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/h");
        if(_shadowh) placemark.setShadowH(_shadowh.text);
        var _shadoww = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/w");
        if(_shadoww) placemark.setShadowW(_shadoww.text);
          }
          else
          {
        placemark.setShadowHref('');
        placemark.setShadowH('');
        placemark.setShadowW('');
          }
      }
      else
      {
          placemark.setScale('');
          placemark.setHref('');
          placemark.setH('');
          placemark.setW('');
          placemark.setShadowHref('');
          placemark.setShadowH('');
          placemark.setShadowW('');
      }
      folder.addPlacemark(placemark);
        }//end for
    }//end if(placemarks)
    this.folderList.add(folder);
      }//end for
  }//end if(folders)
    }

    /*
    *  解析xml----一异步
    */

    function dissolutionXml(markerType)  
    {
  var folderList = new ArrayList();
  var XMLResult = new ActiveXObject("Microsoft.XMLDOM");
  //1.服务器端必须设置DOM设为同步模式加载数据  xmldoc.async=false
  //2.load远程数据时,必须设置为:ServerHTTPRequest xmldoc.setProperty "ServerHTTPRequest",true
  XMLResult.async = false;
  XMLResult.loadXML(this.xml);
  var folders = XMLResult.selectNodes("/kml/Document/Folder");
  if(folders)
  {
      for(var i=0;i<folders.length;i++)
      {
    var folder = new Folder();
    var _foldername = folders[i].selectSingleNode("//name");
    var _open = folders[i].selectSingleNode("//open");
    folder.setFolderName(_foldername.text);
    folder.setOpen(_open.text);

    var placemarks = folders[i].selectNodes("//Placemark");
    if(placemarks)
    {
        folder.createPlacemarkList();
        for(var j=0;j<placemarks.length;j++)
        {
      var placemark = new Placemark();
      var nodelist = placemarks[j].childNodes;
      var _placemarkname = placemarks[j].selectSingleNode("name");
      var _description = placemarks[j].selectSingleNode("description");
      var _coordinates = placemarks[j].selectSingleNode("Point/coordinates");
      placemark.setName(_placemarkname.text);
      placemark.setDescription(_description.text);
      placemark.setCoordinates(_coordinates.text);
      var _iconstyle = placemarks[j].selectSingleNode("Style/IconStyle");
      if(_iconstyle)
      {
          var _scale = placemarks[j].selectSingleNode("Style/IconStyle/scale");
          if(_scale) placemark.setScale(_scale.text);
          var _href = placemarks[j].selectSingleNode("Style/IconStyle/Icon/href");
          if(_href) placemark.setHref(_href.text);
          var _h = placemarks[j].selectSingleNode("Style/IconStyle/Icon/h");
          if(_h) placemark.setH(_h.text);
          var _w = placemarks[j].selectSingleNode("Style/IconStyle/Icon/w");
          if(_w) placemark.setW(_w.text);
        
          var _shadowicon = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon");
          if(_shadowicon)
          {
        var _shadowhref = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/href");
        if(_shadowhref) placemark.setShadowHref(_shadowhref.text);
        var _shadowh = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/h");
        if(_shadowh) placemark.setShadowH(_shadowh.text);
        var _shadoww = placemarks[j].selectSingleNode("Style/IconStyle/ShadowIcon/w");
        if(_shadoww) placemark.setShadowW(_shadoww.text);
          }
          else
          {
        placemark.setShadowHref('');
        placemark.setShadowH('');
        placemark.setShadowW('');
          }
      }
      else
      {
          placemark.setScale('');
          placemark.setHref('');
          placemark.setH('');
          placemark.setW('');
          placemark.setShadowHref('');
          placemark.setShadowH('');
          placemark.setShadowW('');
      }
      folder.addPlacemark(placemark);
        }//end for
    }//end if(placemarks)
    folderList.add(folder);
      }//end for
  }//end if(folders)
  addObject(folderList,markerType);
    }
  
    /*
    *  加标注----一异步
    */

    function addObject(folderList,markerType)
    {
  //利用ArrayList存储得到的标注
  if(folderList)
  {
      for(var i=0;i<folderList.size();i++)
      {
    var foldername = folderList.get(i).getFolderName();
    var placemarkListCount = folderList.get(i).getPlacemarkListCount();
    var placemarkList = folderList.get(i).placemarkList;
    for(var i=0;i<placemarkListCount;i++)
    {
        var placemark = placemarkList.get(i);
        var point = new Point(placemark.getCoordinates().split(',')[0],placemark.getCoordinates().split(',')[1]);
        var icon = new Icon(placemark.getW(), placemark.getH(), placemark.getHref());
        var shadowicon = new Icon(placemark.getShadowW(), placemark.getShadowH(), placemark.getShadowHref());
        Marker.TEST = new Array(icon,shadowicon);
        var marker = new Marker(point, Marker.TEST,markerType);
        marker.setInfo(placemark.getDescription());
        model.addOverlay(marker);
    }
      }
  }
    }
  


    //alert("text:"+item.text);
    //alert("nodename:"+item.attributes[0].name+"    nadevalue:"+item.attributes[0].value);
}


这个类做了两件事.
一是读取KML文档的内容并解析.
二是在异步读取的同时添加标注.
 
这里用到了一个叫ArrayList的类.把它理解成我们C#中的ArrayList就行了.
AjaxXml类中包含了一个createXml方法,实际上就是一个AJAX的封装.很多JS框架都实现了,这里就不多解释了.
dissolutionXml方法用来解析KML节点数据(标注相关信息),并将内容通过之前定义的两个基类存放在ArrayList里.
 
3.建一个用来创建标注个类(这个类用来统一接口,不管前两个类怎么写的,只管调用就好了)
/*
* 创建标注类
* --------by zygao-----------
*  
*/


function CreateObject(model)
{
  
    this.model = model;
  
    this.addObject = function(url,markerType)
    {
  //利用ArrayList存储得到的标注
  var ajaxXml = new AjaxXml(model);
  //将页面地址或.xml文件地址发送到ajaxXml类处理
  if( url!="" ) ajaxXml.createXml(url,true,markerType);
  //同步---得到返回的ArrayList
  var folderList = ajaxXml.getFolderList();
  if(folderList)
  {
      for(var i=0;i<folderList.size();i++)
      {
    var folder = folderList.get(i);
    var foldername = folder.getFolderName();
    var placemarkListCount = folder.getPlacemarkListCount();
    var placemarkList = folder.placemarkList;
    for(var j=0;j<placemarkListCount;j++)
    {  
        //加标注
        var placemark = placemarkList.get(j);
        var point = new Point(placemark.getCoordinates().split(',')[0],placemark.getCoordinates().split(',')[1]);
        var icon = new Icon(placemark.getW(), placemark.getH(), placemark.getHref());
        var shadowicon = new Icon(placemark.getShadowW(), placemark.getShadowH(), placemark.getShadowHref());
        Marker.TEST = new Array(icon,shadowicon);
        var marker = new Marker(point, Marker.TEST,markerType);
        marker.setInfo(placemark.getDescription());
        this.model.addOverlay(marker);
    }
      }
  }  
    }
  
  
    this.addRandomObject = function(count,markerType)
    {
  var viewerBound = this.model.getZoom().getViewerBound();
  var hight = viewerBound.getHeight()/1e16;
  var width = viewerBound.getWidth()/1e16;
  var minx  = viewerBound.getMinX()/1e16;
  var miny  = viewerBound.getMinY()/1e16;
  //var arrList = new ArrayList();
  for (var i = 0; i < count; i++)  
  {
      var point = new Point(minx+width*Math.random(),miny+hight* Math.random());
      this.model.addOverlay(this.addRandomMarker(point, i ,markerType));
  }
    }
  
    this.addRandomMarker = function(point, index,markerType)  
    {
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
  var icon = new Icon(20, 34, "http://ditu.google.com/mapfiles/marker" + letter + ".png");
  var shadowicon = new Icon(37, 34, "http://ditu.google.com/mapfiles/shadow50.png");
  Marker.GOOGLE = new Array(icon,shadowicon);
  var marker = new Marker(point, Marker.GOOGLE,markerType);
  marker.setInfo("标注 :<b>" + letter + "</b>");
  //MapEvent.addListener(marker, MapEvent.MOVESTART, function() { debugger; hideInfoWindown(infoWindowID);   });
  //MapEvent.addListener(marker, MapEvent.MOVEEND, function() { showInfoWindow(mapModel, marker);  });
  return marker;
    }

  
  
}
 
下面介绍怎么用此组件.
第一步:将AjaxXml文件夹和ArrayList.js类文件拷贝到项目里,并包含里面的类文件(方法参照之前的开发体会二).再将XML文件夹拷贝到项目里(这里的XML文件夹仅为测试用,实际应用中KML文档都是通过页面形式输出).
第二步:找到MapBuilder,添加
include(baseDir + "/ArrayList.js");
include(baseDir + "/AjaxXml/AjaxXml.js");
include(baseDir + "/AjaxXml/BaseXml.js");
include(baseDir + "/AjaxXml/CreateObject.js");
    /**
  * 填加扩展工具
  *
  * @param para 扩展工具别名
  */

    this.addTool = function(para) {
  if (para == MapBuilder.TOOL_SLIDERBAR) {
      new SliderWidget(this.mapModel).paint();
  }
  if (para == MapBuilder.TOOL_MAPTYPE) {
      new MapTypeWidget(this.mapModel).paint();
  }
    }
  
  
    //--------by zygao-------
    this.addObject = function(url)
    {
  new CreateObject(this.mapModel).addObject(url,'load');
    }
    this.addRandomObject = function(count)
    {
  new CreateObject(this.mapModel).addRandomObject(count,'load');
    }

    //--------by zygao-------
  
    /**
  * 获得地图对象
  */

    this.getMap = function() {
  return this.mapModel;
    }
第三步:找到demo.html
MapServiceURL = 'xml/Xq_arcims_xml.xml';
//----by zygao------ 地图标注
mapbuilder.addObject(MapServiceURL);
//----by zygao------ 随机地图标注(测试)
mapbuilder.addRandomObject(26);
最后运行一下试试吧.
动态标注 
Posted on 2008-07-09 11:14  寒羽良  阅读(1649)  评论(0编辑  收藏  举报