百度地图(2)

接着昨天的百度地图话题,今天要写一下我的一个拙劣的糅合基础服务,定位服务和绘制服务的程序。怎么建立基本地图应用前面已经说了,现在开始做这个东东,来达到认识百度地图各种特性的目的。


程序基本上是建立在百度的demo上面,基本做法是照搬demo里面的MyLocationDemoActivity。然后加入绘制的代码即可。



照搬demo的代码

首先,我们得实现appication来监听是否连接网络和是否认证好我们的key

public class MyApplication extends Application{
    private static MyApplication mInstance = null;
    public boolean m_bKeyRight = true;
    BMapManager mBMapManager = null;

    
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        initEngineManager(this);
//        Toast.makeText(MyApplication.getInstance().getApplicationContext(), 
//                "开始!", Toast.LENGTH_LONG).show();
    }
    
    public void initEngineManager(Context context) {
        if (mBMapManager == null) {
            mBMapManager = new BMapManager(context);
        }

        if (!mBMapManager.init(new MyGeneralListener())) {
            Toast.makeText(MyApplication.getInstance().getApplicationContext(), 
                    "BMapManager  初始化错误!", Toast.LENGTH_LONG).show();
        }
    }
    
    public static MyApplication getInstance() {
        return mInstance;
    }
    
    
    // 常用事件监听,用来处理通常的网络错误,授权验证错误等
    static class MyGeneralListener implements MKGeneralListener {
        
        @Override
        public void onGetNetworkState(int iError) {
            if (iError == MKEvent.ERROR_NETWORK_CONNECT) {
                Toast.makeText(MyApplication.getInstance().getApplicationContext(), "您的网络出错啦!",
                    Toast.LENGTH_LONG).show();
            }
            else if (iError == MKEvent.ERROR_NETWORK_DATA) {
                Toast.makeText(MyApplication.getInstance().getApplicationContext(), "输入正确的检索条件!",
                        Toast.LENGTH_LONG).show();
            }
            // ...
        }

        @Override
        public void onGetPermissionState(int iError) {
            //非零值表示key验证未通过
            if (iError != 0) {
                //授权Key错误:请在 DemoApplication.java文件输入正确的授权Key,并
                Toast.makeText(MyApplication.getInstance().getApplicationContext(), 
                        "检查您的网络连接是否正常!error: "+iError, Toast.LENGTH_LONG).show();
                MyApplication.getInstance().m_bKeyRight = false;
            }
            else{
                MyApplication.getInstance().m_bKeyRight = true;
                Toast.makeText(MyApplication.getInstance().getApplicationContext(), 
                        "key认证成功", Toast.LENGTH_LONG).show();
            }
        }
    }
}


然后就是activity里面,activity照抄MyLocationDemoActivity,有几个地方需要注意。

在onCreate里面初始化BMapManager类和appication:

		MyApplication app = (MyApplication) this.getApplication();
		if (app.mBMapManager == null) {
			app.mBMapManager = new BMapManager(getApplicationContext());
			/**
			 * 如果BMapManager没有初始化则初始化BMapManager
			 */
			app.mBMapManager.init(new MyApplication.MyGeneralListener());
		}
地图初始化

		// 地图初始化
		mMapView = (MyLocationMapView) findViewById(R.id.bmapView);
		mMapController = mMapView.getController();
		mMapController.enableClick(true);
		mMapView.getController().setZoom(14);
		mMapView.getController().enableClick(true);
		mMapView.setBuiltInZoomControls(true);

定位相关的

		// 定位初始化
		mLocClient = new LocationClient(this);
		locData = new LocationData();
		mLocClient.registerLocationListener(myListener);
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType("bd09ll"); // 设置坐标类型
		option.setScanSpan(1000);
		mLocClient.setLocOption(option);
		mLocClient.start();

		// 定位图层初始化
		myLocationOverlay = new locationOverlay(mMapView);
		// 设置定位数据
		myLocationOverlay.setData(locData);
		// 添加定位图层
		mMapView.getOverlays().add(myLocationOverlay);
		myLocationOverlay.enableCompass();
		// 修改定位数据后刷新图层生效
		// mMapView.refresh();

定位监听:(这个改动比较大,是为了我的程序写的一些逻辑)

	/**
	 * 定位SDK监听函数
	 */
	public class MyLocationListenner implements BDLocationListener {
		@Override
		public void onReceiveLocation(BDLocation location) {
			double distance;
			if (location == null)
				return;
			locData.latitude = location.getLatitude();
			locData.longitude = location.getLongitude();
			// 如果不显示定位精度圈,将accuracy赋值为0即可
			locData.accuracy = location.getRadius();
			// 此处可以设置 locData的方向信息, 如果定位 SDK 未返回方向信息,用户可以自己实现罗盘功能添加方向信息。
			locData.direction = location.getDerect();
			// 更新定位数据
			myLocationOverlay.setData(locData);
			// 更新图层数据执行刷新后生效
			// mMapView.refresh();
			mHandler.sendEmptyMessage(REFRESH_MAP);
			// 是手动触发请求或首次定位时,移动到定位点
			Log.e("busy", "busy9");
			if (isRequest || isFirstLoc) {
				// 移动地图到定位点
				Log.d("LocationOverlay", "receive location, animate to it");
				mMapController.animateTo(new GeoPoint((int) (locData.latitude * 1e6),
						(int) (locData.longitude * 1e6)));
				isRequest = false;
				// myLocationOverlay.setLocationMode(LocationMode.FOLLOWING);
				// requestLocButton.setText("跟随");
				// mCurBtnType = E_BUTTON_TYPE.FOLLOW;
				if (isFirstLoc) {
					p1LL.setLatitudeE6((int) (locData.latitude * 1e6));
					p1LL.setLongitudeE6((int) (locData.longitude * 1e6));
					preNetType = check234G();
					currentNetType = preNetType;
					sendAddPointMsg(p1LL);
					// sendWriteResultMsg(p1LL);
					mHandler.sendEmptyMessage(PRINT_OLD_POINT);					
				} else {
					p2LL.setLatitudeE6((int) (locData.latitude * 1e6));
					p2LL.setLongitudeE6((int) (locData.longitude * 1e6));
					distance = getDistance();
					if (distance > markDistance) {
						// if(distance < maxDistance ||
						// !isAutoRecord){//去除误差较大的点
						// 添加标记点,并写入结果
						sendAddPointMsg(p2LL);
						// sendWriteResultMsg(p2LL);

						p1LL.setLatitudeE6((int) (locData.latitude * 1e6));
						p1LL.setLongitudeE6((int) (locData.longitude * 1e6));
						Log.e(TAG, "Mark!");
						// }else{
						// Toast.makeText(mContext,
						// getResString(R.string.distance_is_too_long) + "\n" +
						// distance,
						// Toast.LENGTH_LONG).show();
						// }
					} else {
						Toast.makeText(mContext,
								getResString(R.string.distance_is_too_short) + "\n" + distance,
								Toast.LENGTH_LONG).show();
					}

				}
			}
			// 首次定位完成
			isFirstLoc = false;
		}





添加自绘图层

以上这些在demo里面都是现成的,只是介绍下各个模块的作用。然后,下面就介绍一下,怎么添加自己绘制的图层

首先,添加图层需要 定义图层

	private MyOverlay mOverlay = null;
	private ArrayList<OverlayItem> mItems = null;

初始化图层并添加到地图上

		mOverlay = new MyOverlay(getResources().getDrawable(R.drawable.icon_gcoding), mMapView);
		mMapView.getOverlays().add(mOverlay);

MyOverlay是继承ItemizedOverlay的,为了响应图层点击事件,我们需要在这个自定义类里面实现相关操作

	public class MyOverlay extends ItemizedOverlay {

		public MyOverlay(Drawable defaultMarker, MapView mapView) {
			super(defaultMarker, mapView);
		}

		// 响应点击
		@Override
		public boolean onTap(int index) {
			OverlayItem item = getItem(index);
			button.setText(item.getTitle());
			GeoPoint pt = new GeoPoint((int) (item.getPoint().getLatitudeE6()),
					(int) (item.getPoint().getLongitudeE6()));
			// 弹出自定义View
			pop.showPopup(button, pt, 32);

			return true;
		}

		@Override
		public boolean onTap(GeoPoint pt, MapView mMapView) {
			if (pop != null) {
				pop.hidePop();
				mMapView.removeView(button);
			}
			return false;
		}
	}

以下是添加绘制点的方法,也是绘制的关键。在需要绘制点的地方,调用这个方法即可。参数是经度(mLat),纬度(mLon),和写入点的内容(network)。

	/**
	 * 添加标记点
	 */
	public void addPoint(int mLat, int mLon, String network) {
		GeoPoint p = new GeoPoint(mLat, mLon);
		OverlayItem item = new OverlayItem(p, network, "");
		item.setMarker(getResources().getDrawable(R.drawable.icon_gcoding));

		/**
		 * 将item 添加到overlay中 注意: 同一个itme只能add一次
		 */
		mOverlay.addItem(item);
		/**
		 * 保存所有item,以便overlay在reset后重新添加
		 */
		mItems.addAll(mOverlay.getAllItem());

		// mMapView.refresh();
		mHandler.sendEmptyMessage(REFRESH_MAP);
	}




manifest相关

值得注意的是,manifest里面还有些东西需要配置,其实文档也说得清清楚楚的

在appication外面添加

    <supports-screens
        android:anyDensity="true"
        android:largeScreens="true"
        android:normalScreens="false"
        android:resizeable="true"
        android:smallScreens="true" />

在appication里面添加

        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote" >

这个服务异常重要,不添加你就无法使用百度的定位服务了。我在这里绕了许久

另外当然还有你的key,上一篇有介绍,这里不说了。

还有添加一些权限,复制demo里面所有权限过来就好了





总结

我也知道我说得很乱没有章法,不过水平就是这样的啦。那总结好好说说。首先,我要说的一点是,百度地图的坐标不是真实坐标,是经过一定的偏移的。但是,百度给出的地图也是经过偏移的,所以负负得正,总的来说你看到的百度地图位置还是很准的。这个问题得益于我们的国家政策,强制偏移电子地图。对于这个问题,可以试试下面的代码得到的坐标,这个是真实的坐标,可以看看在百度地图上定位到了哪里。

			LocationClient mLocationClient =  = new LocationClient(getApplicationContext(), this, // ConnectionCallbacks
					this);
                        lat = mLocationClient.getLastLocation().getLatitude();
			lon = mLocationClient.getLastLocation().getLongitude();

百度地图使用GPS,基站,网络混合定位,定位准确度还是比较高的,而且百度对比谷歌地图的优势在于,百度地图提供了更加丰富的路径规划和兴趣点的服务。而且全中文的文档也是非常易懂。


下面再提供一个可能会常用到的,计算两点之间距离的方法:

	public double getDistance(GeoPoint p1LL, GeoPoint p2LL) {
		double dis;
		try {
			dis = DistanceUtil.getDistance(p1LL, p2LL);
		} catch (Exception e) {
			e.printStackTrace();
			dis = -1;
		}
		Log.e(TAG, "Distance is: " + dis);
		return dis;
	}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值