本文へ移動

Chikyu Earth地球

世界の国の輪郭を線で描いた地球儀です。地球と同じ速さで回ります。宇宙から見たような地球と、好きな場所の目印も使えます。

「地球」(ちきゅう) は、私たちが住む星の名前です。 名前について(英語)

目次

やり方

全画面表示、星に対して止めたカメラ、すべての人工衛星

リアルな地球を画面いっぱいに出し、カメラを星に対して止めて、地球がその下で回り、昼夜の境目が太陽の本当の位置に出るようにします。人工衛星の全グループも、描画の予算内で一度に表示できます。

<chikyu-earth-realistic> は、宇宙から見た地球です。このガイドは、地球を画面いっぱいに出したいページに必要な3つのことを説明します。全画面の表示、カメラの止め方の選択、地球の上に描く人工衛星です。どれも使わなければ負担になりません。デモの fullscreen.html が、この3つをすべて150行ほどで見せています (demo/fullscreen.ts)。

全画面: immersive

<style>
  chikyu-earth-realistic { position: fixed; inset: 0; width: 100%; height: 100%; }
  body { margin: 0; background: #04060c; }
</style>
<chikyu-earth-realistic immersive camera="space" texture-base="/textures/"></chikyu-earth-realistic>
  • 要素は、どんな形の枠でも、その枠いっぱいに広がります。地球は短い辺に収まり、大気の光も枠の内側に入るので、横長のデスクトップでも縦長のスマートフォンでも、全体表示で光が切れません。
  • ふつうのホイールで拡大・縮小し、ページはスクロールしません。要素のどこでもドラッグすると向きが変わり、タッチ画面では、指1本のドラッグがスクロールではなく回転になります。Ctrl (Command、Alt) を押したホイール、ピンチ、キー、そのほかの操作は、これまでどおり kazoku-ui のものです。immersive で手放すのは、ホイールでの移動 (パン) だけです。
  • immersive がなければ何も変わりません。要素は正方形で、全体表示でのふつうのホイールはページをスクロールし、ドラッグは正方形の中で回転します。
  • バーを付けるには、<kazoku-view-controls for="..."> を置き、デモのように、バーの kazoku-viewchange を setView に渡します。ホイールの拡大・縮小は、その表示を受け持つ側 (要素自身か、つないだバー) に渡るので、バーの上限・下限や数値の表示と食い違いません。

ページは、このシリーズ共通のルールも守ります。時計は「今」から動き出す状態で開き (speed="3600"、1秒で1時間)、動きを減らす設定の人には、止まった表示で「再生」を押せる状態にします。ページが見せる時刻は、その端末の時刻です。

カメラ: space (既定)、ground、sun

camera 属性 (とプロパティ) は、カメラの止め方を決めます。center は、カメラが見る場所です。

cameraカメラの止め方見え方
space (既定)星に対して止める。カメラを設定した時点の center が見える向きにする時計が進むと、地球がカメラの下で回ります (360度を23時間56分で)。昼夜の境目は太陽の本当の位置に合わせて出て、星に対しては1日に1度ほどずつ動きます
ground地上に対して止める。center が示す場所の真上から見る地球は動かず、時計が進むと、昼の側と夜の側が地球の上を動きます
sun太陽に対して止める。center は、太陽が真上にある場所を基準にした経度と緯度 (0,0 は正午の場所をまっすぐ見る)地球がその下で回っても、昼夜の境目は画面の同じ場所にあります

星に対して止めたカメラは、要素が読み込まれたときに設定され、time や center を設定したときにも、もう一度設定されます。別の日付に飛ぶページでは、その日付の center が見えるように向き直ります。ドラッグすると、止めた位置から向きが変わり、「中央」を押すと元に戻ります。

import "@johnmorrisdotca/chikyu-earth/realistic/element";
import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element";

const earth = document.querySelector<ChikyuEarthRealistic>("chikyu-earth-realistic")!;
earth.setAttribute("center", "139.7,35.7");
earth.camera = "space";
earth.speed = 3600;
console.log(earth.camera);

cameraCentre と greenwichSidereal (@johnmorrisdotca/chikyu-earth/realistic から) は、その計算だけを取り出したものです。ある時刻に地球が星に対して回っている角度と、カメラが見る場所を返します。

光は、どのモードでも本物の太陽と本物の時刻をもとに描きます。変わるのはカメラの止め方だけです。雲は予報ではなく、ある時点の1枚の画像です。そのため、画像のとおりの場所にあり、地球が回るときはいっしょに回ります。cloud-drift に度数を指定すると、雲が1時間にその度数ずつ東へ流れます (cloud-drift="1.5" なら1時間に1.5度)。見た目に動きを出すためのもので、天気を表すものではありません。

宇宙の表示を全画面で。 <chikyu-space immersive> も同じように動きます。どんな形の枠でもいっぱいに広がり、地球は短い辺に収まって大気の光も内側に入ります。ふつうのホイールで拡大・縮小し、どこをドラッグしても地球のまわりを回ります。ズームは月を越えて太陽や惑星まで (全体表示の100万分の1まで) 引くことができ、2.5倍まで寄れます。ホイールで月まで出て、また戻ってこられます。バーを付けるときは、要素と同じ範囲にします (zoom-min="0.000001" zoom-max="2.5")。デモの fullscreen.html?look=space がそのページで、惑星の画像 (本物の惑星のガイドを見てください) を使い、そのクレジットをタイトルの下に出します。canvas はウィンドウと同じ CSS ピクセルの大きさです。共有レンダラーがピクセル比を下げるので、5K の画面でも600万ピクセルと1辺4096を超えません。

<chikyu-space> も同じ camera を持ちます (0.24より前は、いつも地上固定でした)。さらに earth-size (全体表示で、地球の円が短い辺のどれだけを占めるか。既定は 0.9 で、大気の光が切れません)、earth-x、earth-y (表示の中での地球の中心の位置。中央は 0.5 と 0.5) があります。どちらの要素も、どんな形の枠でもいっぱいに広がるので、デモのパネル、「ワイド」、埋め込みの枠で、中に正方形を置かずに端まで描かれます。

地球の自転のうち、どれだけ一緒に回るか: follow

<chikyu-space> の follow は、0 から 1 までの数です。既定の 0 は、星を止めます。地球がカメラの下で回ります。これは camera="space" がもともとすることなので、ページが何も設定しなければ、これまでと変わりません。1 は地球と一緒に回るので、画面の中央の下の経度は動きません。そのあいだの数は、自転のうちその割合だけ一緒に回ります。時計に従います。速い時計でも、逆回しでも、止めた時計でも同じです (速さ 0 では回りません)。

follow を変えても、中央の下の経度は飛びません。follow-ease は、その変化にかける秒数です。省略すると 0.4 秒で、変化が見えます。0 だと、すぐ変わります。動きを減らす設定の人には、すぐ変わります。ページは、毎フレーム、ヨーに地球の自転の一部を足さなくてよくなります。時計が止まっていて follow も変わっていないときは、何も描きません。

import "@johnmorrisdotca/chikyu-earth/space/element";

const space = document.querySelector("chikyu-space")!;
space.follow = 1;
space.followEase = 0;
console.log(space.centreLongitude, space.shownTime);

地球の見た目

リアルな地球は、パッケージがすでに持っている NASA の画像 (Blue Marble、Black Marble、雲の画像、水域の画像。NOTICE.md を参照) に陰影をつけて描きます。新しいデータは使いません。

  • 大気。 厚さ100 kmの層を光が一度だけ散乱しながら通り抜けるようすを、リアルな地球でも宇宙の表示でも、ピクセルごとにシェーダーで計算します。レイリー散乱は昼の側の縁に向かって濃くなる青いもやに、ミー散乱は太陽の方向に広がる光のにじみになります。昼夜の境目では、太陽の光が低い角度で大気の長い道のりを通ってくるため、赤みを帯びた帯ができます。夜の側から太陽のほうを見ると、暗い地球のまわりに細く光る輪が見えます。どれも絵として描いたものではなく、計算の結果として現れます。その下の表面は、大気に奪われた光の分だけ暗くなります。air="full" は視線に沿って12回、各点から太陽へ向かって4回サンプルを取ります。小さな端末や遅い端末 (4コア以下、メモリ4 GB以下、またはマウスのないタッチ画面) の既定値である air="light" は、6回と2回です。サンプルは大気の濃いところに集めてあるので、どちらも縞が出ません。止まっているときの負担はありません。時計が止まっている間は何も描かず、描画は毎秒30フレームを超えません。見やすいように厚く描きます。 実際の層は厚さ100 kmで、直径12,742 kmの地球に対してごくわずかなため、地球全体を表示すると幅1〜2ピクセルの線にしかならず、スマートフォンではさらに細くなります。そこで、ページで指定しない限り、各要素は大気を実際の3倍の厚さで描きます。既定値は air-thickness="3"、実際の厚さは air-thickness="1" で、1から5までの数を指定できます。変わるのは高さだけです。同じ量の大気を厚い層に広げるので、散乱する光も色も同じで、縁の光の幅が3倍になります。1より大きい間は、各要素が絵の下に「大気は、見やすいように実際の厚さの3倍で描いています。」という一行を表示します (ページがその説明を自分で書く場合は air-label="off" で消せます。デモの全画面ページがそうしています)。デモの「大気を実際の厚さで」を押すと、そのままの厚さで描きます。
  • 昼夜の境目。 太陽が低くなるほど赤みを帯び、明るい側には暖色の帯が、境目の向こう側にはブルーアワーの青みがあります。
  • 海。 澄んだ青で、太陽の真下には鋭い反射、そのまわりには広い照り返しがあり、浅い角度で見る縁では空が映ります。雲があると反射は隠れます。
  • 雲 は地面に影を落とし、太陽が低いほど影が長くなります。
  • 夜。 街の明かりは暖かい色で、やわらかく広がり、雲がかかると暗くなります。

light="lit" と light="boost" は、これまでどおり使えます。light を lit に変えるとき、lit から変えるときは、短いクロスフェードです (300 ms。夜の街の灯りが消え、リアルな表示では光がカメラの側へ向きます。数フレームで、自然に終わり、そのあとは何も描きません)。動きを減らす設定の人には、すぐに切り替わります。stats.lightFade が今の状態を答えます: { mix, fading } で、mix は本当の光が0、lit が1です。

すべての人工衛星を一度に

リアルな地球も、宇宙の表示と同じ呼び出しで人工衛星を描きます。ページが取得した軌道要素から createSatellites でグループを作り (要素の入手先は人工衛星のガイドを参照)、setSatellites に渡します。

import { createSatellites } from "@johnmorrisdotca/chikyu-earth/satellites";
import type { ChikyuEarthRealistic } from "@johnmorrisdotca/chikyu-earth/realistic/element";

const earth = document.querySelector<ChikyuEarthRealistic>("chikyu-earth-realistic")!;
const sets = await fetch("elements/starlink.json").then((response) => response.json());
earth.setSatellites("starlink", createSatellites(sets), { color: "#7fd4ff", size: 2.5 });
earth.addEventListener("chikyu-satellite-click", (event) => {
  console.log((event as CustomEvent).detail.info?.name);
});
  • 1グループにつき描画は1回 です。何機入っていても同じなので、カタログの全グループを同時に出せます (デモの「すべての人工衛星」は、14グループで約4,000機です)。
  • 描画の予算。 1秒に30回まで (小さな端末や電池が少ないときはもっと少なく)、SGP4 の計算は時計の1秒に1回ほどで、その間は補間します。時計が止まっているときや要素が画面の外にあるときは何も描かず、WebGL のコンテキストはページに1つです。時計が MAX_SATELLITE_SPEED より速く進むときは、補間でぼかさず、各衛星を軌道に沿った短い線にします。element.stats.satellites で、配置した数、線の数、いちばん新しい軌道要素の時刻、描画1回のうち衛星に使った時間がわかります。
  • 地球の裏側。 地球の裏にある衛星は地球に隠れ、押すこともできません。
  • showSatellites(group, on)、satelliteGroups、selectSatellite(ref) (衛星のまわりの輪と軌道)、selectedSatellite、satelliteInfo(ref) は宇宙の表示と同じで、イベント chikyu-satellite-click も同じです。
  • 軌道要素は古くなります。人工衛星のガイドのとおり、表示している時刻から14日以上離れたものは、うすく描きます。
  • three として Points と、MAX_SATELLITE_SPEED より速いときの線のための LineSegments を渡す必要があります (必要な部品は、デモの three-subset.ts に並んでいます)。Points がないと人工衛星は出ず、chikyu-satellites-unavailable が送られます。LineSegments がないときは、実際の60倍より速いと点だけになり、コンソールに警告を1回出します。

デモの「人工衛星」の行は、リアルな見た目でも使えます。fullscreen.html?sats=all は、全画面の暗い表示ですべてのグループを見せます。

ソースを見るGitHub で編集@johnmorrisdotca/chikyu-earth 0.51.1 のソースから作成しました。

この日本語は、まだ日本語を母語とする方の確認を受けていません。訂正を歓迎します。