道路googleapi:一些地方失踪,线路通过大厦

问题描述 投票:1回答:1

我正在使用Roads Google API传递一系列位置,我希望通过这些点在汽车驾驶的最可能道路上绘制线条。

有些东西出了问题,因为有些点没有被线穿过,而且线条不仅仅使用道路,有些线路通过大厦或大海直线穿过。我添加了标记来显示问题。

代码中有问题吗?

enter image description here

一些示例代码来获取此错误:

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(39.4321055669415, -0.343169529033198));
    sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
    sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
    sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
    sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
    sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
    sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
    sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));

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

    }
}

}
android google-maps google-places-api google-maps-android-api-2 google-roads-api
1个回答
1
投票

你的代码一切正常:Snap to Roads没有足够的积分。您应该使用Google Maps Directions API而不是Snap to Roads API来获得缺点:格式化路由请求,接收和解析响应 - 您需要overview_polyline标记points字符串值 - 它是路由部分的encoded polyline对于您的源点(图中的蓝色路径):

List<LatLng> sourcePoints = new ArrayList<>();
sourcePoints.add(new LatLng(39.4321055669415, -0.343169529033198));
sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));

使用Google Maps Directions API实现:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

    private static final String TAG = MainActivity.class.getSimpleName();
    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(39.4321055669415, -0.343169529033198));
        sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
        sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
        sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
        sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
        sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
        sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
        sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));

        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> directionsPoints = new ArrayList<>();
        new GetDirectionPointsAsyncTask().execute(sourcePoints, null, directionsPoints);
    }

    private String buildDirectionsUrl(List<LatLng> trackPoints) {

        if (trackPoints.size() < 2) {
            return null;
        }

        final LatLng origin = trackPoints.get(0);
        final LatLng dest = trackPoints.get(trackPoints.size() - 1);

        StringBuilder url = new StringBuilder();
        url.append("https://maps.googleapis.com/maps/api/directions/json?");
        url.append(String.format("origin=%8.5f,%8.5f", origin.latitude, origin.longitude));
        url.append(String.format("&destination=%8.5f,%8.5f", dest.latitude, dest.longitude));

        // add waypoints, if they exists
        if (trackPoints.size() > 2) {
            url.append("&waypoints=");
            LatLng wayPoint;
            for (int ixWaypoint = 1; ixWaypoint < trackPoints.size() - 2; ixWaypoint++) {
                wayPoint = trackPoints.get(ixWaypoint);
                url.append(String.format("%8.5f,%8.5f|", wayPoint.latitude, wayPoint.longitude));
            }
            url.delete(url.length() - 1, url.length());
        }

        url.append(String.format("&key=%s", getResources().getString(R.string.google_maps_key)));

        return url.toString();
    }


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

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

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

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

            HttpURLConnection connection = null;
            BufferedReader reader = null;

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

                int responseCode = connection.getResponseCode();
                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 jsonRoot = new JSONObject(jsonStringBuilder.toString());
                JSONArray jsonRoutes = jsonRoot.getJSONArray("routes");

                if (jsonRoutes.length() < 1) {
                    return null;
                }

                JSONObject jsonRoute = jsonRoutes.getJSONObject(0);
                JSONObject overviewPolyline = jsonRoute.getJSONObject("overview_polyline");
                String overviewPolylineEncodedPoints = overviewPolyline.getString("points");
                routePoints = decodePoly(overviewPolylineEncodedPoints);

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

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

        }
    }

    //
    // Method to decode polyline points
    // Courtesy : http://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<>();
        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;
    }
}

你会得到类似的东西(图中的红色路径):

Route

NB!不要忘记在Google APIs Console上允许Directions API

有关Direction API here以及许多在线教程/示例的更多详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.