前景提要: 项目中要接入一个地图组件,发现flutter的组件并没有js灵活,相关文档也较少。希望我的文章能对大家起到一点帮助,如果有什么问题也欢迎探讨
首先按照官网的内容在项目中配置定位等权限,然后再执行下面步骤
-
插件新增依赖
amap_flutter_map: ^3.0.0
-
配置key值
static const String androidKey = 'xxx';
static const String iosKey = 'xxx';
static const AMapApiKey amapApiKeys =
AMapApiKey(androidKey: androidKey, iosKey: iosKey);
-
添加自定义图片marker
Marker(
position: LatLng(mapCenter.latitude, mapCenter.longitude),
infoWindowEnable: false,
zIndex: 1,
icon: BitmapDescriptor.fromIconPath(Assets.images.car.keyName),
)
-
添加动态文字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),
);
-
添加地图
AMapWidget(
apiKey: amapApiKeys,
onMapCreated: onMapCreated,
markers: markers,
)
-
其他接口能力
- 设置地图显示比例尺层级 api(scaleLevel)
scaleEnabled 比例尺是否显示 TRUE - 设置中心点位置 api
initialCameraPosition: CameraPosition( target: LatLng(mapCenter.latitude, mapCenter.longitude), zoom: 10),- 计算两个经纬度之间的距离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;}