接著上面的項目《Android訪問webservice.客戶端登錄注冊》http://www.linuxidc.com/Linux/2013-04/82747.htm,實現餐廳搜索,這個在吃客游記裡就做過了,然後把餐廳顯示出來,可以把該餐廳加入軌跡
關於軌跡點操作的前後台實現和之前的登錄注冊差不多,這裡主要說一下,用戶查看自己的軌跡時候,在手機
端的顯示。
1.從服務器把軌跡點拿下來
2.地圖上顯示點
3.把點連成線
看代碼吧,注釋比較詳細,關鍵的畫線操作就在OverItemT這個類中。
package seu.android007.xin;
import java.util.ArrayList;
import java.util.List;
import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.GeoPoint;
import com.baidu.mapapi.ItemizedOverlay;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MapActivity;
import com.baidu.mapapi.MapView;
import com.baidu.mapapi.MyLocationOverlay;
import com.baidu.mapapi.OverlayItem;
import com.baidu.mapapi.Projection;
import seu.android007.service.TraceServcie;
import seu.xin.entity.Trace;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Toast;
public class MyTrace extends MapActivity {
static MapView mMapView = null;
LocationListener mLocationListener = null;// onResume時注冊此listener,onPause時需要Remove
MyLocationOverlay mLocationOverlay = null; // 定位圖層
static View mPopView = null; // 點擊mark時彈出的氣泡View
TraceServcie traceServcie;
private ArrayList<Trace> myTraces = new ArrayList<Trace>();
SharedPreferences sp;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_trace);
traceServcie = new TraceServcie();
sp = this.getSharedPreferences("data", MODE_WORLD_READABLE);
int uid = sp.getInt("uid", 0);
myTraces = traceServcie.findTracesByUid(uid);
BMapApp app = (BMapApp) this.getApplication();
if (app.mBMapMan == null) {
app.mBMapMan = new BMapManager(getApplication());
app.mBMapMan.init(app.mStrKey, new BMapApp.MyGeneralListener());
}
app.mBMapMan.start();
// 如果使用地圖SDK,請初始化地圖Activity
super.initMapActivity(app.mBMapMan);
mMapView = (MapView) findViewById(R.id.bmapView);
mMapView.setBuiltInZoomControls(true);
// 設置在縮放動畫過程中也顯示overlay,默認為不繪制
mMapView.setDrawOverlayWhenZooming(true);
// 添加定位圖層
mLocationOverlay = new MyLocationOverlay(this, mMapView);
mMapView.getOverlays().add(mLocationOverlay);
// 注冊定位事件
mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
if (location != null) {
GeoPoint pt = new GeoPoint(
(int) (location.getLatitude() * 1e6),
(int) (location.getLongitude() * 1e6));
mMapView.getController().animateTo(pt);
}
}
};
if (myTraces.size() == 0) {
System.out.println("軌跡為空,調轉到MyActivityGroup");
AlertDialog.Builder builder = new AlertDialog.Builder(MyTrace.this);
builder.setTitle("提醒");
builder.setMessage("沒有軌跡,請添加後再查看");
builder.setPositiveButton("確定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setClass(MyTrace.this, MyActivityGroup.class);
startActivity(intent);
MyTrace.this.finish();
}
});
builder.create().show();
} else {
System.out.println("獲得點後添加到圖層");
// 添加ItemizedOverlay
Drawable marker = getResources().getDrawable(R.drawable.iconmarka); // 得到需要標在地圖上的資源
marker.setBounds(0, 0, marker.getIntrinsicWidth(),
marker.getIntrinsicHeight()); // 為maker定義位置和邊界
mMapView.getOverlays().add(new OverItemT(marker, this, myTraces)); // 添加ItemizedOverlay實例到mMapView
// 創建點擊mark時的彈出泡泡
mPopView = super.getLayoutInflater()
.inflate(R.layout.popview, null);
mMapView.addView(mPopView, new MapView.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, null,
MapView.LayoutParams.TOP_LEFT));
mPopView.setVisibility(View.GONE);
}
}
@Override
protected void onPause() {
BMapApp app = (BMapApp) this.getApplication();
app.mBMapMan.getLocationManager().removeUpdates(mLocationListener);
mLocationOverlay.disableMyLocation();
mLocationOverlay.disableCompass(); // 關閉指南針
app.mBMapMan.stop();
super.onPause();
}
@Override
protected void onResume() {
BMapApp app = (BMapApp) this.getApplication();
// 注冊定位事件,定位後將地圖移動到定位點
app.mBMapMan.getLocationManager().requestLocationUpdates(
mLocationListener);
mLocationOverlay.enableMyLocation();
mLocationOverlay.enableCompass(); // 打開指南針
app.mBMapMan.start();
super.onResume();
}
@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
class OverItemT extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> mGeoList = new ArrayList<OverlayItem>();
private Drawable marker;
private Context mContext;
private ArrayList<Trace> traces = new ArrayList<Trace>();
public OverItemT(Drawable marker, Context context, ArrayList<Trace> traces) {
super(boundCenterBottom(marker));
this.marker = marker;
this.mContext = context;
this.traces = traces;
// 用給定的經緯度構造GeoPoint,單位是微度 (度 * 1E6)
// 構造OverlayItem的三個參數依次為:item的位置,標題文本,文字片段
for (int i = 0; i < traces.size(); i++) {
int lat = new Integer(traces.get(i).getLatitude());
int lon = new Integer(traces.get(i).getLongitude());
String resName = traces.get(i).getResname();
GeoPoint p = new GeoPoint(lat, lon);
mGeoList.add(new OverlayItem(p, resName, i + resName));
populate(); // createItem(int)方法構造item。一旦有了數據,在調用其它方法前,首先調用這個方法
}
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
// Projection接口用於屏幕像素坐標和經緯度坐標之間的變換
Projection projection = mapView.getProjection();
for (int index = size() - 1; index >= 0; index--) { // 遍歷mGeoList
OverlayItem overLayItem = getItem(index); // 得到給定索引的item
String title = overLayItem.getTitle();
// 把經緯度變換到相對於MapView左上角的屏幕像素坐標
Point point = projection.toPixels(overLayItem.getPoint(), null);
// 可在此處添加您的繪制代碼
Paint paintText = new Paint();
paintText.setColor(Color.BLUE);
paintText.setTextSize(15);
canvas.drawText(title, point.x - 30, point.y, paintText); // 繪制文本
}
super.draw(canvas, mapView, shadow);
// 調整一個drawable邊界,使得(0,0)是這個drawable底部最後一行中心的一個像素
// 先所有點的經度轉像素
ArrayList<Point> points = new ArrayList<Point>();
for (int i = 0; i < this.size(); i++) {
Point p = new Point();
OverlayItem overLayItem = getItem(i);
projection.toPixels(overLayItem.getPoint(), p);
points.add(p);
}
// 第二個畫筆 畫線
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setDither(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(4);
// 連接 所有點
Path path = new Path();
path.moveTo(points.get(0).x, points.get(0).y);
for (int i = 1; i < points.size(); i++) {
path.lineTo(points.get(i).x, points.get(i).y);
}
// 畫出路徑
canvas.drawPath(path, paint);
boundCenterBottom(marker);
}
@Override
protected OverlayItem createItem(int i) {
// TODO Auto-generated method stub
return mGeoList.get(i);
}
@Override
public int size() {
// TODO Auto-generated method stub
return mGeoList.size();
}
@Override
// 處理當點擊事件
protected boolean onTap(int i) {
setFocus(mGeoList.get(i));
// 更新氣泡位置,並使之顯示
GeoPoint pt = mGeoList.get(i).getPoint();
MyTrace.mMapView.updateViewLayout(MyTrace.mPopView,
new MapView.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT, pt,
MapView.LayoutParams.BOTTOM_CENTER));
MyTrace.mPopView.setVisibility(View.VISIBLE);
Toast.makeText(this.mContext, mGeoList.get(i).getSnippet(),
Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onTap(GeoPoint arg0, MapView arg1) {
// TODO Auto-generated method stub
// 消去彈出的氣泡
MyTrace.mPopView.setVisibility(View.GONE);
return super.onTap(arg0, arg1);
}
}
運行的效果圖:
更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11