主要的海图调用过程和思路上一篇文章已经介绍
本文将介绍下该Demo中的一些函数和数值模式(源码比较乱,前后几种方式实现都在一起,仅供参考)
工程介绍:VS2013,C#实现,其中用到projNet库
1、通过程序运行的前后来介绍:
Form1_Load(初始化加载)
private void Form1_Load(object sender, EventArgs e)
{
//将窗口置顶并始终显示在右下角
SetWindowPos(this.Handle, -1, 0, 0, 0, 0, 1 | 2);
win_X = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Width - this.Width;
win_Y = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Size.Height - this.Height;
this.SetDesktopLocation(win_X, win_Y);
//设置界面
this.MinimizeBox = false;
// this.OnFormClosed = false;
this.MaximizeBox = true;
//设置加载皮肤
path = System.Environment.CurrentDirectory + "\\UAVShowWindow\\";
skin.SkinFile = path + "SportsBlack.ssk";
skin.Active = true;
//
image_file = System.Environment.CurrentDirectory +"\\"+ "20.PNG";
image_1 = Image.FromFile(image_file);
// Image
p_label_map = 0;
}
海图层级变化
public void ScaleLevel_ValueChanged(object sender, EventArgs e)//EventArgs e
{
//鼠标放大缩小地图
p_CenterX = p_LUpointX + 0.5 * (p_RUpointX - p_LUpointX);
p_CenterY = p_LDpointY + 0.5 * (p_LUpointY - p_LDpointY);
//m_Cpoint = Tran_TW.WorldToTilePos(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
//鼠标放大缩小地图
double l_x = (double)p_picMou_x;
double l_y = (double)p_picMou_y;
p_CenterX = p_LUpointX + (l_x / pictureBox1.Width) * (p_RUpointX - p_LUpointX);
p_CenterY = p_LUpointY - (l_y / pictureBox1.Height) * (p_LUpointY - p_LDpointY);
//m_Cpoint = Tran_TW.WorldToTilePos(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
Vector2D m_point = new Vector2D(0, 0);
m_point = TransformTileWorld.CalculationNum(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
m_Cpoint.X = (float)m_point.X;
m_Cpoint.Y = (float)m_point.Y;
// p_TileIndex = TransformTileWorld.calculateTileIndex(p_CenterX, p_CenterY, (int)ScaleLevel.Value);
if (MapConfig != null)
{
int level = (int)ScaleLevel.Value;
MapConfig.DefaultLevel = level;
CreatCacheDir();
//DoMethod("ReloadMap");
//DoMethod("ReadLoadMap");
DoMethod("ReadWMSMap2");
}
p_label_map = 1;
}
海图加载变换函数ReadWMSMap2
1)记录海图瓦片坐标及显示位置
2)CoordRange(I_x, I_y, i, j); //记录图像范围大小
扫描二维码关注公众号,回复:
2815216 查看本文章
3)海图加载(通过海图坐标进行加载)
try
{
int row = j - startr;
//MapConfig.MapUrl = "http://localhost:9999/landsea/tile/TMS/getTile/cmap/full/{" + s_z + "}/{" + s_y + "}/{" + s_x + "}.png";
string filename = s_z + "/" + s_x + "/" + s_y + ".png";
//stream = new System.IO.MemoryStream(System.Text.Encoding.Default.GetBytes(filename));
if (!System.IO.File.Exists(filename))
{
string picurl = "http://localhost:9999/landsea/tile/TMS/getTile/cmap/full/" + filename;
req = HttpWebRequest.Create(picurl) as System.Net.HttpWebRequest;
req.AllowAutoRedirect = true;
req.KeepAlive = false;
req.Timeout = 10000;
req.ServicePoint.ConnectionLeaseTimeout = 10000;
req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
req.Headers.Add("Accept-Encoding: gzip, deflate, sdch");
req.Headers.Add("Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4");
req.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0";
using (res = req.GetResponse() as System.Net.HttpWebResponse)
{
using (stream = res.GetResponseStream())
{
image = Image.FromStream(stream);
targetgraphic = Graphics.FromImage(bitmap);
Rectangle destRect = new Rectangle((1-j) * (p_w2-2), (i) * (p_h2-1), p_w2, p_h2);
targetgraphic.DrawImage(image, destRect, new Rectangle(0,0,256,256), GraphicsUnit.Pixel);
stream.Close();
}
targetgraphic = null;
stream = null;
res.Close();
}
res = null;
}
}
4)海图缓存处理
if (this.pictureBox1.InvokeRequired)
{
UpdateUI update = delegate { pictureBox1.Image = (Bitmap)bitmap.Clone(); };
pictureBox1.Invoke(update);
}
else
{
pictureBox1.Image = (Bitmap)bitmap.Clone();
}
2、重要函数类介绍
TransformTileWorld坐标转换
WorldToTilePos和TileToWorldPos是Google转换公式,这样子转换过来显示没问题,但存在位置偏移,因为海图的坐标原点不在0,0,而是0.00 221194.08
坐标转换
//4326转3395
public static Vector2D lonLatToMercator(Vector2D lonLat)
{
Vector2D mercator = new Vector2D();
IProjectedCoordinateSystem toCS = CoordinateSystemWktReader.Parse(s3395) as IProjectedCoordinateSystem; //定义海图坐标系
// ICoordinateSystem fromCS = SridReader.GetCSbyID(4326); //定义Google坐标系
IProjectedCoordinateSystem fromCS = CoordinateSystemWktReader.Parse(geo3857) as IProjectedCoordinateSystem;
GeographicCoordinateSystem GeofromCS = (GeographicCoordinateSystem)fromCS.GeographicCoordinateSystem;
List<double[]> pts = new List<double[]>();
double[] xy = new double[] { lonLat.X, lonLat.Y };
pts.Add(xy);
List<double[]> results = new List<double[]>();
results = new List<double[]>();
try
{
CoordinateTransformationFactory ctfac = new CoordinateTransformationFactory();
ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems(GeofromCS, toCS);
results = trans.MathTransform.TransformList(pts);
//bRes = true;
mercator.X = results[0][0];
mercator.Y = results[0][1];
}
catch (SystemException sysEx)
{
}
return mercator;
}
//3395转4326,3395投影坐标转4326经纬度坐标
public static Vector2D MercatorTolonLat(Vector2D mercator)
{
Vector2D lonLat = new Vector2D();
IProjectedCoordinateSystem fromCS = CoordinateSystemWktReader.Parse(s3395) as IProjectedCoordinateSystem; //定义海图坐标系
ICoordinateSystem toCS = SridReader.GetCSbyID(4326); //定义Google坐标系
List<double[]> pts = new List<double[]>();
double[] xy = new double[] { mercator.X, mercator.Y };
pts.Add(xy);
List<double[]> results = new List<double[]>();
results = new List<double[]>();
try
{
CoordinateTransformationFactory ctfac = new CoordinateTransformationFactory();
ICoordinateTransformation trans = ctfac.CreateFromCoordinateSystems(fromCS, toCS);
results = trans.MathTransform.TransformList(pts);
//bRes = true;
lonLat.X = results[0][0];
lonLat.Y = results[0][1];
}
catch (SystemException sysEx)
{
}
return lonLat;
}
其中用到了projNet库
以下为不同坐标参数:
public static string s3395 = "PROJCS[\"WGS 84 / World Mercator\","
+ "GEOGCS[\"WGS 84\","
+ "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
+ "PROJECTION[\"Mercator_1SP\"],"
+ "PARAMETER[\"standard_parallel_1\",0],"
+ "PARAMETER[\"latitude_of_origin\",2],"
+ "PARAMETER[\"central_meridian\",0],"
+ "PARAMETER[\"scale_factor\",1],"
+ "PARAMETER[\"false_easting\",0],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],"
+ "AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH],AUTHORITY[\"EPSG\",\"3395\"]]";
public static string geo900913 = "PROJCS[\"Google Maps Global Mercator\","
+ "GEOGCS[\"WGS 84\","
+ "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,0,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
+ "PROJECTION[\"Mercator_2SP\"],"
+ "PARAMETER[\"standard_parallel_1\",0],"
+ "PARAMETER[\"latitude_of_origin\",0],"
+ "PARAMETER[\"central_meridian\",0],"
+ "PARAMETER[\"false_easting\",0],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"Meter\",1],"
+"EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs\"],AUTHORITY[\"EPSG\",\"900913\"]]";
public static string geo3857 = "PROJCS[\"WGS 84 / Pseudo-Mercator\","
+ "GEOGCS[\"WGS 84\","
+ "DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],"
+ "PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],"
+ "UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]],"
+ "PROJECTION[\"Mercator_1SP\"],"
+ "PARAMETER[\"central_meridian\",0],"
+ "PARAMETER[\"scale_factor\",1],"
+ "PARAMETER[\"false_easting\",0],"
+ "PARAMETER[\"false_northing\",0],"
+ "UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],"
+ "AXIS[\"X\",EAST],AXIS[\"Y\",NORTH],"
+ "EXTENSION[\"PROJ4\",\"+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs\"],AUTHORITY[\"EPSG\",\"3857\"]]";
内部转换函数大家可以去关注源码,上述介绍主要方便大家理解源码方便些,因为实在太乱啦!
源码位置:
http://download.csdn.net/download/u011326478/10247483