缘由

因为各种各种wmts地图客户端产品的标准的支持不一定是一致的,就像ArcGIS不同版本加载WMTS图层的时候计算的规则就有差别(米和经纬度之间转换系数的区别),导致会出现适应各个客户端而出的WMTS服务,里面的ScaleDenominator值有细微的差别。

例如都是Google经纬度(天地图经纬度直投),其切分规则是一样的,但其DPI不一致导致计算的ScaleDenominator是不一致的。

虽然OGC标准里面对DPI大小的定义就是90.714,但是国内天地图使用的DPI标准为96,这里也有一个计算的差值。DPI不同对应的也就是每个像素的大小不一致,也就是分辨率不一致,造成瓦片的行列号计算有差异。

QGIS是支持OGC WMTS标准的,其DPI的大小就是90.714(像素大小0.00028)。为了让QGIS能够支持DPI为96的WMTS服务,需要对QGIS进行一点修改。

解决过程

为了解决这个问题,看了一下QGIS的源码,相关的定义如下:

文件qgis\src\providers\wms\qgswmscapabilities.cpp 1382行前后

      m.tileWidth    = e1.firstChildElement( QStringLiteral( "TileWidth" ) ).text().toInt();
m.tileHeight = e1.firstChildElement( QStringLiteral( "TileHeight" ) ).text().toInt();
m.matrixWidth = e1.firstChildElement( QStringLiteral( "MatrixWidth" ) ).text().toInt();
m.matrixHeight = e1.firstChildElement( QStringLiteral( "MatrixHeight" ) ).text().toInt(); // the magic number below is "standardized rendering pixel size" defined
// in WMTS (and WMS 1.3) standard, being 0.28 pixel
m.tres = m.scaleDenom * 0.00028 / metersPerUnit; QgsDebugMsg( QString( " %1: scale=%2 res=%3 tile=%4x%5 matrix=%6x%7 topLeft=%8" )
.arg( m.identifier )
.arg( m.scaleDenom ).arg( m.tres )
.arg( m.tileWidth ).arg( m.tileHeight )
.arg( m.matrixWidth ).arg( m.matrixHeight )
.arg( m.topLeft.toString() )
); s.tileMatrices.insert( m.tres, m );

这里可以看到通过ScaleDenominator计算瓦片分辨率的过程,这里使用的像素大小是0.00028

因为像素大小0.00028的计算是0.0254/DPI(这个原理网上搜就有了),所以我们可以算出DPI为96时候的像素大小为0.000264583

如果这里我们把0.00028修改为0.000264583再编译就可以支持天地图的了。这里我不打算改它,因为编译太麻烦。

这里我们直接改QGIS的二进制程序文件好了。

使用十六进制编辑器打开C:\Program Files\QGIS 3.0\apps\qgis\plugins目录下在wmsprovider.dll(最好先备份)。

然后搜索0.00028

整个文件就这一处使用了0.00028这个数值,这里直接将其修改为0.000264583保存即可。

再打开QGIS就可以按照96的DPI加载WMTS和WMS图层了。

还可以保留着两个dll文件,写一个批处理来决定加载的时候使用哪一个来运行。

ArcGIS支持DPI 96

ARCGIS中一样没有找到相关的设置,猜测也是写到代码里面了。听闻国内某些单位购买的ArcGIS是支持96的DPI的,但我们没有。

ArcGIS安装目录下找到WMSLayer.dllWMSService.dll的文件,还是一样的套路,搜索0.00028修改为0.000264583即可。

修改QGIS来支持DPI为96的WMTS/WMS服务的更多相关文章

  1. WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务

    原文:WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务 在<基于IIS的WCF服务寄宿(Hosting)实现揭秘>中,我们谈到在采用基于IIS(或者 ...

  2. django 简易博客开发 5 markdown支持、代码高亮、gravatar头像服务

    上一篇博客介绍了comments库使用及ajax支持,现在blog已经具备了基本的功能,但是只能发表文字,不支持富文本编辑.今天我们利用markdown添加富文本支持. markdown语法说明: h ...

  3. 一个尖括号能干什么,画一个笑脸开始(为了支持交互,它又增添了JavaScript。HTML页面也越来越臃肿。于是CSS便诞生了。API和核心代码的出现使HTML能够访问更复杂的软件功能--支持更高级的交互和云服务集成。这就是今天的HTML5)

    一个尖括号 < 一个尖括号能干什么 < ? 你可以编出一顶帽子 <(:-p 或一张笑脸 :-> 再或者更直接一些 20世纪90年代初,html作为一种简单标记语言面世,用于在互 ...

  4. [置顶] 新修改ADB,支持Android 4.2 系统 ,全部中文命令,手机屏幕截图等等

    发过好几个ADB的工具,有很多朋友用了之后给我反馈了不少的意见和bug,这里非常感谢他们,所以今天花了一天的时间重新整理了一下ADB,并且修改了这些BUG.也有朋友建议我给一个修改列表,今天发这个帖子 ...

  5. ok6410 u-boot-2012.04.01移植二修改源码支持单板

    继ok6410 u-boot-2012.04.01移植一后修改代码,对ok6410单板初始化,主要包括时钟.串口.NAND.DDR等初始化.这些工作在以前的裸板程序都写了,直接拿来用.我觉得先写裸板程 ...

  6. MySql 修改外键 支持级联删除

    首先必须要有外键,InnoDB甚么的都不说了,直接上修改句子. 要先删除该外键,然后添加. 具体原因貌似是因为不支持alter外键的操作. ALTER TABLE `t_terminal` DROP ...

  7. 修改GDAL库支持IRSP6数据

    使用GDAL库发现不能打开IRSP6的数据,不过看GDAL提供的文件格式里面却是支持IRSP6的数据的,具体可以参考网页http://www.gdal.org/frmt_fast.html.下面图1是 ...

  8. 修改GDAL库支持RPC像方改正模型

    最近在做基于RPC的像方改正模型,方便对数据进行测试,修改了GDAL库中的RPC纠正模型,使之可以支持RPC像方改正参数. 下面是RPC模型的公式,rn,cn为归一化之后的图像行列号坐标,PLH为归一 ...

  9. 修改ECSHOP,支持图片云存储化(分离到专用图片服务器)

    为了提高页面加载速度和适应中国复杂的网络环境,我决定把所有商品图片都分离到专业的云存储服务器上,具有CDN加速功能. 首先,生成一个域名 img.xxxx.com 并映射到自己的云存储别名,然后把全部 ...

随机推荐

  1. this和判断的位置对赋值的要求

    package charter01; public class Person { private String name; private int age; public String getName ...

  2. oracle中主键自增

    oracle中主键自增 下面用一个例子来说明自增主键的创建: 1.建用户数据表 drop table dectuser; create table dectuser( userid integer p ...

  3. java利用Jsch实现在windows平台远程操作linux服务器

    说明:exec用于执行命令:sftp用于文件处理 package com.wyg.simple; import java.io.BufferedReader; import java.io.File; ...

  4. web网页练习

    一. HTML部分 1. XHTML和HTML有什么区别 HTML是一种基本的WEB网页设计语言,XHTML是一个基于XML的置标语言最主要的不同: XHTML 元素必须被正确地嵌套. XHTML 元 ...

  5. C语言程序内存的分区

    本文转载自:https://blog.csdn.net/shulianghan/article/details/20472269 C语言程序内存分配 (1) 内存分区状况 栈区 (stack) :  ...

  6. python dictionay(字典 )基本用法

    dict(dictionary)是一系列无序对象的集合,由键-值对构成,通过读取键来取得对应的值,具有可变,无序,异构,可嵌套的属性. dict初始化1.直接采用字典格式 2.利用dict(),[注] ...

  7. C#并行编程(3):并行循环

    初识并行循环 并行循环主要用来处理数据并行的,如,同时对数组或列表中的多个数据执行相同的操作. 在C#编程中,我们使用并行类System.Threading.Tasks.Parallel提供的静态方法 ...

  8. IdentityServer4-端点

    一.发现端点 二.授权端点 三.令牌端点 四.UserInfo端点 五.Introspection端点 六.撤销端点 七.结束会话端点 一.发现端点 发现端点可用于检索有关IdentityServer ...

  9. Python解释数学系列——分位数Quantile

    跳转到我的博客 1. 分位数计算案例与Python代码 案例1 Ex1: Given a data = [6, 47, 49, 15, 42, 41, 7, 39, 43, 40, 36],求Q1, ...

  10. Java并发程序设计(九)设计模式与并发之不变模式

    设计模式与并发之不变模式 使用不变模式的目的:除去多线程中的同步操作,提高并行程序的性能. 一个类在的内部状态创建后,在整个生命周期内都不会发生改变,该类就是不变类. /** * @author: T ...