You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
993 lines
36 KiB
993 lines
36 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Text; |
|
using ESRI.ArcGIS.Geometry; |
|
using System.Drawing.Imaging; |
|
using ESRI.ArcGIS.Display; |
|
using ESRI.ArcGIS.Output; |
|
using System.IO; |
|
using System.Data.SQLite; |
|
using ESRI.ArcGIS.esriSystem; |
|
|
|
namespace Kingo.Plugin.MakeTaskPackage.Entity |
|
{ |
|
public class CutTiles |
|
{ |
|
|
|
public string LayerName { get; set; } |
|
public int CutIndex { get; set; } |
|
public System.Windows.Forms.GroupBox groupBox { get; set; } |
|
/// <summary> |
|
/// 图片类型 |
|
/// </summary> |
|
public ImageFormat ImgFormat { get; set; } |
|
/// <summary> |
|
/// 层级 |
|
/// </summary> |
|
public int MaxLevel { get; set; } |
|
|
|
/// <summary> |
|
/// 最新层级 |
|
/// </summary> |
|
public int MinLevel { get; set; } |
|
|
|
/// <summary> |
|
/// 是否加密 |
|
/// </summary> |
|
public bool IsEncrypt { get; set; } |
|
|
|
private int tileSize = 256; |
|
/// <summary> |
|
/// 瓦片大小 |
|
/// </summary> |
|
public int TileSize |
|
{ |
|
get { return tileSize; } |
|
set |
|
{ |
|
tileSize = value; |
|
exportRECT = new tagRECT() |
|
{ |
|
top = 0, |
|
left = 0, |
|
right = value, |
|
bottom = value |
|
}; |
|
pixelBounds.PutCoords(exportRECT.left, exportRECT.top, exportRECT.right, exportRECT.bottom); |
|
pExport.Resolution = 96; |
|
pExport.PixelBounds = pixelBounds; |
|
} |
|
} |
|
/// <summary> |
|
/// mxd路径 |
|
/// </summary> |
|
public string MxdPath { get; set; } |
|
/// <summary> |
|
/// 瓦片文件保存路径 |
|
/// </summary> |
|
public string TilesDBPath { get; set; } |
|
|
|
/// <summary> |
|
/// 分块总数 |
|
/// </summary> |
|
public int BlockHorizontalCount { get; set; } |
|
|
|
public int BlockVerticalCount { get; set; } |
|
/// <summary> |
|
/// 选择分块索引 |
|
/// </summary> |
|
public int BlockIndex { get; set; } |
|
|
|
public bool IsBlock { get; set; } |
|
|
|
/// <summary> |
|
/// 最大比例尺 |
|
/// </summary> |
|
public int MaxScale { get; set; } |
|
|
|
public int MinScale { get; set; } |
|
/// <summary> |
|
/// 切片区域类型 |
|
/// </summary> |
|
public CUTAreaType CutType { get; set; } |
|
|
|
/// <summary> |
|
/// 自定义区域 |
|
/// </summary> |
|
public IEnvelope CustomArea { get; set; } |
|
|
|
public IGeometry CustomGeometry { get; set; } |
|
|
|
public string Projection { get; set; } |
|
|
|
public ESRI.ArcGIS.Controls.AxMapControl axMap { get; set; } |
|
|
|
/// <summary> |
|
/// 瓦片大小 |
|
/// </summary> |
|
private tagRECT exportRECT = new tagRECT(); |
|
|
|
/// <summary> |
|
/// 导出格式 |
|
/// </summary> |
|
private ExportPNGClass pExport = new ExportPNGClass(); |
|
private int hdc; |
|
private IEnvelope pixelBounds = new EnvelopeClass(); |
|
|
|
|
|
public CutTiles() |
|
{ |
|
ImgFormat = ImageFormat.Png; |
|
} |
|
|
|
/// <summary> |
|
/// 获取指定范围外正方形 |
|
/// </summary> |
|
/// <param name="e"></param> |
|
/// <returns></returns> |
|
private IEnvelope GetExtentSquare(IEnvelope e) |
|
{ |
|
IEnvelope extent = new EnvelopeClass() |
|
{ |
|
XMax = e.XMax, |
|
XMin = e.XMin, |
|
YMax = e.YMax, |
|
YMin = e.YMin |
|
}; |
|
double del = (extent.Width - extent.Height) / 2; |
|
if (del > 0) |
|
{ |
|
extent.YMax += del; |
|
extent.YMin -= del; |
|
} |
|
else |
|
{ |
|
extent.XMax -= del; |
|
extent.XMin += del; |
|
} |
|
//extent.XMax += extent.Width/ 16; |
|
//extent.XMin -= extent.Width / 16; |
|
//extent.YMax += extent.Width / 16; |
|
//extent.YMin -= extent.Width / 16; |
|
return extent; |
|
} |
|
|
|
/// <summary> |
|
/// 获取指定范围外正方形 |
|
/// </summary> |
|
/// <param name="e"></param> |
|
/// <returns></returns> |
|
private IEnvelope GetExtentSquareLevel(IEnvelope e) |
|
{ |
|
IEnvelope extent = new EnvelopeClass() |
|
{ |
|
XMax = e.XMax, |
|
XMin = e.XMin, |
|
YMax = e.YMax, |
|
YMin = e.YMin |
|
}; |
|
double del = ((extent.XMax - extent.XMin) - (extent.YMax - extent.YMin)) / 2; |
|
if (del > 0) |
|
{ |
|
extent.YMax += del; |
|
extent.YMin -= del; |
|
} |
|
else |
|
{ |
|
extent.XMax -= del; |
|
extent.XMin += del; |
|
} |
|
return extent; |
|
} |
|
|
|
public void CreateMxdFileKOTilesByLevel() |
|
{ |
|
//获取地图最大范围 |
|
ProcessMXDClass pr = new ProcessMXDClass(); |
|
IEnvelope en = pr.GetMapEnvelope(MxdPath); |
|
IEnvelope extentAll = GetExtentSquareLevel(en); |
|
IEnvelope extent = null; |
|
|
|
extent = extentAll; |
|
|
|
//获取所有瓦片 |
|
List<TileInfo> allTiles = GetAllTiles(extent); |
|
|
|
SQLiteConnection conn = CreateDataBaseLevel(extent); |
|
|
|
pWriteDatabase = new WriteTilesToDataBase() |
|
{ |
|
Conn = conn, |
|
TileCount = allTiles.Count |
|
}; |
|
pWriteDatabase.Done += (s, e) => |
|
{ |
|
this.CreatDown(s, e); |
|
}; |
|
pWriteDatabase.Report += (s, e) => |
|
{ |
|
if (Report != null) |
|
{ |
|
Report(s, e); |
|
} |
|
}; |
|
pWriteDatabase.DoWorkLevel(); |
|
try |
|
{ |
|
ReadTilesData readTiles = new ReadTilesData() |
|
{ |
|
axMap = this.axMap.Object as ESRI.ArcGIS.Controls.IMapControl3, |
|
groupBox = this.groupBox, |
|
ImgFormat = this.ImgFormat, |
|
Level = this.MaxLevel, |
|
MxdPath = this.MxdPath, |
|
TileInfos = allTiles, |
|
TilesDBPath = this.TilesDBPath, |
|
TileSize = this.TileSize, |
|
CustomGeometry = this.CustomGeometry, |
|
writeDb = pWriteDatabase, |
|
LayerName = this.LayerName |
|
}; |
|
readTiles.DoworkLevel(); |
|
readTilesList.Add(readTiles); |
|
|
|
} |
|
catch (Exception ex) |
|
{ |
|
throw; |
|
} |
|
finally |
|
{ |
|
|
|
} |
|
|
|
} |
|
|
|
public void Stop() |
|
{ |
|
if (this.pWriteDatabase != null) |
|
{ |
|
pWriteDatabase.Stop(); |
|
pWriteDatabase = null; |
|
} |
|
if (readTilesList == null) return; |
|
foreach (var item in readTilesList) |
|
{ |
|
item.Stop(); |
|
} |
|
} |
|
|
|
|
|
private List<ReadTilesData> readTilesList = new List<ReadTilesData>(); |
|
private WriteTilesToDataBase pWriteDatabase = null; |
|
IEnvelope extentMax; |
|
public void CreateMxdFileKOTilesThread(int threadnumber) |
|
{ |
|
//获取地图最大范围 |
|
threadnumber = 1; |
|
ProcessMXDClass pr = new ProcessMXDClass(); |
|
IEnvelope en = pr.GetMapEnvelope(MxdPath); |
|
|
|
//指定区域 |
|
if (CutType == CUTAreaType.自定义) |
|
{ |
|
//extentMax = GetExtentSquare(CustomArea); |
|
en = CustomArea; |
|
} |
|
extentMax = GetExtentSquare(en); |
|
//获取所有瓦片 |
|
//List<TileInfo> allTiles = GetAllTiles1(extentMax); |
|
List<TilesParam> allTilesParam = GetAllTiles3(extentMax); |
|
|
|
SQLiteConnection conn = CreateDataBase(IsEncrypt); |
|
int allTilesCount = 0; |
|
foreach (TilesParam item in allTilesParam) |
|
{ |
|
allTilesCount += item.RowCount * (item.EndCol - item.StartCol) * item.CutMultiple * item.CutMultiple; |
|
} |
|
|
|
pWriteDatabase = new WriteTilesToDataBase() |
|
{ |
|
Conn = conn, |
|
TileCount = allTilesCount |
|
}; |
|
pWriteDatabase.Done += (s, e) => |
|
{ |
|
this.CreatDown(s, e); |
|
}; |
|
pWriteDatabase.Report += (s, e) => |
|
{ |
|
if (Report != null) |
|
{ |
|
Report(s, e); |
|
} |
|
}; |
|
pWriteDatabase.DoWork(); |
|
|
|
|
|
int start = 0; |
|
int count = allTilesCount / threadnumber; |
|
for (int i = 0; i < threadnumber; i++) |
|
{ |
|
if (i == threadnumber - 1) |
|
{ |
|
count += allTilesCount % threadnumber; |
|
} |
|
List<TileInfo> tileGroup = null; //allTiles.GetRange(start, count); |
|
//List<TileInfo> tileGroup = allTiles[0]; |
|
start += count; |
|
ReadTilesData readTiles = new ReadTilesData() |
|
{ |
|
axMap = this.axMap.Object as ESRI.ArcGIS.Controls.IMapControl3, |
|
groupBox = this.groupBox, |
|
ImgFormat = this.ImgFormat, |
|
Level = this.MaxLevel, |
|
MxdPath = this.MxdPath, |
|
TileInfos = tileGroup, |
|
TilesParams = allTilesParam, |
|
TilesDBPath = this.TilesDBPath, |
|
TileSize = this.TileSize, |
|
CustomGeometry = this.CustomGeometry, |
|
writeDb = pWriteDatabase, |
|
LayerName = this.LayerName |
|
}; |
|
readTiles.Dowork(); |
|
readTilesList.Add(readTiles); |
|
} |
|
|
|
|
|
} |
|
|
|
public void CreateMxdFileKotiles(int threadnumber = 1) |
|
{ |
|
//获取地图最大范围 |
|
|
|
ProcessMXDClass pr = new ProcessMXDClass(); |
|
IEnvelope en = pr.GetMapEnvelope(MxdPath); |
|
extentMax = GetExtentSquare(en); |
|
|
|
|
|
//指定区域 |
|
if (CutType == CUTAreaType.自定义) |
|
{ |
|
//extentMax = GetExtentSquare(CustomArea); |
|
extentMax = CustomArea; |
|
} |
|
//获取所有瓦片 |
|
List<TileInfo> allTiles = GetAllTiles1(extentMax); |
|
SQLiteConnection conn = CreateDataBase(IsEncrypt); |
|
pWriteDatabase = new WriteTilesToDataBase() |
|
{ |
|
Conn = conn, |
|
TileCount = allTiles.Count |
|
}; |
|
pWriteDatabase.Done += (s, e) => |
|
{ |
|
this.CreatDown(s, e); |
|
}; |
|
pWriteDatabase.Report += (s, e) => |
|
{ |
|
if (Report != null) |
|
{ |
|
Report(s, e); |
|
} |
|
}; |
|
pWriteDatabase.DoWork(); |
|
|
|
int start = 0; |
|
int count = allTiles.Count / threadnumber; |
|
|
|
for (int i = 0; i < threadnumber; i++) |
|
{ |
|
if (i == threadnumber - 1) |
|
{ |
|
count += allTiles.Count % threadnumber; |
|
} |
|
List<TileInfo> tileGroup = allTiles.GetRange(start, count); |
|
|
|
start += count; |
|
ReadTilesData readTiles = new ReadTilesData() |
|
{ |
|
axMap = this.axMap.Object as ESRI.ArcGIS.Controls.IMapControl3, |
|
groupBox = this.groupBox, |
|
ImgFormat = this.ImgFormat, |
|
Level = this.MaxLevel, |
|
MxdPath = this.MxdPath, |
|
TileInfos = tileGroup, |
|
TilesDBPath = this.TilesDBPath, |
|
TileSize = this.TileSize, |
|
CustomGeometry = this.CustomGeometry, |
|
writeDb = pWriteDatabase |
|
}; |
|
readTiles.DoworkNoThread(); |
|
readTilesList.Add(readTiles); |
|
} |
|
|
|
} |
|
|
|
private SQLiteConnection CreateDataBase(bool isEncrypt) |
|
{ |
|
string connString = "Data Source=" + this.TilesDBPath; |
|
if (File.Exists(this.TilesDBPath)) |
|
{ |
|
GC.Collect(); |
|
System.Windows.Forms.Application.DoEvents(); |
|
try |
|
{ |
|
File.Delete(this.TilesDBPath); |
|
} |
|
catch (Exception ex) |
|
{ |
|
throw new Exception("输出文件监测到被占用,请重试!"); |
|
|
|
} |
|
} |
|
string dir = System.IO.Path.GetDirectoryName(this.TilesDBPath); |
|
if (!Directory.Exists(dir)) |
|
{ |
|
Directory.CreateDirectory(dir); |
|
} |
|
// File.WriteAllBytes(this.TilesDBPath, Properties.Resources.Template); |
|
|
|
string path = System.IO.Path.Combine(Activator.bundle.Location, "Resources", "Template.kotiles"); |
|
if (File.Exists(path)) |
|
{ |
|
File.Copy(path, this.TilesDBPath, true); |
|
} |
|
System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection(connString); |
|
conn.Open(); |
|
try |
|
{ |
|
SQLiteTransaction pTan = conn.BeginTransaction(); |
|
SQLiteCommand cmd = new SQLiteCommand(conn); |
|
string sqlFormat = "insert into metadata values('{0}','{1}')"; |
|
//写入图片大小 |
|
cmd.CommandText = string.Format(sqlFormat, "Size", isEncrypt ? EnCode(this.TileSize) : this.TileSize.ToString()); |
|
cmd.ExecuteNonQuery(); |
|
//写入图片格式 |
|
cmd.CommandText = string.Format(sqlFormat, "Format", isEncrypt ? EnCode(ImgFormat.ToString()) : ImgFormat.ToString()); |
|
cmd.ExecuteNonQuery(); |
|
//写入空间参考 |
|
//List<Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct> spList = Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct.GetAllData(); |
|
//Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct sp = spList.Find(p => p.WKID == this.axMap.SpatialReference.FactoryCode); |
|
cmd.CommandText = string.Format(sqlFormat, "Projection", isEncrypt ? EnCode(Projection) : Projection); |
|
cmd.ExecuteNonQuery(); |
|
//写入Extend |
|
cmd.CommandText = string.Format(sqlFormat, "Bounds", |
|
isEncrypt ? EnCode(string.Format("{0},{1},{2},{3}", this.extentMax.XMin, extentMax.YMin, extentMax.XMax, extentMax.YMax)) : string.Format("{0},{1},{2},{3}", this.extentMax.XMin, extentMax.YMin, extentMax.XMax, extentMax.YMax)); |
|
cmd.ExecuteNonQuery(); |
|
//写入origin |
|
cmd.CommandText = string.Format(sqlFormat, "Origin", |
|
isEncrypt ? EnCode(string.Format("{0},{1}", extentMax.XMin, extentMax.YMax)) : string.Format("{0},{1}", extentMax.XMin, extentMax.YMax)); |
|
cmd.ExecuteNonQuery(); |
|
////写入分辨率 |
|
//double dbResolution = extentMax.Width / this.tileSize; |
|
//cmd.CommandText = string.Format(sqlFormat, "Resolution", dbResolution); |
|
//cmd.ExecuteNonQuery(); |
|
////写入比例尺 |
|
//double dbScale = (96 / 0.0254) * dbResolution; |
|
//cmd.CommandText = string.Format(sqlFormat, "Scale", dbScale); |
|
//cmd.ExecuteNonQuery(); |
|
//写入分辨率 |
|
double dbResolution = (this.MinScale * 1.0) / (96 / 0.0254); |
|
cmd.CommandText = string.Format(sqlFormat, "Resolution", isEncrypt ? EnCode(dbResolution) : dbResolution.ToString()); |
|
cmd.ExecuteNonQuery(); |
|
//写入比例尺 |
|
double dbScale = (96 / 0.0254) * dbResolution; |
|
cmd.CommandText = string.Format(sqlFormat, "Scale", isEncrypt ? EnCode(this.MinScale) : this.MinScale.ToString()); |
|
cmd.ExecuteNonQuery(); |
|
//写入Level |
|
cmd.CommandText = string.Format(sqlFormat, "Level", isEncrypt ? EnCode(this.MaxLevel) : this.MaxLevel.ToString()); |
|
cmd.ExecuteNonQuery(); |
|
|
|
//写入Kingo |
|
cmd.CommandText = string.Format(sqlFormat, "Kingo", isEncrypt); |
|
cmd.ExecuteNonQuery(); |
|
cmd.Dispose(); |
|
pTan.Commit(); |
|
pTan.Dispose(); |
|
} |
|
catch (Exception ex) |
|
{ |
|
throw; |
|
} |
|
finally |
|
{ |
|
conn.Close(); |
|
GC.Collect(); |
|
} |
|
return conn; |
|
} |
|
|
|
private SQLiteConnection CreateDataBaseLevel(IEnvelope extent) |
|
{ |
|
string connString = "Data Source=" + this.TilesDBPath; |
|
if (File.Exists(this.TilesDBPath)) |
|
{ |
|
GC.Collect(); |
|
System.Windows.Forms.Application.DoEvents(); |
|
try |
|
{ |
|
File.Delete(this.TilesDBPath); |
|
} |
|
catch (Exception ex) |
|
{ |
|
throw new Exception("输出文件监测到被占用,请重试!"); |
|
|
|
} |
|
} |
|
string dir = System.IO.Path.GetDirectoryName(this.TilesDBPath); |
|
if (!Directory.Exists(dir)) |
|
{ |
|
Directory.CreateDirectory(dir); |
|
} |
|
// File.WriteAllBytes(this.TilesDBPath, Properties.Resources.model); |
|
|
|
|
|
string path = System.IO.Path.Combine(Activator.bundle.Location, "Resources", "model.kotiles"); |
|
if (File.Exists(path)) |
|
{ |
|
File.Copy(path, this.TilesDBPath, true); |
|
} |
|
|
|
|
|
|
|
System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection(connString); |
|
conn.Open(); |
|
try |
|
{ |
|
SQLiteTransaction pTan = conn.BeginTransaction(); |
|
SQLiteCommand cmd = new SQLiteCommand(conn); |
|
|
|
//cmd.CommandText = "CREATE INDEX tiles_index ON tiles (zoom_level,tile_column,tile_row);"; |
|
//cmd.ExecuteNonQuery(); |
|
string sqlFormat = "insert into metadata values('{0}','{1}')"; |
|
//写入图片大小 |
|
cmd.CommandText = string.Format(sqlFormat, "Size", this.TileSize); |
|
cmd.ExecuteNonQuery(); |
|
//写入图片格式 |
|
cmd.CommandText = string.Format(sqlFormat, "Format", "png"); |
|
cmd.ExecuteNonQuery(); |
|
//写入空间参考 |
|
//List<Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct> spList = Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct.GetAllData(); |
|
//Kingo.Mobile.Shape2KOTool.SpatialRefrenceStruct sp = spList.Find(p => p.WKID == this.axMap.SpatialReference.FactoryCode); |
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Projection", Projection); |
|
cmd.ExecuteNonQuery(); |
|
//写入Extend |
|
cmd.CommandText = string.Format(sqlFormat, "Bounds", |
|
string.Format("{0},{1},{2},{3}", extent.XMin, extent.YMin, extent.XMax, extent.YMax)); |
|
cmd.ExecuteNonQuery(); |
|
//写入origin |
|
cmd.CommandText = string.Format(sqlFormat, "Origin", |
|
string.Format("{0},{1}", extent.XMin, extent.YMax)); |
|
cmd.ExecuteNonQuery(); |
|
//写入分辨率 |
|
double dbResolution = WriteTilesToDataBase.GetDistance(extent.YMax, extent.XMax, extent.YMin, extent.XMax) / this.TileSize; |
|
cmd.CommandText = string.Format(sqlFormat, "Resolution", dbResolution); |
|
cmd.ExecuteNonQuery(); |
|
//写入比例尺 |
|
double dbScale = (96 / 0.0254) * dbResolution; |
|
cmd.CommandText = string.Format(sqlFormat, "Scale", dbScale); |
|
cmd.ExecuteNonQuery(); |
|
//写入Level |
|
cmd.CommandText = string.Format(sqlFormat, "Level", this.MaxLevel); |
|
cmd.ExecuteNonQuery(); |
|
cmd.Dispose(); |
|
pTan.Commit(); |
|
pTan.Dispose(); |
|
} |
|
catch (Exception ex) |
|
{ |
|
throw; |
|
} |
|
finally |
|
{ |
|
conn.Close(); |
|
GC.Collect(); |
|
} |
|
return conn; |
|
} |
|
|
|
|
|
private string EnCode(object value) |
|
{ |
|
if (value == null) |
|
return ""; |
|
string str = value.ToString(); |
|
if (string.IsNullOrEmpty(str)) |
|
return ""; |
|
string outStr = ""; |
|
foreach (char item in str) |
|
{ |
|
outStr += (char)(item + 22); |
|
} |
|
return outStr; |
|
} |
|
|
|
public event EventHandler CreatDown; |
|
public event ProgressReport Report; |
|
|
|
/// <summary> |
|
/// 创建单个瓦片 |
|
/// </summary> |
|
/// <param name="tileInfo"></param> |
|
private void CreateKOTiles(TileInfo tileInfo) |
|
{ |
|
string dir = System.Windows.Forms.Application.StartupPath + "\\Tiles"; |
|
if (!System.IO.Directory.Exists(dir)) |
|
{ |
|
System.IO.Directory.CreateDirectory(dir); |
|
} |
|
pExport.ExportFileName = string.Format("{0}\\{1}-{2}-{3}.png", dir, tileInfo.Level, tileInfo.Column, tileInfo.Row); |
|
#region |
|
|
|
#endregion |
|
hdc = pExport.StartExporting(); |
|
axMap.ActiveView.Output(hdc, (int)pExport.Resolution, ref exportRECT, tileInfo.Bound, null); |
|
pExport.FinishExporting(); |
|
pExport.Cleanup(); |
|
byte[] bytes = File.ReadAllBytes(pExport.ExportFileName); |
|
tileInfo.Data = bytes; |
|
File.Delete(pExport.ExportFileName); |
|
|
|
} |
|
|
|
/// <summary> |
|
/// 获取所有瓦片信息 |
|
/// </summary> |
|
/// <param name="extent"></param> |
|
/// <returns></returns> |
|
private List<TileInfo> GetAllTiles(IEnvelope extent) |
|
{ |
|
List<TileInfo> tiles = new List<TileInfo>(); |
|
double originX = extent.XMin; |
|
double originY = extent.YMax; |
|
for (int level = MinLevel - 1; level < MaxLevel; level++) |
|
{ |
|
int count = (int)Math.Pow(2, level); |
|
int startCol = 0; |
|
int endCol = count; |
|
if (level > 3 && CutType == CUTAreaType.自动分块) |
|
{ |
|
int delCount = count / this.BlockHorizontalCount; |
|
startCol = (this.BlockIndex - 1) * delCount; |
|
endCol = this.BlockIndex * delCount; |
|
} |
|
|
|
double del = extent.Width / count; |
|
for (int col = startCol; col < endCol; col++) |
|
{ |
|
for (int row = 0; row < count; row++) |
|
{ |
|
double minx = originX + col * del; |
|
double maxy = originY - row * del; |
|
IEnvelope e = new EnvelopeClass() |
|
{ |
|
XMin = minx, |
|
YMin = maxy - del, |
|
XMax = minx + del, |
|
YMax = maxy |
|
}; |
|
tiles.Add(new TileInfo(e, level, row, col)); |
|
} |
|
} |
|
} |
|
return tiles; |
|
} |
|
|
|
private List<TileInfo> GetAllTiles1(IEnvelope extent) |
|
{ |
|
double maxDistance = extent.XMax - extent.XMin; |
|
double originX = extent.XMin; |
|
double originY = extent.YMax; |
|
List<TileInfo> tiles = new List<TileInfo>(); |
|
|
|
List<int> scales = GetAllScale(MaxScale, maxDistance); |
|
if (scales == null || scales.Count <= 0) return tiles; |
|
|
|
MaxLevel = 0; |
|
for (int i = scales.Count - 1; i >= 0; i--) |
|
{ |
|
|
|
double distanceNow = scales[i] * TileSize * 0.0254 / 96; |
|
int count = (int)(maxDistance / distanceNow); |
|
if (maxDistance % distanceNow != 0) |
|
{ |
|
count = count + 1; |
|
} |
|
int startCol = 0; |
|
int endCol = count; |
|
if (count > 1 && CutType ==CUTAreaType.自动分块) |
|
{ |
|
int delCount = count / this.BlockHorizontalCount; |
|
startCol = (this.BlockIndex - 1) * delCount; |
|
endCol = this.BlockIndex * delCount; |
|
} |
|
for (int col = startCol; col < endCol; col++) |
|
{ |
|
for (int row = 0; row < count; row++) |
|
{ |
|
double minx = originX + col * distanceNow; |
|
double maxy = originY - row * distanceNow; |
|
//IEnvelope e = new EnvelopeClass() |
|
//{ |
|
// XMin = minx, |
|
// YMin = maxy - distanceNow, |
|
// XMax = minx + distanceNow, |
|
// YMax = maxy |
|
//}; |
|
tiles.Add(new TileInfo(null, MaxLevel, row, col) { XMax = minx + distanceNow, XMin = minx, YMax = maxy, YMin = maxy - distanceNow }); |
|
//tiles.Add(new TileInfo(null, MaxLevel, row, col)); |
|
} |
|
} |
|
MaxLevel++; |
|
} |
|
|
|
//foreach (int item in scales) |
|
//{ |
|
// int levelPow = scales[scales.Count - 1] / item; |
|
// int level = 0; |
|
// if (levelPow != 1) |
|
// { |
|
// level = GetPower(levelPow);//(int)Math.Sqrt(levelPow * 1.0); |
|
// } |
|
// if (MaxLevel < level + 1) |
|
// MaxLevel = level + 1; |
|
// double distanceNow = item * TileSize * 0.0254 / 96; |
|
// int count = (int)(maxDistance / distanceNow); |
|
// if (maxDistance % distanceNow != 0) |
|
// { |
|
// count = count + 1; |
|
// } |
|
// int startCol = 0; |
|
// int endCol = count; |
|
// if (count > 1 && CutType == CUTAreaType.自动分块) |
|
// { |
|
// int delCount = count / this.BlockHorizontalCount; |
|
// startCol = (this.BlockIndex - 1) * delCount; |
|
// endCol = this.BlockIndex * delCount; |
|
// } |
|
// for (int col = startCol; col < endCol; col++) |
|
// { |
|
// for (int row = 0; row < count; row++) |
|
// { |
|
// double minx = originX + col * distanceNow; |
|
// double maxy = originY - row * distanceNow; |
|
// IEnvelope e = new EnvelopeClass() |
|
// { |
|
// XMin = minx, |
|
// YMin = maxy - distanceNow, |
|
// XMax = minx + distanceNow, |
|
// YMax = maxy |
|
// }; |
|
// tiles.Add(new TileInfo(e, level, row, col)); |
|
// } |
|
// } |
|
//} |
|
//for (int level = MinLevel - 1; level < MaxLevel; level++) |
|
//{ |
|
// int count = (int)Math.Pow(2, level); |
|
// int startCol = 0; |
|
// int endCol = count; |
|
// if (level > 3 && CutType == CUTAreaType.自动分块) |
|
// { |
|
// int delCount = count / this.BlockHorizontalCount; |
|
// startCol = (this.BlockIndex - 1) * delCount; |
|
// endCol = this.BlockIndex * delCount; |
|
// } |
|
|
|
// double del = extent.Width / count; |
|
// for (int col = startCol; col < endCol; col++) |
|
// { |
|
// for (int row = 0; row < count; row++) |
|
// { |
|
// double minx = originX + col * del; |
|
// double maxy = originY - row * del; |
|
// IEnvelope e = new EnvelopeClass() |
|
// { |
|
// XMin = minx, |
|
// YMin = maxy - del, |
|
// XMax = minx + del, |
|
// YMax = maxy |
|
// }; |
|
// tiles.Add(new TileInfo(e, level, row, col)); |
|
// } |
|
// } |
|
//} |
|
return tiles; |
|
} |
|
|
|
private List<TilesParam> GetAllTiles2(IEnvelope extent) |
|
{ |
|
double maxDistance = extent.XMax - extent.XMin; |
|
double originX = extent.XMin; |
|
double originY = extent.YMax; |
|
|
|
List<int> scales = GetAllScale(MaxScale, maxDistance); |
|
if (scales == null || scales.Count <= 0) return null; |
|
List<TilesParam> tilesParam = new List<TilesParam>(); |
|
MaxLevel = 0; |
|
for (int i = scales.Count - 1; i >= 0; i--) |
|
{ |
|
double distanceNow = scales[i] * TileSize * 0.0254 / 96; |
|
int count = (int)(maxDistance / distanceNow); |
|
if (maxDistance % distanceNow != 0) |
|
{ |
|
count = count + 1; |
|
} |
|
int startCol = 0; |
|
int endCol = count; |
|
if (count > 1 && CutType == CUTAreaType.自动分块) |
|
{ |
|
int delCount = count / this.BlockHorizontalCount; |
|
startCol = (this.BlockIndex - 1) * delCount; |
|
endCol = this.BlockIndex * delCount; |
|
} |
|
tilesParam.Add(new TilesParam() { Distance = distanceNow, Level = MaxLevel, RowCount = count, EndCol = endCol, OriginX = originX, OriginY = originY, StartCol = startCol }); |
|
MaxLevel++; |
|
|
|
} |
|
return tilesParam; |
|
} |
|
|
|
private int cutMultiple = 4; |
|
private List<TilesParam> GetAllTiles3(IEnvelope extent) |
|
{ |
|
double maxDistance = extent.XMax - extent.XMin; |
|
double originX = extent.XMin; |
|
double originY = extent.YMax; |
|
|
|
List<int> scales = GetAllScale(MaxScale, maxDistance); |
|
//maxDistance = scales[scales.Count - 1] * TileSize * 0.0254 / 96; |
|
//originX = (extent.Width / 2 + extent.XMin) - maxDistance / 2; |
|
//originY = (extent.YMax - extent.Height / 2) + maxDistance / 2; |
|
if (scales == null || scales.Count <= 0) return null; |
|
List<TilesParam> tilesParam = new List<TilesParam>(); |
|
MaxLevel = 0; |
|
for (int i = scales.Count - 1; i >= 0; i--) |
|
{ |
|
double distanceNow = scales[i] * TileSize * 0.0254 / 96; |
|
int count = (int)(maxDistance / distanceNow); |
|
if (count < 0) |
|
count = 0; |
|
int currentCutMultiple = 1; |
|
if (maxDistance % distanceNow != 0) |
|
{ |
|
count = count + 1; |
|
} |
|
if (count > cutMultiple) |
|
{ |
|
count = count / cutMultiple;//切的张数 |
|
if (count % cutMultiple != 0) |
|
{ |
|
count = count + 1; |
|
} |
|
currentCutMultiple = cutMultiple; |
|
} |
|
else |
|
{ |
|
currentCutMultiple = count; |
|
} |
|
int startCol = 0; |
|
int endCol = count; |
|
if (count > 1 && CutType == CUTAreaType.自动分块) |
|
{ |
|
int delCount = count / this.BlockHorizontalCount; |
|
startCol = (this.BlockIndex - 1) * delCount; |
|
endCol = this.BlockIndex * delCount; |
|
} |
|
tilesParam.Add(new TilesParam() { Distance = distanceNow, TileSize = this.TileSize * currentCutMultiple, CutMultiple = currentCutMultiple, Level = MaxLevel, RowCount = count, EndCol = endCol, OriginX = originX, OriginY = originY, StartCol = startCol }); |
|
MaxLevel++; |
|
|
|
} |
|
return tilesParam; |
|
} |
|
|
|
/// <summary> |
|
/// 生成比例尺 |
|
/// </summary> |
|
/// <param name="maxScale">最大比例尺</param> |
|
/// <param name="maxDistance">最大距离</param> |
|
/// <returns></returns> |
|
private List<int> GetAllScale(int maxScale, double maxDistance) |
|
{ |
|
List<int> lstScale = new List<int>(); |
|
|
|
double distance = 0; |
|
int scaleNow = maxScale; |
|
int minScale = (int)(maxDistance * 96 / (this.TileSize * 0.0254)); |
|
distance = scaleNow * this.TileSize * 0.0254 / 96; |
|
//if (maxDistance <= distance) |
|
//{ |
|
// lstScale.Add(minScale); |
|
// return lstScale; |
|
//} |
|
lstScale.Add(maxScale); |
|
//while (minScale > scaleNow) |
|
//{ |
|
// if (scaleNow > this.MinScale) break; |
|
// scaleNow = scaleNow * 2; |
|
// distance = scaleNow * 256 * 0.0254 / 96;//计算实际距离 |
|
// if (distance > maxDistance) |
|
// { |
|
// lstScale.Add(minScale); |
|
// //this.MinScale = minScale; |
|
// } |
|
// else |
|
// lstScale.Add(scaleNow); |
|
//} |
|
|
|
while (minScale > scaleNow) |
|
{ |
|
//if (scaleNow >= this.MinScale) break; |
|
scaleNow = scaleNow * 2; |
|
lstScale.Add(scaleNow); |
|
////distance = scaleNow * 256 * 0.0254 / 96;//计算实际距离 |
|
//if (distance > maxDistance) |
|
//{ |
|
// lstScale.Add(minScale); |
|
// //this.MinScale = minScale; |
|
//} |
|
//else |
|
// lstScale.Add(scaleNow); |
|
} |
|
this.MinScale = scaleNow; |
|
//lstScale.Add(minScale); |
|
return lstScale; |
|
} |
|
|
|
private int GetPower(int powNumber) |
|
{ |
|
if (powNumber < 2) return 0; |
|
int count = 1; |
|
while ((powNumber = powNumber / 2) >= 2) |
|
{ |
|
count++; |
|
} |
|
return count; |
|
} |
|
|
|
private IEnvelope GetBlockExtentByIndex(IEnvelope e) |
|
{ |
|
|
|
double x = (e.XMax - e.XMin) / (this.BlockHorizontalCount * 1.0); |
|
double y = (e.YMax - e.YMin) / (this.BlockVerticalCount * 1.0); |
|
|
|
int yIndex = this.BlockIndex / this.BlockHorizontalCount; |
|
int xIndex = this.BlockIndex % this.BlockHorizontalCount; |
|
if (xIndex != 0) |
|
{ |
|
yIndex = yIndex + 1; |
|
} |
|
|
|
double xMax = x * xIndex + e.XMin; |
|
double xMin = x * (xIndex - 1) + e.XMin; |
|
double yMax = e.YMax - y * (yIndex - 1); |
|
double yMin = e.YMax - y * yIndex; |
|
IEnvelope extent = new EnvelopeClass() |
|
{ |
|
XMax = xMax, |
|
XMin = xMin, |
|
YMax = yMax, |
|
YMin = yMin |
|
}; |
|
return extent; |
|
} |
|
|
|
public void Dispose() |
|
{ |
|
if (readTilesList != null) |
|
{ |
|
foreach (ReadTilesData item in readTilesList) |
|
{ |
|
item.Dispose(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
} |
|
}
|
|
|