抽2 GeoPoints上GoogleMap的SupportMapFragment之间的行车路线行车路线、GeoPoints、GoogleMap、SupportMapFragment

2023-09-12 09:57:58 作者:槛外客

这是一个棘手的问题,一直敲我的头一天,请大家帮忙。

This is a tricky question, been banging my head for a day, please help.

我使用谷歌地图API来获取2 GeoPoints我提供之间的最短行驶距离和路线,点等,见下文

I use Google Maps Apis to get the shortest driving distance and its routes, points, etc between 2 GeoPoints that I provide, see code below

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

I also plot the 2 GeoPoints on a google maps fragment, I use SupportMapFragment, i.e. this library com.google.android.gms.maps.SupportMapFragment

我想要做的是,我要画,我从getDistance的功能上面得到的路线,它输出的JSON数据,我可以轻松处理。

what I want to do is, I want to draw the route that I get from the getDistance function above, it outputs the data in JSON which I can easily handle.

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"
        }
    ]
}

请帮忙,我真的真的失去了这里。

Please help, I'm really really lost in here.

推荐答案

看看我在这里提供的职位之一,从谷歌的方向API创建折线这code,您可以更改获取类数据如果您想从其他来源得到它,但是这是你如何做到这一点。创建一个类,将负责获取的方向和解析:

Take a look at this code I was provided here in one of the posts for creating Polyline from Google Direction API, you can change the class that gets the data if you want to get it from other source but this is how you do it. Create a class that will be responsible for getting the direction and parsing:

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

}

在你的活动创建的2种方法:

In your Activity create those 2 methods:

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

最后,运行这个方法来创建折线

findDirections(AppObj.getInstance().currentUserLocation.getLatitude(),
                                                   AppObj.getInstance().currentUserLocation.getLongitude(),
                                                   clickMarkerLatLng.latitude, clickMarkerLatLng.longitude, GMapV2Direction.MODE_DRIVING );