3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Turf.jsを使うよ! ~距離とか面積とかを取得~

Posted at

Turf.jsとは?

 高機能なJavaScriptのWeb地図用GIS演算ライブラリです。
 シンプルで早くて、小さくモジュール化しているから、必要な物だけを取得して使えるよ、ということのようです。

 とにかく山のように命令があってなんかすごそう! とは思いつつ、ご説明は全部英語だし、グーグル翻訳さんに訳してもらったところで、ワタシなどには何するもんだかサッパリな命令も多々あるわけなんですが、とりあえず欲しい機能だけをちょこっと使わせてもらう分には、さして難しいことでも無い様子。

まずは準備です

スクリプトを取り込む

 なでしこ3も、PC版はNode.jsで動いているというのに何ですが、ワタクシいまだによく分からない人なので、とにかく直でHTMLへscriptタグで読み込みたい。
 コレです!

<script src='https://unpkg.com/@turf/turf@6.3.0/turf.min.js'></script>

 簡単ですね♪

 しかし、とりあえずお試しするには良いのですが、フルビルドしたものはサイズがべらぼうなので、カスタムビルドで必要なビットのみを取得せよと書いてある・・・ラシイ。
 結局それかよ、えぬぴーえむかよ、というところですが、とりあえずここで、ポチポチと超簡単に作ることが出来ました。神だね!

helpersの罠

 Turf.jsではなんでもGeoJSONってデータ形式にしなきゃなようで、なんかこんなの。

{
  "type": "Feature",
  "properties": {},
  "geometry": {
    "type": "Point",
    "coordinates": [
      140.75497578224517,
      41.7946708822908
    ]
  }
}

 むむむ・・・(@_@)
 それをやってくれるのが、helpersの中の一連の命令なんですよね。
 緯度経度やその配列を与えただけで、pointやらlineStringやらpolygonやらの形式のGeoJSONにしてくれるって寸法です。だから、大体使います。
 ご本家のExampleでは、こんな風になっております。

var point = turf.point([-75.343, 39.984]);

 これで、ちゃんと動いたんですよ。当初、

<script src='https://unpkg.com/@turf/turf@6.3.0/turf.min.js'></script>

 を取り込んでた段階では。
 ところが、その後、ご入り用のmoduleだけでアレしようとしたら、途端にエラーになっちゃう。
 だから、てっきり、びるど? がうまくいっておらぬのじゃろう・・・と思ってしまったせいで、大分ハマりました(´Д⊂ヽ
 こうでした。

var point = turf.helpers.point([-75.343, 39.984]);

距離を測りたい!

 さて、気を取り直して・・・まず第一にやりたいことは、距離を測ることなんですよね~。
 例えば、時代小説中の人物が歩いた道程を辿ってみるとかね☆
 それが、実際のところ何kmくらいなんですかね? 的な。
 うーむと切絵図を眺めて、それからおもむろにぐーぐるまっぷと首っ引きで距離を測定してみたりする。それが、Maplat + Turf.jsでなら、同一画面上で出来ちゃいそうじゃないですか? 楽しげ♪
 距離の測れそうな命令には、turf.distanceturf.lengthがありました。

 コロナのせいですっかり馴染み深い単語になっちゃいましたね、distance
 これは、二つのpointを与えて、その間の距離を得る物。

 一方lengthは、lineStringを与えてその長さを得る物。

 一応両方試しました。
 なでしこ3は、なでしこのプログラム中に、直でJavascriptを書いて実行することも出来ますよ!
 こんなふうに文字列としてJavascriptの関数を書き、それに引数を与えてJS関数実行できます。
 関数の中身は、ご本家のExampleのとうり。

  • turf.distance
distance
(function(from,to){
  var from = turf.helpers.point(from);
  var to = turf.helpers.point(to);
  var options = {units: 'meters'};
  return turf.distance(from, to, options);})をdistanceに代入

distanceを[[140.76033681119014,41.79635583006893],[140.75360256611546,41.79599719142311]]でJS関数実行して言う。# 559.6794099196878
  • turf.length
length
(function(line){
  var line = turf.lineString(line);
  return turf.length(line, {units: 'meters'});})をlengthに代入

lengthを[[[140.76033681119014,41.79635583006893],[140.75360256611546,41.79599719142311]]]でJS関数実行して言う。# 559.6794099196878

 結果は、バッチリ一緒でした~☆(そりゃそうか)
 そして試しに、ぐーぐるまっぷの「距離を測定」で、ざっくり測ってみたら、ちゃんと大体一致しました~♪
 いや、べべべつにTurf.jsを信じてなかった訳じゃ無いんですがっ!

 それはさておき、distancelengthも結果が合うなら・・・圧倒的にlengthの方が便利ですよね~。
 lengthは、lnglatsの配列をlineStringにして与えれば、二点間はもとより、どんなにぐねぐね曲がりくねろうと、一発で距離を出してくれますが、distanceは、ぐねぐねしていた場合には、lnglatsの配列を反復して、順々足していかなきゃいけませんからね。
 こんな感じ?

  • turf.distance
distance
道程[[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]]

A=0
((道程の要素数)-1)
 AA(distanceを[道程[回数-1],道程[回数]]でJS関数実行)。
ここまで

Aを言う。# 790.762102688524

 やっと、なでしこで書いてる甲斐が出てきたw

  • turf.length
length
lengthを[道程]でJS関数実行して言う。# 790.762102688524

 一発☆

 当然ですけど、こちらもピッタリ一致。
 Turf.js的には、与える引数が点か線かとゆう違いがあるんでしょうが、ワタシなどがなでしこのプラグインにして、ラクに使ってやろうというにあたっては、どっちみち引数は緯度経度にしちゃいますから、一緒ですw

ついでに面積

 面積も、turf.areaでlnglatsの配列をpolygonにして与えたら、複雑な形でもしゅっと出してくれます。

area
(function(lnglats){
  var polygon = turf.helpers.polygon(lnglats);
  return  turf.area(polygon);})をareaに代入

道程に道程[0]を配列追加
areaを[[道程]]でJS関数実行して言う

 でも、四角になるように経緯度を調整して、distanceで二辺の距離を出して計算してみたのとは、ビミョーに合わなかった。
 地球は平面じゃないから、おそらく深遠な計算式があるのであろう。小学校でやるような面積の出し方ではないのだ。
 いや・・・平面ってコトでいいじゃん! って言うような、狭い範囲内なんだけどなあ・・・w
 いずれにせよ、古地図上のことなので、ベツにざっくりとで良いんですが。

 注意点としては、polygonの時はパス(?)が閉じてないとダメです。(lnglatsの最初と最後を同じにする)
 lineStringの配列なので、同じ範囲でも、lengthで外周の長さを測ってやろうという場合より、一段階層が深くなります。
 距離の時には、単位を指定出来るオプションがあったけど、これは平方メートル限定らしい。

中心とか重心とか

 turf.centerとかturf.centroidとか、一応やってみたけど、意味はだいたいわかるけども、私にとって使い途があるかどうかは不明w
 しかも、turf.centroidとturf.centerOfMassの違いが分からんorz。何か、異なる計算式によって算出されているのであろう。

動作確認

 プラグインにして、とりあえずここまでをMaplat上に反映してみました~。

https://snowdrops89.github.io/Maplat_test/test/nako3_test_Turf_1.html

 これで、なでしこらしくp1からp2までの距離取得とか、lineの道程取得とかで、距離を得られるようになりました♪
 ・・・結局distanceも残したので、lengthは長さって言うのもアレだし「道程取得」にしてみたんだけど、どうだろう? 英語力だけじゃなく、日本語力も問われるのか・・・
 なでしこ開発者様のご苦労が忍ばれるね!

 プラグインはココ。

https://github.com/snowdrops89/nako3_plugin_Maplat

 Maplatで使いたいことだけを、ちょこちょこと入れるだけのつもりなので、Maplatと同居。
 しかし、やはり、Maplatのプラグインとはファイルを分けました。
 それぞれのscriptの取り込みが必要ですからね。
 

つづきます

 なんか、肝心のトコまで行き着きませんでしたけど;;;
 もう、使う物は既にプラグインにはしてあるし、別に引っ張るようなアレでも無いんですが、例によって出来たの出来ないのと騒いでいるうち結構な文字数になったので、続きとします。(まだちゃんとしたサンプル作ってお試ししてないし、もう文章書くの疲れたし><;)
 次こそは地図上にバス?を走らせたり、進行方向に従って地図の向きを変えたりしてみます!

Maplat Coreで古地図の上にバスを走らせてみる
Maplat Coreで古地図の上に明滅するバスを走らせてみる
Maplat Coreで古地図上を進行方向に視点を変えながら走り回ってみる

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?