Flutter开发百度地图之定位,保姆级教程

Posted Buliang_C

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter开发百度地图之定位,保姆级教程相关的知识,希望对你有一定的参考价值。

未经本人同意,禁止转载!
前几天开发flutter百度地图,总算是把第一步走通了,这几天把定位功能开发了一下。记录一下,所谓取之于CSDN用之于CSDN。
下面描述的工程是配置android的,ios并没有配置。
开发环境:sdk: “>=2.12.0 < 3.0.0”
Android Studio版本3.4.0


前言

前面地图的步骤,直接按照百度地图保姆级教程(1) 来进行地图的引入即可,包括AK秘钥的引入,地图的显示等,下面的教程都是基于上面的所有步骤完成,地图正确显示之后,才能够进行。在(1)的代码基础上进行添加。部分步骤可以直接按照官网提供的来
flutter sdk2.9.0之后都是支持空安全检测的。

一、引入官网的集成百度地图定位Flutter插件

定位插件引入就引入官网提供的最新版本的,不然可能会出现空安全检测的警告:

flutter_bmflocation: ^2.0.0-nullsafety.0

二、导入dart类,使用对外接口

import ‘package:flutter_bmflocation/bdmap_location_flutter_plugin.dart’;
import ‘package:flutter_bmflocation/flutter_baidu_location.dart’;
import ‘package:flutter_bmflocation/flutter_baidu_location_android_option.dart’;
import ‘package:flutter_bmflocation/flutter_baidu_location_ios_option.dart’;

三、创建主界面代码

使用stack组件进行层叠式布局,将开始定位和停止定位按钮叠加在地图上面。用于控制是否进行定位操作。没怎么调整样式,只是先实现的功能。

Scaffold(
      body:Container(
        width: screenSize.width,
        height: screenSize.height,
        child: Stack(
          alignment:Alignment.center , //指定未定位或部分定位widget的对齐方式
          children: <Widget>[
            Container(
              child:BMFMapWidget(
                onBMFMapCreated: (controller) { // 创建mapView回调
                  onBMFMapCreated(controller);
                },
                mapOptions: initMapOptions(), // 设置map地图参数
              ),
            ),
            Positioned(		// 这部分是用来切换卫星地图和普通地图
              top: 0.0,
              child: mapTypeSelect(),
            ),
            Positioned(		// 这部分用来显示经纬度信息和时间信息,都可以自己随意定义
              top: 50,
              child:Row(
                children: widgets,
              ),
            ),
            Positioned(
              top: 70,
              child: Row(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  new RaisedButton(
                    onPressed: _startLocation,	// 控制开始定位
                    child: new Text('开始定位'),
                    color: Colors.blue,
                    textColor: Colors.white,
                  ),
                  new Container(width: 20.0),
                  new RaisedButton(
                    onPressed: _stopLocation,	// 控制停止定位
                    child: new Text('停止定位'),
                    color: Colors.blue,
                    textColor: Colors.white,
                  )
                ],
              ),
            )
          ],
        ),
      ),
    );
  // 选择组件
  Widget mapTypeSelect() {
    return Container(
        height: 50.00,
        decoration: BoxDecoration(
            color: Colors.blue,
        ),
        child: Row(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Row(
                  ///包裹子布局
                  mainAxisSize: MainAxisSize.max,
                    children: [
                      Radio(
                        ///此单选框绑定的值 必选参数
                        value: 'false',
                        ///当前组中这选定的值  必选参数
                        groupValue: _groupValue,
                        ///点击状态改变时的回调 必选参数
                        onChanged: (v) {
                          myMapController?.updateMapOptions(BMFMapOptions(mapType: BMFMapType.Standard));
                          setState(() {
                            this._groupValue = v;
                          });
                        },
                      ),
                      Text("普通地图",style: TextStyle(color: Colors.white))
                    ],
                  ),
                  Row(
                    ///包裹子布局
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      Radio(
                        ///此单选框绑定的值 必选参数
                        value: 'true',
                        ///当前组中这选定的值  必选参数
                        groupValue: _groupValue,
                        ///点击状态改变时的回调 必选参数
                        onChanged: (v) {
                          myMapController?.updateMapOptions(BMFMapOptions(mapType: BMFMapType.Satellite));
                          setState(() {
                            this._groupValue = v;
                          });
                        },
                      ),
                      Text("卫星地图",style: TextStyle(color: Colors.white))
                    ],
                  ),
                ]
              ),
    );
  }

四、启动定位

准备定位,配置Android端的定位参数

  /// 设置android端和ios端定位参数
  void _setLocOption() {
    /// android 端设置定位参数
    BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
    androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
    androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔高度信息
    androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
    androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
    androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
    androidOption.setOpenGps(true); // 设置是否需要使用gps
    androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
    androidOption.setScanspan(1000); // 设置发起定位请求时间间隔

    Map androidMap = androidOption.getMap();

    /// ios 端设置定位参数
    BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
    iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    iosOption.setBMKLocationCoordinateType("BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
    iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型
    iosOption.setLocationTimeout(10); // 设置位置获取超时时间
    iosOption.setDesiredAccuracy("kCLLocationAccuracyBest");  // 设置预期精度参数
    iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
    iosOption.setDistanceFilter(100); // 设置定位最小更新距离
    iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
    iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统自动暂停

    Map iosMap = iosOption.getMap();

    _locationPlugin.prepareLoc(androidMap, iosMap);
  }

  /// 启动定位
  void _startLocation() {
     if (null != _locationPlugin) {
        _setLocOption();
        _locationPlugin.startLocation();
    }
  }

五、停止定位

  /// 停止定位
  void _stopLocation() {
     if (null != _locationPlugin) {
    _locationPlugin.stopLocation();
     }
  }

六、动态申请定位权限,并进行监听

在initState生命周期中,动态申请定位权限,然后对结果进行实时监听

  @override
  void initState() {
    super.initState();
    /// 动态申请定位权限
    _locationPlugin.requestPermission();
    /// 动态监听地图信息
    _locationListener = _locationPlugin.onResultCallback().listen((Map<String, Object>? result){
      setState(() {
          print('更新了状态');
          if (result != null) {
            _loationResult = result;
          }
      });
    });
  }

七、移动点定位

  // 移动点定位
  void mapLocation(lat, lng) {
    myMapController?.showUserLocation(true);
    BMFCoordinate coordinate = BMFCoordinate(lat, lng);  // 经纬度信息

    BMFLocation location = BMFLocation( // 定位信息
        coordinate: coordinate,   // 经纬度
        altitude: 0,  // 海拔
        horizontalAccuracy: 5,  // 水平精确度
        verticalAccuracy: -1.0, // 垂直精确度
        speed: -1.0,  // 速度
        course: -1.0);  // 航向

    BMFUserLocation userLocation = BMFUserLocation( // 当前位置对象
      location: location,
    );

    myMapController?.updateLocationData(userLocation);  // 动态更新我的位置数据

    BMFUserLocationDisplayParam displayParam = BMFUserLocationDisplayParam(
        locationViewOffsetX: 0,
        locationViewOffsetY: 0,
        accuracyCircleFillColor: Colors.red,
        accuracyCircleStrokeColor: Colors.blue,
        isAccuracyCircleShow: true,
        locationViewImage: 'assets/images/marker_point.png',
        locationViewHierarchy: BMFLocationViewHierarchy.LOCATION_VIEW_HIERARCHY_TOP
    );

    myMapController?.updateLocationViewWithParam(displayParam); // 动态定制我的位置样式

  }

上面的就是所有的步骤了,如果不想看步骤的,可以直接复制下面的代码,直接进行定位操作


八、全部代码,可直接复制使用,已添加空安全检测

地图中心的经纬度可以手动设置固定值,也可以使用定位产生的变化值。

import 'package:flutter/material.dart';
import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart';
import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart';
import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart';
import 'package:flutter_bmflocation/flutter_baidu_location.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart';
import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart';

//import 'package:flutter_baidu_mapapi_search/flutter_baidu_mapapi_search.dart';
//import 'package:flutter_map_blue/BaiduMapHelper.dart';


class TestBaiduMapPage extends StatefulWidget {
  @override
  _TestBaiduMapPageState createState() => _TestBaiduMapPageState();
}

class _TestBaiduMapPageState extends State<TestBaiduMapPage> {
  var lat,lng;
  Map<String, Object>? _loationResult;
  BaiduLocation? _baiduLocation; // 定位结果

  StreamSubscription<Map<String, Object>?>? _locationListener;// 事件监听
  LocationFlutterPlugin _locationPlugin = new LocationFlutterPlugin();


  BMFMapController? myMapController;
  var _groupValue; // 权限选项
  // 选择组件
  Widget mapTypeSelect() {
    return Container(
//        width: 500.00,
        height: 50.00,
        decoration: BoxDecoration(
            color: Colors.blue,
        ),
        child: Row(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  Row(
                  ///包裹子布局
                  mainAxisSize: MainAxisSize.max,
                    children: [
                      Radio(
                        ///此单选框绑定的值 必选参数
                        value: 'false',
                        ///当前组中这选定的值  必选参数
                        groupValue: _groupValue,
                        ///点击状态改变时的回调 必选参数
                        onChanged: (v) {
                          myMapController?.updateMapOptions(BMFMapOptions(mapType: BMFMapType.Standard));
                          setState(() {
                            this._groupValue = v;
                          });
                        },
                      ),
                      Text("普通地图",style: TextStyle(color: Colors.white))
                    ],
                  ),
                  Row(
                    ///包裹子布局
                    mainAxisSize: MainAxisSize.max,
                    children: [
                      Radio(
                        ///此单选框绑定的值 必选参数
                        value: 'true',
                        ///当前组中这选定的值  必选参数
                        groupValue: _groupValue,
                        ///点击状态改变时的回调 必选参数
                        onChanged: (v) {
                          myMapController?.updateMapOptions(BMFMapOptions(mapType: BMFMapType.Satellite));
                          setState(() {
                            this._groupValue = v;
                          });
                        },
                      ),
                      Text("卫星地图",style: TextStyle(color: Colors.white))
                    ],
                  ),
                ]
              ),
    );
  }


  @override
  void initState() {
    super.initState();
    /// 动态申请定位权限
    _locationPlugin.requestPermission();
    /// 动态监听地图信息
    _locationListener = _locationPlugin.onResultCallback().listen((Map<String, Object>? result){
      setState(() {
          print('更新了状态');
          if (result != null) {
            _loationResult = result;
          }
      });
    });
  }


  /// 设置android端和ios端定位参数
  void _setLocOption() {
    /// android 端设置定位参数
    BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption();
    androidOption.setCoorType("bd09ll"); // 设置返回的位置坐标系类型
    androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔高度信息
    androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息
    androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息
    androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述
    androidOption.setOpenGps(true); // 设置是否需要使用gps
    androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式
    androidOption.setScanspan(1000); // 设置发起定位请求时间间隔

    Map androidMap = androidOption.getMap();

    /// ios 端设置定位参数
    BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption();
    iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息
    iosOption.setBMKLocationCoordinateType("BMKLocationCoordinateTypeBMK09LL"); // 设置返回的位置坐标系类型
    iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型
    iosOption.setLocationTimeout(10); // 设置位置获取超时时间
    iosOption.setDesiredAccuracy("kCLLocationAccuracyBest");  // 设置预期精度参数
    iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间
    iosOption.setDistanceFilter(100); // 设置定位最小更新距离
    iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位
    iosOption.setPauseLocUpdateAutomatically(true); //  定位是否会被系统自动暂停

    Map iosMap = iosOption.getMap();

    _locationPlugin.prepareLoc(androidMap, iosMap);
  }

  /// 启动定位
  void _startLocation() {
     if (null != _locationPlugin) {
        _setLocOption();
        _locationPlugin.startLocation();
    }
  }

  /// 停止定位
  void _stopLocation() {
     if (null != _locationPlugin) {
    _locationPlugin.stopLocation();
     }
  }

  void addMarker() {
    /// 创建BMFMarker
    BMFMarker marker = BMFMarker(
        position: BMFCoordinate(自己的经度,自己的纬度),
        title: 'flutterMaker',
        identifier: 'flutter_marker',
        icon: 'assets/images/marker_point.png'
    );

    /// 添加Marker
    myMapController?.addMarker(marker);
  }

  // 移动点定位
  void mapLocation(lat, lng) 保姆级教程带你开发优质的Python库之下篇种子项目

保姆级教程带你开发优质的Python库之下篇种子项目

Android 开发之集成百度地图的定位与地图展示

保姆级教程带你开发优质的Python库之上篇建议收藏

保姆级教程带你开发优质的Python库之上篇建议收藏

保姆级教程带你开发优质的Python库之中篇命令行发行