Прямые маршруты бесполезны. Можно ли их устранить? есть прямые линии, которые мне бы не хотелось.
Ввод от rest_api - это простой json по этой ссылке:
https://drive.google.com/file/d/1S2_xOB9Bj6EqiFwuRNGV5JvrjPjZoQD0/view?usp=sharing
Вывод: карта с маркерами и **Без НИКАКИХ прямых линий. **.
Код:
onMapReady(@NonNull GoogleMap map) {
googleMap = map;
googleMap.getUiSettings().setMapToolbarEnabled(false);
googleMap.getUiSettings().setZoomControlsEnabled(false);
routePoints = new ArrayList<>();
noRoutePoints = new ArrayList<>();
String idTappaSelezionata = MainActivity.idUltimaTappaSelezionata;
if (idTappaSelezionata != null) {
mapView.setVisibility(View.GONE);
StringRequest getPercorsoRequest = new StringRequest(Request.Method.POST, Config.GET_PERCORSO_URL,
response -> {
Logger.show("Mappa getData response: " + response + " | Url: " + Config.GET_PERCORSO_URL);
try {
JSONObject responseObject = new JSONObject(response);
JSONArray percorsoArray = responseObject.getJSONArray("percorso");
if (percorsoArray.length() == 0) {
clearRoutes();
} else {
parseAndDisplayRoute(percorsoArray);
}
mapView.setVisibility(View.VISIBLE);
} catch (JSONException e) {
// handle exception
}
},
error -> {
// handle error
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("user_id", MainActivity.userLoggedId);
params.put("id_tappa", idTappaSelezionata);
params.put("id_via", MainActivity.idUltimaViaSelezionata);
return params;
}
};
SingletonVolley.getInstance(getActivity()).addToRequestQueue(getPercorsoRequest);
} else {
showNoRouteDialog();
}
}
private void clearRoutes() {
getActivity().runOnUiThread(() -> {
routePoints.clear();
noRoutePoints.clear();
});
}
private void parseAndDisplayRoute(JSONArray percorsoArray) throws JSONException {
for (int i = 0; i < percorsoArray.length(); i++) {
Gson gson = new Gson();
String tmpPercorso = percorsoArray.getJSONObject(i).toString();
Percorso newP = gson.fromJson(tmpPercorso, Percorso.class);
if ("rosso".equals(newP.getColore())) {
routePoints.add(new LatLng(newP.getLatitude(), newP.getLongitude()));
} else if ("blu".equals(newP.getColore())) {
noRoutePoints.add(new LatLng(newP.getLatitude(), newP.getLongitude()));
}
}
getActivity().runOnUiThread(() -> {
if (!routePoints.isEmpty()) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(routePoints.get(0), 14));
}
if (routePoints.size() > 1 && noRoutePoints.size() > 1) {
addPolylines();
}
addMarker();
setPolylineClickListener();
});
}
private void addPolylines() {
List<LatLng> percorso = PolyUtil.simplify(routePoints, 0.0001); // Adjusted tolerance
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(percorso)
.clickable(true)
.width(10)
.color(Color.RED);
googleMap.addPolyline(percorsoPolyline);
// List<LatLng> simplifiedNoRoute = PolyUtil.simplify(noRoutePoints, 0.0001); // Adjusted tolerance
/*PolylineOptions polylineOptionsRosso = new PolylineOptions()
.addAll(simplifiedRoute)
.clickable(true)
.width(10)
.color(Color.RED);
googleMap.addPolyline(polylineOptionsRosso);
PolylineOptions polylineOptionsBlu = new PolylineOptions()
.addAll(simplifiedNoRoute)
.clickable(true)
.width(10)
.color(Color.BLUE);
googleMap.addPolyline(polylineOptionsBlu);*/
getExperiences(googleMap);
}
private void addMarker() {
LatLng markerMe = routePoints.get(0);
int customMarkerHeight = 100;
int customMarkerWidth = 100;
BitmapDrawable bitmapDrawable = (BitmapDrawable) getResources().getDrawable(R.drawable.me);
Bitmap customMarkerBitmap = Bitmap.createScaledBitmap(bitmapDrawable.getBitmap(), customMarkerWidth, customMarkerHeight, false);
BitmapDescriptor customMarkerMe = BitmapDescriptorFactory.fromBitmap(customMarkerBitmap);
MarkerOptions markerOp = new MarkerOptions()
.position(markerMe)
.icon(customMarkerMe)
.title("Marker " + getId());
googleMap.addMarker(markerOp);
}
private void setPolylineClickListener() {
googleMap.setOnPolylineClickListener(polyline -> {
List<LatLng> path = polyline.getPoints();
String navigationUri = "http://maps.google.com/maps?daddr = " + path.get(path.size() - 1).latitude + "," + path.get(path.size() - 1).longitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(navigationUri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
});
}
private void showNoRouteDialog() {
mapView.setVisibility(View.GONE);
String message = "Non è stato selezionato nessun percorso. Premere OK per scegliere un percorso.";
androidx.appcompat.app.AlertDialog.Builder dialog = new androidx.appcompat.app.AlertDialog.Builder(getActivity());
dialog.setTitle("Le Vie di Francesco");
dialog.setMessage(message);
dialog.setPositiveButton("OK", (dialogInterface, i) -> {
((MainActivity) getActivity()).caricaFragment("menu_home", new Vie(), "Vie");
});
dialog.setCancelable(false);
dialog.show();
}
Где моя беда?
Спасибо, что поставили -1 на этот вопрос. Кто это сделал, очень, очень глуп.
У вас проблема с данными. Это набор сегментов, который, если рассматривать его как единый список точек, приводит к таким «скачкам».
Пример «прыжка» происходит с точками «rosso» в точках с идентификаторами «968» и «15578» (которые представляют собой последовательные точки «rosso», разделенные разделом «blu» (подробнее об этом ниже):
43.775690,11.439900
43.769571,11.340214
Лучшим решением было бы обновить ваши данные в виде разных сегментов (например, GPX называет их «trkseg»s ) и обновить ваш код для поддержки нескольких сегментов трека.
Однако если предположить, что данные не изменяются, то можно применить тест близости между точками для обнаружения «скачков» и построения нескольких полилиний.
Для этого используйте метод библиотеки SphericalUtil.computeDistanceBetween()
.
Я немного упростил ваш пример и изменил обработку «красных» точек, оставив «синие» точки исходными. Отдельный список segment
используется для сохранения исходных списков (поскольку они могут понадобиться вам для других целей).
В качестве примера используется пороговое расстояние в 500,0 метров — это будет зависеть от данных.
Примечание. PolyUtil.simplify
не имеет отношения к вашей проблеме и был удален здесь, но оставьте его, если хотите, по другим причинам.
private void addPolylines() {
// "rosso"
List<LatLng> percorso = routePoints;
List<LatLng> segment = new ArrayList<>();
LatLng prevPt = percorso.get(0);
for (LatLng pt : percorso) {
double d = SphericalUtil.computeDistanceBetween(prevPt,pt);
if (d > 500.0) {
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(segment)
.clickable(true)
.width(10)
.color(Color.RED);
googleMap.addPolyline(percorsoPolyline);
segment.clear();
}
segment.add(pt);
prevPt = pt;
}
if (segment.size() > 0) {
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(segment)
.clickable(true)
.width(10)
.color(Color.RED);
googleMap.addPolyline(percorsoPolyline);
segment.clear();
}
// "blu"
percorso = noRoutePoints;
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(percorso)
.clickable(true)
.width(10)
.color(Color.BLUE);
googleMap.addPolyline(percorsoPolyline);
}
И результат (с хорошим «россо» и плохим «синим»):
Обратите внимание, что ваши данные организованы в виде серии сегментов «rosso» и «blue», например:
[rosso data]
[blu data]
[rosso data]
[blu data]
Поэтому, когда вы достигаете конца раздела «россо», затем переходите к «синему», а затем обратно к «россо», происходит «прыжок» между последовательными точками «россо». Это могут быть сегменты вашего трека, но, как оказалось, даже в «blu» у вас есть несколько сегментов (читайте дальше).
В качестве альтернативы вы можете просто построить свои полилинии на основе этих группировок и обнаружить переходы:
private void parseAndDisplayRoute(JSONArray percorsoArray) throws JSONException {
String lastColor = "";
List<LatLng> segment = new ArrayList<LatLng>();
LatLng prevPt = new LatLng(0.0,0.0);
for (int i = 0; i < percorsoArray.length(); i++) {
Gson gson = new Gson();
String tmpPercorso = percorsoArray.getJSONObject(i).toString();
Percorso newP = gson.fromJson(tmpPercorso, Percorso.class);
LatLng newPt = new LatLng(newP.getLatitude(), newP.getLongitude());
if (i == 0) {
lastColor = newP.getColore();
segment = new ArrayList<LatLng>();
prevPt = newPt;
}
// detect segment transition based on "color" OR distance
if (!lastColor.equals(newP.getColore())) {
int color = (lastColor.equals("rosso") ? Color.RED : Color.BLUE);
addPolylines(segment, color);
segment.clear();
}
if ("rosso".equals(newP.getColore())) {
routePoints.add(newPt);
segment.add(newPt);
} else if ("blu".equals(newP.getColore())) {
noRoutePoints.add(newPt);
segment.add(newPt);
}
lastColor = newP.getColore();
prevPt = newPt;
}
if (segment.size() > 0) {
int color = (lastColor.equals("rosso") ? Color.RED : Color.BLUE);
addPolylines(segment, color);
segment.clear();
}
if (!routePoints.isEmpty()) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(routePoints.get(0), 14));
}
}
private void addPolylines(List<LatLng> pts, int color) {
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(pts)
.clickable(true)
.width(10)
.color(color);
googleMap.addPolyline(percorsoPolyline);
}
Результат использования только «цветных» разделов — «синий» по-прежнему плох, поскольку в нем есть несколько сегментов...:
Итак, наконец, объединение двух методов (расстояние + переход цвета):
private void parseAndDisplayRoute(JSONArray percorsoArray) throws JSONException {
String lastColor = "";
List<LatLng> segment = new ArrayList<LatLng>();
LatLng prevPt = new LatLng(0.0,0.0);
for (int i = 0; i < percorsoArray.length(); i++) {
Gson gson = new Gson();
String tmpPercorso = percorsoArray.getJSONObject(i).toString();
Percorso newP = gson.fromJson(tmpPercorso, Percorso.class);
double d = 0.0;
LatLng newPt = new LatLng(newP.getLatitude(), newP.getLongitude());
if (i == 0) {
lastColor = newP.getColore();
segment = new ArrayList<LatLng>();
prevPt = newPt;
}
d = SphericalUtil.computeDistanceBetween(prevPt,newPt);
// detect segment transition based on "color" OR distance
if (!lastColor.equals(newP.getColore()) || d > 500.0) {
int color = (lastColor.equals("rosso") ? Color.RED : Color.BLUE);
addPolylines(segment, color);
segment.clear();
}
if ("rosso".equals(newP.getColore())) {
routePoints.add(newPt);
segment.add(newPt);
} else if ("blu".equals(newP.getColore())) {
noRoutePoints.add(newPt);
segment.add(newPt);
}
lastColor = newP.getColore();
prevPt = newPt;
}
if (segment.size() > 0) {
int color = (lastColor.equals("rosso") ? Color.RED : Color.BLUE);
addPolylines(segment, color);
segment.clear();
}
if (!routePoints.isEmpty()) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(routePoints.get(0), 14));
}
// addMarker();
// setPolylineClickListener();
}
private void addPolylines(List<LatLng> pts, int color) {
PolylineOptions percorsoPolyline = new PolylineOptions()
.addAll(pts)
.clickable(true)
.width(10)
.color(color);
googleMap.addPolyline(percorsoPolyline);
}
Для проверки я использовал альтернативную версию вашего URL-адреса для «загрузки»:
https://drive.usercontent.google.com/u/0/uc?id=1S2_xOB9Bj6EqiFwuRNGV5JvrjPjZoQD0&export=download
Хорошо, когда вернусь домой, попробую, спасибо за любую помощь ❤️
Большое спасибо!!! я попробую изменить цвет фьезоле - понтассьеве
Мне действительно нужна помощь... спасибо.