最近的项目想做一个在可以通过手持设备获取经纬度,然后在地图上进行标注显示的功能,因为还在技术调研阶段,所以决定先使用百度地图或Google Maps的API来做Demo。通过网上的一些资料和自己对于Google和百度地图的使用,对这两个地图做了一些简单的对比,结论是很明显的——Google在技术水平和成熟度上都要比百度高很多,可以说完全不在一个档次上,但是鉴于Google和中国政府的微妙关系加上中国特色的互联网管理方式,实在是没有信心使用随时可能被墙的产品,所以最终还是无奈地选择了百度地图。
有那么几点罗列一下:
百度地图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
=
'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,有问题的可以加群里问,不过一般也会被告知这个需要合作伙伴才可以告诉,很郁闷。
我是发邮件给[email protected]才获得了解决方法,也是通过一个网址,将待转换的经纬度以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比起来还是有一定的差距的,希望本文可以对使用的人有所帮助~祝好运。