|
|
|
|
using OSGeo.GDAL;
|
|
|
|
|
using OSGeo.OGR;
|
|
|
|
|
using OSGeo.OSR;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data.SQLite;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Drawing.Imaging;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
|
|
|
|
|
namespace Kingo.Plugin.RasterToKOTilesApp.KoDataBase
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class RasterInfo : IDisposable
|
|
|
|
|
{
|
|
|
|
|
public string Projection { get; private set; }
|
|
|
|
|
public Dataset Dataset { get; private set; }
|
|
|
|
|
public int XSize { get; set; }
|
|
|
|
|
public int YSize { get; set; }
|
|
|
|
|
public double TransScale { get; set; }
|
|
|
|
|
|
|
|
|
|
public Envelope Extent { get; set; }
|
|
|
|
|
public double[] Geotransform { get; private set; }
|
|
|
|
|
public int Bands { get; private set; }
|
|
|
|
|
|
|
|
|
|
private RasterInfo() { }
|
|
|
|
|
public static RasterInfo Create(string fileName)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//消除中文路径无法识别的问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
|
|
|
|
Dataset dataset = Gdal.Open(fileName, Access.GA_ReadOnly);
|
|
|
|
|
return Create(dataset);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public static RasterInfo Create(Dataset dataset)
|
|
|
|
|
{
|
|
|
|
|
RasterInfo pRasterInfo = new RasterInfo();
|
|
|
|
|
pRasterInfo.Dataset = dataset;
|
|
|
|
|
pRasterInfo.XSize = pRasterInfo.Dataset.RasterXSize;
|
|
|
|
|
pRasterInfo.YSize = pRasterInfo.Dataset.RasterYSize;
|
|
|
|
|
pRasterInfo.Geotransform = new double[6];
|
|
|
|
|
pRasterInfo.Dataset.GetGeoTransform(pRasterInfo.Geotransform);
|
|
|
|
|
double north = pRasterInfo.Geotransform[3];
|
|
|
|
|
double south = pRasterInfo.Geotransform[3] + pRasterInfo.Geotransform[5] * pRasterInfo.YSize;
|
|
|
|
|
double east = pRasterInfo.Geotransform[0] + pRasterInfo.Geotransform[1] * pRasterInfo.XSize;
|
|
|
|
|
double west = pRasterInfo.Geotransform[0];
|
|
|
|
|
if (Math.Round(pRasterInfo.Geotransform[1] + pRasterInfo.Geotransform[5], 1) != 0)
|
|
|
|
|
throw new Exception("栅格对象被压缩");
|
|
|
|
|
pRasterInfo.TransScale = pRasterInfo.Geotransform[1];
|
|
|
|
|
pRasterInfo.Bands = pRasterInfo.Dataset.RasterCount;
|
|
|
|
|
//this.ScaleY = geotransform[5];
|
|
|
|
|
pRasterInfo.Projection = pRasterInfo.Dataset.GetProjection();
|
|
|
|
|
pRasterInfo.Extent = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
XMax = east,
|
|
|
|
|
XMin = west,
|
|
|
|
|
YMax = north,
|
|
|
|
|
YMin = south
|
|
|
|
|
};
|
|
|
|
|
return pRasterInfo;
|
|
|
|
|
}
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
Dataset.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public delegate List<TileInfo> CompareTileInfo(List<TileInfo> tileInfos);
|
|
|
|
|
public class MultRaster2MBTiles
|
|
|
|
|
{
|
|
|
|
|
static MultRaster2MBTiles()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ImageFormat ImgFormat { get; set; }
|
|
|
|
|
public int Level { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Layer TopLayer { get; set; }
|
|
|
|
|
private List<RasterInfo> Rasters = new List<RasterInfo>();
|
|
|
|
|
|
|
|
|
|
private Dataset topRasterDs = null;
|
|
|
|
|
|
|
|
|
|
private RasterInfo topRaster = null;
|
|
|
|
|
|
|
|
|
|
public int CompressRate { get; set; } = 25;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 相交
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event CompareTileInfo CompareIntersect = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public EnumSaveType SaveType { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (topRasterDs != null)
|
|
|
|
|
topRasterDs.Dispose();
|
|
|
|
|
if (topRaster != null)
|
|
|
|
|
topRaster.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public MultRaster2MBTiles()
|
|
|
|
|
{
|
|
|
|
|
//Rasters = new List<RasterInfo>();
|
|
|
|
|
//codecInfo = GetEncoder(ImageFormat.Png);
|
|
|
|
|
//System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
|
|
|
|
|
//EncoderParameters myEncoderParameters = new EncoderParameters(1);
|
|
|
|
|
//EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder,8);
|
|
|
|
|
//myEncoderParameters.Param[0] = myEncoderParameter;
|
|
|
|
|
//encoderParameters = myEncoderParameters;
|
|
|
|
|
ImgFormat = ImageFormat.Jpeg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Envelope rasterExtent;
|
|
|
|
|
|
|
|
|
|
public int TiledSize { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string MBTilesPath { get; set; }
|
|
|
|
|
|
|
|
|
|
private List<TileInfo> GetAllTiles(Envelope extent, Envelope envelopeCut = null)
|
|
|
|
|
{
|
|
|
|
|
List<TileInfo> tiles = new List<TileInfo>();
|
|
|
|
|
double originX = extent.XMin;
|
|
|
|
|
double originY = extent.YMax;
|
|
|
|
|
for (int level = 0; level < Level; level++)
|
|
|
|
|
{
|
|
|
|
|
int count = (int)Math.Pow(2, level);
|
|
|
|
|
double del = extent.Width / count;
|
|
|
|
|
for (int col = 0; col < count; col++)
|
|
|
|
|
{
|
|
|
|
|
for (int row = 0; row < count; row++)
|
|
|
|
|
{
|
|
|
|
|
double minx = originX + col * del;
|
|
|
|
|
double maxy = originY - row * del;
|
|
|
|
|
|
|
|
|
|
Envelope e = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
XMin = minx,
|
|
|
|
|
YMin = maxy - del,
|
|
|
|
|
XMax = minx + del,
|
|
|
|
|
YMax = maxy
|
|
|
|
|
};
|
|
|
|
|
if (envelopeCut != null)
|
|
|
|
|
{
|
|
|
|
|
if (!e.Intersects(envelopeCut)) continue;
|
|
|
|
|
}
|
|
|
|
|
tiles.Add(new TileInfo(e, level, row, col));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Rectangle Envelope2Rect(RasterInfo rasterInfo, Envelope extent)
|
|
|
|
|
{
|
|
|
|
|
//int width = (int)((extent.XMax - extent.XMin) / rasterInfo.TransScale + 0.5);
|
|
|
|
|
//int height = (int)((extent.YMax - extent.YMin) / rasterInfo.TransScale + 0.5);
|
|
|
|
|
//int x = (int)((rasterInfo.Extent.XMax - extent.XMax) / rasterInfo.TransScale + 0.5);
|
|
|
|
|
//int y = (int)((rasterInfo.Extent.YMax - extent.YMax) / rasterInfo.TransScale + 0.5);
|
|
|
|
|
//return new Rectangle(x, y, width, height);
|
|
|
|
|
Rectangle rect = Envelope2Rect(rasterInfo.Extent, extent, rasterInfo.TransScale);
|
|
|
|
|
if (rect.Right > rasterInfo.XSize)
|
|
|
|
|
{
|
|
|
|
|
rect.Width -= rect.Right - rasterInfo.XSize;
|
|
|
|
|
}
|
|
|
|
|
if (rect.Bottom > rasterInfo.YSize)
|
|
|
|
|
{
|
|
|
|
|
rect.Height -= rect.Bottom - rasterInfo.YSize;
|
|
|
|
|
}
|
|
|
|
|
return rect;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Rectangle Envelope2Rect(Envelope baseExtent, Envelope extent, double resolution)
|
|
|
|
|
{
|
|
|
|
|
int width = (int)((extent.XMax - extent.XMin) / resolution + 0.5);
|
|
|
|
|
int height = (int)((extent.YMax - extent.YMin) / resolution + 0.5);
|
|
|
|
|
int x = (int)((extent.XMin - baseExtent.XMin) / resolution + 0.5);
|
|
|
|
|
int y = (int)((baseExtent.YMax - extent.YMax) / resolution + 0.5);
|
|
|
|
|
return new Rectangle(x, y, width, height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Envelope GetExtent()
|
|
|
|
|
{
|
|
|
|
|
return GetExtent(this.Rasters);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Envelope GetExtent(List<RasterInfo> rasters)
|
|
|
|
|
{
|
|
|
|
|
Envelope extent = rasters[0].Extent; ;
|
|
|
|
|
for (int i = 1; i < rasters.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
extent = extent.Union(rasters[i].Extent);
|
|
|
|
|
}
|
|
|
|
|
return extent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static Envelope GetExtentZ(Envelope e)
|
|
|
|
|
{
|
|
|
|
|
Envelope extent = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
return extent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Envelope maxExtent = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private string EnCode(object value)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (value == null)
|
|
|
|
|
return "";
|
|
|
|
|
string str = value.ToString();
|
|
|
|
|
return str;
|
|
|
|
|
if (string.IsNullOrEmpty(str))
|
|
|
|
|
return "";
|
|
|
|
|
string outStr = "";
|
|
|
|
|
foreach (char item in str)
|
|
|
|
|
{
|
|
|
|
|
outStr += (char)(item + 22);
|
|
|
|
|
}
|
|
|
|
|
return outStr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//多线程去切
|
|
|
|
|
private List<ReadRaster> readRasterList = new List<ReadRaster>();
|
|
|
|
|
private WriteDatabase pWriteDatabase = null;
|
|
|
|
|
public void CreateMulFilesKOTiles(List<string> files, int threadnumber, bool converWebMercator, SpatialReference spatialReference, Envelope envelopeCut = null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var fileName in files)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
RasterInfo raster = RasterInfo.Create(fileName);
|
|
|
|
|
if (converWebMercator == true)
|
|
|
|
|
{
|
|
|
|
|
if (spatialReference != null)
|
|
|
|
|
{
|
|
|
|
|
Dataset mercatorDataSet = GdalWarp(fileName, spatialReference);
|
|
|
|
|
if (mercatorDataSet != null)
|
|
|
|
|
raster = RasterInfo.Create(mercatorDataSet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (raster != null)
|
|
|
|
|
Rasters.Add(raster);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("获取影像信息失败:" + ex.Message);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
//创建遮罩层
|
|
|
|
|
if (TopLayer != null)
|
|
|
|
|
CreateLayer();
|
|
|
|
|
|
|
|
|
|
//计算全部图层的最小外接正方形
|
|
|
|
|
this.rasterExtent = GetExtent();
|
|
|
|
|
maxExtent = GetExtentZ(rasterExtent);
|
|
|
|
|
//开始切片,获取范围内的瓦片
|
|
|
|
|
//根据层级开始计算网格个数
|
|
|
|
|
List<TileInfo> allTiles = GetAllTiles(maxExtent, envelopeCut);
|
|
|
|
|
|
|
|
|
|
List<List<TileInfo>> tileGroups = new List<List<TileInfo>>();
|
|
|
|
|
int start = 0;
|
|
|
|
|
int count = allTiles.Count / threadnumber;
|
|
|
|
|
if (topRasterDs != null)
|
|
|
|
|
topRaster = RasterInfo.Create(topRasterDs);
|
|
|
|
|
|
|
|
|
|
pWriteDatabase = new WriteDatabase();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < threadnumber; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i == threadnumber - 1)
|
|
|
|
|
{
|
|
|
|
|
count += allTiles.Count % threadnumber;
|
|
|
|
|
}
|
|
|
|
|
List<TileInfo> tileGroup = allTiles.GetRange(start, count);
|
|
|
|
|
|
|
|
|
|
start += count;
|
|
|
|
|
|
|
|
|
|
ReadRaster pReadRaster = new ReadRaster()
|
|
|
|
|
{
|
|
|
|
|
ImgFormat = ImgFormat,
|
|
|
|
|
TiledSize = TiledSize,
|
|
|
|
|
TileInfos = tileGroup,
|
|
|
|
|
TopRasterInfo = topRaster,
|
|
|
|
|
CompressRate = this.CompressRate,
|
|
|
|
|
Rasters = Rasters
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pReadRaster.Dowork();
|
|
|
|
|
|
|
|
|
|
pReadRaster.Event2 += (d, e) => {
|
|
|
|
|
pWriteDatabase.InsertDataRange(d as TileInfo[]);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
readRasterList.Add(pReadRaster);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SQLiteConnection conn = null;
|
|
|
|
|
if (SaveType == EnumSaveType.Level)
|
|
|
|
|
conn = CreateDataBase();
|
|
|
|
|
else if (SaveType == EnumSaveType.Resolution)
|
|
|
|
|
conn = CreateBestDataBase();
|
|
|
|
|
|
|
|
|
|
pWriteDatabase.Conn = conn;
|
|
|
|
|
pWriteDatabase.TileCount = allTiles.Count;
|
|
|
|
|
pWriteDatabase.Done += (s, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (topRaster != null)
|
|
|
|
|
topRaster.Dispose();
|
|
|
|
|
if (topRasterDs != null)
|
|
|
|
|
{
|
|
|
|
|
topRasterDs.Dispose();
|
|
|
|
|
topRasterDs = null;
|
|
|
|
|
}
|
|
|
|
|
if (TopLayer != null)
|
|
|
|
|
{
|
|
|
|
|
TopLayer.Dispose();
|
|
|
|
|
TopLayer = null;
|
|
|
|
|
}
|
|
|
|
|
this.CreatDown(s, e);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
pWriteDatabase.Report += (s, e) =>
|
|
|
|
|
{
|
|
|
|
|
if (Report != null)
|
|
|
|
|
{
|
|
|
|
|
Report(s, e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (SaveType == EnumSaveType.Level)
|
|
|
|
|
{
|
|
|
|
|
pWriteDatabase.DoWorkLevel();
|
|
|
|
|
}
|
|
|
|
|
else if (SaveType == EnumSaveType.Resolution)
|
|
|
|
|
{
|
|
|
|
|
pWriteDatabase.BestDoWork();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CreateMulFilesKOTiles(List<string> files, int threadnumber, bool converWebMercator, Envelope envelopeCut = null)
|
|
|
|
|
{
|
|
|
|
|
foreach (string file in files)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
RasterInfo rasterInfo = RasterInfo.Create(file);
|
|
|
|
|
if (converWebMercator)
|
|
|
|
|
{
|
|
|
|
|
SpatialReference spatialReference = new SpatialReference("");
|
|
|
|
|
spatialReference.ImportFromEPSG(3857);
|
|
|
|
|
Dataset dataset = GdalWarp(file, spatialReference);
|
|
|
|
|
if (dataset != null)
|
|
|
|
|
{
|
|
|
|
|
rasterInfo = RasterInfo.Create(dataset);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (rasterInfo != null)
|
|
|
|
|
{
|
|
|
|
|
Rasters.Add(rasterInfo);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (TopLayer != null)
|
|
|
|
|
{
|
|
|
|
|
CreateLayer();
|
|
|
|
|
}
|
|
|
|
|
rasterExtent = GetExtent();
|
|
|
|
|
maxExtent = GetExtentZ(rasterExtent);
|
|
|
|
|
List<TileInfo> allTiles = GetAllTiles(maxExtent, envelopeCut);
|
|
|
|
|
List<List<TileInfo>> list = new List<List<TileInfo>>();
|
|
|
|
|
int num = 0;
|
|
|
|
|
int num2 = allTiles.Count / threadnumber;
|
|
|
|
|
if (topRasterDs != null)
|
|
|
|
|
{
|
|
|
|
|
topRaster = RasterInfo.Create(topRasterDs);
|
|
|
|
|
}
|
|
|
|
|
pWriteDatabase = new WriteDatabase();
|
|
|
|
|
for (int i = 0; i < threadnumber; i++)
|
|
|
|
|
{
|
|
|
|
|
if (i == threadnumber - 1)
|
|
|
|
|
{
|
|
|
|
|
num2 += allTiles.Count % threadnumber;
|
|
|
|
|
}
|
|
|
|
|
List<TileInfo> range = allTiles.GetRange(num, num2);
|
|
|
|
|
num += num2;
|
|
|
|
|
ReadRaster readRaster = new ReadRaster(files, converWebMercator)
|
|
|
|
|
{
|
|
|
|
|
ImgFormat = ImgFormat,
|
|
|
|
|
TiledSize = TiledSize,
|
|
|
|
|
TileInfos = range,
|
|
|
|
|
TopRasterInfo = topRaster,
|
|
|
|
|
CompressRate = CompressRate
|
|
|
|
|
};
|
|
|
|
|
readRaster.Dowork();
|
|
|
|
|
readRaster.Event2 += delegate (object d, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
pWriteDatabase.InsertDataRange(d as TileInfo[]);
|
|
|
|
|
};
|
|
|
|
|
readRasterList.Add(readRaster);
|
|
|
|
|
}
|
|
|
|
|
SQLiteConnection conn = null;
|
|
|
|
|
if (SaveType == EnumSaveType.Level)
|
|
|
|
|
{
|
|
|
|
|
conn = CreateDataBase();
|
|
|
|
|
}
|
|
|
|
|
else if (SaveType == EnumSaveType.Resolution)
|
|
|
|
|
{
|
|
|
|
|
conn = CreateBestDataBase();
|
|
|
|
|
}
|
|
|
|
|
pWriteDatabase.Conn = conn;
|
|
|
|
|
pWriteDatabase.TileCount = allTiles.Count;
|
|
|
|
|
pWriteDatabase.Done += delegate (object s, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (topRaster != null)
|
|
|
|
|
{
|
|
|
|
|
topRaster.Dispose();
|
|
|
|
|
}
|
|
|
|
|
if (topRasterDs != null)
|
|
|
|
|
{
|
|
|
|
|
topRasterDs.Dispose();
|
|
|
|
|
topRasterDs = null;
|
|
|
|
|
}
|
|
|
|
|
if (TopLayer != null)
|
|
|
|
|
{
|
|
|
|
|
TopLayer.Dispose();
|
|
|
|
|
TopLayer = null;
|
|
|
|
|
}
|
|
|
|
|
this.CreatDown(s, e);
|
|
|
|
|
};
|
|
|
|
|
pWriteDatabase.Report += delegate (int s, int e)
|
|
|
|
|
{
|
|
|
|
|
if (this.Report != null)
|
|
|
|
|
{
|
|
|
|
|
this.Report(s, e);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (SaveType == EnumSaveType.Level)
|
|
|
|
|
{
|
|
|
|
|
pWriteDatabase.DoWorkLevel();
|
|
|
|
|
}
|
|
|
|
|
else if (SaveType == EnumSaveType.Resolution)
|
|
|
|
|
{
|
|
|
|
|
pWriteDatabase.BestDoWork();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Dataset GdalWarp(string inputFile, SpatialReference tileSpatialReference)
|
|
|
|
|
{
|
|
|
|
|
Dataset inputDataset = Gdal.OpenShared(inputFile, Access.GA_ReadOnly);
|
|
|
|
|
OSGeo.OSR.SpatialReference sSpatialReference = inputDataset.GetSpatialRef();
|
|
|
|
|
if (sSpatialReference.IsSame(tileSpatialReference, null) > 0)
|
|
|
|
|
{
|
|
|
|
|
return inputDataset;
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string tempFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Temp");
|
|
|
|
|
if (!Directory.Exists(tempFolder))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(tempFolder);
|
|
|
|
|
}
|
|
|
|
|
string outputFile = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + ".VRT");
|
|
|
|
|
tileSpatialReference.ExportToWkt(out string wkt, null);
|
|
|
|
|
string[] options = new string[] { "-t_srs", wkt, "-r", "rms", "-of", "VRT" };
|
|
|
|
|
|
|
|
|
|
Gdal.GDALProgressFuncDelegate progressFuncDelegate = new Gdal.GDALProgressFuncDelegate((complete, msg, data) =>
|
|
|
|
|
{
|
|
|
|
|
if (complete >= 1)
|
|
|
|
|
{
|
|
|
|
|
//isProgressCompleted = true;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
});
|
|
|
|
|
return Gdal.Warp(outputFile, new Dataset[] { inputDataset }, new GDALWarpAppOptions(options), progressFuncDelegate, null);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
inputDataset.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private SQLiteConnection CreateDataBase()
|
|
|
|
|
{
|
|
|
|
|
string connString = "Data Source=" + this.MBTilesPath;
|
|
|
|
|
if (File.Exists(this.MBTilesPath))
|
|
|
|
|
{
|
|
|
|
|
GC.Collect();
|
|
|
|
|
System.Windows.Forms.Application.DoEvents();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
File.Delete(this.MBTilesPath);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("输出文件监测到被占用,请重试!" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
string dir = Path.GetDirectoryName(this.MBTilesPath);
|
|
|
|
|
if (!Directory.Exists(dir))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(dir);
|
|
|
|
|
}
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
File.WriteAllBytes(this.MBTilesPath, Properties.Resources.Template);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("创建数据库失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
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", EnCode(this.TiledSize));
|
|
|
|
|
int result= cmd.ExecuteNonQuery();
|
|
|
|
|
//写入图片格式
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Format", EnCode(ImgFormat.ToString()));
|
|
|
|
|
result=cmd.ExecuteNonQuery();
|
|
|
|
|
//写入空间参考
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Projection", EnCode(this.Rasters[0].Dataset.GetProjection()));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
//写入Extend
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Bounds",
|
|
|
|
|
EnCode(string.Format("{0},{1},{2},{3}", this.rasterExtent.XMin, rasterExtent.YMin, rasterExtent.XMax, rasterExtent.YMax)));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
//写入origin
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Origin",
|
|
|
|
|
EnCode(string.Format("{0},{1}", maxExtent.XMin, maxExtent.YMax)));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
//写入分辨率
|
|
|
|
|
double dbResolution = maxExtent.Width / this.TiledSize;
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Resolution", EnCode(dbResolution));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
//写入比例尺
|
|
|
|
|
double dbScale = (96 / 0.0254) * dbResolution;
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Scale", EnCode(dbScale));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
//写入Level
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Level", EnCode(this.Level));
|
|
|
|
|
result = cmd.ExecuteNonQuery();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//写入Kingo
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Kingo", "false");
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
cmd.Dispose();
|
|
|
|
|
pTan.Commit();
|
|
|
|
|
pTan.Dispose();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("写入metadata表数据失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
conn.Close();
|
|
|
|
|
GC.Collect();
|
|
|
|
|
}
|
|
|
|
|
return conn;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public event EventHandler CreatDown;
|
|
|
|
|
public event ProgressReport Report;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void CreateLayer()
|
|
|
|
|
{
|
|
|
|
|
// 注册所有的驱动
|
|
|
|
|
// Ogr.RegisterAll();
|
|
|
|
|
//Gdal.AllRegister();
|
|
|
|
|
//消除中文路径无法识别的问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
|
|
|
|
//解决shape文件字段中文内容读取问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
|
|
|
|
|
|
|
|
|
|
//获取transform
|
|
|
|
|
Envelope maxEnvelope = GetExtent(this.Rasters);
|
|
|
|
|
|
|
|
|
|
int[] rasterSize = GetRasterSize(maxEnvelope);
|
|
|
|
|
double[] geoTransform = GetGeoTransform(maxEnvelope, rasterSize[0], rasterSize[1]);
|
|
|
|
|
|
|
|
|
|
Layer layer = TopLayer;
|
|
|
|
|
|
|
|
|
|
topRasterDs = null;
|
|
|
|
|
string tempFile = Application.StartupPath + "\\temp.img";
|
|
|
|
|
if (File.Exists(tempFile))
|
|
|
|
|
File.Delete(tempFile);
|
|
|
|
|
OSGeo.GDAL.Driver dirver = Gdal.GetDriverByName("HFA");//MEM HFA GTiff
|
|
|
|
|
topRasterDs = dirver.Create(tempFile, rasterSize[0], rasterSize[1], 1, DataType.GDT_Byte, null);
|
|
|
|
|
topRasterDs.SetProjection(this.Rasters[0].Projection);
|
|
|
|
|
topRasterDs.SetGeoTransform(geoTransform);
|
|
|
|
|
|
|
|
|
|
Gdal.GDALProgressFuncDelegate callback = new Gdal.GDALProgressFuncDelegate(GDALProgressFuncDelegate);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int rst = Gdal.RasterizeLayer(topRasterDs, 1, new int[] { 1 }, layer, IntPtr.Zero, IntPtr.Zero, 1, new double[] { 255 }, new string[] { "ALL_TOUCHED=TRUE" }, callback, "callback");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private double[] GetGeoTransform(Envelope envelope, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
double[] geoTransform = new double[6];
|
|
|
|
|
|
|
|
|
|
geoTransform[0] = envelope.XMin;
|
|
|
|
|
geoTransform[1] = envelope.Width / x;
|
|
|
|
|
geoTransform[2] = 0;
|
|
|
|
|
geoTransform[3] = envelope.YMax;
|
|
|
|
|
geoTransform[4] = 0;
|
|
|
|
|
geoTransform[5] = -envelope.Height / y;
|
|
|
|
|
|
|
|
|
|
return geoTransform;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int[] GetRasterSize(Envelope envelope)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int[] rasterSize = new int[2];
|
|
|
|
|
rasterSize[0] = (int)(envelope.Width / 10);
|
|
|
|
|
rasterSize[1] = (int)(envelope.Height / 10);
|
|
|
|
|
return rasterSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool isComplete = false;
|
|
|
|
|
private int GDALProgressFuncDelegate(double Complete, IntPtr Message, IntPtr Data)
|
|
|
|
|
{
|
|
|
|
|
if (Complete >= 1)
|
|
|
|
|
{
|
|
|
|
|
isComplete = true;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#region 裁取图斑最高分辨率 2015-11-11 chendewen
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private SQLiteConnection CreateBestDataBase()
|
|
|
|
|
{
|
|
|
|
|
string connString = "Data Source=" + this.MBTilesPath;
|
|
|
|
|
if (File.Exists(this.MBTilesPath))
|
|
|
|
|
{
|
|
|
|
|
GC.Collect();
|
|
|
|
|
System.Windows.Forms.Application.DoEvents();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
File.Delete(this.MBTilesPath);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("输出文件监测到被占用,请重试!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
string dir = Path.GetDirectoryName(this.MBTilesPath);
|
|
|
|
|
if (!Directory.Exists(dir))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(dir);
|
|
|
|
|
}
|
|
|
|
|
File.WriteAllBytes(this.MBTilesPath, Properties.Resources.model);
|
|
|
|
|
System.Data.SQLite.SQLiteConnection conn = new System.Data.SQLite.SQLiteConnection(connString);
|
|
|
|
|
return conn;
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class TileInfo
|
|
|
|
|
{
|
|
|
|
|
public Envelope Bound { get; private set; }
|
|
|
|
|
public int Level { get; private set; }
|
|
|
|
|
public int Row { get; private set; }
|
|
|
|
|
public int Column { get; private set; }
|
|
|
|
|
public byte[] Data { get; set; }
|
|
|
|
|
public double Resolution { get; set; }
|
|
|
|
|
|
|
|
|
|
public TileInfo(Envelope bound, int level, int row, int col)
|
|
|
|
|
{
|
|
|
|
|
this.Bound = bound;
|
|
|
|
|
this.Level = level;
|
|
|
|
|
this.Row = row;
|
|
|
|
|
this.Column = col;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
internal class ReadRaster : IDisposable
|
|
|
|
|
{
|
|
|
|
|
public ImageFormat ImgFormat { get; set; }
|
|
|
|
|
public int TiledSize { get; set; }
|
|
|
|
|
|
|
|
|
|
public List<RasterInfo> Rasters { get; set; }
|
|
|
|
|
public List<TileInfo> TileInfos { get; set; }
|
|
|
|
|
public int CompressRate { get; set; } = 25;
|
|
|
|
|
|
|
|
|
|
public ReadRaster()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public RasterInfo TopRasterInfo { get; set; }
|
|
|
|
|
public ReadRaster(List<string> files, bool converWebMercator)
|
|
|
|
|
{
|
|
|
|
|
Rasters = new List<RasterInfo>();
|
|
|
|
|
foreach (var fileName in files)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
RasterInfo raster = RasterInfo.Create(fileName);
|
|
|
|
|
|
|
|
|
|
if (converWebMercator == true)
|
|
|
|
|
{
|
|
|
|
|
SpatialReference spatialReference = new SpatialReference("");
|
|
|
|
|
spatialReference.ImportFromEPSG(3857);
|
|
|
|
|
|
|
|
|
|
Dataset mercatorDataSet = GdalWarp(fileName, spatialReference);
|
|
|
|
|
if (mercatorDataSet != null)
|
|
|
|
|
raster = RasterInfo.Create(mercatorDataSet);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (raster != null)
|
|
|
|
|
Rasters.Add(raster);
|
|
|
|
|
}
|
|
|
|
|
catch { };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Dataset GdalWarp(string inputFile, SpatialReference tileSpatialReference)
|
|
|
|
|
{
|
|
|
|
|
Dataset inputDataset = Gdal.OpenShared(inputFile, Access.GA_ReadOnly);
|
|
|
|
|
OSGeo.OSR.SpatialReference sSpatialReference = inputDataset.GetSpatialRef();
|
|
|
|
|
if (sSpatialReference.IsSame(tileSpatialReference, null) > 0)
|
|
|
|
|
{
|
|
|
|
|
return inputDataset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string tempFolder = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Temp");
|
|
|
|
|
if (!Directory.Exists(tempFolder))
|
|
|
|
|
{
|
|
|
|
|
Directory.CreateDirectory(tempFolder);
|
|
|
|
|
}
|
|
|
|
|
string outputFile = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + ".VRT");
|
|
|
|
|
tileSpatialReference.ExportToWkt(out string wkt, null);
|
|
|
|
|
string[] options = new string[] { "-t_srs", wkt, "-r", "rms", "-of", "VRT" };
|
|
|
|
|
Gdal.GDALProgressFuncDelegate progressFuncDelegate = new Gdal.GDALProgressFuncDelegate((complete, msg, data) =>
|
|
|
|
|
{
|
|
|
|
|
if (complete >= 1)
|
|
|
|
|
{
|
|
|
|
|
//isProgressCompleted = true;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
});
|
|
|
|
|
return Gdal.Warp(outputFile, new Dataset[] { inputDataset }, new GDALWarpAppOptions(options), progressFuncDelegate, null);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
inputDataset.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建单个瓦片
|
|
|
|
|
private void CreateKOTiles(TileInfo tile)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
byte[] bgra = new byte[TiledSize * TiledSize * 4];
|
|
|
|
|
double resolution = tile.Bound.Width / this.TiledSize;
|
|
|
|
|
|
|
|
|
|
bool isExist = false;
|
|
|
|
|
byte[] rgbTop = null;
|
|
|
|
|
Rectangle dTopRect = new Rectangle();
|
|
|
|
|
if (TopRasterInfo != null)
|
|
|
|
|
{
|
|
|
|
|
Envelope topEnvelope = tile.Bound.Intersection(TopRasterInfo.Extent);
|
|
|
|
|
if (topEnvelope != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Rectangle sTopRect = MultRaster2MBTiles.Envelope2Rect(TopRasterInfo, topEnvelope);
|
|
|
|
|
dTopRect = MultRaster2MBTiles.Envelope2Rect(tile.Bound, topEnvelope, resolution);
|
|
|
|
|
rgbTop = new byte[dTopRect.Width * dTopRect.Height];
|
|
|
|
|
CPLErr err = TopRasterInfo.Dataset.GetRasterBand(1).ReadRaster(sTopRect.X, sTopRect.Y, sTopRect.Width, sTopRect.Height, rgbTop, dTopRect.Width, dTopRect.Height, 0, 0);
|
|
|
|
|
if (err != CPLErr.CE_None)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(string.Format("读取Level:{0},Column:{1},Row:{2}的瓦片出错!", tile.Level, tile.Column, tile.Row));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
//Console.WriteLine(string.Format("读取Level:{0},Column:{1},Row:{2}的瓦片出错!", tile.Level, tile.Column, tile.Row));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//填充数据到bgra
|
|
|
|
|
for (int i = 0; i < dTopRect.Width; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < dTopRect.Height; j++)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * dTopRect.Width;
|
|
|
|
|
byte rVal = rgbTop[offset];
|
|
|
|
|
if (rVal > 250)
|
|
|
|
|
{
|
|
|
|
|
isExist = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("填充数据到bgra失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//没有数据
|
|
|
|
|
if (!isExist)
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var raster in Rasters)
|
|
|
|
|
{
|
|
|
|
|
Envelope pEnvelope = tile.Bound.Intersection(raster.Extent);
|
|
|
|
|
if (pEnvelope == null)
|
|
|
|
|
continue;
|
|
|
|
|
Rectangle sRect = MultRaster2MBTiles.Envelope2Rect(raster, pEnvelope);
|
|
|
|
|
Rectangle dRect = MultRaster2MBTiles.Envelope2Rect(tile.Bound, pEnvelope, resolution);
|
|
|
|
|
if (raster.Bands > 2)
|
|
|
|
|
{
|
|
|
|
|
byte[] rgb = new byte[dRect.Width * dRect.Height * 3];
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
CPLErr err = raster.Dataset.ReadRaster(sRect.X, sRect.Y, sRect.Width, sRect.Height, rgb, dRect.Width, dRect.Height, 3, new int[] { 1, 2, 3 }, 0, 0, 0);
|
|
|
|
|
if (err != CPLErr.CE_None)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(string.Format("读取Level:{0},Column:{1},Row:{2}的瓦片出错!", tile.Level, tile.Column, tile.Row));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
//填充数据到bgra
|
|
|
|
|
for (int i = 0; i < dRect.Width; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < dRect.Height; j++)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * dRect.Width;
|
|
|
|
|
byte rVal = rgb[offset];
|
|
|
|
|
byte gVal = rgb[offset + dRect.Width * dRect.Height];
|
|
|
|
|
byte bVal = rgb[offset + dRect.Width * dRect.Height * 2];
|
|
|
|
|
|
|
|
|
|
if ((rVal == 0 && gVal == 0 && bVal == 0) || (rVal == 255 && gVal == 255 && bVal == 255))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
int pixelPos = (dRect.X + i) + (dRect.Y + j) * this.TiledSize;
|
|
|
|
|
bgra[pixelPos * 4] = bVal;
|
|
|
|
|
bgra[pixelPos * 4 + 1] = gVal;
|
|
|
|
|
bgra[pixelPos * 4 + 2] = rVal;
|
|
|
|
|
bgra[pixelPos * 4 + 3] = 255;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("填充数据到bgra失败:" +ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
byte[] r = new byte[dRect.Width * dRect.Height];
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
CPLErr err = raster.Dataset.GetRasterBand(1).ReadRaster(sRect.X, sRect.Y, sRect.Width, sRect.Height, r, dRect.Width, dRect.Height, 0, 0);
|
|
|
|
|
if (err != CPLErr.CE_None)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(string.Format("读取Level:{0},Column:{1},Row:{2}的瓦片出错!", tile.Level, tile.Column, tile.Row));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//填充数据到bgra
|
|
|
|
|
for (int i = 0; i < dRect.Width; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < dRect.Height; j++)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * dRect.Width;
|
|
|
|
|
byte rVal = r[offset];
|
|
|
|
|
if (rVal < 5)
|
|
|
|
|
continue;
|
|
|
|
|
int pixelPos = (dRect.X + i) + (dRect.Y + j) * this.TiledSize;
|
|
|
|
|
bgra[pixelPos * 4] = rVal;
|
|
|
|
|
bgra[pixelPos * 4 + 1] = rVal;
|
|
|
|
|
bgra[pixelPos * 4 + 2] = rVal;
|
|
|
|
|
bgra[pixelPos * 4 + 3] = 255;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("填充数据到bgra失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rgbTop != null)
|
|
|
|
|
{
|
|
|
|
|
//填充数据到bgra
|
|
|
|
|
for (int i = 0; i < dTopRect.Width; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < dTopRect.Height; j++)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * dTopRect.Width;
|
|
|
|
|
byte rVal = rgbTop[offset];
|
|
|
|
|
if (rVal > 250)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
int pixelPos = (dTopRect.X + i) + (dTopRect.Y + j) * this.TiledSize;
|
|
|
|
|
bgra[pixelPos * 4] = 255;
|
|
|
|
|
bgra[pixelPos * 4 + 1] = 255;
|
|
|
|
|
bgra[pixelPos * 4 + 2] = 255;
|
|
|
|
|
bgra[pixelPos * 4 + 3] = 0;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("填充数据到bgra失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int dataHasValue = 0;
|
|
|
|
|
for (int i = 0; i < TiledSize * TiledSize; i++)
|
|
|
|
|
{
|
|
|
|
|
if (bgra[i * 4 + 3] != 0)
|
|
|
|
|
{
|
|
|
|
|
dataHasValue++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//没有数据
|
|
|
|
|
if (dataHasValue < 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//写入数据文件
|
|
|
|
|
using (MemoryStream ms = new MemoryStream())
|
|
|
|
|
{
|
|
|
|
|
Bitmap bitmap = new Bitmap(TiledSize, TiledSize, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Marshal.Copy(bgra, 0, bitmapData.Scan0, bgra.Length);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("拷贝bgra失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
bitmap.UnlockBits(bitmapData);
|
|
|
|
|
}
|
|
|
|
|
if (ImageFormat.Jpeg.Equals(ImgFormat) || dataHasValue > this.TiledSize * (this.TiledSize - 1))
|
|
|
|
|
{
|
|
|
|
|
EncoderParameter p;
|
|
|
|
|
EncoderParameters ps;
|
|
|
|
|
|
|
|
|
|
ps = new EncoderParameters(1);
|
|
|
|
|
|
|
|
|
|
p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)this.CompressRate);
|
|
|
|
|
ps.Param[0] = p;
|
|
|
|
|
ImageCodecInfo pngEncoder = GetEncoder(ImageFormat.Jpeg);
|
|
|
|
|
bitmap.Save(ms, pngEncoder, ps);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
string path = AppDomain.CurrentDomain.BaseDirectory + @"pngquant\pngquant.exe";
|
|
|
|
|
if (File.Exists(path))
|
|
|
|
|
{
|
|
|
|
|
PngQuant.Run(bitmap, ms, path);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
bitmap.Save(ms, ImageFormat.Png);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("写入数据文件失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
bitmap.Dispose();
|
|
|
|
|
}
|
|
|
|
|
tile.Data = ms.ToArray();
|
|
|
|
|
tile.Resolution = resolution;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("创建单个瓦片失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool isY = false;
|
|
|
|
|
private ImageCodecInfo GetEncoder(ImageFormat format)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
|
|
|
|
|
|
|
|
|
|
foreach (ImageCodecInfo codec in codecs)
|
|
|
|
|
{
|
|
|
|
|
if (codec.FormatID == format.Guid)
|
|
|
|
|
{
|
|
|
|
|
return codec;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Thread doThread;
|
|
|
|
|
public event EventHandler Event2;
|
|
|
|
|
public void Dowork()
|
|
|
|
|
{
|
|
|
|
|
doThread = new Thread(new ThreadStart(read));
|
|
|
|
|
doThread.IsBackground = true;
|
|
|
|
|
doThread.Name = "读取图片线程" + Guid.NewGuid().ToString();
|
|
|
|
|
doThread.Priority = ThreadPriority.Highest;
|
|
|
|
|
doThread.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private List<TileInfo> doneList = new List<TileInfo>();
|
|
|
|
|
public void read()
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in TileInfos)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
CreateKOTiles(item);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("读取图片线程异常" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
doneList.Add(item);
|
|
|
|
|
if (doneList.Count > 20)
|
|
|
|
|
{
|
|
|
|
|
Event2?.Invoke(doneList.ToArray(), null);
|
|
|
|
|
doneList.Clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (doneList.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
Event2?.Invoke(doneList.ToArray(), null);
|
|
|
|
|
doneList.Clear();
|
|
|
|
|
}
|
|
|
|
|
Console.WriteLine(doThread.Name + "结束");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Stop()
|
|
|
|
|
{
|
|
|
|
|
this.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (this.doThread != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
this.doThread.Abort();
|
|
|
|
|
}
|
|
|
|
|
catch { }
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
this.doThread = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public delegate void ProgressReport(int sum, int current);
|
|
|
|
|
internal class WriteDatabase : IDisposable
|
|
|
|
|
{
|
|
|
|
|
public event ProgressReport Report;
|
|
|
|
|
public SQLiteConnection Conn { get; set; }
|
|
|
|
|
public int TileCount { get; set; }
|
|
|
|
|
private List<TileInfo> needInsertDataList = new List<TileInfo>();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void InsertDataRange(TileInfo[] data)
|
|
|
|
|
{
|
|
|
|
|
lock (needInsertDataList)
|
|
|
|
|
{
|
|
|
|
|
needInsertDataList.AddRange(data);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread doworkThread = null;
|
|
|
|
|
|
|
|
|
|
public event EventHandler Done;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
if (doworkThread != null)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
doworkThread.Abort();
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
doworkThread = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void BestDoWork()
|
|
|
|
|
{
|
|
|
|
|
doworkThread = new Thread(new ThreadStart(WriteTodb));
|
|
|
|
|
doworkThread.IsBackground = true;
|
|
|
|
|
doworkThread.Name = "写入图片线程" + Guid.NewGuid().ToString();
|
|
|
|
|
doworkThread.Start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void WriteTodb()
|
|
|
|
|
{
|
|
|
|
|
Conn.Open();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
SQLiteTransaction pTan = Conn.BeginTransaction();
|
|
|
|
|
SQLiteCommand cmd = new SQLiteCommand(Conn);
|
|
|
|
|
cmd.CommandText = "insert into tiles (centerX,centerY,maxX,maxY,minX,minY,resolution,tile_Data) values(@centerX,@centerY,@maxX,@maxY,@minX,@minY,@resolution,@tile_Data)";
|
|
|
|
|
cmd.Parameters.Add(new SQLiteParameter("@centerX", System.Data.DbType.Double));
|
|
|
|
|
cmd.Parameters.Add(new SQLiteParameter("@centerY", System.Data.DbType.Double));
|
|
|
|
|
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));
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in datas)
|
|
|
|
|
{
|
|
|
|
|
if (item.Data == null)
|
|
|
|
|
continue;
|
|
|
|
|
cmd.Parameters[0].Value = (item.Bound.XMax - item.Bound.XMin) / 2 + item.Bound.XMin;
|
|
|
|
|
cmd.Parameters[1].Value = (item.Bound.YMax - item.Bound.YMin) / 2 + item.Bound.YMin;
|
|
|
|
|
cmd.Parameters[2].Value = item.Bound.XMax;
|
|
|
|
|
cmd.Parameters[3].Value = item.Bound.YMax;
|
|
|
|
|
cmd.Parameters[4].Value = item.Bound.XMin;
|
|
|
|
|
cmd.Parameters[5].Value = item.Bound.YMin;
|
|
|
|
|
cmd.Parameters[6].Value = item.Resolution;
|
|
|
|
|
cmd.Parameters[7].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 (centerX,centerY,maxX,maxY,minX,minY);";
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
pTan.Commit();
|
|
|
|
|
pTan.Dispose();
|
|
|
|
|
if (Done != null)
|
|
|
|
|
{
|
|
|
|
|
Done(null, null);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Conn.Close();
|
|
|
|
|
Conn.Dispose();
|
|
|
|
|
SQLiteConnection.ClearPool(Conn);
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
GC.Collect();
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Thread doworkThreadLevel = null;
|
|
|
|
|
public void DoWorkLevel()
|
|
|
|
|
{
|
|
|
|
|
//doworkThreadLevel = new Thread(new ThreadStart(WriteTodbLevel));
|
|
|
|
|
//doworkThreadLevel.IsBackground = true;
|
|
|
|
|
//doworkThreadLevel.Name = "写入图片线程" + Guid.NewGuid().ToString();
|
|
|
|
|
//doworkThreadLevel.Start();
|
|
|
|
|
WriteTodbLevel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void WriteTodbLevel()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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.ExecuteNonQuery();
|
|
|
|
|
item.Data = null;
|
|
|
|
|
}
|
|
|
|
|
dealTileCount += datas.Length;
|
|
|
|
|
if (Report != null)
|
|
|
|
|
{
|
|
|
|
|
Report(TileCount, dealTileCount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//Thread.Sleep(3000);
|
|
|
|
|
Thread.Sleep(0);
|
|
|
|
|
}
|
|
|
|
|
cmd.CommandText = "CREATE INDEX tiles_index ON tiles (zoom_level,tile_column,tile_row);";
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
cmd.Dispose();
|
|
|
|
|
pTan.Commit();
|
|
|
|
|
pTan.Dispose();
|
|
|
|
|
if (Done != null)
|
|
|
|
|
{
|
|
|
|
|
Done(null, null);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("图片写入db失败:" + ex.Message);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
Conn.Close();
|
|
|
|
|
Conn.Dispose();
|
|
|
|
|
SQLiteConnection.ClearPool(Conn);
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
GC.Collect();
|
|
|
|
|
Thread.Sleep(10);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class UnionVector
|
|
|
|
|
{
|
|
|
|
|
public static Layer UnionVectorLayers(List<Layer> layers, double distance = 100.0)
|
|
|
|
|
{
|
|
|
|
|
Layer rstLayer = null;
|
|
|
|
|
Geometry rstGeometry = null;
|
|
|
|
|
foreach (Layer item in layers)
|
|
|
|
|
{
|
|
|
|
|
rstGeometry = UnionGeometry(rstGeometry, UnionVectorLayer(item));
|
|
|
|
|
}
|
|
|
|
|
//double distance = 100.0;
|
|
|
|
|
//double.TryParse(System.Configuration.ConfigurationManager.AppSettings["BufferDistance"], out distance);
|
|
|
|
|
if (rstGeometry == null) return null;
|
|
|
|
|
rstGeometry = rstGeometry.Buffer(distance, 30);
|
|
|
|
|
OSGeo.OGR.Driver ogrDirver = Ogr.GetDriverByName("Memory");
|
|
|
|
|
DataSource dsLayers = ogrDirver.CreateDataSource("", null);
|
|
|
|
|
rstLayer = dsLayers.CreateLayer("", null, wkbGeometryType.wkbPolygon, null);
|
|
|
|
|
Feature f = new Feature(rstLayer.GetLayerDefn());
|
|
|
|
|
f.SetGeometry(rstGeometry);
|
|
|
|
|
rstLayer.CreateFeature(f);
|
|
|
|
|
return rstLayer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Geometry UnionVectorLayer(Layer layer)
|
|
|
|
|
{
|
|
|
|
|
Feature feature = layer.GetNextFeature();
|
|
|
|
|
if (feature == null) return null;
|
|
|
|
|
Geometry rstGeometry = feature.GetGeometryRef();
|
|
|
|
|
while ((feature = layer.GetNextFeature()) != null)
|
|
|
|
|
{
|
|
|
|
|
Geometry geo = feature.GetGeometryRef();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
rstGeometry = rstGeometry.Union(geo);
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
return rstGeometry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Geometry UnionGeometry(Geometry geometry1, Geometry geometry2)
|
|
|
|
|
{
|
|
|
|
|
if (geometry1 == null)
|
|
|
|
|
return geometry2;
|
|
|
|
|
return geometry1.Union(geometry2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Layer UnionVectorLayers(List<LayerInfo> layerPaths, double distance = 100.0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//消除中文路径无法识别的问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
|
|
|
|
//解决shape文件字段中文内容读取问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
|
|
|
|
|
List<Layer> layers = new List<Layer>();
|
|
|
|
|
foreach (LayerInfo item in layerPaths)
|
|
|
|
|
{
|
|
|
|
|
DataSource dataSource = Ogr.Open(item.LayerSourcePath, 0);
|
|
|
|
|
if (string.IsNullOrEmpty(item.LayerName))
|
|
|
|
|
layers.Add(dataSource.GetLayerByIndex(0));
|
|
|
|
|
else
|
|
|
|
|
layers.Add(dataSource.GetLayerByName(item.LayerName));
|
|
|
|
|
}
|
|
|
|
|
return UnionVectorLayers(layers, distance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Layer CreateLayer(List<Geometry> geometrys, double distance = 100.0)
|
|
|
|
|
{
|
|
|
|
|
//消除中文路径无法识别的问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
|
|
|
|
//解决shape文件字段中文内容读取问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
|
|
|
|
|
Geometry rstGeometry = null;
|
|
|
|
|
foreach (Geometry item in geometrys)
|
|
|
|
|
{
|
|
|
|
|
rstGeometry = UnionGeometry(rstGeometry, item);
|
|
|
|
|
}
|
|
|
|
|
if (rstGeometry == null) return null;
|
|
|
|
|
Layer rstLayer = null;
|
|
|
|
|
rstGeometry = rstGeometry.Buffer(distance, 30);
|
|
|
|
|
OSGeo.OGR.Driver ogrDirver = Ogr.GetDriverByName("Memory");
|
|
|
|
|
DataSource dsLayers = ogrDirver.CreateDataSource("", null);
|
|
|
|
|
rstLayer = dsLayers.CreateLayer("", null, wkbGeometryType.wkbPolygon, null);
|
|
|
|
|
Feature f = new Feature(rstLayer.GetLayerDefn());
|
|
|
|
|
f.SetGeometry(rstGeometry);
|
|
|
|
|
rstLayer.CreateFeature(f);
|
|
|
|
|
return rstLayer;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static List<FeatureInfo> GetVectorLayerFeatures(List<LayerInfo> layerPaths)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
//消除中文路径无法识别的问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
|
|
|
|
|
//解决shape文件字段中文内容读取问题
|
|
|
|
|
OSGeo.GDAL.Gdal.SetConfigOption("SHAPE_ENCODING", "UTF-8");
|
|
|
|
|
List<FeatureInfo> layers = new List<FeatureInfo>();
|
|
|
|
|
foreach (LayerInfo item in layerPaths)
|
|
|
|
|
{
|
|
|
|
|
DataSource dataSource = Ogr.Open(item.LayerSourcePath, 0);
|
|
|
|
|
Layer layer = null;
|
|
|
|
|
if (string.IsNullOrEmpty(item.LayerName))
|
|
|
|
|
{
|
|
|
|
|
layer = dataSource.GetLayerByIndex(0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
layer = dataSource.GetLayerByName(item.LayerName);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (layer != null)
|
|
|
|
|
layers.AddRange(GetLayerFeatures(layer));
|
|
|
|
|
}
|
|
|
|
|
return layers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<FeatureInfo> GetLayerFeatures(Layer layer)
|
|
|
|
|
{
|
|
|
|
|
List<FeatureInfo> lst = new List<FeatureInfo>();
|
|
|
|
|
Feature feature = layer.GetNextFeature();
|
|
|
|
|
if (feature == null) return null;
|
|
|
|
|
int fieldNameIndex = layer.FindFieldIndex("XIJXZQMC", 0);
|
|
|
|
|
int fieldCodeIndex = layer.FindFieldIndex("XIJXZQDM", 0);
|
|
|
|
|
while ((feature = layer.GetNextFeature()) != null)
|
|
|
|
|
{
|
|
|
|
|
FeatureInfo featureInfo = new FeatureInfo();
|
|
|
|
|
if (fieldCodeIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
featureInfo.Code = feature.GetFieldAsString("XIJXZQDM");
|
|
|
|
|
}
|
|
|
|
|
if (fieldNameIndex >= 0)
|
|
|
|
|
{
|
|
|
|
|
featureInfo.Name = feature.GetFieldAsString("XIJXZQMC");
|
|
|
|
|
}
|
|
|
|
|
featureInfo.Shape = feature;
|
|
|
|
|
lst.Add(featureInfo);
|
|
|
|
|
}
|
|
|
|
|
return lst;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Layer CreateVectorLayer(FeatureInfo featureInfo)
|
|
|
|
|
{
|
|
|
|
|
Layer rstLayer = null;
|
|
|
|
|
OSGeo.OGR.Driver ogrDirver = Ogr.GetDriverByName("Memory");
|
|
|
|
|
DataSource dsLayers = ogrDirver.CreateDataSource("", null);
|
|
|
|
|
rstLayer = dsLayers.CreateLayer("", null, wkbGeometryType.wkbPolygon, null);
|
|
|
|
|
rstLayer.CreateFeature(featureInfo.Shape);
|
|
|
|
|
return rstLayer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取影像
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="layerInfo"></param>
|
|
|
|
|
/// <param name="distance"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static List<TileInfo> GetTileInfosByLayer(LayerInfo layerInfo, double distance = 100.0)
|
|
|
|
|
{
|
|
|
|
|
DataSource dataSource = null;
|
|
|
|
|
Layer layer = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<TileInfo> tileInfos = new List<TileInfo>();
|
|
|
|
|
dataSource = Ogr.Open(layerInfo.LayerSourcePath, 0);
|
|
|
|
|
if (string.IsNullOrEmpty(layerInfo.LayerName))
|
|
|
|
|
layer = dataSource.GetLayerByIndex(0);
|
|
|
|
|
else
|
|
|
|
|
layer = dataSource.GetLayerByName(layerInfo.LayerName);
|
|
|
|
|
|
|
|
|
|
Feature feature = null;
|
|
|
|
|
OSGeo.OGR.Envelope geoEnvelope = new OSGeo.OGR.Envelope();
|
|
|
|
|
while ((feature = layer.GetNextFeature()) != null)
|
|
|
|
|
{
|
|
|
|
|
Geometry geo = feature.GetGeometryRef();
|
|
|
|
|
geo = geo.Buffer(distance, 30);
|
|
|
|
|
geo.GetEnvelope(geoEnvelope);
|
|
|
|
|
if (geoEnvelope != null)
|
|
|
|
|
{
|
|
|
|
|
Envelope e = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
XMin = geoEnvelope.MinX,
|
|
|
|
|
YMin = geoEnvelope.MinY,
|
|
|
|
|
XMax = geoEnvelope.MaxX,
|
|
|
|
|
YMax = geoEnvelope.MaxY
|
|
|
|
|
};
|
|
|
|
|
tileInfos.Add(new TileInfo(e, 0, 0, 0));
|
|
|
|
|
geoEnvelope.Dispose();
|
|
|
|
|
geoEnvelope = new OSGeo.OGR.Envelope();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tileInfos;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
if (dataSource != null)
|
|
|
|
|
{
|
|
|
|
|
dataSource.Dispose();
|
|
|
|
|
}
|
|
|
|
|
if (layer != null)
|
|
|
|
|
{
|
|
|
|
|
layer.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class LayerInfo
|
|
|
|
|
{
|
|
|
|
|
public string LayerSourcePath { get; set; }
|
|
|
|
|
public string LayerName { get; set; }
|
|
|
|
|
public int LayerIndex { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class FeatureInfo
|
|
|
|
|
{
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
public string Code { get; set; }
|
|
|
|
|
public Feature Shape { get; set; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public enum EnumSaveType
|
|
|
|
|
{
|
|
|
|
|
Level = 0, Resolution = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|