不解释,代码如下:
package org.wx.test;
import java.io.InputStream;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
/**
* 通过物理位置或GPS坐标在地图上进行定位并标记
* 显示google地图 地图有三种显示形式,默认的是传统矢量图,还包括卫星照片和地形视图(显示地形和等高线)
*
* @author wx
*
*/
public class MyMapView extends MapActivity {
private MapView map = null;
private MapController controller = null;
private GeoPoint p = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapview);
// 获得地图
map = (MapView) findViewById(R.id.map);
// 设置显示为交通图(街景图无法显示)
map.setTraffic(true);
map.setSatellite(false);
controller = map.getController();
// 设置地图中心为北京市,这里应该改为通过GPS定位指定位置
map.getController().setCenter(new GeoPoint(39971036, 116314659));
// 设置缩放级别
controller.setZoom(16);
// 显示缩放控件
map.setBuiltInZoomControls(true);
// 这里传入字符串进行地理位置的解析
address2GeoPoint("印度新德里");
}
/**
* 根据获取坐标是否成功的结果进行相应处理
*/
private Handler handler = new Handler() {
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0:
// 获得坐标信息
Bundle b = msg.getData();
int[] ad = b.getIntArray("latlong");
p = new GeoPoint((ad[0]), ad[1]);
// 将显示位置设置为或的的坐标
controller.setCenter(p);
// 在地图上标上现在的位置
List overlays = map.getOverlays();
overlays.add(new PositonOverLay(p, MyMapView.this,
android.R.drawable.ic_notification_overlay));// 使用系统自带的图标
break;
case 1:
Toast.makeText(MyMapView.this, "没有获取到位置信息", 1).show();
break;
case 2:
Toast.makeText(MyMapView.this, "异常信息", 1).show();
break;
case 3:
Toast.makeText(MyMapView.this, "非法的坐标", 1).show();
break;
}
}
};
/**
* 调用此方法解析地址并在地图上显示
*
* @param address
*/
private void address2GeoPoint(final String address) {
new Thread(new Runnable() {
@Override
public void run() {
try {
// 以下代码的服务没有支持,所以得不到结果,只能通过Http请求访问Google 来进行解析咯
// Geocoder geoCoder = new
// Geocoder(MyMapView.this,
// Locale.getDefault());
// List<Address> addresses =
// geoCoder.getFromLocationName(
// "湖北省武汉市珞瑜路华乐商务中心", 5);
GeoPoint g = null;
if (address.contains(",")) {
// 如果传入的是坐标
// 根据传入的字符串格式解析成坐标,传入的字符串,纬度在前,经度在后
String[] geo = address.trim().split(",");
double latitude = Double.parseDouble(geo[0]);
double longitude = Double.parseDouble(geo[1]);
int latitudeE6 = (int) (latitude * 1E6);
int longitudeE6 = (int) (longitude * 1E6);
if (latitude < -90.0 || latitude > 90.0) {
throw new IllegalArgumentException("latitude == "
+ latitude);
}
if (longitude < -180.0 || longitude > 180.0) {
throw new IllegalArgumentException("longitude == "
+ longitude);
}
g = new GeoPoint(latitudeE6, longitudeE6);
} else {
// 如果传入的是物理地址
g = getLatLong(getLocationInfo(address));
}
if (g.getLatitudeE6() != 0 && g.getLongitudeE6() != 0) {
Message msg = new Message();
msg.what = 0;
// 传递数据
Bundle data = new Bundle();
int[] latlong = new int[2];
latlong[0] = g.getLatitudeE6();// 纬度
latlong[1] = g.getLongitudeE6();// 经度
data.putIntArray("latlong", latlong);
msg.setData(data);
handler.sendMessage(msg);
} else {
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
}
} catch (IllegalArgumentException ie) {
Message msg = new Message();
msg.what = 3;
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
Message msg = new Message();
msg.what = 2;
handler.sendMessage(msg);
}
}
}).start();
}
/**
* 传入物理地址
*
* @param address 物理地址
* @return JSONObject
*/
private JSONObject getLocationInfo(String address) {
StringBuilder stringBuilder = new StringBuilder();
InputStream stream = null;
try {
// 请求中空格字符的转意
address = address.replaceAll(" ", "%20");
stringBuilder = new StringBuilder();
HttpPost httppost = new HttpPost(
"http://maps.google.com/maps/api/geocode/json?address="
+ address + "&sensor=false");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
response = client.execute(httppost);
HttpEntity entity = response.getEntity();
stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(stream != null)
stream.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
stream = null;
}
}
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(stringBuilder.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* 通过传入的jsonObject获得坐标值
* @param jsonObject
* @return GeoPoint
*/
private GeoPoint getLatLong(JSONObject jsonObject) {
Double lon = new Double(0);
Double lat = new Double(0);
try {
JSONArray jsonArray = (JSONArray) jsonObject.get("results");
if (jsonArray != null && jsonArray.length() > 0) {
lon = jsonArray.getJSONObject(0).getJSONObject("geometry")
.getJSONObject("location").getDouble("lng");
lat = jsonArray.getJSONObject(0).getJSONObject("geometry")
.getJSONObject("location").getDouble("lat");
}
} catch (Exception e) {
e.printStackTrace();
}
return new GeoPoint((int) (lat * 1E6), (int) (lon * 1E6));
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
/**
* 创建菜单,进行交通图和卫星图的切换,(大陆不支持街景图)
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, 1, 1, "交通图");
menu.add(0, 2, 2, "卫星图");
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case 1:
map.setTraffic(true);
map.setSatellite(false);
break;
case 2:
map.setTraffic(false);
map.setSatellite(true);
break;
default:
map.setTraffic(true);
map.setSatellite(false);
break;
}
return true;
}
/**
* 将GeoPoint 映射为Point 即将GPS坐标转换为地图上的x,y坐标系上对应的坐标点 并在指定位置画上 标记
* @author wx
*/
class PositonOverLay extends Overlay {
private GeoPoint geo;
private Context context;
private int drawable;
public PositonOverLay(GeoPoint geo, Context context, int drawable) {
super();
this.geo = geo;
this.context = context;
this.drawable = drawable;
}
@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
Projection projection = mapView.getProjection();
Point point = new Point();
projection.toPixels(geo, point);
Bitmap bitmap = BitmapFactory.decodeResource(
context.getResources(), drawable);
canvas.drawBitmap(bitmap, point.x - bitmap.getWidth() / 2, point.y
- bitmap.getHeight(), null);
return super.draw(canvas, mapView, shadow, when);
}
}
}
layout文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<com.google.android.maps.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:enabled="true"
android:clickable="true"
android:apiKey="0vOQchwJ8y1yIMIXbnWRAls_PG737JPZXu7WmYg"
/>
</LinearLayout>
mani文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.wx.test">
<application android:label="@string/activity_sample_code"
android:icon="@drawable/app_sample_code" >
<uses-library android:name="com.google.android.maps" />
<activity android:name="org.wx.test.MyMapView" android:label="MapView"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.maps" />
<uses-sdk android:minSdkVersion="8" />
</manifest>