高德地图Flutter插件实现绘制圆
高德地图Flutter插件中目前的文档当中只提供了绘制线、面的功能,并未提供绘制圆的功能。但是目前有一个功能需要根据中心点与半径绘制圆,所以利用其提供的Polygon API实现绘制圆。具体的实现代码如下,希望能给有类似需求的小伙伴提供一种解决方案。
///Created by Qiaozi 20210930
import 'dart:math' as Math;
import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:great_circle_distance2/great_circle_distance2.dart';
import 'package:workstyle/util/color.dart';
import 'package:workstyle/util/constant.dart';
import 'logic.dart';
class RelocationPage extends StatefulWidget {
const RelocationPage({Key key}) : super(key: key);
@override
_RelocationPageState createState() => _RelocationPageState();
}
class _RelocationPageState extends State<RelocationPage> {
AMapController _mapController;
Map<String, Polygon> _polygons = <String, Polygon>{};
String selectedPolygonId;
@override
Widget build(BuildContext context) {
///构建打卡范围坐标集合
_add();
final AMapWidget amap = AMapWidget(
apiKey: AMapApiKey(androidKey: Constant.amapApiKeys, iosKey: Constant.amapApiKeys),
onMapCreated: onMapCreated,
///将多边形添加到地图中
polygons: Set<Polygon>.of(_polygons.values),
);
_changeCameraPosition();
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.1,
width: MediaQuery.of(context).size.width,
child:Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
brightness: Brightness.light,
elevation: 0.2,
leading: IconButton(
icon:materialColor['backIcon'],
onPressed: () {
Get.back();
}),
title: Text('绘制圆', style: materialColor['centerTitle'],),
centerTitle: true,
),
),
),
Container(
height: MediaQuery.of(context).size.height * 0.9,
width: MediaQuery.of(context).size.width,
child: amap,
),
],
),
);
}
void onMapCreated(AMapController controller) {
setState(() {
_mapController = controller;
getApprovalNumber();
});
}
/// 获取审图号
void getApprovalNumber() async {
//普通地图审图号
String mapContentApprovalNumber =
await _mapController?.getMapContentApprovalNumber();
//卫星地图审图号
String satelliteImageApprovalNumber =
await _mapController?.getSatelliteImageApprovalNumber();
setState(() {
if (null != mapContentApprovalNumber) {
_approvalNumberWidget.add(Text(mapContentApprovalNumber));
}
if (null != satelliteImageApprovalNumber) {
_approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
}
});
print('地图审图号(普通地图): $mapContentApprovalNumber');
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
}
///创建打卡范围坐标点集合
_add(){
final Polygon polygon = Polygon(
strokeColor: Colors.green,
fillColor: Colors.grey.withOpacity(0.3),
strokeWidth: 2,
points: _createPoints(),
);
setState(() {
selectedPolygonId = polygon.id;
_polygons[polygon.id] = polygon;
});
}
///创建坐标点
List<LatLng> _createPoints(){
///controller.state.zone.value:半径
///controller.state.lat.value 中心点经度
///controller.state.lng.value 中心点纬度
final List<LatLng> points = <LatLng>[];
double r = 6371000.79;
int numpoints = 360;
double phase = 2 * Math.pi / numpoints;
for(int i=0; i<numpoints;i++){
///计算坐标点
double dx = (controller.state.zone.value * Math.cos(i * phase));
double dy = (controller.state.zone.value * Math.sin(i * phase));//乘以1.6 椭圆比例
///转换成经纬度
double dlng = dx / (r * Math.cos(controller.state.lat.value * Math.pi / 180) * Math.pi / 180);
double dlat = dy / (r * Math.pi / 180);
double newlng = controller.state.lng.value + dlng;
double newlat = controller.state.lat.value + dlat;
points.add( LatLng(newlat,newlng));
}
return points;
}
}