2

这是一个棘手的问题,困扰了我一天,请帮忙。

我使用 Google Maps APIs 来获取我提供的 2 个 GeoPoints 之间的最短行驶距离及其路线、点等,请参见下面的代码

private JSONObject GetDistance(String src, String dest) throws Exception
{
    StringBuilder urlString = new StringBuilder();
    urlString.append("http://maps.googleapis.com/maps/api/directions/json?");
    urlString.append("origin=");// from
    urlString.append(src);
    urlString.append("&destination=");// to
    urlString.append(dest);
    urlString.append("&mode=driving&sensor=true&units=imperial");

    // get the JSON And parse it to get the directions data.
    HttpURLConnection urlConnection = null;
    URL url = null;

    url = new URL(urlString.toString());
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.setDoOutput(true);
    urlConnection.setDoInput(true);
    urlConnection.connect();

    InputStream inStream = urlConnection.getInputStream();
    BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));

    String temp, response = "";
    while ((temp = bReader.readLine()) != null)
    {
        // Parse data
        response += temp;
    }
    // Close the reader, stream & connection
    bReader.close();
    inStream.close();
    urlConnection.disconnect();

    JSONObject object = (JSONObject) new JSONTokener(response).nextValue();

    return (object);
}

我还在谷歌地图片段上绘制了 2 个 GeoPoints,我使用 SupportMapFragment,即这个库 com.google.android.gms.maps.SupportMapFragment

我想要做的是,我想绘制从上面的 getDistance 函数获得的路线,它以 JSON 格式输出我可以轻松处理的数据。

Here is the JSON object that I get from the getDistance function
{
    "status": "OK",
    "routes": [
        {
            "waypoint_order": [],
            "summary": "Wilbraham Rd/A6010",
            "bounds": {
                "southwest": {
                    "lng": -2.26773,
                    "lat": 53.4301
                },
                "northeast": {
                    "lng": -2.19414,
                    "lat": 53.45106000000001
                }
            },
            "legs": [
                {
                    "duration": {
                        "value": 797,
                        "text": "13 mins"
                    },
                    "distance": {
                        "value": 7289,
                        "text": "4.5 mi"
                    },
                    "end_location": {
                        "lng": -2.19414,
                        "lat": 53.43052
                    },
                    "start_address": "137 College Road, Manchester, Greater Manchester M16 0AA, UK",
                    "end_address": "6 Ealing Place, Manchester M19, UK",
                    "start_location": {
                        "lng": -2.26773,
                        "lat": 53.45106000000001
                    },
                    "via_waypoint": [],
                    "steps": [
                        {
                            "html_instructions": "Head <b>southeast</b> on <b>College Rd</b> toward <b>Park Dr</b>",
                            "duration": {
                                "value": 83,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 729,
                                "text": "0.5 mi"
                            },
                            "end_location": {
                                "lng": -2.25758,
                                "lat": 53.45005
                            },
                            "polyline": {
                                "points": "ctfeIh|yLrBaEdAoB`@w@N]BKDM@Q@M?]?WC}AAgAGyG?mAI{GG{JM_HAo@"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.26773,
                                "lat": 53.45106000000001
                            }
                        },
                        {
                            "html_instructions": "Turn <b>right</b> onto <b>Withington Rd</b>",
                            "duration": {
                                "value": 96,
                                "text": "2 mins"
                            },
                            "distance": {
                                "value": 747,
                                "text": "0.5 mi"
                            },
                            "end_location": {
                                "lng": -2.25703,
                                "lat": 53.44339
                            },
                            "polyline": {
                                "points": "ymfeIz|wLJ@v@TL@N?H?HAHCJEXKhAy@JGTEH?|BAzAExAAN?z@Cb@?dA?d@AdFKxCGfCC"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.25758,
                                "lat": 53.45005
                            }
                        },
                        {
                            "html_instructions": "Turn <b>left</b> onto <b>Wilbraham Rd/A6010</b>",
                            "duration": {
                                "value": 249,
                                "text": "4 mins"
                            },
                            "distance": {
                                "value": 2565,
                                "text": "1.6 mi"
                            },
                            "end_location": {
                                "lng": -2.21852,
                                "lat": 53.44261
                            },
                            "polyline": {
                                "points": "edeeIlywLAsGAgA@}D@m@@{EFqGHcG?]LmGHaFDyD@gB?sC?oDIw@?i@AuACoCKiGWcNe@mQKcEK}DASAe@C{AAcAAq@?_B?mABkALkCFgBF[LsCp@sQFyADmALkDj@wNx@_U@wA"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.25703,
                                "lat": 53.44339
                            }
                        },
                        {
                            "html_instructions": "Continue straight onto <b>Moseley Rd/B5093</b><div style=\"font-size:0.9em\">Continue to follow Moseley Rd</div><div style=\"font-size:0.9em\">Go through 1 roundabout</div>",
                            "duration": {
                                "value": 100,
                                "text": "2 mins"
                            },
                            "distance": {
                                "value": 974,
                                "text": "0.6 mi"
                            },
                            "end_location": {
                                "lng": -2.20411,
                                "lat": 53.44213000000001
                            },
                            "polyline": {
                                "points": "i_eeIvhpLDsA@a@Ba@D{@JgAPsAVgBHi@De@Fe@Bc@Bk@D{@@_A?qAB}I?gA@oDBmJ@qD?g@@gGBgD@[?Q?MA[AUG]A??AA??AA??AA??A?AA??A?A?AAA?A?A?A?A?A?A?A@??A?A?A@A?A@??A@A@A@?@AYiE"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.21852,
                                "lat": 53.44261
                            }
                        },
                        {
                            "html_instructions": "At the roundabout, take the <b>2nd</b> exit onto <b>Kingsway/A34</b>",
                            "duration": {
                                "value": 63,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 694,
                                "text": "0.4 mi"
                            },
                            "end_location": {
                                "lng": -2.20629,
                                "lat": 53.43661
                            },
                            "polyline": {
                                "points": "i|deItnmLC?AAA?AAAAA?AA?AACAAAAAC?AAC?AAC?C?C?CAA?C?C@C?C?A?C@C?C@A?C@A@C?A@A@A@A@A@A@?@A@?@A@?@?B?@@@?@@@?@@@??@@@@@?@@@@@?@@@?@?@@@b@V^VZHDBHBf@Rv@ZLD`@NJDB@h@RrFvBLDhGxBjFdB"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.20411,
                                "lat": 53.44213000000001
                            }
                        },
                        {
                            "html_instructions": "Turn <b>left</b> onto <b>Grangethorpe Dr</b>",
                            "duration": {
                                "value": 56,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 415,
                                "text": "0.3 mi"
                            },
                            "end_location": {
                                "lng": -2.20015,
                                "lat": 53.43616
                            },
                            "polyline": {
                                "points": "yyceIh|mL\\aCBUBa@RcCFc@FcAHiB@MReRM}@AI"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.20629,
                                "lat": 53.43661
                            }
                        },
                        {
                            "html_instructions": "Continue onto <b>Crossley Rd</b>",
                            "duration": {
                                "value": 45,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 394,
                                "text": "0.2 mi"
                            },
                            "end_location": {
                                "lng": -2.19433,
                                "lat": 53.43562000000001
                            },
                            "polyline": {
                                "points": "_wceI|ulLGyCBY@GJs@L}@BaA?GFqCBiBDkB@CLkBPkBRsCF{@"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.20015,
                                "lat": 53.43616
                            }
                        },
                        {
                            "html_instructions": "Turn <b>right</b> onto <b>Errwood Rd</b>",
                            "duration": {
                                "value": 60,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 607,
                                "text": "0.4 mi"
                            },
                            "end_location": {
                                "lng": -2.19615,
                                "lat": 53.43027000000001
                            },
                            "polyline": {
                                "points": "ssceIpqkL`GtA`B`@xCt@z@Th@H|EnAjFlA"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.19433,
                                "lat": 53.43562000000001
                            }
                        },
                        {
                            "html_instructions": "Take the 2nd <b>left</b> onto <b>Watford Rd</b>",
                            "duration": {
                                "value": 12,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 83,
                                "text": "272 ft"
                            },
                            "end_location": {
                                "lng": -2.19492,
                                "lat": 53.4301
                            },
                            "polyline": {
                                "points": "erbeI||kL`@uF"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.19615,
                                "lat": 53.43027000000001
                            }
                        },
                        {
                            "html_instructions": "Turn <b>left</b> onto <b>Eastern Cir</b>",
                            "duration": {
                                "value": 20,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 65,
                                "text": "213 ft"
                            },
                            "end_location": {
                                "lng": -2.19415,
                                "lat": 53.43037
                            },
                            "polyline": {
                                "points": "cqbeIfukLWWIMKUG_@AU@g@"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.19492,
                                "lat": 53.4301
                            }
                        },
                        {
                            "html_instructions": "Take the 2nd <b>left</b> onto <b>Ealing Pl</b>",
                            "duration": {
                                "value": 13,
                                "text": "1 min"
                            },
                            "distance": {
                                "value": 16,
                                "text": "52 ft"
                            },
                            "end_location": {
                                "lng": -2.19414,
                                "lat": 53.43052
                            },
                            "polyline": {
                                "points": "yrbeIlpkL]A"
                            },
                            "travel_mode": "DRIVING",
                            "start_location": {
                                "lng": -2.19415,
                                "lat": 53.43037
                            }
                        }
                    ]
                }
            ],
            "warnings": [],
            "overview_polyline": {
                "points": "ctfeIh|yLxDqHp@uAHYB_@E{EGgJQwSOoIbAVp@?TIXKhAy@`@MfCA`GKhB?jGM`HKC{ILyUHaHVoNFaH?cIIw@?i@EeFc@mVq@qWSsICcHPwEFgBF[~@gVLgDx@cTx@_U@wAFuBH}A\\{C`@qCLkAFoAF{BBoLFwW@oHDcECqAK_@CCCM?G@E@GDEBAYiEC?CACCEGEICMAMD[BKFGFCHAFBDDDF@Fd@X^VZHNF~An@~@\\|GjCvG~BjFdB\\aCFw@ZgDPmDTsROgAGyCBYL{@L}@BaAFyCHuENoBd@_GF{@`GtAzFvAdB^|EnAjFlA`@uFWWUc@Iu@@g@]A"
            },
            "copyrights": "Map data ©2013 Google"
        }
    ]
}

请帮忙,我真的在这里迷路了。

4

1 回答 1

6

看看我在一篇文章中提供的这段代码,用于从 Google Direction API 创建折线,如果你想从其他来源获取数据,你可以更改获取数据的类,但这就是你的做法。创建一个负责获取方向和解析的类:

public class GMapV2Direction {
public final static String MODE_DRIVING = "driving";
public final static String MODE_WALKING = "walking";

public GMapV2Direction() { }

public Document getDocument(LatLng start, LatLng end, String mode) {
    String url = "http://maps.googleapis.com/maps/api/directions/xml?" 
            + "origin=" + start.latitude + "," + start.longitude  
            + "&destination=" + end.latitude + "," + end.longitude 
            + "&sensor=false&units=metric&mode="+ mode;

    try {
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        HttpPost httpPost = new HttpPost(url);
        HttpResponse response = httpClient.execute(httpPost, localContext);
        InputStream in = response.getEntity().getContent();
        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        Document doc = builder.parse(in);
        return doc;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

public String getDurationText (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("duration");
    Node node1 = nl1.item(0);
    NodeList nl2 = node1.getChildNodes();
    Node node2 = nl2.item(getNodeIndex(nl2, "text"));
    Log.i("DurationText", node2.getTextContent());
    return node2.getTextContent();
}

public int getDurationValue (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("duration");
    Node node1 = nl1.item(0);
    NodeList nl2 = node1.getChildNodes();
    Node node2 = nl2.item(getNodeIndex(nl2, "value"));
    Log.i("DurationValue", node2.getTextContent());
    return Integer.parseInt(node2.getTextContent());
}

public String getDistanceText (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("distance");
    Node node1 = nl1.item(0);
    NodeList nl2 = node1.getChildNodes();
    Node node2 = nl2.item(getNodeIndex(nl2, "text"));
    Log.i("DistanceText", node2.getTextContent());
    return node2.getTextContent();
}

public int getDistanceValue (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("distance");
    Node node1 = nl1.item(0);
    NodeList nl2 = node1.getChildNodes();
    Node node2 = nl2.item(getNodeIndex(nl2, "value"));
    Log.i("DistanceValue", node2.getTextContent());
    return Integer.parseInt(node2.getTextContent());
}

public String getStartAddress (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("start_address");
    Node node1 = nl1.item(0);
    Log.i("StartAddress", node1.getTextContent());
    return node1.getTextContent();
}

public String getEndAddress (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("end_address");
    Node node1 = nl1.item(0);
    Log.i("StartAddress", node1.getTextContent());
    return node1.getTextContent();
}

public String getCopyRights (Document doc) {
    NodeList nl1 = doc.getElementsByTagName("copyrights");
    Node node1 = nl1.item(0);
    Log.i("CopyRights", node1.getTextContent());
    return node1.getTextContent();
}

public ArrayList<LatLng> getDirection (Document doc) {
    NodeList nl1, nl2, nl3;
    ArrayList<LatLng> listGeopoints = new ArrayList<LatLng>();
    nl1 = doc.getElementsByTagName("step");
    if (nl1.getLength() > 0) {
        for (int i = 0; i < nl1.getLength(); i++) {
            Node node1 = nl1.item(i);
            nl2 = node1.getChildNodes();

            Node locationNode = nl2.item(getNodeIndex(nl2, "start_location"));
            nl3 = locationNode.getChildNodes();
            Node latNode = nl3.item(getNodeIndex(nl3, "lat"));
            double lat = Double.parseDouble(latNode.getTextContent());
            Node lngNode = nl3.item(getNodeIndex(nl3, "lng"));
            double lng = Double.parseDouble(lngNode.getTextContent());
            listGeopoints.add(new LatLng(lat, lng));

            locationNode = nl2.item(getNodeIndex(nl2, "polyline"));
            nl3 = locationNode.getChildNodes();
            latNode = nl3.item(getNodeIndex(nl3, "points"));
            ArrayList<LatLng> arr = decodePoly(latNode.getTextContent());
            for(int j = 0 ; j < arr.size() ; j++) {
                listGeopoints.add(new LatLng(arr.get(j).latitude, arr.get(j).longitude));
            }

            locationNode = nl2.item(getNodeIndex(nl2, "end_location"));
            nl3 = locationNode.getChildNodes();
            latNode = nl3.item(getNodeIndex(nl3, "lat"));
            lat = Double.parseDouble(latNode.getTextContent());
            lngNode = nl3.item(getNodeIndex(nl3, "lng"));
            lng = Double.parseDouble(lngNode.getTextContent());
            listGeopoints.add(new LatLng(lat, lng));
        }
    }

    return listGeopoints;
}

private int getNodeIndex(NodeList nl, String nodename) {
    for(int i = 0 ; i < nl.getLength() ; i++) {
        if(nl.item(i).getNodeName().equals(nodename))
            return i;
    }
    return -1;
}

private ArrayList<LatLng> decodePoly(String encoded) {
    ArrayList<LatLng> poly = new ArrayList<LatLng>();
    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 position = new LatLng((double) lat / 1E5, (double) lng / 1E5);
        poly.add(position);
    }
    return poly;
}
}

创建一个 getDirections AsyncTask

public class GetDirectionsAsyncTask extends AsyncTask<Map<String, String>, Object, ArrayList<LatLng>> {

public static final String USER_CURRENT_LAT = "user_current_lat";
public static final String USER_CURRENT_LONG = "user_current_long";
public static final String DESTINATION_LAT = "destination_lat";
public static final String DESTINATION_LONG = "destination_long";
public static final String DIRECTIONS_MODE = "directions_mode";
private MapFragmentActivity activity;
private String url;

private Exception exception;

private Dialog progressDialog;

public GetDirectionsAsyncTask(MapFragmentActivity activity /*String url*/) 
{
    super();
    this.activity = activity;

    //  this.url = url;
}

public void onPreExecute() {
    progressDialog = DialogUtils.createProgressDialog(activity, activity.getString(R.string.get_data_dialog_message));
    progressDialog.show();
}

@Override
public void onPostExecute(ArrayList<LatLng> result) {
    progressDialog.dismiss();

    if (exception == null) {
        activity.handleGetDirectionsResult(result);
    } else {
        processException();
    }
}

@Override
protected ArrayList<LatLng> doInBackground(Map<String, String>... params) {

    Map<String, String> paramMap = params[0];
    try{
        LatLng fromPosition = new LatLng(Double.valueOf(paramMap.get(USER_CURRENT_LAT)) , Double.valueOf(paramMap.get(USER_CURRENT_LONG)));
        LatLng toPosition = new LatLng(Double.valueOf(paramMap.get(DESTINATION_LAT)) , Double.valueOf(paramMap.get(DESTINATION_LONG)));
        GMapV2Direction md = new GMapV2Direction();
        Document doc = md.getDocument(fromPosition, toPosition, paramMap.get(DIRECTIONS_MODE));
        ArrayList<LatLng> directionPoints = md.getDirection(doc);
        return directionPoints;

    }
    catch (Exception e) {
        exception = e;
        return null;
    }
}

private void processException() {
    Toast.makeText(activity, activity.getString(R.string.error_when_retrieving_data), 3000).show();
}

}

在您Activity创建这两种方法时:

public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints)
{
    Polyline newPolyline;
    GoogleMap mMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 
    PolylineOptions rectLine = new PolylineOptions().width(3).color(Color.RED);

    for(int i = 0 ; i < directionPoints.size() ; i++) 
    {          
        rectLine.add(directionPoints.get(i));
    }
    newPolyline = mMap.addPolyline(rectLine);
}


public void findDirections(double fromPositionDoubleLat, double fromPositionDoubleLong, double toPositionDoubleLat, double toPositionDoubleLong, String mode)
{
    Map<String, String> map = new HashMap<String, String>();
    map.put(GetDirectionsAsyncTask.USER_CURRENT_LAT, String.valueOf(fromPositionDoubleLat));
    map.put(GetDirectionsAsyncTask.USER_CURRENT_LONG, String.valueOf(fromPositionDoubleLong));
    map.put(GetDirectionsAsyncTask.DESTINATION_LAT, String.valueOf(toPositionDoubleLat));
    map.put(GetDirectionsAsyncTask.DESTINATION_LONG, String.valueOf(toPositionDoubleLong));
    map.put(GetDirectionsAsyncTask.DIRECTIONS_MODE, mode);

    GetDirectionsAsyncTask asyncTask = new GetDirectionsAsyncTask(this);
    asyncTask.execute(map); 
}

最后运行这个方法来创建Polyline

findDirections(AppObj.getInstance().currentUserLocation.getLatitude(),
                                                   AppObj.getInstance().currentUserLocation.getLongitude(),
                                                   clickMarkerLatLng.latitude, clickMarkerLatLng.longitude, GMapV2Direction.MODE_DRIVING );
于 2013-04-20T23:59:45.587 回答