【问题标题】:Calculating Total Distance Between Way Points android google api计算路点之间的总距离android google api
【发布时间】:2017-11-03 13:54:32
【问题描述】:

我开发了一个应用程序来绘制起点和目的地之间的路线,并且用户将能够沿着该路径标记一些航点,并且路线将被正确绘制。但是我只能在地图上只标记2个地方时才能得到距离。如果我标记 2、3 个地方,它不会给我距离。这些是我的代码,

public class DirectionsJSONParser {

/** Receives a JSONObject and returns a list of lists containing latitude and longitude */
public List<List<HashMap<String,String>>> parse(JSONObject jObject){

    List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>();
    JSONArray jRoutes = null;
    JSONArray jLegs = null;
    JSONArray jSteps = null;
    JSONObject jDistance = null;
    JSONObject jDuration = null;

    try {

        jRoutes = jObject.getJSONArray("routes");

        /** Traversing all routes */
        for(int i=0;i<jRoutes.length();i++){
            jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
            List path = new ArrayList<HashMap<String, String>>();

            /** Traversing all legs */
            for(int j=0;j<jLegs.length();j++){
                /** Getting distance from the json data */
                jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
                HashMap<String, String> hmDistance = new HashMap<String, String>();
                hmDistance.put("distance", jDistance.getString("text"));

                /** Getting duration from the json data */
                jDuration = ((JSONObject) jLegs.get(j)).getJSONObject("duration");
                HashMap<String, String> hmDuration = new HashMap<String, String>();
                hmDuration.put("duration", jDuration.getString("text"));

                /** Adding distance object to the path */
                path.add(hmDistance);

                /** Adding duration object to the path */
                path.add(hmDuration);
                jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");

                /** Traversing all steps */
                for(int k=0;k<jSteps.length();k++){
                    String polyline = "";
                    polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
                    List<LatLng> list = decodePoly(polyline);

                    /** Traversing all points */
                    for(int l=0;l<list.size();l++){
                        HashMap<String, String> hm = new HashMap<String, String>();
                        hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
                        hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
                        path.add(hm);
                    }
                }
                routes.add(path);
            }
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }catch (Exception e){
    }


    return routes;
}


/**
 * Method to decode polyline points
 * Courtesy : jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
 * */
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 p = new LatLng((((double) lat / 1E5)),
                (((double) lng / 1E5)));
        poly.add(p);
    }

    return poly;
}

}

 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("Error downloading url", e.toString());
    }finally{
        iStream.close();
        urlConnection.disconnect();
    }
    return data;
}



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

        tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration);

        // Drawing polyline in the Google Map for the i-th route
        map.addPolyline(lineOptions);
    }

}

我曾经请求的网址

 String parameters = str_origin+"&"+str_dest+"&"+sensor+"&"+waypoints;

    // Output format
    String output = "json";

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

Error I found when I used 4 points with 2 way points

这是在onPostExecute方法中的行,

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

我在这里做错了什么?

【问题讨论】:

    标签: android google-maps google-maps-api-3 google-distancematrix-api


    【解决方案1】:

    你应该通过改造来试试这个。

    将此代码放在 MainActivity 中的按钮单击上:-

    MainActivity.java

    public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, OnMapReadyCallback {
    
        private static final String LOG_TAG = "TAG1";
        private static final String KEY = "Enter Your Key";
        String displayResponseSource = "";
        String displayResponseDestination = "";
        private Button btn_search;
        private GoogleMap map;
        private APIInterface apiInterface;
        private SupportMapFragment mapFragment;
        private AutoCompleteTextView autoCompViewSource;
        private AutoCompleteTextView autoCompViewDestination;
        private String autocompletetextSource = "";
        private String autocompletetextDestination = "";
        private LatLng maplocationdestination;
        private LatLng maplocationsource;
        private double longitudeSource;
        private double latitudeSource;
        private double latitudeDestination;
        private double longitudeDestination;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            autoCompViewSource = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextViewSource);
            autoCompViewDestination = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextViewDestination);
            btn_search = (Button) findViewById(R.id.btn_search);
            autoCompViewSource.setAdapter(new GooglePlacesAutocompleteAdapterSource(this, R.layout.lv_item));
            autoCompViewSource.setOnItemClickListener(this);
            autoCompViewDestination.setAdapter(new GooglePlacesAutocompleteAdapterDestination(this, R.layout.lv_item));
            autoCompViewDestination.setOnItemClickListener(this);
    
            mapFragment = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
    
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            map = googleMap;
    
            btn_search.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    autocompletetextSource = autoCompViewSource.getText().toString();
                    autocompletetextDestination = autoCompViewDestination.getText().toString();
    
                    apiInterface = APIClient.getClient().create(APIInterface.class);
    
                    Call<ModelLatLong> call = apiInterface.getResponse(autocompletetextSource, KEY);
    //                autocompletetext,KEY
                    call.enqueue(new Callback<ModelLatLong>() {
    
    
                        @Override
                        public void onResponse(Call<ModelLatLong> call, Response<ModelLatLong> response) {
    
                            Log.i("TAG", response.code() + "");
    
                            ModelLatLong resource = response.body();
                            ArrayList<Results> resultsList = resource.getResults();
    
                            for (Results results : resultsList) {
                                longitudeSource = results.getGeometry().getLocation().getLng();
                                latitudeSource = results.getGeometry().getLocation().getLat();
                                Log.i("TAG1", displayResponseSource + "HI");
                            }
                            displayResponseSource = latitudeSource+ "," + longitudeSource;
    
    
    //                        Toast.makeText(MainActivity.this, displayResponseSource, Toast.LENGTH_SHORT).show();
    
                            maplocationsource = new LatLng(latitudeSource, longitudeSource);
    
                            map.addMarker(new MarkerOptions()
                                    .position(maplocationsource)
                                    .snippet(autocompletetextSource)).showInfoWindow();
    
                            CameraUpdate center = CameraUpdateFactory.newLatLngZoom(maplocationsource, 14);
                            map.animateCamera(center);
    
                        }
    
                        @Override
                        public void onFailure(Call<ModelLatLong> call, Throwable t) {
                            Log.i("TAG1", "Failed");
                            call.cancel();
                        }
                    });
    
                    Call<ModelLatLong> calldes = apiInterface.getResponse(autocompletetextDestination, KEY);
    //                autocompletetext,KEY
                    calldes.enqueue(new Callback<ModelLatLong>() {
    
                        @Override
                        public void onResponse(Call<ModelLatLong> call, Response<ModelLatLong> response) {
    
                            Log.i("TAG", response.code() + "");
    
                            ModelLatLong resourcedes = response.body();
                            ArrayList<Results> resultsListdes = resourcedes.getResults();
    
                            for (Results results : resultsListdes) {
                                longitudeDestination = results.getGeometry().getLocation().getLng();
                                latitudeDestination = results.getGeometry().getLocation().getLat();
                                Log.i("TAG1", displayResponseDestination + "HI");
                            }
                            displayResponseDestination = latitudeDestination + "," + longitudeDestination;
    
    //                        Toast.makeText(MainActivity.this, displayResponseDestination, Toast.LENGTH_SHORT).show();
    
                            maplocationdestination = new LatLng(latitudeDestination, longitudeDestination);
    
                            map.addMarker(new MarkerOptions()
                                    .position(maplocationdestination)
                                    .snippet(autocompletetextSource)).showInfoWindow();
    
                            CameraUpdate center = CameraUpdateFactory.newLatLngZoom(maplocationdestination, 14);
                            map.animateCamera(center);
    
                        }
    
                        @Override
                        public void onFailure(Call<ModelLatLong> call, Throwable t) {
                            Log.i("TAG1", "Failed");
                            call.cancel();
                        }
                    });
    
                    Call<ModelRoutes> calldistance = apiInterface.getResponseDistance(Get Your Source Latitude and Longitude Here(Eg. 20.9127766,73.7531254), Get Your Destination Latitude and Longitude Here in String(Eg. 23.0098149, 72.5035273), KEY);
                    calldistance.enqueue(new Callback<ModelRoutes>() {
    
    
                        @Override
                        public void onResponse(Call<ModelRoutes> call, Response<ModelRoutes> response) {
    
                            String displayResponse = "";
    
                            ModelRoutes resourcedis = response.body();
                            Log.i("TAG", response.code() + "Hello");
                            ArrayList<Routes> routesList = resourcedis.getRoutes();
                            for (Routes routes : routesList) {
                                ArrayList<Legs> legsList = routes.getLegs();
                                for (Legs legs : legsList) {
                                    String killoMeter = legs.getDistance().getText();
                                    double timeDistance = legs.getDistance().getValue();
                                    displayResponse += "\n Killometer : " + killoMeter + "\n Time Duration : " + timeDistance + "\n";
                                    Log.i("TAG1", displayResponse + "HI");
                                }
                            }
    
    
                            Toast.makeText(MainActivity.this, displayResponse, Toast.LENGTH_SHORT).show();
    
    
                        }
    
                        @Override
                        public void onFailure(Call<ModelRoutes> call, Throwable t) {
                            Log.i("TAG1", "Failed");
                            call.cancel();
                        }
                    });
    
                }
            });
        }
    
        public void onItemClick(AdapterView adapterView, View view, int position, long id) {
            String str = (String) adapterView.getItemAtPosition(position);
    //        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
        }
    
        public static ArrayList autocomplete(String input) {
            ArrayList resultList = null;
    
            HttpURLConnection conn = null;
            StringBuilder jsonResults = new StringBuilder();
            try {
                StringBuilder sb = new StringBuilder("https://maps.googleapis.com/maps/api/place/autocomplete/json");
                sb.append("?key=Enter Your Key Here");
                sb.append("&input=" + URLEncoder.encode(input, "utf8"));
    
                URL url = new URL(sb.toString());
                conn = (HttpURLConnection) url.openConnection();
                InputStreamReader in = new InputStreamReader(conn.getInputStream());
    
                int read;
                char[] buff = new char[1024];
                while ((read = in.read(buff)) != -1) {
                    jsonResults.append(buff, 0, read);
                }
            } catch (MalformedURLException e) {
                Log.e(LOG_TAG, "Error processing Places API URL", e);
                return resultList;
            } catch (IOException e) {
                Log.e(LOG_TAG, "Error connecting to Places API", e);
                return resultList;
            } finally {
                if (conn != null) {
                    conn.disconnect();
                }
            }
    
            try {
                JSONObject jsonObj = new JSONObject(jsonResults.toString());
                JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
    
                resultList = new ArrayList(predsJsonArray.length());
                for (int i = 0; i < predsJsonArray.length(); i++) {
                    System.out.println(predsJsonArray.getJSONObject(i).getString("description"));
                    resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
                }
            } catch (JSONException e) {
                Log.e(LOG_TAG, "Cannot process JSON results", e);
            }
    
            return resultList;
        }
    
        class GooglePlacesAutocompleteAdapterSource extends ArrayAdapter implements Filterable {
            private ArrayList resultList;
    
            public GooglePlacesAutocompleteAdapterSource(Context context, int textViewResourceId) {
                super(context, textViewResourceId);
            }
    
            @Override
            public int getCount() {
                return resultList.size();
            }
    
            @Override
            public Object getItem(int index) {
                return resultList.get(index);
            }
    
            @Override
            public Filter getFilter() {
                Filter filter = new Filter() {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults filterResults = new FilterResults();
                        if (constraint != null) {
                            resultList = autocomplete(constraint.toString());
    
                            filterResults.values = resultList;
                            filterResults.count = resultList.size();
                        }
                        return filterResults;
                    }
    
                    @Override
                    protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
                        if (results != null && results.count > 0) {
                            notifyDataSetChanged();
                        } else {
                            notifyDataSetInvalidated();
                        }
                    }
                };
                return filter;
            }
        }
    
        class GooglePlacesAutocompleteAdapterDestination extends ArrayAdapter implements Filterable {
            private ArrayList resultList;
    
            public GooglePlacesAutocompleteAdapterDestination(Context context, int textViewResourceId) {
                super(context, textViewResourceId);
            }
    
            @Override
            public int getCount() {
                return resultList.size();
            }
    
            @Override
            public Object getItem(int index) {
                return resultList.get(index);
            }
    
            @Override
            public Filter getFilter() {
                Filter filter = new Filter() {
                    @Override
                    protected FilterResults performFiltering(CharSequence constraint) {
                        FilterResults filterResults = new FilterResults();
                        if (constraint != null) {
                            resultList = autocomplete(constraint.toString());
    
                            filterResults.values = resultList;
                            filterResults.count = resultList.size();
                        }
                        return filterResults;
                    }
    
                    @Override
                    protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
                        if (results != null && results.count > 0) {
                            notifyDataSetChanged();
                        } else {
                            notifyDataSetInvalidated();
                        }
                    }
                };
                return filter;
            }
        }
    }
    

    ModelRoutes.java

    public class ModelRoutes extends Legs {
    
        ArrayList<Routes> routes = null;
    
        public ArrayList<Routes> getRoutes() {
            return routes;
        }
    
        public void setRoutes(ArrayList<Routes> routes) {
            this.routes = routes;
        }
    }
    

    Routes.java

    public class Routes extends Legs{
    
        ArrayList<Legs> legs = null;
    
        public ArrayList<Legs> getLegs() {
            return legs;
        }
    
        public void setLegs(ArrayList<Legs> legs) {
            this.legs = legs;
        }
    }
    

    Legs.java

    public class Legs  {
    
        Distances distance;
        Durations duration;
    
        public Distances getDistance() {
            return distance;
        }
    
        public void setDistance(Distances distance) {
            this.distance = distance;
        }
    
        public Durations getDuration() {
            return duration;
        }
    
        public void setDuration(Durations duration) {
            this.duration = duration;
        }
    
        public class Distances{
            public String getText() {
                return text;
            }
    
            public void setText(String text) {
                this.text = text;
            }
    
            public double getValue() {
                return value;
            }
    
            public void setValue(double value) {
                this.value = value;
            }
    
            String text;
            double value;
    
        }
    
        public class Durations{
            String text;
            double value;
    
            public String getText() {
                return text;
            }
    
            public void setText(String text) {
                this.text = text;
            }
    
            public double getValue() {
                return value;
            }
    
            public void setValue(double value) {
                this.value = value;
            }
        }
    
    }
    

    APIClient.java

    public class APIClient {
        private static Retrofit retrofit = null;
    
        static Retrofit getClient() {
    
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
    
    
            retrofit = new Retrofit.Builder()
                    .baseUrl("https://maps.googleapis.com")
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(client)
                    .build();
    
    
    
            return retrofit;
        }
    }
    

    APIInterface.java

    public interface APIInterface {
        @GET("/maps/api/geocode/json")
        Call<ModelLatLong> getResponse(
                @Query("address") String str,
                @Query("key") String str2);
    
    
        @GET("/maps/api/directions/json")
        Call<ModelRoutes> getResponseDistance(
                @Query("origin") String str,
                @Query("destination") String str1,
                @Query("key") String str2);
    }
    

    ModelLatLong.java

    public class ModelLatLong extends Results {
        private ArrayList<Results> results=null;
    
        public ArrayList<Results> getResults() {
            return results;
        }
    
        public void setResults(ArrayList<Results> results) {
            this.results = results;
        }
    }
    

    Results.java

    public class Results extends Geometry{
        private Geometry geometry;
    
        public Geometry getGeometry() {
            return this.geometry;
        }
    
        public void setGeometry(Geometry geometry) {
            this.geometry = geometry;
        }
    
    }
    

    Geometry.java

    public class Geometry extends Location{
        private Location location;
    
        public Location getLocation() {
            return this.location;
        }
    
        public void setLocation(Location location) {
            this.location = location;
        }
    }
    

    Location.java

    public class Location {
        private double lat;
        private double lng;
    
        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;
        }
    }
    

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/activity_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.gmapplaceapi.MainActivity">
    
        <AutoCompleteTextView
            android:id="@+id/autoCompleteTextViewSource"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="Please enter Source place"
            >
    
            <requestFocus />
        </AutoCompleteTextView>
    
        <AutoCompleteTextView
            android:id="@+id/autoCompleteTextViewDestination"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ems="10"
            android:layout_below="@+id/autoCompleteTextViewSource"
            android:hint="Please enter Destination place"
            >
    
            <requestFocus />
        </AutoCompleteTextView>
    
        <Button
            android:id="@+id/btn_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Search"
            android:layout_below="@+id/autoCompleteTextViewDestination"/>
    
        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:id="@+id/map"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:layout_width="match_parent"
            android:layout_height="fill_parent"
            android:layout_below="@+id/btn_search"
            tools:context="com.example.mapwithmarker.MapsMarkerActivity" />
    
    </RelativeLayout>
    

    lv_item.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="3dp"
        android:textSize="20dp" />
    

    不要忘记将 Internet 权限放入清单文件中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-23
      • 2014-11-29
      • 2012-03-25
      • 1970-01-01
      • 2014-02-28
      • 2010-10-30
      相关资源
      最近更新 更多