Skip to content

#83 Disable draggabledAnnotationController#86

Merged
louwers merged 1 commit into
maplibre:mainfrom
ravenfeld:fix/83_performance_draggable
Sep 16, 2025
Merged

#83 Disable draggabledAnnotationController#86
louwers merged 1 commit into
maplibre:mainfrom
ravenfeld:fix/83_performance_draggable

Conversation

@ravenfeld
Copy link
Copy Markdown
Contributor

As mentioned in issue #83, even annotations that don't use drag are passed through functions, and this has an impact on performance.

  • At each source update, check that there is at least one draggable annotation to activate

We could give the developer the option to skip this loop altogether, but that would create a breaking change.
Does the developer need to remember to activate a + symbol in the manager for this to work? Wouldn't that be too confusing ?

@ravenfeld
Copy link
Copy Markdown
Contributor Author

@louwers any news ?

@louwers
Copy link
Copy Markdown
Member

louwers commented Sep 5, 2025

@ravenfeld Could you clarify the impact on existing users of the annotations plugin? Is this a breaking change?

@ravenfeld
Copy link
Copy Markdown
Contributor Author

So no, there are no changes for current users.
Those who haven't added draggable annotations will see the app perform better, like the @amousavi update.
For others, it will work as before.

@louwers louwers requested a review from amousavi September 16, 2025 12:08
@louwers
Copy link
Copy Markdown
Member

louwers commented Sep 16, 2025

@amousavi Will merge and cut a release if you can also approve. Thanks!

@louwers louwers merged commit 333b9c3 into maplibre:main Sep 16, 2025
1 check passed
@JacobGeoGeek
Copy link
Copy Markdown

Do you have any updates on that? I'm not sure if this PR will resolve my issue, but here's the long story: I'm unable to drag a symbol properly on the map.

@amousavi
Copy link
Copy Markdown

Hi @JacobGeoGeek, what exactly do you see wrong? This MR will simply disable the drag and drop detection if there's no listener for it, but looking over the code there could be other issues, explained in my original analysis.

@JacobGeoGeek
Copy link
Copy Markdown

@amousavi, for some reason, the drag feature does not work correctly with all the symbols I created (see the attached video).

https://github.com/user-attachments/assets/4712d1c3-bdfc-49bc-8003-038e03bd912b. In my class, I haveimplementedt the OnDragListener like:

public class SymbolCreator implements OnSymbolDragListener {

    public interface OnSymbolPositionChange {
        void updateSymbolAtIndex(Symbol symbol, int index);
    }

    private SymbolManager symbolManager = null;
    private MapLibreMap mapLibreMap;
    private final OnSymbolPositionChange onSymbolPositionChange;
    private final OnSymbolClickListener onSymbolClickListener;
    private int symbolCount = 0;
    private boolean shouldUpdate = true;

    public SymbolCreator(OnSymbolPositionChange onSymbolPositionChange, OnSymbolClickListener onSymbolClickListener) {
        this.onSymbolPositionChange = onSymbolPositionChange;
        this.onSymbolClickListener = onSymbolClickListener;
    }

    public void draw(MapView mapView, MapLibreMap mapLibreMap, Style style, List<Point> points, Drawable drawable) {
        initSymbolManager(mapView, mapLibreMap, style, drawable);
        symbolCount = 0;

        for (Point point : points) {
            createSymbol(point);
        }
    }

    private void initSymbolManager(MapView mapView, MapLibreMap mapLibreMap, Style style, Drawable drawable) {
        style.addImage(AppConstants.ID_ICON_EDIT_POINT, drawable);
        this.mapLibreMap = mapLibreMap;
        this.symbolManager = new SymbolManager(mapView, mapLibreMap, style);
        this.symbolManager.setIconIgnorePlacement(true);
        this.symbolManager.setIconAllowOverlap(true);
        this.symbolManager.setTextAllowOverlap(true);
        this.symbolManager.addClickListener(onSymbolClickListener);
        this.symbolManager.addLongClickListener(symbol -> {
            Log.d("SymbolCreator", "Symbol long clicked: " + symbol.getId());
            this.symbolManager.update(symbol);
            this.mapLibreMap.getUiSettings().setAllGesturesEnabled(false);
            this.mapLibreMap.getGesturesManager().getMoveGestureDetector().interrupt();
            symbol.setIconSize(0.6f);
            symbol.setTextSize(24f);
            // symbol.setTextOffset(new PointF(0f, -0.5f));
            symbol.setDraggable(true);
            return true;
        });

        this.symbolManager.addDragListener(this);
    }

    private void createSymbol(Point point) {
        SymbolOptions symbolOptions = new SymbolOptions()
                .withGeometry(point)
                .withIconImage(AppConstants.ID_ICON_EDIT_POINT)
                .withIconSize(0.4f)
                .withIconAnchor(ICON_ANCHOR_BOTTOM)
                .withTextField(String.valueOf(++symbolCount))
                .withIconOffset(new Float[]{0f, -1f})
                .withTextSize(16f)
                .withTextOffset(new Float[]{0f, -0.5f})
                .withTextAnchor(TEXT_ANCHOR_BOTTOM)
                .withTextColor("#000000");
//                .withTextFont(new String[]{"Open Sans Regular", "Arial Unicode MS Regular"});
        symbolManager.create(symbolOptions);
    }

    public void delete(Symbol symbol) {
        symbolManager.delete(symbol);
        symbolCount = 0;

        LongSparseArray<Symbol> annotations = symbolManager.getAnnotations();
        for (int i = 0; i < annotations.size(); i++) {
            long key = annotations.keyAt(i);
            Symbol annotation = annotations.get(key);
            if (annotation != null) {
                annotation.setTextField(String.valueOf(++symbolCount));
            }
        }
    }

    public void clear() {
        symbolCount = 0;
        if (symbolManager != null) {
            symbolManager.deleteAll();
            symbolManager = null;
        }
    }

    @Override
    public void onAnnotationDragStarted(Symbol symbol) {
        Log.d("SymbolCreator", "Symbol drag started: " + symbol.getId());
        this.mapLibreMap.getUiSettings().setAllGesturesEnabled(false);
        shouldUpdate = true;
    }

    @Override
    public void onAnnotationDrag(Symbol symbol) {
        Log.d("SymbolCreator", "Symbol drag: " + symbol.getId());
    }

    @Override
    public void onAnnotationDragFinished(Symbol symbol) {
        Log.d("SymbolCreator", "Symbol drag finished: " + symbol.getId());
        this.mapLibreMap.getUiSettings().setAllGesturesEnabled(true);
        if (shouldUpdate) {
            shouldUpdate = false;
            symbol.setIconSize(0.4f);
            symbol.setTextSize(16f);
            symbol.setTextOffset(new PointF(0f, -0.5f));

            symbol.setDraggable(false);
            int index = symbolManager.getAnnotations().indexOfValue(symbol);
            onSymbolPositionChange.updateSymbolAtIndex(symbol, index);
            symbolManager.update(symbol);
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants