【问题标题】:How to get precise route between Two geo points in android programming如何在android编程中获得两个地理点之间的精确路线
【发布时间】:2015-06-18 04:44:24
【问题描述】:

我正在尝试为自己创建一个谷歌地图示例。目标是计算两个地理点之间的路线。我在试图找出两点之间的路线时遇到了一些问题。一方面,我的地图生成但我在尝试计算距离并在地图上生成路线时遇到了一些错误。请原谅我的编码我是 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
        }
    }

【问题讨论】:

    标签: android maps


    【解决方案1】:

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

    您想要的点在 route->legs->steps->polyline->points 中,并且它们已被编码,因此您需要使用可以找到 here 的代码来解码它们。

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

    【讨论】:

      【解决方案2】:

      您的函数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);
      

      【讨论】:

        【解决方案3】:

        求两点之间的准确距离(跑步距离) 首先从谷歌获取网址,像这样,而不是查找距离

        在 mainActivity 中添加这个

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

        类 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 类时通过这些原点

        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);
        
        }
        

        【讨论】:

        • 感谢您的回答,但我想使用位置管理器生成我的 gps 并计算到某个固定位置的方向
        • 你能说得更具体点吗,你的意思是你想用位置管理器找出你的位置,然后计算某个随机点到你当前位置的距离...???
        • 是的。我想计算距离并显示到那个随机点的路线。
        • 我已编辑答案请检查。
        猜你喜欢
        • 2012-01-03
        • 2011-01-08
        • 2012-08-05
        • 1970-01-01
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多