16

All

I was using the google maps KML output in my iPhone app. If I type the following on my browser, it used to give an option to save the kml file:

http://maps.google.com/maps?q=restaurant&mrt=yp&num=10&sll=37.786945,-122.406013&radius=5&output=kml

But all of a sudden today, it is returning an html file. What happened? any ideas? I use it in my iPhone app and it is throwing error as it is not a valid xml returned. Obviously....

Thanks, mbh

Saravanan
  • 363
  • 1
  • 14
mbh
  • 3,302
  • 2
  • 22
  • 24
  • Same problem with my KML map.. I think we have to switch to XML or JSON.. – thatguy Jul 27 '12 at 09:02
  • oh my god, its my final test in college, and now kml not working, the deadline is one week!! :(( how i'm suppose to do??? – sephtian Jul 27 '12 at 10:48
  • 2
    google just change the setting this day, see https://developers.google.com/maps/documentation/directions/ at the end of the page, gosh! – sephtian Jul 27 '12 at 11:43
  • [Issue 4321](http://code.google.com/p/gmaps-api-issues/issues/detail?id=4321) has been opened in the gmaps-api-issues list, may get some official feedback there (star that issue if you are interested). – geocodezip Jul 29 '12 at 14:35
  • try this, it works well http://stackoverflow.com/questions/11323500/google-maps-api-version-difference/11357351#11357351 – sephtian Aug 01 '12 at 08:08

7 Answers7

8

This way of extracting the Google Directions from Google by parsing the KML file is no longer available since 27 July 2012 (because Google has changed the structure of retrieving Google Directions, now you can only get it by JSON or XML), it is time to migrate your code to JSON instead of KML.

See the answer (for Android only but maybe for iPhone can understand the algorithm and apply it) in my own question here.

Community
  • 1
  • 1
Hesham Saeed
  • 5,358
  • 7
  • 37
  • 57
7

Google changed something and now shows major turns only. But when using JSON, it's showing the path correctly:

public class DrivingDirectionActivity extends MapActivity {

Point p1 = new Point();
Point p2 = new Point();

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    MapView mapView = (MapView) findViewById(R.id.map);
    // setting a default value
    double src_lat = 18.5535;
    double src_long = 73.7966;
    double dest_lat = 18.5535;
    double dest_long = 73.7966;

    Geocoder coder = new Geocoder(getApplicationContext(),
            Locale.getDefault());

    List<Address> address_src = null;
    List<Address> address_dest = null;

    try {
        address_src = coder
                .getFromLocationName(
                        "Deepmala Housing Complex, Pimple Saudagar, Pimpri Chinchwad",
                        1);
        if (address_src.size() > 0) {
            Address loc = address_src.get(0);
            src_lat = loc.getLatitude();
            src_long = loc.getLongitude();
        }
    } catch (IOException e) { // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try {
        address_dest = coder.getFromLocationName(
                "Infosys Phase 2, Hinjewadi Phase II, Hinjewadi", 1);
        if (address_dest.size() > 0) {
            Address loc = address_dest.get(0);
            dest_lat = loc.getLatitude();
            dest_long = loc.getLongitude();
        }
    } catch (IOException e) { // TODO Auto-generated catch block
        e.printStackTrace();
    }

    mapView.setBuiltInZoomControls(true);
    GeoPoint srcGeoPoint = new GeoPoint((int) (src_lat * 1E6),
            (int) (src_long * 1E6));
    GeoPoint destGeoPoint = new GeoPoint((int) (dest_lat * 1E6),
            (int) (dest_long * 1E6));

    DrawPath(srcGeoPoint, destGeoPoint, Color.GREEN, mapView);

    mapView.getController().animateTo(srcGeoPoint);
    mapView.getController().setZoom(13);

}

protected boolean isRouteDisplayed() {
    // TODO Auto-generated method stub
    return false;
}

private void DrawPath(GeoPoint src, GeoPoint dest, int color,
        MapView mMapView) {
    // connect to map web service
    HttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost(makeUrl(src, dest));
    HttpResponse response;
    try {
        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);
        mMapView.getOverlays().add(new MyOverLay(pointToDraw));
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
        // TODO: handle exception
    }

}

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

private String makeUrl(GeoPoint src, GeoPoint dest) {
    // TODO Auto-generated method stub

    StringBuilder urlString = new StringBuilder();

    urlString.append("http://maps.googleapis.com/maps/api/directions/json");
    urlString.append("?origin=");// from
    urlString.append(Double.toString((double) src.getLatitudeE6() / 1.0E6));
    urlString.append(",");
    urlString
            .append(Double.toString((double) src.getLongitudeE6() / 1.0E6));
    urlString.append("&destination=");// to
    urlString
            .append(Double.toString((double) dest.getLatitudeE6() / 1.0E6));
    urlString.append(",");
    urlString
            .append(Double.toString((double) dest.getLongitudeE6() / 1.0E6));
    urlString.append("&sensor=false");

    Log.d("xxx", "URL=" + urlString.toString());
    return urlString.toString();
}

class MyOverLay extends Overlay {
    private int pathColor;
    private final List<GeoPoint> points;
    private boolean drawStartEnd;

    public MyOverLay(List<GeoPoint> pointToDraw) {
        // TODO Auto-generated constructor stub
        this(pointToDraw, Color.GREEN, true);
    }

    public MyOverLay(List<GeoPoint> points, int pathColor,
            boolean drawStartEnd) {
        this.points = points;
        this.pathColor = pathColor;
        this.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);
        ovalPaint.setColor(Color.BLUE);
        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;
    }
}
}
Arjan
  • 22,808
  • 11
  • 61
  • 71
Pankaj Kushwaha
  • 300
  • 1
  • 13
  • ya..it just shows major turns only.. I am looking for some solution.. and alos mailed googel over this.. http://code.google.com/p/gmaps-api-issues/issues/detail?id=4321 – Pankaj Kushwaha Aug 02 '12 at 07:31
  • well..i just edited my code and using json now and its showing path correctly. – Pankaj Kushwaha Aug 06 '12 at 09:11
  • What is an GeoPoint? I got `GeoPoint cannot be resolved to a type` . My project is not android. Java Google map web application. Please help me out.Previously it was workiing with kml. When I converted to JSON only i face same issue. Please – Piraba Aug 17 '12 at 05:24
  • m so sorry I havent worked on web applications..an working on android with google provided APIs. – Pankaj Kushwaha Aug 17 '12 at 08:29
3

I wish Google had not stopped supporting their documented KML without notice.

I migrated my code to google places API now using their xml output.

https://developers.google.com/places/documentation/

mbh
  • 3,302
  • 2
  • 22
  • 24
  • There was a page where it was clearly documented. Early 2011 is when I saw it last. The page is not available anymore. – mbh Jul 27 '12 at 23:23
  • Was it on mapki.com ? That was not offical documentation. Just what people had been able to reverse engineer. – barryhunter Jul 28 '12 at 14:35
  • I think Google Places does not support KML (only XML and JSON) anymore too, Google changed their documentation, 1 August. Glad you chose XML. – Hesham Saeed Aug 02 '12 at 18:28
1

-well i just edited my answer-

lets face it, google has change their sistem, we have to follow them

so lets use JSON or XML

:)

--edited part two--

i just found the best solution, it use JSON and parse into polyline, so we can do it!

Google Maps API Version difference

Community
  • 1
  • 1
sephtian
  • 445
  • 2
  • 11
  • 23
0

As for Android now I am using:

Intent myIntent = 
new Intent( android.content.Intent.ACTION_VIEW,
 Uri.parse( "geo:0,0?q="+ lat +","+ lon ) );                
startActivity(myIntent);

I think there should be something like that in iOS.

Wesley
  • 4,084
  • 6
  • 37
  • 60
Cheb
  • 116
  • 5
0

I found the way to get KML outputs as before using standard google maps links for routes.

It seems that google analyze the referrer for such links and if it is https://code.google.com then it will generate KML attachment instead of showing the map.

So, at first, you need to make a project at https://code.google.com. Then make an issue with you route link in a comment.

Now you can tap the link and get KML attachment.

enter image description here

malex
  • 9,874
  • 3
  • 56
  • 77
0

KML creation lives again!

The dead link simply needs to be modified to point to earth instead of maps

Dead Link:

http://maps.google.com/maps?q=restaurant&mrt=yp&num=10&sll=37.786945,-122.406013&radius=5&output=kml

Working Link:

https://earth.google.com/earth/rpc/search?q=restaurant&mrt=yp&num=10&sll=37.786945,-122.406013&radius=5&output=kml

Casey
  • 6,531
  • 24
  • 43