android 获取地图中心点的经纬度坐标

最近项目中需要让用户在 地图上选择 商户的位置,需要有一个图标一直在屏幕的正中央,然后用户拖动地图的时候,动态解析中心点的地址信息,效果图如下:



废话不多说了,直接上代码吧


界面布局文件 select_shoplocation.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/rl_topbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/list_topbar_height"
        android:background="@drawable/list_bar" >

        <Button
            android:id="@+id/bt_back"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="@dimen/list_topbar_margin"
            android:layout_marginRight="@dimen/favorite_op_margin"
            android:background="@drawable/list_icon_back" />

        <TextView
            android:id="@+id/tv_map_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_centerVertical="true"
            android:text="@string/know_shop"
            android:textColor="@color/white"
            android:textSize="22sp" />

        <Button
            android:id="@+id/bt_save"
            android:layout_width="35dp"
            android:layout_height="35dp"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="@dimen/list_topbar_margin"
            android:layout_marginRight="@dimen/favorite_op_margin"
            android:background="@drawable/icon_ok" />
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <com.yulore.yellowpage.view.MyMapView
            android:id="@+id/mapView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:apiKey="@string/maps_api_key"
            android:clickable="true" />
        
        <com.yulore.yellowpage.view.MyCenterPoint
            android:id="@+id/bt_mapCenter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"/>
        
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:background="#3D3F49" >

        <TextView
            android:id="@+id/tv_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_marginLeft="15dp"
            android:textColor="@color/white"
            android:textSize="13sp" />
    </RelativeLayout>

</LinearLayout>


这里我自定义了两个View:MyMapView、MyCenterPoint,MyMapView继承自 MapView,因为我们需要拦截触摸事件。


MyMapView.java 

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.mapabc.mapapi.core.GeoPoint;
import com.mapabc.mapapi.map.MapView;

public class MyMapView extends MapView {
	private OnMapViewChangedListener mListener;

	public void setOnMapViewChangedListener(OnMapViewChangedListener mListener) {
		this.mListener = mListener;
	}

	public MyMapView(Context arg0, AttributeSet arg1) {
		super(arg0, arg1);
		// TODO Auto-generated constructor stub
	}

	public MyMapView(Context arg0, AttributeSet arg1, int arg2) {
		super(arg0, arg1, arg2);
		// TODO Auto-generated constructor stub
	}

	public MyMapView(Context arg0, String arg1, String arg2) {
		super(arg0, arg1, arg2);
		// TODO Auto-generated constructor stub
	}

	public MyMapView(Context arg0, String arg1) {
		super(arg0, arg1);
		// TODO Auto-generated constructor stub
	}

	@Override
	public boolean onTouchEvent(MotionEvent arg0) {
		
		GeoPoint g = this.getProjection().fromPixels(MyCenterPoint.w, MyCenterPoint.h);
		
		if(mListener!=null)
			mListener.onMapViewChanged(g);
		
		return super.onTouchEvent(arg0);
	}
	/**
	 * 回调接口
	 * @author FX_SKY
	 *
	 */
	public interface OnMapViewChangedListener{
		
		public void onMapViewChanged(GeoPoint point);
	}

}


MyCenterPoint.java

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

import com.yulore.yellowpage.R;

public class MyCenterPoint extends View {

	public static int w;
	public static int h;
	public static  Bitmap mBitmap;

	public MyCenterPoint(Context context) {
		super(context);
	}

	public MyCenterPoint(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public MyCenterPoint(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_map);
		
		w = this.getWidth() / 2 - mBitmap.getWidth() / 2;
		h = this.getHeight() / 2 - mBitmap.getHeight() / 2;
		canvas.drawBitmap(mBitmap, w, h, null);
	}

}


地图界面 SelectLocationActivity

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.mapabc.mapapi.core.GeoPoint;
import com.mapabc.mapapi.core.MapAbcException;
import com.mapabc.mapapi.core.OverlayItem;
import com.mapabc.mapapi.geocoder.Geocoder;
import com.mapabc.mapapi.map.ItemizedOverlay;
import com.mapabc.mapapi.map.MapActivity;
import com.mapabc.mapapi.map.MapController;
import com.mapabc.mapapi.map.MapView;
import com.umeng.analytics.MobclickAgent;
import com.yulore.yellowpage.http.BaseTask;
import com.yulore.yellowpage.http.NetUtil;
import com.yulore.yellowpage.http.RequestVo;
import com.yulore.yellowpage.parser.ResultParser;
import com.yulore.yellowpage.util.CommonUtil;
import com.yulore.yellowpage.util.Constant;
import com.yulore.yellowpage.util.LogUtil;
import com.yulore.yellowpage.util.ThreadPoolManager;
import com.yulore.yellowpage.view.MyCenterPoint;
import com.yulore.yellowpage.view.MyMapView;
import com.yulore.yellowpage.view.MyMapView.OnMapViewChangedListener;

/**
 * 显示店铺位置 界面
 * 
 * @author feng bingbing
 * 
 */
public class SelectLocationActivity extends MapActivity implements
		OnClickListener {

	private static final String TAG = SelectLocationActivity.class
			.getSimpleName();
	private MyMapView mMapView;
	private MapController mMapController;
	private ProgressDialog mProgressDialog = null;
	double lat = 0.0f, lng = 0.0f;
	double oldLat = 0.0f, oldLng = 0.0f;
	private Geocoder coder;// 逆地理编码
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case Constant.QUERY_ADDRESS_SUCCESS:

				address = (String) msg.obj;
				if (address != null) {
					tv_address.setText(address.concat("( ")
							.concat(String.format("%.6f", lat)).concat(",")
							.concat(String.format("%.6f", lng)).concat(" )"));
				}

				break;
			case Constant.QUERY_ADDRESS_FAILED:
				Toast.makeText(getApplicationContext(),
						R.string.map_query_address_failed, 0).show();
				break;

			case Constant.REQUEST_SERVER_SUCCESS:
				mProgressDialog.dismiss();
				String result = msg.obj.toString();
				if (result.equals("0")) {
					Toast.makeText(getApplicationContext(), "您的更改已经提交成功",
							Toast.LENGTH_SHORT).show();
					finish();
					overridePendingTransition(R.anim.back_left_in,
							R.anim.back_right_out);
				} else {
					Toast.makeText(getApplicationContext(), "提交失败,请稍后重新提交",
							Toast.LENGTH_SHORT).show();
				}

				break;

			default:
				if (mProgressDialog != null && mProgressDialog.isShowing()) {
					mProgressDialog.dismiss();
				}
				break;
			}
		};
	};
	private TextView tv_address;
	private int type;
	private TextView tv_map_title;
	private Button bt_save;
	private Button bt_back;
	private RelativeLayout rl_topbar;
	private String address;
	private String shopId;
	private MyCenterPoint bt_mapCenter;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.select_shoplocation);

		LogUtil.i(TAG, "onCreate");

		findView();

		Intent intent = getIntent();
		if (intent != null) {
			String location = intent.getStringExtra("location");

			if (location != null && location.length() > 0) {
				String[] arr = location.split(",");
				lat = Double.parseDouble(arr[0]);
				lng = Double.parseDouble(arr[1]);
				oldLat = lat;
				oldLng = lng;
			}

			type = intent.getIntExtra("type", 1);
			address = intent.getStringExtra("address");

			if (address != null) {
				tv_address.setText(address.concat("( ")
						.concat(String.valueOf(lat)).concat(",")
						.concat(String.valueOf(lng)).concat(" )"));
			}

			shopId = intent.getStringExtra("shopId");
		}

		LogUtil.i(TAG, "onCreate:" + lat + ">>" + lng);

		mMapView.setVectorMap(true);
		mMapView.setBuiltInZoomControls(true);
		mMapController = mMapView.getController();

		coder = new Geocoder(this, getResources().getString(
				R.string.maps_api_key)); // 根据给定的API Key 构造Geocoder 对象

		mMapController.setZoom(15);
		// 设为当前位置显示
		GeoPoint p1 = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));

		switch (type) {
		case 1: // 详情
			rl_topbar.setBackgroundResource(R.drawable.bar);
			bt_back.setBackgroundResource(R.drawable.icon_back);
			tv_map_title.setText("商户位置");
			tv_map_title.setTextColor(getResources().getColorStateList(
					R.color.black));
			bt_save.setVisibility(View.GONE);
			bt_mapCenter.setVisibility(View.GONE);

			if(lat>0 && lng>0){
				newOverlay(lat, lng);
			}else{
				Toast.makeText(getApplicationContext(), "经纬度坐标信息有误", Toast.LENGTH_LONG).show();
			}

			break;
		case 2: // 纠错
			tv_map_title.setText("商户位置错误");
			bt_save.setVisibility(View.VISIBLE);

			mMapController.setCenter(p1); // 设置地图中心点
			mMapController.setCenter(p1); // 设置地图中心点
			mMapView.setOnMapViewChangedListener(new MyOnMapViewChangedListener());

			if(lat>0 && lng>0){
				reverseAddress(lat, lng);
			}else{
				Toast.makeText(getApplicationContext(), "经纬度坐标信息有误", Toast.LENGTH_LONG).show();
			}
			
			break;
		case 3: // 我知道商户
			tv_map_title.setText("请选择商户位置");
			bt_save.setVisibility(View.VISIBLE);

			mMapController.setCenter(p1); // 设置地图中心点
			mMapView.setOnMapViewChangedListener(new MyOnMapViewChangedListener());
			
			//初始化 地图中心点
			if(lat>0 && lng>0){
				reverseAddress(lat, lng);
			}else{
				Toast.makeText(getApplicationContext(), "经纬度坐标信息有误", Toast.LENGTH_LONG).show();
			}
			break;
		default:
			break;
		}

	}

	private class MyOnMapViewChangedListener implements
			OnMapViewChangedListener {

		@Override
		public void onMapViewChanged(GeoPoint point) {

			if (point != null) {
				lat = (float) (point.getLatitudeE6() / 1E6);
				lng = (float) (point.getLongitudeE6() / 1E6);

				// LogUtil.i(TAG, "lat:" + lat + ",lng" + lng);

				reverseAddress(lat,lng);
			}
		}
	}
	
	/**
	 * 根据经纬度 解析地址信息
	 * @param lat
	 * @param lng
	 */
	private void reverseAddress(final double lat, final double lng) {
		
		Runnable task = new Runnable() {

			@Override
			public void run() {
				try {
					List<Address> list = coder.getFromLocation(lat,
							lng, 3);

					StringBuffer sb = new StringBuffer();

					if (list != null && list.size() > 0) {
						Address address = list.get(0);
						String adminArea = address.getAdminArea();
						String locality = address.getLocality();
						String subLocality = address.getSubLocality();
						String feature = address.getFeatureName();

						sb.append(adminArea).append(locality)
								.append(subLocality).append(feature);

						// LogUtil.e(TAG, "adminArea:" + adminArea
						// + ",locality:" + locality + ",subLocality:"
						// + subLocality + ",feature:" + feature);
					}

					Message msg = Message.obtain();
					msg.what = Constant.QUERY_ADDRESS_SUCCESS;
					msg.obj = sb.toString();
					handler.sendMessage(msg);

				} catch (MapAbcException e) {
					e.printStackTrace();
					handler.sendEmptyMessage(Constant.QUERY_ADDRESS_FAILED);
				}
			}
		};
		ThreadPoolManager.getInstance().addTask(task);
	}

	public void onResume() {
		super.onResume();
		MobclickAgent.onResume(this);
	}

	public void onPause() {
		super.onPause();
		MobclickAgent.onPause(this);
	}

	public void newOverlay(double lat, double lng) {

		mMapView.getOverlays().clear();
		Drawable marker = null;
		if (type == 1) {
			marker = getResources().getDrawable(R.drawable.icon_map_local); // 得到需要标在地图上的资源
		} else {
			marker = getResources().getDrawable(R.drawable.icon_map); // 得到需要标在地图上的资源
		}

		marker.setBounds(0, 0, marker.getIntrinsicWidth(),
				marker.getIntrinsicHeight()); // 为maker定义位置和边界
		mMapView.getOverlays().add(new OverItemT(marker, this)); // 添加ItemizedOverlay实例到mMapView

		// 设为当前位置显示
		GeoPoint p1 = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
		// mMapController.animateTo(p1);
		mMapController.setCenter(p1); // 设置地图中心点

	}

	private void findView() {
		mMapView = (MyMapView) findViewById(R.id.mapView);
		bt_back = (Button) findViewById(R.id.bt_back);
		bt_save = (Button) findViewById(R.id.bt_save);
		rl_topbar = (RelativeLayout) findViewById(R.id.rl_topbar);
		bt_mapCenter = (MyCenterPoint) findViewById(R.id.bt_mapCenter);

		tv_address = (TextView) findViewById(R.id.tv_address);
		tv_map_title = (TextView) findViewById(R.id.tv_map_title);

		bt_back.setOnClickListener(this);
		bt_save.setOnClickListener(this);
	}

	/**
	 * 分条目覆盖物。当某个类型的覆盖物,包含多个类型相同、显示方式相同、处理方式相同的项时,使用此类。
	 */
	class OverItemT extends ItemizedOverlay<OverlayItem> {
		private List<OverlayItem> GeoList = new ArrayList<OverlayItem>();
		private Drawable marker;
		private Context mContext;

		public OverItemT(Drawable marker, Context context) {
			super(boundCenterBottom(marker));
			this.marker = marker;
			this.mContext = context;
			// 用给定的经纬度构造GeoPoint,单位是微度(度 * 1E6)
			GeoPoint p1 = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
			// 构造OverlayItem的三个参数依次为:item的位置,标题文本,文字片段
			GeoList.add(new OverlayItem(p1, "", ""));
			populate(); // createItem(int)方法构造item。一旦有了数据,在调用其它方法前,首先调用这个方法
		}

		@Override
		public void draw(Canvas canvas, MapView mapView, boolean shadow) {

			super.draw(canvas, mapView, false);
			// 调整一个drawable边界,使得(0,0)是这个drawable底部最后一行中心的一个像素
			boundCenterBottom(marker);
		}

		@Override
		protected OverlayItem createItem(int i) {
			// TODO Auto-generated method stub
			return GeoList.get(i);
		}

		@Override
		public int size() {
			// TODO Auto-generated method stub
			return GeoList.size();
		}

		@Override
		public boolean onTap(GeoPoint point, MapView mapView) {

			return super.onTap(point, mapView);
		}
	}

	private HashMap<String, String> toJsonStr() {
		HashMap<String, String> map = new HashMap<String, String>();
		map.put("errortype", "mAddress");
		map.put("shopid", shopId);
		map.put("system", "2");
		map.put("version",
				CommonUtil.getAppVersionCode(getApplicationContext()));
		map.put("uid", CommonUtil.getDeviceID(getApplicationContext()));
		map.put("lat", String.valueOf(lat));
		map.put("lng", String.valueOf(lng));
		return map;
	}

	private void postData() {
		mProgressDialog = new ProgressDialog(this);
		mProgressDialog.setMessage("正在提交...");
		mProgressDialog.setIndeterminate(false);
		mProgressDialog.setMax(100);
		mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
		mProgressDialog.setCancelable(false);
		mProgressDialog.setCanceledOnTouchOutside(false);
		mProgressDialog.show();
		RequestVo requestVo = new RequestVo();
		requestVo.context = getApplicationContext();
		requestVo.requestUrl = Constant.APP_HOST
				.concat(Constant.CORRECTION_INFO);
		requestVo.jsonParser = new ResultParser();
		requestVo.requestDataMap = toJsonStr();
		requestVo.type = 1;
		BaseTask task = new BaseTask(getApplicationContext(), requestVo,
				handler);
		ThreadPoolManager.getInstance().addTask(task);
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bt_back:
			this.finish();
			overridePendingTransition(R.anim.back_left_in,
					R.anim.back_right_out);
			break;
		case R.id.bt_save:
			if (type == 2) {
				if (oldLat != lat || oldLng != lng) {
					if (NetUtil.hasNetwork(getApplicationContext())) {
						postData();
					} else {
						Toast.makeText(getApplicationContext(), "网络环境不可用",
								Toast.LENGTH_SHORT).show();
					}
				} else {
					Toast.makeText(getApplicationContext(), "您的更改已经提交成功",
							Toast.LENGTH_SHORT).show();
					finish();
					overridePendingTransition(R.anim.back_left_in,
							R.anim.back_right_out);
				}
			} else {
				Intent data = new Intent();
				data.putExtra("address", address);
				data.putExtra("lat", lat);
				data.putExtra("lng", lng);
				setResult(Constant.REQUEST_MAP_ADDRESS, data);

				this.finish();
				overridePendingTransition(R.anim.back_left_in,
						R.anim.back_right_out);
			}

			break;

		default:
			break;
		}
	}

	// 处理后退键的情况
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			this.finish(); // finish当前activity
			// 设置切换动画,从上边进入,下边退出
			overridePendingTransition(R.anim.back_left_in,
					R.anim.back_right_out);
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}
}




这里我使用的是Mapabc地图,其他的像 Baidu、Google 实现方式都是类似的,这里不贴了,有兴趣的同学 自己可以实现。






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值