高德地图模块架构的封装

2019-04-12  本文已影响0人  Peakmain

ILbsLayer:接口封装

public interface ILbsLayer {

    /**
     *  获取地图
     */
    View getMapView();

    /**
     *  设置位置变化监听
     */
    void setLocationChangeListener(CommonLocationChangeListener locationChangeListener);

    /**
     *  设置定位图标
     */
    void setLocationRes(int res);
    /**
     *  添加,更新标记点,包括位置、角度(通过 id 识别)
     */
    void addOrUpdateMarker(LocationInfo locationInfo, Bitmap bitmap);

    /**
     * 添加多窗体气泡效果
     */
    void addPoiOverlay(List<LocationInfo> locationInfo);

    /**
     *   获取当前城市
     */
    String getCity();

    /**
     * 联动搜索附近的位置
     */
    void poiSearch(String key, OnSearchedListener listener);

    /**
     * 绘制两点之间行车路径
     * @param start 开始的位置
     * @param end 结束的位置
     * @param color 颜色
     * @param listener 事件
     */
    void driverRoute(LocationInfo start,
                     LocationInfo end,
                     int color,
                     OnRouteCompleteListener listener);

    /**
     *  生命周期函数
     */

    void onCreate(Bundle state);
    void onResume();
    void onSaveInstanceState(Bundle outState);
    void onPause();
    void onDestroy();

    void clearAllMarkers();


    interface CommonLocationChangeListener {
        void onLocationChanged(LocationInfo locationInfo);
        void onLocation(LocationInfo locationInfo);
    }
    /**
     * POI 搜索结果监听器
     */
    interface OnSearchedListener {
        void onSearched(List<LocationInfo> results);

        void onError(int rCode);
    }
    /**
     * 路径规划完成监听
     */
    interface OnRouteCompleteListener {
        void onComplete(RouteInfo result);
    }

    /**
     *  移动相机到两点之间的视野范围
     */
    void moveCamera(LocationInfo locationInfo1,
                    LocationInfo locationInfo2);

    /**
     *  移动动相机到某个点,
     * @param locationInfo
     * @param scale 缩放系数
     */
    void moveCameraToPoint(LocationInfo locationInfo, int scale);

}

LocationInfo:经纬度等信息封装

public class LocationInfo {
    private String key;
    private String  name;
    private double  latitude;
    private double longitude;
    private float rotation;
    private String time;
    private String oil;

    public String getTime() {
        return time;
    }

    public void setTime(String time) {
        this.time = time;
    }

    public String getOil() {
        return oil;
    }

    public void setOil(String oil) {
        this.oil = oil;
    }

    public LocationInfo(double latitude, double longitude, String time, String oil) {
        this.latitude = latitude;
        this.longitude = longitude;
        this.time = time;
        this.oil = oil;
    }

    public LocationInfo(double latitude, double longitude) {
        this.latitude = latitude;
        this.longitude = longitude;
    }

    public float getRotation() {
        return rotation;
    }

    public void setRotation(float rotation) {
        this.rotation = rotation;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongitude() {
        return longitude;
    }

    public void setLongitude(double longitude) {
        this.longitude = longitude;
    }

    @Override
    public String toString() {
        return "LocationInfo{" +
                "name='" + name + '\'' +
                ", latitude=" + latitude +
                ", longitude=" + longitude +
                '}';
    }
}

RouteInfo路线等封装

public class RouteInfo {
    /**
     * 两点之间的距离
     */
    private float distance;

    /**
     * 预计行车时间
     */

    private int duration;

    public float getDistance() {
        return distance;
    }

    public void setDistance(float distance) {
        this.distance = distance;
    }


    public int getDuration() {
        return duration;
    }

    public void setDuration(int duration) {
        this.duration = duration;
    }

    @Override
    public String toString() {
        return "RouteInfo{" +
                "distance=" + distance +
                ", duration=" + duration +
                '}';
    }
}

SensorEventHelper帮助类

public class SensorEventHelper implements SensorEventListener {

    private SensorManager mSensorManager;
    private Sensor mSensor;
    private long lastTime = 0;
    private final int TIME_SENSOR = 100;
    private float mAngle;
    private Context mContext;
    private Marker mMarker;

    public SensorEventHelper(Context context) {
        mContext = context;
        mSensorManager = (SensorManager) context
                .getSystemService(Context.SENSOR_SERVICE);
        mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

    }

    public void registerSensorListener() {
        mSensorManager.registerListener(this, mSensor,
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    public void unRegisterSensorListener() {
        mSensorManager.unregisterListener(this, mSensor);
    }

    public void setCurrentMarker(Marker marker) {
        mMarker = marker;
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        

    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (System.currentTimeMillis() - lastTime < TIME_SENSOR) {
            return;
        }
        switch (event.sensor.getType()) {
            case Sensor.TYPE_ORIENTATION: {
                float x = event.values[0];
                x += getScreenRotationOnPhone(mContext);
                x %= 360.0F;
                if (x > 180.0F)
                    x -= 360.0F;
                else if (x < -180.0F)
                    x += 360.0F;

                if (Math.abs(mAngle - x) < 3.0f) {
                    break;
                }
                mAngle = Float.isNaN(x) ? 0 : x;
                if (mMarker != null) {
                    mMarker.setRotateAngle(360 - mAngle);
                }
                lastTime = System.currentTimeMillis();
            }
            default:
                break;
        }

    }

    public static int getScreenRotationOnPhone(Context context) {
        final Display display = ((WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

        switch (display.getRotation()) {
            case Surface.ROTATION_0:
                return 0;

            case Surface.ROTATION_90:
                return 90;

            case Surface.ROTATION_180:
                return 180;

            case Surface.ROTATION_270:
                return -90;
            default:
                break;
        }
        return 0;
    }
}

GaodeLbsLayerImpl高德地图封装类

import static android.R.attr.rotation;

/**
 * author :Peakmain
 * createTime:2019/4/12
 * mail:2726449200@qq.com
 * describe:
 */

public class GaodeLbsLayerImpl implements ILbsLayer {
    public static final String TAG = GaodeLbsLayerImpl.class.getSimpleName();
    private static final String KEY_MY_MARKERE = "1000";
    private Context mContext;
    //位置定位对象
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    // 地图视图对象
    private MapView mapView;
    // 地图管理对象
    private AMap aMap;
    // 地图位置变化回调对象
    private LocationSource.OnLocationChangedListener mMapLocationChangeListener;
    private boolean firstLocation = true;
    private SensorEventHelper mSensorHelper;
    private CommonLocationChangeListener mLocationChangeListener;
    private MyLocationStyle myLocationStyle;
    // 管理地图标记集合
    private Map<String, Marker> markerMap = new HashMap<>();

    //当前城市
    private String mCity;
    // 路径查询对象
    private RouteSearch mRouteSearch;
    private Marker marker;

    public GaodeLbsLayerImpl(Context context) {
        // 创建地图对象
        mapView = new MapView(context);
        // 获取地图管理器
        aMap = mapView.getMap();
        // 创建定位对象
        mlocationClient = new AMapLocationClient(context);
        mLocationOption = new AMapLocationClientOption();
        //设置为高精度定位模式
        mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
        //设置定位参数
        mlocationClient.setLocationOption(mLocationOption);

        // 传感器对象
        mSensorHelper = new SensorEventHelper(context);
        mSensorHelper.registerSensorListener();
        mContext = context;

    }

    @Override
    public View getMapView() {
        return mapView;
    }

    @Override
    public void setLocationChangeListener(CommonLocationChangeListener locationChangeListener) {
        mLocationChangeListener = locationChangeListener;
    }

    @Override
    public void setLocationRes(int res) {
        myLocationStyle = new MyLocationStyle();
        // 设置小蓝点的图标
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory
                .fromResource(res));
        // 设置圆形的边框颜色
        myLocationStyle.strokeColor(Color.BLACK);
        // 设置圆形的填充颜色
        myLocationStyle.radiusFillColor(Color.argb(100, 0, 0, 180));
        // myLocationStyle.anchor(int,int)//设置小蓝点的锚点
        // 设置圆形的边框粗细
        myLocationStyle.strokeWidth(1.0f);
    }

    @Override
    public void addOrUpdateMarker(LocationInfo locationInfo, Bitmap bitmap) {
        if (markerMap == null) {
            markerMap = new HashMap<>();
        }
        Marker storedMarker = markerMap.get(locationInfo.getKey());
        LatLng latLng = new LatLng(locationInfo.getLatitude(), locationInfo.getLongitude());
        if (storedMarker != null) {
            // 如果已经存在则更新角度、位置
            storedMarker.setPosition(latLng);
            storedMarker.setRotateAngle(locationInfo.getRotation());
        } else {
            // 如果不存在则创建
            MarkerOptions options = new MarkerOptions();
            BitmapDescriptor des = BitmapDescriptorFactory.fromBitmap(bitmap);
            options.icon(des);
            options.anchor(0.5f, 0.5f);
            options.position(latLng);
            Marker marker = aMap.addMarker(options);
            marker.setRotateAngle(rotation);
            markerMap.put(locationInfo.getKey(), marker);
            if (KEY_MY_MARKERE.equals(locationInfo.getKey())) {
                // 传感器控制我的位置标记的旋转角度
                mSensorHelper.setCurrentMarker(marker);
            }
        }
    }

    @Override
    public void addPoiOverlay(List<LocationInfo> locationInfos) {
        for (LocationInfo locationInfo : locationInfos) {
            LatLng latlng = new LatLng(locationInfo.getLatitude(), locationInfo.getLongitude());
            MarkerOptions markerOption = new MarkerOptions().icon(BitmapDescriptorFactory
                    .fromView(getBitmapView(mContext, locationInfo)))
                    .position(latlng)
                    .title(locationInfo.getTime())
                    .snippet(locationInfo.getOil())
                    .draggable(false);
            marker = aMap.addMarker(markerOption);
            marker.setObject(locationInfo);
            marker.showInfoWindow();
        }
    }

    //自定义布局,解决只显示最后一个的问题
    private View getBitmapView(Context context, LocationInfo locationInfo) {
        LayoutInflater factory = LayoutInflater.from(context);
        View view = factory.inflate(R.layout.custom_info_window, null);
        TextView tvTitle = (TextView) view.findViewById(R.id.tv_title);
        TextView tvSnippet = (TextView) view.findViewById(R.id.tv_snippet);
        tvTitle.setText(locationInfo.getTime());
        tvSnippet.setText(locationInfo.getOil());
        return view;

    }

    @Override
    public String getCity() {
        return mCity;
    }

    /**
     * 高德地图POI搜索接口
     */
    @Override
    public void poiSearch(String key, final OnSearchedListener listener) {
        if (!TextUtils.isEmpty(key)) {
            // 1 组装关键字
            InputtipsQuery inputQuery = new InputtipsQuery(key, "");
            Inputtips inputTips = new Inputtips(mContext, inputQuery);
            // 2 开始异步搜索
            inputTips.requestInputtipsAsyn();
            // 3 监听处理搜索结果
            inputTips.setInputtipsListener(new Inputtips.InputtipsListener() {
                @Override
                public void onGetInputtips(List<Tip> tipList, int rCode) {
                    if (rCode == AMapException.CODE_AMAP_SUCCESS) {
                        // 正确返回解析结果
                        List<LocationInfo> locationInfos = new ArrayList<LocationInfo>();

                        for (int i = 0; i < tipList.size(); i++) {
                            Tip tip = tipList.get(i);
                            if (tip.getPoint() != null) {
                                LocationInfo locationInfo =
                                        new LocationInfo(tip.getPoint().getLatitude(),
                                                tip.getPoint().getLongitude());
                                locationInfo.setName(tip.getName());
                                locationInfos.add(locationInfo);
                            }
                        }
                        listener.onSearched(locationInfos);
                    } else {
                        listener.onError(rCode);
                    }
                }
            });

        }
    }

    /**
     * 两点之间行车路径
     *
     * @param start    开始的位置
     * @param end      结束的位置
     * @param color    颜色
     * @param listener 事件
     */
    @Override
    public void driverRoute(LocationInfo start, LocationInfo end, final int color, final OnRouteCompleteListener listener) {
        // 1 组装起点和终点信息
        LatLonPoint startLatLng =
                new LatLonPoint(start.getLatitude(), start.getLongitude());
        LatLonPoint endLatLng =
                new LatLonPoint(end.getLatitude(), end.getLongitude());
        final RouteSearch.FromAndTo fromAndTo =
                new RouteSearch.FromAndTo(startLatLng, endLatLng);
        // 2 创建路径查询参数,
        // 第一个参数表示路径规划的起点和终点,
        // 第二个参数表示驾车模式,
        // 第三个参数表示途经点,
        // 第四个参数表示避让区域,
        // 第五个参数表示避让道路
        RouteSearch.DriveRouteQuery query =
                new RouteSearch.DriveRouteQuery(fromAndTo,
                        RouteSearch.DrivingDefault,
                        null,
                        null,
                        "");
        //  3 创建搜索对象,异步路径规划驾车模式查询
        if (mRouteSearch == null) {
            mRouteSearch = new RouteSearch(mContext);
        }
        // 4 执行搜索
        mRouteSearch.calculateDriveRouteAsyn(query);
        mRouteSearch.setRouteSearchListener(new RouteSearch.OnRouteSearchListener() {
            @Override
            public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

            }

            @Override
            public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {
                // 1 获取第一条路径
                DrivePath drivePath = driveRouteResult.getPaths()
                        .get(0);
                /**
                 * 2 获取这条路径上所有的点,使用 Polyline 绘制路径
                 */
                PolylineOptions polylineOptions = new PolylineOptions();
                polylineOptions.color(color);
                // 起点
                LatLonPoint startPoint = driveRouteResult.getStartPos();
                // 路径中间步骤
                List<DriveStep> drivePaths = drivePath.getSteps();
                // 路径终点
                LatLonPoint endPoint = driveRouteResult.getTargetPos();
                // 添加起点
                polylineOptions.add(new LatLng(startPoint.getLatitude(),
                        startPoint.getLongitude()));

                /**
                 * 添加中间节点
                 */
                for (DriveStep step : drivePaths) {
                    List<LatLonPoint> latlonPoints = step.getPolyline();
                    for (LatLonPoint latlonpoint : latlonPoints) {
                        LatLng latLng =
                                new LatLng(latlonpoint.getLatitude(), latlonpoint.getLongitude());
                        polylineOptions.add(latLng);

                    }
                }
                // 添加终点
                polylineOptions.add(new LatLng(endPoint.getLatitude(), endPoint.getLongitude()));
                // 执行绘制
                aMap.addPolyline(polylineOptions);
                /**
                 * 3 回调业务
                 */
                if (listener != null) {

                    RouteInfo info = new RouteInfo();
                    //info.setTaxiCost(driveRouteResult.getTaxiCost());
                    info.setDuration(10 + new Long(drivePath.getDuration() / 1000 * 60).intValue());
                    info.setDistance(0.5f + drivePath.getDistance() / 1000);
                    listener.onComplete(info);
                }

            }

            @Override
            public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

            }

            @Override
            public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

            }
        });
    }

    @Override
    public void onCreate(Bundle savedState) {
        mapView.onCreate(savedState);
        setUpMap();
    }

    private void setUpMap() {

        if (myLocationStyle != null) {
            aMap.setMyLocationStyle(myLocationStyle);
        }

        // 设置地图激活(加载监听)
        aMap.setLocationSource(new LocationSource() {
            @Override
            public void activate(OnLocationChangedListener onLocationChangedListener) {
                mMapLocationChangeListener = onLocationChangedListener;
                Log.e("TAG", "activate");
            }

            @Override
            public void deactivate() {

                if (mlocationClient != null) {
                    mlocationClient.stopLocation();
                    mlocationClient.onDestroy();
                }
                mlocationClient = null;
            }
        });
        // 设置默认定位按钮是否显示,这里先不想业务使用方开放
        aMap.getUiSettings().setMyLocationButtonEnabled(false);
        // 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false,这里先不想业务使用方开放
        aMap.setMyLocationEnabled(true);


    }

    public void setUpLocation() {

        //设置监听器

        mlocationClient.setLocationListener(new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {
                // 定位变化位置
                if (mMapLocationChangeListener != null) {
                    //  当前城市
                    mCity = aMapLocation.getCity();
                    String address = aMapLocation.getAddress();
                    // 地图已经激活,通知蓝点实时更新
                    mMapLocationChangeListener.onLocationChanged(aMapLocation);// 显示系统小蓝点
                    Log.e(TAG, "onLocationChanged");
                    LocationInfo locationInfo = new LocationInfo(aMapLocation.getLatitude(),
                            aMapLocation.getLongitude());
                    locationInfo.setName(aMapLocation.getPoiName());
                    locationInfo.setKey(KEY_MY_MARKERE);
                    if (firstLocation) {
                        firstLocation = false;
                        moveCameraToPoint(locationInfo, 17);
                        if (mLocationChangeListener != null) {

                            mLocationChangeListener.onLocation(locationInfo);
                        }


                    }
                    if (mLocationChangeListener != null) {

                        mLocationChangeListener.onLocationChanged(locationInfo);
                    }
                }
            }
        });
        mlocationClient.startLocation();
    }

    /**
     * 缩放相机
     *
     * @param locationInfo 位置信息
     * @param scale        缩放
     */
    @Override
    public void moveCameraToPoint(LocationInfo locationInfo, int scale) {
        LatLng latLng = new LatLng(locationInfo.getLatitude(),
                locationInfo.getLongitude());
        CameraUpdate up = CameraUpdateFactory.newCameraPosition(new CameraPosition(
                latLng, scale, 30, 30));
        aMap.moveCamera(up);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        mapView.onSaveInstanceState(outState);

    }

    @Override
    public void onResume() {
        mapView.onResume();
        setUpLocation();
    }

    @Override
    public void onPause() {
        mapView.onPause();
        mlocationClient.stopLocation();
    }

    @Override
    public void onDestroy() {
        mapView.onDestroy();
        mlocationClient.onDestroy();
    }

    @Override
    public void clearAllMarkers() {
        aMap.clear();
        markerMap.clear();
    }

    @Override
    public void moveCamera(LocationInfo locationInfo1, LocationInfo locationInfo2) {
        try {
            LatLng latLng =
                    new LatLng(locationInfo1.getLatitude(),
                            locationInfo1.getLongitude());
            LatLng latLng1 =
                    new LatLng(locationInfo2.getLatitude(),
                            locationInfo2.getLongitude());
            LatLngBounds.Builder b = LatLngBounds.builder();
            b.include(latLng);
            b.include(latLng1);
            LatLngBounds latLngBounds = b.build();
            aMap.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 100));
        } catch (Exception e) {
            Log.e(TAG, "moveCamera: " + e.getMessage());
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读