您好,登錄后才能下訂單哦!
接觸了百度地圖開發平臺半個月了,這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; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.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);// 打開gps option.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)); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); mLocationClient.stop(); mGeoCoder.destroy(); } // 定位監聽器 private class MyBDLocationListner implements BDLocationListener { @Override public 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) { // 沒有檢索到結果 } // 獲取地理編碼結果 } @Override public 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() { @Override public void onTouch(MotionEvent event) { // TODO Auto-generated method stub if (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() { @Override public 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); } }; }
自定義的listView適配器
package com.vr.souhuodong.UI.Adapter; import java.util.List; import android.R.integer; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.baidu.mapapi.search.core.PoiInfo; import com.vr.souhuodong.R; public class PlaceListAdapter extends BaseAdapter { List<PoiInfo> mList; LayoutInflater mInflater; int notifyTip ; private class MyViewHolder { TextView placeName; TextView placeAddree; ImageView placeSelected; } public PlaceListAdapter(LayoutInflater mInflater , List<PoiInfo> mList) { super(); this.mList = mList; this.mInflater = mInflater; notifyTip = -1 ; } /** * 設置第幾個item被選擇 * @param notifyTip */ public void setNotifyTip(int notifyTip) { this.notifyTip = notifyTip; } @Override public int getCount() { // TODO Auto-generated method stub return mList.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return mList.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub MyViewHolder holder; if (convertView == null) { System.out.println("----aa-"); convertView = mInflater.inflate(com.vr.souhuodong.R.layout.listitem_place, parent, false); holder = new MyViewHolder(); holder.placeName = (TextView) convertView .findViewById(com.vr.souhuodong.R.id.place_name); holder.placeAddree = (TextView) convertView .findViewById(com.vr.souhuodong.R.id.place_adress); holder.placeSelected = (ImageView) convertView .findViewById(com.vr.souhuodong.R.id.place_select); holder.placeName.setText(mList.get(position).name); holder.placeAddree.setText(mList.get(position).address); holder.placeSelected.setBackgroundResource(R.drawable.greywhite); convertView.setTag(holder); } else { holder = (MyViewHolder) convertView.getTag(); } holder.placeName.setText(mList.get(position).name); holder.placeAddree.setText(mList.get(position).address); //根據重新加載的時候第position條item是否是當前所選擇的,選擇加載不同的圖片 if(notifyTip == position ){ holder.placeSelected.setBackgroundResource(R.drawable.ic_select); } else { holder.placeSelected.setBackgroundResource(R.drawable.greywhite); } return convertView; } // class MyItemClickListener implements OnClickListener { // // ImageView mImg; // public MyItemClickListener(ImageView mImg) { // this.mImg = mImg; // } // @Override // public void onClick(View v) { // // TODO Auto-generated method stub // mImg.setBackgroundResource(R.drawable.ic_select); // } // // } }
總結
以上所述是小編給大家介紹的利用百度地圖Android sdk高仿微信發送位置功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。