Skip to content

Conversation

gabbopalma
Copy link
Contributor

@gabbopalma gabbopalma commented Jul 30, 2025

Features

  • Added addImages method to support loading multiple images at once
  • Added aboveLayerId parameter to addLayer method for more flexible layer positioning
  • Updated example app to demonstrate both features

Changes

  • StyleController: New addImages method to add multiple images in a single call
  • StyleController: Extended addLayer to support positioning layers both above and below existing layers
  • Example pages updated to use new addImages method with multiple pins

Examples

Adding multiple images

// Load multiple pin images at once
final images = <String, Uint8List>{
  'red_pin': await http.readBytes(Uri.parse('red_pin_url')),
  'black_pin': await http.readBytes(Uri.parse('black_pin_url')),
};

await style.addImages(images);

Layer positioning

// Add layer above another layer
await style.addLayer(
  SymbolLayer(
    id: 'markers',
    sourceId: 'points',
    aboveLayerId: 'labels', //! Only supported on Android
  ),
);

// Add layer below another layer
await style.addLayer(
  SymbolLayer(
    id: 'markers',
    sourceId: 'points',
    belowLayerId: 'buildings',
  ),
);

TODO

  • Implement JNI communication for addImage and addImages methods
  • Update example app and test to demonstrate the new aboveLayerId parameter
  • Update documentation with platform-specific details

Note: This PR is currently in draft status while working on the JNI implementation for image handling

Copy link

codecov bot commented Jul 30, 2025

Codecov Report

❌ Patch coverage is 63.51351% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 50.60%. Comparing base (06e0289) to head (6039876).

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gabbopalma
Copy link
Contributor Author

gabbopalma commented Jul 30, 2025

Hi @josxha, since we are currently using jni in style_controller.dart for the addLayer method, can we remove the addLayer methods from MapLibreHostApi=
I actually updated them into MapLibreHostApi too, to be safe.

The same applies now that we have switched to JNI for the addImage and addImages methods.
Furthermore, from this PR onwards, MapLibreHostApi is no longer used in StyleControllerAndroid, generating a warning.

@gabbopalma gabbopalma marked this pull request as ready for review July 30, 2025 14:53
@Copilot Copilot AI review requested due to automatic review settings July 30, 2025 14:53
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces formatting changes to automatically generated JNI Dart bindings files, improving code readability by adding multi-line parameter formatting for constructors, methods, and function calls. The changes are purely cosmetic, affecting code style without altering functionality.

@josxha josxha added this to the v0.3.0 milestone Sep 1, 2025
@josxha
Copy link
Owner

josxha commented Sep 21, 2025

Hi @gabbopalma, thanks for enhancing the functionality. Sorry for taking me that long to respond. You wrote a couple of unchecked bulletpoints in the pr description. What is the current state of this pr?

Hi @josxha, since we are currently using jni in style_controller.dart for the addLayer method, can we remove the addLayer methods from MapLibreHostApi=
I actually updated them into MapLibreHostApi too, to be safe.

Thanks for taking the extra effort. If it's handled by jni, no need to update the kotlin implementation. If it it's no longer required, we can just remove them. In case it is required by iOS but not Android, an empty override should be fine.

Furthermore, from this PR onwards, MapLibreHostApi is no longer used in StyleControllerAndroid, generating a warning.

This is awesome news! Big step to a complete ffi/jni solution. You can remove it or ignore the warning, up to you.

// ignore: unused_field

I included this pr in the v0.3.0 milestone, hope that's alright for you?

@gabbopalma
Copy link
Contributor Author

Hi @josxha, thanks for the review! I will completely remove MapLibreHostApi, in order to improve the goal of full jni/ffi implementation.
The 3.0.0 milestone is good for me 😉

@josxha josxha moved this from Backlog to In Progress in maplibre dev Sep 22, 2025
@gabbopalma
Copy link
Contributor Author

gabbopalma commented Sep 22, 2025

Hi @josxha, I successfully removed MapLibreHostApi, but I noticed that you added the dispose method (which was removed with all the other methods).
Do we want to reintroduce the dispose method? If so, how?
Also, the addImage and addImages methods are currently unavailable on iOS. I tried compiling the app on my iOS simulator to start implementing it and testing all the changes, but I encountered this error:

Semantic Issue (Xcode): Use of undeclared identifier ‘MapLibreIosPlugin’
/Users/gabrielpalmisano/Development/projects/flutter-maplibre/example/ios/Runner/GeneratedPluginRegistrant.m:36:3

@josxha
Copy link
Owner

josxha commented Sep 22, 2025

I successfully removed MapLibreHostApi, but I noticed that you added the dispose method (which was removed with all the other methods).
Do we want to reintroduce the dispose method? If so, how?

Its only usage is currently in the iOS implementation, right? I think I used it in an attempt to get rid of some memory leaks.

func dispose() throws {
print("### dispose MapLibre view ### \(_viewId) ###")
MapLibreRegistry.removeMap(viewId: _viewId)
_mapView.removeFromSuperview()
_mapView.delegate = nil
_mapView = nil
_view.removeFromSuperview()
}

Is it correct that the main scope of this pr is to enhance the FFI capabilities of the StyleController? I'd recommend to keep the dispose() method in place for now. A separate pr might be good.

I tried compiling the app on my iOS simulator to start implementing it and testing all the changes, but I encountered this error:

Did you activate the swift package manager? iOS needs the SwiftPM to run successfully.

flutter config --enable-swift-package-manager

@gabbopalma
Copy link
Contributor Author

gabbopalma commented Sep 22, 2025

Is it correct that the main scope of this pr is to enhance the FFI capabilities of the StyleController? I'd recommend to keep the dispose() method in place for now. A separate pr might be good.

Sure, this is the main scope of the PR. Since we want to restore it, and handle the change in another PR, do we want reintroduce MapLibreHostApi? Just for the dispose method?

Did you activate the swift package manager? iOS needs the SwiftPM to run successfully.

Of course nope ahahah, I just did it, thanks

@josxha
Copy link
Owner

josxha commented Sep 22, 2025

Sure, this is the main scope of the PR. Since we want to restore it, and handle the change in another PR, do we want reintroduce MapLibreHostApi? Just for the dispose method?

Ahh, I see. Probably not for the sake of an unused dispose() method.

    override fun dispose() {
        // free any resources
    }

How about your changes from #162? It makes use of the MapLibreHostApi. I'd like to integrate the functionality at some point into the main branch. Sorry, I waited a bit long with it and how there are numerous conflicts. Do you think a jni integration is feasable here as well or should we keep your implementation with pigeon?

@gabbopalma
Copy link
Contributor Author

How about your changes from #162? It makes use of the MapLibreHostApi. I'd like to integrate the functionality at some point into the main branch.

I'll be a little busy these days because I'm traveling. I'll look at the changes related to #162 and try to integrate them into jni/ffi (unfortunately, it's a very old implementation and, on second thought, there are better ways of doing it)

@josxha
Copy link
Owner

josxha commented Sep 23, 2025

I'll be a little busy these days because I'm traveling. I'll look at the changes related to #162 and try to integrate them into jni/ffi (unfortunately, it's a very old implementation and, on second thought, there are better ways of doing it)

No worries, take your time and enjoy your vacation! Alright, then let's delay the functionality in #162. In that case, what ever is the easiest to you, probably to keep it removed?

@gabbopalma
Copy link
Contributor Author

In that case, what ever is the easiest to you, probably to keep it removed?

Yes, we can leave it removed for now. If you agree, I'll try to implement the drag gestures on the Dart side to remove some platform-specific code and try to don't reintroduce something similar to MapLibreHostApi

Copy link
Owner

@josxha josxha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @gabbopalma, I did a code review and added a couple of comments. Could you take a look when you find some time?
I'd like to put out a release by tomorrow but no need to rush, we can merge whenever ready and also release it with a following release.

Comment on lines +62 to +65
// Each point is displayed as a layer of markers due to the
// randomly generated 'iconImage' property.
// Do not follow this approach, as it is not efficient.
// Instead, use a single 'MarkerLayer' with a list of points.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a more easy and state of the art example implementation for users here.
You can use two MarkerLayers that start with some initial points. When the map gets clicked, update the points of the 2nd layer.

);*/
await _hostApi.addImage(id, bytes);
// TODO: implement addImage
throw UnimplementedError('addImage is not implemented on iOS yet.');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed functionality on ios. Please keep the existing implementation or use an ffi equivalent.

Comment on lines +27 to +30
Future<void> addImages(Map<String, Uint8List> images) {
// TODO: implement addImages
throw UnimplementedError('addImages is not implemented on iOS yet.');
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add an implementation here please? You can use multiple calls to addImage().

https://maplibre.org/maplibre-native/ios/latest/documentation/maplibre-native-for-ios/multipleimagesexample

@override
Future<void> addLayer(
StyleLayer layer, {
String? aboveLayerId,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aboveLayerId has currently no implementation. Please either add an implementation or add an assert and todo.

import MapLibre

class MapLibreView: NSObject, FlutterPlatformView, MLNMapViewDelegate,
MapLibreHostApi, UIGestureRecognizerDelegate
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the MapLibreHostApi on Android but still need to have on it on iOS for the dispose method until we can get rid of the dispose() method.

func dispose() throws {
print("### dispose MapLibre view ### \(_viewId) ###")
MapLibreRegistry.removeMap(viewId: _viewId)
_mapView.removeFromSuperview()
_mapView.delegate = nil
_mapView = nil
_view.removeFromSuperview()
}

@josxha josxha removed this from the v0.3.0 milestone Sep 29, 2025
@josxha josxha marked this pull request as draft September 29, 2025 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: In Progress
Development

Successfully merging this pull request may close these issues.

2 participants