基于Google Maps API v3的Android公交应用:两点间折线路线绘制问题
实现两个标记点间沿公交折线绘制路线的方案
嗨,针对你基于Google Maps API v3开发Android公交应用的需求,我来详细说说怎么实现两个标记点间沿已绘制的公交折线截取路段并绘制的功能:
核心思路
我们需要从你已有的Bus类的Polyline中,提取出起点标记点到终点标记点之间的连续路段,然后用自定义样式在地图上绘制这段路线。具体分为以下几个步骤:
步骤1:完善Bus类的封装(可选但推荐)
你的Bus类里polyline是public的,建议添加getter方法来获取路线的所有坐标点,这样更符合封装原则:
public class Bus { private Polyline polyline; private String route; private String schedule; // 构造方法、其他属性的getter/setter... public List<LatLng> getRoutePoints() { return polyline.getPoints(); } public Polyline getPolyline() { return polyline; } }
步骤2:实现核心方法
下面是完整的实现代码,包含了“找最近路线点”、“截取路段”、“绘制路线”三个核心部分:
import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import com.google.maps.android.SphericalUtil; import java.util.ArrayList; import java.util.Collections; import java.util.List; // 绘制两个标记点间的公交路线路段 public void drawRouteSegment(GoogleMap map, Bus targetBus, LatLng startMarker, LatLng endMarker) { List<LatLng> allRoutePoints = targetBus.getRoutePoints(); if (allRoutePoints.isEmpty()) { // 该公交线路无坐标点,直接返回 return; } // 1. 找到离起点、终点标记最近的路线点索引 int startIndex = findClosestPointIndex(allRoutePoints, startMarker); int endIndex = findClosestPointIndex(allRoutePoints, endMarker); // 2. 根据索引截取路线路段,处理方向问题 List<LatLng> routeSegment; if (startIndex <= endIndex) { // 起点在终点之前,直接截取正序路段 routeSegment = allRoutePoints.subList(startIndex, endIndex + 1); } else { // 起点在终点之后,截取后反转列表保证路线方向正确 routeSegment = new ArrayList<>(allRoutePoints.subList(endIndex, startIndex + 1)); Collections.reverse(routeSegment); } // 3. 创建路线样式并绘制到地图 PolylineOptions segmentOptions = new PolylineOptions() .addAll(routeSegment) .color(0xFF0066CC) // 自定义路线颜色(这里是蓝色) .width(12f) // 路线宽度 .zIndex(2); // 层级高于原公交线路,确保路段可见 // 添加到地图 map.addPolyline(segmentOptions); } // 辅助方法:找到路线点列表中离目标标记点最近的点的索引 private int findClosestPointIndex(List<LatLng> routePoints, LatLng targetPoint) { int closestIndex = 0; double minDistance = Double.MAX_VALUE; for (int i = 0; i < routePoints.size(); i++) { // 计算两点间的直线距离(单位:米) double distance = SphericalUtil.computeDistanceBetween(routePoints.get(i), targetPoint); if (distance < minDistance) { minDistance = distance; closestIndex = i; } } return closestIndex; }
步骤3:依赖准备
上面的代码用到了SphericalUtil来计算两点距离,这个工具类来自Google Maps Android API Utility Library,需要在你的build.gradle(Module级别)中添加依赖:
dependencies { // 其他依赖... implementation 'com.google.maps.android:android-maps-utils:2.2.0' }
额外优化建议
- 区分原路线和路段:可以把原公交线路设置为浅灰色,截取的路段用鲜艳的颜色,用户体验更好。
- 标记起点终点:可以在
drawRouteSegment方法末尾添加代码,在起点和终点位置添加Marker:map.addMarker(new MarkerOptions().position(startMarker).title("起点")); map.addMarker(new MarkerOptions().position(endMarker).title("终点")); - 多线路判断:如果你的应用支持多条线路,建议先判断两个标记点是否在同一条公交线路的范围内,再执行绘制逻辑。
内容的提问来源于stack exchange,提问作者DrFreeze
相关产品推荐
相关产品推荐

