对互连网中不以为奇地图的坐标系斟酌,Google瓦片地图纠正偏差或偏侧

图片 13

对互连网中不以为奇地图的坐标系斟酌,Google瓦片地图纠正偏差或偏侧

   
对Google瓦片地图举办校正,有三种方法:一是对拼接大图举行改良,然后再一次切丝;二是直接对瓦片图举行矫正。这里笔者用的是第三种形式,即直接对瓦片地图实行校正。

作品版权由小编李晓晖和乐乎共有,若转发请于明显处标记出处:。

App.config配置:

1.背景

脚下项目中接受百度地图、高德地图、谷歌(Google卡塔 尔(英语:State of Qatar)中中原人民共和国地图、天地图的须要更是多,这里笔者跟我们一块儿对外市图使用的坐标系做一个回顾的探求。

图片 1图片 2

2.百度地形图——BD-09

百度地图是在GCJ-02坐标系上,又和好对坐标加密了壹次,它官方文书档案里说叫BD-09,最近从GPS坐标转到百度坐标有接口提供,反过来不提供。

当然,最近反转方法在大家实在项目中曾经缓慢解决,准确度能够达标0.5M以内。

<appSettings>
  <add key="inputPath" value="D:_临时文件GISMap1818940751"/>
  <add key="outputPath" value="D:_临时文件GISMapOutput1818940751"/>
  <add key="deltaPixcelX" value="1031"/>
  <add key="deltaPixcelY" value="421"/>
  <add key="fromMapZoom" value="1"/>
  <add key="toMapZoom" value="18"/>
</appSettings>

2.1百度瓦片获取思路

百度地图的黑影依然专门的学问的Web横轴墨卡托投影,所以其切图的坐标原点、范围都是足以总结出来的。瓦片大小、基本USportageL也都得以通过监听百度的U冠道L获取。要求注意的是,百度地图的瓦片行列号和负载地址在分歧品级上都会迥然差别,其转移准则如下:

瓦片的行列号是每增添一个级别便会实行叁个平整的撼动,其偏移算法如下:

     图片 3                      
                     

View Code

2.2地点坐标系图层与百度底图叠合的探幽索隐

对瓦片图进行更正管理的算法代码:

2.2.1 强行对瓦片数据开展改过

在风行的arcBruTile0.7中早就支撑对百度地图的丰裕。能够加载了百度瓦片后,通过搜寻百度地图上与本地地图上的调整点对举行强行修正。

症结是栅格图像纠正偏差或趋向形变是很难制止的,并且工作量也大,並且很难自动化。

图片 4图片 5

2.2.2 将矢量数据调换为百度坐标系——以路易港90坐标系为例

a.获取WGS84到圣萨尔瓦多90坐标系上的7参数。

b.通过确立调节点库(已研发卡塔 尔(阿拉伯语:قطر‎,利用工具(已研究开发卡塔尔国将天津90坐标周全据自动转变为WGS84坐标周到据。

c.更创立WGS84与百度坐标系之间的主宰点库(已研究开发卡塔 尔(英语:State of Qatar),将WGS84数据再更改为百度坐标周密据。

d.叠合后测量试验。

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 + "rn" + ex.StackTrace;
                            LogUtil.LogError(ex, "出错");
                        }));
                    }); //end ThreadUtil.Run
                } //end foreach (string file in fileArr)
            } //end for (int i = _fromMapZoom; i <= _toMapZoom; i++)
        }
    }
}

2.2.3结实展现

                                            图片 6

图片 7

 

View Code

3.高德地图和谷歌(Google卡塔 尔(阿拉伯语:قطر‎中国地形图——GCJ-02

拍卖功能:我自个儿Computer每秒管理大致350张瓦片图,1到18级瓦片共100多万张图片,差不离须求管理50秒钟。

3.1地图坐标系的探赜索隐

高德地图和谷歌(Google卡塔尔地图均是选取的GCJ-02坐标系,以下为测量检验例子:

 图片 8

具体来讲GCJ-02坐标系与WGS84坐标系偏移一般在100M上下,这种管理技能,是透过风流倜傥种艺术将一张地图改正为其它一张地图,改正形成今后,地图上的点,会生出大到几百米,小到几十米的挥动。假诺您用几何上坐标转变的诀要想重理旧业原地图,难度非常的大,因为管理技术的管理映射函数是非线性的。英特网有大多八个坐标之间的转变方法,但是正确度平时般,在10M左右。

在国内,GCJ-02带给的摆荡最大有700米左右,偏移的绝对值能够参考下图(最红处形似700
m,最蓝处大致 20 米卡塔尔:

 图片 9

瓦片图纠正偏差或趋向前后比较:

3.2地面坐标周全据叠合到GCJ-02坐标系上

图片 10

3.2.1转移流程

出于地点数据并不会是大规模的,所以其有个别偏移上得以由此线性方法一时半刻围拢。

a.本地坐标数据调换为WGS84坐标数据。

b.对该地WGS84坐标数据进行Web横轴墨卡托投影。

c.将投歌后的数码叠合到高德只怕Google中华夏族民共和国地形图上。

d.实行线性偏移。

 

3.2.2结果展现

 图片 11

4.天地图——CGCS2000

4.1坐标系商量

天地图上不一致省份使用的坐标系或许不一样,前段时间来看本人经手过的四川、湖南均为正式的国标贰零零叁坐标系。不过有些地点为地方坐标系,还需测绘局提供保密插件进行处理。

国家规范二〇〇四坐标系与WGS84坐标系偏差相当小,因为CGCS2004坐标系与WGS84坐标系的原点、尺度、定向及定向演变的概念都以相仿的,参谋椭球的参数略有分裂而已。相近的坐标点,在CGCS二〇〇〇与WGS84下,经度是同样的,只在纬度上存有0.11mm上下的分别,能够忽视掉。

4.2 本地坐标系矢量数据叠合到天地图上

a.将地点数据调换为WGS84要么国家规范2004坐标周到据。

b.叠合到天地图上。

4.3结果显示

 图片 12

                                                                
 —–招待转发,但保留版权,请于分明处注脚出处:

                                                                     
若是您认为本文确实扶持了你,能够Wechat扫一扫,进行小额的打赏和鞭挞,感激^_^

                                      图片 13

 

admin

网站地图xml地图