elle D
elle D

Reputation: 57

Flutter: Mapbox Cluster and click event on unclustered point

I use this code to have clusters:

for (int index = 0; index < punti_di_interesse.length; index++) {
   var point = {
        "type": "Feature",
        "id": index,
        "properties": {
          "id": index,
          "name": punti_di_interesse[index].name,
          'descrizione': punti_di_interesse[index].descrizione,
        },
        "geometry": {
          "type": "Point",
          "coordinates": [
            punti_di_interesse[index].longitude,
            punti_di_interesse[index].latitude,
            0.0
          ]
        }
   };
   allSymbolGEOJSON.add(point);
}
var allPoints = {
      "type": "FeatureCollection",
      "crs": {
        "type": "name",
        "properties": {"name": "urn:ogc:def:crs:OGC:1.3:CRS84"}
      },
      "features": allSymbolGEOJSON,
};
var source = await controller.addSource(
      "earthquakes",
      GeojsonSourceProperties(
          data: allPoints,
          cluster: true,
          clusterMaxZoom: 14,
          clusterRadius: 50, 
          ),
);
await controller.addLayer(
      "earthquakes",
      "clusters",
      CircleLayerProperties(circleColor: [
        Expressions.step,
        [Expressions.get, 'point_count'],
        '#51bbd6',
        100,
        '#f1f075',
        750,
        '#f28cb1'
      ], circleRadius: [
        Expressions.step,
        [Expressions.get, 'point_count'],
        20,
        100,
        30,
        750,
        40
      ]),
);
await controller.addLayer(
        "earthquakes",
        "cluster-count",
        SymbolLayerProperties(
          textField: [Expressions.get, 'point_count_abbreviated'],
          textSize: 12,
));

await controller.addSymbolLayer(
      "earthquakes",
      "unclustered-point",
      SymbolLayerProperties(
        textField: [Expressions.get, "name"],
        textHaloWidth: 1,
        textSize: 12.5,
        textHaloColor: '#ffffff',
        textOffset: [
          Expressions.literal,
          [0, 2]
        ],
        iconImage: "assets/icona_stato-rosso.png",
        iconSize: 2,
        iconAllowOverlap: true,
        textAllowOverlap: true,
        textColor: '#000000',
        textHaloBlur: 1,
      ),
      filter: [
        '!',
        ['has', 'point_count']
      ],
      enableInteraction: true,
);

Under my custom iconImage I see a black dot, how can this be removed?

In addition, I need that when the iconImage is clicked, a modal opens with information that is contained in the data structure in "properties" I have tried using controller.onFeatureTapped.add(onFeatureTap);

but in the onFeatureTap function how do I access properties from featureId, point or latLng?

Am I doing something wrong?

Upvotes: 0

Views: 1057

Answers (1)

Ben
Ben

Reputation: 38

For anyone stumbling across this problem, i figured out the following: the CircleLayerProperties set a standard #000000 color value for circles. This together with the fact that you recolor everything with a point_count (which singular symbols do not have) leads to the CircleLayer drawing a black circle.

To fix this, use expressions to set the circleOpacity to 0.0 for all the unclustered symbols like so:

circleOpacity: [
          "case",
          ["has", "point_count"],
          1.0,
          [
            "!",
            ["has", "point_count"]
          ],
          0.0,
          1.0
        ]

Edit: To your second point, i can shed some light there too: in general, your are on the right path, but let me put together a more complete example for everyone:

First, define your GeoJson with an id:

var point = {
    "type": "Feature",
    "id": index,
    "properties": {
      ...
    },
    "geometry": {
      ...
    }
};

Then, add a listener to your MapController:

mapController.onFeatureTapped.add((id, point, coordinates) {
  print(id);
}

The print(id) in the above handler will then print the id you defined in your GeoJson (or the id of a cluster, if applicable).

Hope that helps someone!

Upvotes: 1

Related Questions