arcims(HtmlView)开发经验总结《转》
aimsLayers.js
变量定义含义,知道这些,我们自己写 arcXML请求时,不用把图层具体信息硬编码到程序中。
比如 要知道图层的字段, 我们可以从这些数组中得到,而不要写到程序中。
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();
fengyun925(深秋的落叶 卷起片片的凌乱)
这些是ims中放大操作的坐标转换 。有什么问题再问我。
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();
}
webGIS基本框架
viewer.htm
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=GB2312">
</HEAD>
<TITLE>地理信息平台</TITLE>
</HEAD>
<FRAMESET ROWS="*,50" BORDER=0 >
<FRAME NAME="MapFrame" SRC="Map.htm" SCROLLING="No" FRAMEBORDER="1" bordercolor="#ffffffff" RESIZE="YES">
<FRAME NAME="PostFrame" src="/jsForm.htm" MARGINWIDTH="0" MARGINHEIGHT="0" SCROLLING="No" FRAMEBORDER="0" NORESIZE FRAMESPACING="0" BORDER="0">
</FRAMESET>
<NOFRAMES>
<BODY>
<P>
</BODY>
</noframes></HTML>
jsForm.htm
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<TITLE>Default Form</TITLE>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
function passXML() {
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="White" onload="passXML()">
<P>
<FORM ACTION="operate.asp" METHOD="POST" name="theForm">
<INPUT TYPE="Hidden" NAME="x1" SIZE="40">
<INPUT TYPE="Hidden" NAME="x2" SIZE="40">
<INPUT TYPE="Hidden" NAME="y1" SIZE="40">
<INPUT TYPE="Hidden" NAME="y2" SIZE="40">
</FORM>
</BODY>
</HTML>
map.htm
<body onload="init()" onmousedown="m_down()" onmouseup="m_up()">
<div id="map" style="position:absolute;background-color:#ffff9c; overflow:auto; left:15px; top:10px; width:500px; height:400px; z-index:1; visibility:visible;text-align:center;">
我是地图请点击我。
</div>
<div id="shuoming" style="position:absolute;left:600px; top:10px; overflow:auto;">
</div>
</body>
<script>
function init(){
}
var mouseX1;
var mouseY1;
var mouseX2;
var mouseY2;
function m_down(){
var objId=window.event.srcElement.id;
if(objId=='map'){
mouseX1=event.clientX + document.body.scrollLeft-window.event.srcElement.style.pixelLeft;
mouseY1=event.clientY + document.body.scrollTop-window.event.srcElement.style.pixelTop;
pf('鼠标下击:x='+mouseX1+' y='+mouseY1);
}
}
function m_up(){
var objId=window.event.srcElement.id;
if(objId=='map'){
mouseX2=event.clientX + document.body.scrollLeft-window.event.srcElement.style.pixelLeft;
mouseY2=event.clientY + document.body.scrollTop-window.event.srcElement.style.pixelTop;
pf('鼠标释放:x='+mouseX2+' y='+mouseY2);
request();
pf('请求...............');
}
}
function request(){
var thePostForm = parent.PostFrame.document.forms[0];
thePostForm.x1.value = mouseX1;
thePostForm.x2.value = mouseX2;
thePostForm.y1.value = mouseY1;
thePostForm.y2.value = mouseY2;
thePostForm.action='operate.asp';
thePostForm.submit();
}
function process(msg){
pf('响应...............');
alert(msg);
}
function pf(msg){
shuoming.insertAdjacentHTML("BeforeEnd", "<P>" + msg + "</P>");
}
</script>
operate.asp
<%
dim x1,x2,y1,y2
x1=Request.Item("x1")
x2=Request.Item("x2")
y1=Request.Item("y1")
y2=Request.Item("y2")
%>
<HTML><HEAD><meta http-equiv="Content-Type" content="text/html; charset=GB2312">
<TITLE>Default Form</TITLE>
<SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript">
function passXML() {
var x1='<%Response.Write(x1)%>';
var x2='<%Response.Write(x2)%>';
var y1='<%Response.Write(y1)%>';
var y2='<%Response.Write(y2)%>';
var msg='我是从服务器返回的!\r\n'+' newx1='+x1+' newx2='+x2+' newy1='+y1+' newy2='+y2;
parent.MapFrame.process(msg);
}
</SCRIPT>
</HEAD>
<BODY BGCOLOR="White" onload="passXML()">
<P>
<FORM ACTION="operate.asp" METHOD="POST" name="theForm">
<INPUT TYPE="Hidden" NAME="x1" SIZE="40">
<INPUT TYPE="Hidden" NAME="x2" SIZE="40">
<INPUT TYPE="Hidden" NAME="y1" SIZE="40">
<INPUT TYPE="Hidden" NAME="y2" SIZE="40">
</FORM>
</BODY>
</HTML>
据我经验,操作地图而不刷新页面 在性能,美观,状态保存各方面都有优胜。
以上是我依照arcIMS(htmlview)写的个例子,可以在其基础上扩展。
viewer.htm 主页面 包括 地图显示页面(map.htm) 和 隐藏的服务器交互页面(jsForm.htm)
operate.asp 服务器操作。 可以根据客户端发来的参数,用mapxtreme,ims等处理后,返回结果。
用这个框架,我们可以把 逻辑实现 和 表示实现 分离。方便了系统维护,升级。
比如,我想从mapxtreme for nt到mapxtreme for java,表示逻辑变动不到。mapxtreme到ims,也可以很容易的平台变动。
waiting099 by