返回

用好Marker实现Android高德SDK地图起点选择

Android

如何使用高德地图实现起点选择:一个详细指南

导航的地图,选择起点

移动地图应用中,起点选择是用户常用的功能,它可以帮助用户快速规划路线,获取导航信息。本文将重点介绍如何使用高德地图Android SDK中的Marker实现起点选择,涵盖获取地图控件中心点的像素坐标、根据坐标获取POI信息以及在移动地图和停止移动时控制信息窗口的显示和隐藏。

获取地图控件中心点的像素坐标

要实现起点选择,首先需要获取地图控件中心点的像素坐标。高德地图Android SDK提供了Projection类,它可以将经纬度坐标转换为像素坐标。代码如下:

Projection projection = aMap.getProjection();
Point point = projection.toScreenLocation(centerLatLng);
int x = point.x;
int y = point.y;

其中,aMap是地图控件对象,centerLatLng是地图控件中心点的经纬度坐标,point是转换后的像素坐标,xy分别是像素坐标的横纵坐标。

根据坐标获取POI信息

获取了地图控件中心点的像素坐标后,就可以根据这些坐标获取POI信息。高德地图Android SDK提供了SearchManager类,它可以根据像素坐标进行POI搜索。代码如下:

SearchManager searchManager = new SearchManager(context);
List<SearchPoiResult> poiResultList = searchManager.searchInBounds(new Rect(x - radius, y - radius, x + radius, y + radius), 0);

其中,context是当前上下文对象,radius是搜索半径,poiResultList是搜索结果列表。

在移动地图和停止移动时控制信息窗口的显示和隐藏

为了提供更好的用户体验,当地图移动时,需要隐藏信息窗口;当地图停止移动时,需要显示信息窗口并加载数据。高德地图Android SDK提供了OnMapTouchListener接口,它可以监听地图的触摸事件。代码如下:

aMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {
    @Override
    public void onTouch(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                hideInfoWindow();
                break;
            case MotionEvent.ACTION_UP:
                showInfoWindow();
                break;
        }
    }
});

其中,hideInfoWindow()showInfoWindow()方法分别用于隐藏和显示信息窗口。

示例代码

以下是实现Marker起点选择的完整示例代码:

import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;

import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapFragment;
import com.amap.api.maps2d.Projection;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.search.SearchManager;
import com.amap.api.search.SearchPoiResult;

public class MainActivity extends FragmentActivity {

    private AMap aMap;
    private Marker marker;
    private SearchManager searchManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
        aMap = mapFragment.getMap();
        searchManager = new SearchManager(this);
        initMarker();
        setCameraChangeListener();
        setInfoWindowClickListener();
        setOnMapTouchListener();
    }

    private void initMarker() {
        LatLng latLng = new LatLng(39.908448, 116.397511);
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker));
        markerOptions.draggable(true);
        marker = aMap.addMarker(markerOptions);
    }

    private void setCameraChangeListener() {
        aMap.setOnCameraChangeListener(new AMap.OnCameraChangeListener() {
            @Override
            public void onCameraChange(CameraPosition cameraPosition) {
                updateMarkerPosition(cameraPosition.target);
            }

            @Override
            public void onCameraChangeFinish(CameraPosition cameraPosition) {
                showInfoWindow();
            }
        });
    }

    private void setInfoWindowClickListener() {
        marker.setInfoWindowClickListener(new InfoWindowAdapter() {
            @Override
            public View getInfoWindow(Marker marker) {
                return null;
            }

            @Override
            public View getInfoContents(Marker marker) {
                return null;
            }
        });
    }

    private void setOnMapTouchListener() {
        aMap.setOnMapTouchListener(new AMap.OnMapTouchListener() {
            @Override
            public void onTouch(MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        hideInfoWindow();
                        break;
                    case MotionEvent.ACTION_UP:
                        showInfoWindow();
                        break;
                }
            }
        });
    }

    private void updateMarkerPosition(LatLng latLng) {
        Projection projection = aMap.getProjection();
        Point point = projection.toScreenLocation(latLng);
        int radius = 100;
        List<SearchPoiResult> poiResultList = searchManager.searchInBounds(new Rect(point.x - radius, point.y - radius, point.x + radius, point.y + radius), 0);
        if (poiResultList.size() > 0) {
            marker.setTitle(poiResultList.get(0).getTitle());
            marker.setSnippet(poiResultList.get(0).getSnippet());
        }
        marker.setPosition(latLng);
    }

    private void showInfoWindow() {
        marker.showInfoWindow();
    }

    private void hideInfoWindow() {
        marker.hideInfoWindow();
    }
}

结论

本文详细介绍了如何使用高德地图Android SDK中的Marker实现起点选择,包括获取地图控件中心点的像素坐标、根据坐标获取POI信息以及在移动地图和停止移动时控制信息窗口的显示和隐藏。通过掌握这些技术,开发者可以轻松为自己的地图应用添加起点选择功能,提升用户体验。

常见问题解答

1. 如何获取地图控件的中心点?

使用Projection类的toScreenLocation()方法可以将地图控件的中心点经纬度坐标转换为像素坐标。

2. 如何根据坐标获取POI信息?

使用SearchManager类的searchInBounds()方法可以根据像素坐标进行POI搜索。

3. 如何在移动地图和停止移动时控制信息窗口的显示和隐藏?

使用OnMapTouchListener接口可以监听地图的触摸事件,从而控制信息窗口的显示和隐藏。

4. 如何自定义信息窗口的内容?

使用Marker类的setInfoWindowAdapter()方法可以自定义信息窗口的内容。

5. 如何实现Marker的拖拽?

在创建Marker时将draggable()设置为true即可实现Marker的拖拽。