如何创建自定义标记的谷歌Map在Flutter与文本框上的图标

k7fdbhmy  于 2022-12-27  发布在  Flutter
关注(0)|答案(2)|浏览(145)

bounty将在7小时后过期。回答此问题可获得+50的声誉奖励。Florentin Lupascu正在寻找来自声誉良好来源的答案

我尝试创建自定义标记(BitmapDescriptor)在Flutter中显示在我使用谷歌 matplotlib 的屏幕上。我唯一的问题是我的自定义标记在Map上的位置错误。如果我使用默认标记代替,那么标记的位置显示正确。下面是我的代码,也与标记的正确位置,也是标记(自定义标记)的错误位置2截图。
屏幕快照标记-右侧位置

屏幕截图标记-位置错误

/// Load an asset from root library and return it back as a list of bytes
Future<Uint8List> loadImageAsBytes( {required String path, required Size size}) async {
  
    ByteData data = await rootBundle.load(path);
    ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),
      targetWidth: size.width.toInt());
    ui.FrameInfo fi = await codec.getNextFrame();

    return ((await fi.image.toByteData(format: ui.ImageByteFormat.png)) ??
          ByteData(0))
      .buffer
      .asUint8List();
}

/// Load the icon from a list of bytes and return it back as an Image
Future<ui.Image> getImageFromPath(String imagePath, Size iconSize) async {

    Uint8List imageBytes = await loadImageAsBytes(size: iconSize, path: imagePath);

    final Completer<ui.Image> completer = Completer();

    ui.decodeImageFromList(imageBytes, (ui.Image img) {
        return completer.complete(img);
    });

    return completer.future;
}

 /// Here we draw a custom marker which will include the vehicle icon and vehicle plate number.
  Future<BitmapDescriptor> createCustomMarkerWithPlateRegAndIcon({required String iconPath, required Size size, required String plateReg}) async {

    // Create a TextBox where to place the Vehicle Plate Number
    TextSpan span = TextSpan(
        style: const TextStyle(
          height: 1.2,
          color: Colors.black,
          fontSize: 30.0,
          fontWeight: FontWeight.bold,
        ),
        text: plateReg);

    // Align the Vehicle Plate Registration to center in the above TextBox
    TextPainter tp = TextPainter(
      text: span,
      textAlign: TextAlign.center,
      textDirection: TextDirection.ltr,
    );
    // Computes the visual position of the glyphs for painting the text.
    tp.layout();

    // Start recording a new drawing
    ui.PictureRecorder recorder = ui.PictureRecorder();

    // Create an empty canvas where the drawing will be painted
    Canvas canvas = Canvas(recorder);

    // TextBox background colour for Plate Registration (I set it to dark yellow to reflect UK style)
    Paint textBgBoxPaint = Paint()
      ..color = const Color.fromARGB(255, 240, 200, 50);

    // Create a rectangle where to place the Veh Plate Number
    Rect rect = Rect.fromLTWH(0, 0, tp.width + 30, 50);

    // Draw on the canvas the rectangle with yellow background and rounded corners
    canvas.drawRRect(
      RRect.fromRectAndRadius(rect, const Radius.circular(20.0)),
      textBgBoxPaint,
    );

    // Add the Plate Registration to canvas and align it to center in the TextBox
    tp.paint(canvas, const Offset(15.0, 5.0));

    // Create a rectangle where will be placed the vehicle icon
    Rect rectForImage = Rect.fromLTWH(
      0,
      55,
      size.width,
      size.height,
    );

    // Add path to rectangle image
    canvas.clipPath(Path()..addRect(rectForImage));

    // Get the vehicle icon which will gonna be inserted on the canvas
    ui.Image image = await getImageFromPath(iconPath, size);

    // Paint the icon on the canvas
    paintImage(
        canvas: canvas,
        image: image,
        rect: rectForImage,
        fit: BoxFit.fitHeight);

    // Stop the drawing
    ui.Picture p = recorder.endRecording();

    // Take the whole drawing and convert it to a PNG and after to a byte data
    ByteData? pngBytes = await (await p.toImage(
      160,
      160,
    ))
        .toByteData(format: ui.ImageByteFormat.png);

    // This is an empty byte data for null safety
    ByteData emptyData = Uint8List(0).buffer.asByteData();

    // Convert the PNG from byteData to a list of bytes.
    Uint8List data = Uint8List.view((pngBytes ?? emptyData).buffer);

    // Return the PNG (in format list of bytes) as a Google Marker of type BitmapDescriptor
    return BitmapDescriptor.fromBytes(data);
  }

感谢您阅读本文!

w6mmgewl

w6mmgewl1#

    • 解决方案1:**

将其替换为您的代码(从左起添加相同的边距):

// Create a rectangle where will be placed the vehicle icon
Rect rectForImage = Rect.fromLTWH(
  55,
  55,
  size.width,
  size.height,
);
    • 解决方案2:**
// Get rect(rect.width) and the size.width(icon width)
left_margin = (rect.width/2 - size.width/2);
// Create a rectangle where will be placed the vehicle icon
Rect rectForImage = Rect.fromLTWH(
  left_margin,
  55,
  size.width,
  size.height,
);
nhn9ugyo

nhn9ugyo2#

请尝试此解决方案。

Rect rectForImage = Rect.fromLTWH(
      (tp.width + 30)/2,
      55,
      size.width,
      size.height,
    );

相关问题