利用百度地图Android sdk高仿微信发送位置功能

接触了百度地图开发平台半个月了,这2天试着模仿了微信给好友发送位置功能,对百度地图的操作能力又上了一个台阶

我在实现这个功能的时候,遇到一些困难,可能也是别人将会遇到的困难,,特在此列出

1、在微信发送功能中,不管用户如何拖拽地图,总有个覆盖物固定了MapView中央,怎么实现?

其实这很容易实现,只要MapView的布局文件中,将一个ImageView覆盖在MapView的中央,就能够实现不管用户如何拖拽地图,覆盖物(ImageView)总固定总MapView中央

2、如何获取MapView中央的地理坐标,也即是屏幕覆盖物处的坐标?

要获取MapView中央的地理坐标,首先先获取覆盖物在屏幕上的物理坐标,这里得区别一下地理坐标(经纬度)和物理坐标(xy轴);

可以通过

<mCenterPoint = mBaiduMap.getMapStatus().targetScreen;//mBaiduMap是BaiduMap类的实例来获取物理坐标,这个物理坐标是不变的,而物理坐标对应的地理坐标却是随着用户拖拽地图而改变,所以,当我们需要地理坐标时,可以通过currentLatLng = mBaiduMap.getProjection().fromScreenLocation(mCenterPoint);</strong></span>获取。

3、如何获取该地理坐标周围的所有poi信息(也就是周围建筑物的信息),而不只是某个类型的兴趣点?

为了实现这个功能,真是费了我好大劲,因为我之前一直以为用POI周边搜索实现的,有人提示我可以通过循环轴线搜索实现不同关键字搜索,但这样子确实很难实现跟微信那样的效果。通过查看API,发现可以通过反地理编码解决这个问题,至于什么事反地理编码,可以到百度地图官网了解,通过调用它,可以返回一个该地理坐标附近建筑信息的一个列表

4、当用户拖拽地图,如何让列表更新到目前中心地理位置的周边信息?

这个困难其实也不难实现,只是重写mBaiduMap.setOnMapTouchListener(touchListener);触摸事件,在触摸监听器的回调函数中

将MapView中央的物理坐标转换成对应的地理坐标,再通过反地理编码获取周边信息,道理同问题3

5、当点击listview某一项时,如何将项地理位置显示在MapView也就是屏幕中央?

很简单,通过listview的适配器获取item的位置信息,包括经纬度,然后用动画跳转到屏幕中央位置即可。

我认为上面5个问题是实现这个功能的关键所在,下面是效果图

上面是一个MapVIew,覆盖物固定在其中央,地图左下角的白色正方形是回到定位点的按钮,因为没找到好看的图片,就留着空白了

下面是一个listView,显示地图指示地点周围的一些位置信息

贴一下实现该功能的核心代码

Activity类

package com.vr.souhuodong.UI.Sou;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Intent;import android.graphics.Point;import android.net.Uri;import android.os.Bundle;import android.view.MotionEvent;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ImageView;import android.widget.ListView;import android.widget.ProgressBar;import com.baidu.location.BDLocation;import com.baidu.location.BDLocationListener;import com.baidu.location.LocationClient;import com.baidu.location.LocationClientOption;import com.baidu.mapapi.map.BaiduMap;import com.baidu.mapapi.map.BaiduMap.OnMapTouchListener;import com.baidu.mapapi.map.BitmapDescriptor;import com.baidu.mapapi.map.BitmapDescriptorFactory;import com.baidu.mapapi.map.MapStatusUpdate;import com.baidu.mapapi.map.MapStatusUpdateFactory;import com.baidu.mapapi.map.MapView;import com.baidu.mapapi.map.MarkerOptions;import com.baidu.mapapi.map.MyLocationConfiguration;import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;import com.baidu.mapapi.map.MyLocationData;import com.baidu.mapapi.map.OverlayOptions;import com.baidu.mapapi.model.LatLng;import com.baidu.mapapi.search.core.PoiInfo;import com.baidu.mapapi.search.core.SearchResult;import com.baidu.mapapi.search.geocode.GeoCodeResult;import com.baidu.mapapi.search.geocode.GeoCoder;import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;import com.vr.souhuodong.R;import com.vr.souhuodong.UI.Adapter.PlaceListAdapter;public class ChoosePlaceActivity extends Activity {MapView mMapView;BaiduMap mBaiduMap;ProgressBar mLoadBar;ImageView mSelectImg;// 定位LocationClient mLocationClient = null;MyBDLocationListner mListner = null;BitmapDescriptor mCurrentMarker = null;// 当前经纬度double mLantitude;double mLongtitude;LatLng mLoactionLatLng;// 设置第一次定位标志boolean isFirstLoc = true;// MapView中央对于的屏幕坐标Point mCenterPoint = null;// 地理编码GeoCoder mGeoCoder = null;// 位置列表ListView mListView;PlaceListAdapter mAdapter;List<PoiInfo> mInfoList;PoiInfo mCurentInfo;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_chooseplace);initView();}/** * 初始化界面 */private void initView() {// TODO Auto-generated method stub// 初始化地图mMapView = (MapView) findViewById(R.id.chooseplace_bmapView);mMapView.showZoomControls(false);mBaiduMap = mMapView.getMap();MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(17.0f);mBaiduMap.setMapStatus(msu);mBaiduMap.setOnMapTouchListener(touchListener);// 初始化POI信息列表mInfoList = new ArrayList<PoiInfo>();// 初始化当前MapView中心屏幕坐标,初始化当前地理坐标mCenterPoint = mBaiduMap.getMapStatus().targetScreen;mLoactionLatLng = mBaiduMap.getMapStatus().target;// 定位mBaiduMap.setMyLocationEnabled(true);mLocationClient = new LocationClient(this);mListner = new MyBDLocationListner();mLocationClient.registerLocationListener(mListner);LocationClientOption option = new LocationClientOption();option.setOpenGps(true);// 打开gpsoption.setCoorType("bd09ll"); // 设置坐标类型option.setScanSpan(1000);mLocationClient.setLocOption(option);mLocationClient.start();// 地理编码mGeoCoder = GeoCoder.newInstance();mGeoCoder.setOnGetGeoCodeResultListener(GeoListener);// 周边位置列表mListView = (ListView) findViewById(R.id.place_list);mLoadBar = (ProgressBar) findViewById(R.id.place_progressBar);mListView.setOnItemClickListener(itemClickListener);mAdapter = new PlaceListAdapter(getLayoutInflater(), mInfoList);mListView.setAdapter(mAdapter);mSelectImg = new ImageView(this);}public void turnBack(View view) {// 实现动画跳转MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(mLoactionLatLng);mBaiduMap.animateMapStatus(u);mBaiduMap.clear();// 发起反地理编码检索mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(mLoactionLatLng));}@Overrideprotected void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();mLocationClient.stop();mGeoCoder.destroy();}// 定位监听器private class MyBDLocationListner implements BDLocationListener {@Overridepublic void onReceiveLocation(BDLocation location) {// TODO Auto-generated method stub// map view 销毁后不在处理新接收的位置if (location == null || mMapView == null)return;MyLocationData data = new MyLocationData.Builder()//// .direction(mCurrentX)//.accuracy(location.getRadius())//.latitude(location.getLatitude())//.longitude(location.getLongitude())//.build();mBaiduMap.setMyLocationData(data);// 设置自定义图标MyLocationConfiguration config = new MyLocationConfiguration(LocationMode.NORMAL, true, null);mBaiduMap.setMyLocationConfigeration(config);mLantitude = location.getLatitude();mLongtitude = location.getLongitude();LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);mLoactionLatLng = new LatLng(mLantitude, mLongtitude);// 是否第一次定位if (isFirstLoc) {isFirstLoc = false;// 实现动画跳转MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(currentLatLng);mBaiduMap.animateMapStatus(u);mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(currentLatLng));return;}}}// 地理编码监听器OnGetGeoCoderResultListener GeoListener = new OnGetGeoCoderResultListener() {public void onGetGeoCodeResult(GeoCodeResult result) {if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {// 没有检索到结果}// 获取地理编码结果}@Overridepublic void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {// 没有找到检索结果}// 获取反向地理编码结果else {// 当前位置信息mCurentInfo = new PoiInfo();mCurentInfo.address = result.getAddress();mCurentInfo.location = result.getLocation();mCurentInfo.name = "[位置]";mInfoList.clear();mInfoList.add(mCurentInfo);// 将周边信息加入表if (result.getPoiList() != null) {mInfoList.addAll(result.getPoiList());}// 通知适配数据已改变mAdapter.notifyDataSetChanged();mLoadBar.setVisibility(View.GONE);}}};// 地图触摸事件监听器OnMapTouchListener touchListener = new OnMapTouchListener() {@Overridepublic void onTouch(MotionEvent event) {// TODO Auto-generated method stubif (event.getAction() == MotionEvent.ACTION_UP) {if (mCenterPoint == null) {return;}// 获取当前MapView中心屏幕坐标对应的地理坐标LatLng currentLatLng;currentLatLng = mBaiduMap.getProjection().fromScreenLocation(mCenterPoint);System.out.println("—-" + mCenterPoint.x);System.out.println("—-" + currentLatLng.latitude);// 发起反地理编码检索mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption()).location(currentLatLng));mLoadBar.setVisibility(View.VISIBLE);}}};// listView选项点击事件监听器OnItemClickListener itemClickListener = new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {// TODO Auto-generated method stub// 通知是适配器第position个item被选择了mAdapter.setNotifyTip(position);BitmapDescriptor mSelectIco = BitmapDescriptorFactory.fromResource(R.drawable.icon_geo);mBaiduMap.clear();PoiInfo info = (PoiInfo) mAdapter.getItem(position);LatLng la = info.location;// 动画跳转MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(la);mBaiduMap.animateMapStatus(u);// 添加覆盖物OverlayOptions ooA = new MarkerOptions().position(la).icon(mSelectIco).anchor(0.5f, 0.5f);mBaiduMap.addOverlay(ooA);// 选中项打勾mSelectImg.setBackgroundResource(R.drawable.greywhite);mSelectImg = (ImageView) view.findViewById(R.id.place_select);mSelectImg.setBackgroundResource(R.drawable.ic_select);//Uri mUri = Uri.parse("geo:39.940409,116.355257");//Intent mIntent = new Intent(Intent.ACTION_VIEW,mUri);//startActivity(mIntent);}};}既有美妙的风景,也会有称不上景、只有风的地方。

利用百度地图Android sdk高仿微信发送位置功能

相关文章:

你感兴趣的文章:

标签云: