Android 在map上画出路线


最近在搞在地图上画出路线图,经过一段时间的摸索,终于搞明白了,其实也挺简单的,写个类继承 Overlay, 并重写draw方法,在draw方法中画出path即可。对于Overaly,在地图上标记某个点或者画线之类的就要使用 overlay,overlay相当于一个覆盖物,覆盖在地图上,这个覆盖物要自己实现所以要继承Overlay。本例自定义了要画的点,如何得到两地之 间的众多点的坐标(经纬度),可以参考Android在google map上画出导航路线图 http://www.linuxidc.com/Linux/2011-05/36375p2.htm

具体代码:

  1. packagenet.blogjava.mobile.map;
  2. importjava.util.List;
  3. importAndroid.app.AlertDialog;
  4. importandroid.graphics.Bitmap;
  5. importandroid.graphics.BitmapFactory;
  6. importandroid.graphics.Canvas;
  7. importandroid.graphics.Color;
  8. importandroid.graphics.Paint;
  9. importandroid.graphics.Path;
  10. importandroid.graphics.Point;
  11. importandroid.location.Address;
  12. importandroid.location.Geocoder;
  13. importandroid.os.Bundle;
  14. importandroid.view.Menu;
  15. importcom.google.android.maps.GeoPoint;
  16. importcom.google.android.maps.MapActivity;
  17. importcom.google.android.maps.MapController;
  18. importcom.google.android.maps.MapView;
  19. importcom.google.android.maps.Overlay;
  20. importcom.google.android.maps.Projection;
  21. publicclassMainextendsMapActivity{
  22. privateGeoPointgpoint1,gpoint2,gpoint3;//连线的点
  23. @Override
  24. publicvoidonCreate(BundlesavedInstanceState){
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.main);
  27. MapViewmapView=(MapView)findViewById(R.id.mapview);
  28. mapView.setClickable(true);
  29. mapView.setBuiltInZoomControls(true);
  30. MapControllermapController=mapView.getController();
  31. mapView.setTraffic(true);//交通图
  32. //mapView.setSatellite(true);//卫星图
  33. //mapView.setStreetView(true);//街景
  34. MyOverlaymyOverlay=newMyOverlay();
  35. mapView.getOverlays().add(myOverlay);
  36. mapController.setZoom(15);//初始放大倍数
  37. gpoint1=newGeoPoint((int)(24.477384*1000000),
  38. (int)(118.158216*1000000));
  39. gpoint2=newGeoPoint((int)(24.488967*1000000),
  40. (int)(118.144277*1000000));
  41. gpoint3=newGeoPoint((int)(24.491091*1000000),
  42. (int)(118.136781*1000000));
  43. mapController.animateTo(gpoint1);
  44. }
  45. @Override
  46. protectedbooleanisRouteDisplayed(){
  47. //TODOAuto-generatedmethodstub
  48. returnfalse;
  49. }
  50. classMyOverlayextendsOverlay{
  51. @Override
  52. publicvoiddraw(Canvascanvas,MapViewmapView,booleanshadow){
  53. //TODOAuto-generatedmethodstub
  54. super.draw(canvas,mapView,shadow);
  55. //画笔
  56. Paintpaint=newPaint();
  57. paint.setColor(Color.RED);
  58. paint.setDither(true);
  59. paint.setStyle(Paint.Style.STROKE);
  60. paint.setStrokeJoin(Paint.Join.ROUND);
  61. paint.setStrokeCap(Paint.Cap.ROUND);
  62. paint.setStrokeWidth(2);
  63. Projectionprojection=mapView.getProjection();
  64. Pointp1=newPoint();
  65. Pointp2=newPoint();
  66. Pointp3=newPoint();
  67. projection.toPixels(gpoint1,p1);
  68. projection.toPixels(gpoint2,p2);
  69. projection.toPixels(gpoint3,p3);
  70. Pathpath=newPath();
  71. path.moveTo(p1.x,p1.y);
  72. path.lineTo(p2.x,p2.y);
  73. path.lineTo(p3.x,p3.y);
  74. canvas.drawPath(path,paint);//画出路径
  75. }
  76. }
  77. }

main.xml:

  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <LinearLayoutxmlns:Android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <com.google.android.maps.MapView
  6. android:id="@+id/mapview"android:layout_width="fill_parent"
  7. android:layout_height="fill_parent"
  8. android:apiKey="0IB7Kn70qp1LT216Hhb-jmHJ8GLTie4p63O77KQ"/>
  9. </LinearLayout>

最后别忘了加权限 :<uses-permissionAndroid:name="android.permission.INTERNET"/>

在<applacation></applacation>之间加<uses-libraryAndroid:name="com.google.android.maps" />

Android在google map上画线比较容易实现的,但是现在问题在于如何获取起点和终点之间的路线图。这里我们使用Google Directions API来实现, Google Directions API是一种使用 HTTP 请求计算多个位置间路线的服务。路线可以以文本字符串或纬度/经度坐标的形式指定起点、目的地和路标。Google Directions API 可以使用一系列路标传回多段路线。


Google Directions API 请求是以下形式的 HTTP 网址:http://maps.google.com/maps/api/directions/output?parameters

其中,output 可能是以下任何一个值:

l json(建议)表示以 JavaScript 对象表示法 (JSON) 的形式输出

l xml 表示以 XML 的形式输出

具体参数参见http://code.google.com/intl/zh-CN/apis/maps/documentation/directions/

通过http请求获取线路,接下来我们需要对返回结果进行解析,提取出导航线路的一系列路标。

如果我们只是简单的画图路线路,返回结果中的字段overview_path包含可我们所需要的数据。它包含一个对象,该对象包含一组表示生成路线 的近似(平滑)路径的已编码 points 和 levels。编码算法参见http://code.google.com/intl/zh-CN/apis/maps/documentation /utilities/polylinealgorithm.html说明。

我们只需要提取points字段中的字符串进行解码就可以得到我们所需的一系列点了,将这些点按顺序连接起来就是我们所要的路线图了。

  1. /**
  2. *通过解析googlemap返回的xml,在map中画路线图
  3. */
  4. publicvoiddrawRoute(){
  5. Stringurl="http://maps.google.com/maps/api/directions/xml?origin=23.055291,113.391802"+
  6. "&destination=23.046604,113.397510&sensor=false&mode=walking";
  7. HttpGetget=newHttpGet(url);
  8. StringstrResult="";
  9. try{
  10. HttpParamshttpParameters=newBasicHttpParams();
  11. HttpConnectionParams.setConnectionTimeout(httpParameters,3000);
  12. HttpClienthttpClient=newDefaultHttpClient(httpParameters);
  13. HttpResponsehttpResponse=null;
  14. httpResponse=httpClient.execute(get);
  15. if(httpResponse.getStatusLine().getStatusCode()==200){
  16. strResult=EntityUtils.toString(httpResponse.getEntity());
  17. }
  18. }catch(Exceptione){
  19. return;
  20. }
  21. if(-1==strResult.indexOf("<status>OK</status>")){
  22. Toast.makeText(this,"获取导航路线失败!",Toast.LENGTH_SHORT).show();
  23. this.finish();
  24. return;
  25. }
  26. intpos=strResult.indexOf("<overview_polyline>");
  27. pos=strResult.indexOf("<points>",pos+1);
  28. intpos2=strResult.indexOf("</points>",pos);
  29. strResult=strResult.substring(pos+8,pos2);
  30. List<GeoPoint>points=decodePoly(strResult);
  31. MyOverLaymOverlay=newMyOverLay(points);
  32. List<Overlay>overlays=mMapView.getOverlays();
  33. overlays.add(mOverlay);
  34. if(points.size()>=2){
  35. mMapController.animateTo(points.get(0));
  36. }
  37. mMapView.invalidate();
  38. }
  39. /**
  40. *解析返回xml中overview_polyline的路线编码
  41. *
  42. *@paramencoded
  43. *@return
  44. */
  45. privateList<GeoPoint>decodePoly(Stringencoded){
  46. List<GeoPoint>poly=newArrayList<GeoPoint>();
  47. intindex=0,len=encoded.length();
  48. intlat=0,lng=0;
  49. while(index<len){
  50. intb,shift=0,result=0;
  51. do{
  52. b=encoded.charAt(index++)-63;
  53. result|=(b&0x1f)<<shift;
  54. shift+=5;
  55. }while(b>=0x20);
  56. intdlat=((result&1)!=0?~(result>>1):(result>>1));
  57. lat+=dlat;
  58. shift=0;
  59. result=0;
  60. do{
  61. b=encoded.charAt(index++)-63;
  62. result|=(b&0x1f)<<shift;
  63. shift+=5;
  64. }while(b>=0x20);
  65. intdlng=((result&1)!=0?~(result>>1):(result>>1));
  66. lng+=dlng;
  67. GeoPointp=newGeoPoint((int)(((double)lat/1E5)*1E6),
  68. (int)(((double)lng/1E5)*1E6));
  69. poly.add(p);
  70. }
  71. returnpoly;
  72. }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值