Paul
Paul

Reputation: 21

Android: can not get KML file to parse and then draw route on Map

I write an application that help people find appropriate places and show the direction to the target. Before, this functionality work well but now the draw route function does not work. The exception I got is that application can not download and then parse the kml corresponding to the route (the code: xmlreader.parse(is);), although the URL generated to get KML is correct (I test it in Browser) - for example: https://maps.google.com/maps?f=d&hl=en&saddr=21.04664,105.852203&daddr=21.040527,105.849783&ie=UTF8&om=0&output=kml

I ask my self whether the direction API of Google for MapView does not work properly or I missed some thing.

Here is my code to get the route and then generate URL - get KML and then draw the route.

public void drawPath(GeoPoint from,GeoPoint to, int color, MapView mMapView01) {

        NavigationDataSet navSet= new NavigationDataSet();
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.google.com/maps?f=d&hl=en");
        urlString.append("&saddr=");//from
        urlString.append( Double.toString((double)from.getLatitudeE6()/1.0E6 ));
        urlString.append(",");
        urlString.append( Double.toString((double)from.getLongitudeE6()/1.0E6 ));
        urlString.append("&daddr=");//to
        urlString.append( Double.toString((double)to.getLatitudeE6()/1.0E6 ));
        urlString.append(",");
        urlString.append( Double.toString((double)to.getLongitudeE6()/1.0E6 ));
        urlString.append("&ie=UTF8&0&om=0&output=kml");
       Log.v("TEST", urlString.toString());
        try{
            // setup the url
            URL url = new URL(urlString.toString());
            // get our data via the url class
            InputSource is = new InputSource(url.openConnection().getInputStream());
//          DocumentBuilderFactory dbfAdd = DocumentBuilderFactory.newInstance();
//          DocumentBuilder dbAdd = dbfAdd.newDocumentBuilder();
//            dbAdd.parse(url.toString()); 
            // create the factory
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // create a parser
            SAXParser parser = factory.newSAXParser();
            // create the reader (scanner)
            XMLReader xmlreader = parser.getXMLReader();
            // instantiate our handler
            NavigationSaxHandler navSaxHandler = new NavigationSaxHandler();
            // assign our handler
            xmlreader.setContentHandler(navSaxHandler);
            // perform the synchronous parse           
            xmlreader.parse(is);
            // get the results - should be a fully populated RSSFeed instance, or null on error
            navSet= navSaxHandler.getParsedData();
            Log.v("MAP", "input source: " + (is == null));
            } catch(Exception e) {
//              Log.d("DirectionMap","Exception parsing kml.");
                Log.v("DRAW", "Die here");
                e.printStackTrace();
            }
        try {
            String distance = navSet.getRoutePlacemark().getDistance();
            placeLabelTextView.setText(placeLabel + distance);
        } catch (Exception e) {
            // TODO: handle exception


        }
        //hien thi duong di

        Log.v("MAP",(navSet.getCurrentPlacemark() != null) + "-des: ");
        String path = navSet.getRoutePlacemark().getCoordinates();
        String[] pairs = path.trim().split(" ");
        String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude lngLat[1]=latitude lngLat[2]=height
        try {
            GeoPoint startGP = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
            mMapView01.getOverlays().add(new MyOverLay(startGP, startGP, 1));
            GeoPoint gp1;
            GeoPoint gp2 = startGP;
            int w = (int) (5 * ShowPlaceOnMapsActivity.this.getResources().getDisplayMetrics().density);
            for (int i = 1; i < pairs.length; i++) // the last one would be crash
                {
                lngLat = pairs[i].split(",");
                gp1 = gp2;
                gp2 = new GeoPoint((int) (Double.parseDouble(lngLat[1]) * 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
                mMapView01.getOverlays().add(new MyOverLay(gp1, gp2, 2, color,w));
                }
            mMapView01.getOverlays().add(new MyOverLay(gp2, gp2, 3));

            //hien thi cac chi dan
            List<Overlay> mapOverlays;
            mapOverlays=mMapView01.getOverlays();
            String s=new String();
            String description=new String();
            String name=new String();
            Placemark p=new Placemark();
            Drawable drawable1=mMapView01.getResources().getDrawable(R.drawable.way_turn_mark);     
            MyItemizedOverlay itemizedOverlay1 = new MyItemizedOverlay(drawable1, mMapView01);

            for (Iterator<Placemark> iter=navSet.getPlacemarks().iterator();iter.hasNext();) {
                p = (Placemark)iter.next();
                if(!p.getTitle().equals("Route")){
                    s=p.getCoordinates();
                    description=p.getDescription();
//                  Log.v("TEST", "URL: " + p.getAddress());
                    name=p.getTitle();
                    lngLat =s.split(",");
                    gp2= new GeoPoint((int) (Double.parseDouble(lngLat[1])* 1E6), (int) (Double.parseDouble(lngLat[0]) * 1E6));
                    if(description != null)
                        itemizedOverlay1.addOverlay(new OverlayItem(gp2,name+"\n"+description,""));
                    else 
                        itemizedOverlay1.addOverlay(new OverlayItem(gp2, name, ""));
                    }
                }
            mapOverlays.add(itemizedOverlay1);

            mapController.animateTo(new GeoPoint( (startGP.getLatitudeE6() + gp2.getLatitudeE6())/2, (startGP.getLongitudeE6() + gp2.getLongitudeE6())/2 ));
            } catch (NumberFormatException e) {
            }

     }

The exception I got for the code is at:

xmlreader.parse(is);

org.apache.harmony.xml.ExpatParser$ParseException:....... not well-formed

Have you met this problem? Any help and comment is highly appreciated.

Here is exception stack trace

07-30 22:06:03.510: VERBOSE/TEST(234): http://maps.google.com/maps?f=d&hl=en&saddr=21.059457,105.843963&daddr=21.052597,105.840636&ie=UTF8&0&om=0&output=kml
07-30 22:06:04.190: VERBOSE/DRAW(234): Die here
07-30 22:06:04.190: WARN/System.err(234): org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 805: not well-formed (invalid token)
07-30 22:06:04.210: WARN/System.err(234):     at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:508)
07-30 22:06:04.210: WARN/System.err(234):     at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:467)
07-30 22:06:04.210: WARN/System.err(234):     at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:329)
07-30 22:06:04.210: WARN/System.err(234):     at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:302)
07-30 22:06:04.210: WARN/System.err(234):     at hust.se.vtio.icompanion.ShowPlaceOnMapsActivity.drawPath(ShowPlaceOnMapsActivity.java:301)
07-30 22:06:04.210: WARN/System.err(234):     at hust.se.vtio.icompanion.ShowPlaceOnMapsActivity.onOptionsItemSelected(ShowPlaceOnMapsActivity.java:245)
07-30 22:06:04.210: WARN/System.err(234):     at android.app.Activity.onMenuItemSelected(Activity.java:2170)
07-30 22:06:04.210: WARN/System.err(234):     at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:730)
07-30 22:06:04.210: WARN/System.err(234):     at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:139)
07-30 22:06:04.210: WARN/System.err(234):     at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:855)
07-30 22:06:04.210: WARN/System.err(234):     at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:525)
07-30 22:06:04.220: WARN/System.err(234):     at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:122)
07-30 22:06:04.220: WARN/System.err(234):     at android.view.View.onTouchEvent(View.java:4179)
07-30 22:06:04.220: WARN/System.err(234):     at android.widget.TextView.onTouchEvent(TextView.java:6540)
07-30 22:06:04.220: WARN/System.err(234):     at android.view.View.dispatchTouchEvent(View.java:3709)
07-30 22:06:04.220: WARN/System.err(234):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-30 22:06:04.220: WARN/System.err(234):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
07-30 22:06:04.220: WARN/System.err(234):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
07-30 22:06:04.220: WARN/System.err(234):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
07-30 22:06:04.220: WARN/System.err(234):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-30 22:06:04.220: WARN/System.err(234):     at android.os.Looper.loop(Looper.java:123)
07-30 22:06:04.220: WARN/System.err(234):     at android.app.ActivityThread.main(ActivityThread.java:4363)
07-30 22:06:04.220: WARN/System.err(234):     at java.lang.reflect.Method.invokeNative(Native Method)
07-30 22:06:04.220: WARN/System.err(234):     at java.lang.reflect.Method.invoke(Method.java:521)
07-30 22:06:04.220: WARN/System.err(234):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-30 22:06:04.220: WARN/System.err(234):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-30 22:06:04.220: WARN/System.err(234):     at dalvik.system.NativeStart.main(Native Method)

And here is the content of KML I got when open URL in Browser

Here is the content of KML file I got from Browser:

<kml xmlns="http://earth.google.com/kml/2.2">
<Document>
  <name>Driving directions to 21.052597,105.840636</name>
  <description><![CDATA[]]></description>
  <Style id="style3">
    <IconStyle>
      <Icon>
        <href></href>
      </Icon>
    </IconStyle>
  </Style>
  <Style id="style2">
    <LineStyle>
      <color>73FF0000</color>
      <width>5</width>
    </LineStyle>
  </Style>
  <Style id="style1">
    <IconStyle>
      <Icon>
        <href></href>
      </Icon>
    </IconStyle>
  </Style>
  <Placemark>
    <name>From: 21.059457,105.843963</name>
    <styleUrl>#style3</styleUrl>
    <Point>
      <coordinates>105.842567,21.058840,0.000000</coordinates>
    </Point>
  </Placemark>
  <Placemark>
    <name>Driving directions to 21.052597,105.840636</name>
    <styleUrl>#style2</styleUrl>
    <ExtendedData>
      <Data name="_SnapToRoads">
        <value>true</value>
      </Data>
    </ExtendedData>
    <LineString>
      <tessellate>1</tessellate>
      <coordinates>
        105.842567,21.058840,0.000000
        105.842346,21.059200,0.000000
        105.841080,21.060551,0.000000
        105.840530,21.061300,0.000000
        105.840393,21.061399,0.000000
        105.839653,21.061701,0.000000
        105.839653,21.061701,0.000000
        105.838860,21.061159,0.000000
        105.838860,21.061159,0.000000
        105.838852,21.061050,0.000000
        105.838409,21.060699,0.000000
        105.838409,21.060699,0.000000
        105.838692,21.059879,0.000000
        105.840950,21.055691,0.000000
        105.840950,21.055691,0.000000
        105.840477,21.055571,0.000000
        105.839493,21.054930,0.000000
        105.839493,21.054930,0.000000
        105.839981,21.054060,0.000000
        105.840553,21.052561,0.000000
      </coordinates>
    </LineString>
  </Placemark>
  <Placemark>
    <name>To: 21.052597,105.840636</name>
    <styleUrl>#style1</styleUrl>
    <Point>
      <coordinates>105.840546,21.052563,0.000000</coordinates>
    </Point>
  </Placemark>
</Document>
</kml>

Upvotes: 2

Views: 2686

Answers (1)

Hesham Saeed
Hesham Saeed

Reputation: 5378

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 in my own question here.

Upvotes: 3

Related Questions