限制Android地图标记拖动到折线

时间:2016-02-17 20:01:07

标签: android google-maps

我正在寻找一些关于我如何解决我面临的问题的建议我正在使用Android的SupportMapFragment。我使用存储在我的应用程序db中的LatLng协议在SupportMapFragment上绘制折线。我还在第一个和最后一个LatLng协议中添加了一个地图标记,以表示路线的开始和结束。我想通过将开始和结束标记拖动到折线上的所需点来为我的用户提供修剪路径的功能。我面临的问题是限制标记可以拖过的路径,因此它们只能沿折线移动。

1 个答案:

答案 0 :(得分:1)

这个问题有点陈旧,但我希望其他人会觉得这个答案很有用。

boolean PolyUtil.isLocationOnEdge将帮助您确定点与地图上的多边形或折线重叠。

public class RestrictedMarkerDragActivity extends FragmentActivity implements
        OnMapReadyCallback,
        GoogleMap.OnMarkerDragListener {

    private static final float WIDTH = 4;
    private static final double TOLERANCE_IN_METERS = 3.0;

    private GoogleMap map;
    private SupportMapFragment mapFragment;
    private Polyline polyline;
    private Marker marker;
    private LatLng positionOnPolyline;

    @Override
    protected void onCreate(Bundle savedInstance) {
        super.onCreate(savedInstance);
        setContentView(R.layout.activity_maps);

        mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        this.map = googleMap;

        List<LatLng> points = new ArrayList<>();
        points.add(new LatLng(19.35853391311947, -99.15182696733749));
        points.add(new LatLng(19.34384275931999, -99.1546209261358));

        PolylineOptions polylineOptions = new PolylineOptions();
        polylineOptions.color(Color.CYAN);
        polylineOptions.width(WIDTH);
        polyline = map.addPolyline(polylineOptions);
        polyline.setPoints(points);

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.draggable(true);
        markerOptions.position(points.get(0));
        marker = map.addMarker(markerOptions);

        positionOnPolyline = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude);

        map.setOnMarkerDragListener(this);

        map.animateCamera(CameraUpdateFactory.newLatLngZoom(points.get(0), 15));
    }

    @Override
    public void onMarkerDragStart(Marker marker) {
        //Nothing to do here

    }

    @Override
    public void onMarkerDrag(Marker marker) {
        //If the marker overlaps the polyline, polyline width gets bigger and marker position gets updated,
        //else, polyline width remains the same
        if(PolyUtil.isLocationOnEdge(marker.getPosition(), polyline.getPoints(), true, TOLERANCE_IN_METERS)) {
            polyline.setWidth(WIDTH * 3);
            positionOnPolyline = new LatLng(marker.getPosition().latitude, marker.getPosition().longitude);
        } else {
            polyline.setWidth(WIDTH);
        }
    }

    @Override
    public void onMarkerDragEnd(Marker marker) {
        //We set the marker to its last known position over the polyline
        marker.setPosition(positionOnPolyline);
        //We set polyline width to its original
        polyline.setWidth(WIDTH);
    }

}