百度地图开发(二)之添加覆盖物 + 地理编码和反地理编码

  转载请注明出处:http://blog.csdn.net/crazy1235/article/details/43377545

    之前写过一篇关于百度地图开发的blog,主要介绍了百度地图的基本地图的显示。

    详见:Android百度地图开发(一)之初体验

    下面来看一下地图上覆盖物的添加,以及地理编码和反地理编码。

添加覆盖物

    在地图上添加覆盖物,一般需要以下几个步骤:

    1. 定义坐标点,有可能是一个,有可能是多个(比如:多边形覆盖物)。

    2. 构造OverlayOptions(地图覆盖物选型基类)。

    3. 在地图上添加覆盖物。

    4. 添加相应的监听事件。

    在API中可以看到,BaiDuMap类中有一个方法:

这个方法就是用来在地图上添加覆盖物的。此方法需要一个OverlayOptions参数。

    进而查看这个类。从API中可以看到这是个抽象类,实例化它就必须用它的子类。api中已经把它的所有子类列出来了,分别是:ArcOptions(弧线形覆盖物选型类)、CircleOptions(圆形覆盖物选型类)、DotOptions(圆点覆盖物选型类)、GroundOverlayOptions(地形图图层选型类)、MarkerOptions(标注覆盖物选型类)、PolygonOptions(多边形选型类)、PolylineOptions(折线选型类)、TextOptions(文本选型类)。

MarkerOptions--标注覆盖物。

    查看一下API,只需关注返回值是MarkerOptions的方法即可。




    此时很简单就可以构造出一个MarkerOptions对象了。此时需要注意的是:必须添加图标,不然会报错!


    添加图标的话,就可以使用icon(BitmapDescriptor icon)这个方法:


    BitmapDescriptor是一个bitmap描述信息类。但是在api中没有看到任何关于构造这个类的方法,只有一个回收对象的方法recycle()。其实在android中,提到bitmap,一般都会跟一个“xxxFactory” 工厂类联系到一起。所以才想百度api中也会有一个关于构造BitmapDescriptor的工厂类。果不其然,看到了一个BitmapDescriptorFactory这个类。    

    这个类中包括了很多构造bitmap描述信息类的静态方法:


    OK,有了这一步,就可以构造出一个BitmapDescriptor对象了,进而对marker添加一个图片。

  1. // 定义marker坐标点  
  2.         LatLng point = new LatLng(latitude, longitude);  
  3.   
  4.         // 构建markerOption,用于在地图上添加marker  
  5.         OverlayOptions options = new MarkerOptions()//  
  6.                 .position(point)// 设置marker的位置  
  7.                 .icon(bitmap)// 设置marker的图标  
  8.                 .zIndex(9)// 設置marker的所在層級  
  9.                 .draggable(true);// 设置手势拖拽  
  10.         // 在地图上添加marker,并显示  
  11.         marker1 = (Marker) bdMap.addOverlay(options);  
    接下来对marker添加监听事件。一开始我猜想,应该是MarkerOptions这个类中有一个 “setOnxxx” 这种形式的方法来绑定事件,但是没有找到。最后还是在BaiDuMap这个类下面找到了两个静态的接口。

    先看一下点击事件。onMarkerClickListener接口中只有一个函数:


    此时就需要你添加overlay的返回值(marker)了。实际上BaiDuMap的添加覆盖物的方法addOverlay(OverlayOptions options)的返回值是Overlay。而Overlay恰好是一个好抽象类。


    它的子类分别是Arc、Circle、Dot、GroundOverlay、Marker、Polygon、Polyline、Text。

正好与verlayOption的子类一一对应。

    下面是点击事件的代码:

  1. bdMap.setOnMapClickListener(new OnMapClickListener() {  
  2.   
  3.             @Override  
  4.             public boolean onMapPoiClick(MapPoi arg0) {  
  5.                 return false;  
  6.             }  
  7.   
  8.             @Override  
  9.             public void onMapClick(LatLng latLng) {  
  10.                 displayInfoWindow(latLng);  
  11.             }  
  12.         });  
    此时有一个问题,我得到了LatLng地理坐标这个对象了,怎么得到正常的地理信息呢(xx省xx市)?不要着急,慢慢往后看, 反地理编码会解决这个问题的!
    下面看一下, 拖拽事件(onMarkerDragListener):


    这三个方法有点类似于onTouch方法(按下,拖动,抬起)。

  1. bdMap.setOnMarkerDragListener(new OnMarkerDragListener() {  
  2.             @Override  
  3.             public void onMarkerDragStart(Marker arg0) {  
  4.   
  5.             }  
  6.   
  7.             @Override  
  8.             public void onMarkerDragEnd(Marker arg0) {  
  9.                 Toast.makeText(  
  10.                         MainActivity.this,  
  11.                         "拖拽结束,新位置:" + arg0.getPosition().latitude + ", "  
  12.                                 + arg0.getPosition().longitude,  
  13.                         Toast.LENGTH_LONG).show();  
  14.                 reverseGeoCode(arg0.getPosition());  
  15.             }  
  16.   
  17.             @Override  
  18.             public void onMarkerDrag(Marker arg0) {  
  19.   
  20.             }  
  21.         });  
    此时需要注意:拖拽事件,需要长按才能响应。

PolygonOptions(多边形覆盖)

    继续查看API,查看这个类中的返回值是PolygonOptions的方法:



    设置多边形覆盖物,当然需要多个地图上的点了。正好有一个points(List<LatLng> points)的方法用于设置多边形坐标点列表。OK,此时构造出一个PolygonOptions就不难了。

  1. LatLng pt1 = new LatLng(latitude + 0.02, longitude);  
  2.         LatLng pt2 = new LatLng(latitude, longitude - 0.03);  
  3.         LatLng pt3 = new LatLng(latitude - 0.02, longitude - 0.01);  
  4.         LatLng pt4 = new LatLng(latitude - 0.02, longitude + 0.01);  
  5.         LatLng pt5 = new LatLng(latitude, longitude + 0.03);  
  6.         List<LatLng> points = new ArrayList<LatLng>();  
  7.         points.add(pt1);  
  8.         points.add(pt2);  
  9.         points.add(pt3);  
  10.         points.add(pt4);  
  11.         points.add(pt5);  
  12.         //  
  13.         PolygonOptions polygonOptions = new PolygonOptions();  
  14.         polygonOptions.points(points);  
  15.         polygonOptions.fillColor(0xAAFFFF00);  
  16.         polygonOptions.stroke(new Stroke(20xAA00FF00));  
  17.         Overlay polygon = bdMap.addOverlay(polygonOptions);  

TextOptions(文字覆盖物)

    设置文字覆盖物的时候,需要注意文字的颜色,字体大小,位置等属性:



  1. LatLng latLng = new LatLng(latitude, longitude);  
  2.         TextOptions textOptions = new TextOptions();  
  3.         textOptions.bgColor(0xAAFFFF00)  //設置文字覆蓋物背景顏色  
  4.             .fontSize(28)  //设置字体大小  
  5.             .fontColor(0xFFFF00FF)// 设置字体颜色  
  6.             .text("我在这里啊!!!!")  //文字内容  
  7.             .rotate(-30)  //设置文字的旋转角度  
  8.             .position(latLng);// 设置位置  
  9.         bdMap.addOverlay(textOptions);  

GroundOverlay(地形图图层覆盖物)

    地形图图层可以跟随地图进行平移,伸缩等变换,位于底图和标注图层之家,不会遮挡地图标注的信息。定义这个覆盖物的时候,需要指定宽高。这里百度API提供了两种方法:

1. 指定一个地理坐标(LatLng),在用dimensions方法来指定宽度和高度。

2. 使用positionFromBounds(LagLngBounds bounds)方法。LatLngBounds方法表示一个地理范围,包括一个东北角坐标和一个西南角坐标,这样也能确定一个矩形。
    在LatLng中有一个静态内部类Builder--地理范围构造器。


  1. LatLng southwest = new LatLng(latitude - 0.01, longitude - 0.012);//西南  
  2.         LatLng northeast = new LatLng(latitude + 0.01, longitude + 0.012);//东北  
  3.         LatLngBounds bounds = new LatLngBounds.Builder().include(southwest)  
  4.                 .include(northeast).build();//得到一个地理范围对象  
  5.         BitmapDescriptor bitmap2 = BitmapDescriptorFactory  
  6.             .fromResource(R.drawable.csdn_blog);  
  7.         GroundOverlayOptions groundOverlayOptions = new GroundOverlayOptions();  
  8.         groundOverlayOptions.image(bitmap2);//显示的图片  
  9.         groundOverlayOptions.positionFromBounds(bounds);//显示的位置  
  10.         groundOverlayOptions.transparency(0.7f);//显示的透明度  
  11.         bdMap.addOverlay(groundOverlayOptions);  

PolylineOptions(折线覆盖物)

    添加折线与添加多边形的方法大致相同。这里就不多赘述了。

  1. CircleOptions circleOptions = new CircleOptions();  
  2.         circleOptions.center(new LatLng(latitude, longitude));//设置圆心坐标  
  3.         circleOptions.fillColor(0XFFfaa755);//圆的填充颜色  
  4.         circleOptions.radius(150);//设置半径  
  5.         circleOptions.stroke(new Stroke(50xAA00FF00));//设置边框  
  6.         bdMap.addOverlay(circleOptions);  

DotOptions(圆点覆盖物)

  1. DotOptions dotOptions = new DotOptions();  
  2.         dotOptions.center(new LatLng(latitude, longitude));//设置圆心坐标  
  3.         dotOptions.color(0XFFfaa755);//颜色  
  4.         dotOptions.radius(25);//设置半径  
  5.         bdMap.addOverlay(dotOptions);  

CircleOptions(圆形(空心)覆盖物)

  1. CircleOptions circleOptions = new CircleOptions();  
  2.         circleOptions.center(new LatLng(latitude, longitude));//设置圆心坐标  
  3.         circleOptions.fillColor(0XFFfaa755);//圆的填充颜色  
  4.         circleOptions.radius(150);//设置半径  
  5.         circleOptions.stroke(new Stroke(50xAA00FF00));//设置边框  
  6.         bdMap.addOverlay(circleOptions);  

ArcOptions(弧线覆盖物)

  1. LatLng pt1 = new LatLng(latitude, longitude - 0.01);  
  2.         LatLng pt2 = new LatLng(latitude - 0.01, longitude - 0.01);  
  3.         LatLng pt3 = new LatLng(latitude, longitude + 0.01);  
  4.         ArcOptions arcOptions = new ArcOptions();  
  5.         arcOptions.points(pt1, pt2, pt3);//设置弧线的起点、中点、终点坐标  
  6.         arcOptions.width(5);//线宽  
  7.         arcOptions.color(0xFF000000);  
  8.         bdMap.addOverlay(arcOptions);  

弹出窗覆盖物

    在百度地图上可以添加一种可以弹出的覆盖物,弹出的窗口布局可以自定义。



    API中说的很清楚,第二个构造函数,只能做显示用,没有响应事件。通过第一个构造方法,可以添加点击事件。

  1. /** 
  2.      * 显示弹出窗口覆盖物 
  3.      */  
  4.     private void displayInfoWindow(final LatLng latLng) {  
  5.         // 创建infowindow展示的view  
  6.         Button btn = new Button(getApplicationContext());  
  7.         btn.setBackgroundResource(R.drawable.popup);  
  8.         btn.setText("点我点我~");  
  9.         BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory  
  10.                 .fromView(btn);  
  11.         // infowindow点击事件  
  12.         OnInfoWindowClickListener infoWindowClickListener = new OnInfoWindowClickListener() {  
  13.             @Override  
  14.             public void onInfoWindowClick() {  
  15.                 reverseGeoCode(latLng);  
  16.                 //隐藏InfoWindow  
  17.                 bdMap.hideInfoWindow();  
  18.             }  
  19.         };  
  20.         // 创建infowindow  
  21.         InfoWindow infoWindow = new InfoWindow(bitmapDescriptor, latLng, -47,  
  22.                 infoWindowClickListener);  
  23.   
  24.         // 显示InfoWindow  
  25.         bdMap.showInfoWindow(infoWindow);  
  26.     }  

地理编码与反地理编码

    地理编码指的是将地理信息转化成坐标关系的过程。分为正向的和反向的编码。

正向的就是指将地址信息转成坐标点的过程。比如:北京市天安门--> (123.23111, 123.23231)(我瞎写的)。反地理编码就是将地理坐标转换成具体的地址信息,通过百度的坐标定位引擎,插叙出坐标对应的物体所在的行政区划、街道等信息。

    所以我们,在地图上点击的时候,或者拖动marker的时候得到的LatLng对象,就可以通过反地理编码得到具体的地址了。

    实现起来也比较简单:

  1. // 创建地理编码检索实例  
  2.         GeoCoder geoCoder = GeoCoder.newInstance();  
  3.         //  
  4.         OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {  
  5.             // 反地理编码查询结果回调函数  
  6.             @Override  
  7.             public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {  
  8.                 if (result == null  
  9.                         || result.error != SearchResult.ERRORNO.NO_ERROR) {  
  10.                     // 没有检测到结果  
  11.                     Toast.makeText(MainActivity.this"抱歉,未能找到结果",  
  12.                             Toast.LENGTH_LONG).show();  
  13.                 }  
  14.                 Toast.makeText(MainActivity.this,  
  15.                         "位置:" + result.getAddress(), Toast.LENGTH_LONG)  
  16.                         .show();  
  17.             }  
  18.   
  19.             // 地理编码查询结果回调函数  
  20.             @Override  
  21.             public void onGetGeoCodeResult(GeoCodeResult result) {  
  22.                 if (result == null  
  23.                         || result.error != SearchResult.ERRORNO.NO_ERROR) {  
  24.                     // 没有检测到结果  
  25.                 }  
  26.             }  
  27.         };  
  28.         // 设置地理编码检索监听者  
  29.         geoCoder.setOnGetGeoCodeResultListener(listener);  
  30.         //  
  31.         geoCoder.reverseGeoCode(new ReverseGeoCodeOption().location(latLng));  
  32.         // 释放地理编码检索实例  
  33.         // geoCoder.destroy();  

demo下载:

    地址:http://download.csdn.net/detail/crazy1235/8415513

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值