百度地图AndroidSDK:定位、画区域、线路规划、搜索

参考学习:
百度地图官网:
androidsdk/guide/basicmap - Wiki http://lbsyun.baidu.com/index.php?title=androidsdk/guide/basicmap
很有学习价值!!!
Small_Cake的专栏里对于百度地图的使用做了很详细的介绍
1.深入学习百度地图Android SDK v4.0.0【第一关】基础地图 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52193921
2.深入学习百度地图Android SDK v4.0.0【第二关】公交地图 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52199135
3.深入学习百度地图Android SDK v4.0.0【第三关】路线规划 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52212402
4.深入学习百度地图Android SDK v4.0.0【第四关】OpenGL绘制 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52336116
5.深入学习百度地图Android SDK v4.0.0【第五关】瓦片图层 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52370635
6.深入学习百度地图Android SDK v4.0.0【第六关】室内地图 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52370729
7.深入学习百度地图Android SDK v4.0.0【第七关】周边雷达 - xiaoshubing的专栏 - CSDN博客 http://blog.csdn.net/xiaoshubing/article/details/52412099

注意事项:

1.libs文件夹放入jar包,在main里新建的jniLibs文件夹放入.so文件
2.当开发完进行打包apk时i,安装apk在手机上后,之前是会显示地图的,但现在却不显示地图了,只显示网格,这就说明是百度地图的Key有问题了。开发和打包apk对应的key是不一样的,详情请看:在android studio直接运行时百度地图显示,真机打包apk时地图不显示的问题

接入百度地图SDK:

准备:

1.请好好看看:百度地图官网开发指南
2.在控制台创建应用:获取自己电脑Debug模式下的SHA1值(这个只能是此电脑的开发模式下的使用,所以换个电脑或打包apk都不能正常显示地图,必须换成对应的SHA1,则就必须重新在控制台新建应用,输入对应的SHA1值啦)
3.下载SDKSDK下载 - 百度LBS开放平台 http://lbsyun.baidu.com/index.php?title=sdk/download&action#selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtool,mapsdk_radar

Androidstudio配置:

1.把你下载下来的sdk(文件夹的libs中的)全部拷贝到你app的libs中,比如这样

2.app的gradle:

android{
sourceSets{
        main{
            jniLibs.srcDir 'libs'
            //说明so的路径为该libs路径,关联所有地图SDK的so文件
        }
    }
}
dependencies{
implementation files('libs/BaiduLBS_Android.jar') 引进你所有的jar包
}

3.权限:
记得在程序中要动态申请定位权限才能实现定位等功能哦!

<manifest>
    <!-- 百度地图需要的权限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.GET_TASKS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <!-- 这个权限用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <!-- 这个权限用于访问GPS定位-->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <!-- 获取运营商信息,用于支持提供运营商信息相关的接口-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <!-- 用于读取手机当前的状态-->
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <!-- 访问网络,网络定位需要上网-->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- SD卡读取权限,用户写入离线定位数据-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <application              
        <activity android:name=".MainActivity">            
        </activity>
        <meta-data
            android:name="com.baidu.lbsapi.API_KEY"
            android:value="你的key" />     
        <service
            android:name="com.baidu.location.f"
            android:enabled="true"
            android:process=":remote"/>       
    </application>

</manifest>

具体代码:

BaseApplication:

public class BaseApplication extends Application{   
    @Override
    public void onCreate() {
        super.onCreate();
        SDKInitializer.initialize(this);        
    }   
}

把每一个功能都独立出来了,一个大功能一个界面。
1.公交线路搜索:

1.布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/ed_start_bus_station"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入城市名称"/>
    <EditText
        android:id="@+id/ed_end_bus_station"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入公交路线号"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/tv_choose_bus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="搜索公交路线"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:gravity="center"
            android:layout_weight="1"
            android:textSize="21sp"/>
        <TextView
            android:id="@+id/tv_previous"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="上一个"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:gravity="center"
            android:layout_weight="1"
            android:textSize="21sp"/>
        <TextView
            android:id="@+id/tv_next"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="下一个"
            android:layout_marginLeft="15dp"
            android:layout_marginRight="15dp"
            android:gravity="center"
            android:layout_weight="1"
            android:textSize="21sp"/>
    </LinearLayout>
    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:clickable="true" />
</LinearLayout>

2.activity代码:


/**
 * 公交路线:
 * 根据城市名称、公交路线号,搜索公交路线
 */
public class ActBusLineMap extends AppCompatActivity
        implements OnGetBusLineSearchResultListener, OnGetPoiSearchResultListener {

    @BindView(R.id.map_view)
    MapView mapView;
    @BindView(R.id.ed_start_bus_station)
    EditText edStartBusStation;
    @BindView(R.id.ed_end_bus_station)
    EditText edEndBusStation;
    @BindView(R.id.tv_choose_bus)
    TextView tvChooseBus;
    @BindView(R.id.tv_previous)
    TextView tvPrevious;
    @BindView(R.id.tv_next)
    TextView tvNext;

    private BaiduMap mBaiduMap;

    private PoiSearch poiSearch;
    private BusLineSearch busLineSearch;
    private List<String> busLines = new ArrayList<>();
    private int uidPostion = 0;//当前选中第几条路线
    private BusLineResult mBusLineResult;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_buslinemap);
        ButterKnife.bind(this);

        mBaiduMap = mapView.getMap();

        init();
        onEvent();

    }

    /**
     * 点击事件
     * @param view
     */
    @OnClick({R.id.tv_choose_bus, R.id.tv_previous, R.id.tv_next})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_choose_bus:
                poiSearch.searchInCity(
                        new PoiCitySearchOption().city(
                                edStartBusStation.getText().toString()).keyword(edEndBusStation.getText().toString()));
                break;
            case R.id.tv_previous:
                if (uidPostion>0){
                    uidPostion--;
                    searchBusLine();
                }
                break;
            case R.id.tv_next:
                if (uidPostion<(busLines.size()-1)){
                    uidPostion++;
                    searchBusLine();
                }
                break;
        }
    }

    private void onEvent() {

    }

    public void init() {
        //检索查询初始化并监听
        poiSearch = PoiSearch.newInstance();
        poiSearch.setOnGetPoiSearchResultListener(this);
        //路线查询初始化并监听
        busLineSearch = BusLineSearch.newInstance();
        busLineSearch.setOnGetBusLineSearchResultListener(this);
        //公交路线覆盖物,并设置路线的点击事件
        overlay = new BusLineOverlay(mBaiduMap){
            @Override
            public boolean onBusStationClick(int index) {
                if (mBusLineResult.getStations() != null
                        && mBusLineResult.getStations().get(index) != null) {
                    showToast( mBusLineResult.getStations().get(index).getTitle() );
                }
                return true;
            };
        };
        mBaiduMap.setOnMarkerClickListener(overlay);
    }


    /**
     * 【1】首先检索查询
     *
     * @param poiResult
     */
    @Override
    public void onGetPoiResult(PoiResult poiResult) {
        if (poiResult == null || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {
            showToast("抱歉,未找到结果" );
            return;
        }
        if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {

            busLines.clear();
            List<PoiInfo> allPoi = poiResult.getAllPoi();
            if (allPoi == null || allPoi.size() == 0) return;
            for (int i = 0; i < allPoi.size(); i++) {
                PoiInfo poiInfo = allPoi.get(i);
                //如果是公交类型的路线,就把它的UID添加到集合中
                if (poiInfo.type == PoiInfo.POITYPE.BUS_LINE) {
                    busLines.add(poiInfo.uid);
                }
            }
            mBusLineResult=null;
            if (busLines.size() == 0) return;
            uidPostion = 0;
            showToast( "发现"+busLines.size()+"条线路!");
            busLineSearch.searchBusLine(
                    new BusLineSearchOption().city(edStartBusStation.getText().toString()).uid(busLines.get(uidPostion)));
        }
    }

    /**
     * 【2】从检索的结果中筛选出公交路线
     * 并将其添加到地图上
     *
     * @param busLineResult
     */
    private BusLineResult route = null; // 保存驾车/步行路线数据的变量,供浏览节点时使用
    private int nodeIndex = -2; // 节点索引,供浏览节点时使用
    BusLineOverlay overlay; // 公交路线绘制对象
    @Override
    public void onGetBusLineResult(BusLineResult busLineResult) {
        if (busLineResult == null || busLineResult.error != SearchResult.ERRORNO.NO_ERROR) {
            showToast( "抱歉,未找到结果" );
            return;
        }

        mBaiduMap.clear();
        mBusLineResult = busLineResult;
        nodeIndex = -1;
        overlay.removeFromMap();
        overlay.setData(busLineResult);
        overlay.addToMap();
        overlay.zoomToSpan();
        tvPrevious.setVisibility(View.VISIBLE);
        tvNext.setVisibility(View.VISIBLE);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("路线详情").setMessage(busLineResult.getBusLineName()).setPositiveButton("朕知道了",null).show();
    }

    @Override
    public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
    }

    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
    }

    private void searchBusLine(){
        showToast( "当前查询的路线=="+uidPostion);
        busLineSearch.searchBusLine(
                new BusLineSearchOption().city(edStartBusStation.getText().toString()).uid(busLines.get(uidPostion)));

    }

    private void showToast(String str){
        Toast.makeText(ActBusLineMap.this,str,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (!isFinishing()) {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mapView.onDestroy();
        busLineSearch.destroy();
        poiSearch.destroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mapView.onPause();
    }

}

2.定位

1.布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />
    <Button
        android:id="@+id/btn_my_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="我的位置"/>
</RelativeLayout>

2.activity代码:


/**
 * 定位功能
 */
public class ActLocation extends AppCompatActivity {

    @BindView(R.id.map_view)
    MapView mapView;
    @BindView(R.id.btn_my_address)
    Button btnMyAddress;

    private BaiduMap mBaiduMap;
    public LocationClient mLocationClient = null;
    //BDAbstractLocationListener为7.2版本新增的Abstract类型的监听接口,
    // 原有BDLocationListener接口暂时同步保留。具体介绍请参考后文中的说明
    public BDAbstractLocationListener myListener = new MyLocationListener();

    private double coordinateX = 10.598359;
    private double coordinateY = 84.067147;
    private boolean isFirstLocation = false;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_location);
        ButterKnife.bind(this);

        mBaiduMap = mapView.getMap();
        //设置地图级别为18
        initMap(18);

        mLocationClient = new LocationClient(getApplicationContext());
        //声明LocationClient类
        mLocationClient.registerLocationListener(myListener);
        //注册监听函数

        mLocationClient.start();
        initLocation();
    }

    private void initLocation() {

        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备

        option.setCoorType("bd09ll");
        //可选,默认bd09ll表示百度经纬度坐标,设置返回的定位结果坐标系

        int span = 100;
        option.setScanSpan(span);
        //可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的

        option.setIsNeedAddress(true);
        //可选,设置是否需要地址信息,默认不需要

        option.setOpenGps(true);
        //可选,默认false,设置是否使用gps

        option.setLocationNotify(true);
        //可选,默认false,设置是否当GPS有效时按照1S/1次频率输出GPS结果

        option.setIsNeedLocationDescribe(true);
        //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”

        option.setIsNeedLocationPoiList(true);
        //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到

        option.setIgnoreKillProcess(false);
        //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死

//        option.setIgnoreCacheException(false);
        //可选,默认false,设置是否收集CRASH信息,默认收集

        option.setEnableSimulateGps(false);
        //可选,默认false,设置是否需要过滤GPS仿真结果,默认需要

//        option.setWifiValidTime(5*60*1000);
        //可选,7.2版本新增能力,如果您设置了这个接口,首次启动定位时,会先判断当前WiFi是否超出有效期,超出有效期的话,会先重新扫描WiFi,然后再定位

        mLocationClient.setLocOption(option);
    }

    @OnClick({R.id.btn_my_address})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_my_address:
                if(isFirstLocation){
                    //设置“我的位置”为中心点
                    initLocation(coordinateX,coordinateY);
                }
                break;
        }
    }

    public class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {

            if (location != null) {
                if(!isFirstLocation){
                    isFirstLocation = true;
                }
                coordinateX = location.getLatitude();
                coordinateY = location.getLongitude();
                //设置一开始的中心点
                initLocation(location.getLatitude(), location.getLongitude());
                //显示标记图标
                drawMark(location.getLatitude(), location.getLongitude());
                //以此为中心绘制指定区域圆形
                drawCircle(location.getLatitude(), location.getLongitude());
            }

            //获取定位结果
            location.getTime();    //获取定位时间
            location.getLocationID();    //获取定位唯一ID,v7.2版本新增,用于排查定位问题
            location.getLocType();    //获取定位类型
            location.getLatitude();    //获取纬度信息
            location.getLongitude();    //获取经度信息
            location.getRadius();    //获取定位精准度
            location.getAddrStr();    //获取地址信息
            location.getCountry();    //获取国家信息
            location.getCountryCode();    //获取国家码
            location.getCity();    //获取城市信息
            location.getCityCode();    //获取城市码
            location.getDistrict();    //获取区县信息
            location.getStreet();    //获取街道信息
            location.getStreetNumber();    //获取街道码
            location.getLocationDescribe();    //获取当前位置描述信息
            location.getPoiList();    //获取当前位置周边POI信息

            location.getBuildingID();    //室内精准定位下,获取楼宇ID
            location.getBuildingName();    //室内精准定位下,获取楼宇名称
            location.getFloor();    //室内精准定位下,获取当前位置所处的楼层信息

            if (location.getLocType() == BDLocation.TypeGpsLocation) {

                //当前为GPS定位结果,可获取以下信息
                location.getSpeed();    //获取当前速度,单位:公里每小时
                location.getSatelliteNumber();    //获取当前卫星数
                location.getAltitude();    //获取海拔高度信息,单位米
                location.getDirection();    //获取方向信息,单位度

            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {

                //当前为网络定位结果,可获取以下信息
                location.getOperators();    //获取运营商信息

            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {

                //当前为网络定位结果

            } else if (location.getLocType() == BDLocation.TypeServerError) {

                //当前网络定位失败
                //可将定位唯一ID、IMEI、定位失败时间反馈至loc-bugs@baidu.com

            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {

                //当前网络不通

            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {

                //当前缺少定位依据,可能是用户没有授权,建议弹出提示框让用户开启权限
                //可进一步参考onLocDiagnosticMessage中的错误返回码

            }
        }

        /**
         * 回调定位诊断信息,开发者可以根据相关信息解决定位遇到的一些问题
         * 自动回调,相同的diagnosticType只会回调一次
         *
         * @param locType           当前定位类型
         * @param diagnosticType    诊断类型(1~9)
         * @param diagnosticMessage 具体的诊断信息释义
         */
        public void onLocDiagnosticMessage(int locType, int diagnosticType, String diagnosticMessage) {

            if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_GPS) {

                //建议打开GPS

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_BETTER_OPEN_WIFI) {

                //建议打开wifi,不必连接,这样有助于提高网络定位精度!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_LOC_PERMISSION) {

                //定位权限受限,建议提示用户授予APP定位权限!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CHECK_NET) {

                //网络异常造成定位失败,建议用户确认网络状态是否异常!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_CLOSE_FLYMODE) {

                //手机飞行模式造成定位失败,建议用户关闭飞行模式后再重试定位!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_INSERT_SIMCARD_OR_OPEN_WIFI) {

                //无法获取任何定位依据,建议用户打开wifi或者插入sim卡重试!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_NEED_OPEN_PHONE_LOC_SWITCH) {

                //无法获取有效定位依据,建议用户打开手机设置里的定位开关后重试!

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_SERVER_FAIL) {

                //百度定位服务端定位失败
                //建议反馈location.getLocationID()和大体定位时间到loc-bugs@baidu.com

            } else if (diagnosticType == LocationClient.LOC_DIAGNOSTIC_TYPE_FAIL_UNKNOWN) {

                //无法获取有效定位依据,但无法确定具体原因
                //建议检查是否有安全软件屏蔽相关定位权限
                //或调用LocationClient.restart()重新启动后重试!

            }
        }

    }

    /**
     * 设置地图级别为18
     *
     * @param grade
     */
    private void initMap(int grade) {
        //描述地图将要发生的变化,使用工厂类MapStatusUpdateFactory创建,
        //设置级别为18,进去就是18了,默认是12
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(grade);
        mBaiduMap.setMapStatus(mapStatusUpdate);
        //是否显示缩放按钮
        //mMapView.showZoomControls(false);
    }

    /**
     * 绘制mark覆盖物
     */
    private void drawMark(double varX, double varY) {
        MarkerOptions markerOptions = new MarkerOptions();
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.ic_map_mark); // 描述图片
        markerOptions.position(new LatLng(varX, varY)) // 设置位置
                .icon(bitmap) // 加载图片
                .draggable(true) // 支持拖拽
                .title("当前位置"); // 显示文本
        //把绘制的圆添加到百度地图上去
        mBaiduMap.addOverlay(markerOptions);
    }

    /**
     * 设置一开始中心点的经纬度坐标
     *
     * @param varX
     * @param varY
     */
    private void initLocation(double varX, double varY) {
        //经纬度(纬度,经度)
        LatLng latlng = new LatLng(varX, varY);
        MapStatusUpdate mapStatusUpdate_circle = MapStatusUpdateFactory.newLatLng(latlng);
        mBaiduMap.setMapStatus(mapStatusUpdate_circle);
    }

    /**
     * 绘制圆
     */
    private void drawCircle(double varX, double varY) {
        // 1.创建自己
        CircleOptions circleOptions = new CircleOptions();
        // 2.设置数据 以“此位置”为圆心,1000米为半径绘制
        circleOptions.center(new LatLng(varX, varY))//中心
                .radius(1000)  //半径
                .fillColor(0x00000000)//填充圆的颜色 0x60FF0000
                .stroke(new Stroke(10, 0x600FF000));  //边框的宽度和颜色
        //把绘制的圆添加到百度地图上去
        mBaiduMap.addOverlay(circleOptions);
    }


    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (!isFinishing()) {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mapView.onPause();
    }

}

3.搜索关键词:

1.布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_margin="10dp"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <EditText
            android:id="@+id/ed_search"
            android:layout_margin="10dp"
            android:layout_width="match_parent"
            android:layout_weight="1"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/btn_range_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:textSize="24sp"
            android:layout_weight="3"
            android:text="范围搜索"/>
        <Button
            android:id="@+id/btn_around_search"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#00000000"
            android:textSize="24sp"
            android:layout_weight="3"
            android:text="周边搜索"/>
    </LinearLayout>

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />
</LinearLayout>

2.acitivty代码:


/**
 * 搜索功能:
 * 范围搜索、周边搜索
 */
public class ActSearchAddress extends AppCompatActivity {

    @BindView(R.id.ed_search)
    EditText edSearch;
    @BindView(R.id.btn_range_search)
    Button btnRangeSearch;
    @BindView(R.id.btn_around_search)
    Button btnAroundSearch;
    @BindView(R.id.map_view)
    MapView mapView;

    //初始化一个搜索广播
    private PoiSearch poiSearch;

    private BaiduMap mBaiduMap;
    private double coordinateX = 22.5422870000;
    private double coordinateY = 113.9804440000;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_searchaddress);
        ButterKnife.bind(this);

        mBaiduMap = mapView.getMap();

        //设置地图级别为18
        initMap(18);

        //设置地图中心点
        initLocation(coordinateX, coordinateY);
    }

    @OnClick({R.id.btn_range_search, R.id.btn_around_search})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.btn_range_search:
                //范围搜索
                //搜索:指定范围、关键字,周边搜索和范围搜索基本一致
                if (!TextUtils.isEmpty(edSearch.getText().toString().trim())) {
                    rangeSearch(edSearch.getText().toString().trim());
                } else {
                    Toast.makeText(getApplicationContext(), "请输入关键字", Toast.LENGTH_SHORT).show();
                }
                break;
            case R.id.btn_around_search:
                //周边圆形搜索
                //搜索:指定关键字、圆半径、中心点
                if (!TextUtils.isEmpty(edSearch.getText().toString().trim())) {
                    aroundSearch(edSearch.getText().toString().trim());
                } else {
                    Toast.makeText(getApplicationContext(), "请输入关键字", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }

    /**
     * 设置地图级别为18
     *
     * @param grade
     */
    private void initMap(int grade) {
        //描述地图将要发生的变化,使用工厂类MapStatusUpdateFactory创建,
        //设置级别为18,进去就是18了,默认是12
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(grade);
        mBaiduMap.setMapStatus(mapStatusUpdate);
        //是否显示缩放按钮
        //mMapView.showZoomControls(false);
    }

    /**
     * 设置一开始中心点的经纬度坐标
     *
     * @param varX
     * @param varY
     */
    private void initLocation(double varX, double varY) {
        //经纬度(纬度,经度)
        LatLng latlng = new LatLng(varX, varY);
        MapStatusUpdate mapStatusUpdate_circle = MapStatusUpdateFactory.newLatLng(latlng);
        mBaiduMap.setMapStatus(mapStatusUpdate_circle);
    }

    /**
     * 范围搜索:指定范围、关键字进行搜索
     * 标记处此范围内所有与关键字相关的地方
     *
     * @param keyWord
     */
    private void rangeSearch(String keyWord) {
        // 实例化搜索方法
        PoiSearch newInstance = PoiSearch.newInstance();
        newInstance.setOnGetPoiSearchResultListener(new MyRangeSearchListener());
        // 发出搜索的请求 范围检索
        PoiBoundSearchOption boundOption = new PoiBoundSearchOption();
        // 确定两点坐标(东北,西南),在此两点之间的范围内搜索
        LatLngBounds latLngBounds = new LatLngBounds.Builder()
                // 这里我们随机弄两个坐标 分别是深圳世界之窗附近
                .include(new LatLng(22.5441560000, 113.9828800000)) // 世界之窗右上角的美加广场
                .include(new LatLng(22.5413850000, 113.9777770000)) // 世界之窗左下角的一个不知道叫啥的街道
                .build();
        boundOption.bound(latLngBounds); // 设置搜索的范围
        boundOption.keyword(keyWord); // 搜索的关键字
        newInstance.searchInBound(boundOption);
    }

    /**
     * 周边搜索
     *
     * @param keyWord
     */
    private void aroundSearch(String keyWord) {
        poiSearch = PoiSearch.newInstance();
        poiSearch.setOnGetPoiSearchResultListener(new MyAroudSearchListener());

        PoiNearbySearchOption nearbyOption = new PoiNearbySearchOption();
        LatLng hmPos = new LatLng(22.5441560000, 113.9828800000);//指定中心点
        nearbyOption.location(hmPos);// 设置中心点
        nearbyOption.radius(1000);// 设置半径 单位是米
        nearbyOption.keyword(keyWord);// 关键字
        poiSearch.searchNearby(nearbyOption);
    }

    /**
     * 范围搜索监听
     */
    class MyRangeSearchListener implements OnGetPoiSearchResultListener {

        @Override
        public void onGetPoiDetailResult(PoiDetailResult result) {

        }

        @Override
        public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

        }

        @Override
        public void onGetPoiResult(PoiResult result) {
            // 收到发送过来的搜索请求之后我们进行处理
            if (result == null || SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) {
                Toast.makeText(getApplicationContext(), "未搜索到结果", Toast.LENGTH_LONG).show();
                return;
            }
            //搜索类型的类
            PoiOverlay overlay = new PoiOverlay(mBaiduMap);  //处理搜索Poi的覆盖物
            mBaiduMap.setOnMarkerClickListener(overlay);// 把事件分发给overlay,overlay才能处理点击事件
            overlay.setData(result);  //设置结果
            overlay.addToMap();//把搜索的结果添加到地图中去
            overlay.zoomToSpan(); //自动缩放到所以的mark覆盖物都能看到
        }
    }

    /**
     * 周边搜索(圆形)
     */
    class MyAroudSearchListener implements OnGetPoiSearchResultListener {

        @Override
        public void onGetPoiDetailResult(PoiDetailResult result) {
            if (result == null || SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) {
                Toast.makeText(getApplicationContext(), "未搜索到结果", Toast.LENGTH_LONG).show();
                return;
            }

            String text = result.getAddress() + "::" + result.getCommentNum() + result.getEnvironmentRating();
            Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
        }

        @Override
        public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

        }

        @Override
        public void onGetPoiResult(PoiResult result) {
            if (result == null || SearchResult.ERRORNO.RESULT_NOT_FOUND == result.error) {
                Toast.makeText(getApplicationContext(), "未搜索到结果", Toast.LENGTH_LONG).show();
                return;
            }
            PoiOverlay overlay = new MyPoiOverlay(mBaiduMap);// 搜索poi的覆盖物
            mBaiduMap.setOnMarkerClickListener(overlay);// 把事件分发给overlay,overlay才能处理点击事件
            overlay.setData(result);// 设置结果
            overlay.addToMap();// 把搜索的结果添加到地图中
            overlay.zoomToSpan();// 缩放地图,使所有Overlay都在合适的视野内 注: 该方法只对Marker类型的overlay有效
        }

    }

    //自己实现点击事件
    class MyPoiOverlay extends PoiOverlay {

        public MyPoiOverlay(BaiduMap arg0) {
            super(arg0);
        }

        @Override
        public boolean onPoiClick(int index) {
            PoiResult poiResult = getPoiResult();
            PoiInfo poiInfo = poiResult.getAllPoi().get(index);// 得到点击的那个poi信息
            String text = poiInfo.name + "," + poiInfo.address;
            Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();

            PoiDetailSearchOption detailOption = new PoiDetailSearchOption();
            detailOption.poiUid(poiInfo.uid);// 设置poi的uid
            poiSearch.searchPoiDetail(detailOption);

            return super.onPoiClick(index);
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (!isFinishing()) {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mapView.onPause();
    }


}

4.线路规划

1.布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/layout_search_bus_line"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:id="@+id/ed_city"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入城市名"/>
        <EditText
            android:id="@+id/ed_start_bus_station"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入起始点"/>
        <EditText
            android:id="@+id/ed_end_bus_station"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:hint="请输入终点"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:id="@+id/tv_choose_biking"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="骑行"
                android:layout_margin="5dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textSize="21sp"/>
            <TextView
                android:id="@+id/tv_choose_car"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="驾车"
                android:layout_margin="5dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textSize="21sp"/>
            <TextView
                android:id="@+id/tv_choose_bus"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="公交"
                android:layout_margin="5dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textSize="21sp"/>
            <TextView
                android:id="@+id/tv_choose_walk"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="步行"
                android:layout_margin="5dp"
                android:gravity="center"
                android:layout_weight="1"
                android:textSize="21sp"/>
        </LinearLayout>

    </LinearLayout>

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"
        android:clickable="true" />
</LinearLayout>

2.activity代码:


/**
 * 路线规划:
 * 根据城市名、起始点、终点,规划骑行、驾车、公交、步行等线路
 */
public class ActRoutePlanMap extends AppCompatActivity
        implements   OnGetRoutePlanResultListener {

    @BindView(R.id.map_view)
    MapView mapView;

    @BindView(R.id.ed_city)
    EditText edCity;
    @BindView(R.id.ed_start_bus_station)
    EditText edStartBusStation;
    @BindView(R.id.ed_end_bus_station)
    EditText edEndBusStation;
    @BindView(R.id.tv_choose_biking)
    TextView tvChooseBiking;
    @BindView(R.id.tv_choose_car)
    TextView tvChooseCar;
    @BindView(R.id.tv_choose_bus)
    TextView tvChooseBus;
    @BindView(R.id.tv_choose_walk)
    TextView tvChooseWalk;

    private BaiduMap mBaiduMap;

    private RoutePlanSearch routePlanSearch;//路径规划搜索接口

    private BikingRouteOverlay bikingOverlay;
    private DrivingRouteOverlay drivingOverlay;
    private TransitRouteOverlay transOverlay;
    private WalkingRouteOverlay walkingOverlay;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_routeplanmap);
        ButterKnife.bind(this);
        mBaiduMap = mapView.getMap();

        init();
    }

    @OnClick({ R.id.tv_choose_biking,
            R.id.tv_choose_car, R.id.tv_choose_bus, R.id.tv_choose_walk})
    public void onViewClicked(View view) {
        //路径规划中的出行节点信息,出行节点包括:起点,终点,途经点
        PlanNode fromPlanNode = PlanNode.withCityNameAndPlaceName(edCity.getText().toString(), edStartBusStation.getText().toString());
        PlanNode toPlanNode = PlanNode.withCityNameAndPlaceName(edCity.getText().toString(), edEndBusStation.getText().toString());
        switch (view.getId()) {
            /**
             * 各种路线规划的查询
             */
            case R.id.tv_choose_biking:
                //骑行路线
                routePlanSearch.bikingSearch(new BikingRoutePlanOption().from(fromPlanNode).to(toPlanNode));
                break;
            case R.id.tv_choose_car:
                //驾车路线
                routePlanSearch.drivingSearch(new DrivingRoutePlanOption().from(fromPlanNode).to(toPlanNode));
                break;
            case R.id.tv_choose_bus:
                //换乘公共交通工具的路线
                routePlanSearch.transitSearch(new TransitRoutePlanOption().city(edCity.getText().toString()).from(fromPlanNode).to(toPlanNode));
                break;
            case R.id.tv_choose_walk:
                //步行路线
                routePlanSearch.walkingSearch(new WalkingRoutePlanOption().from(fromPlanNode).to(toPlanNode));
                break;
        }
    }

    public void init() {

        //路径规划搜索接口
        routePlanSearch = RoutePlanSearch.newInstance();
        routePlanSearch.setOnGetRoutePlanResultListener(this);

        //骑行覆盖物添加并监听
        bikingOverlay = new BikingRouteOverlay(mBaiduMap);
        //驾车覆盖物添加并监听
        drivingOverlay = new DrivingRouteOverlay(mBaiduMap);
        //换乘覆盖物添加并监听
        transOverlay = new TransitRouteOverlay(mBaiduMap);
        //步行覆盖物添加并监听
        walkingOverlay = new WalkingRouteOverlay(mBaiduMap);
        //TODO: 添加各种路线覆盖物的点击事件
        mBaiduMap.setOnMarkerClickListener(bikingOverlay);
        mBaiduMap.setOnMarkerClickListener(drivingOverlay);
        mBaiduMap.setOnMarkerClickListener(transOverlay);
        mBaiduMap.setOnMarkerClickListener(walkingOverlay);
    }

    /**
     * 以下四个方法是路线规划搜索监听后的回调
     * a.步行回调
     *
     * @param walkingRouteResult
     */

    @Override
    public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
        if (walkingRouteResult == null || walkingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
            showToast( "抱歉,未找到结果");
            return;
        }
        showToast( "步行线路条数:" + walkingRouteResult.getRouteLines().size());
        List<WalkingRouteLine> routeLines = walkingRouteResult.getRouteLines();
        mBaiduMap.clear();
        walkingOverlay.removeFromMap();
        walkingOverlay.setData(routeLines.get(0));
        walkingOverlay.addToMap();
        walkingOverlay.zoomToSpan();
    }

    /**
     * b.换乘路线结果回调
     *
     * @param transitRouteResult
     */

    @Override
    public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
        if (transitRouteResult == null || transitRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
            showToast("抱歉,未找到结果" );
            return;
        }
        showToast( "公交线路条数:" + transitRouteResult.getRouteLines().size());
        List<TransitRouteLine> routeLines = transitRouteResult.getRouteLines();
        mBaiduMap.clear();
        transOverlay.removeFromMap();
        transOverlay.setData(routeLines.get(0));
        transOverlay.addToMap();
        transOverlay.zoomToSpan();
    }

    @Override
    public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {

    }

    /**
     * c.驾车路线结果回调
     *
     * @param drivingRouteResult
     */

    @Override
    public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
        if (drivingRouteResult == null || drivingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
            showToast( "抱歉,未找到结果" );
            return;
        }
        showToast( "驾车线路条数:" + drivingRouteResult.getRouteLines().size());
        List<DrivingRouteLine> routeLines = drivingRouteResult.getRouteLines();
        mBaiduMap.clear();
        drivingOverlay.removeFromMap();
        drivingOverlay.setData(routeLines.get(0));
        drivingOverlay.addToMap();
        drivingOverlay.zoomToSpan();
    }

    @Override
    public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {

    }

    /**
     * d.骑行路线结果回调
     *
     * @param bikingRouteResult
     */

    @Override
    public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
        if (bikingRouteResult == null || bikingRouteResult.error != SearchResult.ERRORNO.NO_ERROR) {
            showToast( "抱歉,未找到结果");
            return;
        }
        showToast( "骑行线路条数:" + bikingRouteResult.getRouteLines().size());
        List<BikingRouteLine> routeLines = bikingRouteResult.getRouteLines();
        mBaiduMap.clear();
        bikingOverlay.removeFromMap();
        bikingOverlay.setData(routeLines.get(0));
        bikingOverlay.addToMap();
        bikingOverlay.zoomToSpan();
    }

    private void showToast(String str){
        Toast.makeText(ActRoutePlanMap.this,str,Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (!isFinishing()) {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mapView.onDestroy();
        routePlanSearch.destroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mapView.onPause();
    }


}

5.标记地址、画区域、更新标记图、自定义弹出框

1.布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:background="#FFFFFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="100dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:orientation="horizontal"
                android:layout_margin="10dp"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/tv_custom_map"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="19sp"
                    android:text="普通地图"/>
                <TextView
                    android:id="@+id/tv_satellite_map"
                    android:layout_marginLeft="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="19sp"
                    android:text="卫星地图"/>
                <TextView
                    android:id="@+id/tv_blank_map"
                    android:layout_marginLeft="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="19sp"
                    android:text="空白地图"/>
            </LinearLayout>
            <LinearLayout
                android:orientation="horizontal"
                android:layout_margin="10dp"
                android:gravity="center"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
                <TextView
                    android:id="@+id/tv_traffic_map"
                    android:layout_marginLeft="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="19sp"
                    android:text="开启交通图"/>
                <TextView
                    android:id="@+id/tv_thermal_map"
                    android:layout_marginLeft="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="19sp"
                    android:text="开启热力图"/>
            </LinearLayout>

        </LinearLayout>
    </ScrollView>

    <com.baidu.mapapi.map.MapView
        android:id="@+id/map_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

</LinearLayout>

2.activity代码:


/**
 * 普通地图:
 * 1.显示地图(普通、卫星、空白、交通图、热力图)
 * 2.标记指定的位置点、不断更新标记图标
 * 3.在指定的位置点显示自定义文字
 * 4.点击指定的位置点的标记图标,显示自定义弹出框
 * 5.指定半径、中心点画出区域圆形图
 * 6.显示指南针
 * 7.设置地图级别、中心点
 */
public class ActCommonMap extends AppCompatActivity {

    @BindView(R.id.map_view)
    MapView mapView;
    @BindView(R.id.tv_custom_map)
    TextView tvCustomMap;
    @BindView(R.id.tv_satellite_map)
    TextView tvSatelliteMap;
    @BindView(R.id.tv_blank_map)
    TextView tvBlankMap;
    @BindView(R.id.tv_traffic_map)
    TextView tvTrafficMap;
    @BindView(R.id.tv_thermal_map)
    TextView tvThermalMap;

    private BaiduMap mBaiduMap;
    //要显示的pop
    private View pop;
    //pop中的文本信息
    private TextView popWindowTitle;

    private boolean isTrafficMap = false;
    private boolean isThermalMap = false;
    private boolean isInfoWindow = false;
    private double coordinateX = 30.598359;//22.5422870000;
    private double coordinateY = 104.067147;//113.9804440000;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_act_commonmap);
        ButterKnife.bind(this);

        initView();
    }

    /**
     * 设置地图属性等等
     */
    private void initView(){
        mBaiduMap = mapView.getMap();
        //设置地图级别为18
        initMap(18);

        //设置地图中心点
        initLocation(coordinateX, coordinateY);

        //显示指南针
        mBaiduMap.getUiSettings().setCompassEnabled(true);

        //绘制区域圆形
        drawCircle();

        //显示自定义文字
        drawText();

        //显示标记图标
        drawMark(coordinateX, coordinateY);

        //初始化popwindow,通过点击mark来控制它的显示
        initPop();

        //mark的点击事件
        // 点击某一个mark在他上放显示泡泡
        // 加载pop 添加到mapview 把他设置为隐藏 当点击的时候更新pop的位置 设置为显示
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker result) {
                showPop(result);
                return true;
            }
        });

        //隐藏pop
        pop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                pop.setVisibility(View.INVISIBLE);
            }
        });

        //不断切换mark图标(显示多个图片的来回切换,类似于帧动画)
//        drawMarks();
    }

    /**
     * 不断更新Mark图标
     * 显示多个图片的来回切换,类似于帧动画
     * 拿上面那个方法直接改的设置icon
     * 绘制mark覆盖物
     */
    private void drawMarks() {
        MarkerOptions markerOptions = new MarkerOptions();
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.ic_map_mark); // 描述图片
        ArrayList<BitmapDescriptor> bitmaps = new ArrayList<BitmapDescriptor>();
        bitmaps.add(bitmap);  //显示多个图片的来回切换,类似于帧动画
        bitmaps.add(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher_round));
        markerOptions.position(new LatLng(22.5422870000, 113.9804440000)) // 设置位置
                //.icon(bitmap) // 加载图片
                //切换图片
                .icons(bitmaps)
                .period(10) //切换时间
                .draggable(true) // 支持拖拽
                .title("世界之窗旁边的草房"); // 显示文本
        mBaiduMap.addOverlay(markerOptions);
    }

    /**
     * 初始化pop
     */
    private void initPop() {
        pop = View.inflate(getApplicationContext(), R.layout.map_pop_window, null);
        //必须使用百度的params
        ViewGroup.LayoutParams params = new MapViewLayoutParams.Builder().layoutMode(MapViewLayoutParams.ELayoutMode.mapMode) //按照经纬度设置
                .position(new LatLng(coordinateX, coordinateY)) //这个坐标无所谓的,但是不能传null
                .width(MapViewLayoutParams.WRAP_CONTENT)  //宽度
                .height(MapViewLayoutParams.WRAP_CONTENT)  //高度
                .build();
        mapView.addView(pop, params);
        //先设置隐藏,点击的时候显示
        pop.setVisibility(View.INVISIBLE);
        popWindowTitle = (TextView) pop.findViewById(R.id.popWindowTitle);
    }

    /**
     * 显示加载pop
     */
    private void showPop( Marker result){
        if( !isInfoWindow){
            //处理点击 ,当点击的时候更新并且显示位置
            ViewGroup.LayoutParams params = new MapViewLayoutParams.Builder().
                    layoutMode(MapViewLayoutParams.ELayoutMode.mapMode) //按照经纬度设置位置
                    .position(result.getPosition()) //这个坐标无所谓的,但是不能传null
                    .width(MapViewLayoutParams.WRAP_CONTENT)  //宽度
                    .height(MapViewLayoutParams.WRAP_CONTENT)  //高度
                    .yOffset(-5)  //相距  正值往下  负值往上
                    .build();
            mapView.updateViewLayout(pop, params);
            //更新下title
            String title = result.getTitle();
            popWindowTitle.setText(title);
            pop.setVisibility(View.VISIBLE);
        }else{
            pop.setVisibility(View.INVISIBLE);
        }
    }

    /**
     * 绘制mark覆盖物
     */
    private void drawMark(double varX, double varY) {
        MarkerOptions markerOptions = new MarkerOptions();
        BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.ic_map_mark); // 描述图片
        markerOptions.position(new LatLng(varX, varY)) // 设置位置
                .icon(bitmap) // 加载图片
                .draggable(true) // 支持拖拽
                .title("世界之窗旁边的草房"); // 显示文本
        //把绘制的圆添加到百度地图上去
        mBaiduMap.addOverlay(markerOptions);
    }

    /**
     * 绘制文字
     */
    private void drawText() {
        TextOptions textOptions = new TextOptions();
        textOptions.fontColor(Color.RED) //设置字体颜色
                .text("自定义文字覆盖物")  //设置显示文本
                .position(new LatLng(22.5422870000, 113.9804440000))   //设置显示坐标
                .fontSize(20) //设置文本大小
                .typeface(Typeface.SERIF)  //设置字体 Android的字体就三种,对称的,不对称的,等宽的
                .rotate(30);  //设置旋转角度
        //把绘制的圆添加到百度地图上去
        mBaiduMap.addOverlay(textOptions);
    }

    /**
     * 绘制圆
     */
    private void drawCircle() {
        // 1.创建自己
        CircleOptions circleOptions = new CircleOptions();
        // 2.设置数据 以世界之窗为圆心,1000米为半径绘制
        circleOptions.center(new LatLng(22.5422870000, 113.9804440000))//中心
                .radius(1000)  //半径
                .fillColor(0x60FF0000)//填充圆的颜色
                .stroke(new Stroke(10, 0x600FF000));  //边框的宽度和颜色
        //把绘制的圆添加到百度地图上去
        mBaiduMap.addOverlay(circleOptions);
    }

    /**
     * 设置地图级别为18
     *
     * @param grade
     */
    private void initMap(int grade) {
        //描述地图将要发生的变化,使用工厂类MapStatusUpdateFactory创建,
        //设置级别为18,进去就是18了,默认是12
        MapStatusUpdate mapStatusUpdate = MapStatusUpdateFactory.zoomTo(grade);
        mBaiduMap.setMapStatus(mapStatusUpdate);
        //是否显示缩放按钮
        //mMapView.showZoomControls(false);
    }

    /**
     * 设置一开始中心点的经纬度坐标
     *
     * @param varX
     * @param varY
     */
    private void initLocation(double varX, double varY) {
        //经纬度(纬度,经度)
        LatLng latlng = new LatLng(varX, varY);
        MapStatusUpdate mapStatusUpdate_circle = MapStatusUpdateFactory.newLatLng(latlng);
        mBaiduMap.setMapStatus(mapStatusUpdate_circle);
    }


    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (!isFinishing()) {
            finish();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
        mapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
        mapView.onPause();
    }

    @OnClick({R.id.tv_custom_map, R.id.tv_satellite_map, R.id.tv_blank_map, R.id.tv_traffic_map, R.id.tv_thermal_map})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.tv_custom_map:
                //普通地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                break;
            case R.id.tv_satellite_map:
                //卫星地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
                break;
            case R.id.tv_blank_map:
                //空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为NONE,
                // 将不会使用流量下载基础地图瓦片图层。使用场景:与瓦片图层一起使用,
                // 节省流量,提升自定义瓦片图下载速度。
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
                break;
            case R.id.tv_traffic_map:
                if (isTrafficMap == false) {
                    //开启交通图
                    mBaiduMap.setTrafficEnabled(true);
                    tvTrafficMap.setText("关闭交通图");
                    isTrafficMap = true;
                } else {
                    //开启交通图
                    mBaiduMap.setTrafficEnabled(false);
                    tvTrafficMap.setText("开启交通图");
                    isTrafficMap = false;
                }
                break;
            case R.id.tv_thermal_map:
                if (isThermalMap == false) {
                    //城市热力图
                    mBaiduMap.setBaiduHeatMapEnabled(true);
                    tvThermalMap.setText("关闭热力图");
                    isThermalMap = true;
                } else {
                    //开启交通图
                    mBaiduMap.setBaiduHeatMapEnabled(false);
                    tvThermalMap.setText("开启热力图");
                    isThermalMap = false;
                }
                break;
        }
    }

}

map_pop_window.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="#FFFFFF"
    android:paddingBottom="0dip" >

    <LinearLayout
        android:id="@+id/user_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="20dip"
        android:layout_weight="1"
        android:background="@color/colorAccent"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <ImageView
            android:id="@+id/round"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="2dip"
            android:src="@mipmap/ic_launcher" />

        <TextView
            android:id="@+id/popWindowTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:text="显示文字提示"
            android:textSize="20sp" />

        <ImageView
            android:id="@+id/roads"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher_round" />
    </LinearLayout>

</LinearLayout>
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值