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就行了,这里我更多的是分享自己的理解与技巧.对于作用域和作用域链,相信绝大多数朋友看了我的分享都能基本理解,少 ...
随机推荐
- Navicat for MySQL11--使用经验
Navicat for MySQL11--使用经验.. --------- /-------------------导出SQL:右键表--转储SQL文件--结构和数据---(Finished - Su ...
- Spring mvc登录拦截器
自己实现的第一个Spring mvc登录拦截器 题目要求:拒绝未登录用户进入系统,只要发现用户未登录,则将用户请求转发到/login.do要求用户登录 实现步骤: 1.在spring的配置文件中添加登 ...
- 新手站长如何快速学习实践SEO?
1. 任何老鸟都是从新人开始通过慢慢不断积累,经过各式各样的失败以及彷徨之后,才让自己拥有越来越多的经验,此时信心才会逐渐出现.如果没有勇气踏出第一步去尝试的话,那么永远不可能走在网络营销这条大路上 ...
- Spring详解(一)------概述
本系列教程我们将对 Spring 进行详解的介绍,相信你在看完后一定能够有所收获. 1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开 ...
- log4j源码解析
前言:本文将在slf4j的基础上解释log4j的应用,阅读本文前可先行阅读SLF4J源码解析-LoggerFactory(二) 前言概要 在前言中提到的slf4j的基础,其主要是通过logback的a ...
- python基础教程(九)
python异常 python用异常对象(exception object)来表示异常情况.遇到错误后,会引发异常.如果异常对象并未被处理或捕捉,程序就会用所谓的 回溯(Traceback, 一种错误 ...
- [2014-12-30]如何动态构造Lambda表达式(动态构造Lambda查询条件表达式)
声明 本文对Lambda表达式的扩展,示例代码来源于网络. 场景描述 web开发查询功能的时候,如果查询条件比较多,就会遇到动态组合查询条件的情况.在手写sql的情况下,我们一般会根据传入的参数,针对 ...
- prop解决一个checkbox选中后再次选中失效的问题
//问题点 初始状态复选框没有全选, 点击全选按钮调用checkAll方法, 实现了全选, 然后点击全不选按钮, 实现了全不选, 然后再次点击全选按钮, 结果却木有全选, 再反复点击木有任何反应. d ...
- 关于react-redux中的connect函数
示例代码 'use strict'; import React from 'react'; import { connect } from 'react-redux'; class demo exte ...
- Http get方式url参数长度以及大小
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp69 众所周知, 传递小量参数(在没有其他原因,例如隐藏参数值的情况下)推 ...