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.
277 lines
10 KiB
277 lines
10 KiB
using System; |
|
using System.Collections.Generic; |
|
using System.Text; |
|
using System.Data.SQLite; |
|
using System.Threading; |
|
|
|
namespace Kingo.Plugin.MakeTaskPackage.Entity |
|
{ |
|
public delegate void ProgressReport(int sum, int current); |
|
public class WriteTilesToDataBase : IDisposable |
|
{ |
|
public event ProgressReport Report; |
|
public SQLiteConnection Conn { get; set; } |
|
public int TileCount { get; set; } |
|
public int BlankImageSize { get; set; } |
|
private List<TileInfo> needInsertDataList = new List<TileInfo>(); |
|
public void InsertData(TileInfo data) |
|
{ |
|
lock (needInsertDataList) |
|
{ |
|
needInsertDataList.Add(data); |
|
} |
|
} |
|
|
|
public void InsertDataRange(TileInfo[] data) |
|
{ |
|
lock (needInsertDataList) |
|
{ |
|
needInsertDataList.AddRange(data); |
|
} |
|
} |
|
|
|
Thread doworkThread = null; |
|
public void DoWork() |
|
{ |
|
doworkThread = new Thread(new ThreadStart(DoWork2)); |
|
doworkThread.IsBackground = true; |
|
//doworkThread.SetApartmentState(ApartmentState.STA); |
|
doworkThread.Name = "写入图片线程" + Guid.NewGuid().ToString(); |
|
//doworkThread.Priority = ThreadPriority.AboveNormal; |
|
doworkThread.Start(); |
|
} |
|
private void DoWork2() |
|
{ |
|
Conn.Open(); |
|
try |
|
{ |
|
SQLiteTransaction pTan = Conn.BeginTransaction(); |
|
SQLiteCommand cmd = new SQLiteCommand(Conn); |
|
cmd.CommandText = "insert into tiles (zoom_level,tile_column,tile_row,tile_data) values(@zoom_level,@tile_column,@tile_row,@tile_data)"; |
|
cmd.Parameters.Add(new SQLiteParameter("@zoom_level", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_column", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_row", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_data", System.Data.DbType.Binary)); |
|
int dealTileCount = 0; |
|
while (dealTileCount < TileCount) |
|
{ |
|
TileInfo[] datas = null; |
|
lock (needInsertDataList) |
|
{ |
|
datas = needInsertDataList.ToArray(); |
|
needInsertDataList.Clear(); |
|
} |
|
if (datas == null || datas.Length == 0) |
|
{ |
|
//Console.WriteLine("Sleep"); |
|
Thread.Sleep(1000); |
|
} |
|
else |
|
{ |
|
Console.WriteLine("record:" + datas.Length.ToString()); |
|
foreach (var item in datas) |
|
{ |
|
if (item.Data == null || item.Data.Length == BlankImageSize)// |
|
continue; |
|
cmd.Parameters[0].Value = item.Level; |
|
cmd.Parameters[1].Value = item.Column; |
|
cmd.Parameters[2].Value = item.Row; |
|
cmd.Parameters[3].Value = item.Data; |
|
cmd.ExecuteNonQuery(); |
|
item.Data = null; |
|
} |
|
dealTileCount += datas.Length; |
|
if (Report != null) |
|
{ |
|
Report(TileCount, dealTileCount); |
|
} |
|
} |
|
Thread.Sleep(0); |
|
} |
|
cmd.CommandText = "CREATE INDEX tiles_index ON tiles (zoom_level,tile_column,tile_row);"; |
|
try |
|
{ |
|
cmd.ExecuteNonQuery(); |
|
} |
|
catch |
|
{ |
|
|
|
} |
|
|
|
pTan.Commit(); |
|
if (Done != null) |
|
{ |
|
Done(null, null); |
|
} |
|
} |
|
finally |
|
{ |
|
Conn.Close(); |
|
Conn.Dispose(); |
|
SQLiteConnection.ClearPool(Conn); |
|
Thread.Sleep(10); |
|
GC.Collect(); |
|
Thread.Sleep(10); |
|
} |
|
} |
|
|
|
|
|
public void DoWorkLevel() |
|
{ |
|
doworkThread = new Thread(new ThreadStart(DoWork2Level)); |
|
doworkThread.IsBackground = true; |
|
//doworkThread.SetApartmentState(ApartmentState.STA); |
|
doworkThread.Name = "写入图片线程" + Guid.NewGuid().ToString(); |
|
//doworkThread.Priority = ThreadPriority.AboveNormal; |
|
doworkThread.Start(); |
|
} |
|
private void DoWork2Level() |
|
{ |
|
Conn.Open(); |
|
try |
|
{ |
|
|
|
SQLiteTransaction pTan = Conn.BeginTransaction(); |
|
SQLiteCommand cmd = new SQLiteCommand(Conn); |
|
cmd.CommandText = "insert into tiles (zoom_level,tile_column,tile_row,tile_data,maxX,maxY,minX,minY,resolution) values(@zoom_level,@tile_column,@tile_row,@tile_data,@maxX,@maxY,@minX,@minY,@resolution)"; |
|
cmd.Parameters.Add(new SQLiteParameter("@zoom_level", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_column", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_row", System.Data.DbType.Int32)); |
|
cmd.Parameters.Add(new SQLiteParameter("@tile_data", System.Data.DbType.Binary)); |
|
cmd.Parameters.Add(new SQLiteParameter("@maxX", System.Data.DbType.Double)); |
|
cmd.Parameters.Add(new SQLiteParameter("@maxY", System.Data.DbType.Double)); |
|
cmd.Parameters.Add(new SQLiteParameter("@minX", System.Data.DbType.Double)); |
|
cmd.Parameters.Add(new SQLiteParameter("@minY", System.Data.DbType.Double)); |
|
cmd.Parameters.Add(new SQLiteParameter("@resolution", System.Data.DbType.Double)); |
|
int dealTileCount = 0; |
|
while (dealTileCount < TileCount) |
|
{ |
|
TileInfo[] datas = null; |
|
lock (needInsertDataList) |
|
{ |
|
datas = needInsertDataList.ToArray(); |
|
needInsertDataList.Clear(); |
|
} |
|
if (datas == null || datas.Length == 0) |
|
{ |
|
//Console.WriteLine("Sleep"); |
|
Thread.Sleep(1000); |
|
} |
|
else |
|
{ |
|
//Console.WriteLine("record:" + datas.Length.ToString()); |
|
foreach (var item in datas) |
|
{ |
|
if (item.Data == null) |
|
continue; |
|
cmd.Parameters[0].Value = item.Level; |
|
cmd.Parameters[1].Value = item.Column; |
|
cmd.Parameters[2].Value = item.Row; |
|
cmd.Parameters[3].Value = item.Data; |
|
cmd.Parameters[4].Value = item.Bound.XMax; |
|
cmd.Parameters[5].Value = item.Bound.YMax; |
|
cmd.Parameters[6].Value = item.Bound.XMin; |
|
cmd.Parameters[7].Value = item.Bound.YMin; |
|
cmd.Parameters[8].Value = item.Resolution; |
|
cmd.ExecuteNonQuery(); |
|
item.Data = null; |
|
} |
|
dealTileCount += datas.Length; |
|
if (Report != null) |
|
{ |
|
Report(TileCount, dealTileCount); |
|
} |
|
} |
|
Thread.Sleep(0); |
|
} |
|
try |
|
{ |
|
cmd.CommandText = "CREATE INDEX tiles_index ON tiles (zoom_level,tile_column,tile_row);"; |
|
cmd.ExecuteNonQuery(); |
|
cmd.CommandText = "CREATE INDEX bound_index ON tiles (maxX,maxY,minX,minY,resolution);"; |
|
cmd.ExecuteNonQuery(); |
|
} |
|
catch |
|
{ |
|
|
|
} |
|
|
|
pTan.Commit(); |
|
if (Done != null) |
|
{ |
|
Done(null, null); |
|
} |
|
} |
|
finally |
|
{ |
|
Conn.Close(); |
|
Conn.Dispose(); |
|
SQLiteConnection.ClearPool(Conn); |
|
Thread.Sleep(10); |
|
GC.Collect(); |
|
Thread.Sleep(10); |
|
} |
|
} |
|
|
|
|
|
public event EventHandler Done; |
|
|
|
public void Stop() |
|
{ |
|
Dispose(); |
|
} |
|
|
|
public void Dispose() |
|
{ |
|
if (doworkThread != null) |
|
{ |
|
try |
|
{ |
|
doworkThread.Abort(); |
|
} |
|
catch |
|
{ |
|
|
|
} |
|
finally |
|
{ |
|
doworkThread = null; |
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
private const double EARTH_RADIUS = 6378137; |
|
/// <summary> |
|
/// 计算两点位置的距离,返回两点的距离,单位 米 |
|
/// 该公式为GOOGLE提供,误差小于0.2米 |
|
/// </summary> |
|
/// <param name="lat1">第一点纬度</param> |
|
/// <param name="lng1">第一点经度</param> |
|
/// <param name="lat2">第二点纬度</param> |
|
/// <param name="lng2">第二点经度</param> |
|
/// <returns></returns> |
|
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) |
|
{ |
|
double radLat1 = Rad(lat1); |
|
double radLng1 = Rad(lng1); |
|
double radLat2 = Rad(lat2); |
|
double radLng2 = Rad(lng2); |
|
double a = radLat1 - radLat2; |
|
double b = radLng1 - radLng2; |
|
double result = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a / 2), 2) + Math.Cos(radLat1) * Math.Cos(radLat2) * Math.Pow(Math.Sin(b / 2), 2))) * EARTH_RADIUS; |
|
return result; |
|
} |
|
|
|
/// <summary> |
|
/// 经纬度转化成弧度 |
|
/// </summary> |
|
/// <param name="d"></param> |
|
/// <returns></returns> |
|
private static double Rad(double d) |
|
{ |
|
return (double)d * Math.PI / 180d; |
|
} |
|
} |
|
}
|
|
|