Mapbox颤振:摄像机的初始位置显示了错误的位置

时间:2020-09-23 17:51:45

标签: android ios flutter geolocation mapbox

我正在使用mapbox_gl,这是一个Flutter插件,用于访问Mapbox服务。应用程序需要显示通过geolocator插件从用户当前位置获取的初始摄像机位置。在Android模拟器上,将当前位置设置为斯洛文尼亚卢布尔雅那的坐标(大约46N,13E)会显示刚果共和国地图,这显然是错误的。

Initial camera location which should display Ljubljana, Slovenia, but it insteads displays a map of Republic of the Congo

MapboxMap小部件的构建方式如下:

class HomeScreen extends StatelessWidget {
  final String mapboxToken = 'XXX-TOKEN-XXX';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: _acquireCurrentPosition(),
        builder: (BuildContext context, AsyncSnapshot snapshot) =>
            snapshot.hasData
                ? MapboxMap(
                    accessToken: mapboxToken,
                    minMaxZoomPreference: MinMaxZoomPreference(6.0, 15.0),
                    compassEnabled: false,
                    initialCameraPosition: CameraPosition(
                      target: snapshot.data,
                    ),
                  )
                : Center(
                    child: CircularProgressIndicator(),
                  ),
      ),
    );
  }
  
  Future<LatLng> _acquireCurrentPosition() async {
    Position position = await getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );
    return LatLng(position.latitude, position.longitude);
  }
}

方法_acquireCurrentPosition()正确获取纬度/经度组合,并已在Android模拟器,iOS Simulator甚至物理Android设备(Xiaomi Redmi Note 8 Pro)上进行了测试。即使使用其他位置,相机初始位置的错误仍然存​​在。

非常感谢您提供任何帮助。

1 个答案:

答案 0 :(得分:0)

一些解决方法后,我设法通过以下步骤确定并解决了问题:

首先,删除geolocator软件包并用location软件包替换,并通过在AndroidManifest.xml中提及它们来明确声明Android和iOS上的位置许可。

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Info.plist

<key>NSLocationWhenInUseUsageDescription</key>
<string>Shows your location on the map and helps improve the map</string>

接下来,您可以使用initialCameraPosition回调函数来代替通过onMapCreated参数设置摄像机的初始位置:

// This is how you'd build the MapboxMap widget
MapboxMap(
  accessToken: mapboxToken,
  onMapCreated: (controller) {
    _acquireCurrentLocation().then((LatLong location) {
      if (location != null) {
        controller.animateCamera(
          CameraUpdate.newCameraPosition(
            CameraPosition(
              target: location,
            ),
          ),
        );
      }
    }).catchError((error) => print(error));
  },
  minMaxZoomPreference: MinMaxZoomPreference(6.0, 15.0),
  initialCameraPosition: CameraPosition(
    target: LatLng(45.45, 45.45),
  ),
);

// Method that uses location plugin
Future<LatLng> _acquireCurrentLocation() async {
  Location location = new Location();

  bool serviceEnabled;
  PermissionStatus permissionGranted;
  LocationData locationData;

  serviceEnabled = await location.serviceEnabled();
    if (!serviceEnabled) {
      serviceEnabled = await location.requestService();
      if (!serviceEnabled) {
        return null;
      }
    }

  permissionGranted = await location.hasPermission();
  if (permissionGranted == PermissionStatus.denied) {
    permissionGranted = await location.requestPermission();
    if (permissionGranted != PermissionStatus.granted) {
      return null;
    }
  }

  locationData = await location.getLocation();
  return LatLng(locationData.latitude, locationData.longitude);
}

我个人的建议是将Android的最低SDK版本更改为23。