SVG映射带有文本叠加层的标记

时间:2019-05-17 10:47:54

标签: google-maps svg flutter

我有一个任务是构建一个带有标记的地图,该标记的顶部可以有动态内容(文本或图标)(作为覆盖层),我正在尝试使用google_maps_flutter和flutter_svg库来实现。

一般来说,我的想法是让标记svg转换为图像,并添加额外的图层(Found DrawableRoot类)转换为字节,并传递到标记构造函数中的BitmapDescriptor.fromBytes()

问题是,当我尝试使用svg作为标记时,我的第一步失败了。 我是这样从我的svg字符串创建字节的:

Future<Uint8List> svg() async {
    final raw = r'''<?xml version="1.0" ?><!DOCTYPE svg  PUBLIC '-//W3C//DTD SVG 1.1//EN'  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 40 52" height="52px" id="Layer_1" version="1.1" viewBox="0 0 40 52" width="40px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g><path d="M20.421-0.125c-11.046,0-20,8.954-20,20s20,32,20,32s20-20.954,20-32S31.467-0.125,20.421-0.125z    M20.421,27.875c-5.522,0-10-4.477-10-10s4.478-10,10-10s10,4.477,10,10S25.943,27.875,20.421,27.875z" fill="#231F20"/><path d="M20.421,11.875c-3.309,0-6,2.691-6,6s2.691,6,6,6s6-2.691,6-6S23.729,11.875,20.421,11.875z" fill="#231F20"/></g></svg>''';
    final pictureInfo = await svg.svgPictureStringDecoder(raw, false, null, raw);
    final image = await pictureInfo.picture.toImage(36, 36);
    final byteData = await image.toByteData();
    final uint8List = byteData.buffer.asUint8List();
    return uint8List;
  }

然后将结果传递给标记构造函数后,我得到的只是“默认”红色标记。

Future<Iterable<Marker>> convertPlacesToMarkers(Iterable<Place> places) async {
final markerBytes = await UITools.convertSvg();
return places
    .map((place) => Marker(
      markerId: MarkerId(place.id),
      position: place.latlng,
      icon: BitmapDescriptor.fromBytes(markerBytes),
      onTap: () => onBusStopMarkerTap(place)))
    .toList();

}

有什么想法我在这里做错了吗? 预先感谢您的帮助

2 个答案:

答案 0 :(得分:0)

BitmapDescriptor.fromBytes采用编码为PNG的字节。请尝试

final byteData = await image.toByteData(format: ImageByteFormat.png);

我还使用一种稍微不同的方法来获取DrawableRoot,方法是使用svg.fromSvgString():

DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, null);
Picture picture = svgDrawableRoot.toPicture();
Image image = await picture.toImage(36, 36);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);

答案 1 :(得分:0)

Rednuht的答案仍然是正确的(2020年8月),但有一个例外:大小必须在DrawableRoot.toPicture()中指定,否则Picture不会由Picture.toImage()缩放;

Picture picture = svgDrawableRoot.toPicture(size: Size(36.0,36.0));