3

私が構築しているアプリで、ユーザーの現在の場所からユーザー定義の場所への道順を取得しようとしています。これは比較的簡単に実行できるように思えますが、どの API を使用するかで行き詰まっています。

現在、私はGoogleの指示APIに接続することができましたが、それが返すJSONは非常に奇妙です(人間が読めるようにするためにどこにでも\nを追加しました)。これは、このAPIが正しいものではないことを示唆していますモバイル用。

この目的で Google Places API が推奨されていることも確認しましたが、ドキュメントからその使用方法を見つけることができないようです。

私は混乱しているだけなので、どんな助けも大歓迎です

編集:質問を明確にするために、マップの方向を取得するためにどのAPIを使用する必要がありますか?

4

2 に答える 2

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

パーサー.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);
}

}

セグメント.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();
于 2013-01-15T13:10:49.580 に答える
1

google http java clientを使用して解析できます。この例を試してください

于 2013-01-15T12:59:30.000 に答える