谷歌瓦片地圖糾偏

来源:https://www.cnblogs.com/s0611163/archive/2018/08/17/9491785.html
-Advertisement-
Play Games

對谷歌瓦片地圖進行糾偏,有兩種方法:一是對拼接大圖進行糾偏,然後重新切片;二是直接對瓦片圖進行糾偏。這裡我用的是第二種方法,即直接對瓦片地圖進行糾偏。 App.config配置: <appSettings> <add key="inputPath" value="D:\_臨時文件\GISMap\18 ...


    對谷歌瓦片地圖進行糾偏,有兩種方法:一是對拼接大圖進行糾偏,然後重新切片;二是直接對瓦片圖進行糾偏。這裡我用的是第二種方法,即直接對瓦片地圖進行糾偏。

App.config配置:

<appSettings>
  <add key="inputPath" value="D:\_臨時文件\GISMap\1818940751"/>
  <add key="outputPath" value="D:\_臨時文件\GISMapOutput\1818940751"/>
  <add key="deltaPixcelX" value="1031"/>
  <add key="deltaPixcelY" value="421"/>
  <add key="fromMapZoom" value="1"/>
  <add key="toMapZoom" value="18"/>
</appSettings>
View Code

對瓦片圖進行糾偏處理的演算法代碼:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Utils;

namespace TileProcess
{
    public partial class Form1 : Form
    {
        private int _count = 0;
        private int _deltaPixcelX;
        private int _deltaPixcelY;
        private string _inputPath;
        private string _outputPath;
        private int _fromMapZoom;
        private int _toMapZoom;

        private DateTime _startTime;
        private int _lastCount;

        public Form1()
        {
            InitializeComponent();

            _deltaPixcelX = Convert.ToInt32(ConfigurationManager.AppSettings["deltaPixcelX"]);
            _deltaPixcelY = Convert.ToInt32(ConfigurationManager.AppSettings["deltaPixcelY"]);
            _inputPath = ConfigurationManager.AppSettings["inputPath"];
            _outputPath = ConfigurationManager.AppSettings["outputPath"];
            _fromMapZoom = Convert.ToInt32(ConfigurationManager.AppSettings["fromMapZoom"]);
            _toMapZoom = Convert.ToInt32(ConfigurationManager.AppSettings["toMapZoom"]);
        }

        private void btnTileProcess_Click(object sender, EventArgs e)
        {
            this.btnTileProcess.Enabled = false;

            Task.Factory.StartNew(() =>
            {
                LogUtil.Log("開始處理");
                Process();
            });

            Thread thread = new Thread(new ThreadStart(() =>
            {
                int sleepInterval = 1000;
                while (true)
                {
                    Thread.Sleep(sleepInterval);
                    this.BeginInvoke(new Action(() =>
                    {
                        double totalSeconds = DateTime.Now.Subtract(_startTime).TotalSeconds;
                        int avg = (int)(_count / totalSeconds);
                        lblMsg.Text = string.Format("已處理 {0} 張瓦片圖", _count);
                        if (_count - _lastCount > 0)
                        {
                            lblSpeed.Text = string.Format("當前速度:{0} 張/每秒,平均速度:{1} 張/每秒", (_count - _lastCount) * 1000.0 / sleepInterval, avg);
                        }
                        _lastCount = _count;
                    }));
                }
            }));
            thread.IsBackground = true;
            thread.Start();
        }

        /// <summary>
        /// 瓦片糾偏處理
        /// </summary>
        private void Process()
        {
            _startTime = DateTime.Now;
            Regex regex = new Regex(@"\\(\d+)\\(\d+).png", RegexOptions.IgnoreCase);
            for (int i = _fromMapZoom; i <= _toMapZoom; i++)
            {
                int deltaPixcelX = (int)Math.Round(_deltaPixcelX / Math.Round(Math.Pow(2, 18 - i)));
                int deltaPixcelY = (int)Math.Round(_deltaPixcelY / Math.Round(Math.Pow(2, 18 - i)));

                string[] fileArr = Directory.GetFiles(_inputPath + "\\" + i, "*.*", SearchOption.AllDirectories);
                foreach (string file in fileArr)
                {
                    ThreadData data = new ThreadData();
                    data.File = file;
                    data.I = i;
                    data.DeltaPixcelX = deltaPixcelX;
                    data.DeltaPixcelY = deltaPixcelY;

                    ThreadUtil.Run((obj) =>
                    {
                        ThreadData d = obj as ThreadData;

                        Match match = regex.Match(d.File);
                        if (match.Success)
                        {
                            int x = Convert.ToInt32(match.Groups[1].Value);
                            int y = Convert.ToInt32(match.Groups[2].Value);

                            string pathTarget = string.Format(string.Format(@"{0}\{1}\{2}\{3}.png", _outputPath, d.I, x, y));
                            if (!File.Exists(pathTarget))
                            {
                                if (!Directory.Exists(Path.GetDirectoryName(pathTarget)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(pathTarget));
                                }
                                Bitmap bmpNew = new Bitmap(256, 256, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                                Graphics graph = Graphics.FromImage(bmpNew);

                                int deltaX = data.DeltaPixcelX / 256;
                                int deltaY = data.DeltaPixcelY / 256;

                                //臨時變數定義
                                string pathSource = null;
                                FileStream fs = null;
                                byte[] bArr = null;
                                MemoryStream ms = null;
                                Bitmap bmpSource = null;

                                //起始
                                pathSource = string.Format(@"{0}\{1}\{2}\{3}.png", _inputPath, d.I, x + deltaX, y + deltaY);
                                if (File.Exists(pathSource))
                                {
                                    fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                    bArr = new byte[fs.Length];
                                    int readCount = fs.Read(bArr, 0, bArr.Length);
                                    ms = new MemoryStream(bArr, 0, readCount);
                                    bmpSource = new Bitmap(ms);
                                    graph.DrawImage(bmpSource, 0, 0, new RectangleF(data.DeltaPixcelX % 256, data.DeltaPixcelY % 256, 256 - data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                    graph.Flush();

                                    fs.Close();
                                    fs = null;
                                    ms.Close();
                                    ms = null;
                                    bmpSource.Dispose();
                                    bmpSource = null;
                                }

                                //
                                pathSource = string.Format(@"{0}\{1}\{2}\{3}.png", _inputPath, d.I, x + deltaX + 1, y + deltaY);
                                if (File.Exists(pathSource))
                                {
                                    fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                    bArr = new byte[fs.Length];
                                    int readCount = fs.Read(bArr, 0, bArr.Length);
                                    ms = new MemoryStream(bArr, 0, readCount);
                                    bmpSource = new Bitmap(ms);
                                    graph.DrawImage(bmpSource, 256 - data.DeltaPixcelX % 256, 0, new RectangleF(0, data.DeltaPixcelY % 256, data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                    graph.Flush();

                                    fs.Close();
                                    fs = null;
                                    ms.Close();
                                    ms = null;
                                    bmpSource.Dispose();
                                    bmpSource = null;
                                }

                                //
                                pathSource = string.Format(@"{0}\{1}\{2}\{3}.png", _inputPath, d.I, x + deltaX, y + deltaY + 1);
                                if (File.Exists(pathSource))
                                {
                                    fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                    bArr = new byte[fs.Length];
                                    int readCount = fs.Read(bArr, 0, bArr.Length);
                                    ms = new MemoryStream(bArr, 0, readCount);
                                    bmpSource = new Bitmap(ms);
                                    graph.DrawImage(bmpSource, 0, 256 - data.DeltaPixcelY % 256, new RectangleF(data.DeltaPixcelX % 256, 0, 256 - data.DeltaPixcelX % 256, data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                    graph.Flush();

                                    fs.Close();
                                    fs = null;
                                    ms.Close();
                                    ms = null;
                                    bmpSource.Dispose();
                                    bmpSource = null;
                                }

                                //右下
                                pathSource = string.Format(@"{0}\{1}\{2}\{3}.png", _inputPath, d.I, x + deltaX + 1, y + deltaY + 1);
                                if (File.Exists(pathSource))
                                {
                                    fs = new FileStream(pathSource, FileMode.Open, FileAccess.Read);
                                    bArr = new byte[fs.Length];
                                    int readCount = fs.Read(bArr, 0, bArr.Length);
                                    ms = new MemoryStream(bArr, 0, readCount);
                                    bmpSource = new Bitmap(ms);
                                    graph.DrawImage(bmpSource, 256 - data.DeltaPixcelX % 256, 256 - data.DeltaPixcelY % 256, new RectangleF(0, 0, data.DeltaPixcelX % 256, data.DeltaPixcelY % 256), GraphicsUnit.Pixel);
                                    graph.Flush();

                                    fs.Close();
                                    fs = null;
                                    ms.Close();
                                    ms = null;
                                    bmpSource.Dispose();
                                    bmpSource = null;
                                }

                                bmpNew.Save(pathTarget);
                                //bmpNew.Save("d:\\_臨時文件\\1234.png"); //測試用

                                bmpNew.Dispose();
                                bmpNew = null;
                                graph.Dispose();
                                graph = null;

                                _count++;
                            } //end if (!File.Exists(pathTarget))
                        } //end if (match.Success)
                    }, data, (ex) =>
                    {
                        this.BeginInvoke(new Action(() =>
                        {
                            lblErrorMsg.Text = "出錯:" + ex.Message + "\r\n" + ex.StackTrace;
                            LogUtil.LogError(ex, "出錯");
                        }));
                    }); //end ThreadUtil.Run
                } //end foreach (string file in fileArr)
            } //end for (int i = _fromMapZoom; i <= _toMapZoom; i++)
        }
    }
}
View Code

處理效率:我自己電腦每秒處理大約350張瓦片圖,1到18級瓦片共100多萬張圖片,大約需要處理50分鐘。

瓦片圖糾偏前後對比:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 紙殼CMS(ZKEACMS)里的Grid是一個TagHelper,是對jQuery插件datatables的一個配置封裝。 grid的使用很簡單,設置Model,使用 ...
  • @{ ViewBag.Title = "UsersList"; } @{ Html.RenderAction("SearchRole", "Shared"); } 賬號(編號或姓名): ... ...
  • 問題:考慮屏幕大小,一般都是會在表單問卷的頁面使用ScrollViewer。問卷中問題漏填漏選時,在提交時校驗不過,需要滾動跳轉至漏填漏選項。 頁面如下: 每個選項使用StackPanel,並對覆選框和單選的勾選事件進行答案記錄,使用全局變數記錄 將所有選項使用StackPanel指定垂直樣式,思路 ...
  • 索引 NET Core應用框架之BitAdminCore框架應用篇系列 框架演示:https://www.bitadmincore.com 框架源碼:https://github.com/chenyinxin/cookiecutter-bitadmin-core 什麼是.NET Core Globa ...
  • 最近我跟一個漏洞還有一群阿三幹起來了…… 背景: 我的客戶是一個世界知名的藥企,最近這個客戶上臺了一位阿三管理者,這個貨上線第一個事兒就是要把現有的軟體供應商重新洗牌一遍。由於我們的客戶關係維護的非常好,直接對口人提前透露給我們這個管理者就是想讓一個阿三公司壟斷他們的軟體供應,並且表示了非常鄙視。我 ...
  • 索引 NET Core應用框架之BitAdminCore框架應用篇系列 框架演示:http://bit.bitdao.cn 框架源碼:https://github.com/chenyinxin/cookiecutter-bitadmin-core 20180817更新內容 1、考慮到大部分項目不需要 ...
  • 本節對委托、事件做以總結。 一、委托: 1、概念:先來說明變數和函數的概念,變數,以某個地址為起點的一段記憶體中所存儲的值,函數,以某個地址為起點的一段記憶體中存儲的機器語言指令。有了這2個概念以後,我們來看c++中的函數指針,函數指針就是指向這個函數的地址,函數指針所指向的類型就是函數在記憶體中的大小, ...
  • 通過以下步驟,可以簡單瞭解到如何下載我們Smobiler Designer(設計器)、Client(客戶端),以及如何通過設計器進行開發和調試移動應用,併在服務端部署、Cloud打包、訪問自己所開發的移動應用。 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...