やり方
現在地と、地球の上の場所
読む人の今いる場所と、いくつでもお気に入りの場所を、宇宙の見た目やリアルな地球に目印で出します。光の柱、ピン、輪の形で地面から立ち上がり、地球といっしょに回り、裏側に回ると隠れ、夜の側では暗めになります。名前は重なりません。何千か所でも 1 回の描画で描き、混み合う場所は数をつけて 1 つにまとめ、goToPlace でその場所へ向きを回せます。現在地をたずねるのはページで、パッケージは何も保存せず、どこにも送りません。
<chikyu-space> と <chikyu-earth-realistic> は、地球の上に場所の目印を出せます。読む人が今いる場所と、その人が残しておきたい場所です。目印は地面から立ち上がる小さな形で、地球といっしょに回り、地球の裏側に回ると隠れます。ズームしても画面の上での大きさ (ピクセル) は変わりません。
<chikyu-space
places='[{"id":"me","lon":139.69,"lat":35.69,"label":"現在地","kind":"here"},{"id":"osaka","lon":135.5,"lat":34.69,"label":"大阪"}]'
places-look="beam"
style="width: 420px"
></chikyu-space>| 属性 | プロパティ | 意味 |
|---|---|---|
places | places | 場所の JSON 配列です。それぞれ { id, lon, lat, label, kind, color } の形です。プロパティを設定すると属性に書き込まれ、空の配列にすると属性が消えます。 |
places-look | placesLook | beam (初期値): 地面から立ち上がる光の柱と、その根元の輪です。pin: 細い棒と丸い頭です。ring: 地面の輪だけです。 |
here-city | hereCity | 初期値はオフ (false) です。属性を付けるか on にすると、here の場所に、100 キロメートル以内でいちばん近い都市の名前が付きます。数字はその上限のキロメートルです。プロパティを false にするとオフになります。 |
- 種類。
kind: "here"は読む人が今いる場所で、背が高く、明るく、根元の輪がゆっくり広がります。ほかの場所はすべてfavourite(お気に入り) で、背が低く、細く、動きません。色は要素かページの--chikyu-place-hereと--chikyu-place-favouriteで変えられます。 - 場所ごとの色。
colorで、場所ごとに自分の色をつけられます。16 進の色 (#e8475f)、数字で書いたrgb()かhsl()、または色の名前です。それ以外は使わず、種類の色になります。 - 地面から立ち上がる。 目印は、画面から見た地面に対して上向きに立ちます。地球のふちの近くでは横にかたむき、根元の輪はほとんど横から見た形になります。真上から見る場所では、点につぶれないように画面の上のほうへかたむきます。
- 名前。 場所の
labelは、すき間があれば目印の上に出ます。hereが先で、あとは渡した順です。名前どうしは重ならず、宇宙の見た目では天体の名前とも重なりません。置く場所がない名前は出しませんが、目印は描きます。場所は、各層の名前のなかで最初に置かれます。目印のラベル、都市の名前、星と星座の名前は、場所の名前、場所の目印、輪を付けた衛星を避けます。逆はありません (空の名前の guide の「層の順序」を参照)。名前の大きさは、ページのフォントで実際に測ります。 - 夜は暗めに。 地球の夜の側にある場所は半分の明るさで描き、名前は読めるように、少しだけ暗くします。夕方や明け方はその間です。
light="lit"のときは地球全体が明るいので、暗くしません。 - 止まっているときは何もしない。 場所の配置は、絵を描くとき (カメラが動いた、時計が進んだ、設定が変わった) だけ計算します。輪が広がる動きは CSS のアニメーションなので、絵を描き直すことはありません。要素が見えないあいだは止まり、動きを減らす設定の人には出ません。
- 最大 5,000 か所。 それより長い配列は
MAX_PLACESまでに切ります。経度が -180 から 180 の外、または緯度が -90 から 90 の外にある場所は出しません。
たくさんの場所
ページは何千か所でも渡せて、それでも重くなりません。
const places = shops.map((shop) => ({ id: shop.id, lon: shop.lon, lat: shop.lat, label: shop.name, color: shop.open ? "#7dd3fc" : "#94a3b8" }));
space.places = [...(here ? [here] : []), ...places];- 最初のいくつかは立つ目印。 見えている場所のうち最初の
PLACE_MARKS(32) か所は、hereが先で、あとは渡した順に、名前といっしょに地面から立ち上がります。いちばん大事な場所を先に置いてください。 - ほかは 1 回の描画。 ほかの場所はすべて地面に置いた輪になり、いくつあっても 1 回の描画 (draw call) でまとめて描きます。輪も目印と同じく、画面の上での大きさが変わらず、地球といっしょに回り、ふちでうすくなり、裏側では出ず、夜の側では暗めになります。
- 混み合う場所はまとめる。 画面の上で約
PLACE_GROUP_PX(24) ピクセルより近い場所は、少し大きい 1 つの輪になり、横に数が出ます。ます目は地面に固定しているので、まとまりは地球といっしょに回り、ズームが約半分か約 2 倍になったときだけ変わります。ズームインすると分かれます。読む人の現在地はまとめません。同じ決まりを、ページやサーバーでもgroupPlacesとgroupCellで使えます。まとめるのが初期設定です。place-groups="off"(またはプロパティplaceGroups = false) にすると、まとめずに、場所ごとに 1 つずつ輪を出します。 - どれだけ描いたか。
stats.placesには、places(渡した数)、shown(見えている数、まとまりの中も数える)、marks(目印として立つ数)、labels(名前の数)、sprites(絵の 1 回の描画で描く輪の数。絵が輪を描けないときは 0)、dots(その代わりに、ページの中の小さい円として描いた輪の数)、groups(輪のうち、まとまりの数)、omitted(見えているのに、描く余地がなくて描けなかった場所の数)、renders(配置を計算した回数) があります。three.js のPointsがないとき (Pointsを含まない一部だけを渡したとき) は、絵の中に輪を描けないので、要素が自分で、輪を小さい円としてページの中に描きます (最大PLACE_DOTS(600) 個)。その円は、絵の中の輪と同じように、地球の縁で薄くなり、夜は暗くなります。それを超えて見えている場所はomittedに数え、そのときだけchikyu-places-unavailableを 1 回送ります (detail.reasonに理由、detail.omittedに数が入ります。Pointsがないだけでは送らず、二度は送りません)。数えられないまま消える場所はありません。
場所へ向ける
goToPlace は、場所が真ん中に来るように見る向きを回します。目で追える速さで回り、動きを減らす設定の人にはすぐに切り替わります。場所は id か名前 (label) で指定します。
const place = await space.goToPlace("tokyo");
if (!place) console.log("その場所はありません");- ズームはそのまま。 変わるのは向きだけです。ズームしたいときはページがします。
- 地球を見ているとき。 宇宙の見た目では、カメラが地球を見ている必要があります。ほかの天体といっしょに移動しているときや、ほかの天体を見ているときは何も動かず、
undefinedが返ります。 - かたむきは 90 度まで。 ドラッグと同じく、
centerから上下に 90 度までです。centerから緯度で 90 度より離れた場所は、その範囲でできるだけ真ん中に近づけます。centerは読む人の現在地の近くにしてください。
読む人の現在地
パッケージがブラウザーに現在地をたずねることはありません。たずねるのはページで、読む人が求めたときだけです。
import { nearby } from "@johnmorrisdotca/chikyu-earth/markers";
const space = document.querySelector("chikyu-space");
document.querySelector("#here").addEventListener("click", () => {
navigator.geolocation.getCurrentPosition((position) => {
const at = nearby({ lon: position.coords.longitude, lat: position.coords.latitude });
space.places = [{ id: "here", lon: at.lon, lat: at.lat, label: "現在地", kind: "here" }];
});
});- ボタンを押したときにたずねる。
getCurrentPositionは読む人のクリックから呼びます。こうすると、ブラウザーの確認は本人が求めたあとに出ます。消す方法も用意してください (space.places = [])。 - まるめる。
nearby(point, km)は、場所を約kmキロメートルのます目 (初期値は 10) に合わせます。目印が通りの名前までわかる位置に出ることはありません。描く前や残す前にまるめてください。 - 端末の中だけに置く。 要素は何も保存せず、どこにも送りません。本人が共有を選ばないかぎり、現在地をページのアドレスに入れたり、サーバーに送ったりしないでください。デモは開いているページの中だけで使い、ページを閉じると消えます。
いちばん近い都市の名前
here-city を付けると、kind: "here" の目印に、いちばん近い都市の名前がページの言語で出ます。初期値はオフです。オンになって、かつ here の場所があるときまで、kuni は読み込まれません。
<chikyu-earth-realistic here-city places='[{"id":"me","lon":139.69,"lat":35.69,"kind":"here","label":"現在地"}]'></chikyu-earth-realistic>- 頼まれたときだけ。 初期値はオフです (
hereCityはfalse)。お気に入りの名前は変わりません。 - 距離。 属性だけ、または
onのときは 100 キロメートル (HERE_CITY_KM) です。here-city="40"は 40 キロメートル以内だけを見ます。受け付けるいちばん遠い距離は 20,000 キロメートル (HERE_CITY_MAX_KM) です。上限より遠い都市は使わず、ページが付けたlabelのままです。 - どの都市か。 まず首都、人口100万人の都市、人口10万人の都市です。そのあと、多くても2つの国の小さな都市を、国ごとに1つのファイル (
citiesOf) から読みます。1つ目の国は、その3つの段でいちばん近い都市の国です。距離は問いません。2つ目は、別の国の都市も上限の内側にあるときだけ足します。国境の近くは、そうやって読みます。大きな都市より近い町があれば、そちらを出します。上限の外は使いません。kuni は、here-cityがオンでhereの場所があるまで読みません。名前は英語です。日本語のページでは、短い日本語名があればそれ、なければ日本語名です。 - ページの一覧は変わらない。
placesには、ページが設定した名前が残ります。変わるのは描かれる名前だけです。goToPlaceは、その名前かidで場所を探します。 - 止まっているときは何もしない。 名前を決めるのは、場所、言語、距離の上限が変わったときと、都市の一覧が届いたときだけです。絵が止まっているあいだは、決め直しません。
お気に入りの場所
kind: "here" がない場所は、すべてお気に入りです。パッケージは自分の一覧も、選ぶための画面も持っていません。読む人の一覧はページが作り (ページ独自の検索や、kuni の都市から)、好きな所に残し、変わるたびに一覧ごと渡します。
const saved = [{ id: "tokyo", lon: 139.69, lat: 35.69, label: "東京" }, { id: "cairo", lon: 31.24, lat: 30.04, label: "カイロ" }];
space.places = [...(here ? [here] : []), ...saved];- 一覧をどこに置くかはページが決める。 アカウントのあるサイトなら、読む人のアカウントに残します。デモは選んだ都市をページのアドレス (
fav=Tokyo,Cairo) に残すので、リンクを開くとその都市が出ます。読む人の現在地をそこに入れることはありません。 - 現在地より控えめ。 お気に入りは背が低く、細く、動かないので、その中でも読む人の現在地が目立ちます。名前が混み合うと、
hereの名前が先に置かれます。
ブラウザーなしで使える部分
@johnmorrisdotca/chikyu-earth/markers には、自分で場所を描くページやサーバー向けの計算部分があります。readPlaces と cleanPlaces (描いても安全な配列にする)、nearby、orthoView (正面から描いた絵を、中心の点、半径、枠から作る)、layoutPlaces (PlaceView から、絵の中の目印と名前の位置を出す。sun を渡すと、それぞれがどれだけ夜に入っているかも出す)、groupPlaces と groupCell (地球の幅が何ピクセルかに合わせて、混み合う場所をまとめる)、readHereCity と hereCityLabels (nearest を持つ一覧から、here の場所に付けるいちばん近い都市の名前を、キロメートルの上限の中で出す) です。
この日本語は、まだ日本語を母語とする方の確認を受けていません。訂正を歓迎します。