Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to load an mbtiles file #318

Open
timautin opened this issue Oct 20, 2023 · 8 comments
Open

How to load an mbtiles file #318

timautin opened this issue Oct 20, 2023 · 8 comments
Labels
documentation Improvements or additions to documentation

Comments

@timautin
Copy link

timautin commented Oct 20, 2023

Hello,
I need to be able to display local .mbtiles files. Using mablibre-gl-js this would be done using the addProtocol method.
It is unsupported yet in flutter-mapblibre-gl, right? Would you be interested by a merge request for this? If so, do you have any guide for setting up a dev environment?

@m0nac0
Copy link
Collaborator

m0nac0 commented Oct 20, 2023

I actually think it should work at least on Android and iOS (see e.g. maplibre/maplibre-native#17), but I haven't tried it recently.

In your merge request, would you want to expose the addProtocol functionality completely in this library, or would you only specifically want to enable loading mbtiles files?

@timautin
Copy link
Author

timautin commented Oct 20, 2023

Thank you for your answer, if mbtiles:// is already working then that's perfect :) ! Is there some documentation somewhere?

I just added an mbtiles file into my resources folder (in my project root) and added this:

  void _addMbtiles() async {

    await _mapController.addSource("mbtiles", const RasterSourceProperties(
        tiles: [ 'mbtiles://resources/map.mbtiles' ],
        tileSize: 256,
        attribution: '[...]'
    ));

    await _mapController.addLayer("mbtiles", "mbtiles", const RasterLayerProperties());
  }

But the app crashes with the following error (indicating that indeed mbtiles support seems there, it's juste that my file is not found):
terminating with uncaught exception of type mapbox::sqlite::Exception: unable to open database file

EDIT: alright I got it working putting the file to the external storage rather than in assets. Here's the code:

  Future<String> get _localPath async {
    return (await getExternalStorageDirectory())!.path;
  }

  void _addMbtiles() async {

    await _mapController.addSource("mbtiles", RasterSourceProperties(
        tiles: [ 'mbtiles://${await _localPath}/map.mbtiles' ],
        tileSize: 256,
        attribution: '[...]'
    ));

    await _mapController.addLayer("mbtiles", "mbtiles", const RasterLayerProperties());
  }

Thank you again for your answer :)

@m0nac0 m0nac0 changed the title addProtocol method support Hot to load an mbtiles file Oct 20, 2023
@m0nac0 m0nac0 changed the title Hot to load an mbtiles file How to load an mbtiles file Oct 20, 2023
@m0nac0
Copy link
Collaborator

m0nac0 commented Oct 20, 2023

That's great to hear! I adjusted the title since this might be relevant for more people in the future.
We might also want to add something about your solution to the docs.

@m0nac0 m0nac0 added the documentation Improvements or additions to documentation label Oct 20, 2023
@timautin
Copy link
Author

Yes indeed an addition to the doc would be nice, that's a common use case I think :)
You can close the issue, everything is ok for me (still have to confirm that it works on iOS, will do this next week).

@m0nac0
Copy link
Collaborator

m0nac0 commented Nov 14, 2023

Did you already check if your solution also works on iOS?

@timautin
Copy link
Author

It also works on iOS, but it needs some more work (on both platforms):

  • when zooming / un-zooming, the zoom level at which the map appears (when zooming) is not the same as the one the map disappears (when un-zooming)
  • small (~5-10MB) mbtiles files works well, but bigger ones (not huge, ~80MB) sometimes do not appear. Seems like setting min and max zoom to the source helps.

@m0nac0
Copy link
Collaborator

m0nac0 commented Nov 17, 2023

Thanks for the feedback. That sounds interesting, have you tried playing with the min/max zoom of the style layers?

@venomwine
Copy link

venomwine commented Nov 24, 2023

I tested another way to load an mbtiles. And It's working.
I copied test.mbtiles and style.json files to assets folder.

Future<String> loadAssets() async {
    var dir = (await getApplicationCacheDirectory()).path;

    const filename = 'test.mbtiles';
    var bytes = await rootBundle.load("assets/$filename");
    writeAssetToFile(bytes, '$dir/$filename');

    String loadedStyleString =
        await rootBundle.loadString("assets/style.json");
    loadedStyleString = loadedStyleString.replaceAll(
        '.pbf', '.pbf?key=abcabc');
    loadedStyleString = loadedStyleString.replaceAll(
        "___MBTILES_URI___", "mbtiles:///$dir/$filename");

    return loadedStyleString;
}
Future<void> writeAssetToFile(ByteData data, String path) {
    final buffer = data.buffer;
    return File(path).writeAsBytes(
        buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
        future: loadAssets(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return MaplibreMap(
              onMapCreated: _onMapCreated,
              initialCameraPosition:
                  const CameraPosition(target: LatLng(0.0, 0.0)),
              onStyleLoadedCallback: _onStyleLoadedCallback,
              styleString: snapshot.data,
            );
          } else {
            return Container(
              color: Colors.red,
            );
          }
        },
      ),
    );
  }

And style.json has this.

"sources": {
		"countries": {
			"type": "vector",
			"tiles": [
				"???/{z}/{x}/{y}.pbf",
				"???/{z}/{x}/{y}.pbf",
				"???/{z}/{x}/{y}.pbf",
				"???/{z}/{x}/{y}.pbf"
			]
		},
		"test-mbtiles": {
			"type": "vector",
			"url": "___MBTILES_URI___"
		}
	},

Thanks this library!

m0nac0 added a commit that referenced this issue Dec 1, 2023
JulianBissekkou added a commit that referenced this issue Dec 19, 2023
…tc.) (#346)

This came up e.g. in
#338 and
#318

Co-authored-by: Julian Bissekkou <36447137+JulianBissekkou@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants