当前位置:
首页 > Python基础教程 >
-
C#教程之谷歌瓦片地图纠偏
对谷歌瓦片地图进行纠偏,有两种方法:一是对拼接大图进行纠偏,然后重新切片;二是直接对瓦片图进行纠偏。这里我用的是第二种方法,即直接对瓦片地图进行纠偏。
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>
对瓦片图进行纠偏处理的算法代码:
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++) } } }
处理效率:我自己电脑每秒处理大约350张瓦片图,1到18级瓦片共100多万张图片,大约需要处理50分钟。
瓦片图纠偏前后对比:
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式