本文へ移動

Chikyu Earth地球

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

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

目次

解説

アーキテクチャ

平面の地球儀、宇宙から見た地球、目印、宇宙の表示がどう組み合わさっているか、どこが純粋でどこが任意かを説明します。

Chikyu Earth は、小さな中核と4つの任意の層でできています。各層は独立したエントリーポイントなので、線画の地球儀だけがほしいページは、その分だけを負担します。

中核:純粋な関数と小さな要素

globe(options) は SVG の文字列をひとつ返します。正射図法の円盤、その上の国の輪郭、縁取りです。この関数は純粋で、時計も DOM も使わず、同じオプションなら同じマークアップを返します。そのため、サーバーでも、テストでも、要素の中でも動きます。

import { COUNTRIES, globe } from "@johnmorrisdotca/chikyu-earth";

const svg = globe({ size: 240, style: "thick", centre: { lon: 139.7, lat: 35.7 }, graticule: true });
console.log(svg.startsWith("<svg"), COUNTRIES.features.length, "countries");
true 177 countries

輪郭はこのパッケージには入っていません。chizu の world-geo(Natural Earth 1:110m、パブリックドメイン)を、読み込み時に一度だけ整形して使います。実行時には何も取得しません。実行時の依存パッケージは d3-geo と chizu だけです。

見た目は表の1項目

見た目で変わるのは線と塗りだけで、形は変わりません。STYLES には line と thick の項目がひとつずつあり、色は同じファミリーのほかの図と同じです。それ以外の値は初期値に戻されます(cleanStyle)。

import { cleanStyle, DEFAULT_STYLE, STYLE_NAMES } from "@johnmorrisdotca/chikyu-earth";

console.log(STYLE_NAMES, cleanStyle("neon"), DEFAULT_STYLE);
[ 'line', 'thick' ] line line

ビューはカメラで、投影に対応づけられる

共有のビューコントロール(kazoku-ui)は、カメラ { yaw, tilt, zoom, panX, panY } を伝えてきます。projectionView はそれを d3-geo の正射投影に対応づけます。yaw は基準の経度から地球を軸まわりに回し、tilt は基準の緯度から極の方へ傾け、zoom は拡大率を掛け、pan は平行移動を足します。yaw、tilt、pan がなければ、ビューは基準の中心になり、Fit は zoom が1の状態です。この対応づけは純粋で、単独でテストされています。

import { HOME_VIEW, projectionView } from "@johnmorrisdotca/chikyu-earth";

const view = projectionView({ lon: 139.7, lat: 35.7 }, 420, { ...HOME_VIEW, yaw: 30, zoom: 2 });
console.log(view.rotation, view.scale, view.translate);
[ -109.69999999999999, -35.7 ] 418 [ 210, 210 ]

地球自身の速さ

自動で回すときの速さは選べません。地球自身の速さを使います。恒星日は23時間56分4.0905秒なので、地球儀は毎秒0.004178度で回り、実際の時間と合います。

import { DEGREES_PER_MS, SIDEREAL_DAY_MS, spinAt } from "@johnmorrisdotca/chikyu-earth";

console.log((SIDEREAL_DAY_MS / 3_600_000).toFixed(4), "hours;", (DEGREES_PER_MS * 1000).toFixed(6), "degrees a second;", spinAt(SIDEREAL_DAY_MS / 4), "degrees in a quarter day");
23.9345 hours; 0.004178 degrees a second; 90 degrees in a quarter day

要素は必要なときだけ描く

<chikyu-earth> は状態を持ち、何かが変わったときだけ再描画を求めます。操作の最中は変形をひとつ動かすだけで、操作が落ち着くと SVG を最初から描き直します。スタイルは constructable stylesheet としてシャドウルートに書き込まれるので、厳格なコンテンツセキュリティポリシー(style-src 'self')でも許可されます。

4つの任意の層

エントリーポイント加わるもの必要なもの
/realistic と /realistic/element宇宙から見た地球:本物の太陽による昼と夜、街の明かり、海の太陽の反射、雲、大気。three
/markersattachMarkers:どちらの地球儀にも目印、まとめ表示、ラベルを付けます。投影、まとめ、ラベルの配置は純粋です。追加なし
/space と /space/element<chikyu-space>:ある日時の地球、月、太陽、惑星の位置。three、astronomy-engine
/satellites軌道要素(SGP4)から求める人工衛星の位置と、動く天体にカメラを載せる機能。satellite.js

純粋な部分はどれもサーバーで読み込めます。three.js を使う部分は、kazoku-ui の共有レンダラーを通ります。WebGL コンテキストはページにひとつで、どの要素が描いても同じものを使い、最後の要素がページから外れて1秒後に解放されます。宇宙の表示と人工衛星は、毎フレーム計算し直す代わりに、1秒離れた2つの計算結果のあいだを補間します。

しないこと

  • 実行時に、輪郭、名前、そのほかのデータを取得すること。
  • 何も変わらないのにフレームのループを回すこと、画面外や隠れたタブで描くこと、1辺4096ピクセル・合計600万ピクセルを超えるキャンバスを作ること。
  • style 属性から見た目を読むこと。HTML では本物の CSS であり、React では壊れるので、見た目は look で指定します。軽さを保つしくみを参照してください。

制限の全体は軽さを保つしくみに、各層はリアルな地球と目印にあります。

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

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