Android:无法获取KML文件进行解析,然后在Map上绘制路线

时间:2012-07-30 14:33:44

标签: android maps kml draw routes

我编写了一个应用程序,帮助人们找到合适的位置并向目标显示方向。之前,此功能运行良好,但现在绘制路线功能不起作用。我得到的例外是应用程序无法下载然后解析与路由相对应的kml(代码:xmlreader.parse(is); ),尽管为获取KML而生成的URL是正确的(I在浏览器中测试它 - 例如: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

我问自己,Google for MapView的方向API是否无法正常工作,或者我错过了一些东西。

这是我获取路线然后生成URL的代码 - 获取KML然后绘制路线。

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) {
            }

     }

我获得代码的例外是:

xmlreader.parse(是);

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

你遇到过这个问题吗?任何帮助和评论都非常感谢。

这是异常堆栈跟踪

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)

以下是我在浏览器中打开网址时获得的KML内容

以下是我从浏览器获取的KML文件的内容:

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

1 个答案:

答案 0 :(得分:3)

自2012年7月27日以来,这种通过解析KML文件从Google中提取Google方向的方式已不再可用(因为Google已经更改了检索Google方向的结构,现在您只能通过JSON或XML获取它),它是时候将代码迁移到JSON而不是KML。

在我自己的问题here中查看答案。