之前写过一篇关于百度地图开发的blog,主要介绍了百度地图的基本地图的显示。     详见:Android百度地图开发(一)之初体验     下面来看一下地图上覆盖物的添加,以及地理编码和反地理编码。 添加覆盖物     在地图上添加覆盖物,一般需要以下几个步骤:     1.定义坐标点,有可能是一个,有可能是多个(比如:多边形覆盖物)。     2.构造OverlayOpti**(地图覆盖物选型基类)。     3.在地图上添加覆盖物。     4.添加相应的**事件。     在API中可以看到,BaiDuMap类中有一个方法:                               这个方法就是用来在地图上添加覆盖物的。此方法需要一个OverlayOpti**参数。     进而查看这个类。从API中可以看到这是个抽象类,实例化它就必须用它的子类。api中已经把它的所有子类列出来了,分别是:ArcOpti**(弧线形覆盖物选型类)、CircleOpti**(圆形覆盖物选型类)、DotOpti**(圆点覆盖物选型类)、GroundOverlayOpti**(地形图图层选型类)、MarkerOpti**(标注覆盖物选型类)、PolygonOpti**(多边形选型类)、PolylineOpti**(折线选型类)、TextOpti**(文本选型类)。 MarkerOpti**--标注覆盖物。     查看一下API,只需关注返回值是MarkerOpti**的方法即可。  
    此时很简单就可以构造出一个MarkerOpti**对象了。此时需要注意的是:必须添加图标,不然会报错!  
    添加图标的话,就可以使用icon(BitmapDescriptor icon)这个方法:  
   BitmapDescriptor是一个bitmap描述信息类。但是在api中没有看到任何关于构造这个类的方法,只有一个回收对象的方法recycle()。其实在android中,提到bitmap,一般都会跟一个“xxxFactory” 工厂类联系到一起。所以才想百度api中也会有一个关于构造BitmapDescriptor的工厂类。果不其然,看到了一个BitmapDescriptorFactory这个类。          这个类中包括了很多构造bitmap描述信息类的静态方法:  
    OK,有了这一步,就可以构造出一个BitmapDescriptor对象了,进而对marker添加一个图片。 [java] view plaincopy 1.   // 定义marker坐标点   2.           LatLng point = new LatLng(latitude, longitude);   3.      4.           // 构建markerOption,用于在地图上添加marker   5.           OverlayOpti** opti** = new MarkerOpti**()//   6.                   .position(point)// 设置marker的位置   7.                   .icon(bitmap)// 设置marker的图标   8.                   .zIndex(9)// 設置marker的所在層級   9.                   .draggable(true);// 设置手势拖拽   10.          // 在地图上添加marker,并显示   11.          marker1 = (Marker) bdMap.addOverlay(opti**);      接下来对marker添加**事件。一开始我猜想,应该是MarkerOpti**这个类中有一个 “setOnxxx” 这种形式的方法来绑定事件,但是没有找到。最后还是在BaiDuMap这个类下面找到了两个静态的接口。 
  
 
     先看一下点击事件。onMarkerClickListener接口中只有一个函数:  
    此时就需要你添加overlay的返回值(marker)了。实际上BaiDuMap的添加覆盖物的方法addOverlay(OverlayOpti** opti**)的返回值是Overlay。而Overlay恰好是一个好抽象类。  
    它的子类分别是Arc、Circle、Dot、GroundOverlay、Marker、Polygon、Polyline、Text。 正好与verlayOption的子类一一对应。     下面是点击事件的代码: [java] view plaincopy 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方法(按下,拖动,抬起)。 [java] view plaincopy 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.          });      此时需要注意:拖拽事件,需要长按才能响应。 PolygonOpti**(多边形覆盖)     继续查看API,查看这个类中的返回值是PolygonOpti**的方法:  
    设置多边形覆盖物,当然需要多个地图上的点了。正好有一个points(List<LatLng> points)的方法用于设置多边形坐标点列表。OK,此时构造出一个PolygonOpti**就不难了。 [java] view plaincopy 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.          PolygonOpti** polygonOpti** = new PolygonOpti**();   14.          polygonOpti**.points(points);   15.          polygonOpti**.fillColor(0xAAFFFF00);   16.          polygonOpti**.stroke(new Stroke(2, 0xAA00FF00));   17.          Overlay polygon = bdMap.addOverlay(polygonOpti**);   TextOpti**(文字覆盖物)     设置文字覆盖物的时候,需要注意文字的颜色,字体大小,位置等属性:  
 
[java] view plaincopy 1.   LatLng latLng = new LatLng(latitude, longitude);   2.           TextOpti** textOpti** = new TextOpti**();   3.           textOpti**.bgColor(0xAAFFFF00)  //設置文字覆蓋物背景顏色   4.               .fontSize(28)  //设置字体大小   5.               .fontColor(0xFFFF00FF)// 设置字体颜色   6.               .text("我在这里啊!!!!")  //文字内容   7.               .rotate(-30)  //设置文字的旋转角度   8.               .position(latLng);// 设置位置   9.           bdMap.addOverlay(textOpti**);   GroundOverlay(地形图图层覆盖物)     地形图图层可以跟随地图进行平移,伸缩等变换,位于底图和标注图层之家,不会遮挡地图标注的信息。定义这个覆盖物的时候,需要指定宽高。这里百度API提供了两种方法: 1. 指定一个地理坐标(LatLng),在用dimensi**方法来指定宽度和高度。 2. 使用positionFromBounds(LagLngBounds bounds)方法。LatLngBounds方法表示一个地理范围,包括一个东北角坐标和一个西南角坐标,这样也能确定一个矩形。 
    在LatLng中有一个静态内部类Builder--地理范围构造器。  
[java] view plaincopy 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.           GroundOverlayOpti** groundOverlayOpti** = new GroundOverlayOpti**();   8.           groundOverlayOpti**.image(bitmap2);//显示的图片   9.           groundOverlayOpti**.positionFromBounds(bounds);//显示的位置   10.          groundOverlayOpti**.transparency(0.7f);//显示的透明度   11.          bdMap.addOverlay(groundOverlayOpti**);   PolylineOpti**(折线覆盖物)     添加折线与添加多边形的方法大致相同。这里就不多赘述了。 
 
 [java] view plaincopy 1.   CircleOpti** circleOpti** = new CircleOpti**();   2.           circleOpti**.center(new LatLng(latitude, longitude));//设置圆心坐标   3.           circleOpti**.fillColor(0XFFfaa755);//圆的填充颜色   4.           circleOpti**.radius(150);//设置半径   5.           circleOpti**.stroke(new Stroke(5, 0xAA00FF00));//设置边框   6.           bdMap.addOverlay(circleOpti**);   DotOpti**(圆点覆盖物) [java] view plaincopy 1.   DotOpti** dotOpti** = new DotOpti**();   2.           dotOpti**.center(new LatLng(latitude, longitude));//设置圆心坐标   3.           dotOpti**.color(0XFFfaa755);//颜色   4.           dotOpti**.radius(25);//设置半径   5.           bdMap.addOverlay(dotOpti**);   CircleOpti**(圆形(空心)覆盖物) [java] view plaincopy 1.   CircleOpti** circleOpti** = new CircleOpti**();   2.           circleOpti**.center(new LatLng(latitude, longitude));//设置圆心坐标   3.           circleOpti**.fillColor(0XFFfaa755);//圆的填充颜色   4.           circleOpti**.radius(150);//设置半径   5.           circleOpti**.stroke(new Stroke(5, 0xAA00FF00));//设置边框   6.           bdMap.addOverlay(circleOpti**);   ArcOpti**(弧线覆盖物) [java] view plaincopy 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.           ArcOpti** arcOpti** = new ArcOpti**();   5.           arcOpti**.points(pt1, pt2, pt3);//设置弧线的起点、中点、终点坐标   6.           arcOpti**.width(5);//线宽   7.           arcOpti**.color(0xFF000000);   8.           bdMap.addOverlay(arcOpti**);   弹出窗覆盖物     在百度地图上可以添加一种可以弹出的覆盖物,弹出的窗口布局可以自定义。  
 
   API中说的很清楚,第二个构造函数,只能做显示用,没有响应事件。通过第一个构造方法,可以添加点击事件。 [java] view plaincopy 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对象,就可以通过反地理编码得到具体的地址了。     实现起来也比较简单: [java] view plaincopy 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();    
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/43377545 |