FlutterとMapLibre GLでMapTilerのスタイルを表示してみた

![img](https://day-journal.com/memo/images/try-075_03.gif)

<br>

![img](https://day-journal.com/memo/images/try-075_01.png)

<br>

この記事は、「[FOSS4G Advent Calendar 2021](https://qiita.com/advent-calendar/2021/foss4g)」の16日目の記事です。

### FlutterとMapLibre GLでMapTilerのスタイルを表示してみました :tada:  

[Flutter](https://flutter.dev)で[MapLibre GL](https://maplibre.org)を利用できるプラグインの「[Flutter MapLibre GL](https://github.com/m0nac0/flutter-maplibre-gl)」で、[MapTiler](https://maptiler.jp)のスタイルを表示してみました!

<br>

事前準備

- Flutterの環境準備  
    - [Flutter #001 - インストール](https://day-journal.com/memo/flutter-001)
    - [Flutter #002 - 環境構築](https://day-journal.com/memo/flutter-002)
      - Flutter v2.8.0
      - Dart v2.15.0
      - Xcode v13.1
      - Android SDK v32.0.0
      - Android Studio v2020.3
      - Visual Studio Code v1.63.0
      - Flutter extension v3.29.0

<br>

### Flutter x MapLibre GL

[Flutter MapLibre GL](https://github.com/m0nac0/flutter-maplibre-gl)を利用するために、事前に準備したひな形のコードを修正していきます。

<br>

全体構成

![img](https://day-journal.com/memo/images/try-075_02.png)

<br>

#### pubspec.yaml

```yaml
name: map_app
description: A new Flutter project.

publish_to: 'none'

version: 1.0.0+1

environment:
    sdk: '>=2.15.0 <3.0.0'

dependencies:
    flutter:
        sdk: flutter

    cupertino_icons: ^1.0.2

    maplibre_gl:
        git:
            url: https://github.com/m0nac0/flutter-maplibre-gl.git
            ref: main

dev_dependencies:
    flutter_test:
        sdk: flutter

    flutter_lints: ^1.0.0

flutter:
    uses-material-design: true
```

<br>

Flutter MapLibre GLをインストールします。
2021年12月現在、Flutter MapLibre GLはプラグインとしてリリースされていないため、インストール時にはGitHubのリポジトリを参照します。


```yaml
maplibre_gl:
    git:
        url: https://github.com/m0nac0/flutter-maplibre-gl.git
        ref: main
```

<br>

/lib

#### main.dart

```dart
import 'package:flutter/material.dart';
import 'package:maplibre_gl/mapbox_gl.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => FullMapState();
}

class FullMapState extends State<MyHomePage> {
  MaplibreMapController? mapController;

  void _onMapCreated(MaplibreMapController controller) {
    mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        body: MaplibreMap(
      onMapCreated: _onMapCreated,
      initialCameraPosition: const CameraPosition(
          target: LatLng(35.681, 139.767), zoom: 10.0, tilt: 60.0),
      styleString:
          'https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=[APIキー]',
    ));
  }
}
```

<br>

Flutter MapLibre GLを読み込みます。

```dart
import 'package:maplibre_gl/mapbox_gl.dart';
```

<br>

MaplibreMapで初期の中心位置(target)・ズームレベル(zoom)・傾き(tilt)・スタイル(styleString)を設定します。
スタイルはMapTilerのスタイルURLを指定するだけで表示可能です。

```dart
@override
Widget build(BuildContext context) {
    return new Scaffold(
        body: MaplibreMap(
    onMapCreated: _onMapCreated,
    initialCameraPosition: const CameraPosition(
          target: LatLng(35.681, 139.767), zoom: 10.0, tilt: 60.0),
      styleString:
          'https://api.maptiler.com/maps/jp-mierune-streets/style.json?key=[APIキー]',
    ));
}
```

<br>

/android/app

#### build.gradle

```gradle
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
    localPropertiesFile.withReader('UTF-8') { reader ->
        localProperties.load(reader)
    }
}

def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
    throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}

def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
    flutterVersionCode = '1'
}

def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

android {
    compileSdkVersion flutter.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = '1.8'
    }

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.map_app"
        minSdkVersion 20
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.debug
        }
    }
}

flutter {
    source '../..'
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
```

<br>


AndroidでFlutter MapLibre GLを表示するには、現状でAndroid SDKのバージョンを指定する必要があるため「minSdkVersion」と「targetSdkVersion」を固定で指定します。

```gradle
    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.map_app"
        minSdkVersion 20
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
```

<br>

VSCodeの「実行とデバッグ」を実行して確認してみます。

![img](https://day-journal.com/memo/images/try-075_03.gif)

<br>

#### FlutterとMapLibre GLでMapTilerのスタイルを表示できました :thumbsup: 

FlutterでMapLibre GLを利用し、MapTilerのスタイルを表示できました:bulb: ただ、プラグイン内のコードを見るとまだMapbox GLに依存しているところもありそうなので、今後改善されそうな気がしています。

<br>

Flutterについて、他にも記事を書いています。よろしければぜひ :bow:
<a href="https://day-journal.com/memo/tags/Flutter" target="_blank">tags - Flutter</a>

やってみたシリーズ :grinning:
<a href="https://day-journal.com/memo/tags/Try" target="_blank">tags - Try</a>

https://qiita.com/dayjournal/items/4b9f8f8fbdc233abacbf

https://qiita.com/dayjournal/items/044ac00459bdbf0f74f2

https://qiita.com/dayjournal/items/8fe865169e89c8bad343

https://qiita.com/dayjournal/items/28adab778631bf5d76ca



<br>
<br>

<a href="https://dayjournal.booth.pm" target="_blank"><img src="https://day-journal.com/memo/images/etc/book.png" alt="book"></a>