Maplat Coreで古地図の上にバスを走らせてみる

Maplat Advent Calendar 11日目ですが、Maplat Coreで古地図の上にバスを走らせてみます。
今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 11](https://codesandbox.io/s/maplat-advent-calendar-day-11-tkgr6)

走らせるのは昨日のラインの上の経路なので、ベースは昨日のコードを元に改造しましょう。
バスを走らせるので、バスのアイコン画像`parts/blue_bus.png`[^1]も追加しておきます。

「バスを走らせる」の定義ですが、経路を20分割して、その線上の点を1秒毎に移動して、20秒で経路を一周するよう、バスアイコンを移動させることとしましょう。
経路を20分割して、その線上の点を取る、という処理を行うために必要なJavascriptモジュールを導入しておきます。
具体的には、`@turf/helpers`、`@turf/length`、`@turf/line-chunk`、`@turf/explode`あたりをロードしておきます。

その上で、以下のようにコードを改変します。

```app.js
import "@maplat/core/dist/maplat_core.css";
import { MaplatApp } from "@maplat/core";
import { lineString } from "@turf/helpers";
import length from "@turf/length";
import lineChunk from "@turf/line-chunk";
import explode from "@turf/explode";

var option = {
  appid: "maplat_ac_day11"
};

var app = new MaplatApp(option);
app.waitReady.then(function() {
  var ring = [
    [139.53184, 36.251013],
    [139.534322, 36.249581],
    [139.533853, 36.24814],
    [139.530729, 36.248649],
    [139.53184, 36.251013]
  ];
  app.addLine({
    lnglats: ring,
    stroke: {
      color: "#ffcc33",
      width: 2
    }
  });
  document.getElementById("gsi").addEventListener("click", function(e) {
    app.changeMap("gsi");
  });
  document.getElementById("osm").addEventListener("click", function(e) {
    app.changeMap("osm");
  });
  document.getElementById("ojo").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_ojozu");
  });
  document.getElementById("aki").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_castle_akimoto");
  });

  var ringFeature = lineString(ring);
  var ringLength = length(ringFeature, { units: "meters" });
  var divLength = ringLength / 20;
  var chunk = lineChunk(ringFeature, divLength, { units: "meters" });
  var points = chunk.features.map(function(line) {
    var nodes = explode(line);
    return nodes.features[0].geometry.coordinates;
  });
  app.addMarker({
    id: "moveMarker",
    lat: points[0][1],
    lng: points[0][0],
    icon: "parts/blue_bus.png"
  });
  console.log(points);
  var index = 0;
  var regularRun = function() {
    var point = points[index];
    app.updateMarker("moveMarker", {
      lat: point[1],
      lng: point[0]
    });
    index = index + 1;
    if (index > 19) index = 0;
    setTimeout(regularRun, 1000);
  };
  regularRun();
});

```

`var ringFeature = ...`あたりから後が追加部分で、まあこの辺はMaplatの使い方ではなく[Turf.js](https://turfjs.org/)の使い方になるのですが、`lineString`で経路の座標列をLineStirngのGeoJsonオブジェクトにし、`length`でその長さを測ります。
続いてその長さを20分割し、`lineChunk`を使って20分割した長さで経路GeoJsonをぶつ切りにします。
ぶつ切りした各ラインに対してループを回し、`explode`で各線分の先頭の点を取得し、その座標を取得してバスを動かすための座標列を生成しています。

その後、`setTimeout`で1秒毎の処理を実行し、その度に次の座標でマーカーの属性を`app.updateMarker`して、バスの位置を動かしています。

実行した様子はこんな感じになります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/04098cb3-e273-551e-ffba-0181a16b8e6e.gif)

ちょっと面白くないですか？

以前、ホリエモン万博というイベントで、公式の方がStrolyというMaplatライクなサービスを使って公式地図を配信していた際に、[ホリエモンの現在地を地図上に表示するのに手作業で位置を変更していたというツイート](https://twitter.com/hori_fes/status/1091298998013485056?s=20)をみたのですが、

<blockquote class="twitter-tweet"><a href="https://twitter.com/hori_fes/status/1091298998013485056"/></blockquote>

Maplatなら、ホリエモンにGPSデバイスでも持たせて現在地を常時クラウドにアップさせておけば、APIで自動でホリエモン現在地を更新できるので、運営さんはむっちゃ楽になりますね。
あと、Maplatはホリエモン万博のドメイン上で動作させることもできるし、オープンソースなので無償で利用することもできるし。

明日は、さらに少しひねって「古地図の上に、明滅するバスを走らせて」みましょう。


[^1]: (c) Font Awesome