高德地图 java_几行代码实现高德地图的高级用法

前段时间搞高德地图,集成地图后,发现如果把地图这块放在view里面,不便于后期的维护,想着封装一个,把地图有关的方法,专门放一个类,同时也方便以后的偷懒☺.Let's Go!

1c5840c01be3

显示地图

1c5840c01be3

public class MapActivity extends AppCompatActivity {

@InjectView(R.id.mapView)

MapView mMapView;

private AMap aMap;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_map);

// 使用黄油刀注解找控件

ButterKnife.inject(this);

initMap(savedInstanceState);

}

private void initMap(Bundle savedInstanceState) {

mMapView.onCreate(savedInstanceState);

aMap = null;

if (aMap == null) {

aMap = mMapView.getMap();

}

// 显示地图

MapUtil.getInstance().initMap(aMap, this);

}

@Override

public void onDestroy() {

super.onDestroy();

// 在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图

mMapView.onDestroy();

}

@Override

public void onResume() {

super.onResume();

// 在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图

mMapView.onResume();

}

@Override

public void onPause() {

super.onPause();

// 在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制

mMapView.onPause();

}

@Override

public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

// 在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态

mMapView.onSaveInstanceState(outState);

}

}

除了地图相关的配置外,你只需要 MapUtil.getInstance().initMap(aMap, this);一行代码就可以实现,够简洁吧!下面我们看下,内部的实现

// 单例没啥好说的

private static MapUtil sMapUtil;

private LatLng mLatLng;

private MapUtil() {

}

![![微信图片_20180519135100.jpg](https://upload-images.jianshu.io/upload_images/5286943-34dfb6ace9ea966b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

](https://upload-images.jianshu.io/upload_images/5286943-5ea74273e21ca41f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

public static MapUtil getInstance() {

if (sMapUtil == null) {

synchronized (MapUtil.class) {

if (sMapUtil == null) {

sMapUtil = new MapUtil();

}

}

}

return sMapUtil;

}

// 初始化地图,关键代码

public MapUtil initMap(AMap aMap, Context context) {

this.aMap = aMap;

this.mContext = context;

mlocationClient = new AMapLocationClient(context);

//初始化定位参数

mLocationOption = new AMapLocationClientOption();

//设置定位监听

mlocationClient.setLocationListener(this);

//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式

mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);

//设置定位间隔,单位毫秒,默认为2000ms

mLocationOption.setInterval(3000);

//设置定位参数

mlocationClient.setLocationOption(mLocationOption);

// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,

// 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求

// 在定位结束后,在合适的生命周期调用onDestroy()方法

// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除

//启动定位

mlocationClient.startLocation();

// TODO: 2018/5/13 地图的层级大小,可以对外暴露

aMap.moveCamera(CameraUpdateFactory.zoomTo(19));

// 显示定位蓝点

initPoint();

// 去掉右边缩放按钮

aMap.getUiSettings().setZoomControlsEnabled(false);

aMap.setOnCameraChangeListener(this);

return this;

}

// 自定义定位蓝点

public void initPoint() {

MyLocationStyle myLocationStyle;

myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。

myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。

// 设置边框的颜色

myLocationStyle.strokeColor(Color.TRANSPARENT);

// 设置边框的填充色

myLocationStyle.radiusFillColor(Color.TRANSPARENT);

// 设置定位点图片

myLocationStyle.myLocationIcon(getBitmapDescriptor(R.mipmap.icon_location_blue));

// 定位一次,且将视角移动到地图中心点

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);

aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style

//aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。

aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。

// 因为模式问题,所以要手动调用

if (mLatLng != null) {

aMap.moveCamera(CameraUpdateFactory.changeLatLng(mLatLng));

}

}

绘制Marker点

1c5840c01be3

private void initMap(Bundle savedInstanceState) {

mMapView.onCreate(savedInstanceState);

aMap = null;

if (aMap == null) {

aMap = mMapView.getMap();

}

// 显示地图,设置地图回调

MapUtil.getInstance().initMap(aMap, this).setMapRefreshListener(this);

}

public void drawMarker(LatLng latLng) {

// 模拟数据集合

List markerList = new ArrayList<>();

for (int i = 0; i < 4; i++) {

double longitude = latLng.longitude + ((i + 1) * 0.0001);

double latitude = latLng.latitude + ((i + 1) * 0.0001);

markerList.add(new LatLng(latitude, longitude));

}

// 绘制Marker集合

MapUtil.getInstance().addAllMarker(markerList);

// 绘制Marker点

MapUtil.getInstance().addMarker(latLng);

}

/**

* 得到经纬度

* @param latLng

*/

@Override

public void getLatLng(LatLng latLng) {

// 绘制marker

drawMarker(latLng);

}

MapUtil

public void addAllMarker(List latLngList) {

for (LatLng latLng : latLngList) {

addMarker(latLng);

}

}

public void addMarker(LatLng latLng) {

MarkerOptions markerOptions = new MarkerOptions();

markerOptions.position(latLng);

// TODO: 2018/5/13 如果是复杂的,可以把布局转成bitmap

// View view = View.inflate(mContext, R.layout.marker, null);

// Bitmap bitmap = convertViewToBitmap(view);

// 自定义图片

markerOptions.icon(BitmapDescriptorFactory.fromBitmap(BitmapFactory

.decodeResource(mContext.getResources(), R.mipmap.icon_taskcar_get)));

// markerOptions.icon(BitmapDescriptorFactory.fromBitmap(bitmap));

Marker marker = aMap.addMarker(markerOptions);

mMarkerSparseArray.put(mMarkerSparseArray.size(), marker);

marker.showInfoWindow();

// 是否需要显示弹窗

infoWindow();

}

Marker点的点击事件

1c5840c01be3

我就是怎么强大

// 由于第一次点击也会走地图的回调,所以要加个开关

private boolean toggle = false;

// 定义 Marker [图片上传中...(31bcedde8ed5d0abf39d165177c83736.gif-b70360-1526708414566-0)]

点击事件监听

AMap.OnMarkerClickListener markerClickListener = new AMap.OnMarkerClickListener() {

// marker 对象被点击时回调的接口

// 返回 true 则表示接口已响应事件,否则返回false

@Override

public boolean onMarkerClick(Marker marker) {

mMarker = marker;

toggle = true;

MapUtil.getInstance().addInfoWindow(marker);

return false;

}

};

private void initMap(Bundle savedInstanceState) {

mMapView.onCreate(savedInstanceState);

// 使用黄油刀注解找控件

aMap = null;

if (aMap == null) {

aMap = mMapView.getMap();

}

// 显示地图,设置地图回调

MapUtil.getInstance().initMap(aMap, this).setMapRefreshListener(this);

// 实现地图的监听

aMap.setOnMapClickListener(new AMap.OnMapClickListener() {

@Override

public void onMapClick(LatLng latLng) {

if (!toggle && mMarker != null) {

MapUtil.getInstance().removeInfoWindow(mMarker);

mMarker = null;

}

toggle = false;

}

});

// 实现marker的监听

aMap.setOnMarkerClickListener(markerClickListener);

}

MapUtil

/**

* 添加移除infoWindow

* @param marker

*/

public void addInfoWindow(Marker marker) {

marker.setInfoWindowEnable(true);

}

/**

* 移除infoWindow

* @param marker

*/

public void removeInfoWindow(Marker marker) {

marker.setInfoWindowEnable(false);

}

绘制矩形

1c5840c01be3

/**

* 得到经纬度

*

* @param latLng

*/

@Override

public void getLatLng(LatLng latLng) {

// 绘制marker

drawMarker(latLng);

// 绘制线

drawRectangle(latLng);

}

private void drawRectangle(LatLng latLng) {

MapUtil.getInstance().addRectangle(latLng);

}

MapUtil

public void addRectangle(LatLng latLng) {

// 绘制一个长方形

aMap.addPolygon(new PolygonOptions()

.addAll(createRectangle(latLng, 0.0001, 0.0001))

.fillColor(Color.parseColor("#FFCBCB"))

// 线的宽度取消

.strokeWidth(0)

);

// 虚线组成一个长方形

aMap.addPolyline(new PolylineOptions()

.addAll(createRectangle(latLng, 0.0001, 0.0001))

.width(10)

.setDottedLine(true)

.color(Color.parseColor("#F45A5A")));

}

public void addRectangle(List latLngList) {

// 绘制一个长方形

aMap.addPolygon(new PolygonOptions()

.addAll(latLngList)

.fillColor(Color.parseColor("#4DBDEDFF"))

// 线的宽度取消

.strokeWidth(0)

);

// 虚线组成一个长方形

aMap.addPolyline(new PolylineOptions()

.addAll(latLngList)

.width(10)

.setDottedLine(true)

.color(Color.parseColor("#3BC3F5")));

}

/**

* 生成一个长方形的四个坐标点

*/

private List createRectangle(LatLng center, double halfWidth, double halfHeight) {

List latLngs = new ArrayList();

// TODO: 2018/5/19 添加最后一个点,组成闭合,不然会少一边

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));

// 矩形的四个点

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude - halfWidth));

latLngs.add(new LatLng(center.latitude - halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude + halfWidth));

latLngs.add(new LatLng(center.latitude + halfHeight, center.longitude - halfWidth));

return latLngs;

}

这里要注意:画矩形要给5个点,第一个和最后一个点一样,文档上是4个点,会少一边

移动指定距离刷新地图

@Override

public void onCameraChange(CameraPosition cameraPosition) {

}

@Override

public void onCameraChangeFinish(CameraPosition cameraPosition) {

LatLng currentLatlng = cameraPosition.target;

double distance = AMapUtils.calculateLineDistance(preLatlng, currentLatlng);

totalDistance = distance;

Log.d(TAG, "onCameraChange: 距离" + totalDistance);

if (totalDistance >= REFRESH_DISTANCE) {

if (firstChange) {

firstChange = false;

return;

}

preLatlng = currentLatlng;

Log.d(TAG, "onCameraChange: 要刷新了");

totalDistance = 0;

if (mMapListener != null) {

mMapListener.refresh();

}

}

}

监听地图中心点的位置,和起始点位置,获取距离,如果大于,就把当前点记录,这里要注意的是,刚开始的时候位置会偏移很大,排除第一次的

重置指南针

1c5840c01be3

image

MapActivity没什么好说的

@OnClick(R.id.iv_location)

public void onViewClicked() {

MapUtil.getInstance().initPoint();

}

MapUtil

// 开启指南针

// 初始化地图,关键代码

public MapUtil initMap(AMap aMap, Context context, int getZoomB) {

this.aMap = aMap;

this.mContext = context;

mlocationClient = new AMapLocationClient(context);

//初始化定位参数

mLocationOption = new AMapLocationClientOption();

//设置定位监听

mlocationClient.setLocationListener(this);

//设置定位模式为高精度模式,Battery_Saving为低功耗模式,Device_Sensors是仅设备模式

mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);

//设置定位间隔,单位毫秒,默认为2000ms

mLocationOption.setInterval(3000);

//设置定位参数

mlocationClient.setLocationOption(mLocationOption);

// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,

// 注意设置合适的定位时间的间隔(最小间隔支持为1000ms),并且在合适时间调用stopLocation()方法来取消定位请求

// 在定位结束后,在合适的生命周期调用onDestroy()方法

// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除

//启动定位

mlocationClient.startLocation();

// 显示定位蓝点

initPoint();

// 去掉右边缩放按钮

aMap.getUiSettings().setZoomControlsEnabled(false);

aMap.setOnCameraChangeListener(this);

// 开启指南针

aMap.getUiSettings().setCompassEnabled(true);

return this;

}

// 自定义定位蓝点

public void initPoint() {

MyLocationStyle myLocationStyle;

myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。

myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。

// 设置边框的颜色

myLocationStyle.strokeColor(Color.TRANSPARENT);

// 设置边框的填充色

myLocationStyle.radiusFillColor(Color.TRANSPARENT);

// 设置定位点图片

myLocationStyle.myLocationIcon(getBitmapDescriptor(R.mipmap.icon_location_blue));

// 定位一次,且将视角移动到地图中心点

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);

aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style

//aMap.getUiSettings().setMyLocationButtonEnabled(true);设置默认定位按钮是否显示,非必需设置。

aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。

// 因为模式问题,所以要手动调用

if (mLatLng != null) {

aMap.moveCamera(CameraUpdateFactory.changeLatLng(mLatLng));

}

// 地图的层级大小

aMap.moveCamera(CameraUpdateFactory.zoomTo(getZoomB));

// TODO: 2018/5/21 0021 重置指南针位置,找了好久

if (mLatLng != null) {

float bearing = 0.0f; // 地图默认方向

float tilt = 0.0f; // 地图默认方向

aMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(mLatLng, getZoomB, tilt, bearing)));

}

}

文末:主要提供一种思路,如果有不对或者可以改进的,欢迎下方留言

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值