在GIS中,當你拿到一個圖層的地理座標後,如果需要繪製到屏幕上,那麼不可避免的需要在地理座標和屏幕座標之間進行轉換,轉換的方法相信每一個做GIS的都會有自己的實現方法,本文描述的是和ArcGIS、WMS、OpenLayers完全一致的座標轉換方法,當然這三個工具、標準、腳本也是採用的相同的方法;
因爲採用完全一致的座標轉換方法,因此在我自己實現的WMS服務程序中提供的含透明通道的圖,可以完全和ArcGIS提供的圖在WEB客戶端進行精確的匹配;
現在來介紹座標轉換的原理,其實該原理很簡單,就是將視圖的中心點和視野的中心點進行配對,然後給定一個地理座標根據該座標和視野中心點的偏移和比例尺來進行計算就可以獲得屏幕座標,反之亦然;
下面就是將窗口座標轉換爲地理座標的代碼:
1
2
|
ptGeo.x
= geo_center_.x + ( ptWnd.x - see_center_.x ) * resolution_ ; ptGeo.y
= geo_center_.y - ( ptWnd.y - see_center_.y ) * resolution_ ; |
下面是將地理座標轉化爲窗口座標的代碼:
1
2
|
ptWnd.x
= see_center_.x + ( long )(
( ptGeo.x - geo_center_.x ) / resolution_ + 0.5 ); ptWnd.y
= see_center_.y - ( long )(
( ptGeo.y - geo_center_.y ) / resolution_ + 0.5 ); |
在上面的代碼中,see_center_ 是屏幕座標的窗口中心、geo_center_ 是地理座標的視野中心,而 resolution_ 就是當前的比例尺;
然而最關鍵的是,當傳入的視野和窗口的比例不一致時,如何進行處理,標準的做法就是分別計算水平和垂直的比例尺,然後取其中較大的那個值作爲比例尺,也就是說比例尺的調整向着地理視野更小的方向進行調整,參考如下的代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
void Coord_Transform::Reset_Resolution(
GeoRect & extent , DevRect & client ) { //
calc geo_center_ Member geo_center_.x
= ( extent.left + extent.right ) / 2.0 ; geo_center_.y
= ( extent.top + extent.bottom ) / 2.0 ; //
calc see_center_ Member see_center_.x
= ( client.left + client.right ) / 2 ; see_center_.y
= ( client.top + client.bottom ) / 2 ; //
calc resolution_ Member double RoH
= extent.Height( ) / client.Height( ); //
Resolution of Height double RoW
= extent.Width( ) / client.Width( ); //
Resolution of Width this ->resolution_
= RoH > RoW ? RoH : RoW ; this ->geo_change_
= true ; } |
在 WMS 協議中,如果請求的圖片大小和視野的寬高比不成比例時也是要求將圖片較小的一邊增加,讓地理視野和圖片的比例一致,然後進行繪製,最後一步將生成的圖片進行不等比放縮到原始請求的圖片大小,這是爲了保證客戶端採用非矩形點陣的顯示設備時能夠正常顯示地理圖;