Mapbox Flutter: How to Show Popup on Feature Tap?

143 Views Asked by At

I am working on a Flutter application using using the mapbox_gl: ~0.16.0 plugin, and I'm having difficulty implementing a feature where a popup is displayed when a user taps on a feature on the map. As I was unable to locate any suitable plugin-based popup control or similar functionality, I am unsure of how to incorporate that specific feature. Here is a simplified version of my code:

/* view code */
 MapboxMap(
  onMapCreated: (mController) {
    mapboxMapController = mController;
    controller.onMapCreated(mController);
  },
  zoomGesturesEnabled: true,
  accessToken: "<MAPBOX ACCESS TOKEN>",
  initialCameraPosition: const CameraPosition(
      target:
          LatLng(47.59051426075817, -107.77329953835964),
      zoom: 15.0),
  trackCameraPosition: true,
  onCameraIdle: () {
    controller.getView(mapboxMapController);
  },
  styleString:
      "mapbox://styles/mapbox/outdoors-v12?optimize=true&attribution=false&logo=false",
  rotateGesturesEnabled: false, // Allow rotation gestures
  tiltGesturesEnabled: false, // Allow tilt gestures
);
/* view code */

/* controller code */
 void onMapCreated(MapboxMapController mapboxMap) async {
  var bounds = await mapboxMap.getVisibleRegion();

  double northeastLat = bounds.northeast.latitude;
  double northeastLng = bounds.northeast.longitude;
  double northwestLat = bounds.northeast.latitude;
  double northwestLng = bounds.southwest.longitude;
  double southeastLat = bounds.southwest.latitude;
  double southeastLng = bounds.northeast.longitude;
  double southwestLat = bounds.southwest.latitude;
  double southwestLng = bounds.southwest.longitude;

  String queryString =
      "myAPI.php?northeastLat=$northeastLat&northeastLng=$northeastLng&"
      "northwestLat=$northwestLat&northwestLng=$northwestLng&"
      "southeastLat=$southeastLat&southeastLng=$southeastLng&"
      "southwestLat=$southwestLat&southwestLng=$southwestLng&"
      "zmLvl=15&uid=100";

  Map<String, dynamic> mappedData = {};

  var servResJson = await sendDataServer(queryString, mappedData);
  var servRes = jsonDecode(jsonEncode(servResJson.data));
  geojson = Map<String, Object>.from(servRes);

  await Future.wait([
    mapboxMap.removeLayer("fills-count"),
    mapboxMap.removeLayer("fills-circle"),
    mapboxMap.removeLayer("fills-fills"),
    mapboxMap.removeSource("fills"),
    mapboxMap.addSource(
      "fills",
      GeojsonSourceProperties(
        data: geojson,
      ),
    ),
    mapboxMap.addFillLayer(
      "fills",
      "fills-fills",
      FillLayerProperties(
        fillColor: [
          "match",
          ["get", "status"],
          1, statusColors[1], // Status 1 - Blue
          2, statusColors[2], // Status 2 - Yellow
          3, statusColors[3], // Status 3 - Green
          4, statusColors[4], // Status 4 - Transparent
          convertColorToRgba(
              const Color.fromARGB(128, 246, 246, 246), 0), // Default color
        ],
        fillAntialias: true,
        fillOpacity: 0.6,
        fillOutlineColor: 'rgba(0, 0, 0, 1)',
      ),
      filter: ["has", "status"],
      enableInteraction: true,
    ),
  ]);
  
  update();
}
/* controller code */

This is my sample GeoJSON response from API:

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "id": "56019",
            "status": 2,
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            -107.774000467,
                            47.598100673
                        ],
                        [
                            -107.765000467,
                            47.598100673
                        ],
                        [
                            -107.765000467,
                            47.589100673
                        ],
                        [
                            -107.774000467,
                            47.589100673
                        ],
                        [
                            -107.774000467,
                            47.598100673
                        ]
                    ]
                ]
            },
            "properties": {
                "dbId": "56019",
                "status": 2,
                "uid": 100,
                "isBlocked": 0,
                "id": "56019",
                "left": -107.774000467,
                "top": 47.598100673,
                "right": -107.765000467,
                "bottom": 47.589100673
            }
        },
        // some more items
    ]
}

I want to display a popup with id from the tapped feature when a user taps on a feature on the Mapbox map. Any help or guidance would be greatly appreciated.

I am not sure what to do with this code block since when I try it, all I receive is the feature/property id.Is it possible to display a popup that comes with the package without creating a new dialog widget?

mapboxMap.onFeatureTapped.add((id, point, coordinates) {
  if (id != null) {
    debugPrint(
        'Tapped feature with ID - $id, Point - $point, Coordinates - $coordinates');
  }
});

I have a requirement like this (*Right now, it's sufficient to only display the ID in the popup; I can handle the remaining portion.):

This is what i want

1

There are 1 best solutions below

5
SilkeNL On