[转]百度地图API详解之地图坐标系统
博客原文地址:http://www.jiazhengblog.com/blog/2011/07/02/289/
我们都知道地球是圆的,电脑显示器是平的,要想让位于球面的形状显示在平面的显示器上就必然需要一个转换过程,这个过程就叫做投影(Projection)。在地球上我们通过经纬度来描述某个位置,而经过投影之后的地图也有自己的坐标系统,本篇文章就来详细介绍在百度地图API中涉及的各种坐标体系。
在百度地图API中,你需要了解如下坐标系:
- 经纬度:通过经度(longitude)和纬度(latitude)描述的地球上的某个位置。
- 平面坐标:投影之后的坐标(用x和y描述),用于在平面上标识某个位置。
- 像素坐标:描述不同级别下地图上某点的位置。
- 图块坐标:地图图块编号(用x和y描述)。
- 可视区域坐标:地图可视区域的坐标系(用x和y描述)。
- 覆盖物坐标:覆盖物相对于容器的坐标(用x和y描述)。
别被这么多的坐标系吓着,看完了后面的讲解相信你会逐渐理解它们。
经纬度
这个就不多说了,不熟悉的可以翻翻地理书。但需要注意的是即便同是经纬度坐标也可能属于不同的坐标体系。一般GPS设备获取的经纬度属于WGS84坐标系,这是一个比较通用的坐标体系。由于某些原因国内不能直接使用WGS84坐标,因此百度地图API的经纬度是经过加密偏移的。
平面坐标
前面说过,球面上的形状需要经过投影才能变换为平面上的形状,变换后就需要有一个平面坐标系统来描述地图上某个位置。百度地图API默认使用墨卡托投影(Mercator Projection),同样需要注意的是由于投影参数不同,同样是墨卡托投影也会有所差别。
平面坐标系的原点与经纬度的原点一致,即赤道与0度经线相交的位置:

在百度地图API中,平面坐标是以最大级别18级为基准的。就是说在18级下,平面坐标的一个单位就代表了屏幕上的1个像素。平面坐标与地图所展示的级别没有关系,也就是说在1级和18级下,天安门位置的平面坐标都是一致的。那么如何知道某个位置的平面坐标呢?可通过BMap.MercatorProjection类来完成,该类提供经纬度与平面坐标互相转换的方法。例如天安门的经纬度大约为116.404, 39.915,经过转换即可得到平面坐标:
var projection =new BMap.MercatorProjection();
var point = projection.lngLatToPoint(new BMap.Point(116.404, 39.915));
alert(point.x +", "+ point.y);
结果如下:

这个就是平面坐标。你可以这样理解它的含义:第18级下,天安门距离坐标原点的位置差为:12958175, 4825923.77,单位为像素。
像素坐标
在第18级下,我们直接将平面坐标向下取整就得到了像素坐标,而在其他级别下可以通过如下公式进行换算(这里取整为向下取整):
像素坐标 = |平面坐标 × zoom -|
比如经过计算,在第4级天安门位置的像素坐标是:790, 294

不同级别下,同一个地理位置的像素坐标是不一样的,它与当前地图的级别相关。
图块坐标
百度地图API在展示地图时是将整个地图图片切割成若干图块来显示的,当地图初始化或是地图级别、中心点位置发生变化时,地图API会根据当前像素坐标计算出视野内需要的图块坐标(也叫图块编号),从而加载对应的图块用以显示地图。
百度地图的图块坐标原点与平面坐标一致,从原点向右上方开始编号为0, 0:

如何知道某个位置的图块坐标呢?通过如下公式计算即可(这里为向下取整):
图块坐标 =|像素坐标 ÷ |
256实际上是每个图块的宽度和高度,我们用像素坐标除以这个数就知道图块坐标了。还以天安门为例,在第4级下天安门所在的图块编号为:3, 1,而在第18级下,图块编号为:50617, 18851
可视区域坐标
地图都是显示在确定大小的矩形框中的,这个矩形框通常是开发者在初始化地图传入的某个容器元素。这个矩形框也有自己的坐标系,在百度地图API中称之为可视区域坐标系,它的原点位于矩形的左上角。

通过Map类的pointToPixel和pixelToPoint方法可以相互转换经纬度坐标与可视区域坐标。
覆盖物坐标
覆盖物在实现上就是若干DOM元素,这些元素会被放在若干覆盖物容器内(具体请参考地图API开发指南),那么覆盖物的坐标实际上就是相对于这些覆盖物容器的坐标。在地图初始化完成后,覆盖物容器的左上角与地图可视区域左上角位置相同,一旦地图被移动、缩放,覆盖物容器位置就会发生变化。在自定义覆盖物的时候API提供经纬度信息,而开发者需要自行将经纬度转换为覆盖物的像素坐标,从而覆盖物才能显示在正确的位置上。这个转换过程可以通过Map的pointToOverlayPixel和overlayPixelToPoint两个方法来实现。
讲这么多都快晕了吧,我们最后通过一个完整的代码示例来回顾上面所提到的坐标系概念:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>地图坐标概念</title>
<script src="http://api.map.baidu.com/api?v=1.2"></script>
</head>
<body>
<div id="map_container" style="width:500px;height:320px;"></div>
<script>
var map =new BMap.Map('map_container', {defaultCursor: 'default'});
map.centerAndZoom(new BMap.Point(116.404, 39.915), 11); var TILE_SIZE =256; map.addEventListener('click', function(e){
var info =new BMap.InfoWindow('', {width: 260});
var projection =this.getMapType().getProjection(); var lngLat = e.point;
var lngLatStr ="经纬度:"+ lngLat.lng +", "+ lngLat.lat; var worldCoordinate = projection.lngLatToPoint(lngLat);
var worldCoordStr ="<br />平面坐标:"+ worldCoordinate.x +", "+ worldCoordinate.y; var pixelCoordinate =new BMap.Pixel(Math.floor(worldCoordinate.x * Math.pow(2, this.getZoom() -18)),
Math.floor(worldCoordinate.y * Math.pow(2, this.getZoom() -18)));
var pixelCoordStr ="<br />像素坐标:"+ pixelCoordinate.x +", "+ pixelCoordinate.y; var tileCoordinate =new BMap.Pixel(Math.floor(pixelCoordinate.x /256),
Math.floor(pixelCoordinate.y /256));
var tileCoordStr ="<br />图块坐标:"+ tileCoordinate.x +", "+ tileCoordinate.y; var viewportCoordinate = map.pointToPixel(lngLat);
var viewportCoordStr ="<br />可视区域坐标:"+ viewportCoordinate.x +", "+ viewportCoordinate.y; var overlayCoordinate = map.pointToOverlayPixel(lngLat);
var overlayCoordStr ="<br />覆盖物坐标:"+ overlayCoordinate.x +", "+ overlayCoordinate.y; info.setContent(lngLatStr + worldCoordStr + pixelCoordStr + tileCoordStr +
viewportCoordStr + overlayCoordStr);
map.openInfoWindow(info, lngLat);
});
</script>
</body>
</html>
效果如图:

引文连接:百度地图API详解之地图坐标系统
[转]百度地图API详解之地图坐标系统的更多相关文章
- 百度地图Api详解之地图标注
标注概述 标注(Marker)是用来表示一个点位置的可见元素,每个标注自身都包含地理信息.比如你在西单商场位置添加了一个标注,不论地图移动.缩放,标注都会跟随一起移动,保证其始终指向正确的地理位置. ...
- 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:
原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...
- 百度地图API详解之自定义地图类型
http://blog.csdn.net/sup_heaven/article/details/8461586 今天的文章主要介绍如何利用地图API实现自定义地图. 百度地图API目前默认支持两种地图 ...
- 【百度地图API】如何自定义地图图层?实例:制作麻点图(自定义图层+热区)
原文:[百度地图API]如何自定义地图图层?实例:制作麻点图(自定义图层+热区) 摘要:自定义地图图层的用途十分广泛.常见的应用,比如制作魔兽地图和清华校园地图(使用切图工具即可轻松实现).今天我们来 ...
- iOS原生地图开发详解
在上一篇博客中:http://my.oschina.net/u/2340880/blog/414760.对iOS中的定位服务进行了详细的介绍与参数说明,在开发中,地位服务往往与地图框架结合使用,这篇博 ...
- 微信小程序 使用腾讯地图SDK详解及实现步骤
信小程序 使用腾讯地图SDK详解及实现步骤 微信小程序JavaScript SDK: 官方文档:http://lbs.qq.com/qqmap_wx_jssdk/index.html 步骤: 1 ...
- 【百度地图API】如何利用地图API制作汽车沿道路行驶的动画?——如何获得道路层数据
原文:[百度地图API]如何利用地图API制作汽车沿道路行驶的动画?--如何获得道路层数据 有几个做汽车导航的朋友问我说,他们想在地图上制作一辆车沿着道路行驶的动画.可是,百度地图的道路数据并没有公开 ...
- 【百度地图API】如何在地图上添加标注?——另有:坐标拾取工具+打车费用接口介绍
原文:[百度地图API]如何在地图上添加标注?--另有:坐标拾取工具+打车费用接口介绍 摘要: 在这篇文章中,你将学会,如何利用百度地图API进行标注.如何使用API新增的打车费用接口. ------ ...
- 【百度地图API】多家地图API文件大小对比
原文:[百度地图API]多家地图API文件大小对比 于2011.6.9日更新百度地图API文件大小.同时更新图片. 任务描述: 明天就是元宵佳节啦~这是一个团团圆圆的节日,于是,再次想把各家API聚在 ...
随机推荐
- 4.java设计模式-原型模式(prototype)
在<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更 ...
- 基于netcore对ElasitSearch客户端NEST查询功能的简单封装NEST.Repository
NEST.Repository A simple encapsulation with NEST client for search data form elasticsearch. github A ...
- 理解webpack4.splitChunks之chunks
上回说到按照默认的splitChunks配置,入口里面的第三方依赖没有打包出来,这个是因为chunks属性的原因,下面我们就介绍chunks属性的意义和用法. chunks的含义是拆分模块的范围,它有 ...
- css文本内容显示省略号
文字显示省略号width: 4.5rem;overflow: hidden;white-space: nowrap;text-overflow: ellipsis; 但是这个属性只支持单行文本的溢出显 ...
- laravel开发之-(1)数据库链接测试
composer安装成功后,网站建设的操作记录: 一.修改默认首页.伪静态配置文件 1.将serve.php改为index.php 2.public文件夹下的.htaccess文件复制到根目录下 二. ...
- PHP array_flip() array_merge() array+array的使用总结
array_flip(array); //传递一个数组参数,对该数组的键.值进行翻转 例如: $a = array( 'a', 'b', 'c' ); print_r(array_flip($a)); ...
- flask多线程多协程操作
local的作用:各个线程各开辟一块空间互不影响 基于local""" import threading from threading import local impo ...
- C# winform 打印事例
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- pt-summary
pt-summary主要是用来统计机器信息: [root@mxqmongodb2 bin]# ./pt-summary # Percona Toolkit System Summary Report ...
- 如何检索某个字段在sqlserver中的哪个些存储过程中?很简单的SQL语句。
SELECT obj.Name 存储过程名, sc.TEXT 存储过程内容 FROM syscomments sc INNER JOIN sysobjects obj ON sc.Id = obj.I ...