2012-07-11 116 views
0

我想在路線圖中畫一條線。爲此,我使用這裏的代碼http://csie-tw.blogspot.com/2009/06/android-driving-direction-route-path.html。但它不起作用。它顯示了這種錯誤(((((java.lang.RuntimeException:無法啓動活動ComponentInfo {...............}:android.os.NetworkOnMainThreadException))))。我的清單文件是確定的。有什麼問題?在路線圖中畫一條線

謝謝你的建議。

+0

請檢查我的答案。 – 2012-07-11 09:23:11

回答

1

使用下面的代碼。

MainActivity.java

public class MainActivity extends MapActivity { 
    LinearLayout linearLayout; 
    MapView mapView; 
    private Road mRoad; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     mapView = (MapView) findViewById(R.id.mapview); 
     mapView.setBuiltInZoomControls(true); 

     new Thread() { 
      @Override 
      public void run() { 
       double fromLat = 49.85, fromLon = 24.016667, toLat = 50.45, toLon = 30.523333; 
       String url = RoadProvider 
         .getUrl(fromLat, fromLon, toLat, toLon); 
       InputStream is = getConnection(url); 
       mRoad = RoadProvider.getRoute(is); 
       mHandler.sendEmptyMessage(0); 
      } 
     }.start(); 
    } 

    Handler mHandler = new Handler() { 
     public void handleMessage(android.os.Message msg) { 
      TextView textView = (TextView) findViewById(R.id.description); 
      textView.setText(mRoad.mName + " " + mRoad.mDescription); 
      MapOverlay mapOverlay = new MapOverlay(mRoad, mapView); 
      List<Overlay> listOfOverlays = mapView.getOverlays(); 
      listOfOverlays.clear(); 
      listOfOverlays.add(mapOverlay); 
      mapView.invalidate(); 
     }; 
    }; 

    private InputStream getConnection(String url) { 
     InputStream is = null; 
     try { 
      URLConnection conn = new URL(url).openConnection(); 
      is = conn.getInputStream(); 
     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return is; 
    } 

    @Override 
    protected boolean isRouteDisplayed() { 
     return false; 
    } 
} 

class MapOverlay extends com.google.android.maps.Overlay { 
    Road mRoad; 
    ArrayList<GeoPoint> mPoints; 

    public MapOverlay(Road road, MapView mv) { 
     mRoad = road; 
     if (road.mRoute.length > 0) { 
      mPoints = new ArrayList<GeoPoint>(); 
      for (int i = 0; i < road.mRoute.length; i++) { 
       mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000), 
         (int) (road.mRoute[i][0] * 1000000))); 
      } 
      int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
        mPoints.size() - 1).getLatitudeE6() - mPoints.get(0) 
        .getLatitudeE6())/2); 
      int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
        mPoints.size() - 1).getLongitudeE6() - mPoints.get(0) 
        .getLongitudeE6())/2); 
      GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong); 

      MapController mapController = mv.getController(); 
      mapController.animateTo(moveTo); 
      mapController.setZoom(7); 
     } 
    } 

    @Override 
    public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) { 
     super.draw(canvas, mv, shadow); 
     drawPath(mv, canvas); 
     return true; 
    } 

    public void drawPath(MapView mv, Canvas canvas) { 
     int x1 = -1, y1 = -1, x2 = -1, y2 = -1; 
     Paint paint = new Paint(); 
     paint.setColor(Color.GREEN); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(3); 
     for (int i = 0; i < mPoints.size(); i++) { 
      Point point = new Point(); 
      mv.getProjection().toPixels(mPoints.get(i), point); 
      x2 = point.x; 
      y2 = point.y; 
      if (i > 0) { 
       canvas.drawLine(x1, y1, x2, y2, paint); 
      } 
      x1 = x2; 
      y1 = y2; 
     } 
    } 
} 

添加下列類

Point.java

public class Point { 
    String mName; 
    String mDescription; 
    String mIconUrl; 
    double mLatitude; 
    double mLongitude; 
} 

Road.java

public class Road { 
    public String mName; 
    public String mDescription; 
    public int mColor; 
    public int mWidth; 
    public double[][] mRoute = new double[][] {}; 
    public Point[] mPoints = new Point[] {}; 
} 

RoadProvider.java

public class RoadProvider { 

    public static Road getRoute(InputStream is) { 
     KMLHandler handler = new KMLHandler(); 
     try { 
      SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); 
      parser.parse(is, handler); 
     } catch (ParserConfigurationException e) { 
      e.printStackTrace(); 
     } catch (SAXException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return handler.mRoad; 
    } 

    public static String getUrl(double fromLat, double fromLon, double toLat, 
      double toLon) {// connect to map web service 
     StringBuffer urlString = new StringBuffer(); 
     urlString.append("http://maps.google.com/maps?f=d&hl=en"); 
     urlString.append("&saddr=");// from 
     urlString.append(Double.toString(fromLat)); 
     urlString.append(","); 
     urlString.append(Double.toString(fromLon)); 
     urlString.append("&daddr=");// to 
     urlString.append(Double.toString(toLat)); 
     urlString.append(","); 
     urlString.append(Double.toString(toLon)); 
     urlString.append("&ie=UTF8&0&om=0&output=kml"); 
     return urlString.toString(); 
    } 
} 

class KMLHandler extends DefaultHandler { 
    Road mRoad; 
    boolean isPlacemark; 
    boolean isRoute; 
    boolean isItemIcon; 
    private Stack<String> mCurrentElement = new Stack<String>(); 
    private String mString; 

    public KMLHandler() { 
     mRoad = new Road(); 
    } 

    public void startElement(String uri, String localName, String name, 
      Attributes attributes) throws SAXException { 
     mCurrentElement.push(localName); 
     if (localName.equalsIgnoreCase("Placemark")) { 
      isPlacemark = true; 
      mRoad.mPoints = addPoint(mRoad.mPoints); 
     } else if (localName.equalsIgnoreCase("ItemIcon")) { 
      if (isPlacemark) 
       isItemIcon = true; 
     } 
     mString = new String(); 
    } 

    public void characters(char[] ch, int start, int length) 
      throws SAXException { 
     String chars = new String(ch, start, length).trim(); 
     mString = mString.concat(chars); 
    } 

    public void endElement(String uri, String localName, String name) 
      throws SAXException { 
     if (mString.length() > 0) { 
      if (localName.equalsIgnoreCase("name")) { 
       if (isPlacemark) { 
        isRoute = mString.equalsIgnoreCase("Route"); 
        if (!isRoute) { 
         mRoad.mPoints[mRoad.mPoints.length - 1].mName = mString; 
        } 
       } else { 
        mRoad.mName = mString; 
       } 
      } else if (localName.equalsIgnoreCase("color") && !isPlacemark) { 
       mRoad.mColor = Integer.parseInt(mString, 16); 
      } else if (localName.equalsIgnoreCase("width") && !isPlacemark) { 
       mRoad.mWidth = Integer.parseInt(mString); 
      } else if (localName.equalsIgnoreCase("description")) { 
       if (isPlacemark) { 
        String description = cleanup(mString); 
        if (!isRoute) 
         mRoad.mPoints[mRoad.mPoints.length - 1].mDescription = description; 
        else 
         mRoad.mDescription = description; 
       } 
      } else if (localName.equalsIgnoreCase("href")) { 
       if (isItemIcon) { 
        mRoad.mPoints[mRoad.mPoints.length - 1].mIconUrl = mString; 
       } 
      } else if (localName.equalsIgnoreCase("coordinates")) { 
       if (isPlacemark) { 
        if (!isRoute) { 
         String[] xyParsed = split(mString, ","); 
         double lon = Double.parseDouble(xyParsed[0]); 
         double lat = Double.parseDouble(xyParsed[1]); 
         mRoad.mPoints[mRoad.mPoints.length - 1].mLatitude = lat; 
         mRoad.mPoints[mRoad.mPoints.length - 1].mLongitude = lon; 
        } else { 
         String[] coodrinatesParsed = split(mString, " "); 
         int lenNew = coodrinatesParsed.length; 
         int lenOld = mRoad.mRoute.length; 
         double[][] temp = new double[lenOld + lenNew][2]; 
         for (int i = 0; i < lenOld; i++) { 
          temp[i] = mRoad.mRoute[i]; 
         } 
         for (int i = 0; i < lenNew; i++) { 
          String[] xyParsed = split(coodrinatesParsed[i], ","); 
          for (int j = 0; j < 2 && j < xyParsed.length; j++) 
           temp[lenOld + i][j] = Double 
             .parseDouble(xyParsed[j]); 
         } 
         mRoad.mRoute = temp; 
        } 
       } 
      } 
     } 
     mCurrentElement.pop(); 
     if (localName.equalsIgnoreCase("Placemark")) { 
      isPlacemark = false; 
      if (isRoute) 
       isRoute = false; 
     } else if (localName.equalsIgnoreCase("ItemIcon")) { 
      if (isItemIcon) 
       isItemIcon = false; 
     } 
    } 

    private String cleanup(String value) { 
     String remove = "<br/>"; 
     int index = value.indexOf(remove); 
     if (index != -1) 
      value = value.substring(0, index); 
     remove = "&#160;"; 
     index = value.indexOf(remove); 
     int len = remove.length(); 
     while (index != -1) { 
      value = value.substring(0, index).concat(
        value.substring(index + len, value.length())); 
      index = value.indexOf(remove); 
     } 
     return value; 
    } 

    public Point[] addPoint(Point[] points) { 
     Point[] result = new Point[points.length + 1]; 
     for (int i = 0; i < points.length; i++) 
      result[i] = points[i]; 
     result[points.length] = new Point(); 
     return result; 
    } 

    private static String[] split(String strString, String strDelimiter) { 
     String[] strArray; 
     int iOccurrences = 0; 
     int iIndexOfInnerString = 0; 
     int iIndexOfDelimiter = 0; 
     int iCounter = 0; 
     if (strString == null) { 
      throw new IllegalArgumentException("Input string cannot be null."); 
     } 
     if (strDelimiter.length() <= 0 || strDelimiter == null) { 
      throw new IllegalArgumentException(
        "Delimeter cannot be null or empty."); 
     } 
     if (strString.startsWith(strDelimiter)) { 
      strString = strString.substring(strDelimiter.length()); 
     } 
     if (!strString.endsWith(strDelimiter)) { 
      strString += strDelimiter; 
     } 
     while ((iIndexOfDelimiter = strString.indexOf(strDelimiter, 
       iIndexOfInnerString)) != -1) { 
      iOccurrences += 1; 
      iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length(); 
     } 
     strArray = new String[iOccurrences]; 
     iIndexOfInnerString = 0; 
     iIndexOfDelimiter = 0; 
     while ((iIndexOfDelimiter = strString.indexOf(strDelimiter, 
       iIndexOfInnerString)) != -1) { 
      strArray[iCounter] = strString.substring(iIndexOfInnerString, 
        iIndexOfDelimiter); 
      iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length(); 
      iCounter += 1; 
     } 

     return strArray; 
    } 
} 

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <TextView 
     android:id="@+id/description" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" /> 

    <com.google.android.maps.MapView 
     android:id="@+id/mapview" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:apiKey="Your API Key" 
     android:clickable="true" /> 

</LinearLayout> 

添加以下權限到你的Android清單文件。

<uses-permission android:name="android.permission.INTERNET"/>