在我的谷歌地图上看到一条直线而不是一条路线



嗨,我正在尝试实现一个谷歌地图应用程序,显示两个位置标记之间的方向路线。我的第一个标记/位置是我设备的当前位置,第二个标记/位置是通过 API 从数据库获取的。

输出的图片附在这个问题上。

谷歌地图输出

这是我的代码。

HttpConnection.java类 ->

    public class HttpConnection {
     String downloadUrl(String strUrl) throws IOException {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(strUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();
            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 reading url", e.toString());
        } finally {
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
}

DirectionsJSONParser.java类->

    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;
        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++){
                    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 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 : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
     * */
    private List decodePoly(String encoded) {
        List poly = new ArrayList();
        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;
    }
}

主活动.java类 ->

public class MainActivity extends FragmentActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
    private GoogleMap mMap;
    ArrayList<LatLng> MarkerPoints = new ArrayList<>();
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker1,mCurrLocationMarker2;
    LocationRequest mLocationRequest;
    private static final int PERMISSIONS_REQUEST_READ_PHONE_STATE = 1;
    String stringIMEI = "",stringLatitudeOrigin = "",stringLongitudeOrigin = "",
            stringLatitudeDest = "",stringLongitudeDest = "";
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
//        MultiDex.install(this);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(map);
        mapFragment.getMapAsync(this);
        if (checkLocationPermission()){
            buildGoogleApiClient();
        }
        if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{android.Manifest.permission.READ_PHONE_STATE},
                    PERMISSIONS_REQUEST_READ_PHONE_STATE);
        }else {
            TelephonyManager mngr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
            stringIMEI = mngr.getDeviceId().toString();
        }
    }
    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        if (checkLocationPermission()) {
            mMap.setMyLocationEnabled(true);
        }
    }
    private String getUrl(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;
/*       String waypoints = "waypoints=optimize:true|" + ANDHERI.latitude + "," + ANDHERI.longitude + "|"
              + JAGRUTI_NAGAR.latitude + "," + JAGRUTI_NAGAR.longitude + "|";
         Sensor enabled
        String sensor = "sensor=false";
        String mode = "mode=driving"; */
        String key = "key=mygoogleapikey";
        // Building the parameters to the web service
        String parameters = str_origin + "&"  + str_dest + "&"  + key;//+ waypoints + "&"
        // Output format
        String output = "json";
        // Building the url to the web service
        String url = "http://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
        return url;
    }
    /**
     * A method to download json data from url
     */
    // Fetches data from url passed
    private class FetchUrl extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... url) {
            String data = "";
            try {
                HttpConnection http = new HttpConnection();
                data = http.downloadUrl(url[0]);
            } catch (Exception e) {
                Log.d("Background Task", e.toString());
            }
            return data;
        }
        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            new 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]);
                Log.d("ParserTask",jsonData[0].toString());
                DirectionsJSONParser parser = new DirectionsJSONParser();
                Log.d("ParserTask", parser.toString());
                // Starts parsing data
                routes = parser.parse(jObject);
                Log.d("ParserTask","Executing routes");
                Log.d("ParserTask",routes.toString());
            } catch (Exception e) {
                Log.d("ParserTask",e.toString());
                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;
            PolylineOptions lineOptions = null;
            // Traversing through all the routes
            for (int i = 0; i < result.size(); i++) {
                points = new ArrayList<>();
                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 < MarkerPoints.size(); j++) {
                    HashMap<String, String> point = path.get(j);
                    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(10);
                lineOptions.color(Color.RED);
                Log.d("onPostExecute","onPostExecute lineoptions decoded");
            }
            // Drawing polyline in the Google Map for the i-th route
            if(lineOptions != null) {
                mMap.addPolyline(lineOptions);
            }
            else {
                Log.d("onPostExecute","without Polylines drawn");
            }
        }
    }
    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }
    @Override
    public void onConnected(Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }
    @Override
    public void onConnectionSuspended(int i) { }
    @Override
    public void onLocationChanged(Location location) {
        mLastLocation = location;
        if (mCurrLocationMarker1 != null) {
            mCurrLocationMarker1.remove();
        }
        //Place current location marker
        LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
        stringLatitudeOrigin = String.valueOf(location.getLatitude());
        stringLongitudeOrigin = String.valueOf(location.getLongitude());
        mCurrLocationMarker1 = mMap.addMarker(new MarkerOptions().position(latLng).title("Your device"));
        GetLocationVolleyRequest();
        //move map camera
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,13.0f));
        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) { }
    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    public boolean checkLocationPermission(){
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            // Asking user if explanation is needed
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {
                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
                //Prompt the user once explanation has been shown
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted. Do the
                    // contacts-related task you need to do.
                    if (ContextCompat.checkSelfPermission(this,
                            Manifest.permission.ACCESS_FINE_LOCATION)
                            == PackageManager.PERMISSION_GRANTED) {
                        if (mGoogleApiClient == null) {
                            buildGoogleApiClient();
                        }
                        mMap.setMyLocationEnabled(true);
                    }
                }else {
                    // Permission denied, Disable the functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                }
                return;
            }
            case PERMISSIONS_REQUEST_READ_PHONE_STATE : {
                if (requestCode == PERMISSIONS_REQUEST_READ_PHONE_STATE
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    TelephonyManager mngr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
                    stringIMEI = mngr.getDeviceId().toString();
                }else {
                    // Permission denied, Disable the functionality that depends on this permission.
                    Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                }
            } // other 'case' lines to check for other permissions this app might request.
            // You can add here other case statements according to your requirement.
        }
    }
    public void GetLocationVolleyRequest(){
        StringRequest stringRequest = new StringRequest(Request.Method.POST, Constants.LOCATIONAPI_URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        try {
                            JSONObject json = new JSONObject(response);
                            if (json.getString("success").equals("1")) {
                                stringLatitudeDest = json.getString("latitude");
                                stringLongitudeDest = json.getString("longitude");
                                Toast.makeText(MainActivity.this,"Other Device -> Lat : "+stringLatitudeDest + " Lng : " +
                                        stringLongitudeDest,Toast.LENGTH_LONG).show();
                                mCurrLocationMarker2 = mMap.addMarker(new MarkerOptions().position(new LatLng(Double.parseDouble(stringLatitudeDest),
                                        Double.parseDouble(stringLongitudeDest))).title("Other device"));
                                MarkerPoints.add(new LatLng(Double.parseDouble(stringLatitudeOrigin),
                                        Double.parseDouble(stringLongitudeOrigin)));
                                MarkerPoints.add(new LatLng(Double.parseDouble(stringLatitudeDest),
                                        Double.parseDouble(stringLongitudeDest)));
//                                 Instantiating the class PolylineOptions to plot polyline in the map
                                PolylineOptions polylineOptions = new PolylineOptions();
                                // Setting the color of the polyline
                                polylineOptions.color(Color.RED);
                                // Setting the width of the polyline
                                polylineOptions.width(10);
                                // Setting points of polyline
                                polylineOptions.addAll(MarkerPoints);
                                // Adding the polyline to the map
                                mMap.addPolyline(polylineOptions);
                                // Checks, whether start and end locations are captured
                                if (MarkerPoints.size() >= 2) {
                                    LatLng origin = MarkerPoints.get(0);
                                    LatLng dest = MarkerPoints.get(1);
                                    // Getting URL to the Google Directions API
                                    String url = getUrl(origin, dest);
                                    Log.d("onMapClick", url.toString());
                                    FetchUrl fetchUrl = new FetchUrl();
                                    // Start downloading json data from Google Directions API
                                    fetchUrl.execute(url);
                                    //move map camera
                                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(origin,14.0f));
                                }
                            }else {
                                Toast.makeText(MainActivity.this,"Could not Co-ordinates due to"+json.getString("error_msg"),
                                        Toast.LENGTH_LONG).show();
                            }
                        }catch (JSONException je){
                            je.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_LONG).show();
                    }
                }){
            @Override
            protected Map<String,String> getParams(){
                Map<String,String> params = new HashMap<String, String>();
                params.put("imei",stringIMEI);
                params.put("latitude",stringLatitudeOrigin);
                params.put("longitude",stringLongitudeOrigin);
                return params;
            }
        };
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        requestQueue.add(stringRequest);
    }
}

请帮忙。

试试这个:

1 获取方向网址需要调用谷歌地图 API

private String  getMapsApiDirectionsUrl(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;
}

2. 在后台进行 URL 调用

  private class ReadTask extends AsyncTask<String, Void , String> {
    @Override
    protected String doInBackground(String... url) {
        // TODO Auto-generated method stub
        String data = "";
        try {
            MapHttpConnection http = new MapHttpConnection();
            data = http.readUr(url[0]);

        } catch (Exception e) {
            // TODO: handle exception
            Log.d("Background Task", e.toString());
        }
        return data;
    }
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        new ParserTask().execute(result);
    }
    }
 public class MapHttpConnection {
  public String readUr(String mapsApiDirectionsUrl) throws IOException{
      String data = "";
      InputStream istream = null;
      HttpURLConnection urlConnection = null;
      try {
          URL url = new URL(mapsApiDirectionsUrl);
          urlConnection = (HttpURLConnection) url.openConnection();
          urlConnection.connect();
          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 reading url", e.toString());
      } finally {
          istream.close();
          urlConnection.disconnect();
      }
      return data;
  }
}

3. 创建解析器类以将数据从 JSON 解析为点列表

  public class PathJSONParser {
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;
    try {
        jRoutes = jObject.getJSONArray("routes");
        for (int i=0 ; i < jRoutes.length() ; i ++) {
            jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
            List<HashMap<String, String>> path = new ArrayList<HashMap<String,String>>();
            for(int j = 0 ; j < jLegs.length() ; j++) {
                jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("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);
                    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 (Exception e) {
        e.printStackTrace();
    }
    return routes;
}
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;
}}
  1. 使用另一个线程进行解析以扩展性能

    private class ParserTask extends AsyncTask<String,Integer, 
     List<List<HashMap<String , String >>>> {
     @Override
      protected List<List<HashMap<String, String>>> doInBackground(
          String... jsonData) {
      // TODO Auto-generated method stub
      JSONObject jObject;
      List<List<HashMap<String, String>>> routes = null;
      try {
          jObject = new JSONObject(jsonData[0]);
          PathJSONParser parser = new PathJSONParser();
          routes = parser.parse(jObject);
    
      } catch (Exception e) {
          e.printStackTrace();
        }
         return routes;
     }
    @Override
    protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
      ArrayList<LatLng> points = null;
      PolylineOptions polyLineOptions = null;
      // traversing through routes
      for (int i = 0; i < routes.size(); i++) {
          points = new ArrayList<LatLng>();
          polyLineOptions = new PolylineOptions();
          List<HashMap<String, String>> path = routes.get(i);
          for (int j = 0; j < path.size(); j++) {
              HashMap<String, String> point = path.get(j);
              double lat = Double.parseDouble(point.get("lat"));
              double lng = Double.parseDouble(point.get("lng"));
              LatLng position = new LatLng(lat, lng);
              points.add(position);
          }
          polyLineOptions.addAll(points);
          polyLineOptions.width(4);
          polyLineOptions.color(Color.BLUE);
      }
      googleMap.addPolyline(polyLineOptions);
     }}
    

5 当你想得到两点的路径时

String url = getMapsApiDirectionsUrl(latlngOne, latlngTwo);                    
    ReadTask downloadTask = new ReadTask();       
    // Start downloading json data from Google Directions API
    downloadTask.execute(url);

计算点之间的距离

float[] results = new float[1];
Location.distanceBetween(latLongA.latitude, latLongB.longitude,
                         latLongB.latitude, latLongB.longitude,
                         results); 

注意:结果将以米为单位

没有

从谷歌 api 网址得到任何对我的 android 代码的回应,http://所以把它改成了https://,它工作了。

最新更新