using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace gmap_tool
{
public partial class gmaptoolMainForm : Form
{
public gmaptoolMainForm()
{
InitializeComponent();
}//
// /**
// * 取GE image url
// * @param int intZoom 倍数
// * @param double douLongitudeX 经度
// * @param double douLatitudeY 纬度
// */
// public static String getImageURL(int intZoom, double douLongitudeX, double douLatitudeY)
//{
// StringBuffer sbURL = new StringBuffer();
// StringBuffer sbT = new StringBuffer("t");
// int intX = 0;
// int intY = 0;
// int intWidthX = 180;
// int intHeigthY = 180;
// for (int i = 1; i < intZoom; i++)
// {
// if (douLongitudeX >= intX && douLatitudeY >= intY) //右上位置
// {
// sbT.append("r");
// //设置下一层坐标点位置
// intX = intX + intWidthX / 2;
// intY = intY + intHeigthY / 2;
// }
// else if (douLongitudeX >= intX && douLatitudeY < intY) //右下位置
// {
// sbT.append("s");
// intX = intX + intWidthX / 2;
// intY = intY - intHeigthY / 2;
// }
// else if (douLongitudeX < intX && douLatitudeY < intY) //左下位置
// {
// sbT.append("t");
// intX = intX - intWidthX / 2;
// intY = intY - intHeigthY / 2;
// }
// else //左上位置
// {
// sbT.append("q");
// intX = intX - intWidthX / 2;
// intY = intY + intHeigthY / 2;
// }
// intWidthX = intWidthX / 2;
// intHeigthY = intHeigthY / 2;
// }
// sbURL.append("http://kh.google.com/kh?v=3&t=";).append(sbT);
// return sbURL.toString();
//}
/**
* 取GE image url
* @param int intZoom 倍数
* @param double douLongitudeX 经度
* @param double douLatitudeY 纬度
*/
public static String getImageURL(int intZoom, double douLongitudeX, double douLatitudeY)
{
StringBuilder sbURL = new StringBuilder();
StringBuilder sbT = new StringBuilder("t");
int intX = 0;
int intY = 0;
int intWidthX = 180;
int intHeigthY = 180;
for (int i = 1; i < intZoom; i++)
{
if (douLongitudeX >= intX && douLatitudeY >= intY) //右上位置
{
sbT.Append("r");
//设置下一层坐标点位置
intX = intX + intWidthX / 2;
intY = intY + intHeigthY / 2;
}
else if (douLongitudeX >= intX && douLatitudeY < intY) //右下位置
{
sbT.Append("s");
intX = intX + intWidthX / 2;
intY = intY - intHeigthY / 2;
}
else if (douLongitudeX < intX && douLatitudeY < intY) //左下位置
{
sbT.Append("t");
intX = intX - intWidthX / 2;
intY = intY - intHeigthY / 2;
}
else //左上位置
{
sbT.Append("q");
intX = intX - intWidthX / 2;
intY = intY + intHeigthY / 2;
}
intWidthX = intWidthX / 2;
intHeigthY = intHeigthY / 2;
}
//sbURL.Append("http://kh.google.com/kh?v=3&t=";).Append(sbT);
sbURL.Append("http://kh.google.com/kh?v=3&t=").Append(sbT);
//sbURL.Append("http://kh.google.com/kh?v=3&t=";);
//sbURL.Append(sbT);
return sbURL.ToString();
}//
/**<summary>此函数取得相应纬度对应的瓦片纵轴序号,参数为纬度</summary>*/
static private int getMercatorLatitude(double lati, int zoom)
{
double maxlat = Math.PI;
double lat = lati;
if (lat > 90) lat = lat - 180;
if (lat < -90) lat = lat + 180;
// conversion degre=>radians
// 转换度数到弧度
double phi = Math.PI * lat / 180;
double res;
//网上其他帖子这个地方有问题,应该为加号
//double temp = Math.Tan(Math.PI / 4 phi / 2);
//res = Math.Log(temp);
//下面这一句是上面的合并
res = 0.5 * Math.Log((1 + Math.Sin(phi)) / (1 - Math.Sin(phi)));
double maxTileY = Math.Pow(2, zoom);
int result = (int)(((1 - res / maxlat) / 2) * (maxTileY));
return (result);
}
static double get1(double lat, int intZoom)
{
//my = math.log(math.tan((90 + lat) * pi_val / 360.0)) / (pi_val / 180.0)
//my = my * origin_shift / 180.0
double pi_val = Math.PI;
double my = Math.Log(Math.Tan((90 + lat) * pi_val / 360.0)) / (pi_val / 180.0);
//my = my * origin_shift / 180.0
int count = (int)Math.Pow(2, intZoom);
my = my * count / 180.0;
return my;
}
//墨卡托投影
//百度地图和Google Maps使用的投影方法都是墨卡托投影。
//经过墨卡托投影后的经线是均匀分布,在此主要介绍纬度的变换方法。
//墨卡托投影把纬度为Φ (-90°<Φ<90°)的点投影到
//y = ln(tan(45° + Φ/2))
//这种投影算法使得赤道附近的纬线较密,极地附近的纬线较稀。极点被投影到无穷远,所以这种投影不适合在高纬度地区使用。Google Maps的选取的范围为 -π<y<π ,这样近似的有 -85°<Φ<85°
//以上知识即可实现编程转换。
static double get2(double lat, int intZoom)
{
double y = Math.Log(Math.Tan(45 + lat/2));
return y;
}
//原有的方法已经失效了
public static String getImageURL_new(int intZoom, double douLongitudeX, double douLatitudeY)
{
StringBuilder sbURL = new StringBuilder();
StringBuilder sbT = new StringBuilder("t");
//double m = Math.Pow(y, x);
//Console.WriteLine(y + "的" + x + "的次方是" + m);
int count = (int)Math.Pow(2, 0);
count = (int)Math.Pow(2, intZoom);
//count 是按次方将地球的经纬分成了多少块
double lon_one = (double)(360) / count;//当前 zoom 下一块地图占多少经度
double lat_one = (double)180 / count;//当前 zoom 下一块地图占多少纬度
//--------------------------------------------------
//起始经纬度是不对的,要重新计算
douLongitudeX = douLongitudeX + 180;
// douLatitudeY = 90 - douLatitudeY;//不对纬度的百分比不是这样算的,高纬度占的距离要大得多
//墨卡托投影。由于在显示时使用了墨卡托投影,因此上述的算法需要进行修改。在墨卡托投影中,两条纬线间的距离不一定相等,所以描述tile的角度依据它的垂直位置。
//--------------------------------------------------
int x = (int)(douLongitudeX / lon_one);//当前地图分块索引
int y = (int)(douLatitudeY / lat_one);//当前地图分块索引
y = (int)Math.Ceiling(get2(douLatitudeY, intZoom));
y = getMercatorLatitude(douLatitudeY, intZoom);
// y = (int)Math.Ceiling(get1(douLatitudeY, intZoom));
//x = (int)(douLongitudeX * count / 360);//当前地图分块索引
//y = (int)(douLatitudeY / lat_one);//当前地图分块索引
int intX = 0;
int intY = 0;
int intWidthX = 180;
int intHeigthY = 180;
for (int i = 1; i < intZoom; i++)
{
if (douLongitudeX >= intX && douLatitudeY >= intY) //右上位置
{
sbT.Append("r");
//设置下一层坐标点位置
intX = intX + intWidthX / 2;
intY = intY + intHeigthY / 2;
}
else if (douLongitudeX >= intX && douLatitudeY < intY) //右下位置
{
sbT.Append("s");
intX = intX + intWidthX / 2;
intY = intY - intHeigthY / 2;
}
else if (douLongitudeX < intX && douLatitudeY < intY) //左下位置
{
sbT.Append("t");
intX = intX - intWidthX / 2;
intY = intY - intHeigthY / 2;
}
else //左上位置
{
sbT.Append("q");
intX = intX - intWidthX / 2;
intY = intY + intHeigthY / 2;
}
intWidthX = intWidthX / 2;
intHeigthY = intHeigthY / 2;
}
//sbURL.Append("http://kh.google.com/kh?v=3&t=";).Append(sbT);
//sbURL.Append("http://kh.google.com/kh?v=3&t=").Append(sbT);
//sbURL.Append("http://kh.google.com/kh?v=3&t=";);
//sbURL.Append(sbT);
//http://mt0.google.cn/vt/hl=zh-CN&gl=cn&x=13127&y=7163&z=14&s=
string s = "http://mt0.google.cn/vt/lyrs=m@121&hl=zh-CN&gl=cn&x="+x+"&y="+y+"&z="+intZoom+"&s=";
return s;// sbURL.ToString();
}//
private void btnGetGMapUrl_Click(object sender, EventArgs e)
{
string url = getImageURL(15, Convert.ToDouble(txtLon.Text), Convert.ToDouble(txtLat.Text));
url = getImageURL_new(Convert.ToInt32(txtZoom.Text), Convert.ToDouble(txtLon.Text), Convert.ToDouble(txtLat.Text));
txtGMapUrl.Text = url;
webBrowser_GMapUrl.Navigate(url);
}
private void btnGo_Click(object sender, EventArgs e)
{
webBrowser_GMapUrl.Navigate(txtGMapUrl.Text);
}//
}//
}//