var layerCount = 0;//图层数量

var LayerName = new Array();//图层名称
var LayerID = new Array();      //ID
var LayerVisible = new Array(); //是否可见
var LayerType = new Array();    //图层类型    
var LayerIsFeature = new Array();//是否为矢量图层 
var LayerExtent = new Array();   //图层显示范围    以|分界的字符串
var LayerMinScale = new Array();  //最小比例
var LayerMaxScale = new Array();  //最大比例
var LayerRenderString = new Array(); //没用

var LayerShapeField = new Array();   //SHAPE字段的名称  为  #SHAPE#
var LayerIDField = new Array();      //主键 字段名称   MAPUSER.  .OBJECTID
var LayerFieldList = new Array();          //字段名称 以 , 隔开的字符串
var LayerFieldTypeList = new Array();        //字段类型 以 , 隔开的字符串
var LayerFieldSizeList = new Array();        //字段长度 以 , 隔开的字符串
var LayerFieldPrecisionList = new Array();   //精确度   以 , 隔开的字符串

var LayerFields = new Array();         //活动图层的字段名称
var LayerFieldType = new Array();      //活动图层的字段类型
var LayerFieldCount=0;                 //活动图层的字段数量
var ActiveLayer="";                    //活动图层的ID
var ActiveLayerType="";                //活动图层的类型

var layerLeft = 0;                     //没用
var layerRight = 0;                    //没用
var layerTop = 0;                      //没用
var layerBottom = 0;                   //没用

var fieldIndex = 0;                    //没用
var FeatureLayerCount = 0;             // 矢量层的数量

// field aliases arrays
var AliasFieldName = new Array();      //没用 
var AliasFieldAlias = new Array();     //没用 
var LayerListOpen=false;
var queryOpen = false;
var displayLayerInfoButton=false;
var setLayerVisible = new Array();


                               arcims开发经验总结(2) (地图放大缩小、鹰眼实现逻辑)

放大缩小:
var x1,y2;   //起点   坐标
var y1 ,x2;   //对角点坐标
//开始拉框。由鼠标点击触发
function startZoomBox(e) {
    //把地图所在的<DIV>移动到初始位置。
 moveLayer("theMap",hspc,vspc);
 //得到开始的屏幕坐标(相对与地图的哦) mouseX   mouseY
 getImageXY(e); 
 //判断是否在地图中点击   地图宽度 iWidth   地图高度 iHeight
 if ((mouseX<iWidth) && (mouseY<iHeight)) {
  if (zooming) {//zooming表示正在放大中
   stopZoomBox(e);//停止拉框
  } else {
   x1=mouseX;//开始点 x
   y1=mouseY//停止点  y
   x2=x1+1; //表示你画的框的宽度
   y2=y1+1;

   zleft=x1;//你画的框 左边 的位置
   ztop=y1;//你画的框 上边 的位置
   zbottom=y1;//你画的框 下边 的位置
   zright=x1//你画的框 右边 的位置
   boxIt(x1,y1,x2,y2);//画红框,dhtml实现
   zooming=true;      //表示正在放大中
  }
 }
 return false;
}
//拉框中,移动鼠标
function mouseStuff() {
 x2=mouseX; //得到当前鼠标坐标
 y2=mouseY; //得到当前鼠标坐标

 if (x1>x2) {//判断起点 终点 x坐标大小,重新给zright zleft附值
  zright=x1;
  zleft=x2;
 } else {
  zleft=x1;
  zright=x2;
 }
 if (y1>y2) {//判断起点 终点 y zbottom ztop 附值
  zbottom=y1;
  ztop=y2;
 } else {
  ztop=y1;
  zbottom=y2;
 }
 //如果起点 终点不是一个点时,画框
 if ((x1 != x2) && (y1 != y2)) {
  boxIt(zleft,ztop,zright,zbottom);
 }
}

//停止拉框,鼠标释放触发事件
function stopZoomBox(e) {
 zooming=false;//表示放大完成

 //当我们拉框太小,小于线的宽度时,就当作点放大。
 if ((zright <zleft+2) && (zbottom < ztop+2)) {
  zoomin(e);
 } else {//拉框放大

  var tempLeft=lastLeft;
  var tempRight=lastRight;
  var tempTop=lastTop;
  var tempBottom=lastBottom;
  saveLastExtent();

  //得到 横向 每个象素代表的 实际距离  xDistance 表示当前地图比例时,横向距离。
  //其实是 每个象素代表的 经纬度
  pixelX = xDistance / iWidth;
        //拉框上边 和 地图底边的距离  屏幕距离
  //为什么要定义这个呢??
  //屏幕坐标 左上角为坐标原点
  //地理坐标  我们当成 左下角为坐标原点
  var theY = iHeight - ztop;
  //得到 纵向 每个象素代表的 实际距离  yDistance 表示当前地图比例时,纵向距离。
  pixelY = yDistance / iHeight;
        //大家仔细看下面代码, 得到我们操作后,上下左右 的(距离)经纬度
  //结果上边经度  = 每个象素代表的经度 * /拉框上边和地图底边的距离(屏幕距离)+ 操作以前的底边经度
  //在这里eTop等是地理坐标  zTop等是屏幕坐标
  eTop = pixelY * theY + eBottom;  
  eRight = pixelX * zright + eLeft;
  eLeft = pixelX * zleft + eLeft;
  theY = iHeight - zbottom;
  pixelY = yDistance / iHeight;
  eBottom = pixelY * theY + eBottom;
       
  //得到 eTop eRight eLeft eBottom 四个经纬度值,请求ims服务器,返回合适的地图。
  sendMapXML();
 }
 return true;
}

鹰眼实现:
鹰眼实现方法:根据arcIMS代码说明,掌握逻辑后,mapinfo,mapx,mo等实现就容易了。

开始前,大家首先要对arcims中,如何记录地图位置熟悉。

抓一副全图,存成gif文件,作为鹰眼图底图。

var fullOVLeft = 116;    //全图时,地图最左边代表的经度   当你用其他坐标体系的坐标时,这个值不同。一般,我们熟悉经纬度。
var fullOVRight = 117;   //全图时,地图最右边代表的经度
var fullOVTop = 40;      //全图时,地图最上边代表的经度
var fullOVBottom = 39.6; //全图时,地图最下边代表的经度

//点击鹰眼, 入口参数是 屏幕 鼠标的坐标
function ovMapClick(x,y) {
var ovWidth = 150;    //我们鹰眼图的宽度 单位px,是屏幕单位
var ovHeight = 100;   //鹰眼图的高度    单位px,是屏幕单位

//下面两行代码得到,为什么要两个呢。可能我们显示的时候,把服务器返回的图片压缩了。
//每 px单位的屏幕宽度 代表的 经度距离
var ovXincre = fullOVWidth / ovWidth;
//每 px单位的屏幕宽度 代表的 纬度距离
var ovYincre = fullOVHeight / ovHeight;
      
var ovX = x;
var ovY = ovHeight - y;//注意,屏幕 和 地理 坐标原点不同。在其他文章中提到过。
        //下面两行代码我们得到了 鼠标点击位置代表的 地理位置。(经纬度)
var ovmapX = ovX * ovXincre + fullOVLeft;
var ovmapY = ovY * ovYincre + fullOVBottom;
//arcims带的,当我们想看上一操作的地图时,这些保存的东西就有用咯。
saveLastExtent();
        //下面代码表示 改变地图的中心点,但是room 值不变。arcIMS中,是以下实现的。在
mapxtreme中,一个函数就OK了。

        //熟悉arcIMS的,以下代码可能明白。
eLeft = ovmapX - xHalf;
eRight = ovmapX + xHalf;
eTop = ovmapY + yHalf;
eBottom = ovmapY - yHalf;
sendMapXML();

}



                                                 arcims开发经验总结(3) (杂谈1)

有幸在arcims mapxtreme两大平台上做过开发,谈谈个人感受

   抛开arcgis9 的 arcgis Server.先说arcIms开发。(以Image Services为例,ArcMap Image Services我估计在arcgis9中,着重在arcGIS Server体现)

    arcIms的核心是AcrXML,也可以说是围绕着ArcXML进行的开发,如果熟悉了ArcXML,估计关于arcIms的开发就掌握了60%. 象htmlview,javaconnect,Activex等各种连接,只是对ArcXML的一个封装。

  ArcIMS服务器,其实相当于一个webservice.我们输入一定格式的参数,他处理后就返回相应的结果。而这个格式就是ArcXML。(其实ArcXML还是ims的配置文件,由author生成。)ARCXML包括内容丰富,还在不断增强。 我们常用的请求为Using GET_IMAGE and IMAGE with Image Services,Using GET_FEATURES and FEATURES 分别得到图象和属性值。
 
     对于我们二次开发来说,我们只是不断的组合请求的ArcXML,得到我们想要的结果。然后显示这些结果。 我把这个开发过程分为 GIS业务应用 和 WEB编程。 比如:北京工交网: 其实就是组合了几个ARCXML ,然后显示出来。IT公司WEB编程肯定没问题,所以现在GIS行业焦点在如何最大的挖掘需求,挖掘行业应用。如何把行业需求用GIS软件提供的功能表达出来。(难啊!)作了两年GIS,做的基本都是放大,缩小。业务上,在中国政府机构,公司很难提出什么应用来。(急需一些标准)。估计以后是个方向。(我要有钱,专门做GIS应用行业标准)
 
   我较喜欢htmlview, 用他可以作出很漂亮的界面(有段时间我认为做GIS和做美工性质一样)。很多工作在客户端。但安全性低,都用javascript实现。至于javaConnect等,更符合OOP,但是1、因为webGIS系统有很多状态,比如地图的比例,活动层的选择等要保持,要保持这些状态,必须把这些放到缓冲中,那对于大用户量来说,性能是个大问题。2、javaconnect和mapxtreme很类似, 改变地图要刷新MAP对象,把MAP对象放到SESSION中。(急剧影响性能,访问量大了)所以状态要保持,对web服务器也是个挑战。对很酷的地图操作也是个挑战。3、个人觉得javaconnector类库的设计好象不是面向开发人员的,完全以地理分类的概念分组,打包。(package  Map对象应该分成几个对象,弄的太复杂了,对不同的请求,有些属性是空的。)
(现在我正在研究用javaconnector开发高性能ims webGIS)

在ArcGIS9中,ESRI公司有了新的webGIS编程模型,地理分析可以在web上实现(当然IMS还有),主要针对J2ee 和 .Net平台。 新内容有 1、由arcgis   Server管理AO对象 2、可以远程调用这些AO对象3、有个ArcObject Develop FrameWork(ADF) 和 运行时,支持J2ee,.net平台,可以开发webgis.4、webservice,EJB支持
看了一下文档,焦点在对象的远程调用 和 对象状态的保持 两方面。 第一点,性能问题,没用过,但估计悬, 但AO对象强大的功能通过远程对象访问搬到web上来了,值得期待。 第二点:对象状态保持, 和mapxtreme一样,有对象池了概念。和EJB的有状态bean 无状态Bean类似。和有状态Bean一样,对象状态保持问题好象解决的不好。但gis大多为有状态对象。麻烦啊。状态保持方案 好象有  shallowly stateful application 和 deeply stateful Web application。需要很大的编程技巧。 个人感觉,.net在这开发还好。J2ee的JSF不知道什么时候能成熟啊。



                               arcims开发经验总结(4) (arcIMS 客户端 连接器的选择)

客户端选择。
   就IMS来说提供了 HTML Viewer Java Standard Viewer Java Custom Viewer
 
   Java Standard Viewer,Java Custom Viewer功能差不多。 对于程序员、中国客户来说。Java   
Standard Viewer基本不用。典型的胖客户端,Image 和Feature MapServices 都要下载APPLET,客户端还要装jre。随着微软IE对applet的抵制 和 Arcgis Server(远程数据分析,Feature MapServices的替代)成熟,估计这种胖客户端没什么大用了,至少我觉得在中国是这样的。就我接触的webgis项目中,applet的应用不是很多,政府部门更是因为安全性,很少用。(http://www.668map.com/)用applet,但是假如我们对于大数据量的gis应用,有还多业务查询、分析。估计把数据放到缓冲中的做法就悬了。还有假如我要加遥感应用,数据量大的更是可怕。 我个人对Java Viewer前景不是看好。

   HTML Viewer:DHTML和JavaScript 实现。随着web程序的流行,dhtml,javascript,css的成熟(对不同浏览器有统一标准就完美了,不过客户端IE就现在还是老大)。arcgis server的客户端也是html view(没办法.net,j2ee还是以浏览器为主要客户端的)。另外html是如此的轻便,页面是可以如此的漂亮,扩展,维护也不用编译什么的。虽然不支持Feature MapService,但Feature MapService的应用可以由arcgis server实现。

连接器选择。
.NET Link 、ActiveX 、AppServerLink 、ColdFusion 、General、Java 、Servlet 、WMS
思想就是把ArcXML封装了,再向ArcIMS发送请求,客户端展示。下面以arcIMS提供了例子探讨一下Servlet Connector ,javaconnector。请自行配置htmlview和javasconnector的例子。

Servlet Connector:修改viewer.htm,使jsForm.htm 可以在页面中看到。(<FRAMESET ROWS="30,*,30,50"—)

jsForm.htm加载地图前代码
......
function passXML() {
}
......  
加载地图后代码
......
function passXML() {
var XMLResponse='<?xml version="1.0" encoding="UTF-8"?><ARCXML
version="1.1"><RESPONSE><IMAGE><ENVELOPE minx="116.325273231549" miny="39.9126536248245"
maxx="116.741417757427" maxy="40.08" /><OUTPUT url="http://zhangkj:8080/Output/txzy_ZHANGKJ188425841.jpg" /></IMAGE></RESPONSE></ARCXML>';
parent.MapFrame.processXML(XMLResponse);
}
........
在aimsXML.js中看函数function htmlSendToServer(URLString,XMLRequest,theType)和function
processXML(theReplyIn) 一目了然了,htmlSendToServer把我们组合的arcXML发送到com.esri.esrimap.Esrimap?ServiceName,返回的XMLResponse由processXML显示出来。
核心代码就这些,你在javascript文件夹中的大部分js文件是 组合请求的arcXML字符串 和 解析从arcIMS返回的arcXML字符串。其他js文件是DHTML,参数,公有函数等。看上去挺吓人的。我个人觉得htmlview例子里的js代码可重用性很高。但必须很熟悉这些代码,函数。和其他连接器比较,htmlview可以说是最简单的了。 熟悉html,熟悉javascript,有arcXML文档,这就够了。

剩下的是用 javascript构造不同的arcXML,请求arcIms, 用dhtml,javascript显示返回arcXML.
(大家可以看一下jspForm.jsp,用com.esri.aims.mtier.io.ConnectionProxy类来请求IMS服务。和上面的流程差不多。http://support.esri.com/index.cfm?fa=knowledgebase.techarticles.gateway&p=16&pf=217上面讲的都不错,从更深的角度讲了各个连接)

javaconnector:把arcXML文档用java对象封装起来。组合arcXML的工作由纯面向对象的java语言来做,
com.esri.aims.mtier.io.ConnectionProxy对象请求ims服务器,返回java对象的响应。servlet connector 是字符串,而java connector是java对象。这样java语言的优势,java对象的可操作性,易用性,方便性就显露出来拉。javaconnector对arcIMS服务动态增加等。

Map map=new Map();
map.initMap(mapCon,750,false,false,false,false);
map.setHeight(500);
map.setWidth(400);
map.refresh();  
String url=map.getMapOutput().getURL();
Map对象封装ArcXML,map.refresh() 请求IMS服务。 请求完了Map对象包括响应的内容。(其实map.initMap也触发了一次请求 GET_SERVERINFO。javaconnector的类库设计的有问题。)

servlet connector 和 javaconnector比较

一、性能
   servlet connector: 用户下载javascript文件。组合arcXML在客户端执行。如果用户机器不是太慢的话,性能应该是最好的,服务器压力也小。据说ims 群集安装,系统配置的好的话,可以支持几百万用户。
   javaconnector:比不上servlet connector。1、java对象的封装,在服务器端运行。(不过可忽略)2、Map对象建立的性能损耗。map.initMap(),map.refresh()都要触发请求ims。操作一次地图 新建一个map对

象的做法是不可能的。有两个解决 把map对象放到Session中 和 map对象池。 把map对象放到Session,用户多的时候,web服务器压力很大,多用户时不可行。 map对象池 ,map对象的 钝化,激活(EJB的提法)操作复杂。因为不同用户当前操作状态不一样(在arcgis9 server中,状态保存是个值得研究的地方)。 运用javaconnector 性能问题得考虑。 (个人觉得javaconnector类库建立的有问题,用反编译工具看,代码设计有改进的地方,可以解决map对象初始化问题)。

二、功能:
   servlet connector: arcXML的所有功能。 问题在 组合arcXML和显示响应的arcXML的环节上。 因为这些用javascript实现。有一定局限性。 比如,我要把 响应arcXML 的查询结果排序。实现起来费事。(arcXML查询不支持order by ).不可以对ims服务操作。
   javaconnector:arcXML的所有功能。可以用java语言的优势处理很多问题。比如前面排序。动态图层、与遥感影象图的叠加实现起来都比较方便。还可以结合arcSDE的java接口处理原数据。