折线不在道路上:它直接从一个点到另一个点。

4

我的地图包含多个点,可以通过点击用户通过的位置来标记,但是折线不会显示在道路上,而是直接连接两个标记。我希望我的折线可以穿过道路:当道路转弯时,折线也应该跟着转弯。

这是相关代码:

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

尝试使用此教程绘制两点之间的路径。该教程使用Google方向和Google地图Android API V2。https://www.androidtutorialpoint.com/intermediate/google-maps-draw-path-two-points-using-google-directions-google-map-android-api-v2/ - Tara
1个回答

7
尝试使用Google Maps Roads APISnap to Road部分,它可以返回给定一组GPS坐标的最佳道路几何形状。该服务可以接收沿途收集的最多100个GPS点,并返回类似的数据集,其中点被捕捉到车辆行驶的最可能道路上。类似于从Google Maps Roads API Snap to Road示例中获取的数据。
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));

        }
    }

}

请不要忘记在Google APIs控制台中为您的项目添加Google Maps Roads API支持(选择您的项目,然后选择仪表板,然后按“+启用API和服务”按钮,然后在左侧“按过滤器”选择“地图”,然后按“Google Maps Roads API”按钮,最后按“启用”按钮)。
您应该会得到类似下面的内容:

Snapped points polyline

位置:蓝色折线表示源点,红色折线表示捕捉点。

请记住,每个用户(IP)每天最多只能请求100个GPS点和2500次请求,并且每秒最多只能请求10次。此外,您需要更优雅的解决方案来下载捕捉点JSON。


@TobiasHvassMølbak 那个例子是用于 Directions API,而不是 Roads API。 - Andrii Omelchenko
@RanaArslan 只需前往Google APIs控制台,选择您的项目,然后选择仪表板,再按“+启用API和服务”按钮,然后在左侧的“筛选器”中选择“地图”,然后按“Google Maps Roads API”按钮,最后按“启用”按钮即可。 - Andrii Omelchenko
@AndriiOmelchenko 它没有将点映射到道路上,请检查更新的问题输出并附上。 - Rana Arslan
@RanaArslan 是的,这是完全不同的API:https://developers.google.com/maps/documentation/directions/intro,具有完全不同的请求和响应。请看这个:https://android.jlelse.eu/google-maps-directions-api-5b2e11dee9b0 教程。 - Andrii Omelchenko
@AndriiOmelchenko,我发现有时候路线不会显示所有的点,会丢失一些点。你知道为什么吗? - NullPointerException
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接