Я хочу разместить маркеры, используя изображения .svg в качестве значков. Я использую библиотеку google_maps_flutter. Это работало с преобразованными изображениями .png, но я не нашел способа напрямую использовать файлы .svg.
Пишу сюда после прочтения этого выпуска: Использование маркеров SVG в google_maps_flutter Плагин Flutter
И пытаюсь использовать метод fromAssetImage, как описано в этой теме: Как изменить размер значка маркера Google Map во Flutter?
Я надеялся, что эта новая версия библиотеки поможет решить мою проблему.
Я попытался решить это с помощью следующего кода:
Класс MapWidget
for (Place place in widget.places) {
place.toMarker(
context,
() => _onPlaceTapped(place),
).then(setState((){
markerSet.add
}));
}
Место класса
Future<Marker> toMarker(BuildContext context, VoidCallback onTap) async {
return Marker(
markerId: MarkerId(id.toString()),
position: LatLng(lat, lon),
icon: await category.markerIcon(createLocalImageConfiguration(context)),
onTap: onTap,
);
Класс категории
Future<BitmapDescriptor> markerIcon(ImageConfiguration configuration) async {
BitmapDescriptor b;
switch (type) {
case CategoryType.FirstCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-first.svg');
break;
case CategoryType.SecondCategory:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-second.svg');
break;
default:
b = await BitmapDescriptor.fromAssetImage(configuration, 'assets/markers/marker-third.svg');
break;
}
return b;
}
Если вам интересно, путь к изображениям уже добавлен в pubspec.yaml.
Я ожидал, что красные маркеры Google по умолчанию будут заменены некоторыми пользовательскими маркерами (на каждом пользовательском маркере должно быть небольшое изображение значка) на карте, однако отображаются только маркеры по умолчанию (не по умолчанию в операторе switch, я говорю о маркеры Google по умолчанию).
Нет сообщения об ошибке при использовании симулятора iOS и версии библиотеки google_maps_flutter 0.5.15+1.
Возможный дубликат Использование маркеров SVG в google_maps_flutter Плагин Flutter
Действительно, мы говорим об одном и том же. Я попробовал то, что было рекомендовано в этом посте, но это не сработало для меня. Поэтому я подумал, что могу создать пост, показывающий код, который я пробовал. В таком случае мне закрывать тему? Я вижу, что есть новые ответы, так что я мог бы найти там свое решение сейчас.
Вы пробовали использовать flutter_svg? Я полагаю, что ответ с использованием этого пакета еще не был опубликован на момент создания вашего вопроса.
Да, это не так. Я имел в виду свою ситуацию в то время. Я попробую ваше решение, как только смогу.
Большое спасибо @rednuht! Это сработало как шарм. Поскольку я еще не могу прокомментировать ваш ответ (<50 повторений), я скажу вам здесь переименовать drawableRoot как svgDrawableRoot и, возможно, добавить комментарий о том, что размеры, используемые в picture.toPicture(32, 32), должны быть тщательно выбраны, иначе победит изображение svg. не отображаться целиком.
У вас есть идея, как масштабировать полученное изображение вверх и вниз? Мои маркеры слишком малы, когда я использую изображение svg.
Я также обнаружил, что масштабирование сложно. DrawableRoot.toPicture() принимает аргумент размера, который вы можете установить в дополнение к параметрам размера в picture.toImage(). Кажется, ни один из них не принимает во внимание соотношение пикселей устройства. Поэтому вам нужно получить соотношение пикселей из MediaQuery и умножить его на желаемый размер. Я обновил ответ, чтобы отразить это.



Ответ на этот вопрос вы можете найти здесь:
Использование маркеров SVG в google_maps_flutter Плагин Flutter
Я попробовал ответ Реднухта, и это сработало как шарм.
РЕДАКТИРОВАТЬ (резюме)
Ответ требует использования плагина flutter_svg (мне показалось, что ^ 0.13 или 0.14.1 работает).
Во-первых, создайте функцию, которая даст вам BitmapDescriptor из актива. Убедитесь, что ресурс объявлен в вашем файле pubspec.
import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
Future<BitmapDescriptor> _bitmapDescriptorFromSvgAsset(BuildContext context, String assetName) async {
String svgString = await DefaultAssetBundle.of(context).loadString(assetName);
//Draws string representation of svg to DrawableRoot
DrawableRoot svgDrawableRoot = await svg.fromSvgString(svgString, null);
ui.Picture picture = svgDrawableRoot.toPicture();
ui.Image image = await picture.toImage(26, 37);
ByteData bytes = await image.toByteData(format: ui.ImageByteFormat.png);
return BitmapDescriptor.fromBytes(bytes.buffer.asUint8List());
}
Я создал экземпляр объекта Map в начале своего приложения, чтобы использовать BitmapDescriptors без большого количества вызовов async/await.
data_model.dart
Map<CategoryType, BitmapDescriptor> descriptors = Map<Category, BitmapDescriptor>();
Future<void> loadBitmapDescriptors(context) async {
descriptors[CategoryType.FirstCatgory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-first.svg');
descriptors[CategoryType.SecondCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-second.svg');
descriptors[CategoryType.ThirdCategory] = await _bitmapDescriptorFromSvgAsset(context, 'assets/markers/marker-third.svg');
}
основной дротик
DataModel.of(context).loadBitmapDescriptors(context);
Так что все, что мне нужно было сделать после этого, это правильно вызвать его, когда это необходимо.
Marker marker = Marker(markerId: MarkerId(id.toString()), icon: descriptors[category], position: LatLng(lat, lon));
Пожалуйста, кратко опишите содержание, так как ссылка может быть устаревшей.
У меня была та же проблема, и я закончил с этой реализацией из-за того, что без de devicePixelRatio он показывал пиксельные маркеры.
Future<BitmapDescriptor> getBitmapDescriptorFromSVGAsset(
BuildContext context,
String svgAssetLink, {
Size size = const Size(30, 30),
}) async {
String svgString = await DefaultAssetBundle.of(context).loadString(
svgAssetLink,
);
final drawableRoot = await svg.fromSvgString(
svgString,
'debug: $svgAssetLink',
);
final ratio = ui.window.devicePixelRatio.ceil();
final width = size.width.ceil() * ratio;
final height = size.height.ceil() * ratio;
final picture = drawableRoot.toPicture(
size: Size(
width.toDouble(),
height.toDouble(),
),
);
final image = await picture.toImage(width, height);
final byteData = await image.toByteData(format: ui.ImageByteFormat.png);
final uInt8List = byteData.buffer.asUint8List();
return BitmapDescriptor.fromBytes(uInt8List);
}
BitmapDescriptor.fromAssetImage() не работает с файлами SVG. Пожалуйста, проверьте мой ответ на вопрос, который вы связали: stackoverflow.com/a/57609840/2344535