2013-01-15 24 views
3

我试图从用户的当前位置获取用户定义的位置在我正在构建的应用程序中。这看起来应该是一件相对容易的事情,但我陷入了使用哪个API。谷歌地图指示 - 哪个API?

现在我已经设法挂接到google directions API,但它返回的JSON很奇怪(他们已经在每个地方添加了一个\ n以使其可读),这向我暗示这个API不是正确的一个移动。

我也看到了谷歌地方API被推荐用于此目的,但我似乎无法找到如何从文档中使用它。

任何帮助是极大的赞赏,因为我只是一个titch混淆

编辑:只是为了澄清的问题是,我应该使用以获取地图路线的API?

回答

3

我不记得我在哪里得到它,但这个课程帮助我很多,它包括如果你想绘制路线。

GoogleParser.java

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.util.ArrayList; 
import java.util.List; 

import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import com.google.android.maps.GeoPoint; 
import com.monumentos.log.Logger; 

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

    public GoogleParser(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 GeoPoint position = new GeoPoint((int) (start.getDouble("lat")*1E6), 
            (int) (start.getDouble("lng")*1E6)); 
          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) { 

        Logger.appendLog("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) { 
      Logger.appendLog("Google parser, stream2string"); 
    } finally { 
     try { 
      input.close(); 
     } catch (IOException e) { 
      Logger.appendLog("Google parser, stream2string"); 
     } 
    } 
    return sBuf.toString(); 
} 

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

    private List<GeoPoint> decodePolyLine(final String poly) { 
      int len = poly.length(); 
      int index = 0; 
      List<GeoPoint> decoded = new ArrayList<GeoPoint>(); 
      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 GeoPoint(
        (int) (lat*1E6/1E5), (int) (lng*1E6/1E5))); 
      } 

      return decoded; 
      } 
} 

Parser.java

public interface Parser { 
    public Route parse(); 
} 

Route.java

import java.util.ArrayList; 
import java.util.List; 

import com.google.android.maps.GeoPoint; 

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

    public Route() { 
      points = new ArrayList<GeoPoint>(); 
      segments = new ArrayList<Segment>(); 
    } 

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

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

    public List<GeoPoint> 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; 
    } 

} 



RouteOverlay.java 

public class RouteOverlay extends Overlay { 
/** GeoPoints representing this routePoints. **/ 
private final List<GeoPoint> routePoints; 
/** Colour to paint routePoints. **/ 
private int colour; 
/** Alpha setting for route overlay. **/ 
private static final int ALPHA = 200; 
/** Stroke width. **/ 
private static final float STROKE = 4.5f; 
/** Route path. **/ 
private final Path path; 
/** Point to draw with. **/ 
private final Point p; 
/** Paint for path. **/ 
private final Paint paint; 


/** 
* Public constructor. 
* 
* @param route Route object representing the route. 
* @param defaultColour default colour to draw route in. 
*/ 

public RouteOverlay(final Route route, final int defaultColour) { 
     super(); 
     routePoints = route.getPoints(); 
     colour = defaultColour; 
     path = new Path(); 
     p = new Point(); 
     paint = new Paint(); 
} 

@Override 
public final void draw(final Canvas c, final MapView mv, 
       final boolean shadow) { 
     super.draw(c, mv, shadow); 

     paint.setColor(colour); 
     paint.setAlpha(ALPHA); 
     paint.setAntiAlias(true); 
     paint.setStrokeWidth(STROKE); 
     paint.setStyle(Paint.Style.STROKE); 

     redrawPath(mv); 
     c.drawPath(path, paint); 
} 

/** 
* Set the colour to draw this route's overlay with. 
* 
* @param c Int representing colour. 
*/ 
public final void setColour(final int c) { 
     colour = c; 
} 

/** 
* Clear the route overlay. 
*/ 
public final void clear() { 
     routePoints.clear(); 
} 

/** 
* Recalculate the path accounting for changes to 
* the projection and routePoints. 
* @param mv MapView the path is drawn to. 
*/ 

private void redrawPath(final MapView mv) { 
     final Projection prj = mv.getProjection(); 
     path.rewind(); 
     final Iterator<GeoPoint> it = routePoints.iterator(); 
     prj.toPixels(it.next(), p); 
     path.moveTo(p.x, p.y); 
     while (it.hasNext()) { 
       prj.toPixels(it.next(), p); 
       path.lineTo(p.x, p.y); 
     } 
     path.setLastPoint(p.x, p.y); 
} 

}

Segment.java

import com.google.android.maps.GeoPoint; 

public class Segment { 
    /** Points in this segment. **/ 
    private GeoPoint 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 GeoPoint to add. 
    */ 

    public void setPoint(final GeoPoint point) { 
      start = point; 
    } 

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

    public GeoPoint 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; 
    } 

} 

XMLParser.java

import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 

import com.monumentos.log.Logger; 

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) { 
       Logger.appendLog("XML parser - " + feedUrl); 
      } 
    } 

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

希望它会帮助你。

调用API例如:

 Parser parser; 

     String jsonURL = "http://maps.googleapis.com/maps/api/directions/json?"; 
     final StringBuffer sBuf = new StringBuffer(jsonURL); 
     sBuf.append("origin="); 
     sBuf.append(points.get(0).getLatitudeE6()/1E6); 
     sBuf.append(','); 
     sBuf.append(points.get(0).getLongitudeE6()/1E6); 
     sBuf.append("&destination="); 
     sBuf.append(points.get(points.size()-1).getLatitudeE6()/1E6); 
     sBuf.append(','); 
     sBuf.append(points.get(points.size()-1).getLongitudeE6()/1E6); 

     sBuf.append("&sensor=true&mode="+routeMode); 


     Logger.appendLog(sBuf.toString()); 


     parser = new GoogleParser(sBuf.toString()); 

     Route r = parser.parse(); 
+0

api是\t \t \t'String jsonURL =“http://maps.googleapis.com/maps/api/directions/json?”;'' –

1

您可以使用google http java client解析它们。试试这个example

+0

我已经在使用谷歌的GSON库来解析他们,我不知道我应该调用其API路 –

+0

@CTulip看到这个https://developers.google .com/maps/documentation/directions – Fido

+0

非常感谢! –