package AndroidApi;
import java.util.ArrayList;
import java.util.Observable;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import android.content.Context;
import android.graphics.Point;
import android.location.Criteria;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.GpsStatus.Listener;
import android.os.Bundle;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
public class GoogleMap extends Observable
{
private MapActivity m_mapServer = null;
public MapView m_viewCtrl = null;
public LocationManager m_posCtrl = null;
public MapController m_mapCtrl = null;
private final int DEFAULT_CITY = 24;
/**
* 监控变化
*/
private final LocationListener m_posListener = new LocationListener()
{
public void onLocationChanged(Location location){}
public void onProviderDisabled(String provider){}
public void onProviderEnabled(String provider){}
public void onStatusChanged(String provider,int status,Bundle extras){}
};
public void refresh()
{
setChanged();
notifyObservers();
}
/**
* 构造
* @param objService
* @param viewCtrl
* @throws Exception
*/
public GoogleMap(MapActivity objService, int VIEW_ID) throws Exception
{
AndroidDebug.println("MapControl.MapControl");
m_mapServer = objService;
m_posCtrl = (LocationManager)m_mapServer.getSystemService(Context.LOCATION_SERVICE);
m_viewCtrl = (MapView)m_mapServer.findViewById(VIEW_ID);
m_mapCtrl = m_viewCtrl.getController();
if( null == m_posCtrl || null == m_viewCtrl || null == m_mapCtrl)
{
throw new NullPointerException();
}
}
/**
* 获得地图中心的位置
* @return
*/
public final GeoPoint getMapCenter()
{
return m_viewCtrl.getMapCenter();
}
/**
* 获得地图中心的位置
* @return
*/
public final void getMapBounds(GeoPoint geoPt0, GeoPoint geoPt1, GeoPoint geoPt2, GeoPoint geoPt3)
{
geoPt0 = m_viewCtrl.getProjection().fromPixels(0, 0);
geoPt1 = m_viewCtrl.getProjection().fromPixels(m_viewCtrl.getWidth(), 0);
geoPt2 = m_viewCtrl.getProjection().fromPixels(0, m_viewCtrl.getHeight());
geoPt3 = m_viewCtrl.getProjection().fromPixels(m_viewCtrl.getWidth(), m_viewCtrl.getHeight());
}
/**
* 经纬点转视野点
* @param geoPoint
* @return
*/
public Point toPixPoint(GeoPoint geoPoint)
{
Point pixPoint = new Point();
m_viewCtrl.getProjection().toPixels(geoPoint, pixPoint);
return pixPoint;
}
/**
* 视野点转经纬点
* @param pixPoint
* @return
*/
public GeoPoint toGeoPoint(Point pixPoint)
{
GeoPoint geoPoint = m_viewCtrl.getProjection().fromPixels(pixPoint.x,pixPoint.y);
return geoPoint;
}
/**
* 析构
*/
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
String pProvider = getProvider();
if( null != pProvider)
{
m_posCtrl.removeUpdates(m_posListener);
}
m_mapServer = null;
m_viewCtrl = null;
m_posCtrl = null;
m_mapCtrl = null;
AndroidDebug.println("MapControl.finalize");
}
/**
* 设置默认值
*/
public void initDefault()
{
//设置显示模式
m_viewCtrl.setEnabled(true);
m_viewCtrl.setClickable(true);
m_viewCtrl.setTraffic(false);
m_viewCtrl.setSatellite(false);
m_viewCtrl.setStreetView(true);
m_viewCtrl.setBuiltInZoomControls(true);
//设置地图等级
m_mapCtrl.setZoom(8);
//得到坐标相关的信息
final GeoPoint ptLoc = getLocation();
if( null != ptLoc)
moveTo(ptLoc.getLatitudeE6()/1E6,ptLoc.getLongitudeE6()/1E6);
else
moveTo(Double.parseDouble(CityPos.CITY_POSITION[DEFAULT_CITY][1]),Double.parseDouble(CityPos.CITY_POSITION[DEFAULT_CITY][2]));
//设置监控器
String pProvider = getProvider();
if( null != pProvider)
{
m_posCtrl.requestLocationUpdates(pProvider, 1000, 0, m_posListener);
}
}
/**
* 获得服务商
*/
public String getProvider()
{
//经度要求
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(false);
criteria.setPowerRequirement(Criteria.POWER_LOW);
//取得效果最好的criteria
String provider = m_posCtrl.getBestProvider(criteria, true);
//得到坐标相关的信息
return provider;
}
/**
* 移动地图中心到目标位置
* @param dLon
* @param dLat
*/
public void moveTo(double dLat, double dLon)
{
Double geoLat = dLat*1E6;
Double geoLon = dLon*1E6;
GeoPoint point = new GeoPoint(geoLat.intValue(),geoLon.intValue());
m_mapCtrl.animateTo(point);
point = null;
geoLat = geoLon = null;
}
/**
* 获得本地位置
* @return
*/
public final GeoPoint getLocation()
{
String pProvider = getProvider();
if( null != pProvider)
{
Location posLocation = m_posCtrl.getLastKnownLocation(pProvider);
if( null != posLocation)
{
Double geoLat = posLocation.getLatitude()*1E6;
Double geoLon = posLocation.getLongitude()*1E6;
GeoPoint point = new GeoPoint(geoLat.intValue(),geoLon.intValue());
return point;
}
}
return null;
}
/**
* 从本地位置导航到目标位置
* @return
*/
public final ArrayList<GeoPoint> getRoute(double dEndLat, double dEndLon)
{
final GeoPoint ptLoc = getLocation();
final ArrayList<GeoPoint> lstPath = getRoute(ptLoc.getLatitudeE6()/1E6,ptLoc.getLongitudeE6()/1E6,dEndLat,dEndLon);
return lstPath;
}
/**
* 获得导航路径
* @param dStartLat
* @param dStartLon
* @param dEndLat
* @param dEndLon
* @return
*/
public final ArrayList<GeoPoint> getRoute(double dStartLat, double dStartLon, double dEndLat, double dEndLon)
{
/*
String url = "http://maps.google.com/maps/api/directions/xml?origin=22.549999,114.099998" +
"&destination=23.046604,113.397510&sensor=false&mode=walking";
*/
String url = "http://maps.google.com/maps/api/directions/xml?origin=" + dStartLat + "," + dStartLon +
"&destination=" + dEndLat + "," + dEndLon + "&sensor=false&mode=walking";
HttpGet get = new HttpGet(url);
String strResult = "";
try
{
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpResponse httpResponse = null;
httpResponse = httpClient.execute(get);
if ( 200 == httpResponse.getStatusLine().getStatusCode())
{
strResult = EntityUtils.toString(httpResponse.getEntity());
}
}
catch (Exception e)
{
e.printStackTrace();
AndroidDebug.Log("GoogleMap", "获取导航路线失败!");
return null;
}
if (-1 == strResult.indexOf("<status>OK</status>"))
{
AndroidDebug.Log("GoogleMap", "获取导航路线失败!");
return null;
}
int pos = strResult.indexOf("<overview_polyline>");
pos = strResult.indexOf("<points>", pos + 1);
int pos2 = strResult.indexOf("</points>", pos);
strResult = strResult.substring(pos + 8, pos2);
final ArrayList<GeoPoint> ptPath = decodePath(strResult);
if( null != ptPath)
AndroidDebug.Log("GoogleMap", "获取导航路线成功!");
return ptPath;
}
/**
* xml中overview_polyline的路径解码
* @param szPath
* @return
*/
private final ArrayList<GeoPoint> decodePath(String szPath)
{
ArrayList<GeoPoint> ptPath = new ArrayList<GeoPoint>();
int index = 0, len = szPath.length();
int lat = 0, lng = 0;
while (index < len)
{
int b, shift = 0, result = 0;
do
{
b = szPath.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do
{
b = szPath.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
(int) (((double) lng / 1E5) * 1E6));
ptPath.add(p);
}
return ptPath;
}
}
//-----------------------------------------------
package MapLayer;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import AndroidApi.AndroidDebug;
import AndroidApi.CityPos;
import AndroidApi.GoogleMap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
public class GoogleRoute extends Overlay implements Observer
{
GoogleMap m_mapGoogle = null;
ArrayList<GeoPoint> m_lstPaht = null;
public GoogleRoute(GoogleMap mCtrlMap)
{
// TODO Auto-generated constructor stub
m_mapGoogle = mCtrlMap;
m_mapGoogle.addObserver(this);
}
public void update(Observable observable, Object data)
{
// TODO Auto-generated method stub
if( observable instanceof GoogleMap)
{
AndroidDebug.println("update GoogleRoute!");
List<Overlay> pOverlays = m_mapGoogle.m_viewCtrl.getOverlays();
pOverlays.remove(this);
final GeoPoint ptStart = m_mapGoogle.getMapCenter();
double dSLat = ptStart.getLatitudeE6()/1E6;
double dSLon = ptStart.getLongitudeE6()/1E6;
double dELat = Double.parseDouble(CityPos.CITY_POSITION[13][1]);
double dELon = Double.parseDouble(CityPos.CITY_POSITION[13][2]);
m_lstPaht = m_mapGoogle.getRoute(dSLat, dSLon, dELat, dELon);
pOverlays.add(this);
}
}
@Override
protected void finalize() throws Throwable
{
// TODO Auto-generated method stub
super.finalize();
m_mapGoogle.deleteObserver(this);
}
@Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
{
// TODO Auto-generated method stub
super.draw(canvas, mapView, shadow, when);
synchronized(GoogleRoute.class)
{
Paint paint = new Paint();
//消除锯齿
paint.setStrokeWidth(1);
paint.setARGB(255, 255, 0, 0);
paint.setStyle(Paint.Style.STROKE);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(16);
AndroidDebug.println("GoogleRoute draw");
if( null != m_lstPaht)
{
AndroidDebug.println("m_lstPaht");
Point scPoint0 = new Point();
Point scPoint1 = new Point();
mapView.getProjection().toPixels(m_lstPaht.get(0), scPoint0);
mapView.getProjection().toPixels(m_lstPaht.get(m_lstPaht.size()-1), scPoint1);
canvas.drawLine(scPoint0.x, scPoint0.y, scPoint1.x, scPoint1.y, paint);
AndroidDebug.println("GoogleRoute draw m_lstPaht");
}
return true;
}
}
}
//----------------------------------
package AndroidApi;
public class CityPos
{
public static final String CITY_POSITION[][] =
{
{"北京", "39.930000", "116.279998"}, //0
{"上海", "31.399999", "121.470001"},
{"天津", "39.099998", "117.169998"}, //2
{"重庆", "29.520000", "106.480003"},
{"唐山", "39.669998", "118.150001"}, //4
{"石家庄", "38.029998", "114.419998"},
{"大连", "38.900001", "121.629997"}, //6
{"哈尔滨", "45.750000", "126.769996"},
{"海口", "20.030000", "110.349998"}, //8
{"长春", "43.900001", "125.220001"},
{"长沙", "28.229999", "112.870002"}, //10
{"成都", "30.670000", "104.019996"},
{"福州", "26.079999", "119.279998"}, //12
{"广州", "23.129999", "113.319999"},
{"贵阳", "26.579999", "106.720001"}, //14
{"合肥", "30.229999", "120.169998"},
{"呼和浩特", "31.870000", "117.230003"}, //16
{"昆明", "25.020000", "102.680000"},
{"拉萨", "29.657589", "111.320500"}, //18
{"兰州", "36.040000", "103.879997"},
{"南昌", "28.600000", "115.919998"}, //20
{"南京", "32.000000", "118.800003"},
{"南宁", "22.819999", "108.349998"}, //22
{"青岛", "36.069999", "120.330001"},
{"深圳", "22.549999", "114.099998"}, //24
{"沈阳", "41.770000", "123.430000"},
{"太原", "37.779998", "112.550003"}, //26
{"乌鲁木齐", "43.779998", "87.6200020"},
{"武汉", "30.620000", "114.129997"}, //28
{"西安", "34.299999", "108.930000"},
{"西宁", "36.619998", "101.769996"}, //30
{"厦门", "24.479999", "118.080001"},
{"徐州", "34.279998", "117.150001"}, //32
{"银川", "38.479999", "106.220001"},
{"郑州", "34.720001", "113.650001"} //34
};
}
//-----------------------
package AndroidApi;
import android.util.Log;
class Monitoring implements Runnable
{
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
try
{
Thread.sleep(100);
} catch (InterruptedException s)
{
Thread.currentThread().interrupt();
}
AndroidDebug.printVaryMemory();
}
}
}
public class AndroidDebug
{
private static boolean m_bIsDebug = false;
/**
* 设置调试模式
*
* @param bIsDebug
*/
public static void setMode(boolean bIsDebug)
{
m_bIsDebug = bIsDebug;
}
/**
* 是否调试模式
* @return
*/
public static boolean isDebug()
{
return m_bIsDebug;
}
/**
* 打印信息
*
* @param strTxt
*/
public static void println(String strTxt)
{
if (m_bIsDebug)
{
System.out.println(strTxt);
}
}
/**
* 打印信息
*
* @param strTxt
*/
public static void Log(String strTag, String strTxt)
{
if (m_bIsDebug)
{
Log.i(strTag,strTxt);
}
}
/**
* 强制回收垃圾,可用于检测析构函数,检测未使用对象是否有
*/
public static void gc()
{
if (m_bIsDebug)
{
System.gc();
}
}
/**
* 打印堆总量
*/
public static void printTotalMemory()
{
Runtime r = Runtime.getRuntime();
AndroidDebug.println("Total memory is :" + r.totalMemory());
}
/**
* 打印堆剩余量
*/
public static void printFreeMemory()
{
gc(); // 执行强制回收以获得准确的剩余量
Runtime r = Runtime.getRuntime();
AndroidDebug.println("Free memory is :" + r.freeMemory());
}
/**
* 打印堆变化量
*/
static long longPre = 0;
public static void printVaryMemory()
{
gc(); // 执行强制回收以获得准确的剩余量
Runtime r = Runtime.getRuntime();
long longNow = r.freeMemory();
if (longNow > longPre)
{
AndroidDebug.println("Free memory -> :" + (longNow - longPre));
longPre = longNow;
} else if (longNow < longPre)
{
AndroidDebug.println("Free memory <- :" + (longPre - longNow));
longPre = longNow;
}
}
/**
* 监控内存
*
* @param bIsOpen
*/
private static Thread m_pThread = null;
public static void setMonitore(boolean bIsOpen)
{
if (bIsOpen)
{
if (null == m_pThread)
m_pThread = new Thread(new Monitoring());
m_pThread.setDaemon(true);
m_pThread.start();
}
else
{
if (null != m_pThread)
{
m_pThread.interrupt();
m_pThread = null;
}
}
}
}
package android.LB;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.Overlay;
import AndroidApi.AndroidDebug;
import AndroidApi.CityPos;
import AndroidApi.GoogleMap;
import MapLayer.GoogleRoute;
import android.os.Bundle;
import android.view.KeyEvent;
public class Main extends MapActivity implements Observer
{
/** Called when the activity is first created. */
public GoogleMap m_ctrlMap = null;
private GoogleRoute m_viewRoute = null;
private Thread m_thread = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
AndroidDebug.setMode(true);
try
{
m_ctrlMap = new GoogleMap(this, R.id.MapView);
m_viewRoute = new GoogleRoute(m_ctrlMap);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
AndroidDebug.println("Failed to new GoogleMap!");
}
m_ctrlMap.initDefault();
double dSLat = Double.parseDouble(CityPos.CITY_POSITION[24][1]);
double dSLon = Double.parseDouble(CityPos.CITY_POSITION[24][2]);
m_ctrlMap.moveTo(dSLat, dSLon);
m_ctrlMap.refresh();
m_thread = new Thread(new InvalidateThread());
m_thread.start();
}
@Override
protected boolean isRouteDisplayed()
{
// TODO Auto-generated method stub
return false;
}
@Override
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
m_thread.interrupt();
if (null != m_ctrlMap)
m_ctrlMap = null;
AndroidDebug.gc();
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
// TODO Auto-generated method stub
if( AndroidDebug.isDebug())
{
switch(keyCode)
{
case KeyEvent.KEYCODE_DPAD_DOWN:
{
final GeoPoint ptDownLoc = m_ctrlMap.getMapCenter();
m_ctrlMap.moveTo(ptDownLoc.getLatitudeE6()/1E6-0.11, ptDownLoc.getLongitudeE6()/1E6);
m_ctrlMap.refresh();
break;
}
case KeyEvent.KEYCODE_DPAD_UP:
{
final GeoPoint ptUpLoc = m_ctrlMap.getMapCenter();
m_ctrlMap.moveTo(ptUpLoc.getLatitudeE6()/1E6+0.1, ptUpLoc.getLongitudeE6()/1E6);
m_ctrlMap.refresh();
break;
}
}
}
return super.onKeyUp(keyCode, event);
}
public void update(Observable observable, Object data)
{
// TODO Auto-generated method stub
}
class InvalidateThread implements Runnable
{
public void run()
{
while( !Thread.currentThread().isInterrupted())
{
try
{
Thread.sleep(1000);
}
catch( InterruptedException e)
{
Thread.currentThread().interrupt();
}
AndroidDebug.println("InvalidateThread");
if( null != m_ctrlMap)
m_ctrlMap.m_viewCtrl.postInvalidate();
}
AndroidDebug.println("InvalidateThread exit");
}
}
}