Google Maps API и пользовательский маршрут полилинии между маркерами
Я хотел бы создать пользовательский маршрут для приложения Android, я не уверен, какой API мне следует использовать и совместим ли он с Java.
Насколько я знаю, мне нужно использовать путевые точки для построения маршрута (мне не нужно знать расстояние между двумя точками, просто для построения маршрута).
Цель состоит в том, чтобы выбрать опцию из меню сбоку карты и показать один из пользовательских маршрутов между двумя маркерами.
Переведено автоматически
Ответ 1
Вы можете сделать это с помощью Google Maps API v2 для Android и Google Maps Directions webservice API
Для начала работы с Google Maps API уже есть множество других хороших ответов. Смотрите здесь полный рабочий пример простого действия с картой. Обратите внимание, что вам также потребуется настроить ключ API для работы с вашим проектом.
Что касается использования API веб-сервиса Google Maps Directions, вам следует сначала прочитать документацию. Вы можете использовать ключ API и включить API в своей консоли разработчика, но в настоящее время он по-прежнему работает без использования ключа API.
Вот базовый код, который вам понадобится, чтобы использовать Google Maps API для рисования полилинии между двумя точками, обратите внимание, что точки, возвращаемые API, закодированы в строке с кодировкой base 64, которую необходимо декодировать.
Во-первых, убедитесь, что в вашем проекте включена библиотека утилит Google Maps Utility, которая будет использоваться для декодирования полилинии в кодировке base64:
dependencies {
compile 'com.google.maps.android:android-maps-utils:0.5+'
//.......
}
Вот асинхронная задача, которой вы должны присвоить две точки LatLng при ее вызове.
Вы бы вызвали AsyncTask с двумя объектами LatLng, например, между двумя маркерами:
new GetDirectionsAsync().execute(markerOne.getPosition(), markerTwo.getPosition());
Вот код 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);
}
}
AsyncTask ссылается на некоторые переменные-члены Activity, а именно на полилинию и GoogleMap, определение Activity будет выглядеть следующим образом:
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback{
GoogleMap mMap;
Polyline line;
//.....
Вот класс 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;
}
}
Результат рисования маршрута между двумя маркерами: