Search code examples
androidmapboxmapbox-android

Aligning Mapbox text SymbolLayer with icon SymbolLayer


I'm presently working on clustering symbols on a Mapbox map using a method similar to this official example. When testing, I have found that the icons and text appear as expected, however the text layer appears to lose its alignment with the icon layer when I interact with, and rotate the map.

I'm making use of the PropertyFactory.iconAnchor and PropertyFactory.iconTranslate properties when creating the SymbolLayer objects. Am I missing a property that is used to ensure these two layers maintain a relative position?

In case it helps, the code that I'm using to create the SymbolLayer objects is as follows:

public List<SymbolLayer> createClusterLevelSymbolLayer(int[] layers) {
    List<SymbolLayer> symbolLayers = new ArrayList<>();

    for (int i = 0; i < layers.length; i++) {
        SymbolLayer symbolLayer = new SymbolLayer("cluster-" + i, "points");
        symbolLayer.setProperties(
                iconImage("circle-15"),
                iconTranslate(new Float[]{1f, 13f}),
                iconSize(1.5f),
                iconAnchor(Property.ICON_ANCHOR_BOTTOM)
        );

        Expression pointCount = toNumber(get("point_count"));
        symbolLayer.setFilter(
                i == 0
                        ? all(has("point_count"),
                        gte(pointCount, literal(layers[i]))
                ) : all(has("point_count"),
                        gt(pointCount, literal(layers[i])),
                        lt(pointCount, literal(layers[i - 1]))
                )
        );
        symbolLayers.add(symbolLayer);
    }

    return symbolLayers;
}

public SymbolLayer createClusterTextLayer() {
    return new SymbolLayer("count", "points").withProperties(
            textField(Expression.toString(get("point_count"))),
            textSize(12f),
            textColor(Color.BLACK),
            textIgnorePlacement(true),
            textAllowOverlap(true),
            textAnchor(Property.TEXT_ANCHOR_BOTTOM)
    );
}

Edit (07/02/2019 @ 10:15am) As per @riastrad's recommendation, please find screenshots of the behaviour that I'm experiencing, below:

Upon booting into the app, the clustered symbol appears just fine, with icon beneath a text layer (aligned well). (Above) Upon booting into the app, the clustered symbol appears just fine, with icon beneath a text layer (aligned well).

(Below) However when gesturing to rotate the map, both icon and text separate until the view/camera position are returned to their starting point

Misaligned text SymbolLayer over icon SymbolLayer (approximate 90 degree rotation)

Misaligned text SymbolLayer over icon SymbolLayer (approximate 180 degree rotation)


Solution

  • I believe this is happening because you are setting a value for icon-translate for your icon SymbolLayer.

    Per the linked documentation, this represents the:

    Distance that the icon's anchor is moved from its original placement.

    So essentially you are anchoring both your text & icon to the bottom, but at the same time you are shifting your icon over by Float[]{1f, 13f}.

    The solution should be to either set the same values for your text-translate or remove it from your icon SymbolLayer altogether.