🎄

Flutterで検索結果を三次元散布図(Scatter3D)に表示する

2024/12/24に公開

本記事はFlutter大学 Advent Calendar 2024の24日目の記事です。

長くなるので、コードはここには載せません。
コードに興味のある方は、リンクを張りますので、GitHubや関連記事でご覧ください。

歴史を三次元空間に再構成する?

『四次元年表』というデータベースをつくっている。
「いつ、どこで、何があった」という情報のみに特化したデータベースで、
それを、時間軸、空間軸を取って表示する。
何でそんなことをするのか、とか、それによって何が得られるのか、とか
そういうことには、今回は触れないことにする。

2023年は時間軸をがんばった

歴史好きな人も大嫌いな人も、ちょっと思い出してほしいのだが、
「年表」というのはだいたい、ぎゅうぎゅう詰めに書かれている。
一年にいくつものできごとがあったり、かと思えば50年ぐらい飛んだり、
紙に印刷するなら、それは致し方ないことだ。
でも今は21世紀。紙じゃなくバーチャル空間に表示するなら、
「何も起こっていないところ」を余白として残しても、
もったいない、とか、収まらない、とかいうことはない。
23年にがんばったのは、データが時間軸上に固定されていて、
zoom-inすれば細かく見えるし、zoom-outすれば概略が見えるし、
そしていつも、できごとの相対的距離が正しく見える、という表示方法だ。

scalable-timeline on YouTube

2024年、時間軸を世界地図に載せよう

私が使っているのはFlutterだ。
こういうことをするのに、Flutterが適しているかどうか、わからない。
もともとはUnityで作りかけていたのだけれど、そちらは今、停滞中だ。
だから、
「Flutterでやるなら、どういう方法があるか」という考え方になる。
地図といえばGoogleMap!な時代だけれど、
私の目的からいえば、GoogleMapは「過剰」だ。
QGISのような地理情報システムも試したけど、今ひとつピンとこない。

articles about QGIS on zenn

そして行きついたのが、三次元散布図だ。
データサイエンスの可視化でよく出てくる、
データを三次元空間内に点描して、グラフごとグルグル360°回せるヤツ。
私のデータは緯度、経度、時間という三つの値を持っているから、
そのまま点描できるだろう。

まずはflutter_echartsを使う

二次元グラフをつくるPackageはいろいろあるけれど、
三次元散布図は、これしかなかった。
ので、これでいく。
https://pub.dev/packages/flutter_echarts

assetsにjson形式のデータを置いて読んでみる

How Cassini aimed at Saturn on YouTube

これは「四次元年表inSpace」というアプリに実装した機能だ。
xy平面上に太陽系の日心黄道座標をとり、z軸を時間軸として、
宇宙船がスイングバイを繰り返しながら、目的地を目指す様子を表示している。
こちらは、この作業をしているころに書いた記事。

articles about flutter_echarts on zenn

データベースから取得したDartのMapを表示してみる

What happens in Space on YouTube

同じアプリで、データベースから読み込んだデータも表示してみた。
私のバックエンドはserverpodなので、データはdartで出力される。
これをjsonに読み替えて表示する。
理屈としてはこれでいいのだけれど、ぱっと見、何がどうなっているのかわかりにくい。
改善の余地あり。

chronomap-in-space on GitHub

assetsにjson形式のデータを置いて世界地図を表示する

search and show on YouTube

こちらは最新作、「四次元年表in Maritime」というアプリに実装した機能。
前回は宇宙だったが、今回のxy平面は世界地図。
世の中には便利なデータがいっぱいあって、世界地図のGioJsonもあるのだけれど、
これもまた私には「過剰」。
すてきすぎる背景が、年表データをじゃまする。
だから、海岸線のみの地理情報だけ抽出してcoastline.jsonをつくってみた。
ふつうに表示すると子午線基準、ヨーロッパ中心地図になる。
でも、環太平洋のできごとのためには、
やっぱり日本人の見慣れた太平洋中心地図もほしい。
読み替えの計算式を書いて、同じデータから表示できた。

データベースから取得したDartのMapを表示する 2

今回は、絞り込みの機能もつけたので、ページ遷移やデータの受け渡しが複雑になった。
データベースへのアクセス回数はできるだけ減らしたいし、
でも、いろんな表示を楽しんでほしいし、と欲張りすぎたかもしれない。
これが最適解、とはとてもいえないけど、現状、自分の力に照らして、満足。
世界地図はz軸の中央に配置している。
中央って? 
絞り込んだ検索結果のうち、
「一番昔のできごと」と「一番新しいできごと」の真ん中を取る計算式を書いた。
Projectionはorthographicにしたので、
xy平面を真上から見下ろすと、点描された事象は世界地図上にマッピングされる。
一方、90°横倒しにして、z軸が直立するように表示すれば、
点描された事象は時系列に並ぶ。
それも一列ではなくて、地図上の緯度経度によって、左右に展開する。
それを360°グルグル回して遊ぶ。 とくだん意味はないが、楽しい。

articles about flutter_echarts on zenn

地図だけじゃなくて、地球儀でもやりたいなあ

https://echarts.apache.org/en/index.html
flutter_echartsは 
ApacheEChartsというJS,TSのライブラリを読み込むPackageなのだけれど、
その本家を見ていたら、あ、地球儀がある、これを使いたい!
でも、flutter_echartsの対象には、どうやら入っていないらしい。
いないらしいんだが、強引にやってみた。
ら、
あれ、いけそう?
おもしろいことに、データは表示できるが、背景や地球儀のテクスチャーが出ない。
でも、出たところで、また「過剰」になるだけだから、これでいいんでは?
時間軸は立てられないけど、世界地図が持っている「歪み」がないのがうれしい。
高緯度・極地の距離感がきれい! なので、おまけとして採用する。

How Globe rotates on YouTube
chronomap-in-maritime on GitHub

ところが!

私はiPadのヘビーユーザーで
一にiPadPro、二にMac、三、四がなくて五にiPhone、という生活をしている。
Flutterで開発しているとはいえ、ついついBuildはSimulatorで、ということになる。
ところが、もうリリースしよう、というだんになって、問題が判明。
androidでは、この地球儀、表示されない!
iOSがうまくいったのは、たまたまrenderingの相性がよかった、みたいな話らしい。
ということで、このボーナストラックはiOSのみ。

FlutterWebに表示する

『四次元年表』は「統合版」をWebで、テーマ特化版をアプリで展開している。
せっかくアプリで使えるようになったScatter3DをWeb版にも載せたい。
が、flutter_echartsはwebをサポートしていない。
地球儀みたいに「なんとなくできた」という芽もなくて、
あとは本家ApacheEChartsから直で読むしかない。

運用中のWeb版をいきなり触れないので

テスト用プロジェクトをつくって実験。
四苦八苦の途中経過はこちら。
https://zenn.dev/flutteruniv_dev/articles/a65b4ecc2188e2

検索結果、のつもりの、決め打ちデータを表示

苦労したのは、DartのMapをPopUpで表示する、その書き方がわからなかったこと。
QuotationMarkをつけるとか、つけないとか、
要素をItem番号で呼ぶか、Field名で呼ぶかとか、
ともかく手当たり次第やって、ようやく表示にこぎ着ける。
デザイン、イマイチなんだけど、表示しなくていいものまで表示されるんだけど、
取りあえず、妥協。

データ取得と描画のタイミング

もっと苦労したのは、こちら。
最初、本番に似たページ遷移込みのプロジェクトをつくったら、
なにが悪くてうまくいかないのか、まったく理解できないまま沼りに沼ったので
徹底的に小さなプロジェクトでやり直した。
ページ遷移もなければ、UIとロジックの分離もない。
全部main.dartに突っ込みました状態。
それで、現状、どこまでできたか、というと

  • まず地図だけ表示する
  • 検索、の代わりに「取得ボタン」をつける。
  • 「取得ボタン」を押して、「検索したつもりid(決め打ち)」をつかってデータを取る。
  • データが取れたら再描画する。
  • 地図上ではデータのポイントのみを表示(地図が文字でいっぱいにならない)
  • 選択したポイントのデータをPop Upで表示。
    最後の二つは、モバイル版に逆輸入したい。
How Scatter3D works on 四次元年表Web on YouTube
テストプロジェクト on GitHub

この記事の目標は「Web版に実装報告」だったんだけれど

そこまでいけなかった。
だから、以下は2025年最初の宿題にします。

  • Web版への地図と地球儀の実装。
  • androidへの地球儀の実装。

そして2025年の目標は

宿題をこなした上で、
2025年はぜひ、Unityに帰って、「歴史空間内を歩ける、飛び回れる」を実現させたい。
MetaQuest3Sを使って

まだだれも見たことのない歴史、を表現する!

断言引き寄せ方式\(^O^)/

夢は大きく、コードは一行ずつ

🎄Merry Xmas & Happy New Year🎄

2025年も、よい年でありますように。

Flutter大学

Discussion