仿滴滴打车地图选点(包含地图选点,离线地图,导航路线)

根据项目的需要今天做一个百度地图得功能:  百度地图API使用详解
     1、百度地图状态改变监听,用户拖动地图(可以设置只能在半径范围内活动)可以实时展示经纬度
     2、接入全国各省市离线地图,下载离线地图后无网络情况下实时显示位置
     3、设置导航路线,从当前位置到目的地调用第三方地图导航
效果图:


下面开始讲一下项目中主要知识点,文章末尾附上demo,便于更多的同学运用
集成百度地图api
使用百度地图api需要申请密钥,如下网址有详细操作步奏 
http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key 
其中获取sha1值时如果使用的是androidstudio有一个最快的方式请看截图:按照1,2,3步骤即可快速获取sha1值。

1、接下来在application中SDK 各组间之前初始化
// 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext
SDKInitializer.initialize(this);

2、在清单文件中替换成你自己申请的API_KEY,避免地图不显示经纬度问题。

 <application
        android:name="com.ctao.demo.BaseApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="CgtUAFYmzRU1D1ySVHGwqszUewr5382g" />
    </application>

3、 在MainActivity中主要代码:

private void initSettingMapView() {
		// 初始化地图
		mMapView.showZoomControls(false);
		mBaiduMap = mMapView.getMap();
		// 开启定位图层
		mBaiduMap.setMyLocationEnabled(true);
		// 定位初始化
		mLocationClient = new LocationClient(this);
		mLocationClient.registerLocationListener(new MyBDLocationListner());
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType(CoordinateType.BD09LL); // 设置坐标类型
		option.setScanSpan(1000);
		mLocationClient.setLocOption(option);
		mLocationClient.start();

		//初始化缩放比例
		MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);
		mBaiduMap.setMapStatus(msu);
		mBaiduMap.setOnMapTouchListener(new MyMapTouchListener());

		// 初始化当前MapView中心屏幕坐标(物理坐标)
		mMapView.post(new Runnable() {
			@Override
			public void run() {
				mCenterPoint = mBaiduMap.getMapStatus().targetScreen;
				int x = mCenterPoint.x;
				int y = mCenterPoint.y;

				ImageView imageview = new ImageView(getApplicationContext());
				Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_location_chatbox);

				imageview.setImageBitmap(bitmap);
				imageview.setX(x - bitmap.getWidth() / 2);
				imageview.setY(y - bitmap.getHeight());
				ViewGroup parent = (ViewGroup) mMapView.getParent();
				parent.addView(imageview,new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT));
			}
		});
		//初始化当前地理坐标
		mLoactionLatLng = mBaiduMap.getMapStatus().target;
		// 地理编码
		mGeoCoder = GeoCoder.newInstance();
		mGeoCoder.setOnGetGeoCodeResultListener(new MyGetGeoCoderResultListener());
	}

 该代码主要包含初始化地图,打开定位,设置当前覆盖物,获取地理位置编码
 

// 定位监听器
	private class MyBDLocationListner implements BDLocationListener {
		@Override
		public void onReceiveLocation(BDLocation location) {
			// map view 销毁后不在处理新接收的位置
			if (location == null || mMapView == null){
				return;
			}
			MyLocationData data = new MyLocationData.Builder()//
					.accuracy(mRadius)//location.getRadius()
					.direction(location.getDirection())
					.latitude(location.getLatitude())//
					.longitude(location.getLongitude())//
					.build();
			mBaiduMap.setMyLocationData(data);

			mLatitude = location.getLatitude();
			mLongtitude = location.getLongitude();
			mLoactionLatLng = new LatLng(mLatitude, mLongtitude);

			// 是否第一次定位
			if (isFirstLoc) {
				isFirstLoc = false;
				// 实现动画跳转
				MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);
				mBaiduMap.animateMapStatus(u);
				mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(mLoactionLatLng));
			}
		}
	}

该代码定位当前位置得监听器,通过location获取到经纬度,通过

new MyLocationData.Builder()//
      .accuracy(mRadius)//location.getRadius()
      .direction(location.getDirection())
      .latitude(location.getLatitude())//
      .longitude(location.getLongitude())//
      .build();
可以得出当前半径得范围,demo中设置的radius=500。
// 地图触摸事件监听器
	private class MyMapTouchListener implements BaiduMap.OnMapTouchListener {
		@Override
		public void onTouch(MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_UP ) {
				if (mCenterPoint == null) {
					return;
				}
				// 获取当前MapView中心屏幕坐标对应的地理坐标
				currentLatLng = mBaiduMap.getProjection().fromScreenLocation(mCenterPoint);
				//发起反地理编码检索
				mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(currentLatLng));
				double distance = getDistance(mLongtitude, mLatitude, currentLatLng.longitude, currentLatLng.latitude);
				Toast.makeText(MainActivity.this,"当前纬度"+ currentLatLng.latitude+"当前经度"+ currentLatLng.longitude,Toast.LENGTH_LONG).show();
				if(distance > mRadius){
					Toast.makeText(MainActivity.this,"已经超出可选区域范围",Toast.LENGTH_LONG).show();
					//设定中心点坐标
					LatLng point = new LatLng(mLatitude, mLongtitude);
					//定义地图状态
					MapStatus mMapStatus = new MapStatus.Builder()
							.target(point)
							.zoom(17)
							.build();
					//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
					MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
					//改变地图状态
					mBaiduMap.setMapStatus(mMapStatusUpdate);
				}
			}
		}
	}

该代码是通过手指移动地图位置,地图选点获取经纬度,根据之前按设置得半径,如果移动的终点和起点得距离大于500时移动的点直接回到原点处,
点击离线地图时直接跳到百度地图离线页面,下载离线地图使用。
点击导航按钮时,通过移动的位置点为终点,起点为当前点,调用第三方的app(如百度,高德,腾讯)
高德地图:http://lbs.amap.com/api/amap-mobile/guide/android/route
百度地图:http://lbsyun.baidu.com/index.php?title=uri/api/android
腾讯地图:http://lbs.qq.com/uri_v1/guide-route.html
一定要注意打开之前确认下是否安装第三方地图app,具体的写法如果调用百度,高德,腾讯可以参照下面得util工具类

public class Util {

    private static final String BAIDU_PACKAGE_NAME = "com.baidu.BaiduMap";
    private static final String GAODE_PACKAGE_NAME = "com.autonavi.minimap";
    private static final String TENCENT_PACKAGE_NAME = "com.tencent.map";

    /**
     * 是否安装百度地图
     */
    public static boolean haveBaiduMap(Context context) {
        return exist(context, BAIDU_PACKAGE_NAME);
    }

    public static boolean haveGaodeMap(Context context) {
        return exist(context, GAODE_PACKAGE_NAME);
    }

    public static boolean haveTencentMap(Context context) {
        return exist(context, TENCENT_PACKAGE_NAME);
    }

    /**
     * 检查手机上是否安装了指定的软件
     *
     * @param context
     * @param packageName:应用包名
     * @return true 存在
     */
    public static boolean exist(Context context, String packageName) {
        //获取packagemanager
        final PackageManager packageManager = context.getPackageManager();
        //获取所有已安装程序的包信息
        List<PackageInfo> packageInfos = packageManager.getInstalledPackages(0);
        //用于存储所有已安装程序的包名
        List<String> packageNames = new ArrayList<>();
        //从pinfo中将包名字逐一取出,压入pName list中
        if (packageInfos != null) {
            for (int i = 0; i < packageInfos.size(); i++) {
                String packName = packageInfos.get(i).packageName;
                packageNames.add(packName);
            }
        }
        //判断packageNames中是否有目标程序的包名,有true,没有false
        return packageNames.contains(packageName);
    }

    /**
     * 调用高德地图app,导航
     *
     * @param context            上下文
     * @param destination        目标经纬度
     * @param destinationAddress 目标地址
     *                           高德地图:http://lbs.amap.com/api/amap-mobile/guide/android/route
     */
    public static void openGaodeMap(Context context, LatLng destination,
                                    String destinationAddress) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.addCategory("android.intent.category.DEFAULT");
        intent.setData(Uri.parse("amapuri://route/plan/?" +
            "dlat=" + destination.latitude +
            "&dlon=" + destination.longitude +
            "&dname=" + destinationAddress +
            "&dev=0" +
            "&t=0"));
        context.startActivity(intent);
    }

    /**
     * 调用百度地图
     *
     * @param destination        目的地经纬度
     * @param destinationAddress 目的地地址
     *                           百度参考网址:http://lbsyun.baidu.com/index.php?title=uri/api/android
     */
    public static void openBaiduMap(Context context, LatLng destination,
                                    String destinationAddress) {
        Intent intent = new Intent();
        intent.setData(Uri.parse("baidumap://map/direction?" +
            "destination=latlng:" + destination.latitude + "," + destination.longitude +
            "|name:" + destinationAddress +
            "&mode=driving"));
        context.startActivity(intent);
    }

    /**
     * 调用腾讯地图
     *
     * @param context
     * @param destination        目的地经纬度
     * @param destinationAddress 目的地地址
     *                           腾讯地图参考网址:http://lbs.qq.com/uri_v1/guide-route.html
     */
    public static void openTentcentMap(Context context, LatLng destination, String destinationAddress) {
        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.setData(Uri.parse("qqmap://map/routeplan?" +
            "type=drive" +
            "&from=" +
            "&fromcoord=" +
            "&to=" + destinationAddress +
            "&tocoord=" + destination.latitude + "," + destination.longitude +
            "&policy=0" +
            "&referer=appName"));
        context.startActivity(intent);
    }
     /**
     * 打开网页版 导航
     * 不填我的位置,则通过浏览器定未当前位置
     *
     * @param context
     * @param myLatLng 起点经纬度
     * @param myAddress 起点地址名展示
     * @param destination 终点经纬度
     * @param destinationAddress 终点地址名展示
     */
    public static void openBrowserMap(Context context, LatLng myLatLng, String myAddress, LatLng destination,
                                          String destinationAddress) {

        Intent intent = new Intent();
        intent.setAction("android.intent.action.VIEW");
        intent.setData(Uri.parse("http://uri.amap.com/navigation?" +
            "from=" + myLatLng.longitude + "," + myLatLng.latitude + "," + myAddress +
            "to=" + destination.longitude + "," + destination.latitude + "," + destinationAddress +
            "&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0"));
        context.startActivity(intent);

    }
}

到此处,主要代码都已经讲解完了,包含地图定位,离线地图,导航路线等,希望对有需要的同学提供帮助,下面附上完整的代码地址:https://download.csdn.net/download/lou_liang/11646220
有问题可以在下方留言讨论,谢谢大家!

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值