PolyLine 不在道路上:它从一个点直行到另一个点 [英] PolyLine is not on the roads: it goes straight from one point to other

查看:22
本文介绍了PolyLine 不在道路上:它从一个点直行到另一个点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的地图包含多个点以点击用户从他经过的位置,但是 道路上不显示折线,而是显示从一个标记到另一个标记的直线.我希望我的多段线穿过马路:当道路转弯时,它也应该转弯.

这是我的相关代码

 dataholder = FirebaseDatabase.getInstance().getReference("UserLocation");Log.d("onMapReady", "我在这里");dataholder.addValueEventListener(new ValueEventListener() {@覆盖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","我在循环");mMap = googleMap;双纬度 = Double.parseDouble(lati.get(i));Double longi = Double.parseDouble(longit.get(i));悉尼 = 新 LatLng(longi, lat);点加(悉尼);MarkerOptions mop = new MarkerOptions();拖把位置(悉尼);mop.title("检查");mMap.addMarker(mop);Log.d("纬度", String.valueOf(lat));Log.d("longitude", String.valueOf(longi));//在悉尼添加一个标记并移动相机mMap.addMarker(new MarkerOptions().position(sydney).title("check"));mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));我++;}line.addAll(points).width(5).color(Color.RED);line.geodesic(真);mMap.addPolyline(line);mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {@覆盖公共布尔 onMarkerClick(标记标记){Toast.makeText(getApplicationContext(),marker.getTitle().toString(),Toast.LENGTH_LONG).show();返回假;}});

解决方案

尝试使用 GoogleMaps Roads API 部分 Snap to Road

<块引用>

为给定的 GPS 坐标集返回最适合的道路几何形状.此服务最多需要沿路线收集 100 个 GPS 点,并且返回一组相似的数据,其中的点被捕捉到最多车辆行驶的可能道路.

类似于来自 Google Maps Roads API Snap to Road 示例的数据:

公共类 MainActivity 扩展 AppCompatActivity 实现 OnMapReadyCallback {私人谷歌地图 mGoogleMap;私有 MapFragment mapFragment;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map_fragment);mapFragment.getMapAsync(this);}@覆盖公共无效 onMapReady(GoogleMap googleMap) {mGoogleMap = googleMap;列表<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));列表<LatLng>snappedPoints = new ArrayList<>();new GetSnappedPointsAsyncTask().execute(sourcePoints, null, snappedPoints);}private String buildRequestUrl(List 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>);返回 url.toString();}私有类 GetSnappedPointsAsyncTask 扩展了 AsyncTask、Void、List>{受保护的无效 onPreExecute() {super.onPreExecute();}protected ListdoInBackground(List... params) {列表<LatLng>snappedPoints = new ArrayList<>();HttpURLConnection 连接 = null;BufferedReader 阅读器 = null;尝试 {URL url = 新 URL(buildRequestUrl(params[0]));连接 = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");连接.connect();InputStream 流 = connection.getInputStream();reader = new BufferedReader(new InputStreamReader(stream));StringBuilder jsonStringBuilder = new StringBuilder();StringBuffer 缓冲区 = new StringBuffer();字符串行 = "";while ((line = reader.readLine()) != null) {buffer.append(line+"
");jsonStringBuilder.append(line);jsonStringBuilder.append("
");}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");双纬度 = snappedPointLocation.getDouble("纬度");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();} 最后 {如果(连接!= null){connection.disconnect();}尝试 {如果(读者!= null){reader.close();}} catch (IOException e) {e.printStackTrace();}}返回 snappedPoints;}@覆盖protected void onPostExecute(List 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 边界 = builder.build();mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));}}}

并且不要忘记在

其中:蓝色折线 - 源点,红色折线 - 捕捉点.

请记住,每个用户 (IP) 每天有 100 个 GPS 点和 2500 个请求,每秒有 10 个请求.而且您还需要更优雅的解决方案来下载快照点 JSON.

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

解决方案

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+"
");
                    jsonStringBuilder.append(line);
                    jsonStringBuilder.append("
");
                }

                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.

这篇关于PolyLine 不在道路上:它从一个点直行到另一个点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆