百度地图API初体验和偏移纠正方法

摘要:
%@pagelanguage=“java”import=“java.util.*”pageEncoding=“UTF-8”%>metaname=“viewport”content=“初始比例=1.0;字符集=utf-8”/>百度地图API演示<html{height;margin;padding;services=true“>

      最近的项目想做一个在可以通过手持设备获取经纬度,然后在地图上进行标注显示的功能,因为还在技术调研阶段,所以决定先使用百度地图或Google Maps的API来做Demo。通过网上的一些资料和自己对于Google和百度地图的使用,对这两个地图做了一些简单的对比,结论是很明显的——Google在技术水平和成熟度上都要比百度高很多,可以说完全不在一个档次上,但是鉴于Google和中国政府的微妙关系加上中国特色的互联网管理方式,实在是没有信心使用随时可能被墙的产品,所以最终还是无奈地选择了百度地图。

      有那么几点罗列一下:

  • Google地图能够放大到比百度地图更加细致的比例尺,而且在地图标注上也比百度的详细很多。
  • 百度地图在道路的绘制上可能比Google Maps更加详细些,具体来说是某些小的道路,Google Maps并不显示,而会在百度地图上看到。
  • 两者的免费版都不允许商业应用,并且Google Maps API按IP进行限制,貌似是15K每天,如果超过这个限额就会返回错误,不过可以发邮件给Google说这个问题,添加白名单之类。百度暂时没有发现存在这个限制。
  • 企业版费用,Google Maps API如果是商业应用的话,貌似是最少10000美元每年的费用,百度问了一下是15万人民币的年费。
  • GPS经纬度坐标偏移问题。这个是由于中国要求对经纬度进行加密导致的,所以百度和Google的地图上都存在这个问题,即使用手持设备或者导航设备获取到的经纬度在地图上定位发现并不是对应的位置,而存在很大的偏移。Google地图的位置纠正网上有很多资料,我这里就不说了,可以自己去查,后面会讲下百度地图偏移问题的解决方法。
  • API性能对比。这个网上有一些对比,我自己做的实验也不具有代表性,因此此处不说了,结论是Google的相对较好些,有个链接可以稍微参考下:http://www.cnblogs.com/milkmap/archive/2011/02/09/1950142.html

  百度地图API的使用主要是JavaScript的方式,参考资料只能是百度地图官网的API说明和示例,基本也够用了,我此处做的例子就是直接拷贝的它的代码进行了简单的综合,非常的简单,一个从url传入经纬度值,进行以此坐标为中心显示一定比例尺的地图,加入地图漫游、缩放、鱼骨和比例尺控件功能,添加右键事件响应菜单,获取所点击点的坐标传递给一个url的过程。仅仅粘贴代码如下,包括一些url参数提取的函数和api的注释都是网上的,不能算是完全的原创。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

		<title>百度地图API Demo</title>
		<style type="text/css">
html {
	height: 100%
}

body {
	height: 100%;
	margin: 0px;
	padding: 0px
}

#container {
	height: 100%
}
</style>
		<script type="text/javascript"
			src="http://api.map.baidu.com/api?v=1.1&services=true"></script>
	</head>

	<body>
		<div id="container"></div>
	</body>
	<script type="text/javascript">
	function GetRequest() {
		var url = location.search; //获取url中"?"符后的字串
		var theRequest = new Object();

		if (url.indexOf("?") != -1) {
			var str = url.substr(1);
			strs = str.split("&");
			for ( var i = 0; i < strs.length; i++) {
				theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
			}
		}
		return theRequest;
	}

	var Request = new Object();
	Request = GetRequest();
	var xLocation, yLocation;
	xLocation = Request['xLocation'];
	yLocation = Request['yLocation'];
	var map = new BMap.Map("container"); // 创建地图实例   
	var point = new BMap.Point(xLocation, yLocation); // 创建点坐标   
	map.centerAndZoom(point, 18); // 初始化地图,设置中心点坐标和地图级别
	map.enableScrollWheelZoom(); // 启用滚轮放大缩小。
	map.enableKeyboard(); // 启用键盘操作。
	map.addControl(new BMap.NavigationControl()); // 添加平移缩放控件
	map.addControl(new BMap.ScaleControl()); // 添加比例尺控件
	map.addControl(new BMap.OverviewMapControl()); //添加缩略地图控件
	var marker = new BMap.Marker(point);        // 创建标注
	map.addOverlay(marker);                          // 将标注添加到地图中	

	var menu = new BMap.ContextMenu();
	var txtMenuItem = [ {
		text : '传递坐标',
		callback : function(p) {
			//window.location.href='http://t.zoukankan.com/MyJsp.jsp?x=' + p.lng;
		window.open('MyJsp.jsp?lng=' + p.lng + '&lat=' + p.lat);
	}
	} ];

	for ( var i = 0; i < txtMenuItem.length; i++) {
		menu.addItem(new BMap.MenuItem(txtMenuItem[i].text,
				txtMenuItem[i].callback, 100));
	}
	map.addContextMenu(menu);
</script>
</html>
 

   下面简单介绍下经纬度坐标偏移问题的解决方法,这个官方说法是因为百度在国家标准的加密算法的基础上又进行了一次加密导致的,解决方案需要询问百度。这里有一个百度hi群的群号:1306508,有问题的可以加群里问,不过一般也会被告知这个需要合作伙伴才可以告诉,很郁闷。

  我是发邮件给mapapi@baidu.com才获得了解决方法,也是通过一个网址,将待转换的经纬度以url参数的形式传递进去,打开的页面是经过了Base64形式的校正经纬度坐标,实验了一下还挺准确的。之前在互联网上查到过一个网址,不过都说已经被百度停止服务了,不过对比了一下和百度给我的网址,发现并没有停止服务,而是对参数名称进行了改变。。。具体的网址我就不便多说了(其实是掩耳盗铃),跟百度沟通应该就可以获取得到~

  由于我做的程序不能直接使用那个转换服务进行转换,因此我使用JAVA写了一个程序,模仿HTTP发送请求,然后解析返回的页面信息。具体的代码如下:

package tools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

public class BaiduAPIConverter {

	public static void testPost(String x, String y) throws IOException {
		URL url = new URL(
				"XXXXX");
		URLConnection connection = url.openConnection();
		/**
		 * 然后把连接设为输出模式。URLConnection通常作为输入来使用,比如下载一个Web页。
		 * 通过把URLConnection设为输出,你可以把数据向你个Web页传送。下面是如何做:
		 */
		connection.setDoOutput(true);
		OutputStreamWriter out = new OutputStreamWriter(connection
				.getOutputStream(), "utf-8");
		// remember to clean up
		out.flush();
		out.close();
		// 一旦发送成功,用以下方法就可以得到服务器的回应:
		String sCurrentLine;
		String sTotalString;
		sCurrentLine = "";
		sTotalString = "";
		InputStream l_urlStream;
		l_urlStream = connection.getInputStream();
		BufferedReader l_reader = new BufferedReader(new InputStreamReader(
				l_urlStream));
		while ((sCurrentLine = l_reader.readLine()) != null) {
			if (!sCurrentLine.equals(""))
				sTotalString += sCurrentLine;
		}
		System.out.println(sTotalString);
		sTotalString = sTotalString.substring(1, sTotalString.length()-1);
		String[] results = sTotalString.split("\\,");
		if (results.length == 3){
			if (results[0].split("\\:")[1].equals("0")){
				String mapX = results[1].split("\\:")[1];
				String mapY = results[2].split("\\:")[1];
				mapX = mapX.substring(1, mapX.length()-1);
				mapY = mapY.substring(1, mapY.length()-1);
				mapX = new String(Base64.decode(mapX));
				mapY = new String(Base64.decode(mapY));
				System.out.println(mapX);
				System.out.println(mapY);
			}
		}
		
	}

	public static void main(String[] args) throws IOException {
		testPost("116.31500244140287", "40.006434917448786");
	}
}

  结果我使用了Apache的Base64包进行转码,如果你想代码跑起来需要去下载这个包,或者你可以输出转码前的字符串~哦,对了,Base64编码的坐标信息可以直接传递给百度地图的API进行使用。

  总体来说,百度地图API做得还算简单,使用还算方便,但是和Google Maps比起来还是有一定的差距的,希望本文可以对使用的人有所帮助~祝好运。

免责声明:文章转载自《百度地图API初体验和偏移纠正方法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇VisionPro工业视觉的标定方法web | [pasecactf_2019]flask_ssti下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

日志服务:NLog

ylbtech-日志服务:NLog NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码。 NLog是一个简单灵活的.NET日志记录类库。通过使用NLog,我们可以在任何一种.NET语言中输出带有上下文的(contextual information)调试诊断信息,根据喜好配置其表现样式之后发送到一个或多个输...

HTML调用servlet(一)

1.页面的数据表单 在使用Servlet处理用户请求之前,先准备一个页面,该页面用来提供数据表单。数据表单就是HTML中的<form>...</form>部分,当用户单击Submit按钮提交表单之后,表单中包含的一些变量(或者成为字段)将会被发送到服务器端进行处理。下面编写一个HTML文件,文件代码如下: add.html &l...

Java Api Consumer 连接启用Kerberos认证的Kafka

java程序连接到一个需要Kerberos认证的kafka集群上,消费生产者生产的信息,kafka版本是2.10-0.10.0.1; Java程序以maven构建,(怎么构建maven工程,可去问下度娘:“maven工程入门示例”) 先上pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0...

reindex-maven 私服(nexus)架设以及项目管理中遇到的问题及解决方案(updating)

---    用maven 的过程中 大问题小问题实在是不少 ,就不一篇文章一篇文章的写了,干脆写在一起 ---- -------  nexus 加索引  点击Administration菜单下面的Repositories,将这三个仓库Apache Snapshots,Codehaus Snapshots,Maven Central的configura...

阿里druid数据源配置及数据库密码加密

注意: 1、阿里默认只对用户密码解密 2、druid 1.0.16版本及以上的解密时需要同时配置publicKey 一.生成密文密码 1 前提:已经配置了jdk环境 1、生成密文密码需要准备druid的jar包.然后通过命令行生成,如下步骤: 1.1准备jar包 1、(示例使用 druid-0.2.23.jar),放到某目录下,且打开命令窗口(win用户可...

WPF知识点全攻略13- 绘图

WPF基础图形: Line:直线,可设置笔触(Stroke) Rectangle:矩形,既有笔触(Stroke),又有填充(Fill) Ellipse:椭圆,有笔触和填充(包含正圆) Polygon:多边形(闭合),由多条直线段围成的闭合区域,有笔触和填充 Polyline:折线(不闭合),由多条首尾相接的直线段组成 Path:路径,基本图形中功能最强大的...