2012-12-17 34 views
9

私は現在のユーザーの位置と興味のあるポイントとの間の経路を知る必要があるアプリケーションを開発しています。Google Maps Android V2とDirection API

私はアンドロイド2.3.3、Googleマップアンドロイドv2と方向APIを使用しています。 私の問題は、私が見つけたすべてのコードが古いバージョンのマップ用であることです。また、コードを修正しようとしましたが、失敗しました。 LatLngでGeoPoint(この新しいバージョンではサポートされていない)を変更しようとしています。 問題は、パスを表示できないため、新しいポリラインを作成してマップに追加することです。

パーサ:

public interface Parser { 
    public Route parse(); 
} 

のXMLParser

public class XMLParser { 
    // names of the XML tags 
    protected static final String MARKERS = "markers"; 
    protected static final String MARKER = "marker"; 

    protected URL feedUrl; 

    protected XMLParser(final String feedUrl) { 
      try { 
        this.feedUrl = new URL(feedUrl); 
      } catch (MalformedURLException e) { 
        Log.e(e.getMessage(), "XML parser - " + feedUrl); 
      } 
    } 

    protected InputStream getInputStream() { 
      try { 
        return feedUrl.openConnection().getInputStream(); 
      } catch (IOException e) { 
        Log.e(e.getMessage(), "XML parser - " + feedUrl); 
        return null; 
      } 
    } 
} 

JsonParser(グーグル方向JSONをパース)

public class JsonParser extends XMLParser implements Parser { 
    /** Distance covered. **/ 
    private int distance; 

    public JsonParser(String feedUrl) { 
     super(feedUrl); 
    } 

    /** 
    * Parses a url pointing to a Google JSON object to a Route object. 
    * @return a Route object based on the JSON object. 
    */ 

    public Route parse() { 
     // turn the stream into a string 
     final String result = convertStreamToString(this.getInputStream()); 
     //Create an empty route 
     final Route route = new Route(); 
     //Create an empty segment 
     final Segment segment = new Segment(); 
     try { 
      //Tranform the string into a json object 
      final JSONObject json = new JSONObject(result); 
      //Get the route object 
      final JSONObject jsonRoute = json.getJSONArray("routes").getJSONObject(0); 
      //Get the leg, only one leg as we don't support waypoints 
      final JSONObject leg = jsonRoute.getJSONArray("legs").getJSONObject(0); 
      //Get the steps for this leg 
      final JSONArray steps = leg.getJSONArray("steps"); 
      //Number of steps for use in for loop 
      final int numSteps = steps.length(); 
      //Set the name of this route using the start & end addresses 
      route.setName(leg.getString("start_address") + " to " + leg.getString("end_address")); 
      //Get google's copyright notice (tos requirement) 
      route.setCopyright(jsonRoute.getString("copyrights")); 
      //Get the total length of the route. 
      route.setLength(leg.getJSONObject("distance").getInt("value")); 
      //Get any warnings provided (tos requirement) 
      if (!jsonRoute.getJSONArray("warnings").isNull(0)) { 
       route.setWarning(jsonRoute.getJSONArray("warnings").getString(0)); 
      } 
      /* Loop through the steps, creating a segment for each one and 
      * decoding any polylines found as we go to add to the route object's 
      * map array. Using an explicit for loop because it is faster! 
      */ 
      for (int i = 0; i < numSteps; i++) { 
       //Get the individual step 
       final JSONObject step = steps.getJSONObject(i); 
       //Get the start position for this step and set it on the segment 
       final JSONObject start = step.getJSONObject("start_location"); 
       final LatLng position = new LatLng(start.getDouble("lat"), start.getDouble("lng")); 
       segment.setPoint(position); 
       //Set the length of this segment in metres 
       final int length = step.getJSONObject("distance").getInt("value"); 
       distance += length; 
       segment.setLength(length); 
       segment.setDistance(distance/1000); 
       //Strip html from google directions and set as turn instruction 
       segment.setInstruction(step.getString("html_instructions").replaceAll("<(.*?)*>", "")); 
       //Retrieve & decode this segment's polyline and add it to the route. 
       route.addPoints(decodePolyLine(step.getJSONObject("polyline").getString("points"))); 
       //Push a copy of the segment to the route 
       route.addSegment(segment.copy()); 
      } 
     } catch (JSONException e) { 
      Log.e(e.getMessage(), "Google JSON Parser - " + feedUrl); 
     } 
     return route; 
    } 

    /** 
    * Convert an inputstream to a string. 
    * @param input inputstream to convert. 
    * @return a String of the inputstream. 
    */ 

    private static String convertStreamToString(final InputStream input) { 
     final BufferedReader reader = new BufferedReader(new InputStreamReader(input)); 
     final StringBuilder sBuf = new StringBuilder(); 

     String line = null; 
     try { 
      while ((line = reader.readLine()) != null) { 
       sBuf.append(line); 
      } 
     } catch (IOException e) { 
      Log.e(e.getMessage(), "Google parser, stream2string"); 
     } finally { 
      try { 
       input.close(); 
      } catch (IOException e) { 
       Log.e(e.getMessage(), "Google parser, stream2string"); 
      } 
     } 
     return sBuf.toString(); 
    } 

    /** 
    * Decode a polyline string into a list of LatLng. 
    * @param poly polyline encoded string to decode. 
    * @return the list of GeoPoints represented by this polystring. 
    */ 

    private List<LatLng> decodePolyLine(final String poly) { 
     int len = poly.length(); 
     int index = 0; 
     List<LatLng> decoded = new LinkedList<LatLng>(); 
     int lat = 0; 
     int lng = 0; 

     while (index < len) { 
      int b; 
      int shift = 0; 
      int result = 0; 
      do { 
       b = poly.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 = poly.charAt(index++) - 63; 
       result |= (b & 0x1f) << shift; 
       shift += 5; 
      } while (b >= 0x20); 
      int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); 
      lng += dlng; 

      decoded.add(new LatLng((lat/1E5),(lng/1E5))); 
     } 

     return decoded; 
    } 
} 

ルート(JSONを保存する

は、私は私のコードを投稿します情報)

public class Route { 
    private String name; 
    private final List<LatLng> points; 
    private List<Segment> segments; 
    private String copyright; 
    private String warning; 
    private String country; 
    private int length; 
    private String polyline; 

    public Route() { 
     points = new LinkedList<LatLng>(); 
     segments = new LinkedList<Segment>(); 
    } 

    public void addPoint(final LatLng p) { 
     points.add(p); 
    } 

    public void addPoints(final List<LatLng> points) { 
     this.points.addAll(points); 
    } 

    public List<LatLng> getPoints() { 
     return points; 
    } 

    public void addSegment(final Segment s) { 
     segments.add(s); 
    } 

    public List<Segment> getSegments() { 
     return segments; 
    } 

    /** 
    * @param name the name to set 
    */ 
    public void setName(final String name) { 
     this.name = name; 
    } 

    /** 
    * @return the name 
    */ 
    public String getName() { 
     return name; 
    } 

    /** 
     * @param copyright the copyright to set 
     */ 
    public void setCopyright(String copyright) { 
     this.copyright = copyright; 
    } 

    /** 
     * @return the copyright 
     */ 
    public String getCopyright() { 
     return copyright; 
    } 

    /** 
     * @param warning the warning to set 
     */ 
    public void setWarning(String warning) { 
     this.warning = warning; 
    } 

    /** 
     * @return the warning 
     */ 
    public String getWarning() { 
     return warning; 
    } 

    /** 
     * @param country the country to set 
     */ 
    public void setCountry(String country) { 
     this.country = country; 
    } 

    /** 
     * @return the country 
     */ 
    public String getCountry() { 
     return country; 
    } 

    /** 
     * @param length the length to set 
     */ 
    public void setLength(int length) { 
     this.length = length; 
    } 

    /** 
     * @return the length 
     */ 
    public int getLength() { 
     return length; 
    } 


    /** 
     * @param polyline the polyline to set 
     */ 
    public void setPolyline(String polyline) { 
     this.polyline = polyline; 
    } 

    /** 
     * @return the polyline 
     */ 
    public String getPolyline() { 
     return polyline; 
    } 

} 

セグメント:

public class Segment { 
    /** Points in this segment. **/ 
    private LatLng start; 
    /** Turn instruction to reach next segment. **/ 
    private String instruction; 
    /** Length of segment. **/ 
    private int length; 
    /** Distance covered. **/ 
    private double distance; 

    /** 
    * Create an empty segment. 
    */ 

    public Segment() { 
    } 


    /** 
    * Set the turn instruction. 
    * @param turn Turn instruction string. 
    */ 

    public void setInstruction(final String turn) { 
      this.instruction = turn; 
    } 

    /** 
    * Get the turn instruction to reach next segment. 
    * @return a String of the turn instruction. 
    */ 

    public String getInstruction() { 
      return instruction; 
    } 

    /** 
    * Add a point to this segment. 
    * @param point LatLng to add. 
    */ 

    public void setPoint(LatLng point) { 
      start = point; 
    } 

    /** Get the starting point of this 
    * segment. 
    * @return a LatLng 
    */ 

    public LatLng startPoint() { 
      return start; 
    } 

    /** Creates a segment which is a copy of this one. 
    * @return a Segment that is a copy of this one. 
    */ 

    public Segment copy() { 
      final Segment copy = new Segment(); 
      copy.start = start; 
      copy.instruction = instruction; 
      copy.length = length; 
      copy.distance = distance; 
      return copy; 
    } 

    /** 
    * @param length the length to set 
    */ 
    public void setLength(final int length) { 
      this.length = length; 
    } 

    /** 
    * @return the length 
    */ 
    public int getLength() { 
      return length; 
    } 

    /** 
    * @param distance the distance to set 
    */ 
    public void setDistance(double distance) { 
      this.distance = distance; 
    } 

    /** 
    * @return the distance 
    */ 
    public double getDistance() { 
      return distance; 
    } 

} 

マイMainActivity(326コードの行があるため、ユーザーのローカライズであり、あなたがGoogleの開発者向けサイトでそれを見つけることができますので、我々はちょうど2つの静的点Aを持っていると仮定することができますし、 BおよびI)は、AからBに行きたい:

public class MainActivity extends FragmentActivity{ 
    private GoogleMap map; 
    private Marker currentLocation; 
    private PolylineOptions pathLine; 
    private LatLng imhere = new LatLng(41.8549038,12.4618208); 
     private LatLng poi = new LatLng(41.89000,12.49324); 


    private LocationManager mLocationManager; 
    private Handler mHandler; 
    private boolean mUseBoth; 
    private Context context; 
    // Keys for maintaining UI states after rotation. 
    private static final String KEY_BOTH = "use_both"; 
    // UI handler codes. 
    private static final int UPDATE_LATLNG = 2; 

    private static final int FIVE_SECONDS = 5000; 
    private static final int THREE_METERS = 3; 
    private static final int TWO_MINUTES = 1000 * 60 * 2; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 
     Marker colosseoMarker = map.addMarker(new MarkerOptions() 
     .position(colosseo) 
     .title("Start") 
     .snippet("poi") 
     .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))); 

       Marker current pos = map.addMarker(new MarkerOptions() 
     .position(imhere) 
     .title("i'm here") 
     .snippet("here!") 
     .icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_launcher))); 

     context =this ; 
     map.setOnMarkerClickListener(new OnMarkerClickListener() { 

      @Override 
      public boolean onMarkerClick(Marker marker) { 
       final String[] options = {"Calcola il Percorso"}; 
       AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 
       builder.setTitle("Ottieni Informazioni aggiuntive"); 
       builder.setPositiveButton("Calcola Percorso",new DialogInterface.OnClickListener() { 
        public void onClick(DialogInterface dialog,int id) { 
         LatLng start = new LatLng(imhere.latitude,imhere.longitude); 
         LatLng dest = new LatLng(poi.latitude, poi.longitude); 
         Route route = drawPath(start, dest); 

         List<LatLng> list= route.getPoints(); 

if(pathLine!= null) pathline =null;       
pathLine = new PolylineOptions(); 

         pathLine.addAll(list); 
         pathLine.color(Color.rgb(0,191,255)); 

         map.addPolyline(pathLine); 

        } 
        }); 

       AlertDialog alert = builder.create(); 
       alert.show(); 
       Toast.makeText(MainActivity.this, marker.getSnippet(),Toast.LENGTH_SHORT).show(); 
       return true; 
      } 
     }); 


        map.animateCamera(CameraUpdateFactory.newLatLngZoom(imhere, 12)); 
       } 
      } 
     }; 
     // Get a reference to the LocationManager object. 
     mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 
    } 


    private Route drawPath(LatLng start, LatLng dest) { 
      Parser parser; 
      String jsonURL = "http://maps.google.com/maps/api/directions/json?"; 
      final StringBuffer sBuf = new StringBuffer(jsonURL); 
      sBuf.append("origin="); 
      sBuf.append(start.latitude); 
      sBuf.append(','); 
      sBuf.append(start.longitude); 
      sBuf.append("&destination="); 
      sBuf.append(dest.latitude); 
      sBuf.append(','); 
      sBuf.append(dest.longitude); 
      sBuf.append("&sensor=true&mode=walking"); 
      parser = new JsonParser(sBuf.toString()); 
      Route r = parser.parse(); 
      return r; 
     } 
} 

すべての提案がうまく受け入れられている

+0

はJsonParserでIはdecoded.add変更次のように

Marker interestedMarker; private void plot_direction(){ if (currentSelectedPin !=null) { LatLng origin = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude()); new GoogleMapDirection(getActivity(), origin, interestedMarker.getPosition(), new DirectionListener() { @Override public void onDirectionPointsReceived(ArrayList<RouteModel> routeList, String distance, String duration) { PolylineOptions lineOptions = null; for (RouteModel route : routeList) { lineOptions = new PolylineOptions(); lineOptions.addAll(route.getSteps()); lineOptions.width(20); lineOptions.color(ContextCompat.getColor(getContext(), R.color.map_route)); } //For removing existing line if (routeMap!=null){ routeMap.remove(); } if(lineOptions != null) { routeMap = mMap.addPolyline(lineOptions); } } }); } } 

GoogleMapDirectionクラスがある(新しい緯度経度((LAT * 1E6/1E5)、(LNG * 1E6/1E5)))。デコードされた.add(new LatLng((lat/1E5)、(lng/1E5)));ダブル(私は思う...)とそれは仕事だが、時にはアプリケーションがパスを再描画するように頼んだら、動作を停止する – antedesk

+2

'Activity'にはいくつかの問題があります。 'drawPath'を使ったJSON呼び出しは' AsyncTask'で行わなければなりません。 'map'を操作する前に、使用準備が整っていることを確認してください。' setUpMapIfNeeded'が 'onResume()'で実行されるようにSDKのサンプルコードを見てください。 'map.clear()'は再描画の前に地図をクリアします。 – qubz

+0

はい、ありがとう、私は 'AsyncTask'を使用し、今それは良いです。今私は() ' – antedesk

答えて

-1

私は以下のようにしています。私はこれがあなたを助けると思う。

public class GoogleMapDirection { 
    private DirectionListener listener; 
    public GoogleMapDirection(final Activity activity, LatLng source, LatLng destination, DirectionListener listener){ 
     this.listener=listener; 
     String url = null; 
     try { 
      url = "https://maps.googleapis.com/maps/api/directions/json?origin="+ URLEncoder.encode(Double.toString(source.latitude) + "," + Double.toString(source.longitude), "UTF-8") + "&destination=" + URLEncoder.encode(Double.toString(destination.latitude) + "," + Double.toString(destination.longitude), "UTF-8") + "&mode=driving&sensor=false&key=" + Config.GOOGLE_API_BROWSER_KEY; 
      Print.d(url); 
     } catch (UnsupportedEncodingException e) { 
      Print.exception(e); 
     } 

     JSONObject parameters = new JSONObject(); 
     VolleyJsonBodyRequest.execute(activity, url, parameters, new VolleyResponseListener() { 
      @Override 
      public void onResponse(JSONObject response) { 
       try { 
        if (response.getString("status").equals("OK")) { 
         String distance = "NA"; 
         String duration = "NA"; 
         if (response.has("routes")){ 
          JSONArray routesJArray = response.getJSONArray("routes"); 
          if (routesJArray.length()>0){ 
           if (routesJArray.getJSONObject(0).has("legs")){ 
            JSONArray legsJArray = routesJArray.getJSONObject(0).getJSONArray("legs"); 
            if (legsJArray.length()>0){ 
             JSONObject firstLegsJObj = legsJArray.getJSONObject(0); 
             if (firstLegsJObj.has("distance")){ 
              distance = firstLegsJObj.getJSONObject("distance").getString("text"); 
             } 
             if (firstLegsJObj.has("duration")){ 
              duration = firstLegsJObj.getJSONObject("duration").getString("text"); 
             } 


            } 
           } 
          } 
         } 
         GoogleResponseParserTask task = new GoogleResponseParserTask(distance,duration); 
         task.execute(response); 
        } 
       } catch (JSONException e) { 
        Print.exception(e); 
        DialogWindow.showOK(activity, Config.MESSAGE_INVALID_RESPONSE_FORMAT, new DialogListenerOK() { 
         @Override 
         public void onOK() { 

         } 
        }); 
       } 
      } 
      @Override 
      public void onErrorResponse(VolleyResponseError error) { 
       Print.e(error.getDetails()); 
       DialogWindow.showOK(activity, error.getMessage(), new DialogListenerOK() { 
        @Override 
        public void onOK() { 

        } 
       }); 
      } 
     }); 
    } 


    /** 
    * A class to parse the Google Places in JSON format 
    */ 
    private class GoogleResponseParserTask extends AsyncTask<JSONObject, Integer, ArrayList<RouteModel>> { 

     String distance; 
     String duration; 
     private GoogleResponseParserTask(String distance, String duration){ 
      this.distance=distance; 
      this.duration=duration; 

     } 
     @Override 
     protected ArrayList<RouteModel> doInBackground(JSONObject... jsonResponse) { 
      ArrayList<RouteModel> routes = null; 
      try { 
       routes = parse(jsonResponse[0]); 
      } catch (Exception e) { 
       Print.exception(e); 
      } 
      return routes; 
     } 
     @Override 
     protected void onPostExecute(ArrayList<RouteModel> result) { 
      listener.onDirectionPointsReceived(result,distance,duration); 
     } 
    } 


    /** Receives a JSONObject and returns a list of lists containing latitude and longitude */ 
    public ArrayList<RouteModel> parse(JSONObject jObject){ 

     ArrayList<RouteModel> routeList = new ArrayList<>() ; 
     JSONArray jRoutes; 
     JSONArray jLegs; 
     JSONArray jSteps; 

     try { 

      jRoutes = jObject.getJSONArray("routes"); 

      /** Traversing all routes */ 
      for(int i=0;i<jRoutes.length();i++){ 
       jLegs = ((JSONObject)jRoutes.get(i)).getJSONArray("legs"); 
       ArrayList<LatLng> pointList = new ArrayList<>(); 

       /** Traversing all legs */ 
       for(int j=0;j<jLegs.length();j++){ 
        jSteps = ((JSONObject)jLegs.get(j)).getJSONArray("steps"); 
        JSONObject jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance"); 
        JSONObject jDuration = ((JSONObject) jLegs.get(j)).getJSONObject("duration"); 

        String distance = jDistance.getString("text"); 
        String duration = jDuration.getString("text"); 

        /** Traversing all steps */ 
        for(int k=0;k<jSteps.length();k++){ 
         String polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points"); 
         ArrayList<LatLng> stepList = decodePoly(polyline); 

         /** Traversing all points */ 
         for(int l=0;l<stepList.size();l++){ 
          LatLng point = new LatLng((stepList.get(l)).latitude, (stepList.get(l)).longitude); 
          pointList.add(point); 
         } 
        } 
        RouteModel routeModel = new RouteModel(); 
        routeModel.setSteps(pointList); 
        routeModel.setDistance(distance); 
        routeModel.setDuration(duration); 
        routeList.add(routeModel); 
       } 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     }catch (Exception e){ 
     } 


     return routeList; 
    } 


    /** 
    * Method to decode polyline points 
    * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java 
    * */ 
    private ArrayList<LatLng> decodePoly(String encoded) { 

     ArrayList<LatLng> poly = new ArrayList<>(); 
     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; 

      LatLng p = new LatLng((((double) lat/1E5)), 
        (((double) lng/1E5))); 
      poly.add(p); 
     } 

     return poly; 
    } 
関連する問題