地图组件接入

225 阅读2分钟

前景提要: 项目中要接入一个地图组件,发现flutter的组件并没有js灵活,相关文档也较少。希望我的文章能对大家起到一点帮助,如果有什么问题也欢迎探讨

首先按照官网的内容在项目中配置定位等权限,然后再执行下面步骤

  1. 插件新增依赖

amap_flutter_map: ^3.0.0
  1. 配置key值

  static const String androidKey = 'xxx';
  static const String iosKey = 'xxx';
  static const AMapApiKey amapApiKeys =
      AMapApiKey(androidKey: androidKey, iosKey: iosKey);
  1. 添加自定义图片marker

 Marker(
      position: LatLng(mapCenter.latitude, mapCenter.longitude),
      infoWindowEnable: false,
      zIndex: 1,
      icon: BitmapDescriptor.fromIconPath(Assets.images.car.keyName),
    )
  1. 添加动态文字marker

由于高德地图flutter只支持自定义icon,所以需要利用提供的fromBytes方法将自定义widget转换成字节流。如果没有动态内容可以直接引用静态图片。

设置自定义widget

  ///自定义widget
  widgetContext() {
    return Container(
      width: 140,
      height: 70,
      color: Colors.black,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const [
          Directionality(
              textDirection: TextDirection.ltr, child: Text('12312321')),
          Directionality(
              textDirection: TextDirection.ltr, child: Text('asdfsdfsdf')),
        ],
      ),
    );
  }

转为字节流

  widgetToImage(Widget widget,
      {Alignment alignment = Alignment.center,
      Size size = const Size(double.maxFinite, double.maxFinite),
      double devicePixelRatio = 1.0,
      double pixelRatio = 1.0}) async {
    RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary();

    RenderView renderView = RenderView(
      child: RenderPositionedBox(alignment: alignment, child: repaintBoundary),
      configuration: ViewConfiguration(
        size: size,
        devicePixelRatio: devicePixelRatio,
      ),
      window: ui.window,
    );

    PipelineOwner pipelineOwner = PipelineOwner();
    pipelineOwner.rootNode = renderView;
    renderView.prepareInitialFrame();

    BuildOwner buildOwner = BuildOwner(focusManager: FocusManager());
    RenderObjectToWidgetElement rootElement = RenderObjectToWidgetAdapter(
      container: repaintBoundary,
      child: widget,
    ).attachToRenderTree(buildOwner);
    buildOwner.buildScope(rootElement);
    buildOwner.finalizeTree();

    pipelineOwner.flushLayout();
    pipelineOwner.flushCompositingBits();
    pipelineOwner.flushPaint();

    ui.Image image = await repaintBoundary.toImage(pixelRatio: pixelRatio);
    ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png);

    return byteData;
  }

配置marker

    Marker markerInfoWindow = Marker(
      infoWindowEnable: false,
      position: LatLng(mapCenter.latitude + 0.05, mapCenter.longitude + 0.05),
      icon: BitmapDescriptor.fromBytes(byteData!.buffer.asUint8List());,
      zIndex: 2,
      anchor: const Offset(0, 1.0),
    );
  1. 添加地图

 AMapWidget(
         apiKey: amapApiKeys,
        onMapCreated: onMapCreated,
        markers: markers,
      )
  1. 其他接口能力

    1. 设置地图显示比例尺层级 api(scaleLevel)
    scaleEnabled比例尺是否显示TRUE
    1. 设置中心点位置 api
    initialCameraPosition: CameraPosition(
                target: LatLng(mapCenter.latitude, mapCenter.longitude), zoom: 10),
    
    1. 计算两个经纬度之间的距离api
  • 在flutter中没有提供两点距离api方法,网络上dart经纬度距离计算如下:
  • import 'dart:math';void main() {print("distance between two point is : ${getDistance(119.9831030000, 30.2340350000, 119.9809580000, 30.2320980000)}");}getDistance(double lat1, double lng1, double lat2, double lng2) {
      double radLat1 = rad(lat1);
      double radLat2 = rad(lat2);
      double a = radLat1 - radLat2;
      double b = rad(lng1) - rad(lng2);
      double s = 2 *asin(sqrt(pow(sin(a / 2), 2) +cos(radLat1) * cos(radLat2) * pow(sin(b / 2), 2)));return s * 6378138.0;}
    
    double rad(double d) {return d * pi / 180.0;}