实例介绍
【实例简介】
【实例截图】

【核心代码】
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using System.Net;
namespace GoogleMapDownLoader
{
public partial class Form1 : Form
{
ArrayList _waittodownload = new ArrayList(); //待下载图片集合
string _path=""; //保存路径
int _thread = 0; //下载线程数目
int _downloadnum = 0; //已下载图片张数
int _zoom=0; //缩放级别
int _totalwidth = 0; //地图合并之后的宽度
int _totalheight = 0; //地图合并之后的高度
DateTime _startTime = DateTime.Now; //开始下载时间
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 浏览保存目录
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
using (FolderBrowserDialog fb = new FolderBrowserDialog())
{
if (fb.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
txtPath.Text = fb.SelectedPath;
}
}
}
/// <summary>
/// 开始下载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
double flng=0; //左上经度
double flat=0; //左上纬度
double slng=0; //右下经度
double slat=0; //右下纬度
int zomm=0; //缩放级别
int thread=4; //下载线程数目
try
{
_path = txtPath.Text;
if (_path == "")
{
throw new Exception();
}
zomm = (int)numZoom.Value;
thread = (int)numThread.Value;
flng = double.Parse(txtfirstlng.Text);
flat = double.Parse(txtfirstlat.Text);
slng = double.Parse(txtsecondlng.Text);
slat = double.Parse(txtsecondlat.Text);
}
catch
{
MessageBox.Show("参数设置异常!");
}
Point p = LatLongToPixel(flat, flng, zomm); //将第一个点经纬度转换成平面2D坐标
Point p2 = LatLongToPixel(slat, slng, zomm); //将第二个点经纬度转换成平面2D坐标
int startX = p.X / 256; //起始列
int endX = p2.X / 256; //结束列
if (endX == Math.Pow(2, zomm)) //结束列超出范围
{
endX--;
}
int startY = p.Y / 256; //起始行
int endY = p2.Y / 256; //结束行
if (endY == Math.Pow(2, zomm)) //结束行超出范围
{
endY--;
}
//以上由startX endX startY endY 围成的区域 即为待下载区域 该区域由许多256*256大小方块组成
_totalwidth = (endX - startX 1) * 256; //合并图的宽度
_totalheight = (endY - startY 1) * 256; //合并图的高度
int serverId = 0;
int threadId = 0;
_waittodownload.Clear();
for (int y = startY; y <= endY; y )
{
for (int x = startX; x <= endX; x )
{
RectInfo ri = new RectInfo();
ri.serverId = serverId; //分别从不同的服务器下载
ri.threadId = threadId; //分别由不同的线程下载
ri.url = BuildURL(serverId);
ri.x = x;
ri.y = y;
ri.z = zomm;
ri.bComplete = false;
_waittodownload.Add(ri); //将每个小方块放入待下载集合
serverId = (serverId 1) % 4; //从4个不同的服务器上下载图片
threadId = (threadId 1) % thread; //由thread个不同线程下载图片
}
}
if (MessageBox.Show("共有" _waittodownload.Count "张图片需要下载,确定下载吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK)
{
_thread = thread;
_zoom = zomm;
_downloadnum = 0;
groupBox1.Enabled = false;
button2.Enabled = false;
linkLabel1.Enabled = false;
rchOuput.Clear();
groupBox2.Text = "输出(" _waittodownload.Count "张)";
_startTime = DateTime.Now;
for (int i = 1; i <= thread; i)
{
Thread t = new Thread(new ParameterizedThreadStart(DownloadThreadProc));
t.Start(i); //开启下载线程
}
}
}
/// <summary>
/// 浏览地图
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if (_downloadnum == _waittodownload.Count && _downloadnum != 0) //全部下载完毕
{
Bitmap b = new Bitmap(_totalwidth, _totalheight);
Graphics g = Graphics.FromImage(b);
int startx = ((RectInfo)(_waittodownload[0])).x;
int starty = ((RectInfo)(_waittodownload[0])).y;
foreach (RectInfo rf in _waittodownload)
{
g.DrawImage(rf.Bitmap, new Point((rf.x - startx) * 256, (rf.y - starty) * 256));
}
g.Dispose();
b.Save(_path "\\" _zoom "_total.jpg");
b.Dispose();
System.Diagnostics.Process.Start(_path "\\" _zoom "_total.jpg");
}
}
#region help methods
/// <summary>
/// 根据服务器id创建地图下载url的前缀
/// </summary>
/// <param name="serverId"></param>
/// <returns></returns>
private string BuildURL(int serverId)
{
if (radioButton7.Checked) //国外服务器 类似 http://mts0.googleapis.com/vt?lyrs=m&x=0&y=0&z=0
{
string url = "";
url = "http://mts";
url = serverId.ToString();
url = ".googleapis.com/vt?lyrs=";
if (radioButton1.Checked) //路线图
{
url = "m";
}
if (radioButton2.Checked) //卫星图
{
url = "s";
}
if (radioButton3.Checked) //卫星图 带标签
{
url = "y";
}
if (radioButton4.Checked) //地形图
{
url = "t";
}
if (radioButton5.Checked) //地形图 带标签
{
url = "p";
}
return url;
}
if (radioButton6.Checked) //国内服务器 类似 http://mt0.google.cn/vt/lyrs=m@234000000&hl=zh-CN&gl=CN&src=app&x=0&y=0&z=0
{
string url = "";
url = "http://mt";
url = serverId.ToString();
url = ".google.cn/vt/lyrs=";
if (radioButton1.Checked) //路线图
{
url = "m";
}
if (radioButton2.Checked) //卫星图
{
url = "s";
}
if (radioButton3.Checked) //卫星图 带标签
{
url = "y";
}
if (radioButton4.Checked) //地形图
{
url = "t";
}
if (radioButton5.Checked) //地形图 带标签
{
url = "p";
}
url = "@234000000&hl=zh-CN&gl=CN&src=app";
return url;
}
return "";
}
/// <summary>
/// 根据url下载地图
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private Bitmap DownloadImage(string url)
{
Bitmap bitmap = null;
Stream stream = DownloadResource(url);
if (stream != null)
{
bitmap = new Bitmap(stream);
}
return bitmap;
}
/// <summary>
/// 利用webclient 根据url下载web资源
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public Stream DownloadResource(string url)
{
MemoryStream stream = null;
try
{
WebClient client = new WebClient();
client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
byte[] data = client.DownloadData(url);
stream = new MemoryStream(data);
client.Dispose();
}
catch (WebException e)
{
}
return stream;
}
/// <summary>
/// 下载线程方法
/// </summary>
/// <param name="param"></param>
public void DownloadThreadProc(object param)
{
int threadId = (int)param; //当前线程Id
this.Invoke((Action)delegate() //输出
{
rchOuput.SelectionColor = Color.Blue;
rchOuput.AppendText(DateTime.Now.ToLongTimeString() " 第" threadId "号线程开始执行\r\n");
});
for (int i = 0; i < _waittodownload.Count; i )
{
RectInfo ri = (RectInfo)_waittodownload[i];
if ((!ri.bComplete) &&(ri.threadId 1 == threadId))
{
try
{
string url = ri.url;
//根据每个图片的行、列、缩放级别 完善url
url = "&x=" ri.x.ToString().Trim(); //列
url = "&y=" ri.y.ToString().Trim(); //行
url = "&z=" ri.z.ToString().Trim(); //缩放级别
Bitmap map = DownloadImage(url);
string file = _path "\\" ri.z.ToString() "_" ri.x.ToString() "_" ri.y.ToString() ".jpg";
ri.Bitmap = map;
//文件保存格式 “缩放级别_列_行.jpg”
map.Save(file, System.Drawing.Imaging.ImageFormat.Jpeg);
this.Invoke((Action)delegate() //输出
{
rchOuput.SelectionColor = Color.Green;
rchOuput.AppendText(DateTime.Now.ToLongTimeString() " 第" threadId "号线程下载图片" ri.z.ToString() "_" ri.x.ToString() "_" ri.y.ToString() ".jpg\r\n");
});
_downloadnum ;
ri.bComplete = true;
}
catch
{
this.Invoke((Action)delegate() //输出
{
rchOuput.SelectionColor = Color.Red;
rchOuput.AppendText(DateTime.Now.ToLongTimeString() " 第" threadId "号线程下载图片" ri.z.ToString() "_" ri.x.ToString() "_" ri.y.ToString() ".jpg失败!\r\n");
});
}
}
}
this.Invoke((Action)delegate() //输出
{
rchOuput.SelectionColor = Color.Blue;
rchOuput.AppendText(DateTime.Now.ToLongTimeString() " 第" threadId "号线程执行完毕\r\n" );
});
_thread--; //工作线程数目减一
if (_thread == 0) //所有线程均结束
{
this.Invoke((Action)delegate() //输出
{
rchOuput.SelectionColor = Color.Blue;
rchOuput.AppendText(DateTime.Now.ToLongTimeString() " 图片下载结束!共下载" _downloadnum "张,共耗时" (DateTime.Now-_startTime).TotalSeconds "秒");
groupBox1.Enabled = true;
button2.Enabled = true;
linkLabel1.Enabled = true;
});
}
}
/// <summary>
/// 根据缩放级别zoom 将经纬度坐标系统中的某个点 转换成平面2D图中的点(原点在屏幕左上角)
/// </summary>
/// <param name="latitude"></param>
/// <param name="longitude"></param>
/// <param name="zoom"></param>
/// <returns></returns>
public Point LatLongToPixel(double latitude, double longitude, double zoom)
{
Point point = new Point();
double centerPoint = Math.Pow(2, zoom 7);
double totalPixels = 2 * centerPoint;
double pixelsPerLngDegree = totalPixels / 360;
double pixelsPerLngRadian = totalPixels / (2 * Math.PI);
double siny = Math.Min(Math.Max(Math.Sin(latitude * (Math.PI / 180)), -0.9999), 0.9999);
point = new Point((int)Math.Round(centerPoint longitude * pixelsPerLngDegree), (int)Math.Round(centerPoint - 0.5 * Math.Log((1 siny) / (1 - siny)) * pixelsPerLngRadian));
return point;
}
#endregion
}
/// <summary>
/// 地图中每个256*256尺寸的方块
/// </summary>
public class RectInfo
{
public int serverId; //目标服务器
public int threadId; //目标下载线程
public string url; //下载url
public int x; //列
public int y; //行
public int z; //缩放级别
public bool bComplete; //是否完成
public Bitmap Bitmap; //图片
}
}
好例子网口号:伸出你的我的手 — 分享!
相关软件
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


支持(0) 盖楼(回复)