我想在我的 Android 应用中显示两个位置之间的行车路线。我只想在路段顶部绘制路线。
堆栈溢出本身有几个答案,所有答案都使用相同的方法。使用谷歌方向 API 获取从起点到目的地的路线,并在返回的点之间绘制一条折线。以下是使用此方法的一些答案。
https://stackoverflow.com/a/17007360/1015678
https://stackoverflow.com/a/40563930/1015678
但是,上述方法的问题是,当道路不直时,黎明死记硬背并不总是在道路顶部,因为方向 API 只返回您需要从一条道路转向另一条道路的点(在路口) .它不会在同一路段的弯道中提供点详细信息。因此,当我在道路有很多弯道的区域使用上述方法时,绘制的路线几乎总是不在路段的顶部。
我找到了 this使用 javascript API 来回答我需要做的事情。在此解决方案中,绘制的路线很好地遵循道路,类似于 google maps android 应用程序。有人知道这是否可以在 android 应用中实现?
Google Maps android 应用程序可以很好地绘制从一个点到另一个点的路线,使路线保持在道路上。有谁知道谷歌地图是如何做到的?是否使用了其他未公开的 API?
最佳答案
确实,您可以使用 Directions API 网络服务提供的结果在 Google Maps Android API 中绘制精确路线。如果您阅读了 Directions API 的文档您将看到该响应包含有关路线段和步骤的信息。每个步骤都有一个字段 polyline
,在文档中描述为
polyline contains a single points object that holds an encoded polyline representation of the step. This polyline is an approximate (smoothed) path of the step.
因此,解决您的问题的主要思路是从 Directions API 获得响应,循环遍历路线支路和步骤,对于每个步骤获取 encoded polyline并将其解码为坐标列表。完成后,您将获得组成路线的所有坐标的列表,不仅是每个步骤的起点和终点。
为简单起见,我建议将 Java 客户端库用于 Google Maps Web 服务:
https://github.com/googlemaps/google-maps-services-java
使用这个库,您可以避免为折线实现自己的异步任务和解码功能。阅读文档以了解如何在项目中添加客户端库。
在 Gradle 中应该类似于
compile 'com.google.maps:google-maps-services:(insert latest version)'
compile 'org.slf4j:slf4j-nop:1.7.25'
我创建了一个简单的示例来演示它是如何工作的。看看我在代码中的注释
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private String TAG = "so47492459";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng barcelona = new LatLng(41.385064,2.173403);
mMap.addMarker(new MarkerOptions().position(barcelona).title("Marker in Barcelona"));
LatLng madrid = new LatLng(40.416775,-3.70379);
mMap.addMarker(new MarkerOptions().position(madrid).title("Marker in Madrid"));
LatLng zaragoza = new LatLng(41.648823,-0.889085);
//Define list to get all latlng for the route
List<LatLng> path = new ArrayList();
//Execute Directions API request
GeoApiContext context = new GeoApiContext.Builder()
.apiKey("YOUR_API_KEY")
.build();
DirectionsApiRequest req = DirectionsApi.getDirections(context, "41.385064,2.173403", "40.416775,-3.70379");
try {
DirectionsResult res = req.await();
//Loop through legs and steps to get encoded polylines of each step
if (res.routes != null && res.routes.length > 0) {
DirectionsRoute route = res.routes[0];
if (route.legs !=null) {
for(int i=0; i<route.legs.length; i++) {
DirectionsLeg leg = route.legs[i];
if (leg.steps != null) {
for (int j=0; j<leg.steps.length;j++){
DirectionsStep step = leg.steps[j];
if (step.steps != null && step.steps.length >0) {
for (int k=0; k<step.steps.length;k++){
DirectionsStep step1 = step.steps[k];
EncodedPolyline points1 = step1.polyline;
if (points1 != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords1 = points1.decodePath();
for (com.google.maps.model.LatLng coord1 : coords1) {
path.add(new LatLng(coord1.lat, coord1.lng));
}
}
}
} else {
EncodedPolyline points = step.polyline;
if (points != null) {
//Decode polyline and add points to list of route coordinates
List<com.google.maps.model.LatLng> coords = points.decodePath();
for (com.google.maps.model.LatLng coord : coords) {
path.add(new LatLng(coord.lat, coord.lng));
}
}
}
}
}
}
}
}
} catch(Exception ex) {
Log.e(TAG, ex.getLocalizedMessage());
}
//Draw the polyline
if (path.size() > 0) {
PolylineOptions opts = new PolylineOptions().addAll(path).color(Color.BLUE).width(5);
mMap.addPolyline(opts);
}
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(zaragoza, 6));
}
}
请注意,对于 Web 服务,您必须创建单独的 API key ,具有 Android 应用限制的 API key 将不适用于 Web 服务。
我的例子的结果显示在屏幕截图中
您也可以从
下载完整的示例项目https://github.com/xomena-so/so47492459
别忘了用你的替换 API key 。
我希望这会有所帮助!
关于android - 如何在两点之间沿着现有道路绘制路线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47492459/