简体   繁体   English

标记之间的Google Maps API和自定义折线路线

[英]Google Maps API and custom polyline route between Markers

I'd like to make a custom route for an android app, I'm not sure which API should I use and if it is compatible with Java. 我想为android应用创建自定义路由,我不确定应该使用哪个API以及它是否与Java兼容。

As far as I know I need to use waypoints to make a route (I don't need to know the distance between the two points, just to make a route). 据我所知,我需要使用航点来制作路线(我不需要知道两个点之间的距离,而只是要制作一条路线)。

The objective is to choose an option from a menu on the side of the map and show one of the custom routes between two Markers. 目的是从地图侧面的菜单中选择一个选项,并显示两个标记之间的自定义路线之一。

You can do this using the Google Maps API v2 for Android , and the Google Maps Directions webservice API 您可以使用适用于AndroidGoogle Maps API v2Google Maps Directions网络服务API来执行此操作

For getting started with the Google Maps API, there are plenty of other good answers already. 要开始使用Google Maps API,已经有很多其他好的答案。 See here for a complete working example of a simple map Activity. 有关简单地图活动的完整工作示例, 请参见此处 Note that you'll also need to get an API key set up to work with your project. 请注意,您还需要设置一个API密钥才能与您的项目一起使用。

As for using the Google Maps Directions webservice API, you should first read the documentation. 至于使用Google Maps Directions网络服务API,您应该先阅读文档。 You can use an API key and enable the API in your developer console, but it still works currently without using an API key. 您可以使用API​​密钥并在开发人员控制台中启用该API,但是当前仍可以在不使用API​​密钥的情况下使用。

Here is the basic code you'll need in order to use the Google Maps API to draw a Polyline between two points, note that the points returned from the API are encoded in a base 64 encoded String that needs to be decoded. 这是您需要的基本代码,才能使用Google Maps API在两点之间绘制一条折线,请注意,从API返回的点编码为需要解码的基本64编码字符串。

First, ensure that your project includes the Google Maps Utility library, which will be used to decode the base64 encoded polyline: 首先,请确保您的项目包含Google Maps Utility库,该库将用于解码base64编码的折线:

dependencies {
    compile 'com.google.maps.android:android-maps-utils:0.5+'
    //.......
}

Here is the AsyncTask, that you should give two LatLng points to when calling it. 这是AsyncTask,在调用它时应该给两个LatLng点。

You would call the AsyncTask with two LatLng objects, for example between two Markers: 您将使用两个LatLng对象(例如,两个标记之间)调用AsyncTask:

new GetDirectionsAsync().execute(markerOne.getPosition(), markerTwo.getPosition());

Here is the AsyncTask code: 这是AsyncTask代码:

class GetDirectionsAsync extends AsyncTask<LatLng, Void, List<LatLng>> {

    JSONParser jsonParser;
    String DIRECTIONS_URL = "https://maps.googleapis.com/maps/api/directions/json";


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected List<LatLng> doInBackground(LatLng... params) {
        LatLng start = params[0];
        LatLng end = params[1];

        HashMap<String, String> points = new HashMap<>();
        points.put("origin", start.latitude + "," + start.longitude);
        points.put("destination", end.latitude + "," + end.longitude);

        jsonParser = new JSONParser();

        JSONObject obj = jsonParser.makeHttpRequest(DIRECTIONS_URL, "GET", points, true);

        if (obj == null) return null;

        try {
            List<LatLng> list = null;

            JSONArray routeArray = obj.getJSONArray("routes");
            JSONObject routes = routeArray.getJSONObject(0);
            JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
            String encodedString = overviewPolylines.getString("points");
            list = PolyUtil.decode(encodedString);

            return list;

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

        return null;
    }

    @Override
    protected void onPostExecute(List<LatLng> pointsList) {

        if (pointsList == null) return;

        if (line != null){
            line.remove();
        }

        PolylineOptions options = new PolylineOptions().width(5).color(Color.MAGENTA).geodesic(true);
        for (int i = 0; i < pointsList.size(); i++) {
            LatLng point = pointsList.get(i);
            options.add(point);
        }
        line = mMap.addPolyline(options);

    }
}

The AsyncTask references some member variables of the Activity, namely the Polyline and the GoogleMap, the Activity definition would look like this: AsyncTask引用了Activity的一些成员变量,即Polyline和GoogleMap,Activity定义如下所示:

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback{

    GoogleMap mMap;
    Polyline line;
    //.....

Here's the JSONParser class used in this example, note that this is a modified version updated for android-23 that I wrote a blog post about : 这是此示例中使用的JSONParser类,请注意,这是针对android-23更新的修改版本,我写了一篇有关以下内容的博客文章

public class JSONParser {

    String charset = "UTF-8";
    HttpURLConnection conn;
    DataOutputStream wr;
    StringBuilder result;
    URL urlObj;
    JSONObject jObj = null;
    StringBuilder sbParams;
    String paramsString;

    public JSONObject makeHttpRequest(String url, String method,
                                      HashMap<String, String> params, boolean encode) {

        sbParams = new StringBuilder();
        int i = 0;
        for (String key : params.keySet()) {
            try {
                if (i != 0){
                    sbParams.append("&");
                }
                if (encode) {
                    sbParams.append(key).append("=")
                            .append(URLEncoder.encode(params.get(key), charset));
                }
                else{
                    sbParams.append(key).append("=")
                            .append(params.get(key));
                }

            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            i++;
        }

        if (method.equals("POST")) {
            // request method is POST
            try {
                urlObj = new URL(url);

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(true);

                conn.setRequestMethod("POST");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setReadTimeout(10000);
                conn.setConnectTimeout(15000);

                conn.connect();

                paramsString = sbParams.toString();

                wr = new DataOutputStream(conn.getOutputStream());
                wr.writeBytes(paramsString);
                wr.flush();
                wr.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        else if(method.equals("GET")){
            // request method is GET

            if (sbParams.length() != 0) {
                url += "?" + sbParams.toString();
            }

            Log.d("JSONParser", "full GET url: " + url);

            try {
                urlObj = new URL(url);

                conn = (HttpURLConnection) urlObj.openConnection();

                conn.setDoOutput(false);

                conn.setRequestMethod("GET");

                conn.setRequestProperty("Accept-Charset", charset);

                conn.setConnectTimeout(15000);

                conn.connect();

            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        try {
            //Receive the response from the server
            InputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            String line;
            result = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d("JSON Parser", "result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        conn.disconnect();

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        // return JSON Object
        return jObj;
    }
}

Result of drawing a route between two Markers: 在两个标记之间绘制路线的结果:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM