flutter_mbtiles_extractor 0.0.4

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • 67

flutter_mbtiles_extractor

Basic plugin to extract the data (png tiles) from an .mbtiles file and automatically create the folder structure (../folder_name/{z}/{x}/{y}.png).

example_gif

Installation

Import the dependency in the dart file you will use it.

   import 'package:flutter_mbtiles_extractor/mbtiles_extractor.dart';

In Android you need to add permissions to read and write in the storage of the device. In your project add the following lines to your AndroidManifest.xml file in your project's Android folder.

       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Remember that on API 23 and later you need to ask to the user to grant access for this permissions.

How to use

In the following example you can see how to realize a extraction of one file.

ExtractResult extractResult = await MBTilesExtractor.extractMBTilesFile(
        new ExtractRequest(
          "${dir.path}/volcan_villarica.mbtiles", //This is the name of the file i was testing.
          desiredPath: "${dir.path}/tiles/", //Example of final folder
          requestPermissions: true, //This is for Android 6.0+
          removeAfterExtract: true, //Deletes the +.mbtiles file after the extraction is completed
          stopOnError: true, //Stops is one tile could not be extracted
          returnReference: true, //Returns the list of tiles once the extraction is completed
          onlyReference: false, //If true the reference of tiles is returned but the extraction is not performed
        ),
      );

The extraction will return an instance of ExtractResult that contains a code and data. The code determinate the extraction result and could be checked using the isSuccessful() function in ExtractResult class or could be done manually.

    if (extractResult.code == ExtractResult.RESULT_FILE_CORRUPT) {
      //The file could not be read because it was damaged
    }

If the file was extracted successfully the data will contain the path to the folder where the tiles are stored.

    if (extractResult.isSuccessful()) {
        var folder= extractResult.data;
        //Do something
    }

Extra info

This plugin uses the extracted folder to generate a Google Maps like map so you could make a project that uses offline maps.

apptreesoftware/flutter_map

The Android part use a library to read the .mbtiles file. The original project for Java:

mbtiles4j

And the Android version:

mbtiles4j-android

NOTE: I included a compiled .jar of this library since it don't exist in Maven or JitPack (at least i couldn't find it). Consider update it if exists a new version.

Changelog

0.0.4

  • Quick fix. A crash was produced when extracting the metadata of an incomplete mbtiles file.

0.0.3

  • Revision on imports

0.0.2

  • Added asynchronous working so the extraction doesn't freeze the UI while working.

  • Updated the example

0.0.1

  • First release with basic functionality for extracting the tiles from a .mbtiles file.

example/lib/main.dart

import 'dart:async';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_document_picker/flutter_document_picker.dart';
import 'package:flutter_mbtiles_extractor/mbtiles_extractor.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => new _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _extractionStatus = 'Select a file to extract';
  bool _isBusy = false;
  File _selectedFile;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> widgets = [];
    widgets.addAll([
      Text(
        'Extraction Status:\n $_extractionStatus\n',
        textAlign: TextAlign.center,
      ),
      _isBusy
          ? Padding(
              padding: EdgeInsets.all(16.0),
              child: LinearProgressIndicator(),
            )
          : MaterialButton(
              onPressed: () {
                if (_selectedFile == null || !_selectedFile.existsSync()) {
                  _launchFilePicker();
                } else {
                  _extractMBTilesFile();
                }
              },
              child: Text(_selectedFile != null ? "Extract" : "Select File"),
              color: Colors.blue,
            ),
    ]);
    if (_selectedFile != null && !_isBusy) {
      widgets.add(MaterialButton(
        onPressed: () {
          _clearSelectedFile();
        },
        child: Text("Deselect File"),
        color: Colors.red,
      ));
    }
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('MBTilesExtractor example app'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            mainAxisSize: MainAxisSize.min,
            children: widgets,
          ),
        ),
      ),
    );
  }

  Future<void> _extractMBTilesFile() async {
    String result;
    try {
      //Get directory of the application. This way works best for iOS.
      //The main point here is that the origin of the file is not relevant,
      //as long as you have access to the file.
      //Add path_provider dependency in example/pubspec.yaml to use the next function
      setState(() {
        _extractionStatus = "Extracting... Please wait!";
        _isBusy = true;
      });
      Directory appDirectory = await getApplicationDocumentsDirectory();
      print(_selectedFile.path);
      ExtractResult extractResult = await MBTilesExtractor.extractMBTilesFile(
        new ExtractRequest(
          _selectedFile.path,
          //This is the name of the file i was testing.
          desiredPath: appDirectory.path,
          //Example of final folder
          requestPermissions: true,
          //Vital in android
          removeAfterExtract: false,
          //Deletes the *.mbtiles file after the extraction is completed
          stopOnError: true,
          //Stops is one tile could not be extracted
          returnReference: true,
          //Returns the list of tiles once the extraction is completed
          onlyReference:
              false, //If true the reference of tiles is returned but the extraction is not performed
        ),
      );
      result = """
      Result Code = ${extractResult.code}
      Extraction Message = ${extractResult.data}
      Tile Count = ${extractResult.tiles.length}
      Metadata = ${extractResult.metadata.toMap()}
      *Tile count only is displayed if reference is being returned
      """;
    } catch (ex, st) {
      print(ex);
      print(st);
    }
    setState(() {
      _extractionStatus = "$result";
      _isBusy = false;
    });
  }

  void _launchFilePicker() async {
    File file;
    String message = "Selection Cancelled";
    setState(() {
      this._isBusy = true;
    });
    try {
      FlutterDocumentPickerParams params = FlutterDocumentPickerParams(
        allowedFileExtensions: ["mbtiles"],
      );
      final filePath = await FlutterDocumentPicker.openDocument(params: params);
      if (filePath != null && filePath.isNotEmpty) {
        String extension = path.extension(filePath);
        if (extension == ".mbtiles") {
          file = File(filePath);
          message = "Ready to extract";
        } else {
          message = "Selected file is not mbtiles";
        }
      }
    } catch (ex) {
      message = "Selected file is not mbtiles";
    } finally {
      setState(() {
        this._extractionStatus = message;
        this._selectedFile = file;
        this._isBusy = false;
      });
    }
  }

  void _clearSelectedFile() {
    setState(() {
      this._selectedFile = null;
      this._extractionStatus = "File de-selected. Select a file to extract";
    });
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  flutter_mbtiles_extractor: ^0.0.4

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:flutter_mbtiles_extractor/mbtiles_extractor.dart';
import 'package:flutter_mbtiles_extractor/model/extract_request.dart';
import 'package:flutter_mbtiles_extractor/model/extract_result.dart';
import 'package:flutter_mbtiles_extractor/model/mbtiles_metadata.dart';
import 'package:flutter_mbtiles_extractor/model/tile.dart';
  
Version Uploaded Documentation Archive
0.0.4 Sep 28, 2018 Go to the documentation of flutter_mbtiles_extractor 0.0.4 Download flutter_mbtiles_extractor 0.0.4 archive
0.0.3 Sep 10, 2018 Go to the documentation of flutter_mbtiles_extractor 0.0.3 Download flutter_mbtiles_extractor 0.0.3 archive
0.0.2 Sep 10, 2018 Go to the documentation of flutter_mbtiles_extractor 0.0.2 Download flutter_mbtiles_extractor 0.0.2 archive
0.0.1 Jul 31, 2018 Go to the documentation of flutter_mbtiles_extractor 0.0.1 Download flutter_mbtiles_extractor 0.0.1 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
39
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
90
Overall:
Weighted score of the above. [more]
67
Learn more about scoring.

We analyzed this package on Oct 10, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.0.0
  • pana: 0.12.4
  • Flutter: 0.9.5

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Maintenance suggestions

Package is pre-v0.1 release. (-10 points)

While there is nothing inherently wrong with versions of 0.0.*, it usually means that the author is still experimenting with the general direction of the API.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0-dev.28.0 <3.0.0
flutter 0.0.0
Transitive dependencies
collection 1.14.11
meta 1.1.6
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8