接触了百度地图开发平台半个月了,这2天试着模仿了微信给好友发送位置功能,对百度地图的操作能力又上了一个台阶
(如果需要完整demo,请评论留下邮箱)
我在实现这个功能的时候,遇到一些困难,可能也是别人将会遇到的困难,特在此列出
1、在微信发送功能中,不管用户如何拖拽地图,总有个覆盖物固定了MapView*,怎么实现?
其实这很容易实现,只要MapView的布局文件中,将一个ImageView覆盖在MapView的*,就能够实现不管用户如何拖拽地图,覆盖物(ImageView)总固定总MapView*
2、如何获取MapView*的地理坐标,也即是屏幕覆盖物处的坐标?
要获取MapView*的地理坐标,首先先获取覆盖物在屏幕上的物理坐标,这里得区别一下地理坐标(经纬度)和物理坐标(xy轴);
可以通过
- <mCenterPoint = mBaiduMap.getMapStatus().targetScreen;//mBaiduMap是BaiduMap类的实例
- currentLatLng = mBaiduMap.getProjection().fromScreenLocation(
- mCenterPoint);
3、如何获取该地理坐标周围的所有poi信息(也就是周围建筑物的信息),而不只是某个类型的兴趣点?
为了实现这个功能,真是费了我好大劲,因为我之前一直以为用POI周边搜索实现的,有人提示我可以通过循环轴线搜索实现不同关键字搜索,但这样子确实很难实现跟微信那样的效果。通过查看API,发现可以通过反地理编码解决这个问题,至于什么事反地理编码,可以到百度地图官网了解,通过调用它,可以返回一个该地理坐标附近建筑信息的一个列表
4、当用户拖拽地图,如何让列表更新到目前中心地理位置的周边信息?
这个困难其实也不难实现,只是重写mBaiduMap.setOnMapTouchListener(touchListener);触摸事件,在触摸监听器的回调函数中
将MapView*的物理坐标转换成对应的地理坐标,再通过反地理编码获取周边信息,道理同问题3
5、当点击listview某一项时,如何将项地理位置显示在MapView也就是屏幕*?
很简单,通过listview的适配器获取item的位置信息,包括经纬度,然后用动画跳转到屏幕*位置即可。
我认为上面5个问题是实现这个功能的关键所在,下面是效果图(如果需要完整demo,请评论留下邮箱)
上面是一个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);
- // }
- //
- // }
- }