Android

PolyLine is not on the roads: it goes straight from one point to other

Ломаной линии нет на дорогах: она идет прямо из одной точки в другую

Моя карта содержит несколько точек, по которым можно определить местоположение пользователя, откуда он проезжает, но ломаная линия не показана на дорогах, но показывает прямую линию от одного маркера к другому. Я хочу, чтобы моя ломаная линия пересекала дорогу: когда дороги поворачивают, она тоже должна поворачивать.

Вот мой соответствующий код

 dataholder = FirebaseDatabase.getInstance().getReference("UserLocation");
Log.d("onMapReady", "iam here");
dataholder.addValueEventListener(new ValueEventListener() {

@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("data",String.valueOf(dataSnapshot.getValue()));
System.out.println(dataSnapshot.getValue());
for (DataSnapshot a : dataSnapshot.getChildren()) {
MapData mapData = a.getValue(MapData.class);
arrayList.add(mapData);
lati.add(arrayList.get(i).getLatituide());
longit.add(arrayList.get(i).getLongitude());
Log.d("mapi","i am in loop");
mMap = googleMap;
Double lat = Double.parseDouble(lati.get(i));
Double longi = Double.parseDouble(longit.get(i));
sydney = new LatLng(longi, lat);
points.add(sydney);
MarkerOptions mop = new MarkerOptions();
mop.position(sydney);
mop.title("check");
mMap.addMarker(mop);
Log.d("latitude", String.valueOf(lat));
Log.d("longitude", String.valueOf(longi));
// Add a marker in Sydney and move the camera
mMap.addMarker(new MarkerOptions().position(sydney).title("check"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));

i++;
}

line.addAll(points).width(5).color(Color.RED);
line.geodesic(true);
mMap.addPolyline(line);

mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
Toast.makeText(getApplicationContext(),marker.getTitle().toString(),Toast.LENGTH_LONG).show();
return false;
}
});
Переведено автоматически
Ответ 1

Попробуйте использовать часть привязки к дорогеAPI дорог Google Maps, которая


возвращает геометрию дороги, наиболее подходящую для данного набора координат GPS. Этот сервис использует до 100 точек GPS, собранных по маршруту, и возвращает аналогичный набор данных с привязкой точек к наиболее вероятным дорогам, по которым двигалось транспортное средство.


Что-то подобное для данных из Google Maps Roads API, например, Привязка к дороге:

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

private GoogleMap mGoogleMap;
private MapFragment mapFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mapFragment = (MapFragment) getFragmentManager()
.findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;

List<LatLng> sourcePoints = new ArrayList<>();
sourcePoints.add(new LatLng(-35.27801,149.12958));
sourcePoints.add(new LatLng(-35.28032,149.12907));
sourcePoints.add(new LatLng(-35.28099,149.12929));
sourcePoints.add(new LatLng(-35.28144,149.12984));
sourcePoints.add(new LatLng(-35.28194,149.13003));
sourcePoints.add(new LatLng(-35.28282,149.12956));
sourcePoints.add(new LatLng(-35.28302,149.12881));
sourcePoints.add(new LatLng(-35.28473,149.12836));

PolylineOptions polyLineOptions = new PolylineOptions();
polyLineOptions.addAll(sourcePoints);
polyLineOptions.width(5);
polyLineOptions.color(Color.BLUE);
mGoogleMap.addPolyline(polyLineOptions);

mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sourcePoints.get(0), 15));

List<LatLng> snappedPoints = new ArrayList<>();
new GetSnappedPointsAsyncTask().execute(sourcePoints, null, snappedPoints);
}


private String buildRequestUrl(List<LatLng> trackPoints) {
StringBuilder url = new StringBuilder();
url.append("https://roads.googleapis.com/v1/snapToRoads?path=");

for (LatLng trackPoint : trackPoints) {
url.append(String.format("%8.5f", trackPoint.latitude));
url.append(",");
url.append(String.format("%8.5f", trackPoint.longitude));
url.append("|");
}
url.delete(url.length() - 1, url.length());
url.append("&interpolate=true");
url.append(String.format("&key=%s", <your_Google_Maps_API_key>);

return url.toString();
}


private class GetSnappedPointsAsyncTask extends AsyncTask<List<LatLng>, Void, List<LatLng>> {

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

protected List<LatLng> doInBackground(List<LatLng>... params) {

List<LatLng> snappedPoints = new ArrayList<>();

HttpURLConnection connection = null;
BufferedReader reader = null;

try {
URL url = new URL(buildRequestUrl(params[0]));
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();

InputStream stream = connection.getInputStream();

reader = new BufferedReader(new InputStreamReader(stream));
StringBuilder jsonStringBuilder = new StringBuilder();

StringBuffer buffer = new StringBuffer();
String line = "";

while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
jsonStringBuilder.append(line);
jsonStringBuilder.append("\n");
}

JSONObject jsonObject = new JSONObject(jsonStringBuilder.toString());
JSONArray snappedPointsArr = jsonObject.getJSONArray("snappedPoints");

for (int i = 0; i < snappedPointsArr.length(); i++) {
JSONObject snappedPointLocation = ((JSONObject) (snappedPointsArr.get(i))).getJSONObject("location");
double lattitude = snappedPointLocation.getDouble("latitude");
double longitude = snappedPointLocation.getDouble("longitude");
snappedPoints.add(new LatLng(lattitude, longitude));
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}

return snappedPoints;
}

@Override
protected void onPostExecute(List<LatLng> result) {
super.onPostExecute(result);

PolylineOptions polyLineOptions = new PolylineOptions();
polyLineOptions.addAll(result);
polyLineOptions.width(5);
polyLineOptions.color(Color.RED);
mGoogleMap.addPolyline(polyLineOptions);

LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(result.get(0));
builder.include(result.get(result.size()-1));
LatLngBounds bounds = builder.build();
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));

}
}

}

И не забудьте добавить поддержку Google Maps Roads API для вашего проекта в консоль Google APIs (выберите свой проект, затем выберите панель мониторинга, затем нажмите кнопку "+ ВКЛЮЧИТЬ API И СЕРВИСЫ", затем слева "Фильтровать по" выберите "Карты", затем нажмите "Google Maps Roads API" и, наконец, нажмите кнопку "ВКЛЮЧИТЬ").

У вас должно получиться что-то вроде этого:

Ломаная линия с привязанными точками

где: синяя ломаная линия - для исходных точек, красная ломаная линия - для точек привязки.

Помните, что существует ограничение в 100 точек GPS и 2500 запросов в день на пользователя (IP) и 10 запросов в секунду. А также вам нужно более элегантное решение для загрузки JSON с привязанными точками.

java android google-maps