天天看點

ArcGIS緊湊型切片讀取與應用2-webgis動态加載緊湊型切片(附源碼)

系列文章目錄

ArcGIS緊湊型切片讀取與應用1-解析(附源碼)

ArcGIS緊湊型切片讀取與應用2-webgis動态加載緊湊型切片(附源碼)

ArcGIS緊湊型切片讀取與應用3-緊湊型批量轉分散型(附源碼)

1.前言

     上篇主要講了一下緊湊型切片的的解析邏輯,這一篇主要講一下使用openlayers動态加載緊湊型切片的web地圖服務。

2.代碼實作

    上篇已經可以通過切片的x、y、z得對應的切片圖檔,現在使用asp.net mvc方式提供讀取服務,這裡有一問題就是頻繁打開切檔案會存在資源未釋放的占用的情況,導緻請求失敗,這裡使用單例模式保證相同切片檔案隻打開一次,并且提供檔案緩存與過期釋放機制,加快服務的請求傳回速率。

1.切片請求服務入口,提供基本的參數x、y、z以及緊湊切片檔案路徑,系統傳回對應的切片資料。

// 切片請求控制器
public ActionResult GetTile(int x, int y, int z)
{
     try
     {
         ArcgisBundleHelper Helper = new ArcgisBundleHelper(@"G:\feiq\Recv Files\Map_test\map");
         var data = Helper.GetTile(x, y, z);
         return File(data, "image/jpeg");
     }
     catch (Exception ex)
     {
         throw;
     }
}      

2.單例模式實作的切檔案緩存類,實作切片檔案的新增緩存、過期緩存清除,以及通過索引的方式通路切片檔案。

/// <summary>
/// 緩存切片單例類
/// </summary>
public class TileCache
{
     /// <summary>
     /// 擷取切片檔案索引
     /// </summary>
     /// <param name="id"></param>
     /// <returns></returns>
     public BundleCache this[bundlx id]
     {
         get
         {
                 lock (obj)
                 {
                     return AddBundleCache(id);
                 }

        }
     }
     private static volatile TileCache instance;
     private static readonly object obj = new object();
     private TileCache() { }
     //線程安全單例
     public static TileCache Instance
     {
         get
         {
             if (null == instance)
             {
                 lock (obj)
                 {
                     if (null == instance)
                     {
                         instance = new TileCache();
                     }
                 }

            }
             return instance;
         }
     }
     /// <summary>
     /// 設定最多緩存檔案數目
     /// </summary>
     private static int cacheCount = 20;
     /// <summary>
     /// 切片檔案緩存集合類
     /// </summary>
     private static List<BundleCache> bundleCacheList = new List<BundleCache>();
     /// <summary>
     /// 通過id傳回切片緩存
     /// </summary>
     /// <param name="cache"></param>
     /// <returns></returns>
     private static BundleCache AddBundleCache(bundlx cache)
     {
         string cacheid = cache.id;

            if (bundleCacheList.Select(e => e.BundleId).ToList().Contains(cacheid))
             {
                 //更新最後通路時間
                 BundleCache tem = bundleCacheList.Where(e => e.BundleId == cacheid).FirstOrDefault();
                 tem.LastTime = DateTime.Now;
                 changeCache();
                 return bundleCacheList.Where(e => e.BundleId == cacheid).FirstOrDefault();
             }
             else
             {
                 //未添加的檔案,寫入緩存集合
                 BundleCache bc = new BundleCache();
                 bc.BundleId = cache.id;
                 bc.CTime = DateTime.Now;
                 bc.LastTime = DateTime.Now;
                 using (FileStream file = new FileStream(cache.bundlxFileName, FileMode.Open))
                 {
                     byte[] bufferfile = new byte[file.Length];
                     file.Read(bufferfile, 0, (int)file.Length);
                     //寫入資料
                     bc.BundlxData = bufferfile;
                 }
                 using (FileStream file = new FileStream(cache.bundleFileName, FileMode.Open))
                 {
                     byte[] bufferfile = new byte[file.Length];
                     file.Read(bufferfile, 0, (int)file.Length);
                     //寫入資料
                     bc.BundleData = bufferfile;
                 }
                 bundleCacheList.Add(bc);
                 changeCache();
                 return bc;
         }
     }
     /// <summary>
     /// 保證緩存檔案數目一定
     /// </summary>
     private static void changeCache()
     {
         if (bundleCacheList.Count>cacheCount)
         {
             bundleCacheList= bundleCacheList.OrderByDescending(e => e.LastTime).ToList().Take(cacheCount).ToList();
         }
     }
}      

3.我們的服務位址為 "/Tile/GetTile?x={x}&y={y}&z={z}",使用openlayers動态加載緊湊型切片。加載的結果如圖。

ArcGIS緊湊型切片讀取與應用2-webgis動态加載緊湊型切片(附源碼)
@{
     ViewBag.Title = "Index";
     Layout = null;
}
<style>

    html, body, #map {
         height: 100%;
         width: 100%;
         margin: 0;
         padding: 0;
     }
</style>
<div id="map">

</div>
<script src="~/Content/openlayer4.64/ol.js"></script>
<script type="text/javascript">
     var mapurl = "/Tile/GetTile?x={x}&y={y}&z={z}";
     var maplayer = new ol.layer.Tile({
         name: "testLayer",
         // 瓦片圖像資料源
         source: new ol.source.XYZ({
             crossOrigin: 'anonymous',
             url: mapurl
         }),
         opacity: 1
     });
     var map = new ol.Map({
         target: 'map',
         layers: [
             maplayer
         ],
         view: new ol.View({
             center: ol.proj.fromLonLat([104.41, 33.82]),
             zoom: 4
         })
     });
</script>      

3.結束

     上面方法使用動态解析緊湊型切片的方式,實作webgis的實時加載功能,由于是動态解析檔案,傳回的效率不高,下一篇我們開發一個程式,實作從緊湊型切片批量轉為分散型切片的方法。

百度網盤連結:https://pan.baidu.com/s/1I-Bj3EQSN57pQHvKZ2hBUA   提取碼:lliw

github項目位址:https://github.com/HuHongYong/TilerArcgisBundle

作者:ATtuing

出處:http://www.cnblogs.com/ATtuing

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結。