前回の続きです。
とりあえず、Turf.js使うこと出来ました☆
なでしこ3のプラグインにも出来ました☆
MaplatのAPIと組み合わせて、ちゃんと動かすことが出来ました☆
というわけで・・・
A地点からB地点への道程を表示
この記事ではぐるっと環状線のようになっていますが、ここではAからBまで移動する道程ということにします。
道程=[
[140.76033681119014,41.79635583006893],
[140.758478619304,41.79556157762579],
[140.75721413722778,41.79432302386439],
[140.75619270341997,41.79496643842464],
[140.75497595771563,41.79462275418183],
[140.75484194014732,41.79560505340086],
[140.75360256611546,41.79599719142311]
]
まあ、経緯度配列の先頭と最後を同じにすればぐるっと繋がるし、別なら(見た目に超近くても)一本の線という扱いになるってだけのことです。
経路を分割した座標配列を作る
元記事の説明によれば、こうゆうコト。
lineStringで経路の座標列をLineStirngのGeoJsonオブジェクトにし、lengthでその長さを測ります。
続いてその長さを20分割し、lineChunkを使って20分割した長さで経路GeoJsonをぶつ切りにします。
ぶつ切りした各ラインに対してループを回し、explodeで各線分の先頭の点を取得し、その座標を取得してバスを動かすための座標列を生成しています。
コレをまるっとプラグインにする。
ほぼコピペである(/ω\)
注意点としては、環状線なら最初と最後の点が同じになるので問題ないのですが、「各線分の先頭の点を取得」しているため、終着点が入ってないので、AからBへという場合には、追加してやる必要があります。
lnglatsの最初と最後の要素が同じでなかったら、pointsにlnglatsの最後の要素(終着点)を追加して返すようにしておく。
なでしこなら簡単なのに・・・出来たやつを見たらそれ程でもないのに・・・何気にうまく行かなくて大変だった(´Д⊂ヽ
toString()
がミソ?
// @道程分割(lineChunk,length,explode,helpers)
'道程分割': { // @lnglatsの線を個数vに分割 // @みちのりぶんかつ
type: 'func',
josi: [['を'],['に', 'で']],
fn: function (lnglats, v, sys) {
var line = turf.helpers.lineString(lnglats);
var options = {units: sys.__v0['Turf単位']};
var lineLength = turf.length(line, options);
var divLength = lineLength / v;
var chunk = turf.lineChunk(line, divLength, options);
var points = chunk.features.map(function(line) {
var nodes = turf.explode(line);
return nodes.features[0].geometry.coordinates;
});
if (lnglats[0].toString() != lnglats[lnglats.length-1].toString()) {
points.push(lnglats[lnglats.length-1]);
}
return points;
}
}
}
何はともあれ、これで、なでしこでは、
lnglatsをvに道程分割。
だけで、lnglatsで指定したルートをv分割したpointsの配列が取得出来るようになったよ。やったね☆
あとは、タイマーでこの配列を反復するだけ!(環状線じゃないので配列の最後まで行ったらタイマー止めるのを忘れず)
カウンタ=0。
v=20。//道程を何分割するか。
停留所=道程をvで道程分割。
0.1秒タイマー開始した時には(道程分割タイマー)
もし、カウンタ≧(停留所の要素数)ならば、
道程分割タイマーのタイマー停止。戻る。
違えば、
停留所[カウンタ]へ点打つ。
カウンタ=カウンタ+1。
ここまで。
ここまで。
alongって命令もある
ところで、Turf.jsのリファレンスを眺めていたら、同じようなことのできそうな命令に、alongがありました。ていうか、一番上なのでいやでも目に付きますw
これは、与えたline
に沿って、スタート地点からv
だけ進んだ地点のpoint
を返すという命令。
うーん、何も知らずにわたしが自力でやったとしたら、おそらくコレを使っただろうな。
やってみます!
// @道進所(along,helpers)
'道進所': { // @lnglatsで道程を設定し、スタート地点からvだけ進んだ位置を返す // @みちすすんだところ
type: 'func',
josi: [['を'],['だけ']],
fn: function (lnglats, v, sys) {
var line = turf.helpers.lineString(lnglats);
var options = {units: sys.__v0['Turf単位']};
var along = turf.along(line, v, options);
return along.geometry.coordinates;
}
},
vは、あくまでもスタート地点からの進んだ距離なので、タイマーの中でvを増やしていく感じ?
あるいは、あらかじめ繰り返しで配列を作っちゃえば、前のと同じになりますよね。
ちなみに、vがlineより長くなってても、ちゃんと終着点が返ってくるっぽい。便利♪
カウンタ=0。
0.1秒タイマー開始した時には(道進所タイマー)
v=(道程の道程取得)/20。//道程を何mずつ進むか。
道程を(カウンタ*v)だけ道進んだ所に点打つ。
もし、(カウンタ*v)≧(道程の道程取得)ならば、
道進所タイマーのタイマー停止。戻る。
違えば、
カウンタ=カウンタ+1。
ここまで。
ここまで。
道進んだ所!www
道程分割した時と、同じく動作しているので、ご満悦。
常に進行方向を上にして移動
コレですね☆
ちょっとかっこいいですよね♪ やってみます!
まずは、bearingで今進んでいる道の方角を取得するんですね。
// @方角取得(bearing,helpers)
'方角取得': { // @lnglatで二点間の地理的方位(北の線からの角度) // @ほうがくしゅとく
type: 'func',
josi: [['と', 'から'], ['の', 'で']],
fn: function (p1, p2, sys) {
p1 = turf.helpers.point(p1);
p2 = turf.helpers.point(p2);
return turf.bearing(p1, p2);
}
},
そして、逆方向に地図回転すればいいんですね。
こんな感じ?
カウンタ=0。
v=80。//道程を何分割するか。
停留所=道程をvで道程分割。
0.03秒タイマー開始した時には(進行方向タイマー)
もし、カウンタ≧((停留所の要素数)-1)ならば、
進行方向タイマーのタイマー停止。戻る。
違えば、
p1=停留所[カウンタ]。
p2=停留所[カウンタ+1]。
[p1,p2]の線引く。
方角=p1からp2の方角取得。
方角*-1で地図回転。
p2へ地図経緯度移動。
カウンタ=カウンタ+1。
ここまで。
ここまで。
点々ではなく、スムーズに線が延びていく感じにしてみましたが、ちょっと描画がもたつく感じ? PCの性能によるのかも;
動作確認
これで、だいたい元記事で紹介されていた内容は網羅出来たと思います。
https://snowdrops89.github.io/Maplat_test/test/nako3_test_Turf_2.html
ええっ、バス~、バスは~~~?www
実は・・・秒毎にマーカーを変更しながら表示することで、バスを点滅させながら進ませることが出来るのなら、
地図上をRPGのドット絵キャラみたいのを歩かすことが出来るんじゃ? とひらめいたんですけれど・・・めんどーだからやめちゃいました;
だって、一方向で、停止、右足、左足、みたいな感じで最低3パターンはアニメーションするんだよね。4方向でも12、8方向なら24・・・どっかから画像をお借りしてくるにしても、マーカー画像としてこんだけの枚数にバラして保存し直さなきゃならないですよね~。
v3はファイルとして画像を保存出来ないし、v1は、透過pngが扱えないのがツラい( ;∀;)
なんて感じでうだうだして、ムダに日を過ごした挙句、結局やらないっていうね;;;
そして、マーカーの位置や画像を更新すること自体は前にやったので、それも割愛。
というわけで、今回はここまで。
おわります
Maplatの使い方も覚え、紹介されていたこと、わたしがやりたそうなことは一通り、なでしこ3で出来るようになったと思います。
今度はガチな地図をマッピングして、何か良きものが出来たら発表するかも?
その中で、やりたいことが新たに発生したらプラグインを追加したり、不都合があれば修正したりしながらやっていきますです。