百度地图的简单开发之方向传感器实现定位功能

来源:互联网 发布:车辆mod修改软件 编辑:程序博客网 时间:2024/05/19 11:18

今天我们来谈下百度地图的定位功能,在此之前我已经将百度地图的基本地图大概说了下,其实百度地图的基本功能还有很多的内容。感兴趣的可以到百度地图的开发者的官网看看。今天就开始来讲下百度地图中的定位功能。

今天所讲的百度地图所涉及的内容主要有:基本定位的实现,自定义定位图标,结合方向传感器定位,选择定位中的几种模式(罗盘模式,普通模式,跟随模式)。

一、基本定位的实现:

所谓定位无非就是获取到一个地方所处地球的经纬度坐标,这个反映到地图中就是一个点。但是怎么去实现一个定位呢??

首先,需要去创建一个定位客户端对象,然后给这个定位客户端对象设置监听器,并且每隔1s中就去请求一次定位,这就是所谓实时监听定位信息的变化,也就是位置发生变化,那么所处的经纬度就变化了,通过经纬度值可以得到一个经纬度对象,通过这个经纬度对象(实际上就是对应一个点),反映在地图上点的位置发生了变化。这样一来定位也是一个高耗的工作,所以我们也需要管理定位的生命周期,当我们开启应用就去开启定位,关闭应用就得关闭定位的请求。记住一点就是使用定位功能还得在AndroidManifest.xml配置一个Service。

注册service:

[html] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <service  
  2.        android:name="com.baidu.location.f"  
  3.        android:enabled="true"  
  4.        android:process=":remote" >  
  5.        <intent-filter>  
  6.            <action android:name="com.baidu.location.service_v2.2" >  
  7.            </action>  
  8.        </intent-filter>  
  9.    </service>  

将定位的生命周期和Activity的生命周期进行绑定:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. protected void onStart() {  
  3.  myLocationClient.start();//将定位与Activity生命周期进行绑定,开启定位  
  4.  super.onStart();  
  5. }  
  6. @Override  
  7. protected void onStop() {  
  8.  myLocationClient.stop();//将定位与Activity生命周期进行绑定,关闭定位  
  9.  super.onStop();  
  10. }  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1.    

初始化定位功能:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. <pre class="java" name="code">/** 
  2.      * @author Mikyou 
  3.      * 初始化定位功能 
  4.      * */  
  5.     private void initMapLocation() {  
  6.         myLocationClient=new LocationClient(this);//创建一个定位客户端对象  
  7.         myListener=new MyLocationListener();//创建一个定位事件监听对象  
  8.         myLocationClient.registerLocationListener(myListener);//并给该定位客户端对象注册监听事件  
  9.         //对LocaitonClient进行一些必要的设置  
  10.         LocationClientOption option=new LocationClientOption();  
  11.         option.setCoorType("bd09ll");//设置坐标的类型  
  12.         option.setIsNeedAddress(true);//返回当前的位置信息,如果不设置为true,默认就为false,就无法获得位置的信息  
  13.         option.setOpenGps(true);//打开GPS  
  14.         option.setScanSpan(1000);//表示1s中进行一次定位请求  
  15.         myLocationClient.setLocOption(option);  
  16.         useLocationOrientationListener();//调用方向传感器  
  17.     }  
  18.     /** 
  19.      * @author Mikyou 
  20.      * 定位结合方向传感器,从而可以实时监测到X轴坐标的变化,从而就可以检测到 
  21.      * 定位图标方向变化,只需要将这个动态变化的X轴的坐标更新myCurrentX值, 
  22.      * 最后在MyLocationData data.driection(myCurrentX); 
  23.      * */  
  24.     private void useLocationOrientationListener() {  
  25.         myOrientationListener=new MyOrientationListener(MainActivity.this);  
  26.         myOrientationListener.setMyOrientationListener(new onOrientationListener() {  
  27.             @Override  
  28.             public void onOrientationChanged(float x) {//监听方向的改变,方向改变时,需要得到地图上方向图标的位置  
  29.                 myCurrentX=x;  
  30.                 System.out.println("方向:x---->"+x);  
  31.             }  
  32.         });       
  33.     }  

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.      * @author zhongqihong 
  3.      * 获取位置信息的客户端对象的监听器类MyLocationListener 
  4.      * */  
  5.     class MyLocationListener implements BDLocationListener{  
  6.   
  7.         @Override  
  8.         public void onReceiveLocation(BDLocation location) {  
  9.             //得到一个MyLocationData对象,需要将BDLocation对象转换成MyLocationData对象  
  10.             MyLocationData data=new MyLocationData.Builder()  
  11.             .accuracy(location.getRadius())//精度半径  
  12.             .direction(myCurrentX)//myCurrentX就是通过方向传感器监听得到的值来设置定位的方向  
[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. .latitude(location.getLatitude())//经度  
  2. .longitude(location.getLongitude())//纬度  
  3. .build();  
  4. myBaiduMap.setMyLocationData(data);  
  5. //配置自定义的定位图标,需要在紧接着setMyLocationData后面设置  
  6. //调用自定义定位图标  
  7. changeLocationIcon();  
  8. latitude=location.getLatitude();//得到当前的经度  
  9. longtitude=location.getLongitude();//得到当前的纬度  
  10. //toast("经度:"+latitude+"     纬度:"+longtitude);  
  11. if (isFirstIn) {//表示用户第一次打开,就定位到用户当前位置,即此时只要将地图的中心点设置为用户此时的位置即可  
  12.     getMyLatestLocation(latitude,longtitude);//获得最新定位的位置,并且地图的中心点设置为我的位置  
  13.     isFirstIn=false;//表示第一次才会去定位到中心点  
  14.     locationTextString=""+location.getAddrStr();//这里得到地址必须需要在设置LocationOption的时候需要设置isNeedAddress为true;  
  15.     toast(locationTextString);  
  16.     locationText.setText(locationTextString);  
  17. }  

二、修改自定义图标

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @author zhongqihong 
  3.  * 自定义定位图标 
  4.  * */  
  5. private void changeLocationIcon() {  
  6.     myBitmapLocation=BitmapDescriptorFactory  
  7.             .fromResource(R.drawable.ic_launcher);//引入自己的图标  
  8.     if (isFirstIn) {//表示第一次定位显示普通模式  
  9.         MyLocationConfiguration config=new   
  10.                 MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  11.         myBaiduMap.setMyLocationConfigeration(config);  
  12.     }             
  13. }  

获取最新的位置

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @author zhongqihong 
  3.  * 获得最新定位的位置,并且地图的中心点设置为我的位置 
  4.  * */  
  5. private void getMyLatestLocation(double lat,double lng) {  
  6.     LatLng latLng=new LatLng(lat, lng);//创建一个经纬度对象,需要传入当前的经度和纬度两个整型值参数  
  7.     MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);//创建一个地图最新更新的状态对象,需要传入一个最新经纬度对象  
  8.     myBaiduMap.animateMapStatus(msu);//表示使用动画的效果传入,通过传入一个地图更新状态对象,然后利用百度地图对象来展现和还原那个地图更新状态,即此时的地图显示就为你现在的位置  
  9. }  

三、结合方向传感器来控制定位图标方向,使得整个图标会随着手机方向的转动而转动。但是如果去实时判断手机在转动呢?以及手机转动的方向和角度是多少呢?这时候就需要手机中内置的方向传感器,该方向传感器可以监测到手机在X,Y,Z轴方向上偏移量,但是我们一般都是在一个平面内转动,也就是一个用于在东南西北方向转动,所以只需要用方向传感器去实时监测X轴方向的偏移量即可,并用一个变量记录一下当前偏移值,当当前偏移值和上一次偏移值的绝对值超过一个临界值,就可以判定方向发生改变,并把该方向的偏移量myCurrent设置给MyLocationData对象即可。但是方向传感器的开启和关闭,还需要和定位服务生命保持一致,如果定位都关闭了,那就没有必要去开启方向传感器了,既然定位生命周期和Activity绑定在一起,所以也只需要把方向传感器的生命周期和Activity生命周期绑定在一起即可。

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. protected void onDestroy() {  
  2.         super.onDestroy();  
  3.         //在Activity执行onDestory时执行mapView(地图)生命周期管理  
  4.         myMapView.onDestroy();  
  5.     }  
  6.     @Override  
  7.     protected void onStart() {//当Activity调用onStart方法,开启定位以及开启方向传感器,即将定位的服务、方向传感器和Activity生命周期绑定在一起  
  8.         myBaiduMap.setMyLocationEnabled(true);//开启允许定位  
  9.         if (!myLocationClient.isStarted()) {  
  10.             myLocationClient.start();//开启定位  
  11.         }  
  12.         //开启方向传感器  
  13.         myOrientationListener.start();  
  14.         super.onStart();  
  15.     }  
  16.     @Override  
  17.     protected void onStop() {//当Activity调用onStop方法,关闭定位以及关闭方向传感器  
  18.         myBaiduMap.setMyLocationEnabled(false);  
  19.         myLocationClient.stop();//关闭定位  
  20.         myOrientationListener.stop();//关闭方向传感器  
  21.         super.onStop();  
  22.     }  
  23.     @Override  
  24.     protected void onResume() {  
  25.         // TODO Auto-generated method stub  
  26.         super.onResume();  
  27.         //在Activity执行onResume是执行MapView(地图)生命周期管理  
  28.         myMapView.onResume();  
  29.     }  
  30.     @Override  
  31.     protected void onPause() {  
  32.         // TODO Auto-generated method stub  
  33.         super.onPause();  
  34.         myMapView.onPause();  
  35.     }  

方向传感器监听器

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.mikyou.sensor;  
  2.   
  3. import android.content.Context;  
  4. import android.hardware.Sensor;  
  5. import android.hardware.SensorEvent;  
  6. import android.hardware.SensorEventListener;  
  7. import android.hardware.SensorManager;  
  8.   
  9. public class MyOrientationListener implements SensorEventListener{  
  10.     private SensorManager mySensorManager;  
  11.     private Sensor mySensor;  
  12.     private Context myContext;   
  13.     private float lastX;  
  14.     private onOrientationListener myOrientationListener;  
  15.     public void start(){//开启方向传感器  
  16.         //先通过系统服务来得到传感器管理对象mySensorManager  
  17.         mySensorManager=(SensorManager) myContext.getSystemService(Context.SENSOR_SERVICE);  
  18.         if (mySensorManager!=null) {//如果传感器管理对象不为空,则可以通过传感器管理对象来获得方向传感器对象  
  19.             //获得方向传感器对象  
  20.             mySensor=mySensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);  
  21.         }  
  22.         if (mySensor!=null) {//如果方向传感器不为空,则给该方向传感器注册监听事件  
  23.             mySensorManager.registerListener(this, mySensor, SensorManager.SENSOR_DELAY_UI);  
  24.         }  
  25.     }  
  26.     public void stop(){//解除注册方向传感器监听事件  
  27.         mySensorManager.unregisterListener(this);  
  28.     }  
  29.     public MyOrientationListener(Context myContext) {//方向传感器的一个构造器  
  30.         super();  
  31.         this.myContext = myContext;  
  32.     }  
  33.     @Override  
  34.     public void onAccuracyChanged(Sensor sensor, int accuracy) {  
  35.         // TODO Auto-generated method stub  
  36.     }  
  37.     //监听方向发生变化  
  38.     @Override  
  39.     public void onSensorChanged(SensorEvent event) {//精度发生改变的时候  
  40.         if (event.sensor.getType()==Sensor.TYPE_ORIENTATION) {//如果是方向传感器  
  41.             float x=event.values[SensorManager.DATA_X];//获得传感器的X轴的坐标,可以返回3个值,即X轴的坐标,Y轴坐标,Z轴坐标,我们只需要X轴坐标  
  42.             if (Math.abs(x-lastX)>1.0) {//对比本次的X坐标的变化比上一次的变化差大于1.0就说明方向发生改变  
  43.                 if (myOrientationListener!=null) {//说明主界面已经注册了事件,即不为空,然后产生一个回调将实时变化X轴的坐标传入  
  44.                     //通过一个回调方法,通知主界面去更新UI  
  45.                     myOrientationListener.onOrientationChanged(lastX);//就需要把上一次的X轴坐标传入,在MainActivity中的回调方法中去获取即可  
  46.                 }  
  47.             }  
  48.             lastX=x;  
  49.         }  
  50.     }  
  51.   
  52.     public void setMyOrientationListener(onOrientationListener myOrientationListener) {  
  53.         this.myOrientationListener = myOrientationListener;  
  54.     }  
  55.     //写一个接口实现方向改变的监听产生的回调  
  56.     public interface onOrientationListener{  
  57.         void onOrientationChanged(float x);//回调的方法  
  58.     }  
  59. }  

四、选择定位中的几种模式(罗盘模式,普通模式,跟随模式):

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * @author mikyou 
  3.  * 选择定位的模式 
  4.  * */  
  5. private void selectLocation() {  
  6.     AlertDialog.Builder builder2=new AlertDialog.Builder(this);  
  7.     builder2.setIcon(R.drawable.track_collect_running)  
  8.     .setTitle("请选择定位的模式")  
  9.     .setItems(LocationModeString, new DialogInterface.OnClickListener() {  
  10.   
  11.         @Override  
  12.         public void onClick(DialogInterface dialog, int which) {  
  13.             String mode=LocationModeString[which];  
  14.             if (mode.equals("罗盘模式")) {  
  15.                 MyLocationConfiguration config=new   
  16.                         MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);  
  17.                 myBaiduMap.setMyLocationConfigeration(config);  
  18.             }else if (mode.equals("跟随模式")) {  
  19.                 MyLocationConfiguration config=new   
  20.                         MyLocationConfiguration(LocationMode.FOLLOWING, true, myBitmapLocation);  
  21.                 myBaiduMap.setMyLocationConfigeration(config);  
  22.             }else if (mode.equals("普通模式")) {  
  23.                 MyLocationConfiguration config=new   
  24.                         MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  25.                 myBaiduMap.setMyLocationConfigeration(config);  
  26.             }else if (mode.equals("3D俯视模式(已关闭)")||mode.equals("3D俯视模式(已打开)")) {  
  27.                 if (mode.equals("3D俯视模式(已打开)")) {  
  28.                     UiSettings   mUiSettings = myBaiduMap.getUiSettings();  
  29.                     mUiSettings.setCompassEnabled(true);  
  30.                     LocationModeString[which]="3D俯视模式(已关闭)";  
  31.                     toast("3D模式已关闭");  
  32.                 }else{  
  33.                     MyLocationConfiguration config=new   
  34.                             MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);  
  35.                     myBaiduMap.setMyLocationConfigeration(config);  
  36.                     MyLocationConfiguration config2=new   
  37.                             MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  38.                     myBaiduMap.setMyLocationConfigeration(config2);  
  39.                     LocationModeString[which]="3D俯视模式(已打开)";  
  40.                     toast("3D模式已打开");  
  41.                 }  
  42.             }  
  43.         }  
  44.     }).show();        
  45. }  

最后附上整个Activity源码:

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package com.mikyou.maptest;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import android.app.Activity;  
  7. import android.app.AlertDialog;  
  8. import android.content.DialogInterface;  
  9. import android.graphics.Color;  
  10. import android.graphics.Point;  
  11. import android.os.Bundle;  
  12. import android.view.View;  
  13. import android.view.View.OnClickListener;  
  14. import android.view.Window;  
  15. import android.widget.ImageView;  
  16. import android.widget.LinearLayout;  
  17. import android.widget.TextView;  
  18. import android.widget.Toast;  
  19. import android.widget.ZoomControls;  
  20.   
  21. import com.baidu.location.BDLocation;  
  22. import com.baidu.location.BDLocationListener;  
  23. import com.baidu.location.LocationClient;  
  24. import com.baidu.location.LocationClientOption;  
  25. import com.baidu.mapapi.SDKInitializer;  
  26. import com.baidu.mapapi.map.BaiduMap;  
  27. import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;  
  28. import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;  
  29. import com.baidu.mapapi.map.BitmapDescriptor;  
  30. import com.baidu.mapapi.map.BitmapDescriptorFactory;  
  31. import com.baidu.mapapi.map.InfoWindow;  
  32. import com.baidu.mapapi.map.MapPoi;  
  33. import com.baidu.mapapi.map.MapStatusUpdate;  
  34. import com.baidu.mapapi.map.MapStatusUpdateFactory;  
  35. import com.baidu.mapapi.map.MapView;  
  36. import com.baidu.mapapi.map.Marker;  
  37. import com.baidu.mapapi.map.MarkerOptions;  
  38. import com.baidu.mapapi.map.MyLocationConfiguration;  
  39. import com.baidu.mapapi.map.UiSettings;  
  40. import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;  
  41. import com.baidu.mapapi.map.MyLocationData;  
  42. import com.baidu.mapapi.map.OverlayOptions;  
  43. import com.baidu.mapapi.model.LatLng;  
  44. import com.mikyou.beans.MarkInfo;  
  45. import com.mikyou.sensor.MyOrientationListener;  
  46. import com.mikyou.sensor.MyOrientationListener.onOrientationListener;  
  47.   
  48.   
  49.   
  50. public class MainActivity extends Activity implements OnClickListener,OnMapClickListener,OnMarkerClickListener{  
  51.     private MapView mapView=null;  
  52.     private BaiduMap myBaiduMap=null;  
  53.     //修改默认View相关  
  54.     private View defaultBaiduMapScaleButton,defaultBaiduMapLogo,defaultBaiduMapScaleUnit;  
  55.     //基本地图类型,实时交通,及覆盖物相关  
  56.     private ImageView mapRoad;  
  57.     private ImageView mapType;  
  58.     private String[] types={"普通地图","卫星地图","热力地图(已关闭)"};  
  59.     private float current;//放大或缩小的比例系数  
  60.     private ImageView expandMap;//放大地图控件  
  61.     private ImageView narrowMap;//缩小地图  
  62.     private ImageView addMarks;//添加覆盖物控件  
  63.     private BitmapDescriptor myMarks;  
  64.     private List<MarkInfo> markInfoList;  
  65.     private LinearLayout markLayout;  
  66.     //定位相关  
  67.     private LocationClient myLocationClient;//专门用于监听位置的客户端对象  
  68.     private MyLocationListener myListener;//定位监听器对象  
  69.     private double latitude,longtitude;//经纬度  
  70.     private BitmapDescriptor myBitmapLocation;//定位的自定义图标  
  71.     private boolean isFirstIn=true;//设置一个标记,查看是否是第一次  
  72.     private String locationTextString;//定义的位置的信息  
  73.     private TextView locationText;//显示定位信息的TextView控件  
  74.     private MyOrientationListener myOrientationListener;  
  75.     private float myCurrentX;  
  76.     private ImageView selectLocationMode;  
  77.     private String[] LocationModeString={"罗盘模式","普通模式","跟随模式","3D俯视模式(已关闭)"};  
  78.     @Override  
  79.     protected void onCreate(Bundle savedInstanceState) {  
  80.         super.onCreate(savedInstanceState);  
  81.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  82.         SDKInitializer.initialize(getApplicationContext());  
  83.         setContentView(R.layout.activity_main);  
  84.         mapView=(MapView) findViewById(R.id.map_view_test);  
  85.         initMapView();  
  86.         changeDefaultBaiduMapView();  
  87.         initMapLocation();  
  88.     }  
  89.     /** 
  90.      * @author Mikyou 
  91.      * 初始化定位功能 
  92.      * */  
  93.     private void initMapLocation() {  
  94.         myLocationClient=new LocationClient(this);//创建一个定位客户端对象  
  95.         myListener=new MyLocationListener();//创建一个定位事件监听对象  
  96.         myLocationClient.registerLocationListener(myListener);//并给该定位客户端对象注册监听事件  
  97.         //对LocaitonClient进行一些必要的设置  
  98.         LocationClientOption option=new LocationClientOption();  
  99.         option.setCoorType("bd09ll");//设置坐标的类型  
  100.         option.setIsNeedAddress(true);//返回当前的位置信息,如果不设置为true,默认就为false,就无法获得位置的信息  
  101.         option.setOpenGps(true);//打开GPS  
  102.         option.setScanSpan(1000);//表示1s中进行一次定位请求  
  103.         myLocationClient.setLocOption(option);  
  104.         useLocationOrientationListener();//调用方向传感器  
  105.     }  
  106.     /** 
  107.      * @author Mikyou 
  108.      * 定位结合方向传感器,从而可以实时监测到X轴坐标的变化,从而就可以检测到 
  109.      * 定位图标方向变化,只需要将这个动态变化的X轴的坐标更新myCurrentX值, 
  110.      * 最后在MyLocationData data.driection(myCurrentX); 
  111.      * */  
  112.     private void useLocationOrientationListener() {  
  113.         myOrientationListener=new MyOrientationListener(MainActivity.this);  
  114.         myOrientationListener.setMyOrientationListener(new onOrientationListener() {  
  115.             @Override  
  116.             public void onOrientationChanged(float x) {//监听方向的改变,方向改变时,需要得到地图上方向图标的位置  
  117.                 myCurrentX=x;  
  118.                 System.out.println("方向:x---->"+x);  
  119.             }  
  120.         });       
  121.     }  
  122.     /** 
  123.      * @author zhongqihong 
  124.      * 获取位置信息的客户端对象的监听器类MyLocationListener 
  125.      * */  
  126.     class MyLocationListener implements BDLocationListener{  
  127.   
  128.         @Override  
  129.         public void onReceiveLocation(BDLocation location) {  
  130.             //得到一个MyLocationData对象,需要将BDLocation对象转换成MyLocationData对象  
  131.             MyLocationData data=new MyLocationData.Builder()  
  132.             .accuracy(location.getRadius())//精度半径  
  133.             .direction(myCurrentX)//方向  
  134.             .latitude(location.getLatitude())//经度  
  135.             .longitude(location.getLongitude())//纬度  
  136.             .build();  
  137.             myBaiduMap.setMyLocationData(data);  
  138.             //配置自定义的定位图标,需要在紧接着setMyLocationData后面设置  
  139.             //调用自定义定位图标  
  140.             changeLocationIcon();  
  141.             latitude=location.getLatitude();//得到当前的经度  
  142.             longtitude=location.getLongitude();//得到当前的纬度  
  143.             //toast("经度:"+latitude+"     纬度:"+longtitude);  
  144.             if (isFirstIn) {//表示用户第一次打开,就定位到用户当前位置,即此时只要将地图的中心点设置为用户此时的位置即可  
  145.                 getMyLatestLocation(latitude,longtitude);//获得最新定位的位置,并且地图的中心点设置为我的位置  
  146.                 isFirstIn=false;//表示第一次才会去定位到中心点  
  147.                 locationTextString=""+location.getAddrStr();//这里得到地址必须需要在设置LocationOption的时候需要设置isNeedAddress为true;  
  148.                 toast(locationTextString);  
  149.                 locationText.setText(locationTextString);  
  150.             }  
  151.         }  
  152.   
  153.           
  154.   
  155.   
  156.     }  
  157.     /** 
  158.      * @author zhongqihong 
  159.      * 获得最新定位的位置,并且地图的中心点设置为我的位置 
  160.      * */  
  161.     private void getMyLatestLocation(double lat,double lng) {  
  162.         LatLng latLng=new LatLng(lat, lng);//创建一个经纬度对象,需要传入当前的经度和纬度两个整型值参数  
  163.         MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);//创建一个地图最新更新的状态对象,需要传入一个最新经纬度对象  
  164.         myBaiduMap.animateMapStatus(msu);//表示使用动画的效果传入,通过传入一个地图更新状态对象,然后利用百度地图对象来展现和还原那个地图更新状态,即此时的地图显示就为你现在的位置  
  165.     }  
  166.   
  167.     /** 
  168.      * @author zhongqihong 
  169.      * 自定义定位图标 
  170.      * */  
  171.     private void changeLocationIcon() {  
  172.         myBitmapLocation=BitmapDescriptorFactory  
  173.                 .fromResource(R.drawable.ic_launcher);//引入自己的图标  
  174.         if (isFirstIn) {//表示第一次定位显示普通模式  
  175.             MyLocationConfiguration config=new   
  176.                     MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  177.             myBaiduMap.setMyLocationConfigeration(config);  
  178.         }             
  179.     }  
  180.     /** 
  181.      * @author zhongqihong 
  182.      * 初始化地图的View 
  183.      * */  
  184.     private void initMapView() {  
  185.         registerAllIds();  
  186.         registerAllEvents();  
  187.     }  
  188.     private void registerAllIds() {  
  189.         mapRoad=(ImageView) findViewById(R.id.road_condition);  
  190.         mapType=(ImageView) findViewById(R.id.map_type);  
  191.         expandMap=(ImageView) findViewById(R.id.add_scale);  
  192.         narrowMap=(ImageView) findViewById(R.id.low_scale);  
  193.         addMarks=(ImageView) findViewById(R.id.map_marker);  
  194.         markLayout=(LinearLayout) findViewById(R.id.mark_layout);  
  195.         locationText=(TextView) findViewById(R.id.mylocation_text);  
  196.         selectLocationMode=(ImageView) findViewById(R.id.map_location);  
  197.     }  
  198.     private void registerAllEvents() {  
  199.         mapRoad.setOnClickListener(this);  
  200.         mapType.setOnClickListener(this);  
  201.         expandMap.setOnClickListener(this);  
  202.         narrowMap.setOnClickListener(this);  
  203.         addMarks.setOnClickListener(this);  
  204.         selectLocationMode.setOnClickListener(this);  
  205.     }  
  206.     /** 
  207.      * @author zhongqihong 
  208.      * 除去百度地图上的默认控件 
  209.      * */  
  210.     private void changeDefaultBaiduMapView() {  
  211.         changeInitialzeScaleView();//改变默认百度地图初始加载的地图比例  
  212.         //设置隐藏缩放和扩大的百度地图的默认的比例按钮  
  213.         for (int i = 0; i < mapView.getChildCount(); i++) {//遍历百度地图中的所有子View,找到这个扩大和缩放的按钮控件View,然后设置隐藏View即可  
  214.             View child=mapView.getChildAt(i);  
  215.             if (child instanceof ZoomControls) {  
  216.                 defaultBaiduMapScaleButton=child;//该defaultBaiduMapScaleButton子View是指百度地图默认产生的放大和缩小的按钮,得到这个View  
  217.                 break;  
  218.             }  
  219.         }  
  220.         defaultBaiduMapScaleButton.setVisibility(View.GONE);//然后将该View的Visiblity设为不存在和不可见,即隐藏  
  221.         defaultBaiduMapLogo =mapView.getChildAt(1);//该View是指百度地图中默认的百度地图的Logo,得到这个View  
  222.         defaultBaiduMapLogo.setPadding(300, -10100100);//设置该默认Logo View的位置,因为这个该View的位置会影响下面的刻度尺单位View显示的位置  
  223.         mapView.removeViewAt(1);//最后移除默认百度地图的logo View  
  224.         defaultBaiduMapScaleUnit=mapView.getChildAt(2);//得到百度地图的默认单位刻度的View  
  225.         defaultBaiduMapScaleUnit.setPadding(1000115,200);//最后设置调整百度地图的默认单位刻度View的位置       
  226.     }  
  227.     /** 
  228.      * @author zhongqihong 
  229.      * 改变默认初始化的地图的比例 
  230.      * */  
  231.     private void changeInitialzeScaleView() {  
  232.         myBaiduMap=mapView.getMap();//改变百度地图的放大比例,让首次加载地图就开始扩大到500米的距离,获得百度地图对象  
  233.         MapStatusUpdate factory=MapStatusUpdateFactory.zoomTo(15.0f);  
  234.         myBaiduMap.animateMapStatus(factory);         
  235.     }  
  236.     /** 
  237.      * @author zhongqihong 
  238.      * 管理地图的生命周期 
  239.      * */  
  240.     protected void onDestroy() {  
  241.         super.onDestroy();  
  242.         //在Activity执行onDestory时执行mapView(地图)生命周期管理  
  243.         mapView.onDestroy();  
  244.     }  
  245.     @Override  
  246.     protected void onStart() {//当Activity调用onStart方法,开启定位以及开启方向传感器,即将定位的服务、方向传感器和Activity生命周期绑定在一起  
  247.         myBaiduMap.setMyLocationEnabled(true);//开启允许定位  
  248.         if (!myLocationClient.isStarted()) {  
  249.             myLocationClient.start();//开启定位  
  250.         }  
  251.         //开启方向传感器  
  252.         myOrientationListener.start();  
  253.         super.onStart();  
  254.     }  
  255.     @Override  
  256.     protected void onStop() {//当Activity调用onStop方法,关闭定位以及关闭方向传感器  
  257.         myBaiduMap.setMyLocationEnabled(false);  
  258.         myLocationClient.stop();//关闭定位  
  259.         myOrientationListener.stop();//关闭方向传感器  
  260.         super.onStop();  
  261.     }  
  262.     @Override  
  263.     protected void onResume() {  
  264.         // TODO Auto-generated method stub  
  265.         super.onResume();  
  266.         //在Activity执行onResume是执行MapView(地图)生命周期管理  
  267.         mapView.onResume();  
  268.     }  
  269.     @Override  
  270.     protected void onPause() {  
  271.         // TODO Auto-generated method stub  
  272.         super.onPause();  
  273.         mapView.onPause();  
  274.     }  
  275.     //点击事件相关  
  276.     @Override  
  277.     public void onClick(View v) {  
  278.         switch (v.getId()) {  
  279.         case R.id.road_condition://是否打开实时交通  
  280.             switchRoadCondition();  
  281.             break;  
  282.         case R.id.map_type://选择地图的类型  
  283.             selectMapType();  
  284.             break;  
  285.         case R.id.add_scale://放大地图比例  
  286.             expandMapScale();  
  287.             break;  
  288.         case R.id.low_scale://缩小地图比例  
  289.             narrowMapScale();  
  290.             break;  
  291.         case R.id.map_marker://添加覆盖物  
  292.             addMapMarks();  
  293.             break;  
  294.         case R.id.my_location://定位功能,需要用到LocationClient进行定位  
  295.             //BDLocationListener  
  296.             getMyLatestLocation(latitude,longtitude);  
  297.             break;  
  298.         case R.id.map_location://选择定位模式  
  299.             selectLocation();  
  300.             break;  
  301.         default:  
  302.             break;  
  303.         }  
  304.     }  
  305.     /** 
  306.      * @author mikyou 
  307.      * 选择定位的模式 
  308.      * */  
  309.     private void selectLocation() {  
  310.         AlertDialog.Builder builder2=new AlertDialog.Builder(this);  
  311.         builder2.setIcon(R.drawable.track_collect_running)  
  312.         .setTitle("请选择定位的模式")  
  313.         .setItems(LocationModeString, new DialogInterface.OnClickListener() {  
  314.   
  315.             @Override  
  316.             public void onClick(DialogInterface dialog, int which) {  
  317.                 String mode=LocationModeString[which];  
  318.                 if (mode.equals("罗盘模式")) {  
  319.                     MyLocationConfiguration config=new   
  320.                             MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);  
  321.                     myBaiduMap.setMyLocationConfigeration(config);  
  322.                 }else if (mode.equals("跟随模式")) {  
  323.                     MyLocationConfiguration config=new   
  324.                             MyLocationConfiguration(LocationMode.FOLLOWING, true, myBitmapLocation);  
  325.                     myBaiduMap.setMyLocationConfigeration(config);  
  326.                 }else if (mode.equals("普通模式")) {  
  327.                     MyLocationConfiguration config=new   
  328.                             MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  329.                     myBaiduMap.setMyLocationConfigeration(config);  
  330.                 }else if (mode.equals("3D俯视模式(已关闭)")||mode.equals("3D俯视模式(已打开)")) {  
  331.                     if (mode.equals("3D俯视模式(已打开)")) {  
  332.                         UiSettings   mUiSettings = myBaiduMap.getUiSettings();  
  333.                         mUiSettings.setCompassEnabled(true);  
  334.                         LocationModeString[which]="3D俯视模式(已关闭)";  
  335.                         toast("3D模式已关闭");  
  336.                     }else{  
  337.                         MyLocationConfiguration config=new   
  338.                                 MyLocationConfiguration(LocationMode.COMPASS, true, myBitmapLocation);  
  339.                         myBaiduMap.setMyLocationConfigeration(config);  
  340.                         MyLocationConfiguration config2=new   
  341.                                 MyLocationConfiguration(LocationMode.NORMAL, true, myBitmapLocation);  
  342.                         myBaiduMap.setMyLocationConfigeration(config2);  
  343.                         LocationModeString[which]="3D俯视模式(已打开)";  
  344.                         toast("3D模式已打开");  
  345.                     }  
  346.                 }  
  347.             }  
  348.         }).show();        
  349.     }  
  350.     /** 
  351.      * @author Mikyou 
  352.      * 添加覆盖物 
  353.      * */  
  354.     private void addMapMarks() {  
  355.         initMarksData();  
  356.         myBaiduMap.clear();//先清除一下图层  
  357.         LatLng latLng=null;  
  358.         Marker marker=null;  
  359.         OverlayOptions options;  
  360.         myMarks=BitmapDescriptorFactory.fromResource(R.drawable.mark);//引入自定义的覆盖物图标,将其转化成一个BitmapDescriptor对象  
  361.         //遍历MarkInfo的List一个MarkInfo就是一个Mark  
  362.         for (int i = 0; i < markInfoList.size(); i++) {  
  363.             //经纬度对象  
  364.             latLng=new LatLng(markInfoList.get(i).getLatitude(), markInfoList.get(i).getLongitude());//需要创建一个经纬对象,通过该对象就可以定位到处于地图上的某个具体点  
  365.             //图标  
  366.             options=new MarkerOptions().position(latLng).icon(myMarks).zIndex(6);  
  367.             marker=(Marker) myBaiduMap.addOverlay(options);//将覆盖物添加到地图上  
  368.             Bundle bundle=new Bundle();//创建一个Bundle对象将每个mark具体信息传过去,当点击该覆盖物图标的时候就会显示该覆盖物的详细信息  
  369.             bundle.putSerializable("mark", markInfoList.get(i));  
  370.             marker.setExtraInfo(bundle);  
  371.         }  
  372.         MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);//通过这个经纬度对象,地图就可以定位到该点  
  373.         myBaiduMap.animateMapStatus(msu);  
  374.     }  
  375.     /** 
  376.      * @author mikyou 
  377.      * 初始化覆盖物信息数据 
  378.      * */  
  379.     private void initMarksData() {  
  380.         markInfoList=new ArrayList<MarkInfo>();  
  381.         markInfoList.add(new MarkInfo(32.079254118.787623, R.drawable.pic1, "英伦贵族小旅馆""距离209米"1888));  
  382.         markInfoList.add(new MarkInfo(32.064355118.787624, R.drawable.pic2, "沙井国际高级会所""距离459米"388));  
  383.         markInfoList.add(new MarkInfo(28.7487420000115.8748860000, R.drawable.pic4, "华东交通大学南区""距离5米"888));  
  384.         markInfoList.add(new MarkInfo(28.7534890000115.8767960000, R.drawable.pic3, "华东交通大学北区""距离10米"188));  
  385.         myBaiduMap.setOnMarkerClickListener(this);  
  386.         myBaiduMap.setOnMapClickListener(this);     
  387.     }  
  388.     /** 
  389.      * @author zhongqihong 
  390.      * 放大地图的比例 
  391.      * */  
  392.     private void narrowMapScale() {  
  393.         current-=0.5f;  
  394.         MapStatusUpdate msu=MapStatusUpdateFactory.zoomTo(15.0f+current);  
  395.         myBaiduMap.animateMapStatus(msu);  
  396.     }  
  397.     /** 
  398.      *@author zhongqihong 
  399.      *缩小地图的比例  
  400.      * */  
  401.     private void expandMapScale() {  
  402.         current+=0.5f;  
  403.         MapStatusUpdate msu2=MapStatusUpdateFactory.zoomTo(15.0f+current);  
  404.         myBaiduMap.animateMapStatus(msu2);  
  405.     }  
  406.     /** 
  407.      * @author mikyou 
  408.      * 选择地图的类型 
  409.      * */  
  410.     private void selectMapType() {  
  411.         AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);  
  412.         builder.setIcon(R.drawable.icon)  
  413.         .setTitle("请选择地图的类型")  
  414.         .setItems(types, new DialogInterface.OnClickListener() {  
  415.             @Override  
  416.             public void onClick(DialogInterface dialog, int which) {  
  417.                 String select=types[which];  
  418.                 if (select.equals("普通地图")) {  
  419.                     myBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);  
  420.                 }else if (select.equals("卫星地图")) {  
  421.                     myBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);  
  422.                 }else if (select.equals("热力地图(已关闭)")||select.equals("热力地图(已打开)")) {  
  423.                     if(myBaiduMap.isBaiduHeatMapEnabled()) {  
  424.                         myBaiduMap.setBaiduHeatMapEnabled(false);  
  425.                         Toast.makeText(MainActivity.this"热力地图已关闭"0).show();  
  426.                         types[which]="热力地图(已关闭)";  
  427.                     }else {  
  428.                         myBaiduMap.setBaiduHeatMapEnabled(true);  
  429.                         Toast.makeText(MainActivity.this"热力地图已打开"0).show();  
  430.                         types[which]="热力地图(已打开)";  
  431.                     }  
  432.                 }  
  433.             }  
  434.         }).show();  
  435.     }  
  436.     /** 
  437.      * @author mikyou 
  438.      * 是否打开实时交通 
  439.      * */  
  440.     private void switchRoadCondition() {  
  441.         if (myBaiduMap.isTrafficEnabled()) {//如果是开着的状态,当点击后,就会出关闭状态  
  442.             myBaiduMap.setTrafficEnabled(false);  
  443.             mapRoad.setImageResource(R.drawable.main_icon_roadcondition_off);  
  444.         }else{//如果是的关闭的状态,当点击后,就会处于开启的状态  
  445.             myBaiduMap.setTrafficEnabled(true);  
  446.             mapRoad.setImageResource(R.drawable.main_icon_roadcondition_on);  
  447.         }  
  448.     }  
  449.     /** 
  450.      * @author mikyou 
  451.      * 覆盖物的点击事件 
  452.      * */  
  453.     @Override  
  454.     public boolean onMarkerClick(Marker marker) {  
  455.         Bundle bundle=  marker.getExtraInfo();  
  456.         MarkInfo MyMarker=(MarkInfo) bundle.getSerializable("mark");  
  457.         ImageView iv=(ImageView) markLayout.findViewById(R.id.mark_image);  
  458.         TextView distanceTv=(TextView) markLayout.findViewById(R.id.distance);  
  459.         TextView nameTv=(TextView) markLayout.findViewById(R.id.name);  
  460.         TextView zanNumsTv=(TextView) markLayout.findViewById(R.id.zan_nums);  
  461.         iv.setImageResource(MyMarker.getImageId());  
  462.         distanceTv.setText(MyMarker.getDistance()+"");  
  463.         nameTv.setText(MyMarker.getName());  
  464.         zanNumsTv.setText(MyMarker.getZanNum()+"");  
  465.         //初始化一个InfoWindow  
  466.         initInfoWindow(MyMarker,marker);  
  467.         markLayout.setVisibility(View.VISIBLE);  
  468.         return true;  
  469.     }  
  470.     /** 
  471.      *@author mikyou 
  472.      *初始化出一个InfoWindow 
  473.      *  
  474.      * */  
  475.     private void initInfoWindow(MarkInfo MyMarker,Marker marker) {  
  476.         // TODO Auto-generated method stub  
  477.         InfoWindow infoWindow;  
  478.         //InfoWindow中显示的View内容样式,显示一个TextView  
  479.         TextView infoWindowTv=new TextView(MainActivity.this);  
  480.         infoWindowTv.setBackgroundResource(R.drawable.location_tips);  
  481.         infoWindowTv.setPadding(30203050);  
  482.         infoWindowTv.setText(MyMarker.getName());  
  483.         infoWindowTv.setTextColor(Color.parseColor("#FFFFFF"));  
  484.   
  485.         final LatLng latLng=marker.getPosition();  
  486.         Point p=myBaiduMap.getProjection().toScreenLocation(latLng);//将地图上的经纬度转换成屏幕中实际的点  
  487.         p.y-=47;//设置屏幕中点的Y轴坐标的偏移量  
  488.         LatLng ll=myBaiduMap.getProjection().fromScreenLocation(p);//把修改后的屏幕的点有转换成地图上的经纬度对象  
  489.         /** 
  490.          * @author mikyou 
  491.          * 实例化一个InfoWindow的对象 
  492.          * public InfoWindow(View view,LatLng position, int yOffset)通过传入的 view 构造一个 InfoWindow, 此时只是利用该view生成一个Bitmap绘制在地图中,监听事件由开发者实现。 
  493.          *  参数: 
  494.          * view - InfoWindow 展示的 view 
  495.          * position - InfoWindow 显示的地理位置 
  496.          * yOffset - InfoWindow Y 轴偏移量 
  497.          * */  
  498.         infoWindow=new InfoWindow(infoWindowTv, ll, 10);  
  499.         myBaiduMap.showInfoWindow(infoWindow);//显示InfoWindow  
  500.     }  
  501.     /** 
  502.      * @author zhongqihong 
  503.      * 给整个地图添加的点击事件 
  504.      * */  
  505.     @Override  
  506.     public void onMapClick(LatLng arg0) {//表示点击地图其他的地方使得覆盖物的详情介绍的布局隐藏,但是点击已显示的覆盖物详情布局上,则不会消失,因为在详情布局上添加了Clickable=true  
  507.         //由于事件的传播机制,因为点击事件首先会在覆盖物布局的父布局(map)中,由于map是可以点击的,map则会把点击事件给消费掉,如果加上Clickable=true表示点击事件由详情布局自己处理,不由map来消费  
  508.         markLayout.setVisibility(View.GONE);  
  509.         myBaiduMap.hideInfoWindow();//隐藏InfoWindow  
  510.     }  
  511.     @Override  
  512.     public boolean onMapPoiClick(MapPoi arg0) {  
  513.         return false;  
  514.     }  
  515.     public void toast(String str){  
  516.         Toast.makeText(MainActivity.this, str, 0).show();  
  517.     }  
  518. }  
作者:辛风华
阅读全文
1 0
原创粉丝点击