😸

Mapbox Maps SDK Flutter Pluginでスタイル・レイヤーを操作する

2023/05/12に公開

はじめに

この記事はMapbox Maps SDK Flutter Pluginを使ってみるの続きです。スタイルやレイヤーを操作してみます。

初期位置を設定する

初期位置はcameraOptionsで設定します。以下のようにcenterzoom等が設定できます。centerはtoJson()でJSONにしているのが少し奇妙な感じがします。CameraOptionscenterMap<String?, Object?>型ですが、toJson()を実行することでPointMap<String, dynamic>に変換して型を合わせています。

class _MapPageState extends State<MapPage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: MapWidget(
        resourceOptions: ResourceOptions(accessToken: YOUR_MAPBOX_PUBLIC_ACCESS_TOKEN),
        cameraOptions: CameraOptions(
          center: Point(coordinates: Position(139.7586677640881, 35.67369269880291)).toJson(),
          zoom: 14,
        ),
      )
    );
  }
}

ではなぜMapで管理しているのかという疑問が湧いてきます。(あくまで私の予想ですが)メソッドチャネル経由でMapbox Maps SDK for Android/iOSにデータを渡す際にMap<String, Any>で渡し、ネイティブ側のオブジェクトに戻すという処理が行われいる都合上便利だからだと考えられます。しかし、内部の構造がユーザーのコードに滲み出ているのは少し気持ち悪い感じもします。

結果は以下のとおりです。

Camera

スタイルを設定する

次はスタイルを変更してみます。以下のようにstyleUriにURLを設定するだけでOKです。Mapboxが提供するコアスタイルはMapboxStyles.LIGHTのように指定することも可能です。これは内部でmapbox://styles/mapbox/light-v10"と定義されている定数です。

ここで指定したスタイルはMapboxのスタイルを体験するで使用したものです。

class _MapPageState extends State<MapPage> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: MapWidget(
        resourceOptions: ResourceOptions(accessToken: YOUR_MAPBOX_PUBLIC_ACCESS_TOKEN),
        cameraOptions: CameraOptions(
          center: Point(coordinates: Position(139.7586677640881, 35.67369269880291)).toJson(),
          zoom: 14,
        ),
        styleUri: "mapbox://styles/yochi/clgc8zfir000301pdahjtsax8",
      )
    );
  }
}

結果は以下のとおりです。少しわかりにくいですが、右下の道路が赤色になっています。

Style

レイヤーを作る

GeoJSONレイヤー表示における各地図サービスの比較と同じGeoJSONレイヤーを作成してみましょう。

まず、onMapCreatedを指定します。これはMapbox GL JSにおけるmap.on('load', ()=>{})に相当する処理です。

  Widget build(BuildContext context) {
    return Scaffold(
      body: MapWidget(
        resourceOptions: ResourceOptions(accessToken: YOUR_MAPBOX_PUBLIC_ACCESS_TOKEN),
        cameraOptions: CameraOptions(
          center: Point(coordinates: Position(139.7586677640881, 35.67369269880291)).toJson(),
          zoom: 16,
        ),
        styleUri: "mapbox://styles/yochi/clgc8zfir000301pdahjtsax8",
        onMapCreated: _onMapCreated,
      )
    );
  }

次に実際の処理を書きます。addSourceでGeoJSONを追加し、addLayerでレイヤーを追加します。Mapbox GL JSの記事を見比べるとほぼ同じ処理であることがわかります。

  _onMapCreated(MapboxMap mapboxMap) async {
    await mapboxMap.style.addSource(GeoJsonSource(id: "geojson_source", data: '''
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [
          [
            [139.75715452555397, 35.67501088740674],
            [139.75715452555397, 35.672275911172164],
            [139.7609465361483, 35.672275911172164],
            [139.7609465361483, 35.67501088740674],
            [139.75715452555397, 35.67501088740674]
          ]
        ],
        "type": "Polygon"
      }
    }
  ]
}
    '''));

    await mapboxMap.style.addLayerAt(FillLayer(
      id: "polygon_layer",
      sourceId: "geojson_source",
      fillColor: const Color(0xFF000088).value),
      LayerPosition(below: "building")
    );
  }

結果は以下のとおりです。

Layer

まとめ

Mapbox Maps SDK Flutter PluginでもMapbox GL JSと同じようにスタイルやレイヤーが操作できることがわかりました。Mapbox GL JSやMapbox Maps SDK for Androi/iOSに慣れている方は違和感なく使うことができるかと思います。

記事一覧

以下の記事もぜひご参照ください。

https://zenn.dev/ottylab/articles/d9ba57ca498170/
https://zenn.dev/ottylab/articles/8d206839a11067/

GitHubで編集を提案
マップボックス・ジャパン合同会社

Discussion