问题描述
我正在使用Roads Google API传递位置列表,并希望通过这些点在汽车驾驶的最可能的道路上绘制线条.
出问题了,因为某些点没有被线交叉,并且这些线不仅仅使用道路,其中一些通过直线穿过建筑物或海洋.我添加了标记来显示问题.
代码有问题吗?
一些示例代码会出现此错误:
公共类MainActivity扩展了AppCompatActivity实现的OnMapReadyCallback {私有GoogleMap mGoogleMap;私有MapFragment mapFragment;@Override受保护的void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mapFragment =(MapFragment)getFragmentManager().findFragmentById(R.id.map_fragment);mapFragment.getMapAsync(this);}@Overridepublic void onMapReady(GoogleMap googleMap){mGoogleMap = googleMap;列表< LatLng>sourcePoints = new ArrayList<>();sourcePoints.add(new LatLng(39.4321055669415,-0.343169529033198));sourcePoints.add(new LatLng(39.4279737815806,-0.334743742804801));sourcePoints.add(new LatLng(39.4235262880062,-0.341102620562518));sourcePoints.add(new LatLng(39.4216973481355,-0.340624944612178));sourcePoints.add(new LatLng(39.4194951574233,-0.335974058847626));sourcePoints.add(new LatLng(39.4216760915054,-0.340342003540913));sourcePoints.add(new LatLng(39.4235646246302,-0.340901154018858));sourcePoints.add(new LatLng(39.4321131753486,-0.342995147300383));PolylineOptions polyLineOptions =新的PolylineOptions();polyLineOptions.addAll(sourcePoints);polyLineOptions.width(5);polyLineOptions.color(Color.BLUE);mGoogleMap.addPolyline(polyLineOptions);mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sourcePoints.get(0),15));列表< LatLng>snappedPoints =新的ArrayList<>();新的GetSnappedPointsAsyncTask().execute(sourcePoints,null,snappedPoints);}私有字符串buildRequestUrl(List< LatLng> trackPoints){StringBuilder url = new StringBuilder();url.append("https://roads.googleapis.com/v1/snapToRoads?path=");对于(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>));返回url.toString();}私有类GetSnappedPointsAsyncTask扩展了AsyncTask< List< LatLng> ;, Void,List< LatLng>{受保护的void onPreExecute(){super.onPreExecute();}受保护的列表< LatLng>doInBackground(List< LatLng> ... params){列表< LatLng>snappedPoints =新的ArrayList<>();HttpURLConnection connection = null;BufferedReader reader = null;尝试 {URL url =新URL(buildRequestUrl(params [0]));连接=(HttpURLConnection)url.openConnection();connection.setRequestMethod("GET");connection.connect();InputStream流= connection.getInputStream();reader = new BufferedReader(new InputStreamReader(stream));StringBuilder jsonStringBuilder = new StringBuilder();StringBuffer buffer =新的StringBuffer();字符串行=";while((line = reader.readLine())!= null){buffer.append(line +"\ n");jsonStringBuilder.append(line);jsonStringBuilder.append("\ n");}JSONObject jsonObject =新的JSONObject(jsonStringBuilder.toString());JSONArray snappedPointsArr = jsonObject.getJSONArray("snappedPoints");for(int i = 0; i< snappedPointsArr.length(); i ++){JSONObject snappedPointLocation =(((JSONObject)(snappedPointsArr.get(i))).getJSONObject("location");双纬度= snappedPointLocation.getDouble("latitude");双经度= snappedPointLocation.getDouble("longitude");snappedPoints.add(new LatLng(纬度,经度));}} catch(MalformedURLException e){e.printStackTrace();} catch(IOException e){e.printStackTrace();} catch(JSONException e){e.printStackTrace();} 最后 {if(connection!= null){connection.disconnect();}尝试 {如果(读者!= null){reader.close();}} catch(IOException e){e.printStackTrace();}}返回snappedPoints;}@Override受保护的void onPostExecute(List< LatLng>结果){super.onPostExecute(result);PolylineOptions polyLineOptions =新的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));}}}
您的代码没问题:
NB!不要忘记在 Google API控制台
上允许使用Directions API有关Direction API的更多详细信息,此处在线教程/示例.
I'm using the Roads Google API passing a list of positions and I want to paint lines in the most probable road driven by a car by these points.
Something is going wrong because some points are not being crossed by the lines and the lines are not using only roads, some of them pass through edifices or the sea with straight lines. I added markers to show the problem.
Is something wrong in the code?
Some sample code to get this error:
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(39.4321055669415, -0.343169529033198));
sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));
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));
}
}
}
It's everything ok with your code: there are not enough points for Snap to Roads. You should use Google Maps Directions API instead of Snap to Roads API to get lacking points: format route request, receive and parse response - you need overview_polyline
tag points
String value - it's encoded polyline of route part For your source points (blue path on figure):
List<LatLng> sourcePoints = new ArrayList<>();
sourcePoints.add(new LatLng(39.4321055669415, -0.343169529033198));
sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));
with Google Maps Directions API implementation like that:
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
private static final String TAG = MainActivity.class.getSimpleName();
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(39.4321055669415, -0.343169529033198));
sourcePoints.add(new LatLng(39.4279737815806, -0.334743742804801));
sourcePoints.add(new LatLng(39.4235262880062, -0.341102620562518));
sourcePoints.add(new LatLng(39.4216973481355, -0.340624944612178));
sourcePoints.add(new LatLng(39.4194951574233, -0.335974058847626));
sourcePoints.add(new LatLng(39.4216760915054, -0.340342003540913));
sourcePoints.add(new LatLng(39.4235646246302, -0.340901154018858));
sourcePoints.add(new LatLng(39.4321131753486, -0.342995147300383));
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> directionsPoints = new ArrayList<>();
new GetDirectionPointsAsyncTask().execute(sourcePoints, null, directionsPoints);
}
private String buildDirectionsUrl(List<LatLng> trackPoints) {
if (trackPoints.size() < 2) {
return null;
}
final LatLng origin = trackPoints.get(0);
final LatLng dest = trackPoints.get(trackPoints.size() - 1);
StringBuilder url = new StringBuilder();
url.append("https://maps.googleapis.com/maps/api/directions/json?");
url.append(String.format("origin=%8.5f,%8.5f", origin.latitude, origin.longitude));
url.append(String.format("&destination=%8.5f,%8.5f", dest.latitude, dest.longitude));
// add waypoints, if they exists
if (trackPoints.size() > 2) {
url.append("&waypoints=");
LatLng wayPoint;
for (int ixWaypoint = 1; ixWaypoint < trackPoints.size() - 2; ixWaypoint++) {
wayPoint = trackPoints.get(ixWaypoint);
url.append(String.format("%8.5f,%8.5f|", wayPoint.latitude, wayPoint.longitude));
}
url.delete(url.length() - 1, url.length());
}
url.append(String.format("&key=%s", getResources().getString(R.string.google_maps_key)));
return url.toString();
}
private class GetDirectionPointsAsyncTask extends AsyncTask<List<LatLng>, Void, List<LatLng>> {
protected void onPreExecute() {
super.onPreExecute();
}
protected List<LatLng> doInBackground(List<LatLng>... params) {
List<LatLng> routePoints = new ArrayList<>();
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(buildDirectionsUrl(params[0]));
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
int responseCode = connection.getResponseCode();
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 jsonRoot = new JSONObject(jsonStringBuilder.toString());
JSONArray jsonRoutes = jsonRoot.getJSONArray("routes");
if (jsonRoutes.length() < 1) {
return null;
}
JSONObject jsonRoute = jsonRoutes.getJSONObject(0);
JSONObject overviewPolyline = jsonRoute.getJSONObject("overview_polyline");
String overviewPolylineEncodedPoints = overviewPolyline.getString("points");
routePoints = decodePoly(overviewPolylineEncodedPoints);
} 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 routePoints;
}
@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));
}
}
//
// Method to decode polyline points
// Courtesy : http://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;
}
}
you get something like that (red path on figure):
NB! Don't forget to allow Directions API on Google APIs Console
More details about Direction API here and in many online tutorials/examples.
这篇关于googleapi道路:某些地方不见了,线路穿过了建筑物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!