使用OpenLayers以切片方式調用mapxtreme java渲染出的地圖 2010-01-09 22:06 1353人閱讀 評論(11) 收藏 舉報
使用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這個庫進行地圖操作,或許現在要放棄這種思路了。
在此發帖,希望有達人解惑!!