文章版權由做者李曉暉和博客園共有,若轉載請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/。html
這周利用晚上在家時間研究了下如何使用AE來開發切圖工具。最初的想法是直接調用GP服務,利用CreateMapServerCache 、ManageMapServerCacheTiles 和Geoprocessor 這樣三個類來作。可是這個思路有個巨大的弊端就是必須先發布地圖服務。因而接下來又立刻轉換思路,想可否經過瓦片選址算法以及AE的一些細粒度類來實現這個功能。在通過了三個晚上的算法編寫和功能編寫後,整個工具基本成型,其中包括了對算法的優化以及一些具體問題的解決。這裏跟你們大體分享下。算法
若是對瓦片和瓦片尋址的相關算法不熟悉的朋友,請參考我寫的從底層探究WebGIS的原理系列:http://www.cnblogs.com/naaoveGIS/category/600559.html。數組
這裏我直接給出所涉及到的幾個公式。微信
resolution=scale*inch2centimeter/dpi。其中scale是地圖比例尺,inch2centimeter爲英寸轉釐米的參數,dpi爲1英寸所包含的像素。工具
假設,地圖切圖的原點是(originX,oringinY),地圖的瓦片大小是tileSize,地圖屏幕上1像素表明的實際距離是resolution。計算座標點(x,y)所在的瓦片的行列號的公式是:優化
col = floor((originX- x)/( tileSize*resolution))spa
row = floor((oringinY - y)/( tileSize*resolution))htm
本工具的目標是切出與AGS瓦片相同格式的瓦片。AGS的瓦片具備如下特色(在http://www.cnblogs.com/naaoveGIS/p/3903270.html我作了詳細的講解):blog
(a).L開頭的表明了Level,R開頭的表明了row,C開頭的表明了Col。索引
(b). L後的數字是兩位字符串,R後的是八位字符串,C後的也是八位字符串。
(c).英文後的數字均是16進制數,而後不足位數的用0補充。
咱們首先得到用戶輸入的切圖級別數組levelScaleArr,瓦片大小(imgWidth,imgHeight),切圖原點(originX,originY)還有像素值DPI。同時咱們還要經過接口得到此時地圖的範圍(dXMin,dYMin,dXMax,dYMax)。
流程的盒模型以下所示:
實現上,主要使用了AE作了這樣幾個功能:
(a).使用IMapControl類得到mxd的四角座標。
(b).使用IActiveView、ExportPNGClass和EnvelopeClass實現將地圖局部導出功能。
其餘均按照上述流程圖實現。
在AE中能夠導出多種格式的圖片。利用ExportJPEGClass(),ExportBMPClass(),ExportEMFClass(),ExportGIFClass()等便可實現。
經過上面的類直接導出的圖片其背景色默認爲了白色。而AGS切圖中,背景色是透明的,因此這裏還要作一個圖片透明度優化過程。C#中轉成Bitmap後,利用該類自帶的MakeTransparent便可實現。
在流程中,咱們默認的切圖是從切圖原點開始的,這樣會切成不少不少的無用圖。咱們能夠直接從離地圖DXmin和DYmax最近處開始切圖便可。
startXByLevel = (int)Math.Abs((Math.Floor((DXmin-originX) / dImageWidth)));
startYByLevel = (int)Math.Abs((Math.Floor((originY-DYMax) / dImageHeight)));
startXByLevel和startYByLevel即爲X軸和Y軸的切圖初始點。
咱們常常會切出整張圖都是透明的空白圖。可是在AGS的切圖中,是看不到這樣的無效圖的。咱們能夠在切圖時先判斷此範圍內是否有要素存在,有的話就切,沒有的話,continue掉。這樣也能夠減小切圖的數目。
目前上面的全部過程,均只對作了投影轉換的mxd有效,可是若是咱們的mxd中的座標系無投影轉換隻有一個地理座標系呢,也就是當地圖爲經緯度座標時,此時該如何實現切圖?
其實思路也很簡單,若是咱們真正理解以上resolution的所表明實際意義,那麼解決這個問題的思路就應該有了。
當地圖爲經緯度時,咱們切圖的比例尺設置應該改成切圖的分辨率設置。這樣咱們就直接獲得了每一個級別的resolution,而後用resolution來切圖便可。不用再作以上的將比例尺轉換爲resolution的步驟。
在levelScaleArr中,裏面的比例尺數字是隨着index增長而增長的,可是比例尺數字越大,其對應的Level是越小的。因此咱們在遍歷Level層時,應該是一個遞減的遍歷,這樣生成的L文件夾的編號纔是正確的。
如下是效果圖:
(a).目前沒法切出緊湊型(Compact)瓦片。解決思路,用上面的方法導出圖後,須要把圖變成二進制而後按照bundle的格式從新生成,而且還要生成索引文件bundleX。
(b).所用的AE畢竟是封裝的很好的組件庫了。用GDAL的話,因爲封裝層次低一些,效率應該會更好一些。
-----歡迎轉載,但保留版權,請於明顯處標明出處:http://www.cnblogs.com/naaoveGIS/
若是您以爲本文確實幫助了您,能夠微信掃一掃,進行小額的打賞和鼓勵,謝謝 ^_^