Google Maps API Version difference

2020-01-26 03:41发布

问题:

I'm trying to show route between two places, I want to used Google Places API V3 for route steps between two points.


Before I was using Old Google Maps API, and following request gives perfect result:

http://maps.google.com/maps?f=d&hl=en&saddr=19.5217608,-99.2615823&daddr=19.531224,-99.248262&ie=UTF8&0&om=0&output=kml

Output :


Now I try to replace this with New Google Maps API, and following request gives wrong result, In both case i'm using same source and destination, but result gives different behavior on Google Map:

http://maps.googleapis.com/maps/api/directions/json?origin=19.5217608,-99.2615823&destination=19.531224,-99.248262&sensor=false

My problem is that, New Google Maps API return less number of steps between source and destination therefore the route not showing perfect on Google Map.

Please help to resolve this problem for New Google Maps API v3.

Thanks in advance.

回答1:

What's new in Google Map API v3?
Google Maps Directions API v3 for Android provide routes in the Encoded Polyline Algorithm Format.

What we must have to do?
We must have to decode this Polyline for showing exact Map

How we decode this encoded Polyline provided by Google Directions API v3?
Please Refer these three links to more clear with encoded Polyline returns from the Google Maps Directions API v3

  • Decoding polylines from google maps direction api with java
  • Encoding polylines for Google Maps
  • The encoding algorithm for the levels string

How we can resolve problem in above question?
Please refer these three answer links, that solves your problem :

  • Android - Draw route map between two geopoints
  • https://stackoverflow.com/a/10268114/1472665
  • https://stackoverflow.com/a/11357351/1494309


回答2:

I've taken your request URL and pasted it in my app, which is using the newer version, and it works great. The problem may be how you parse the data, or decode the received JSON string.

String url = "http://maps.googleapis.com/maps/api/directions/json?origin=19.5217608,-99.2615823&destination=19.531224,-99.248262&sensor=false";

HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
InputStream is = null;
is = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
    sb.append(line + "\n");
}
is.close();
reader.close();
String result = sb.toString();
JSONObject jsonObject = new JSONObject(result);
JSONArray routeArray = jsonObject.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
List<GeoPoint> pointToDraw = decodePoly(encodedString);

//Added line:
mapView.getOverlays().add(new RoutePathOverlay(pointToDraw));

and the decodePoly() method is taken from another question here in SO, which I don't remember the author:

private List<GeoPoint> decodePoly(String encoded) {

    List<GeoPoint> poly = new ArrayList<GeoPoint>();
    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;

        GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));
        poly.add(p);
    }

    return poly;
}

I'm including what I've used in order to add the overlay to the map itself as well, I can't find the tutorial it's taken from.. sorry for not giving credit. (added the call to this in the first method I posted)

public class RoutePathOverlay extends Overlay {

    private int _pathColor;
    private final List<GeoPoint> _points;
    private boolean _drawStartEnd;

    public RoutePathOverlay(List<GeoPoint> points) {
            this(points, Color.RED, true);
    }

    public RoutePathOverlay(List<GeoPoint> points, int pathColor, boolean drawStartEnd) {
            _points = points;
            _pathColor = pathColor;
            _drawStartEnd = drawStartEnd;
    }


    private void drawOval(Canvas canvas, Paint paint, Point point) {
            Paint ovalPaint = new Paint(paint);
            ovalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
            ovalPaint.setStrokeWidth(2);
            int _radius = 6;
            RectF oval = new RectF(point.x - _radius, point.y - _radius, point.x + _radius, point.y + _radius);
            canvas.drawOval(oval, ovalPaint);               
    }

    public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
            Projection projection = mapView.getProjection();
            if (shadow == false && _points != null) {
                    Point startPoint = null, endPoint = null;
                    Path path = new Path();
                    //We are creating the path
                    for (int i = 0; i < _points.size(); i++) {
                            GeoPoint gPointA = _points.get(i);
                            Point pointA = new Point();
                            projection.toPixels(gPointA, pointA);
                            if (i == 0) { //This is the start point
                                    startPoint = pointA;
                                    path.moveTo(pointA.x, pointA.y);
                            } else {
                                    if (i == _points.size() - 1)//This is the end point
                                            endPoint = pointA;
                                    path.lineTo(pointA.x, pointA.y);
                            }
                    }

                    Paint paint = new Paint();
                    paint.setAntiAlias(true);
                    paint.setColor(_pathColor);
                    paint.setStyle(Paint.Style.STROKE);
                    paint.setStrokeWidth(5);
                    paint.setAlpha(90);
                    if (getDrawStartEnd()) {
                            if (startPoint != null) {
                                    drawOval(canvas, paint, startPoint);
                            }
                            if (endPoint != null) {
                                    drawOval(canvas, paint, endPoint);
                            }
                    }
                    if (!path.isEmpty())
                            canvas.drawPath(path, paint);
            }
            return super.draw(canvas, mapView, shadow, when);
    }

    public boolean getDrawStartEnd() {
            return _drawStartEnd;
    }

    public void setDrawStartEnd(boolean markStartEnd) {
            _drawStartEnd = markStartEnd;
    }
}

Hope this works for you.



回答3:

You are not using all the points returned in the result. You haven't provided your code, but here is an example with the v3 API that shows the same path as that returned by your "google maps" example.



回答4:

Please check this link..

And Specify Travel Modes

-- driving
-- walking 
-- bicycling 
-- transit 

so you get different results.

please try it.



回答5:

With regards to GeoPoint being unresolved, I just changed all the occurances of GeoPoint to LatLng and everything worked.



回答6:

The solution above posted by https://stackoverflow.com/users/975959/la-bla-bla works very well with Google Maps API V2 but it needs some minor modifications:
Replace all the occurrences of GeoPoint with LatLng.
Replace the line:

GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6), (int) (((double) lng / 1E5) * 1E6));

Which is located just before the end of the method decodePoly, with this line:

LatLng p = new LatLng(lat / 1E5, lng / 1E5);

Hope this works for Google Maps API v2 users.



回答7:

I used the solution given by "La bla bla", but I made some little modifications. I was having an issue displaying the path when i had too many points, when you Zoom in too much, the route is not displayed anymore, and you get this message in logcat "shape path too large to be rendered into a texture".

What I did was to subdivide the path in the following way:

if (shadow == false && _points != null) {
        Path path = new Path();;
        //We are creating the path
        Point pointA = new Point();
        for (int i = 0; i < _points.size(); i++) {
            mapView.getProjection().toPixels(_points.get(i), pointA);
            if (i == 0) path.moveTo(pointA.x, pointA.y);                
            else path.lineTo(pointA.x, pointA.y);

            if(i%10==0 || i == _points.size()-1){
                Paint paint = new Paint();
                paint.setAntiAlias(true);
                paint.setColor(_pathColor);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeJoin(Paint.Join.ROUND);
                paint.setStrokeCap(Paint.Cap.ROUND);
                paint.setStrokeWidth(mapView.getZoomLevel()-10);
                paint.setAlpha(200);
                if (!path.isEmpty()) canvas.drawPath(path, paint);
                path = new Path();
                path.moveTo(pointA.x, pointA.y);
            }
        }
    }

I make paths every 10 points, it can be less efficient, but this way you can display the path when the zoom is in high values.



回答8:

@Ghareeb-Strange- But why would we need that with API v2? I mean, we have polyline that makes it way more easier.

private void drawPath(){
        PolylineOptions options = new PolylineOptions();
        options.width(4);
        options.color(Color.RED);
        for(int i = 0; i< pathList.size(); i++ ){
            options.add(pathList.get(i));
        }
        map.addPolyline(options);
    }

With something like the code posted above you would have the path perfectly drawed in your app.

pathList is a List containing all the points of our path.

Cheers!



回答9:

It seems there are enough answers but for this subject, i benefit this link. But it didn't work when i downloaded and imported. So i implemented on my own application. And there is a mistake in that code. When you want to second time calculate a route, the app. breaks.

    if (mMarkerPoints.size() > 1) {

                mMarkerPoints.clear();
                map.clear();
                // LatLng startPoint = new LatLng(nearbyLatitude,
                // nearbyLongitude);
                // drawMarker(startPoint);
            }

Find that lines and make comment as i have done. Anyway, actually you asked to draw a route not whole code, so you can check code on that web-site. It is good at to draw route between to points (markers). Have a good day.