|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using OSGeo.GDAL;
|
|
|
|
|
using System.Data.SQLite;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Drawing.Imaging;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
|
|
|
|
namespace Kingo.Plugin.RasterToKOTilesApp.KoDataBase
|
|
|
|
|
{
|
|
|
|
|
class Raster2MBTiles
|
|
|
|
|
{
|
|
|
|
|
public ImageFormat ImgFormat { get; set; }
|
|
|
|
|
private Envelope rasterExtent;
|
|
|
|
|
|
|
|
|
|
private Envelope gridExtent;
|
|
|
|
|
|
|
|
|
|
private Rectangle rasterRect;
|
|
|
|
|
|
|
|
|
|
private Rectangle gridRect;
|
|
|
|
|
|
|
|
|
|
public int Level { get; set; }
|
|
|
|
|
|
|
|
|
|
//public Color TransparentColor { get; set; }
|
|
|
|
|
|
|
|
|
|
public int TiledSize { get; set; }
|
|
|
|
|
|
|
|
|
|
public string MBTilesPath { get; set; }
|
|
|
|
|
public Raster2MBTiles()
|
|
|
|
|
{
|
|
|
|
|
ImgFormat = ImageFormat.Jpeg;
|
|
|
|
|
}
|
|
|
|
|
//private
|
|
|
|
|
//设定层级,瓦片尺寸大小,计算初始网格,
|
|
|
|
|
//获取栅格数据的范围
|
|
|
|
|
//
|
|
|
|
|
private void CreateGrid()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
private Dataset dataset = null;
|
|
|
|
|
public void Open(string fileName)
|
|
|
|
|
{
|
|
|
|
|
//@"C:\Users\admin\Desktop\img\3203212013SPOT6DOM.img"
|
|
|
|
|
Gdal.AllRegister();
|
|
|
|
|
dataset = Gdal.Open(fileName, Access.GA_ReadOnly);
|
|
|
|
|
|
|
|
|
|
int xsize = dataset.RasterXSize;
|
|
|
|
|
int ysize = dataset.RasterYSize;
|
|
|
|
|
double[] geotransform = new double[6];
|
|
|
|
|
dataset.GetGeoTransform(geotransform);
|
|
|
|
|
double north = geotransform[3];
|
|
|
|
|
double south = geotransform[3] + geotransform[5] * ysize;
|
|
|
|
|
double east = geotransform[0] + geotransform[1] * xsize;
|
|
|
|
|
double west = geotransform[0];
|
|
|
|
|
//获取栅格范围
|
|
|
|
|
this.rasterExtent = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
XMax = east,
|
|
|
|
|
XMin = west,
|
|
|
|
|
YMax = north,
|
|
|
|
|
YMin = south
|
|
|
|
|
};
|
|
|
|
|
this.rasterRect = new Rectangle(0, 0, xsize, ysize);
|
|
|
|
|
//计算最小外接正方形
|
|
|
|
|
double width = east - west;
|
|
|
|
|
double height = north - south;
|
|
|
|
|
double maxLength = width > height ? width : height;
|
|
|
|
|
this.gridExtent = new Envelope()
|
|
|
|
|
{
|
|
|
|
|
YMax = north + (maxLength - height) / 2,
|
|
|
|
|
YMin = south - (maxLength - height) / 2,
|
|
|
|
|
XMax = east + (maxLength - width) / 2,
|
|
|
|
|
XMin = west - (maxLength - width) / 2,
|
|
|
|
|
};
|
|
|
|
|
int gridWidth = xsize > ysize ? xsize : ysize;
|
|
|
|
|
this.gridRect = new Rectangle(0, 0, gridWidth, gridWidth);
|
|
|
|
|
//CreateMBTiles2(dataset);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateMBTiles(Dataset dataset)
|
|
|
|
|
{
|
|
|
|
|
string dir = System.Windows.Forms.Application.StartupPath + "\\Tiles";
|
|
|
|
|
if (!System.IO.Directory.Exists(dir))
|
|
|
|
|
{
|
|
|
|
|
System.IO.Directory.CreateDirectory(dir);
|
|
|
|
|
}
|
|
|
|
|
for (int level = 0; level < Level; level++)
|
|
|
|
|
{
|
|
|
|
|
int count = (int)Math.Pow(2, level);
|
|
|
|
|
int delSize = (int)(this.gridRect.Width / count);
|
|
|
|
|
for (int col = 0; col < count; col++)
|
|
|
|
|
{
|
|
|
|
|
int offsetx = col * delSize;
|
|
|
|
|
int sizex = delSize;
|
|
|
|
|
int BufferWidth = TiledSize;
|
|
|
|
|
bool isOutX = (offsetx + delSize) >= this.rasterRect.Width;
|
|
|
|
|
if (isOutX)
|
|
|
|
|
{
|
|
|
|
|
//计算x方向真正的偏移量
|
|
|
|
|
sizex = this.rasterRect.Width - offsetx;
|
|
|
|
|
BufferWidth = (int)((sizex * 1.0 / delSize) * TiledSize);
|
|
|
|
|
}
|
|
|
|
|
for (int row = 0; row < count; row++)
|
|
|
|
|
{
|
|
|
|
|
int offsety = row * delSize;
|
|
|
|
|
int sizey = delSize;
|
|
|
|
|
int BufferHeight = TiledSize;
|
|
|
|
|
bool isOutY = (offsety + delSize) >= this.rasterRect.Height;
|
|
|
|
|
if (isOutY)
|
|
|
|
|
{
|
|
|
|
|
//计算y方向真正的偏移量
|
|
|
|
|
sizey = this.rasterRect.Height - offsety;
|
|
|
|
|
BufferHeight = (int)((sizey * 1.0 / delSize) * TiledSize);
|
|
|
|
|
}
|
|
|
|
|
//读取数据
|
|
|
|
|
Bitmap bitmap = new Bitmap(TiledSize, TiledSize, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
|
|
|
|
|
int bufferSize = BufferWidth * BufferHeight;
|
|
|
|
|
int[] r = new int[bufferSize];
|
|
|
|
|
Band band1 = dataset.GetRasterBand(1);
|
|
|
|
|
band1.ReadRaster(offsetx, offsety, sizex, sizey, r, BufferWidth, BufferHeight, 0, 0); //读取图像到内存
|
|
|
|
|
|
|
|
|
|
int[] g = new int[bufferSize];
|
|
|
|
|
Band band2 = dataset.GetRasterBand(2);
|
|
|
|
|
band2.ReadRaster(offsetx, offsety, sizex, sizey, g, BufferWidth, BufferHeight, 0, 0);
|
|
|
|
|
|
|
|
|
|
int[] b = new int[bufferSize];
|
|
|
|
|
Band band3 = dataset.GetRasterBand(3);
|
|
|
|
|
band3.ReadRaster(offsetx, offsety, sizex, sizey, b, BufferWidth, BufferHeight, 0, 0);
|
|
|
|
|
|
|
|
|
|
int i, j, numNoColor = 0;
|
|
|
|
|
for (i = 0; i < BufferWidth; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < BufferHeight; j++)
|
|
|
|
|
{
|
|
|
|
|
int cur = i + j * BufferWidth;
|
|
|
|
|
|
|
|
|
|
if (r[cur] != 0 || g[cur] != 0 || b[cur] != 0)
|
|
|
|
|
{
|
|
|
|
|
Color newColor = Color.FromArgb(255, r[cur], g[cur], b[cur]);
|
|
|
|
|
bitmap.SetPixel(i, j, newColor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
numNoColor++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (numNoColor != bufferSize)
|
|
|
|
|
{
|
|
|
|
|
//写入数据文件
|
|
|
|
|
bitmap.Save(string.Format("{0}\\{1}-{2}-{3}.png", dir, level, col, row));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
bitmap.Dispose();
|
|
|
|
|
//越界后停止读取
|
|
|
|
|
if (isOutY)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//越界后停止读取
|
|
|
|
|
if (isOutX)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void CreateMBTiles2()
|
|
|
|
|
{
|
|
|
|
|
string connString = "Data Source=" + this.MBTilesPath;
|
|
|
|
|
if (File.Exists(this.MBTilesPath))
|
|
|
|
|
{
|
|
|
|
|
File.Delete(this.MBTilesPath);
|
|
|
|
|
}
|
|
|
|
|
File.WriteAllBytes(this.MBTilesPath, Properties.Resources.Template);
|
|
|
|
|
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 = "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));
|
|
|
|
|
CreateKOTiles(cmd);
|
|
|
|
|
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.TiledSize);
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//写入图片格式
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Format", "png");
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//写入空间参考
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Projection", this.dataset.GetProjection());
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//写入Extend
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Bounds",
|
|
|
|
|
string.Format("{0},{1},{2},{3}", this.rasterExtent.XMin, rasterExtent.YMin, rasterExtent.XMax, rasterExtent.YMax));
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//写入origin
|
|
|
|
|
cmd.CommandText = string.Format(sqlFormat, "Origin",
|
|
|
|
|
string.Format("{0},{1}", rasterExtent.XMin, rasterExtent.YMax));
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//写入分辨率
|
|
|
|
|
double dbResolution = (this.gridExtent.XMax - this.gridExtent.XMin) / this.TiledSize;
|
|
|
|
|
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.Level);
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
cmd.Dispose();
|
|
|
|
|
pTan.Commit();
|
|
|
|
|
pTan.Dispose();
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
conn.Close();
|
|
|
|
|
GC.Collect();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CreateKOTiles(SQLiteCommand cmd)
|
|
|
|
|
{
|
|
|
|
|
for (int level = 0; level < Level; level++)
|
|
|
|
|
{
|
|
|
|
|
int count = (int)Math.Pow(2, level);
|
|
|
|
|
double delSize = this.gridRect.Width * 1.0 / count;
|
|
|
|
|
for (int col = 0; col < count; col++)
|
|
|
|
|
{
|
|
|
|
|
double offsetx = col * delSize;
|
|
|
|
|
double sizex = delSize;
|
|
|
|
|
int bufferWidth = TiledSize;
|
|
|
|
|
bool isOutX = (offsetx + delSize) >= this.rasterRect.Width;
|
|
|
|
|
if (isOutX)
|
|
|
|
|
{
|
|
|
|
|
//计算x方向真正的偏移量
|
|
|
|
|
sizex = this.rasterRect.Width - offsetx;
|
|
|
|
|
bufferWidth = (int)Math.Round((sizex / delSize) * TiledSize);
|
|
|
|
|
}
|
|
|
|
|
for (int row = 0; row < count; row++)
|
|
|
|
|
{
|
|
|
|
|
double offsety = row * delSize;
|
|
|
|
|
double sizey = delSize;
|
|
|
|
|
int bufferHeight = TiledSize;
|
|
|
|
|
bool isOutY = (offsety + delSize) >= this.rasterRect.Height;
|
|
|
|
|
if (isOutY)
|
|
|
|
|
{
|
|
|
|
|
//计算y方向真正的偏移量
|
|
|
|
|
sizey = this.rasterRect.Height - offsety;
|
|
|
|
|
bufferHeight = (int)Math.Round((sizey / delSize) * TiledSize);
|
|
|
|
|
}
|
|
|
|
|
//读取数据
|
|
|
|
|
byte[] bytes = GetBitmap(bufferWidth, bufferHeight, (int)Math.Round(offsetx), (int)Math.Round(offsety), (int)Math.Round(sizex), (int)Math.Round(sizey));
|
|
|
|
|
if (bytes != null)
|
|
|
|
|
{
|
|
|
|
|
cmd.Parameters[0].Value = level;
|
|
|
|
|
cmd.Parameters[1].Value = col;
|
|
|
|
|
cmd.Parameters[2].Value = row;
|
|
|
|
|
cmd.Parameters[3].Value = bytes;
|
|
|
|
|
cmd.ExecuteNonQuery();
|
|
|
|
|
//for (int i = 0; i < 10000; i++)
|
|
|
|
|
//{
|
|
|
|
|
// cmd.ExecuteNonQuery();
|
|
|
|
|
//}
|
|
|
|
|
//return;
|
|
|
|
|
//bitmap.Save(string.Format("{0}\\{1}-{2}-{3}.png", dir, level, col, row));
|
|
|
|
|
//File.WriteAllBytes(string.Format("{0}\\tiles\\{1}-{2}-{3}.png", System.Windows.Forms.Application.StartupPath, level, col, row),bytes);
|
|
|
|
|
}
|
|
|
|
|
//越界后停止读取
|
|
|
|
|
if (isOutY)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//越界后停止读取
|
|
|
|
|
if (isOutX)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private byte[] GetBitmap(int bufferWidth, int bufferHeight, int offsetx, int offsety, int sizex, int sizey)
|
|
|
|
|
{
|
|
|
|
|
int bufferSize = bufferWidth * bufferHeight;
|
|
|
|
|
byte[] argb = new byte[TiledSize * TiledSize * 4];
|
|
|
|
|
for (int i = 0; i < TiledSize * TiledSize; i++)
|
|
|
|
|
{
|
|
|
|
|
argb[i * 4] = 255;
|
|
|
|
|
argb[i * 4 + 1] = 255;
|
|
|
|
|
argb[i * 4 + 2] = 255;
|
|
|
|
|
}
|
|
|
|
|
int numNoColor = 0;
|
|
|
|
|
if (this.dataset.RasterCount >= 3)
|
|
|
|
|
{
|
|
|
|
|
byte[] rgb = new byte[bufferSize * 3];
|
|
|
|
|
dataset.ReadRaster(offsetx, offsety, sizex, sizey, rgb, bufferWidth, bufferHeight, 3, new int[] { 1, 2, 3 }, 0, 0, 0);
|
|
|
|
|
int i, j;
|
|
|
|
|
for (i = 0; i < bufferWidth; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < bufferHeight; j++)
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * bufferWidth;
|
|
|
|
|
byte rVal = rgb[offset];
|
|
|
|
|
byte gVal = rgb[offset + bufferSize];
|
|
|
|
|
byte bVal = rgb[offset + bufferSize * 2];
|
|
|
|
|
if (rVal != 0 || gVal != 0 || bVal != 0)
|
|
|
|
|
{
|
|
|
|
|
int pixelPos = i + j * this.TiledSize;
|
|
|
|
|
argb[pixelPos * 4] = bVal;
|
|
|
|
|
argb[pixelPos * 4 + 1] = gVal;
|
|
|
|
|
argb[pixelPos * 4 + 2] = rVal;
|
|
|
|
|
argb[pixelPos * 4 + 3] = 255;
|
|
|
|
|
//Color newColor = Color.FromArgb(255, rVal, gVal, bVal);
|
|
|
|
|
//bitmap.SetPixel(i, j, newColor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
numNoColor++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//bitmap.LockBits(
|
|
|
|
|
byte[] r = new byte[bufferSize];
|
|
|
|
|
Band band1 = dataset.GetRasterBand(1);
|
|
|
|
|
band1.ReadRaster(offsetx, offsety, sizex, sizey, r, bufferWidth, bufferHeight, 0, 0);
|
|
|
|
|
int i, j;
|
|
|
|
|
for (i = 0; i < bufferWidth; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 0; j < bufferHeight; j++)
|
|
|
|
|
{
|
|
|
|
|
int offset = i + j * bufferWidth;
|
|
|
|
|
byte rVal = r[offset];
|
|
|
|
|
if (rVal != 0)
|
|
|
|
|
{
|
|
|
|
|
int pixelPos = i + j * this.TiledSize;
|
|
|
|
|
argb[pixelPos * 4] = rVal;
|
|
|
|
|
argb[pixelPos * 4 + 1] = rVal;
|
|
|
|
|
argb[pixelPos * 4 + 2] = rVal;
|
|
|
|
|
argb[pixelPos * 4 + 3] = 255;
|
|
|
|
|
//Color newColor = Color.FromArgb(255, rVal, rVal, rVal);
|
|
|
|
|
//bitmap.SetPixel(i, j, newColor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
numNoColor++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (numNoColor != bufferSize)
|
|
|
|
|
{
|
|
|
|
|
//写入数据文件
|
|
|
|
|
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(argb, 0, bitmapData.Scan0, argb.Length);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
bitmap.UnlockBits(bitmapData);
|
|
|
|
|
}
|
|
|
|
|
bitmap.Save(ms, ImgFormat);
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
bitmap.Dispose();
|
|
|
|
|
}
|
|
|
|
|
return ms.ToArray();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
if (dataset != null)
|
|
|
|
|
{
|
|
|
|
|
dataset.Dispose();
|
|
|
|
|
dataset = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Envelope
|
|
|
|
|
{
|
|
|
|
|
public double XMax { get; set; }
|
|
|
|
|
public double YMax { get; set; }
|
|
|
|
|
public double XMin { get; set; }
|
|
|
|
|
public double YMin { get; set; }
|
|
|
|
|
public double Width { get { return this.XMax - this.XMin; } }
|
|
|
|
|
public double Height { get { return this.YMax - this.YMin; } }
|
|
|
|
|
|
|
|
|
|
public Envelope() { }
|
|
|
|
|
public Envelope(double x1, double y1, double x2, double y2)
|
|
|
|
|
{
|
|
|
|
|
//this.XMin = double.NaN;
|
|
|
|
|
//this.XMax = double.NaN;
|
|
|
|
|
//this.YMin = double.NaN;
|
|
|
|
|
//this.YMax = double.NaN;
|
|
|
|
|
//this.XMin = Math.Min(x1, x2);
|
|
|
|
|
//this.YMin = Math.Min(y1, y2);
|
|
|
|
|
//this.XMax = Math.Max(x1, x2);
|
|
|
|
|
//this.YMax = Math.Max(y1, y2);
|
|
|
|
|
this.XMin = double.NaN;
|
|
|
|
|
this.XMax = double.NaN;
|
|
|
|
|
this.YMin = double.NaN;
|
|
|
|
|
this.YMax = double.NaN;
|
|
|
|
|
this.XMin = Math.Min(x1, x2);
|
|
|
|
|
this.YMin = Math.Min(y1, y2);
|
|
|
|
|
this.XMax = Math.Max(x1, x2);
|
|
|
|
|
this.YMax = Math.Max(y1, y2);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Envelope Intersection(Envelope extent)
|
|
|
|
|
{
|
|
|
|
|
if (!this.Intersects(extent))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
//return new Envelope(Math.Max(this.XMin, extent.XMin), Math.Max(this.YMin, extent.YMin), Math.Min(this.XMax, extent.XMax), Math.Min(this.YMax, extent.YMax));
|
|
|
|
|
return new Envelope(Math.Max(this.XMin, extent.XMin), Math.Max(this.YMin, extent.YMin), Math.Min(this.XMax, extent.XMax), Math.Min(this.YMax, extent.YMax));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Intersects(Envelope other)
|
|
|
|
|
{
|
|
|
|
|
if (other == null)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return ((((other.XMin <= this.XMax) && (other.XMax >= this.XMin)) && (other.YMin <= this.YMax)) && (other.YMax >= this.YMin));
|
|
|
|
|
|
|
|
|
|
//return ((((other.XMin <= this.XMax) && (other.XMax >= this.XMax)) && (other.YMin <= this.YMin)) && (other.YMax >= this.YMax));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool Within(Envelope other)
|
|
|
|
|
{
|
|
|
|
|
return ((((this.XMin >= other.XMin) && (this.XMax <= other.XMax)) && (this.YMin >= other.YMin)) && (this.YMax <= other.YMax));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Envelope Union(Envelope extent)
|
|
|
|
|
{
|
|
|
|
|
Envelope envelope = new Envelope();
|
|
|
|
|
if (extent == null)
|
|
|
|
|
{
|
|
|
|
|
extent = this;
|
|
|
|
|
}
|
|
|
|
|
if (double.IsNaN(this.XMin))
|
|
|
|
|
{
|
|
|
|
|
envelope.XMin = extent.XMin;
|
|
|
|
|
}
|
|
|
|
|
else if (double.IsNaN(extent.XMin))
|
|
|
|
|
{
|
|
|
|
|
envelope.XMin = this.XMin;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
envelope.XMin = Math.Min(extent.XMin, this.XMin);
|
|
|
|
|
}
|
|
|
|
|
if (double.IsNaN(this.XMax))
|
|
|
|
|
{
|
|
|
|
|
envelope.XMax = extent.XMax;
|
|
|
|
|
}
|
|
|
|
|
else if (double.IsNaN(extent.XMax))
|
|
|
|
|
{
|
|
|
|
|
envelope.XMax = this.XMax;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
envelope.XMax = Math.Max(extent.XMax, this.XMax);
|
|
|
|
|
}
|
|
|
|
|
if (double.IsNaN(this.YMin))
|
|
|
|
|
{
|
|
|
|
|
envelope.YMin = extent.YMin;
|
|
|
|
|
}
|
|
|
|
|
else if (double.IsNaN(extent.YMin))
|
|
|
|
|
{
|
|
|
|
|
envelope.YMin = this.YMin;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
envelope.YMin = Math.Min(extent.YMin, this.YMin);
|
|
|
|
|
}
|
|
|
|
|
if (double.IsNaN(this.YMax))
|
|
|
|
|
{
|
|
|
|
|
envelope.YMax = extent.YMax;
|
|
|
|
|
return envelope;
|
|
|
|
|
}
|
|
|
|
|
if (double.IsNaN(extent.YMax))
|
|
|
|
|
{
|
|
|
|
|
envelope.YMax = this.YMax;
|
|
|
|
|
return envelope;
|
|
|
|
|
}
|
|
|
|
|
envelope.YMax = Math.Max(extent.YMax, this.YMax);
|
|
|
|
|
return envelope;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|