年度变更建库软件5.0版本
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

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();
}
}
}
}
}