PolyLine is not on the roads: it goes straight from one point to other

China☆狼群 提交于 2019-12-17 13:29:10

问题


My map contains multiple points to tap the location of the user from where he passes, but the polyline is not shown on the roads, but shows a direct line from one marker to other. I want my polyline to go across the road: as the roads turns, it should also turn.

Here's my relevant code

 dataholder = FirebaseDatabase.getInstance().getReference("UserLocation");
 Log.d("onMapReady", "iam here");
 dataholder.addValueEventListener(new ValueEventListener() {

     @Override
     public void onDataChange(DataSnapshot dataSnapshot) {
         Log.d("data",String.valueOf(dataSnapshot.getValue()));
         System.out.println(dataSnapshot.getValue());
         for (DataSnapshot a : dataSnapshot.getChildren()) {
             MapData mapData = a.getValue(MapData.class);
             arrayList.add(mapData);
             lati.add(arrayList.get(i).getLatituide());
             longit.add(arrayList.get(i).getLongitude());
             Log.d("mapi","i am in loop");
             mMap = googleMap;
             Double lat = Double.parseDouble(lati.get(i));
             Double longi = Double.parseDouble(longit.get(i));
             sydney = new LatLng(longi, lat);
             points.add(sydney);
             MarkerOptions mop = new MarkerOptions();
             mop.position(sydney);
             mop.title("check");
             mMap.addMarker(mop);
             Log.d("latitude", String.valueOf(lat));
             Log.d("longitude", String.valueOf(longi));
             // Add a marker in Sydney and move the camera
             mMap.addMarker(new MarkerOptions().position(sydney).title("check"));
             mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

             i++;
         }

    line.addAll(points).width(5).color(Color.RED);
    line.geodesic(true);
    mMap.addPolyline(line);

    mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
        @Override
        public boolean onMarkerClick(Marker marker) {
            Toast.makeText(getApplicationContext(),marker.getTitle().toString(),Toast.LENGTH_LONG).show();
            return false;
        }
    });

回答1:


Try to use Google Maps Roads API part Snap to Road which

returns the best-fit road geometry for a given set of GPS coordinates. This service takes up to 100 GPS points collected along a route, and returns a similar set of data with the points snapped to the most likely roads the vehicle was traveling along.

Something like that for data from Google Maps Roads API Snap to Road example:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mGoogleMap;
    private MapFragment mapFragment;

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

        mapFragment = (MapFragment) getFragmentManager()
                .findFragmentById(R.id.map_fragment);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;

        List<LatLng> sourcePoints = new ArrayList<>();
        sourcePoints.add(new LatLng(-35.27801,149.12958));
        sourcePoints.add(new LatLng(-35.28032,149.12907));
        sourcePoints.add(new LatLng(-35.28099,149.12929));
        sourcePoints.add(new LatLng(-35.28144,149.12984));
        sourcePoints.add(new LatLng(-35.28194,149.13003));
        sourcePoints.add(new LatLng(-35.28282,149.12956));
        sourcePoints.add(new LatLng(-35.28302,149.12881));
        sourcePoints.add(new LatLng(-35.28473,149.12836));

        PolylineOptions polyLineOptions = new PolylineOptions();
        polyLineOptions.addAll(sourcePoints);
        polyLineOptions.width(5);
        polyLineOptions.color(Color.BLUE);
        mGoogleMap.addPolyline(polyLineOptions);

        mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sourcePoints.get(0), 15));

        List<LatLng> snappedPoints = new ArrayList<>();
        new GetSnappedPointsAsyncTask().execute(sourcePoints, null, snappedPoints);
    }


    private String buildRequestUrl(List<LatLng> trackPoints) {
        StringBuilder url = new StringBuilder();
        url.append("https://roads.googleapis.com/v1/snapToRoads?path=");

        for (LatLng trackPoint : trackPoints) {
            url.append(String.format("%8.5f", trackPoint.latitude));
            url.append(",");
            url.append(String.format("%8.5f", trackPoint.longitude));
            url.append("|");
        }
        url.delete(url.length() - 1, url.length());
        url.append("&interpolate=true");
        url.append(String.format("&key=%s", <your_Google_Maps_API_key>);

        return url.toString();
    }


    private class GetSnappedPointsAsyncTask extends AsyncTask<List<LatLng>, Void, List<LatLng>> {

        protected void onPreExecute() {
            super.onPreExecute();
        }

        protected List<LatLng> doInBackground(List<LatLng>... params) {

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

            HttpURLConnection connection = null;
            BufferedReader reader = null;

            try {
                URL url = new URL(buildRequestUrl(params[0]));
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.connect();

                InputStream stream = connection.getInputStream();

                reader = new BufferedReader(new InputStreamReader(stream));
                StringBuilder jsonStringBuilder = new StringBuilder();

                StringBuffer buffer = new StringBuffer();
                String line = "";

                while ((line = reader.readLine()) != null) {
                    buffer.append(line+"\n");
                    jsonStringBuilder.append(line);
                    jsonStringBuilder.append("\n");
                }

                JSONObject jsonObject = new JSONObject(jsonStringBuilder.toString());
                JSONArray snappedPointsArr = jsonObject.getJSONArray("snappedPoints");

                for (int i = 0; i < snappedPointsArr.length(); i++) {
                    JSONObject snappedPointLocation = ((JSONObject) (snappedPointsArr.get(i))).getJSONObject("location");
                    double lattitude = snappedPointLocation.getDouble("latitude");
                    double longitude = snappedPointLocation.getDouble("longitude");
                    snappedPoints.add(new LatLng(lattitude, longitude));
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            return snappedPoints;
        }

        @Override
        protected void onPostExecute(List<LatLng> result) {
            super.onPostExecute(result);

            PolylineOptions polyLineOptions = new PolylineOptions();
            polyLineOptions.addAll(result);
            polyLineOptions.width(5);
            polyLineOptions.color(Color.RED);
            mGoogleMap.addPolyline(polyLineOptions);

            LatLngBounds.Builder builder = new LatLngBounds.Builder();
            builder.include(result.get(0));
            builder.include(result.get(result.size()-1));
            LatLngBounds bounds = builder.build();
            mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));

        }
    }

}

And don't forget to add Google Maps Roads API support for your project in Google APIs Console (select your project, than select Dashboard, than press "+ ENABLE APIS AND SERVICES " button, than on the left side "Filter by" select "Maps", than press "Google Maps Roads API" and, finally, press button "ENABLE").

You should get something like that:

where: blue polyline - for source points, red polyline - for snapped points.

Remember there is a limit of 100 GPS points and 2500 request per day per user (IP) and 10 requests per sec. And also you need more elegant solution for snapped points JSON downloading.



来源:https://stackoverflow.com/questions/47329243/polyline-is-not-on-the-roads-it-goes-straight-from-one-point-to-other

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!