如何在android编程中获得两个地理点之间的精确路由

时间:2015-06-18 04:44:24

标签: android maps

我正在尝试为自己创建一个谷歌地图示例。目标是计算两个地理点之间的路线。我试图找出两点之间的路线有点问题。对于我的地图生成一个,但我有一些错误试图计算距离并在地图上生成路线。请原谅我的编码我不熟悉Android编程。

   import android.content.Context;
   import android.location.Criteria;
   import android.location.Geocoder;
   import android.location.Location;
   import android.location.LocationManager;
   import android.support.v4.app.FragmentActivity;
   import android.os.Bundle;
   import android.util.Log;
   import android.widget.Toast;
   import com.google.android.gms.common.api.GoogleApiClient;
   import com.google.android.gms.location.LocationServices;
   import com.google.android.gms.maps.CameraUpdate;
   import com.google.android.gms.maps.CameraUpdateFactory;
   import com.google.android.gms.maps.GoogleMap;
   import com.google.android.gms.maps.SupportMapFragment;
   import com.google.android.gms.maps.model.CameraPosition;
   import com.google.android.gms.maps.model.LatLng;
   import com.google.android.gms.maps.model.MarkerOptions;

    import java.text.DecimalFormat;

     public class MapsActivity extends FragmentActivity {

private GoogleMap mMap; // Might be null if Google Play services APK is not available.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    setUpMapIfNeeded();
}

@Override
protected void onResume() {
    super.onResume();
    setUpMapIfNeeded();
}

/**
 * Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
 * installed) and the map has not already been instantiated.. This will ensure that we only ever
 * call {@link #setUpMap()} once when {@link #mMap} is not null.
 * <p/>
 * If it isn't installed {@link SupportMapFragment} (and
 * {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
 * install/update the Google Play services APK on their device.
 * <p/>
 * A user can return to this FragmentActivity after following the prompt and correctly
 * installing/updating/enabling the Google Play services. Since the FragmentActivity may not
 * have been completely destroyed during this process (it is likely that it would only be
 * stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
 * method in {@link #onResume()} to guarantee that it will be called.
 */
private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

/**
 * This is where we can add markers or lines, add listeners or move the camera. In this case, we
 * just add a marker near Africa.
 * <p/>
 * This should only be called once and when we are sure that {@link #mMap} is not null.
 */

private void setUpMap() {

    mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker").snippet("Snippet"));

    // Enable MyLocation Layer of Google Map
    mMap.setMyLocationEnabled(true);

    // Get LocationManager object from System Service LOCATION_SERVICE
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // Create a criteria object to retrieve provider
    Criteria criteria = new Criteria();

    // Get the name of the best provider
    String provider = locationManager.getBestProvider(criteria, true);

    // Get Current Location
    Location myLocation = locationManager.getLastKnownLocation(provider);

    // set map type
    mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

    // Get latitude of the current location

    Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

    if (location != null) {
        double longitude = location.getLongitude();
        double latitude = location.getLatitude();


        // Get longitude of the current location

        // Create a LatLng object for the current location
        LatLng latLng = new LatLng(latitude, longitude);

        // Show the current location in Google Map
        mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

        // Zoom in the Google Map
        //LatLng myCoordinates = new LatLng(latitude, longitude);
        //CameraUpdate yourLocation = CameraUpdateFactory.newLatLngZoom(myCoordinates, 20);
        //mMap.animateCamera(yourLocation);
        mMap.animateCamera(CameraUpdateFactory.zoomTo(20));
        mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("You are here!").snippet("Consider yourself located"));

    }
    double fromLat = 49.85, fromLon = 24.016667;
    double toLat = 50.45, toLon = 30.523333;
    CalculationByDistance(fromLat,toLat);

}



public double CalculationByDistance(LatLng StartP, LatLng EndP) {
    int Radius = 6371;// radius of earth in Km
    double lat1 = StartP.latitude;
    double lat2 = EndP.latitude;
    double lon1 = StartP.longitude;
    double lon2 = EndP.longitude;
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
            + Math.cos(Math.toRadians(lat1))
            * Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
            * Math.sin(dLon / 2);
    double c = 2 * Math.asin(Math.sqrt(a));
    double valueResult = Radius * c;
    double km = valueResult / 1;
    DecimalFormat newFormat = new DecimalFormat("####");
    int kmInDec = Integer.valueOf(newFormat.format(km));
    double meter = valueResult % 1000;
    int meterInDec = Integer.valueOf(newFormat.format(meter));
    Log.i("Radius Value", "" + valueResult + "   KM  " + kmInDec
            + " Meter   " + meterInDec);

    return Radius * c;
}


        public void onFinish() {
            // Your code here to do something after the Map is rendered
        }
    }

3 个答案:

答案 0 :(得分:1)

首先,您需要使用Google Directions API来获取您希望在地图上绘制的一组点。在调用Web服务并获得结果后,您将不得不解析类似this的json。

您想要的点位于route-&gt; leg-&gt; steps-&gt;折线 - &gt;点并且它们已经过编码,因此您需要使用可以找到here的代码解码它们。

此时,正如Neal指出的那样,您需要获取这些点并将它们添加到PolylineOptions并将它们添加到地图中。

答案 1 :(得分:0)

您的函数CaculationByDistance接收LatLng个类型变量。所以尝试改变:

double fromLat = 49.85, fromLon = 24.016667;
double toLat = 50.45, toLon = 30.523333;

要:

LatLng fromLatLng = new LatLng(49.85, 24.016667);
LatLng toLatLng = new LatLng(50.45, 30.523333);

然后你的功能应该有效:

CalculationByDistance(fromLatLng,toLatLng);

答案 2 :(得分:0)

找到两点之间的确切距离(跑步距离) 首先从谷歌获取URL,比如找到距离

在mainActivity中添加此内容

String url = getDirectionsUrl(fromLatLng, toLatLng);
DownloadTask downloadTask = new DownloadTask();             
// Start downloading json data from Google Directions API
downloadTask.execute(url);

class getDirectionsURL

 private String getDirectionsUrl(LatLng origin,LatLng dest){

        // Origin of route
        String str_origin = "origin="+origin.latitude+","+origin.longitude;

        // Destination of route
        String str_dest = "destination="+dest.latitude+","+dest.longitude;      


        // Sensor enabled
        String sensor = "sensor=false";         

        // Building the parameters to the web service
        String parameters = str_origin+"&"+str_dest+"&"+sensor;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;


        return url;
    }

查找距离的课程

// Fetches data from url passed
    private class DownloadTask extends AsyncTask<String, Void, String>{         

        // Downloading data in non-ui thread
        @Override
        protected String doInBackground(String... url) {

            // For storing data from web service
            String data = "";

            try{
                // Fetching the data from web service
                data = downloadUrl(url[0]);
            }catch(Exception e){
                Log.d("Background Task",e.toString());
            }
            return data;        
        }

        // Executes in UI thread, after the execution of
        // doInBackground()
        @Override
        protected void onPostExecute(String result) {           
            super.onPostExecute(result);            

            ParserTask parserTask = new ParserTask();

            // Invokes the thread for parsing the JSON data
            parserTask.execute(result);

        }       
    }



    /** A class to parse the Google Places in JSON format */
    private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{

        // Parsing the data in non-ui thread        
        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {

            JSONObject jObject; 
            List<List<HashMap<String, String>>> routes = null;                     

            try{
                jObject = new JSONObject(jsonData[0]);
                DirectionsJSONParser parser = new DirectionsJSONParser();

                // Starts parsing data
                routes = parser.parse(jObject);    
            }catch(Exception e){
                e.printStackTrace();
            }
            return routes;
        }

        // Executes in UI thread, after the parsing process
        @SuppressWarnings("unused")
        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {
            ArrayList<LatLng> points = null;
            PolylineOptions lineOptions = null;
            MarkerOptions markerOptions = new MarkerOptions();
            String distance = "";
            String duration = "";



            if(result.size()<1){
                Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show();
                return;
            }


            // Traversing through all the routes
            for(int i=0;i<result.size();i++){
                points = new ArrayList<LatLng>();
                lineOptions = new PolylineOptions();

                // Fetching i-th route
                List<HashMap<String, String>> path = result.get(i);

                // Fetching all the points in i-th route
                for(int j=0;j<path.size();j++){
                    HashMap<String,String> point = path.get(j); 

                    if(j==0){   // Get distance from the list
                        distance = (String)point.get("distance");                       
                        continue;
                    }else if(j==1){ // Get duration from the list
                        duration = (String)point.get("duration");
                        continue;
                    }

                    double lat = Double.parseDouble(point.get("lat"));
                    double lng = Double.parseDouble(point.get("lng"));
                    LatLng position = new LatLng(lat, lng); 

                    points.add(position);                       
                }

                // Adding all the points in the route to LineOptions
                lineOptions.addAll(points);
                lineOptions.width(2);
                lineOptions.color(Color.RED);   

            }

            Log.e("Distance: "+distance , "Duration: "+duration);
            tvDistanceDuration.setText("Distance: "+distance + ", Duration: "+duration);
            // Drawing polyline in the Google Map for the i-th route
            map.addPolyline(lineOptions);                           
        }           
    }

    /** A method to download json data from url */
    private String downloadUrl(String strUrl) throws IOException{
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
                URL url = new URL(strUrl);

                // Creating an http connection to communicate with url 
                urlConnection = (HttpURLConnection) url.openConnection();

                // Connecting to url 
                urlConnection.connect();

                // Reading data from url 
                iStream = urlConnection.getInputStream();

                BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

                StringBuffer sb  = new StringBuffer();

                String line = "";
                while( ( line = br.readLine())  != null){
                        sb.append(line);
                }

                data = sb.toString();

                br.close();

        }catch(Exception e){
                Log.d("Exception while downloading url", e.toString());
        }finally{
                iStream.close();
                urlConnection.disconnect();
        }
        return data;
     }

这是一个获取当前位置的类

使用

调用此方法
LatLng origin = getCurrentLocation();

并在致电getDirectionsUrl class

时传递这些原点
private LatLng getCurrentLocation() {
    // Do a null check to confirm that we have not already instantiated the
    // map.
    if (googleMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        googleMap = ((MapFragment) getFragmentManager().findFragmentById(
                R.id.map)).getMap();
        googleMap.setMyLocationEnabled(true);
        // Check if we were successful in obtaining the map.
        if (googleMap != null) {

            googleMap
                    .setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {

                        @Override
                        public void onMyLocationChange(Location arg0) {

                            googleMap.addMarker(new MarkerOptions()
                                    .position(
                                            new LatLng(arg0.getLatitude(),
                                                    arg0.getLongitude()))
                                    .title("You're Here"));

                            latlng = new LatLng(arg0.getLatitude(), arg0
                                    .getLongitude());

                            CameraPosition cameraPosition = new CameraPosition(
                                    latlng, 12, 0, 0);
                            Geocoder geocoder = new Geocoder(
                                    getApplicationContext(), Locale.ENGLISH);
                            List<Address> addresses;
                            try {
                                addresses = geocoder.getFromLocation(
                                        arg0.getLatitude(),
                                        arg0.getLongitude(), 1);
                                if (addresses != null
                                        && addresses.size() > 0) {
                                    Address address = addresses.get(0);
                                    country = address.getCountryName();
                                    latitute = arg0.getLatitude();
                                    longitude = arg0.getLongitude();
                                    Log.e("latitude", latitute+"");
                                    Log.e("longitude", longitude+"");
                                    latSource=latitute;
                                    longSource=longitude;

                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }

                            googleMap.animateCamera(CameraUpdateFactory
                                    .newCameraPosition(cameraPosition),
                                    4000, null);
                            googleMap.setOnMyLocationChangeListener(null);
                        }
                    });
        }
    }
    return new LatLng(latitute, longitude);

}