做Android开发经常会使用到地图,我一般会选择百度地图,因为用得比较多。百度地图一般会用到地图显示坐标点,我之前做过几次,也用到了点聚合等功能。本文主要是我从后台获取坐标集合,显示在地图上的一个例子。
请求后台,我这里主要用到了retrofit2.0+Rxjava,这是我获取retrofitClient的代码:
public RetrofitApi getSSLRetrofit(Context context,ClientType type){ OkHttpClient client = null; try { InputStream inputStream = context.getAssets().open(".cer"); client = new HttpsUtils().getSSLClient(inputStream);//证书验证 // setCertificates(client,inputStream); } catch (IOException e) { e.printStackTrace(); client = new OkHttpClient(); } if (mRetrofitApi == null){ Retrofit retrofit = new Retrofit.Builder() .baseUrl(Appcontext.TEST_BASE_HTTP) .client(client) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(new GsonBuilder().setLenient().create())) .build(); mRetrofitApi = retrofit.create(RetrofitApi.class); } return mRetrofitApi; }
因为用到了Https,所以加了自定义的证书验证。然后是数据请求:
Subscription subscription = ApiManager.getInstence().getSSLRetrofit(getApplicationContext(), ClientType.TYPE_HTTPSUTILS) .getStationcall(json) .map(new Func1<ResultData, List<Station>>() { @Override public List<Station> call(ResultData resultData) { return resultData.getSiteList();//这里使用了一个过滤,将坐标集合从请求的结果取出来 } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Subscriber<List<Station>>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(List<Station> resultDatas) { if (bikeStation==null){ bikeStation = new BikeStationOverlays(mBaiduMap); } if (mBaiduMap!=null){ bikeStation.removeFromMap(); bikeStation.clear(); } for (Station station : resultDatas) { overlayOption = new MarkerOptions() .position(new LatLng(station.getStationLat(),station.getStationLng())) .icon(mMapMarker);//配置坐标图标 bikeStation.addOverlay(overlayOption);//添加单个坐标到集合中 } bikeStation.addToMap();//添加坐标到地图上 } });
这里面是用到了一个BikeStationOverlays,是OverlayManager的一个子类:
private class BikeStationOverlays extends OverlayManager{ ArrayList<OverlayOptions> overlayOptions = new ArrayList<OverlayOptions>(); public BikeStationOverlays(BaiduMap baiduMap) { super(baiduMap); } public void addOverlay(OverlayOptions option){ overlayOptions.add(option);//添加需要操作的overlay点 } public void clear(){ overlayOptions.clear(); } @Override public List<OverlayOptions> getOverlayOptions() { return overlayOptions;//获取到要操作的overlay点 } @Override public boolean onMarkerClick(Marker marker) { return false;//这里可以添加Marker点击事件 } @Override public boolean onPolylineClick(Polyline polyline) { return false; } }
在界面销毁时可以调用bikeStation.clear();清理坐标,也可以在加载新坐标之前,清理上次加载的坐标。顺便看一下OverlayManager:
public abstract class OverlayManager implements OnMarkerClickListener, OnPolylineClickListener { BaiduMap mBaiduMap = null; private List<OverlayOptions> mOverlayOptionList = null; List<Overlay> mOverlayList = null; /** * 通过一个BaiduMap 对象构造 * * @param baiduMap */ public OverlayManager(BaiduMap baiduMap) { mBaiduMap = baiduMap; // mBaiduMap.setOnMarkerClickListener(this); if (mOverlayOptionList == null) { mOverlayOptionList = new ArrayList<OverlayOptions>(); } if (mOverlayList == null) { mOverlayList = new ArrayList<Overlay>(); } } /** * 覆写此方法设置要管理的Overlay列表 * * @return 管理的Overlay列表 */ public abstract List<OverlayOptions> getOverlayOptions(); /** * 将所有Overlay 添加到地图上 */ public final void addToMap() { if (mBaiduMap == null) { return; } removeFromMap(); List<OverlayOptions> overlayOptions = getOverlayOptions(); if (overlayOptions != null) { mOverlayOptionList.addAll(getOverlayOptions()); } for (OverlayOptions option : mOverlayOptionList) { mOverlayList.add(mBaiduMap.addOverlay(option)); } } /** * 将所有Overlay 从 地图上消除 */ public final void removeFromMap() { if (mBaiduMap == null) { return; } for (Overlay marker : mOverlayList) { marker.remove(); } mOverlayOptionList.clear(); mOverlayList.clear(); } /** * 缩放地图,使所有Overlay都在合适的视野内 * <p> * 注: 该方法只对Marker类型的overlay有效 * </p> * */ public void zoomToSpan() { if (mBaiduMap == null) { return; } if (mOverlayList.size() > 0) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (Overlay overlay : mOverlayList) { // polyline 中的点可能太多,只按marker 缩放 if (overlay instanceof Marker) { builder.include(((Marker) overlay).getPosition()); } } mBaiduMap.setMapStatus(MapStatusUpdateFactory .newLatLngBounds(builder.build())); } } }