使用OpenLayers以切片方式调用mapxtreme java渲染出的地图
使用OpenLayers以切片方式调用mapxtreme java渲染出的地图遇到的问题
---无法根据坐标范围获取精确范围的地图图片
1 简述
想要达到的目的:使用OpenLayers以切片方式调用mapxtreme java渲染出的地图
环境:mapxtreme java 4.8.1 + apache tomcat5.5 + OpenLayers
具体情况:使用MapXtreme JAVA根据坐标范围渲染地图时,渲染出来地图的范围与程序Set进去的坐标范围不一致。这就导致以切片形式请求的地图不能正常显示。
2 具体说明
个人实现了一个简单的OGC WMS,以Mapxtreme java作为地图来源,根据请求中的坐标范围以及请求图片的大小返回对应的地图图片,主要功能GETMAP实现的差不多不正常了,请看下图:了,也能出图了,但是却发现,如果以切片(tiled)的方式来请求地图,组合出来的地图就无法正常组合在一起了
图1:正常情况下mapxtreme显示的地图(singleTile=true)
图2:以切片形式请求返回的地图
图3:以切片形式请求返回的地图放大后
从上图可以看出切片地图的拼接出了问题,不能按正常情况显示,我开始检查自己写的代码,一行一行跟代码。
最终发现问题的所在,原来是mapxtreme对客户端的请求参数做了处理,它“优化”了客户端传进去的坐标范围,基本上我们无法获取我们想要的坐标范围的地图。
比如我们以坐标范围(45.0, 22.5, 67.5, 45.0)请求一张256*256像素大小的地图时,它使用坐标范围(37.06172554402468, 22.499855126681798, 78.20303563112182, 45.00029952050648)来渲染一张256*256的地图图片,也就是说mapxtreme java返回的图片对应的坐标范围“包含”了你请求的坐标范围,所有在使用OpenLayers进行请求时返回了无法正确组合的地图。
产生这种情况的可能原因:
1、 这是mapxtreme对地图显示的“优化”。Mapxtreme java这样设计的初衷可能是以更友好的方式显示地图,防止用户请求的图片扭曲。
2、 Mapxtreme java 在进行屏幕坐标与地理坐标转换的时候没有做到“精确”,从而影响了地图的输出。
个人认为时第一种原因可能性最大。至于第二种原因,如果mapinfo公司(现在应该是PB了)连屏幕坐标与地理坐标的转换都做不“精确”的话,那么mapinfo这个品牌也就该快退出GIS舞台了。
3 主要代码:
对应的参数值由servlet请求提供(这里没有贴出异常处理代码)
MapJ myMap = new MapJ();
myMap.loadMapDefinition(“D:/temp/world.mdf”);
System.out.println("User setBounds:" + new DoubleRect(x1, y1, x2, y2));
myMap.setBounds(new DoubleRect(x1, y1, x2, y2));
System.out.println("after setBounds: " + myMap.getBounds());
System.out.println("---------------------------------------");
myMap.setDeviceBounds(new DoubleRect(0, 0, width, height));
BufferedImage buffimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
LocalRenderer renderer = new LocalRenderer(buffimg);
ImageRequestComposer irc = ImageRequestComposer.create(
myMap, ImageRequestComposer.MAX_COLORS_TRUECOLOR, java.awt.Color.white, "image/png");
renderer.render(irc);
结果:
User setBounds is: (45.0, 22.5, 67.5, 45.0)
after setBounds: (37.06172554402468, 22.499855126681798, 78.20303563112182, 45.00029952050648)
---------------------------------------
User setBounds is: (22.5, 22.5, 45.0, 45.0)
after setBounds: (15.49842299530567, 22.499779394844932, 54.681248394867325, 45.000436451865)
---------------------------------------
User setBounds is: (0.0, 67.5, 22.5, 90.0)
after setBounds: (-5.506164807444929, 67.49941249738097, 36.7287746678222, 89.90020794487229)
---------------------------------------
User setBounds is: (22.5, 67.5, 45.0, 90.0)
after setBounds: (15.298770365092468, 67.49954934286292, 63.326133328274345, 89.89954380989911)
---------------------------------------
User setBounds is: (0.0, 45.0, 22.5, 67.5)
after setBounds: (-7.751736681286414, 44.999501713235716, 35.0333672831887, 67.50069049220401)
为了能实现我想要的功能,根据用户的坐标范围返回图像,我使用了暴力的方法-反射,不使用MapJ的setBounds方法,而是直接为其属性m_bounds赋值,但是结果还是一样。
4 结语
不知道是我对mapxtreme提供的方法不太熟悉,没有找到对应的方法来进行对应坐标范围的地图渲染,还是mapxtreme java没有提供这样的方法,现在无法完成想要的功能。
本想扩展一下mapinfo,使其能支持OGC WMS,以更好地使用OpenLayers这个库进行地图操作,或许现在要放弃这种思路了。
在此发帖,希望有达人解惑!!