Google Maps output=kml broken?
Asked Answered
B

7

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

Brout answered 27/7, 2012 at 2:59 Comment(5)
Same problem with my KML map.. I think we have to switch to XML or JSON..Hauck
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???Defeasance
google just change the setting this day, see developers.google.com/maps/documentation/directions at the end of the page, gosh!Defeasance
Issue 4321 has been opened in the gmaps-api-issues list, may get some official feedback there (star that issue if you are interested).Clio
try this, it works well #11324000Defeasance
B
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/

Brout answered 27/7, 2012 at 18:11 Comment(3)
There was a page where it was clearly documented. Early 2011 is when I saw it last. The page is not available anymore.Brout
Was it on mapki.com ? That was not offical documentation. Just what people had been able to reverse engineer.Rectify
I think Google Places does not support KML (only XML and JSON) anymore too, Google changed their documentation, 1 August. Glad you chose XML.Isobaric
I
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.

Isobaric answered 31/7, 2012 at 17:13 Comment(0)
K
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;
    }
}
}
Kristie answered 28/7, 2012 at 12:7 Comment(4)
ya..it just shows major turns only.. I am looking for some solution.. and alos mailed googel over this.. code.google.com/p/gmaps-api-issues/issues/detail?id=4321Kristie
well..i just edited my code and using json now and its showing path correctly.Kristie
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. PleaseRatib
m so sorry I havent worked on web applications..an working on android with google provided APIs.Kristie
B
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/

Brout answered 27/7, 2012 at 18:11 Comment(3)
There was a page where it was clearly documented. Early 2011 is when I saw it last. The page is not available anymore.Brout
Was it on mapki.com ? That was not offical documentation. Just what people had been able to reverse engineer.Rectify
I think Google Places does not support KML (only XML and JSON) anymore too, Google changed their documentation, 1 August. Glad you chose XML.Isobaric
D
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

Defeasance answered 27/7, 2012 at 10:46 Comment(0)
S
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.

Stripe answered 27/7, 2012 at 9:42 Comment(0)
D
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

Dryly answered 29/8, 2014 at 11:40 Comment(0)
G
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

Gigantes answered 12/2, 2019 at 0:38 Comment(1)
aaaand it is dead again :(Gigantes

© 2022 - 2024 — McMap. All rights reserved.