什么是百度地图API-(3)百度地图移动版API(Android)是一套基于Android设备的应用程序接口,通过该接口,可以轻松访问百度服务和数据,构建功能丰富、交互性强的地图应用程序。
百度地图移动版API不仅包含构建地图的基本接口,还提供了本地搜索、路线规划、地图定位等数据服务。
sdk下载地址:http://developer.baidu.com/map/
使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index.html查询地理
百度地图入门(45)
三大核心BMapManager:百度引擎的管理工具。
MapView:显示地图的类,它的父类是ViewGroup.
MapView 的MKMapViewListener
MapController:对当前地图进行控制:缩放、旋转、平移。
|
准备工作 1、获取API Key
Android签名证书的sha1值获取方式有两种: 第一种方法:使用keytool 第1步:运行进入控制台 第2步:定位到.android文件夹下,输入cd .android
第3步:输入keytool -list -v -keystore debug.keystore,会得到三种指纹证书,选取SHA1类型的证书(密钥口令是android),例如: 其中keytool为jdk自带工具;keystorefile为Android 签名证书文件
| 获取API Key 地址:http://developer.baidu.com/map/android-mobile-apply-key.htm 已经得到的Key: 1A4A4ABEFBEECD8C17DEE880C4EA69B9607020B5
电影时光: 8gvYUwg6QKIqfMHhcMyys531pH7PWGHW
不同的地图厂商,申请API Key
2、建立工程 创建工程后BaiduMap
添加引擎到Andoid工程中 添加jar包:baidumapapi_v2_1_2.jar和locSDK_3.1.jar 添加.so文件:拷贝libapp_BaiduMapApplib_v2_1_2.so、liblocSDK3.so、libvi_voslib.so到libs\armeabi目录下 注:liblocSDK3.so和locSDK_3.1.jar为百度定位SDK所使用资源,开发者可根据实际需求自行添加。
3、在布局文件mapView初始化前 添加地图引擎到Andoid工程中 initManager();
4、添加权限
<!-- gps --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- wifi --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 网络的权限 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 离线包 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 获取手机信息 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
5、初始化地图引擎
/** * 初始化地图引擎 */ private void initManager() { // 地图引擎 manager = new BMapManager(this); /** * strKey - 申请的授权验证码 listener - 注册回调事件 */
manager.init(ConfigValues.key, new MKGeneralListener() {
// MKEvent // 授权验证 @Override public void onGetPermissionState(int iError) { // if (iError == MKEvent.ERROR_PERMISSION_DENIED) { Toast.makeText(getApplicationContext(), "授权失败", 1).show(); } }
// 网络状态 @Override public void onGetNetworkState(int iError) { if (iError == MKEvent.ERROR_NETWORK_CONNECT) { Toast.makeText(getApplicationContext(), "网络连接失败", 1).show(); } } });
}
6、引入布局(地图控件)common.xml Layout中添加MapView控件用于展示地图
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.baidu.mapapi.map.MapView android:layout_width="wrap_content" android:layout_height="wrap_content" />
</RelativeLayout>
运行演示,看看显示效果。
7、缩放级别 打开浏览器看一看百度地图最小级别 地图缩放级别 V1.X : 3--18级别 V2.X : 3--19级别 V2.X和V1.X的主要区别 A:修改了地图文件袋格式,节省空间。 例如北京市地图:V1.x:120MB,V2.X:20MB,相对于压缩9倍。 B:放大级别多了一个级别变成19级别,增加了3D效果。
8、MapController地图控制器 创建管理工具,并初使化 BMapManager在init时校验key(300)和网络状态(2),关于状态码信息我们可以在MKEvent查询
管理某个具体的MapView:缩放、旋转、移动;
private void init() { //MapController管理某个MapView:缩放、旋转、移动 mapView = (MapView) findViewById(R.id.map_view); controller = mapView.getController(); //设置地图的缩放级别,这个参数取值范围3--19 controller.setZoom(12); } 运行起来,演示一下。 9、添加控制地图放大放小按钮 //需要在mapview添加一组按钮,mapview.addView(view) mapView.setBuiltInZoomControls(true);
10.中心点的设置 默认地图中心设置是天安门 如果自己设置喜欢的中心点? 北京天安门广场的经纬度(东经:116°23′17〃,北纬:39°54′27〃 ) int latitudeE6 = 116°23′17 乘以 10六次方 这样便于支持小数点后几位 代码如下: int latitude=(int) (40.107218*1E6);//纬度 int longitude=(int) (116.385178*1E6);//经度 GeoPoint point=new GeoPoint(latitude, longitude);//尚硅谷 controller.setCenter(point);
|
[align=justify]退出项目,进来,拖动地图出现下面bug.如图:[/align]
解决代码如下:
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.destroy();
}
|
MapController:主要用于控制地图移动、缩放、旋转的工具
动画形式移动 :animateTo(GeoPoint point)
缩放:zoomOut()—缩小;zoomIn()—放大;setZoom(arg0)—指定缩放级别
旋转
水平方向:setRotation,旋转角范围: 0 ~ 360(?) , 单位:度 默认值为0度,逆时针旋转为角度增大方向,通过MapView的getMapRotation获取当前角度
俯视:setOverlooking,俯角范围: -45 ~ 0 , 单位: 度
指南针设置:setCompassMargin(int x, int y) ,坐标系原点为MapView左上顶点 ,指南针在3D模式下自动显现,注意了,旋转式才出现。
以一个点为中心旋转:
基于一条线旋转(overlooking俯视)
代码如下:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// 缩放、旋转、移动
switch (keyCode) {
case KeyEvent.KEYCODE_1:
// 放大(一级级)
controller.zoomIn();
break;
case KeyEvent.KEYCODE_2:
// 缩小(一级级)
controller.zoomOut();
break;
case KeyEvent.KEYCODE_3:
// 以一个点为中心旋转
// 获取到地图当前的角度
// -180~180
int rotation = mapView.getMapRotation();
controller.setRotation(rotation + 30);
Log.i(TAG, "rotation:" + rotation);
break;
case KeyEvent.KEYCODE_4:
// 俯瞰,以一条线旋转overlooking
// -45~0
int overlooking = mapView.getMapOverlooking();
controller.setOverlooking(overlooking - 5);
Log.i(TAG, "overlooking:" + overlooking);
break;
case KeyEvent.KEYCODE_5:
// 移动
controller.animateTo(new GeoPoint(40065796, 116349868));
break;
}
return super.onKeyDown(keyCode, event);
}
演示看效果以及旋转日志。Android 4.1没法直接接收键盘的数字
|
[b]高级功能简介[/b]
地图图层-(20)什么是地图图层
地图可以包含一个或多个图层,每个图层在每个级别都是由若干个图块组成的,它们覆盖了地图的整个表面。例如您所看到包括街道、兴趣点、学校、公园等内容的地图展现就是一个图层,另外交通流量的展现也是通过图层来实现的。
图层分类
底图
基本的地图图层,包括若干个缩放级别,显示基本的地图信息,包括道路、街道、学校、 公园等内容。
实时交通信息图:MapView.setTraffic(true)
卫星图:MapView.setSatellite(true)
卫星地图是卫星拍摄的真实的地理面貌,所以卫星地图可用来检测地面的信息,你可以了解到地理位置,地形等。 1、创建图层页面 LayerDemo==>基于Hello.java
[align=justify] @Override[/align] [align=justify] public boolean onKeyDown(int keyCode, KeyEvent event) {[/align] [align=justify] // 底层,交通实时图,卫星图[/align] [align=justify] switch (keyCode) {[/align] [align=justify] case KeyEvent.KEYCODE_1:[/align] [align=justify] // 底图[/align] [align=justify] mapView.setTraffic(false);[/align] [align=justify] mapView.setSatellite(false);[/align] [align=justify] break;[/align] [align=justify] case KeyEvent.KEYCODE_2:[/align] [align=justify] // 交通实时图[/align] [align=justify] mapView.setTraffic(true);[/align] [align=justify] mapView.setSatellite(false);[/align] [align=justify] break;[/align] [align=justify] case KeyEvent.KEYCODE_3:[/align] [align=justify] // 卫星图[/align] [align=justify] mapView.setSatellite(true);[/align] [align=justify] mapView.setTraffic(false);[/align] [align=justify] break;[/align] [align=justify] }[/align] [align=justify] return super.onKeyDown(keyCode, event);[/align] [align=justify] }[/align]
[align=justify] private void init() {[/align] [align=justify] mapView = (MapView) findViewById(R.id.map_view);[/align] [align=justify] controller = mapView.getController();[/align] [align=justify] controller.setZoom(12);[/align]
mapView.setBuiltInZoomControls(true); [align=justify] }[/align]
[align=justify]}[/align]
|
覆盖物概念所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。如标注、矢量图形元素(包括:折线和多边形和圆)、定位图标等。覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的处理。
覆盖物包括:
覆盖物的抽象基类:Overlay(核心类),第四个核心类
几何图形绘制覆盖物:GraphicsOverlay
文字绘制覆盖物:TextOverlay
分条目覆盖物:ItemizedOverlay
本地搜索覆盖物:PoiOverlay
路线规划覆盖物:RouteOverlay
换乘路线覆盖物:TransitOverlay
我的位置覆盖物:MyLocationOverlay ---------------------------------------------------------------------------------------------------------------------------------------------------------------
Overlay是一个基类,它表示可以显示在地图上方的覆盖物。
从2.0.0开始,SDK不支持直接继承Overlay , 用户可通过继承ItemizedOverlay来添加覆盖物。
关于Overlay的使用,即在MapView上显示Overlay的步骤
1、需要获取到MapView中保存Overlay的集合
2、在其中添加需要显示的内容
3、然后刷新界面
注意:所不同的是如何给不同的Overlay设置数据,这也是重点。
覆盖物-GraphicsOverlay-
自定义绘制几何图形需要以下几个类的支持: Geometry:这是一个几何图形类,利用此类,可以构建待绘制的各种基本几何元素; Symbol:样式类,如果只构建几何图形类而没有样式的话,该几何图形是无意义的; Graphic:图形类,利用几何图形加上样式,这样就可以构建一个图形类,Graphic就是这样一个类,用于管理所添加的图形; GraphicsOverlay:这是一个用于绘制图形的overlay,和其他的各种overlay用法相同。 绘制步骤 创建自绘图形:Geometry,Geometry表示一个用于绘图的几何图形,目前绘图api提供五种几何图形:点,线,圆、矩形和凸多边形。 为自绘图形选择合适的样式:Symbol,Symbol表示绘图样式,如点颜色,线宽,填充色等。 构建绘图对象:Graphic,通过几何元素(Geometry)和相对应的样式(Symbol)就可以组合成Graphic, Graphic表示SDK可直接用于绘制的一个绘图对象,用户通过操纵Graphic对象向地图添加/移除自绘图形。
[align=justify]GraphicsOverlay:将自绘图形添加到地图中。Graphic对象可通过GraphicsOvelay添加到MapView中。[/align] private void draw() {
//1.从MapView得到所有的覆盖物
List<Overlay> overlays = mapview.getOverlays();
//2.自定义GraphicsOverlay
GraphicsOverlay graphicsOverlay = new GraphicsOverlay(mapview);
//3.给GraphicsOverlay设置参数
setData(graphicsOverlay);
//4.添加到覆盖物的列表集合中
overlays.add(graphicsOverlay);//不能少
//5.MapView刷新
mapview.refresh(); } [align=justify]//设置一个圆[/align] private void setData(GraphicsOverlay overlay) {
[align=justify] //1.定义几何图形:圆心和半径[/align] [align=justify] //几何[/align]
Geometry geometry = new Geometry();
[align=justify] /**[/align] * geoPoint - 地理坐标 radius - 圆的半径,单位:米 [align=justify] */[/align] geometry.setCircle( point, 1000); [align=justify] [/align] [align=justify] //2.样式:颜色、是否填充、绘制圆形是的线条的粗心[/align] [align=justify] //符号[/align] Symbol symbol = new Symbol(); [align=justify] /**[/align] * color - 颜色 status - 填充状态,0表示不填充,1表示填充
linewidth - 线宽,当填充状态为填充时线宽无意义 [align=justify] */[/align] Symbol.Color color =symbol. new Color(); color. red = 255; color. green = 0; color. blue = 0;
color. alpha = 100; [align=justify] symbol.setSurface(color, 1, 5);[/align]
[align=justify] //图形[/align] Graphic graphic = new Graphic(geometry, symbol);
[align=justify] overlay.setData(graphic); [/align] [align=justify] }[/align] [align=justify]}[/align]
[align=justify]把地图公共功能抽取到BaseActivity,代码如下:[/align] [align=justify][/align]
|
[align=justify]覆盖物-TextOverlay-[/align] 简单介绍 Geometry的方法,就是支持的图形。
[align=justify]文字绘制的方法与几何图形绘制的方法类似,它也需要几个类的功能支持才能完成最终绘制:[/align] [align=justify]Symbol:样式类,主要负责为所绘制的文字提供颜色属性;[/align] [align=justify]TextItem:文字类,包含文字对齐方式、颜色、字号、绘制位置、字体等基本信息;[/align] [align=justify]TextOverlay:这是一个用于绘制文字的overlay,和其他的各种overlay用法相同。[/align] [align=justify]绘制步骤[/align] [align=justify]定义并初始化两个Symbol.Color对象,用于设置文字的颜色和其背景的颜色;[/align] [align=justify]定义并初始化TextItem对象,用于所绘制文字的基本属性信息;[/align] [align=justify]基本信息设置:大小、对齐方式等[/align]
[align=justify]/**[/align] [align=justify] * 文字展示[/align] [align=justify] *[/align] [align=justify] */[/align] public class TextOverlayDemo extends BaseActivity { [align=justify] @Override[/align] protected void onCreate(Bundle savedInstanceState) { [align=justify] super.onCreate(savedInstanceState);[/align] [align=justify] draw();[/align] [align=justify] }[/align]
[align=justify] /**[/align] [align=justify] * 绘制文字[/align] [align=justify] */[/align] private void draw() { //1.从MapView得到所有的覆盖物 List<Overlay> overlays = mapview.getOverlays(); //2.自定义TextOverlay TextOverlay textOverlay = new TextOverlay(mapview); //3.给TextOverlay设置参数 setData(textOverlay); //4.添加到覆盖物的列表集合中 overlays.add(textOverlay); //5.MapView刷新 mapview.refresh();
[align=justify] }[/align]
[align=justify] /**[/align] [align=justify] * 设置数据[/align] [align=justify] *[/align] * @param textOverlay [align=justify] */[/align] private void setData(TextOverlay textOverlay) { // int align [align=justify] // 文字对齐方式 ,为 ALIGN_TOP,ALIGN_CENTER, ALIGN_BOTTOM中的一个值[/align] // static int ALIGN_BOTTOM [align=justify] // 文字对齐参数,下边中点对齐[/align] // static int ALIGN_CENTER [align=justify] // 文字对齐参数,中心对齐[/align] // static int ALIGN_TOP [align=justify] // 文字对齐参数,上边中点对齐[/align]
[align=justify] // Symbol.Color bgColor[/align] [align=justify] // 文字背景色, 默认为透明[/align]
[align=justify] // Symbol.Color fontColor[/align] [align=justify] // 文字颜色[/align]
// int fontSize [align=justify] // 字号大小[/align]
// GeoPoint pt [align=justify] // 文字显示的位置,用经纬度坐标表示[/align]
[align=justify] // String text[/align] [align=justify] // 要显示的文字内容[/align]
// Typeface typeface [align=justify] // 文字字体, android 字体表示,为空则用系统默认字体.[/align] TextItem textItem = new TextItem(); textItem. align = TextItem. ALIGN_CENTER;
textItem. fontColor = getColor(); textItem. fontSize = 20; textItem. pt = point; textItem. text = "尚硅谷" ; textItem. typeface = Typeface. SERIF; [align=justify] textOverlay.addText(textItem);[/align]
[align=justify] }[/align]
private Color getColor() { [align=justify] // 符号[/align] Symbol symbol = new Symbol(); [align=justify] /**[/align] * color - 颜色 status - 填充状态,0表示不填充,1表示填充 linewidth - 线宽,当填充状态为填充时线宽无意义 [align=justify] */[/align] Symbol.Color color = symbol. new Color(); color. red = 255; color. green = 0; color. blue = 0; color. alpha = 100; return color; [align=justify] }[/align]
[align=justify]}[/align]
|
覆盖物-多条目的绘制-ItemizedOverlay 1、某个类型的覆盖物,包含多个类型相同、显示方式相同、处理方式相同的项时,使用此类。 2、开发步骤 继承ItemizedOverlay 创建OverlayItem,准备overlay数据; 创建ItemizedOverlay实例,调用 addItem(OverlayItem)} 接口添加overlay。 调用MapView.getOverlays().add()方法添加overlay到mapview中。 调用MapView.refresh() 使Overlay生效 3、显示一个“泡泡窗口”
案例代码: OverlayItem item=new OverlayItem(atguiguPos, "尚硅谷", "牛"); overlay.addItem(item);
item = new OverlayItem(new GeoPoint(latitude + 1000, longitude), "向北", "增加纬度"); overlay.addItem(item);
item = new OverlayItem(new GeoPoint(latitude, longitude + 1000), "向东", "增加经度"); overlay.addItem(item);
item = new OverlayItem(new GeoPoint(latitude - 1000, longitude - 1000), "向西南", "减少经纬度"); overlay.addItem(item); 代码如下: /** * 多条条目绘制 * */ public class ItemizedOverlayDemo extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initPop(); draw(); controller.setZoom(16); }
/** * 画多条和泡泡 */ private void draw() { ItemizedOverlay<OverlayItem> overlay = new ItemizedOverlay<OverlayItem>( getResources().getDrawable(R.drawable.eat_icon), mapView);
setData(overlay);
mapView.getOverlays().add(overlay);
}
private void setData(ItemizedOverlay<OverlayItem> overlay) {
// protected GeoPoint mPoint // 该item的位置 // protected String mSnippet // 该item的文字片段 // protected String mTitle // 该item的标题文本 OverlayItem item = new OverlayItem(point, "尚硅谷", "不6k不就业"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude + 1000, longitude), "向北", "增加纬度"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude, longitude + 1000), "向东", "增加经度"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude - 1000, longitude - 1000), "向西南", "减少经纬度"); overlay.addItem(item); } }
|
显示一个“泡泡窗口”
显示一个“泡泡窗口”-(15)
1、准备好泡泡的layout <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:paddingBottom="0dip" >
<LinearLayout android:id="@+id/user_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:background="@drawable/popupmap" android:orientation="horizontal" android:gravity="center_vertical" android:layout_marginBottom="20dip" >
<ImageView android:id="@+id/round" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="2dip" android:src="@drawable/round" />
<TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" android:text="标题" android:textSize="20sp" />
<ImageView android:id="@+id/roads" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/roads" /> </LinearLayout>
</LinearLayout>
2、在MapView中添加该泡泡 addView(View child, LayoutParams params) LayoutParams:MapView.LayoutParams MapView.LayoutParams(int width, int height, GeoPoint point, int alignment),其中alignment为对其方式,采用BOTTOM_CENTER 在处理onTap时更新Layout,利用LayoutParams传递点位信息,同时可以获取标题信息,设置给TextView
添加泡泡代码如下红色部分:
/** * 多条绘制 * */ public class ItemizedOverlayDemo extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initPop(); draw(); controller.setZoom(16); }
/** * 画多条和泡泡 */ private void draw() {
//1.从MapView得到所有的覆盖物
// List<Overlay> overlays = mapview.getOverlays();
//2.自定义ItemizedOverlay
ItemizedOverlay itemizedOverlay = new ItemizedOverlay(getResources().getDrawable(R.drawable.eat_icon),mapview){
@Override
public int compare(Object lhs, Object rhs) {
return 0;
}
@Override
protected boolean onTap(int i) {
OverlayItem overlayItem = getItem(i);
//设置标题
tv_title.setText(overlayItem.getTitle());
//配置参数 MapView.LayoutParams params = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT,overlayItem.getPoint(),0,-100,MapView.LayoutParams.BOTTOM_CENTER); pop.setVisibility(View.VISIBLE);
//更新地图
mapview.updateViewLayout(pop,params);
return super.onTap(i);
}
};
//3.给ItemizedOverlay设置参数
setData(itemizedOverlay);
//4.添加到覆盖物的列表集合中
mapview.getOverlays().add(itemizedOverlay);
//5.MapView刷新
mapview.refresh();
controller.setZoom(16);
}
private void setData(ItemizedOverlay<OverlayItem> overlay) {
// protected GeoPoint mPoint // 该item的位置 // protected String mSnippet // 该item的文字片段 // protected String mTitle // 该item的标题文本 OverlayItem item = new OverlayItem(point, "尚硅谷", "不4k不就业"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude + 1000, longitude), "向北", "增加纬度"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude, longitude + 1000), "向东", "增加经度"); overlay.addItem(item); item = new OverlayItem(new GeoPoint(latitude - 1000, longitude - 1000), "向西南", "减少经纬度"); overlay.addItem(item); }
private View pop; private TextView title;
// 添加泡泡 // 单击某一条具体的Item的时候其上方显示 // 加载pop // 添加到mapview中,不这种坐标,pop隐藏 // 当点击时,显示泡泡,位置更新 private void initPop() { pop = View.inflate(this, R.layout.pop, null); title = (TextView) pop.findViewById(R.id.title); // MapView.LayoutParams(int width, int height, GeoPoint point, int // alignment) // 创建自定义布局参数,按地理坐标布局 MapView.LayoutParams params = new MapView.LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, null, MapView.LayoutParams.BOTTOM_CENTER); mapView.addView(pop, params); pop.setVisibility(View.INVISIBLE);
}
}
|
[align=justify]
搜索[/align]
1、百度地图移动版API集成搜索服务包括 位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索。 2、核心类: MKSearch和MKSearchListener 3、实现思路 初始化MKSearch类,通过init方法注册搜索结果的监听对象MKSearchListener,实现异步搜索服务。 通过自定义MySearchListener实现类,处理不同的回调方法,获得搜索结果。 注意,MKSearchListener只支持一个,以最后一次设置为准 4、结合覆盖物展示搜索 本地搜索覆盖物:PoiOverlay-圆形区域的、矩形区域、全城范围内搜索。 路线覆盖物:RouteOverlay 换乘路线覆盖物:TransitOverlay
本地搜索 1、POI(Point of Interest兴趣点)搜索有三种方式 根据范围和检索词发起范围检索PoiSearchInbounds 兴趣的界内搜索 周边检索poiSearchNearBy 城市poi检索poiSearchInCity poi详细信息检索 poiDetailSearch 2、结果的展示: PoiOverlay
参数及案例:
poiSearchInbounds:使用参数信息 左下:40.103148 116.368541 右上:40.112916 116.399012,
GeoPoint ptLB = new GeoPoint((int) (40.103148 * 1E6), (int) (116.368541 * 1E6)); GeoPoint ptRT = new GeoPoint((int) (40.112916 * 1E6), (int) (116.399012 * 1E6));
//搜索 public int poiSearchInbounds(java.lang.String key, GeoPoint ptLB, GeoPoint ptRT) 根据范围和检索词发起范围检索.异步函数,返回结果在MKSearchListener里的onGetPoiResult方法通知 参数: key - 关键词 ptLB - 地理坐标,范围的左下角 ptRT - 地理坐标,范围的右上角 返回: 成功返回0,否则返回-1
//结果处理 void onGetPoiResult(MKPoiResult result, int type, int iError) 返回poi搜索结果
参数: result - 搜索结果 type - 返回结果类型: MKSearch.TYPE_POI_LIST, MKSearch.TYPE_AREA_POI_LIST, MKSearch.TYPE_AREA_MULTI_POI_LIST, MKSearch.TYPE_CITY_LIST iError - 错误号,0表示正确返回 对于poiSearchInbounds和poiSearchNearBy,type的值为MKSearch.TYPE_AREA_POI_LIST 对于poiSearchInCity,type的值为MKSearch.TYPE_POI_LIST
3、查询加油站信息
多种查询方法,但结果的处理都在MKSearchListener的onGetPoiResult方法中,在该方法中可以通过传递的type值来区分是范围搜索还是城市检索。
处理步骤: 判断服务器结果返回 创建poi覆盖物 将服务器返回数据添加到poi覆盖物中 添加覆盖物到MapView 刷新MapView
4、注意事项 POI检索结果每页容量默认情况下为10,可以通过setPoiPageCapacity设置,支持1-50(10) 翻页功能通过MKSearch类的goToPoiPage实现,该方法是异步函数,搜索成功后会调用注册的事件处理函数onGetPoiResult 返回查询页的结果。 支持分类搜索,例如mSearch.poiSearchInCity("北京", "娱乐")
|
首先将监听方法写在基类.矩形区域检索 public class PoiSearchInboundsDemo extends BaseActivity {
private MKSearch search;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener(){
@Override//检索结果的回调 public void onGetPoiResult(MKPoiResult mkPoiResult, int i, int i1) {
super.onGetPoiResult(mkPoiResult, i, i1);
if(mkPoiResult != null&&i1 ==0){
//得到兴趣点
PoiOverlay poiOverlay = new PoiOverlay(PoiSearchInboundsDemo.this,mapview);
poiOverlay.setData(mkPoiResult.getAllPoi());
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
}else{
Toast.makeText(PoiSearchInboundsDemo.this,"检索未找到结果",Toast.LENGTH_SHORT).show();
}
}
});
//矩形区域检索兴趣点
// 参数:
// key - 关键词
// ptLB - 地理坐标,范围的左下角
// ptRT - 地理坐标,范围的右上角
// 返回:
// 成功返回0,否则返回-1
int code = search.poiSearchInbounds("加油站",new GeoPoint(40057884,116248736),new GeoPoint(40178827,116539643));
if(code ==0){
Toast.makeText(PoiSearchInboundsDemo.this,"检索成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(PoiSearchInboundsDemo.this,"检索失败",Toast.LENGTH_SHORT).show();
}
}
}
|
|
圆形(附近)区域搜索-(16)
public class PoiSearchNearByDemo extends BaseActivity {
private MKSearch search;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener(){
@Override
public void onGetPoiResult(MKPoiResult mkPoiResult, int i, int i1) {
super.onGetPoiResult(mkPoiResult, i, i1);
if(mkPoiResult != null&&i1 ==0){
//得到兴趣点
PoiOverlay poiOverlay = new PoiOverlay(PoiSearchNearByDemo.this,mapview);
poiOverlay.setData(mkPoiResult.getAllPoi());
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
}else{
Toast.makeText(PoiSearchNearByDemo.this,"检索未找到结果",Toast.LENGTH_SHORT).show();
}
}
});
// 参数:
// key - 关键词
// pt - 中心点地理坐标
// radius - 半径,单位:米
// 返回:
// 成功返回0,否则返回-1
int code = search.poiSearchNearBy("洗浴", atguiguPoint,3000);
if(code ==0){
Toast.makeText(PoiSearchNearByDemo.this,"检索成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(PoiSearchNearByDemo.this,"检索失败",Toast.LENGTH_SHORT).show();
}
}
}
|
[align=justify]全城搜索[/align] [align=justify][/align]
public class PoiSearchInCityDemo extends BaseActivity {
private MKSearch search;
private int indexPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
btn_next.setVisibility(View.VISIBLE);
btn_next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
indexPager++;
search.goToPoiPage(indexPager);
}
});
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener(){
@Override
public void onGetPoiResult(MKPoiResult mkPoiResult, int i, int i1) {
super.onGetPoiResult(mkPoiResult, i, i1);
if(mkPoiResult != null&&i1 ==0){
//注意检索的值超过10个只显示10,需要分页
mkPoiResult.getAllPoi();//总的个数
mkPoiResult.getNumPages();//总夜数
mkPoiResult.getCurrentNumPois();//当前页的个数
mkPoiResult.getNumPois();//总兴趣点
indexPager = mkPoiResult.getPageIndex();//当前页面
String msg = "总兴趣点=="+mkPoiResult.getNumPois()+",当前页的个数=="+ mkPoiResult.getCurrentNumPois()+
",当前页面=="+mkPoiResult.getPageIndex();
System.out.println(msg);
Toast.makeText(PoiSearchInCityDemo.this,msg,Toast.LENGTH_SHORT).show();
//得到兴趣点
PoiOverlay poiOverlay = new PoiOverlay(PoiSearchInCityDemo.this,mapview);
poiOverlay.setData(mkPoiResult.getAllPoi());
mapview.getOverlays().clear();//先清除上次页面
mapview.getOverlays().add(poiOverlay);//再加载新的页面
mapview.refresh();
}else{
Toast.makeText(PoiSearchInCityDemo.this,"检索未找到结果",Toast.LENGTH_SHORT).show();
}
}
});
// 参数:
// city - 城市名
// key - 关键词
// 返回:
// 成功返回0,否则返回-1
int code = search.poiSearchInCity("北京市", "加油站");
if(code ==0){
Toast.makeText(PoiSearchInCityDemo.this,"检索成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(PoiSearchInCityDemo.this,"检索失败",Toast.LENGTH_SHORT).show();
}
}
|
[b]路线检索-驾车路线-(20)[/b]
[align=justify]1、可以进行驾车和步行路线查询[/align] [align=justify]结果展示: RouteOverlay[/align] [align=justify]2、案例:从尚硅谷到北京大学路线查询[/align] [align=justify]3、驾车路线查询[/align] [align=justify]查询:MKSearch.drivingSearch(java.lang.String startCity, MKPlanNode start, java.lang.String endCity, MKPlanNode end)驾乘路线搜索,或者增加途经点.[/align] [align=justify]MKPlanNode内容的设置:可以使用经纬度和地名,但不支持模糊查询,需要输入准确的名称[/align] 可以通过setDrivingPolicy(int policy) 来设置驾车路线规划策略 [align=justify]结果处理:MKSearchListener.onGetDrivingRouteResult(MKDrivingRouteResult result, int iError)[/align] [align=justify]参数案例:[/align] [align=justify]尚硅谷办公楼:40107218,116385178[/align] [align=justify]ECAR_DIS_FIRST 最短距离[/align] [align=justify]ECAR_FEE_FIRST 较少费用[/align] [align=justify]ECAR_TIME_FIRST 时间优先[/align]
|
[align=justify]驾车路线[/align] [align=justify][/align] public class DrivingSearchDemo extends BaseActivity {
private MKSearch search;
private int indexPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener(){
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult mkPoiResult, int i) {
super.onGetDrivingRouteResult(mkPoiResult, i);
if(mkPoiResult != null&&i ==0){ if(mkPoiResult.getNumPlan()>0){ RouteOverlay poiOverlay = new RouteOverlay(DrivingSearchDemo.this,mapview); poiOverlay.setData(mkPoiResult.getPlan(0).getRoute(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
}else{
Toast.makeText(DrivingSearchDemo.this,"此路不通",Toast.LENGTH_SHORT).show();
}
}else{
Toast.makeText(DrivingSearchDemo.this,"检索未找到结果",Toast.LENGTH_SHORT).show();
}
}
});
//设置驾车策略
search.setDrivingPolicy(MKSearch.ECAR_TIME_FIRST);
// startCity - 起点所在城市,起点为坐标时可不填
// start - 搜索的起点,可以为坐标,名称任一种
// endCity - 终点所在城市,终点为坐标时可不填
// end - 搜索的终点,可以为坐标,名称任一种
// 返回:
// 成功返回0,否则返回-1
MKPlanNode start = new MKPlanNode();
start.pt = atguiguPoint;
MKPlanNode end = new MKPlanNode();
end.name = "北京大学";
// int code = search.drivingSearch("北京",start,"北京",end);
ArrayList<MKWpNode> list = new ArrayList<>();
MKWpNode mknode = new MKWpNode();
mknode.city = "北京";
mknode.name = "北京外国语大学";
list.add(mknode);
int code = search.drivingSearch("北京",start,"北京",end,list);
if(code ==0){
Toast.makeText(DrivingSearchDemo.this,"检索成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(DrivingSearchDemo.this,"检索失败",Toast.LENGTH_SHORT).show();
}
}
|
[align=justify]文档中驾车第二个方法:[/align]
privatevoidinitSearch() {
listener
=
new MyListener();
search.init(
manager,
listener);
// 检索策略
// static
int ECAR_DIS_FIRST
// 驾乘检索策略常量:最短距离
// static
int ECAR_FEE_FIRST
// 驾乘检索策略常量:较少费用
// static
int ECAR_TIME_FIRST
// 驾乘检索策略常量:时间优先
search.setDrivingPolicy(MKSearch.
ECAR_TIME_FIRST);
// 参数:
// startCity - 起点所在城市,起点为坐标时可不填
// start - 搜索的起点,可以为坐标,名称任一种
// endCity - 终点所在城市,终点为坐标时可不填
// end - 搜索的终点,可以为坐标,名称任一种
//wpNodes - 途经点数据
// 返回:
// 成功返回0,否则返回-1
MKPlanNode start =
newMKPlanNode();
start.
pt
= point;
[align=justify] [/align]
[align=justify]// MKPlanNode end = new MKPlanNode();[/align]
[align=justify]// end.name = "天安门";[/align]
[align=justify] [/align]
MKPlanNode end =
new MKPlanNode();
end.pt =
new GeoPoint(40065796,116349868);
// 搜索
[align=justify]// search.drivingSearch("北京", start, "北京", end);[/align]
[align=justify] [/align]
//途径点
ArrayList<MKWpNode> arrayList =
new ArrayList<MKWpNode>();
MKWpNode mkWpNode =
new MKWpNode();
[align=justify] mkWpNode.city = "北京";[/align]
[align=justify] mkWpNode.name = "天安门";[/align]
[align=justify] arrayList.add(mkWpNode);[/align]
search.drivingSearch(
"北京", start,
"北京"
, end,arrayList
);
[align=justify] [/align]
[align=justify] [/align]
[align=justify] }[/align]
路线检索-步行检索-
public class WalkingSearchDemo extends BaseActivity {
private MKSearch search;
/**
* 页面下标
*/
private int indexPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener() {
@Override
public void onGetWalkingRouteResult(MKWalkingRouteResult mkPoiResult, int i) {
super.onGetWalkingRouteResult(mkPoiResult, i);
if (mkPoiResult != null && i == 0) {
if (mkPoiResult.getNumPlan() > 0) {
RouteOverlay poiOverlay = new RouteOverlay(WalkingSearchDemo.this, mapview);
poiOverlay.setData(mkPoiResult.getPlan(0).getRoute(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
} else {
Toast.makeText(WalkingSearchDemo.this, "此路不通", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(WalkingSearchDemo.this, "检索未找到结果", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult mkPoiResult, int i) {
super.onGetDrivingRouteResult(mkPoiResult, i);
if (mkPoiResult != null && i == 0) {
if (mkPoiResult.getNumPlan() > 0) {
RouteOverlay poiOverlay = new RouteOverlay(WalkingSearchDemo.this, mapview);
poiOverlay.setData(mkPoiResult.getPlan(0).getRoute(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
} else {
Toast.makeText(WalkingSearchDemo.this, "此路不通", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(WalkingSearchDemo.this, "检索未找到结果", Toast.LENGTH_SHORT).show();
}
}
});
|
路线检索-换乘路线-
public class TransitSearchDemo extends BaseActivity {
private MKSearch search;
private int indexPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initSeach();
}
private void initSeach() {
search = new MKSearch();
search.init(mapManager, new BaseMKSearchListener() {
@Override
public void onGetTransitRouteResult(MKTransitRouteResult mkTransitRouteResult, int i) {
super.onGetTransitRouteResult(mkTransitRouteResult, i);
if (mkTransitRouteResult != null && i == 0) {
if (mkTransitRouteResult.getNumPlan() > 0) {
//注意检索的值超过10个只显示10,需要分页
//得到兴趣点
TransitOverlay poiOverlay = new TransitOverlay(TransitSearchDemo.this, mapview);
poiOverlay.setData(mkTransitRouteResult.getPlan(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
} else {
Toast.makeText(TransitSearchDemo.this, "此路不通", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(TransitSearchDemo.this, "检索未找到结果", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onGetWalkingRouteResult(MKWalkingRouteResult mkPoiResult, int i) {
super.onGetWalkingRouteResult(mkPoiResult, i);
if (mkPoiResult != null && i == 0) {
if (mkPoiResult.getNumPlan() > 0) {
RouteOverlay poiOverlay = new RouteOverlay(TransitSearchDemo.this, mapview);
poiOverlay.setData(mkPoiResult.getPlan(0).getRoute(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
} else {
Toast.makeText(TransitSearchDemo.this, "此路不通", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(TransitSearchDemo.this, "检索未找到结果", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onGetDrivingRouteResult(MKDrivingRouteResult mkPoiResult, int i) {
super.onGetDrivingRouteResult(mkPoiResult, i);
if (mkPoiResult != null && i == 0) {
if (mkPoiResult.getNumPlan() > 0) {
RouteOverlay poiOverlay = new RouteOverlay(TransitSearchDemo.this, mapview);
poiOverlay.setData(mkPoiResult.getPlan(0).getRoute(0));
mapview.getOverlays().add(poiOverlay);
mapview.refresh();
} else {
Toast.makeText(TransitSearchDemo.this, "此路不通", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(TransitSearchDemo.this, "检索未找到结果", Toast.LENGTH_SHORT).show();
}
}
});
//设置换乘策略
search.setTransitPolicy(MKSearch.EBUS_TIME_FIRST);
// city - 城市名,用于在哪个城市内进行检索(必须填写)
// start - 检索的起点,可通过关键字,坐标,两种方式指定
// end - 检索的终点,可通过关键字,坐标,两种方式指定
// 返回:
// 成功返回0,否则返回-1
MKPlanNode start = new MKPlanNode();
start.name = "尚硅谷";
MKPlanNode end = new MKPlanNode();
end.name = "北京大学";
int code = search.transitSearch("北京", start, end);
if(code ==0){
Toast.makeText(TransitSearchDemo.this,"检索成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(TransitSearchDemo.this,"检索失败",Toast.LENGTH_SHORT).show();
}
}
}
|
定位--MyLocationOverlay-
一个负责显示用户当前位置的Overlay。
在百度地图移动版API中,提供一个重要的特色功能:定位,通过这个功能,能获取到用户当前所在位置。
在程序中,如果使用此功能,必须注册GPS和网络的使用权限。
在获取用户位置时,优先使用GPS进行定位;如果GPS定位没有打开或者没有可用位置信息,则会通过判断网络是否连接(即确认手机是否能上网,不论是连接2G/3G或Wi-Fi网络),如果是,则通过请求百度网络定位服务,返回网络定位结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。
目前系统自带的网络定位服务精度低,且服务不稳定、精度低,并且从未来的趋势看,基站定位是不可控的(移动公司随时可能更改基站编号以垄断定位服务),而Wi-Fi定位则不然,它是一种精度更高、不受管制的定位方法。国内其它使用Wi-Fi定位的地图软件,Wi-Fi定位基本不可用,百度的定位服务量化指标优秀,网络接口返回速度快(服务端每次定位响应时间50毫秒以内),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆盖率98%,在国内处于一枝独秀的地位。
自2.0.0版本开始,MyLocationOverlay只负责显示我的位置,位置数据请使用百度定位SDK获取,将获取的位置数据放在一个LocationData结构中并用该结构设置MyLcationOverlay的数据源,即可创建MyLocationOverlay。
LocationData数据获取
创建监听器:当获取到位置信息时,将信息添加到LocationData中,监听器需要实现BDLocationListener接口,
两个方法需要实现:
1.接收异步返回的定位结果,参数是BDLocation类型参数。
2.接收异步返回的POI查询结果,参数是BDLocation类型参数。
监听的设置:
创建LocationClient对象,注册监听registerLocationListener
设置定位参数(LocationClientOption):定位模式(单次定位,定时定位),返回坐标类型,是否打开GPS等等。
通过LocationClient的start、stop控制定位信息获取,在做中间可以手动发起定位的请求requestLocation
注意
关于经纬度的说明:该经纬度信息是经过加密处理,所以在其它地图工具中测得的经纬度 信息不适合百度的坐标系统。
使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index.html查询地理坐标如果需要在百度地图上显示使用其他坐标系统的位置,请发邮件至mapapi@baidu.com申请坐标转换接口 http://developer.baidu.com/map/geosdk-android-developv3.3.htm option.setOpenGps(true);
option.setAddrType("all");//返回的定位结果包含地址信息
option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000);//设置发起定位请求的间隔时间为5000ms
option.disableCache(true);//禁止启用缓存定位
option.setPoiNumber(5); //最多返回POI个数
option.setPoiDistance(1000); //poi查询距离
option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信
/**
* 定位
*
*/
public class MyLocationOverlayDeom extends BaseActivity {
public LocationClient mLocationClient = null;
public BDLocationListener myListener = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initLocation();
}
@Override
protected void onResume() {
mLocationClient.registerLocationListener(myListener);
mLocationClient.requestLocation();
mLocationClient.start();
super.onResume();
}
@Override
protected void onPause() {
mLocationClient.unRegisterLocationListener(myListener);
mLocationClient.stop();
super.onPause();
}
private void initLocation() {
//1.发起定位请求
mLocationClient = new LocationClient(this);
LocationClientOption option = new LocationClientOption();
option.setOpenGps(true);
option.setAddrType("all");//返回的定位结果包含地址信息
option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
option.setScanSpan(5000);//设置发起定位请求的间隔时间为5000ms
option.disableCache(true);//禁止启用缓存定位
option.setPoiNumber(5); //最多返回POI个数
option.setPoiDistance(1000); //poi查询距离
option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息
mLocationClient.setLocOption(option);
myListener = new MyListener();
mLocationClient.registerLocationListener(myListener);
//2.显示结果
}
class MyListener implements BDLocationListener{
@Override
public void onReceiveLocation(BDLocation location) {
if(location ==null)
return;
MyLocationOverlay locationOverlay = new MyLocationOverlay(mapView);
LocationData arg0 = new LocationData();
arg0.longitude = location.getLongitude();
arg0.latitude = location.getLatitude();
locationOverlay.setData(arg0 );
mapView.getOverlays().clear();
mapView.getOverlays().add(locationOverlay);
mapView.refresh();
//地图移动
controller.animateTo(new GeoPoint((int)(arg0.longitude*1E6), (int)(arg0.latitude*1E6)));
}
@Override
public void onReceivePoi(BDLocation poi) {
}
}
}
|