Openlayers系列(一)关于地图投影的理解
背景
近期开发以MongoDB为基础的分布式地理数据管理平台系统,被要求做一个简单的demo给客户进行演示。于是笔者便打算向数据库中存储一部分瓦片数据,写一个简单的存取服务器,使用Openlayers客户端加载瓦片进行展示。本来是个挺简单的功能,可是谁曾想,“打了一辈子鹰,却被鹰啄瞎了眼”。在使用Openlayers客户端进行瓦片加载时,出现了加载的瓦片偏移、行列号不正确的问题。
问题描述
如图所示,地图出现了上下偏移的问题,并且,这些瓦片的实际行列号与当前Openlayers计算的行列号并不一致。
Arcgis Server切出的行列号分别是
上面一行瓦片是:104/50,105/50,106/50/107/50
下面一行瓦片是:104/49,105/49,106/49/107/49
Openlayers计算得到的行列号分别是
上面一行瓦片是:104/18,108/18,108/18/107/18
下面一行瓦片是:104/19,105/19,106/19/107/19

猜测及思路
看到行列号及瓦片的偏移,笔者的第一反应是切片方案存在问题。经过排查此次使用的ArcGIS Server采用的切片方案时Google切片方案(EPSG3857,web mercator投影坐标系)。而Openlayers默认采用的坐标系也是EPSG3857,正好吻合,按道理说应该毫无问题。可是既然出现了错误,那就要排查问题,修改错误。既然Arcgis Server的切片方案没问题,那就是Openlayers手动设置了不正确的坐标系。仔细观察果然发现,在Layer的source处将数据源的投影坐标设置为了EPSG4326。何其低级的错误,竟然花费了将近一个小时来排查。

解决方案
将Layer的source投影坐标系设置为3857即可。

补充说明
(一)出现上述错误的原因是Arcgis Server中发布的切片缓存使用了Google切片方案,该切片方案采用Web Mercator投影坐标系,以[-20037508,20037508]作为坐标原点,瓦片大小是256像素(具体的切片方案描述可以在ArcGIS Server Manager的相应服务中看到详细信息)。而本次出错的前端代码中将数据源的投影设置为EPSG:4326,与所发布服务的投影坐标系不匹配,导致Openlayers在计算行列号时无法计算出正确的结果,所以出现了加载错误。
Openlayers(2/3/4)默认采用EPSG:3857作为数据源的投影坐标系,该参数需要与后端的地图服务所采用的投影坐标系匹配才可正常加载地图,所以当我们采用Google的切片方案时(Web Mercator,也就是EPSG:3857),即使不设置Openlayers数据源的投影坐标系,也可正常加载。
Openlayers3的View中也有一个Projection参数,该参数为显示地图的坐标系,设置EPSG:4326或者EPSG:3857都可以,不影响数据的加载。唯一的不同就是,EPSG4326是WGS84地理坐标系,以经纬度为单位;EPSG3857是Web Mercator投影坐标系,以米为单位。如果将坐标系设置成4326,那么你是用openlayer从地图上获得的坐标数据都是经纬度坐标,向地图添加坐标点时,坐标点的数据也应该是经纬度坐标。如果不幸的你设置了4326坐标系,而手上的数据确是3857的投影坐标系数据,那么你有比较简便的方案解决这个问题:
1、 将View的Projection设置成epsg3857
2、 使用Openlayers提供的ol.proj.transform(coordinate, source, destination)方法,将3857坐标系的数据动态的转换成4326坐标系的数据。
(二)
地图服务的坐标系取决于切片方案里的设置,而非原tiff数据或者shp数据本身的坐标系。Google的切片方案采用的就是EPSG3857的投影,读者也可以自行定义切片方案,把坐标系设置为EPSG4326,或者GCJ2000都可以,只要你正确的设置切片方案的参数即可。
Openlayers系列(一)关于地图投影的理解的更多相关文章
- java高并发系列 - 第5天:深入理解进程和线程
进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.程序是指令.数据及其组织形式的描述,进程是程序的实体. 进程具有的 ...
- Openlayers系列(一)关于地图投影相关错误的解决方案
背景 近期开发以MongoDB为基础的分布式地理数据管理平台系统,被要求做一个简单的demo给客户进行演示.于是笔者便打算向数据库中存储一部分瓦片数据,写一个简单的存取服务器,使用Openlayers ...
- .Net Discovery系列之十二-深入理解平台机制与性能影响(下)
上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制.即时编译机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的异常捕获机制与字符串驻留机制. 三.关于异常捕获机制 虽然我们已经很 ...
- 深度学习基础系列(五)| 深入理解交叉熵函数及其在tensorflow和keras中的实现
在统计学中,损失函数是一种衡量损失和错误(这种损失与“错误地”估计有关,如费用或者设备的损失)程度的函数.假设某样本的实际输出为a,而预计的输出为y,则y与a之间存在偏差,深度学习的目的即是通过不断地 ...
- 重学Golang系列(一): 深入理解 interface和reflect
前言 interface(即接口),是Go语言中一个重要的概念和知识点,而功能强大的reflect正是基于interface.本文即是对Go语言中的interface和reflect基础概念和用法的一 ...
- 【Azure 机器人】微软Azure Bot 编辑器系列(6) : 添加LUIS,理解自然语言 (The Bot Framework Composer tutorials)
欢迎来到微软机器人编辑器使用教程,从这里开始,创建一个简单的机器人. 在该系列文章中,每一篇都将通过添加更多的功能来构建机器人.当完成教程中的全部内容后,你将成功的创建一个天气机器人(Weather ...
- [牛感悟系列]JAVA(1)理解JAVA垃圾回收
理解JAVA垃圾回收的好处是什么?满足求知欲是一方面,编写更好的JAVA应用是另外一方面. 如果一个人对垃圾回收过程感兴趣,那表明他在应用程序开发领域有相当程度的经验.如果一个人在思考如何选择正确的垃 ...
- ELK系列~对fluentd参数的理解
这段时候一直在研究ELK框架,主要集成在对fluentd和nxlog的研究上,国内文章不多,主要看了一下官方的API,配合自己的理解,总结了一下,希望可以帮到刚入行的朋友们! Fluentd(日志收集 ...
- js对象系列【二】深入理解js函数,详解作用域与作用域链。
这次说一下对象具体的一个实例:函数,以及其对应的作用域与作用域链.简单的东西大家查下API就行了,这里我更多的是分享自己的理解与技巧.对于作用域和作用域链,相信绝大多数朋友看了我的分享都能基本理解,少 ...
随机推荐
- linux系统参数调优
执行 ulimit -a 查看系统配置 需要修改max user processes 和 open files 这两个值 vim /etc/security/limits.conf #新增下面几行 ...
- 程序猿表白练级之Hello World
程序猿表白练级之Hello World ... 推荐一个优秀的编程网站:Hello World http://www.he11oworld.com/ The Hello World Collectio ...
- Oracle 11g的安装详细过程
本次采用的电脑为win10 专业版,以下为本人电脑的配置情况: 本人是第一次在win10系统上面进行oracle 11g的安装. 以下为安装步骤: 一.下载软件包 以下为各种oracle安装包的下载网 ...
- JavaScript练习题 全局变量 局部变量 作用域
前沿:大家好~我是阿飞~本次 任何简单的事情都可以复杂化,本次让我们来做下搞事情的练习题吧 例题1: var a = 1; function fn1(){ var a = 2; alert(a); / ...
- 正则表达式-linux基础
通配符 通赔符是模糊匹配的基础,因为通赔符机制的存在使得我们在查找文件的时候非常方便 * :匹配任意长度的任意字符,也可以一个都没有 . :匹配任意单个字符,必须有一个 [ ] ...
- AC Analysis
1.从Options---sheet properties—circuit—show all调出来节点编号 :
- Java中面向字符的输入流
Java中面向字符的输入流 2016-12-04 Java程序员联盟 Java程序员联盟 Java程序员联盟 微信号 javalm 功能介绍 莫道君行早,更有早行人 全心敲代码,天道自酬勤 字符流是针 ...
- [2014-08-17]Mac OSX 截图快捷键
系统:OSX 10.9.4 内容来自网络,存于此以便查阅 基本操作 全屏截图:Command-Shift-3 指定区域截图:Command-Shift-4 指定窗口截图:Commnad-Shift-4 ...
- asp.net core策略授权
在<asp.net core认证与授权>中讲解了固定和自定义角色授权系统权限,其实我们还可以通过其他方式来授权,比如可以通过角色组,用户名,生日等,但这些主要取决于ClaimTypes,其 ...
- Java中的异常和处理详解
简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...