WebGIS原理与实践 (2).ppt
WebGIS原理与开发技术Ajax与WebGIS(上),侯景伟宁夏大学资源环境学院,2012,主要内容,基于Ajax的Web应用模型什么是AjaxxmlHttprequest对象基于Ajax的Web地图模型地图的异步请求与响应服务器端接口,基于Ajax的Web应用模型,传统Web应用主要依靠表单来实现客户端与服务器端的通信,这是一种同步通信模式。主要两个问题:(1)客户等待延迟;(2)整个网页刷新。,传统的Web应用模型,基于Ajax的Web应用模型,Ajax Web应用模型,什么是Ajax,Ajax实际上是多种技术的结合体,包括JavaScript,CSS,DOM,XMLHttpRequest,XML,XSLT,XHTML等。其主要技术特点是通过CSS,XHTML、DOM来表现网页的内容和样式;通过xmlHttpRequest对象进行客户端与服务器端异步数据通讯;通过JavaScript处理相关业务逻辑。这种在设计和编程上将内容、表现、业务和数据分层的开发模式,带来的是一种全新的用户交互体验和Web应用性能的提高。,xmlHttprequest对象,XmlHttpRequest是Web客户端通过Javascript、VbScript、Jscript等脚本语言向Web服务器请求和处理XML格式或其他格式的数据的一组API。XmlHttp提供了客户端同http服务器通信的协议,可实现同步和异步的交互。XMLHttpRequest是Ajax异步通讯技术得以实现的最主要对象。使用xmlHttpRequest对象的最大的好处是可以更新网页的部分内容而不需要刷新整个页面。现在的绝对多数浏览器都增加了对XMLHttpRequest的支持。,xmlhttpRequest对象的主要属性,xmlhttpRequest对象的主要方法,如何使用xmlhttprequest对象,function getXHR()var A=null;if(!A,如何使用xmlhttprequest对象,function testXHR()var xhr=getXHR();if(xhr)xhr.onreadystatechange=function()if(xhr.readyState=4)var odiv=document.getElementById(test);odiv.innerHTML=unescape(xhr.responseText);xhr.Open(get,test.txt,true);xhr.Send(null);,客户端MVC开发模式,MVC是模型-视图-控制开发模式的简称,它是一种将用户交互和业务逻辑进行分离的一种程序开发方式。MVC通常用于大规模的应用开发中。在我们这个实习中,我们通过DOM来实现地图页面布局;通过CSS来定义地图的外观和交互样式;以XMLHttpRequest对象为客户端与服务器端通讯协议,通过JavaScript实现客户端的地图交互逻辑和通信控制。服务器端ASP脚本专注于服务器端地图服务功能实现,不参与客户端地图的行为。,客户端MVC开发模式,基于Ajax的Web地图模型,主要特点:(1)客户端代码与服务器端代码完全分离,客户端AjaxMap.html主要用来实现地图表现以及与用户的交互;(2)客户端通过XmlHttpRequest对象(而不是表单)向服务器进行异步地图数据请求,从而实现了页面的部分更新,同时减少了网络的延迟,因而有更好的用户体验;(3)利用来组织地图,并进行地图交互,从而可以实现一些特殊的效果如拉框放大,平移等地图交互功能。(4)利用客户端JavaScript来控制系统交互的流程。,地图视图设计,地图视图设计代码示例,你好,AJAX地图全图放大缩小漫游,定义地图的外观(部分样式),/以下css只定义了部分内容#mapview width:610px;height:400px;position:relative;margin:auto auto;overflow:hidden;border:#ccaa88 1px solid;#basemap position:absolute;top:0px;left:0px;z-index:1;,#rubbleoverflow:hidden;filter:Alpha(opacity=50);opacity:0.50;moz-Opacity:0.50;visibility:hidden;display:inline-block;#mapImage position:absolute;/,详细代码及说明请参考教材和实习光盘。,地图交互流程,客户端地图交互的内容包括用户选择地图工具如放大、缩小和平移等,用户在地图上用相应的工具进行放大、缩小和平移操作如拉框放大、拉框缩小和拖动地图等。客户端地图交互的主要流程如图所示:,地图交互流程初始化地图,当客户第一次载入地图时,调用init()方法初始化地图。/这里定义全局变量 function init()var mapview=document.getElementById(mapview);rubble=document.getElementById(rubble);mapImage=document.getElementById(mapImage);mapview.onmousedown=MouseDownEvt;mapview.onmousemove=MouseMoveEvt;mapview.onmouseup=MouseUpEvt;setMapTool(ZoomAll);/window.onload=init();,地图交互流程设置地图工具,当用户选择地图工具按钮时,调用setMapTool()函数,setMapTool()的一个主要功能是给全局变量curTool赋值,同时修改鼠标光标的样式,以用于后续的拉框缩放或平移地图等操作。,function setMapTool(value)if(!value)value=ZoomAll;curtool=value.toLowerCase();switch(curtool)case zoomin:case zoomout:=crosshair;break;case pan:=move;break;case=default;RequestMap();break;=default;/document.getElementById(tooltip).innerHTML=当前地图工具:+value;,地图交互设计-MouseDown,缩放和拖动地图涉及到三个鼠标事件:MouseDown、MouseMove和MouseUp。在MouseDown事件中记下了一些很必要的初始状态,包括:(1)鼠标的位置startX和startY,(2)橡皮拉框(rubbleDiv,用来进行拉框缩放地图)的初始位置rblLeft和rblTop,(3)地图图片的初始位置imgLeft和imgTop以及地图视图的位置等。,地图交互设计-MouseDown,function MouseDownEvt(event)startX=event.clientX;startY=event.clientY;rblLeft=event.offsetX;rblTop=event.offsetY;imgTop=);imgLeft=);mapViewLeft=event.clientX-event.offsetX+;mapViewTop=event.clientY-event.offsetY+;if(curtool=pan)dragging=trueelse if(curtool=zoomin|curtool=zoomout)zooming=true;,地图交互设计-MouseMove,在MouseMove事件中,我们先判断当前鼠标位置是否超出地图视图的边界,然后我们计算相对于MouseDown事件的鼠标的偏移量:dltx=event.clientX-startX;dlty=event.clientY-startY;如果是平移地图操作,则根据鼠标的偏移量修改地图图片的当前位置,从而实现图片的移动效果:mapImg.top=imgTop+dlty;mapImg.left=imgLeft+dltx;如果是拉框缩放地图操作,我们需要修改rubbleDiv的位置和大小属性。,地图交互设计-MouseUp,鼠标弹起时,我们要做两件事,一件事是结束当前对地图的平移或拉框缩放操作,另一件事是根据操作结果请求地图。对于第一件事件我们通过设置两个状态变量的值为false即可:dragging=false;zooming=false;=hidden;第二件事我们通过调用RequestMap()函数来实现,另外还需要记下鼠标弹起时的坐标endX和endY。至此完成了一个完整的地图交互过程。,地图的请求与响应RequestMap,当用户完成地图的交互后就转入向服务器请求地图并处理请求结果的过程。这个过程由RequeMap()函数共同实现。RequestMap()先调用calcReqParams()函数收集和计算请求地图时相应的参数,然后后调用xhrRequest(reqParams)向服务器请求地图。function RequestMap()var mapParams=calcReqParams();if(!mapParams=)xhrRequest(mapParams);,地图的请求与响应,reqParams=mapTool=+curTool+/null,地图的请求与响应xhrRequest,function xhrRequest(reqParams)var xhr=getXMLHTTP();if(xhr)var mapImg=document.getElementById(mapImage);xhr.onreadystatechange=function()if(xhr.readyState=4)if(xhr.status=200)if(mapImg)mapImg.src=xhr.responseText;=0;=0;var stamp=(new Date().getTime();var mapURL=mapsvr.asp?+reqParams+,地图的请求与响应,对服务器返回的结果的处理是通过onreadystatechange句柄实现。在该函数中,如果获取到服务器返回的地图图片(图片的URL包含在xhr的responseText中),就修改mapImg元素的URL。xhr.onreadystatechange=function()if(xhr.readyState=4)if(xhr.status=200)if(mapImg)mapImg.src=xhr.responseText;=0;=0;/onreadystatechange,AjaxMap示例,服务器端接口设计,服务器端代码与客户端代码是完全独立的,这意味着只要保持地图请求的参数形式不变(即接口不变),客户端代码的修改不会影响地图服务器的正确响应。Ajax地图的服务器端代码MapSvr.asp与HelloMap.asp相比主要作了以下修改:一是在调用流程中增加了一个向Web客户端返回地图图片的URL的语句Response.Write(getMapImage)。if not HasAMapObj thenInitMapEngine end ifif HasAMapObj then AjustMapResponse.Write(getMapImage)end if,服务器端接口,另外一个比较大的改动是对AjustMap()函数的修改,主要用来计算由拉框缩放或平移地图后地图的zoom值和中心点的坐标,基本原理如下:如果是拉框缩放地图操作,先获取“橡皮”框的中心点坐标(sx,sy)以及高度和宽度(dlty,dlyx),这些都是屏幕坐标:sx=(ScreenX1+ScreenX2)/2sy=(ScreenY1+ScreenY2)/2dltx=ScreenX2-ScreenX1dlty=ScreenY2-ScreenY1,服务器端接口计算缩放比例,缩放比例的计算需要同时考虑橡皮框的宽度和高度与地图视图的宽度和高度的比值,原则是取比值较小的一个值,以避免过分放大或缩小地图而产生的意料之外的结果:nScale=1.0if dltx2 then nscale=abs(mapWidth/dltx)if dlty2 thenif abs(500/dlty)nscale then nscale=abs(mapHight/dlty)end ifend if 如果是平移操作,需要先计算出平移后地图中心点的位置(屏幕坐标):sx=mapWidth/2-dltx;sy=mapHeight/2-dlty;,服务器端接口AjustMap(),select case getMapTool()case zoominSession(MapObj).screen2WorldEx sx,sy,fMapX,fMapYfNewZoom=fZoom/nScalecase zoomoutSession(MapObj).screen2WorldEx sx,sy,fMapX,fMapY fNewZoom=fZoom*nScalecase panSession(MapObj).screen2WorldEx cx-dltx,cy-dlty,fMapX,fMapYfNewZoom=fZoomcase else fNewZoom=fZoomend select if getMapToolzoomall thenSession(MapObj).ZoomTo fMapX,fMapY,fNewZoom elseSession(MapObj).ZoomTo session(x0),session(y0),session(z0)end if,思考题,重新设计一个基于Ajax的Info查询其他技术Html5与Canvas使用Iframe或标签实现异步请求,