应用ArcIMS构建GMap风格的地图应用

Google Maps之前,各种 网络 地图 技术 上采用传统 WebGIS 的方式,使用Java Applet、SVG、动态生成地图图片,而Google Maps采用 Ajax 和瓦片拼接方案构建出的新的网络地图模式得到了广泛认同,一时间, 电子地图 服务的网站,除了少数外,几乎都采用或提供了这种模式的浏览方式。那么,传统的WebGIS是否也可以通过某种方式支持类似的地图 应用 呢,答案是肯定的。

上一篇关于 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绑定比较死,要在其他环境使用还需要一些工作。

通过透明图层叠加,或者在渲染端做一些工作,可以使类似应用增加图层功能,这样就可以用于比较专业的领域。
原文地址:https://www.cnblogs.com/maweifeng/p/483598.html