实例介绍
【实例简介】
【实例截图】
【核心代码】
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) 盖楼(回复)