Как буферизовать ломаную линию в Android или нарисовать многоугольник вокруг ломаной?
Я пытаюсь поместить буфер вокруг полилинии в MapsV2 для Android, но я пока не нашел, как это сделать, я думал о том, как нарисовать многоугольник вокруг полилинии, но также не нашел никого, кто это сделал, не так ли? возможный?
4 ответа
Хотите нарисовать путь на карте или хотите нарисовать прямые линии на карте?
В обоих случаях вы можете следовать приведенному ниже коду
PolylineOptions polyLineOptions = new PolylineOptions();
ArrayList<LatLng> points = new ArrayList<>();
//Code to populate Latlng
polyLineOptions.addAll(points);
polyLineOptions.width(mActivity.getResources().getDimensionPixelSize(R.dimen._2sdp));
polyLineOptions.color(ContextCompat.getColor(mContext, Color_Resource_id));
if (polyLineOptions != null) {
googleMap.addPolyline(polyLineOptions);
}
Выше код должен рисовать только прямые линии на карте.
Теперь, если вы хотите нарисовать полный путь на карте, вам, вероятно, потребуется использовать API-адрес направления Google https://maps.googleapis.com/maps/api/directions/
Вы можете использовать ниже класс, чтобы разобрать ответ от того же самого, чтобы получить итоговые значения
public class PathJSONParser {
public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
List<List<HashMap<String, String>>> routes = new ArrayList<>();
JSONArray jRoutes;
JSONArray jLegs;
JSONArray jSteps;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for (int i = 0; i < jRoutes.length(); i++) {
jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<>();
/** Traversing all legs */
for (int j = 0; j < jLegs.length(); j++) {
jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps");
/** Traversing all steps */
for (int k = 0; k < jSteps.length(); k++) {
String polyline;
polyline = (String) ((JSONObject) ((JSONObject) jSteps
.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
/** Traversing all points */
for (int l = 0; l < list.size(); l++) {
HashMap<String, String> hm = new HashMap<>();
hm.put("lat",
Double.toString(( list.get(l)).latitude));
hm.put("lng",
Double.toString(( list.get(l)).longitude));
path.add(hm);
}
}
routes.add(path);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
/**
* Method Courtesy :
* jeffreysambells.com/2010/05/27
* /decoding-polylines-from-google-maps-direction-api-with-java
* */
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
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 p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
}
И, наконец, вы можете использовать это в своем классе с кодом ниже
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = new ArrayList<>();
try {
jObject = new JSONObject(jsonData[0]);
PathJSONParser parser = new PathJSONParser();
routes = parser.parse(jObject);
} catch (Exception e) {
e.printStackTrace();
}
return routes;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> routes) {
if (routes != null && routes.size() > 0) {
new DrawPoly().execute(routes);
}
}
}
private class DrawPoly extends AsyncTask<List<List<HashMap<String, String>>>,
PolylineOptions, PolylineOptions> {
@Override
protected PolylineOptions doInBackground(List<List<HashMap<String, String>>>... params) {
PolylineOptions polyLineOptions = new PolylineOptions();
ArrayList<LatLng> points;
if (params[0] != null && params[0].size() > 0) {
// traversing through routes
for (int j = 0; j < params[0].size(); j++) {
points = new ArrayList<>();
polyLineOptions = new PolylineOptions();
try {
List<HashMap<String, String>> path = params[0].get(j);
for (int k = 0; k < path.size(); k++) {
HashMap<String, String> point = path.get(k);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
} catch (Exception e) {
e.printStackTrace();
}
polyLineOptions.addAll(points);
polyLineOptions.width(mActivity.getResources().getDimensionPixelSize(R.dimen.five));
polyLineOptions.color(ContextCompat.getColor(mContext, R.color.red));
}
}
return polyLineOptions;
}
@Override
protected void onPostExecute(PolylineOptions polyLineOptions) {
super.onPostExecute(polyLineOptions);
if (polyLineOptions != null) {
googleMap.addPolyline(polyLineOptions);
}
}
}
Вы должны убедиться, что вы помещаете его в asyncTask. Я надеюсь, что это будет работать для вас.
В инструкции Google api ( https://maps.googleapis.com/maps/api/directions/json?origin=75+9th+Ave+New+York,+NY&destination=MetLife+Stadium+1+MetLife+Stadium+Dr+East+Rutherford,+NJ+07073&key=YOUR_API_KEY) вы получаете один обзор_полинии jsonObject, отсюда получаете кодированные точки и декодируете его, используя этот метод:
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
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 p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
Вы получаете Список широты и долготы, теперь, используя метод getMapAsync карты Google, добавьте этот latlng в вашу карту:
googleMap.addPolyline(new PolylineOptions().geodesic(true).addAll(latLngList));
Я нашел способ добавить полилинии на карту.
Из приведенной выше ссылки вам нужно три класса из Google Maps Android-утилиты. MathUtil, PolyUtil и SpheriacalUtil.
Я сделал функцию и использую Retrofit для подключения к Google
public void drawMapPath (String origin, String destination, String travel){
RestInterface restInterface = ApiClient.getClient().create(RestInterface.class);
Call<GoogleDirections> call = restInterface.getDirections(origin, destination, travel, AppConfig.API_GOOGLEMAPS);
call.enqueue(new Callback<GoogleDirections>(){
@Override
public void onResponse(Call<GoogleDirections> call, Response<GoogleDirections> response){
if (response.isSuccessful()){
Routes[] route = response.body().getRoutes();
/** get bounds to set map after completion */
LatLngBounds.Builder mapBounds = new LatLngBounds.Builder();
LatLng northEast = new LatLng(Double.parseDouble(route[0].getBounds().getNortheast().getLat()),Double.parseDouble(route[0].getBounds().getNortheast().getLng()));
mapBounds.include(northEast);
LatLng southWest = new LatLng(Double.parseDouble(route[0].getBounds().getSouthwest().getLat()),Double.parseDouble(route[0].getBounds().getSouthwest().getLng()));
mapBounds.include(southWest);
/** no alternatives set so only one route*/
Legs[] leg = route[0].getLegs();
/** get the steps */
Steps[] step =leg[0].getSteps();
/** init points and options */
points = new ArrayList();
lineOptions = new PolylineOptions();
/** Traversing through the steps */
for (int i=0; i < step.length; i++ ){
String polyline;
polyline = step[i].getPolyline().getPoints();
/** classes needed from google */
List<LatLng> list = decodePoly(polyline);
/** Traversing all points in list*/
for (int n = 0; n < list.size(); n++) {
double lat = list.get(n).latitude;
double lon = list.get(n).longitude;
LatLng position=new LatLng(lat, lon);
points.add(position);
}
}
lineOptions.addAll(points);
lineOptions.width(12);
lineOptions.color(Color.BLUE);
lineOptions.geodesic(true);
googleMap.addPolyline(lineOptions);
googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(),10));
} else {
Toast.makeText(getActivity(), getString(R.string.server_broken), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<GoogleDirections> call, Throwable t) {
Log.d("Error ", t.getMessage());
}
});
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
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 p = new LatLng((((double) lat / 1E5)),
(((double) lng / 1E5)));
poly.add(p);
}
return poly;
}
Лучший способ сделать это - использовать метод mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(yourBounds,200));
, Второй аргумент (200
) является отступом вокруг линии поли, определенной в yourBounds
,
Вот пример кода:
private GoogleMap mMap;
public void addPolyline(ArrayList<LatLng> result) {
// Paint Lines on map
PolylineOptions lineOptions = null;
lineOptions = new PolylineOptions();
lineOptions.addAll(result);
lineOptions.width(10);
lineOptions.color(Color.RED);
mMap.addPolyline(lineOptions);
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (LatLng l: result) { b.include(l); }
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(b.build(),200));
}