上一篇关于 ArcIMS 的文章中提到了Mapdex使用ArcIMS和 GMap 的API构建GMap风格的网络地图,但需要使用GMap的API,本文则介绍一种无须使用任何API的解决方案。
要构建GMap风格的网络地图,首先需要有一个类似GMap风格的JS库,作为客户端;其次是如何使该客户端和ArcIMS连接起来,如何缓存图片等等。本文是在以下基础上构建的:
- MapEasy,一个国人写的网络地图JS库,可以在mapeasy.sf.net下载,不过该库好像很久没有更新了,比较可惜。类似的JS库还有不少,但没有相对完整、可用的。
- 来自Maplex的一段连接GMap API和ArcIMS的ASP程序,本文的程序是在这段程序的基础上修改而来的。
以下是运行截图:
读者可以 下载 试用,地址:
http://www.3snews.net/html/95/295_itemid_2823.html
使用前需要修改config.asp文件中的有关参数:
ArcIMSServer = "localhost" ' 服务器 ArcIMSServerHost = 5300 ' 端口 MapService = "BlueViewer" ' 地图服务 MapImageWidth = 256 ' 输出地图的大小 ' 地图的范围 MapXMin = -130 MapXMax = -50 MapYMin = 0 MapYMax = 70 ImageType = "png" ' 输出类型 CacheName = "test" ' 缓存名称 CacheDir = "E:\Documents\ArcIMS\GMap\img\" ' 缓存路径 |
然后在浏览器中打开浏览即可。
需要说明的是,由于客户端的JS代码默认的范围是(-180,180,-90,90),因此,按照经纬度坐标加上去的标注返回位置不对,需要进行校正。
下面简单说一下运行机制:
在html文件中,创建一个地图的JS代码:
function IMSMapType() { MapType.apply(this); this.getSrc = function(level, row, column) { return "arcims.asp?z="+level+"&x="+column+"&y="+row } } MapModel.mapTypes = new Array(new IMSMapType()); MapModel.maxZoomLevel=10 |
这段代码创建了一个地图类型,也可以创建多种地图类型(类似GMap),其中getSrc函数定义了如何返回图片的方法,其中有3个参数:缩放比例、横向位置和纵向位置。而在MapEasy这个库中,不同缩放级别的图片是按照类似二维数组的下标方式拼接的。
例如缩放比例为2(4(22)幅拼接图片):
0,0 1,0
0,1 1,1
缩放比例为3(8(23)幅拼接图片):
0,0 1,0 2,0 3,0
0,1 1,1 2,1 3,1
0,2 1,2 2,2 3,2
0,3 1,3 2,3 3,3
也就是说,从左上角依次增加数值,然后调用arcims.asp,根据位置参数和缩放比例,将地图缩放到相应的位置(缩放比例),返回图片就可以了。
在arcims.asp 中,主要的程序流程就是(下图),首先根据图片的位置参数,构建图片名,然后判断是否存在,如果存在,则返回之,否则调用ArcIMS渲染并保存图片。其 中返回图片没有使用重定向到图片,而是通过写数据流的方式来做的(类似ASP中上传文件保存到数据库,然后返回给客户端的做法)。
如果判断图片在缓存存在的执行流程为:1,2,3,7;判断图片在缓存不存在的执行流程为:1,2,4,5,6,7。所以,每个缩放比例的图片在ArcIMS中只渲染一遍,因此可以大大提高运行效率。
其中如何获取一幅地图的代码如下:
if isObject(Session("IMSGmapMapObj")) then Set mMap = Session("IMSGmapMapObj") else call InitMapServer() end if set mLayers = mMap.Layers '计算地图范围,获得宽度 Dim MapWidth1, MapWidth2 MapWidth1 = MapXMax - MapXMin MapWidth2 = MapYMax - MapYMin If MapWidth1 < MapWidth2 Then MapWidth = MapWidth1 Else MapWidth = MapWidth2 End if Dim mExtent Set mExtent = Server.CreateObject("aims.Envelope") mExtent.XMin = MapWidth / (2^(z-1)) * x + MapXMin mExtent.YMin = MapWidth / (2^(z-1)) * (2^(z-1) - y - 1) + MapYMin mExtent.XMax = mExtent.XMin + MapWidth / (2^(z-1)) mExtent.YMax = mExtent.YMin + MapWidth / (2^(z-1)) mMap.DoZoomToExtent mExtent mMap.Refresh OUT_IMAGEURL = mMap.GetImageAsUrl() |
首先获得地图对象(如果没有缓存在Session,则初始化服务器),然后计算范围,根据参数返回范围内的地图路径。
地图保存后,通过Response.BinaryWrite向浏览器端发送,这种方式可以保护图片,例如可以将图片保存在通过Web服务器无法直接访问的地方,在返回图片时进行身份验证。
ps:
目前对于大多数开发者,最缺乏的是一个可用的、功能齐全的JS前端,MapEasy提供了基础的功能,如果可以在这基础上继续完善,是一件不错的事情。MapTools下的Kmap也是一个类似的东西,但由于和PHP绑定比较死,要在其他环境使用还需要一些工作。
通过透明图层叠加,或者在渲染端做一些工作,可以使类似应用增加图层功能,这样就可以用于比较专业的领域。