使用Flutter Google Maps在屏幕上放置标记

15

我正在尝试使用Google Maps for Flutter进行实验。我希望地图视图适应屏幕上的所有标记。基本上,我想要做与这里在安卓中所做的相同的事情。

我假设cameraTargetBounds描述了应该适合屏幕边界内的区域。但实际上,它并没有完全适配该区域,而是聚焦于中间某处。

到目前为止,我已经做了什么:

  @override
  Widget build(BuildContext context) {
    final bloc = Provider.of<BlocMap>(context);
    return SafeArea(
      child: Container(
        child: Stack(
          children: <Widget>[
            Positioned.fill(
              child: StreamBuilder<MapData>(
                  stream: bloc.mapData,
                  builder: (context, snap) {
                    final mapData = snap.data;
                    print("mapData: $mapData");
                    return GoogleMap(
                      padding: EdgeInsets.only(bottom: 42),
                      mapType: _mapType,
                      cameraTargetBounds: mapData?.markers == null
                          ? CameraTargetBounds.unbounded
                          : CameraTargetBounds(_bounds(mapData?.markers)),
                      initialCameraPosition: _cameraPosition,
                      myLocationEnabled: true,
                      myLocationButtonEnabled: true,
                      gestureRecognizers: _buildGestureRecognizer(),
                      onMapCreated: (GoogleMapController controller) {
                        _controller.complete(controller);
                      },
                      markers: mapData?.markers,
                      polylines: mapData?.polylines,
                      polygons: mapData?.polygons,
                      onLongPress: (latLng) {
                        print("LatLng: $latLng");
                      },
                    );
                  }),
            ),
            Positioned(
              left: 0,
              right: 0,
              bottom: 0,
              child: _buildBtnBar(),
            )
          ],
        ),
      ),
    );

    LatLngBounds _bounds(Set<Marker> markers) {
    if (markers == null || markers.isEmpty) return null;
    return _createBounds(markers.map((m) => m.position).toList());
  }


 LatLngBounds _createBounds(List<LatLng> positions) {
    final southwestLat = positions.map((p) => p.latitude).reduce((value, element) => value < element ? value : element); // smallest
    final southwestLon = positions.map((p) => p.longitude).reduce((value, element) => value < element ? value : element);
    final northeastLat = positions.map((p) => p.latitude).reduce((value, element) => value > element ? value : element); // biggest
    final northeastLon = positions.map((p) => p.longitude).reduce((value, element) => value > element ? value : element);
    return LatLngBounds(
        southwest: LatLng(southwestLat, southwestLon),
        northeast: LatLng(northeastLat, northeastLon)
    );
  }

在Flutter中,实现这种基本功能的预期方法是什么?有什么建议吗?

3个回答

9

使用此代码实现您想要的功能。

onMapCreated: (GoogleMapController controller) {
   _controller.complete(controller);

   setState(() {
      controller.animateCamera(CameraUpdate.newLatLngBounds(_bounds(markers), 50));
   });
}

3

尝试使用控制器将相机移动到新的边界,例如(来自插件示例):

mapController.moveCamera(
  CameraUpdate.newLatLngBounds(
    LatLngBounds(
      southwest: const LatLng(-38.483935, 113.248673),
      northeast: const LatLng(-8.982446, 153.823821),
    ),
    10.0,
  ),
);

2

首先,创建一个包含经纬度的列表,并将其传递给指定的方法。

List<LatLng> latlonList = [LatLng(125.75,87.00),LatLng(165,46.76),LatLng(175.87,86.00),];

    final GoogleMapController googleMapController = await widget.completer.future;
        googleMapController.moveCamera(CameraUpdate.newLatLngBounds(
          MapUtils.boundsFromLatLngList(latlonList),
            4.0,
            ),
          );

之后您的地图将移动到所有指针。但为了更好地显示更多标记,我们使用另一种方法,该方法给出所有标记的中心点。
 var centerPoint =  computeCentroid(latlonList);

  var  zoom = await googleMapController.getZoomLevel();

this.updateLocation(centerPoint.latitude, centerPoint.longitude,zoom -2);  

现在只需复制这些方法,一切都可以完美地运行。
LatLng computeCentroid(Iterable<LatLng> points) {
  double latitude = 0;
  double longitude = 0;
  int n = points.length;

  for (LatLng point in points) {
    latitude += point.latitude;
    longitude += point.longitude;
  }

  return LatLng(latitude / n, longitude / n);
}


    class MapUtils {
       static LatLngBounds boundsFromLatLngList(List<LatLng> list) {
        double? x0, x1, y0, y1;
        for (LatLng latLng in list) {
          if (x0 == null) {
            x0 = x1 = latLng.latitude;
            y0 = y1 = latLng.longitude;
          } else {
            if (latLng.latitude > x1!) x1 = latLng.latitude;
            if (latLng.latitude < x0) x0 = latLng.latitude;
            if (latLng.longitude > y1!) y1 = latLng.longitude;
            if (latLng.longitude < y0!) y0 = latLng.longitude;
          }
        }
        return LatLngBounds(northeast: LatLng(x1!, y1!), southwest: LatLng(x0!, y0!));
      }
    }
  updateLocation(double latitude,double longitude,double zoom) async {

    final GoogleMapController googleMapController = await widget.completer.future;
     print("zoom$zoom");
    googleMapController.animateCamera(CameraUpdate.newCameraPosition(
      CameraPosition(
        bearing: 0,
        target: LatLng(latitude,longitude),
        zoom:zoom,
      ),
    ));
    
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接