系列文章目錄
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動态加載緊湊型切片。加載的結果如圖。
@{
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
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結。