/// <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>
        /// 开始下载
        /// </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 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);  //开启下载线程
                }
            }
        }