由於百度地圖flutter插件並沒有提供畫扇形的方式,所以需要自己通過代碼畫扇形,其實futter版本畫出來的也不是扇形,而是三角形
一、百度地圖api里提供的畫的圖形有:
- 繪制點標記 BMFMarker https://lbsyun.baidu.com/index.php?title=flutter/loc/render-map/point
- 繪制線 https://lbsyun.baidu.com/index.php?title=flutter/loc/render-map/ployline
- 繪制弧線和面 https://lbsyun.baidu.com/index.php?title=flutter/loc/render-map/ploygon
二、自己繪制扇形--三角形
通過BMFPloygon
- 構造一個對象,需要經緯度和角度
///經緯度加角度 class LatLngDegree{ double latitude; double longitude; int degree; LatLngDegree({this.latitude, this.longitude, this.degree}); }
-
扇形的圓弧坐標算法
///扇形的圓弧坐標算法 Future<LatLng> offsetBearing(LatLng point, double dist, int bearing) async { //計算1經度與原點的距離 double lngConv = await BMFCalculateUtils.getLocationDistance(BMFCoordinate(point.latitude, point.longitude), BMFCoordinate(point.latitude, point.longitude + 0.1)); //計算1緯度與原點的距離 double latConv = await BMFCalculateUtils.getLocationDistance(BMFCoordinate(point.latitude, point.longitude), BMFCoordinate(point.latitude + 0.1, point.longitude)); //正弦計算待獲取的點的緯度與原點緯度差 double lat = dist * sin(bearing * pi / 180) / latConv; //余弦計算待獲取的點的經度與原點經度差 double lng = dist * cos(bearing * pi / 180) / lngConv; return LatLng(latitude: point.latitude + lat, longitude: point.longitude + lng); }
-
通過一個點構造扇形點集合
///以畫多邊形區域的方法畫扇形區域 //畫出以point點為圓心,radius為半徑,夾角從startAngle到endAngle的扇形 Future<List<LatLng>> sector(LatLng point, double radius, int startAngle, int endAngle) async { //創建構成多邊形的坐標點數組 List<LatLng> sectorPoints = []; //根據扇形的總夾角確定每步夾角度數,最大為10 int step = (endAngle- startAngle)/10 > 10 ? 10 : endAngle- startAngle; sectorPoints.add(point); for (int i = startAngle; i < endAngle + 0.001; i += step) { //循環獲取每步的圓弧上點的坐標,存入點數組 LatLng latLng = await offsetBearing(point, radius, i); sectorPoints.add(latLng); } return sectorPoints; }
-
畫出扇形的方法,通過BMFPolygon
void _drawSector(List<LatLngDegree> mapPoints) async { print('添加扇形-----------'); for(LatLngDegree latLngDegree in mapPoints){ int azimuth1 = 90-latLngDegree.degree-20; int azimuth2 = 90-latLngDegree.degree+20; List<LatLng> sectorPoints = await sector(LatLng(latitude: latLngDegree.latitude, longitude: latLngDegree.longitude), 10, azimuth1, azimuth2); List<BMFCoordinate> coordinates = []; for(LatLng latLng in sectorPoints){ coordinates.add(BMFCoordinate(latLng.latitude, latLng.longitude)); } BMFPolygon bmfPolygon = BMFPolygon(coordinates: coordinates, ); myMapController.addPolygon(bmfPolygon); } }
-
傳入的點是需要畫出的扇形--mapPoints
void addPloyTest(){ List<LatLngDegree> mapPoints = []; mapPoints.add(LatLngDegree(latitude: _lat, longitude: _lng, degree: 0)); mapPoints.add(LatLngDegree(latitude: _lat, longitude: _lng, degree: 120)); mapPoints.add(LatLngDegree(latitude: _lat, longitude: _lng, degree: 240)); _drawSector(mapPoints); }
-
我項目是通過按鈕添加扇形
///測試按鈕 _buildTestButton(){ return Positioned( right: 20.w, bottom: 200.h, child: ElevatedButton(onPressed: (){addPloyTest();}, child: Text("按鈕添加扇形"))); }
三、另外我真的需要用到請求后台數據獲取點的時候,畫扇形,需要一個視口經緯度范圍
1.獲取手機地圖視口經緯度訪問的方法
///獲取視口邊界坐標 void _getMapBounds() async { BMFCoordinateBounds visibleMapBounds = await myMapController?.getVisibleMapBounds(); if(visibleMapBounds != null){ print("視口邊界"); _northeast = visibleMapBounds.northeast; _southwest = visibleMapBounds.southwest; print("northeast-----------------latitude" + _northeast.latitude.toString() + "--------longitude" + _northeast.longitude.toString()); print("southwest-----------------latitude" + _southwest.latitude.toString() + "--------longitude" + _southwest.longitude.toString()); } }