Google Map Android API V2 中两个位置之间的旅行时间

Posted

技术标签:

【中文标题】Google Map Android API V2 中两个位置之间的旅行时间【英文标题】:travel time between two locations in Google Map Android API V2 【发布时间】:2013-05-21 08:27:58 【问题描述】:

如何在 Google Map android API V2 中显示两个位置之间的旅行时间, 在我的程序中我使用 JSONParse 显示行驶距离,但我无法显示显示行程时间,我制作的这个示例程序:DirectionActivity.java

public class DirectionActivity extends FragmentActivity implements OnMyLocationChangeListener

private LatLng          start;
private LatLng          end;
private String          nama;
private final String    URL = "http://maps.googleapis.com/maps/api/directions/json?";
private GoogleMap       map;
private JSONHelper      json;
private ProgressDialog  pDialog;
private List<LatLng>    listDirections;

@Override
protected void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_direction);
    json = new JSONHelper();
    setupMapIfNeeded();

    Bundle b = getIntent().getExtras();
    if (b != null)
    
        start = new LatLng(b.getDouble(MainActivity.KEY_LAT_ASAL), b.getDouble(MainActivity.KEY_LNG_ASAL));
        end = new LatLng(b.getDouble(MainActivity.KEY_LAT_TUJUAN), b.getDouble(MainActivity.KEY_LNG_TUJUAN));
        nama = b.getString(MainActivity.KEY_NAMA);
    

    new AsyncTaskDirection().execute();


private void setupMapIfNeeded()

    if (map == null)
    
        FragmentManager fragmentManager = getSupportFragmentManager();
        SupportMapFragment supportMapFragment = (SupportMapFragment) fragmentManager
                .findFragmentById(R.id.mapsdirections);
        map = supportMapFragment.getMap();

        if (map != null)
        
            setupMap();
        
    



private void setupMap()

    map.setMyLocationEnabled(true);
    map.setOnMyLocationChangeListener(this);
    moveToMyLocation();


private void moveToMyLocation()

    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();

    Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
    if (location != null)
    
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(location.getLatitude(), location.getLongitude()), 13));
    


@Override
public boolean onCreateOptionsMenu(Menu menu)

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;


@Override
protected void onResume()

    // TODO Auto-generated method stub
    super.onResume();
    int resCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
    if (resCode != ConnectionResult.SUCCESS)
    
        GooglePlayServicesUtil.getErrorDialog(resCode, this, 1);
    


private class AsyncTaskDirection extends AsyncTask<Void, Void, Void>

    @Override
    protected Void doInBackground(Void... params)
    
        String uri = URL
                + "origin=" + start.latitude + "," + start.longitude
                + "&destination=" + end.latitude + "," + end.longitude
                + "&sensor=true&units=metric";

        JSONObject jObject = json.getJSONFromURL(uri);
        listDirections = json.getDirection(jObject);

        return null;
    

    @Override
    protected void onPreExecute()
    
        // TODO Auto-generated method stub
        super.onPreExecute();
        pDialog = new ProgressDialog(DirectionActivity.this);
        pDialog.setMessage("Loading....");
        pDialog.setCancelable(true);
        pDialog.show();
    

    @Override
    protected void onPostExecute(Void result)
    
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        pDialog.dismiss();
        gambarDirection();
    



public void gambarDirection()

    PolylineOptions line = new PolylineOptions().width(3).color(Color.BLUE);
    for (int i = 0; i < listDirections.size(); i++)
    
        line.add(listDirections.get(i));
    
    map.addPolyline(line);

    // tambah marker di posisi end
    map.addMarker(new MarkerOptions()
            .position(end)
            .title(nama));


@Override
public void onMyLocationChange(Location location)

    Toast.makeText(this, "Lokasi berubah ke " + location.getLatitude() + "," + location.getLongitude(),
            Toast.LENGTH_SHORT).show();




JSONHelper.java

public class JSONHelper

private InputStream     is              = null;
private JSONObject      jsonObject      = null;
private String          json            = "";

private final String    TAG_TEMPATMAKAN = "tempatmakan";
private final String    TAG_ID          = "id";
private final String    TAG_NAMA        = "nama";
private final String    TAG_ALAMAT      = "alamat";
private final String    TAG_LAT         = "lat";
private final String    TAG_LNG         = "lng";
private final String    TAG_ROUTES      = "routes";
private final String    TAG_LEGS        = "legs";
private final String    TAG_STEPS       = "steps";
private final String    TAG_POLYLINE    = "polyline";
private final String    TAG_POINTS      = "points";
private final String    TAG_START       = "start_location";
private final String    TAG_END         = "end_location";

public JSONObject getJSONFromURL(String url)

    try
    
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);

        HttpResponse httpResponse = httpClient.execute(httpGet);
        HttpEntity httpEntity = httpResponse.getEntity();
        is = httpEntity.getContent();
     catch (UnsupportedEncodingException e)
    
        e.printStackTrace();
     catch (ClientProtocolException e)
    
        e.printStackTrace();
     catch (IOException e)
    
        e.printStackTrace();
    

    try
    
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                is, "iso-8859-1"), 8);

        StringBuilder sb = new StringBuilder();
        String line = null;

        while ((line = reader.readLine()) != null)
        
            sb.append(line + "\n");
        

        is.close();
        json = sb.toString();
     catch (Exception e)
    
        // TODO: handle exception
    

    try
    
        jsonObject = new JSONObject(json);

     catch (JSONException e)
    
        // TODO: handle exception
    

    return jsonObject;


public ArrayList<TempatMakan> getTempatMakanAll(JSONObject jobj)

    ArrayList<TempatMakan> listTempatMakan = new ArrayList<TempatMakan>();

    try
    
        JSONArray arrayTempatMakan = jobj.getJSONArray(TAG_TEMPATMAKAN);

        for (int i = 0; i < arrayTempatMakan.length(); i++)
        
            JSONObject jobject = arrayTempatMakan.getJSONObject(i);

            Log.d("log", "muter ke " + i);
            listTempatMakan.add(new TempatMakan(jobject.getInt(TAG_ID), jobject.getString(TAG_NAMA), jobject
                    .getString(TAG_ALAMAT), jobject
                    .getDouble(TAG_LAT), jobject.getDouble(TAG_LNG)));

        
     catch (JSONException e)
    
        e.printStackTrace();
    
    return listTempatMakan;


/*
 * Untuk decode Polyline
 * 
 * @params String
 * 
 * @return List<LatLng>
 */
private List<LatLng> decodePoly(String encoded)

    List<LatLng> poly = new ArrayList<LatLng>();
    int index = 0, len = encoded.length();
    int lat = 0, lng = 0;
    while (index < len)
    
        int b, shift = 0, result = 0;
        do
        
            b = encoded.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 = encoded.charAt(index++) - 63;
            result |= (b & 0x1f) << shift;
            shift += 5;
         while (b >= 0x20);
        int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
        lng += dlng;

        LatLng position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
        poly.add(position);
    
    return poly;



/*
 * Untuk mendapatkan direction
 * 
 * @params JSONObject
 * 
 * @return List<LatLng>
 */
public List<LatLng> getDirection(JSONObject jObj)


    List<LatLng> directions = new ArrayList<LatLng>();

    try
    
        JSONObject objRoute = jObj.getJSONArray(TAG_ROUTES).getJSONObject(0);
        JSONObject objLegs = objRoute.getJSONArray(TAG_LEGS).getJSONObject(0);
        JSONArray arraySteps = objLegs.getJSONArray(TAG_STEPS);
        for (int wi2t = 0; wi2t < arraySteps.length(); wi2t++)
        
            JSONObject step = arraySteps.getJSONObject(wi2t);
            JSONObject objStart = step.getJSONObject(TAG_START);
            JSONObject objEnd = step.getJSONObject(TAG_END);
            double latStart = objStart.getDouble(TAG_LAT);
            double lngStart = objStart.getDouble(TAG_LNG);

            directions.add(new LatLng(latStart, lngStart));

            JSONObject poly = step.getJSONObject(TAG_POLYLINE);
            String encodedPoly = poly.getString(TAG_POINTS);

            List<LatLng> decodedPoly = decodePoly(encodedPoly);
            for (int eka = 0; eka < decodedPoly.size(); eka++)
            
                directions.add(new LatLng(decodedPoly.get(eka).latitude, decodedPoly.get(eka).longitude));
            

            double latEnd = objEnd.getDouble(TAG_LAT);
            double lngEnd = objEnd.getDouble(TAG_LNG);
            directions.add(new LatLng(latEnd, lngEnd));

        
     catch (JSONException e)
    
        // TODO: handle exception
    

    return directions;


MainActivity.java

public class MainActivity extends FragmentActivity implements OnInfoWindowClickListener

private GoogleMap           map;
private JSONHelper          json;
private ProgressDialog      pDialog;
private Button      btnGetDirection;

private List<TempatMakan>   listTempatMakan;
private final String        URL_API     = "http://lhocation1203.hostzi.com/dataapi/tempatmakan.php";

public static final String  KEY_NAMA    = "nama";
public static final String  KEY_ALAMAT  = "alamat";
public static final String  KEY_LAT_TUJUAN  = "lat_tujuan";
public static final String  KEY_LNG_TUJUAN  = "lng_tujuan";
public static final String  KEY_LAT_ASAL    = "lat_asal";
public static final String  KEY_LNG_ASAL    = "lng_asal";

@Override
protected void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    json = new JSONHelper();

    new AsynTaskMain().execute();

    setupMapIfNeeded();


private void setupMapIfNeeded()

    if (map == null)
    
        FragmentManager fragmentManager = getSupportFragmentManager();
        SupportMapFragment supportMapFragment = (SupportMapFragment) fragmentManager.findFragmentById(R.id.maps);
        map = supportMapFragment.getMap();

        if (map != null)
        
            setupMap();
        
    



private void setupMap()

    map.setMyLocationEnabled(true);
    map.setOnInfoWindowClickListener(this);
    moveToMyLocation();


private void moveToMyLocation()

    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();

    Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
    if (location != null)
    
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                new LatLng(location.getLatitude(), location.getLongitude()), 13));
    


@Override
public boolean onCreateOptionsMenu(Menu menu)

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;


@Override
protected void onResume()

    // TODO Auto-generated method stub
    super.onResume();

    int resCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
    if (resCode != ConnectionResult.SUCCESS)
    
        GooglePlayServicesUtil.getErrorDialog(resCode, this, 1);
    


private class AsynTaskMain extends AsyncTask<Void, Void, Void>


    @Override
    protected void onPostExecute(Void result)
    
        // TODO Auto-generated method stub
        pDialog.dismiss();
        runOnUiThread(new Runnable()
        

            @Override
            public void run()
            
                // TODO Auto-generated method stub
                for (int i = 0; i < listTempatMakan.size(); i++)
                

                    map.addMarker(new MarkerOptions()
                            .position(new LatLng(listTempatMakan.get(i).getLat(),
                                    listTempatMakan.get(i).getLng()))
                            .title(listTempatMakan.get(i).getNama())
                            .snippet(listTempatMakan.get(i).getAlamat()));

                
            
        );

        super.onPostExecute(result);
    

    @Override
    protected void onPreExecute()
    
        // TODO Auto-generated method stub
        super.onPreExecute();
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Loading....");
        pDialog.setCancelable(true);
        pDialog.show();
    

    @Override
    protected Void doInBackground(Void... params)
    
        // TODO Auto-generated method stub

        JSONObject jObject = json.getJSONFromURL(URL_API);
        listTempatMakan = json.getTempatMakanAll(jObject);
        return null;
    


@Override
public void onInfoWindowClick(Marker marker)

    // marker id -> m0, m1, m2 dst..
    String id = marker.getId();
    id = id.substring(1);

    LatLng myLocation = new LatLng(map.getMyLocation().getLatitude(), map.getMyLocation().getLongitude());

    if (myLocation != null)
    
        Bundle bundle = new Bundle();
        bundle.putString(KEY_NAMA, listTempatMakan.get(Integer.parseInt(id)).getNama());
        bundle.putString(KEY_ALAMAT, listTempatMakan.get(Integer.parseInt(id)).getAlamat());
        bundle.putDouble(KEY_LAT_TUJUAN, marker.getPosition().latitude);
        bundle.putDouble(KEY_LNG_TUJUAN, marker.getPosition().longitude);
        bundle.putDouble(KEY_LAT_ASAL, myLocation.latitude);
        bundle.putDouble(KEY_LNG_ASAL, myLocation.longitude);

        Intent i = new Intent(MainActivity.this, InfoTempatMakanActivity.class);
        i.putExtras(bundle);
        startActivity(i);

     else
    
        Toast.makeText(this, "Tidak dapat menemukan lokasi anda ", Toast.LENGTH_LONG).show();
    


InfoTempatMakanActivity.java

public class InfoTempatMakanActivity extends Activity implements OnClickListener


private TextView    tvNama;
private TextView    tvAlamat;
private Button      btnGetDirection;

private LatLng      lokasiTujuan;
private LatLng      lokasiAwal;
private String      nama;
private String      alamat;

@Override
protected void onCreate(Bundle savedInstanceState)

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_info_tempat_makan);

    initialize();

    Bundle bundle = getIntent().getExtras();
    if (bundle != null)
    
        nama = bundle.getString(MainActivity.KEY_NAMA);
        alamat = bundle.getString(MainActivity.KEY_ALAMAT);
        lokasiTujuan = new LatLng(bundle.getDouble(MainActivity.KEY_LAT_TUJUAN),
                bundle.getDouble(MainActivity.KEY_LNG_TUJUAN));
        lokasiAwal = new LatLng(bundle.getDouble(MainActivity.KEY_LAT_ASAL),
                bundle.getDouble(MainActivity.KEY_LNG_ASAL));
    

    setTeksView();



private void setTeksView()

    tvNama.setText(nama);
    tvAlamat.setText(alamat);


private void initialize()

    tvAlamat = (TextView) findViewById(R.id.alamatTempatMakan);
    tvNama = (TextView) findViewById(R.id.namaTempatMakan);
    btnGetDirection = (Button) findViewById(R.id.btnDirection);
    btnGetDirection.setOnClickListener(this);


@Override
public void onClick(View v)

    Bundle bundle = new Bundle();
    bundle.putDouble(MainActivity.KEY_LAT_ASAL, lokasiAwal.latitude);
    bundle.putDouble(MainActivity.KEY_LNG_ASAL, lokasiAwal.longitude);
    bundle.putDouble(MainActivity.KEY_LAT_TUJUAN, lokasiTujuan.latitude);
    bundle.putDouble(MainActivity.KEY_LNG_TUJUAN, lokasiTujuan.longitude);
    bundle.putString(MainActivity.KEY_NAMA, nama);

    Intent intent = new Intent(this, DirectionActivity.class);
    intent.putExtras(bundle);

    startActivity(intent);



TempatMakan.java

public class TempatMakan

private int id;
private String  nama;
private String  alamat;
private double  lat;
private double  lng;

public TempatMakan()

    // TODO Auto-generated constructor stub


public TempatMakan(int id, String nama, String alamat, double lat, double lng)

    super();
            this.id = id;
    this.nama = nama;
    this.alamat = alamat;
    this.lat = lat;
    this.lng = lng;


public String getNama()

    return nama;


public void setNama(String nama)

    this.nama = nama;


public String getAlamat()

    return alamat;


public void setAlamat(String alamat)

    this.alamat = alamat;


public double getLat()

    return lat;


public void setLat(double lat)

    this.lat = lat;


public double getLng()

    return lng;


public void setLng(double lng)

    this.lng = lng;



【问题讨论】:

这个链接会帮助你wptrafficanalyzer.in/blog/… @Rachel Gallen 谢谢,但我仍然对如何在我的程序中放置旅行时间感到困惑,我尝试将我的程序与那个教程结合起来,但我仍然不能 【参考方案1】:

Google Directions JSON Response 在“LEGS”数组中有一个名为 Distance 和 Duration 的对象,如下所示:

"legs": [
                
                    "distance": 
                        "text": "0.3 km", 
                        "value": 263
                    , 
                    "duration": 
                        "text": "1 min", 
                        "value": 52
                    , 
                 ....... //omitted value
        ]

因此,您可以尝试将距离和持续时间(如果需要)解析到您的应用中。 可能是这样的:

JSONArray legs = jobject.getString("legs");
for (int i = 0; i < legs.length(); i++)
    
        JSONObject legsObject = legs.getJSONObject(i);
        JSONObject distanceObject = legsObject.getString("distance");
        String distanceText = distanceObject.getString("text");
        String distanceValue = String.valueOf(distanceObject.getString("value"));
        //do anything else
    

哦,把legs数组解析放到ArrayTempatMakan解析里面。我可以使用 Jackson JSON 解析器获取距离和持续时间,因此您应该可以使用 org.JSON 解析器来完成。

祝你好运^^

编辑:

在这个getDirection (JSONObject jObj)方法中你成功在这里检索到objLegs,你需要得到objLegs内的Distance和Duration

    JSONObject objRoute = jObj.getJSONArray(TAG_ROUTES).getJSONObject(0);
    JSONObject objLegs = objRoute.getJSONArray(TAG_LEGS).getJSONObject(0);
    JSONArray arraySteps = objLegs.getJSONArray(TAG_STEPS);

我认为你应该在objLegs下面添加这个:

JSONObject objDistance = objLegs.getJSONObject("distance");
JSONObject objDuration = objLegs.getJSONObject("duration");
String text_distance = objDistance.getString("text");
Log.d("Distance", text_distance); //adds an entry to the logCat, Check whether the value of Distance is successfully taken.
String text_duration = objDuration.getString("text");
Log.d("Duration", text_duration); //adds an entry to the logCat, Check whether the value of Distance is successfully taken.

在那里,我相信您应该能够获取值,然后,您可以将值添加到列表结果中。

如果您仍然无法插入距离和持续时间,请在您的帖子中包含 TempatMakan 课程。

编辑 2:

在 TempatMakan.Java 中将距离和持续时间声明为字符串:

private String durasi;
private String jarak;

在你的构造函数中:

public TempatMakan(int id, String nama, String alamat, String jarak, String durasi, double lat, double lng)

    super();
    this.id = id;
    this.nama = nama;
    this.alamat = alamat;
    this.lat = lat;
    this.lng = lng;
    this.jarak = jarak;
    this.durasi = durasi;

然后为jarakdurasi 声明各自的getter 和setter。

在你的JSONHelper.javagetTempatMakanAll 方法中,添加这些:

for (int i = 0; i < arrayTempatMakan.length(); i++)
        
            JSONObject jobject = arrayTempatMakan.getJSONObject(i);
            JSONObject objRoute = jobject.getJSONArray(TAG_ROUTES).getJSONObject(0);
            JSONObject objLegs = objRoute.getJSONArray(TAG_LEGS).getJSONObject(0);
            JSONObject objDistance = objLegs.getJSONObject("distance");
            JSONObject objDuration = objLegs.getJSONObject("duration");

            Log.d("log", "muter ke " + i);
            listTempatMakan.add(
            new TempatMakan(
                    jobject.getInt(TAG_ID),
                    jobject.getString(TAG_NAMA),
                    jobject.getString(TAG_ALAMAT),
                    objDistance.getString("text"),//jarak
                    objDuration.getString("text"),//durasi
                    jobject.getDouble(TAG_LAT),
                    jobject.getDouble(TAG_LNG)));

        

之后,只需修改您的列表视图适配器以显示这些值。

祝你好运,对不起,我不能给你另一个代码或修改你的项目,你必须自己弄清楚:)

P.S : Skripsi 还是 Tugas Kuliah?

【讨论】:

非常感谢,我会试试的,^_^ 你能把你的程序放到我的程序里吗??我仍然对 json 解析感到困惑 编辑了我的答案,试试看:D 我在帖子中添加了一些课程,请查看:) 这里是我的项目,你可以下载,dropbox.com/s/lm7j6m6f072glup/Tempat%20Makan%20Jogja.rar

以上是关于Google Map Android API V2 中两个位置之间的旅行时间的主要内容,如果未能解决你的问题,请参考以下文章

捕获 Google Map Android API V2 的屏幕截图

Google Developer 控制台“Google Map Android API V2”选项未查看启用

在 android 中扩展 google map api v2 的离线矢量 TileProvider

Google Map Android API V2 中两个位置之间的旅行时间

Android onLocationChanged with Direction使用Google Map Api v2

使用 Google Map API V2 查找地图上两点之间的距离