Leaflet のコードを 3D の地球儀へ
npm i @ortho-earth/leaflet @ortho-earth/globe
@ortho-earth/leaflet は、Leaflet 1.9 と同じ形の L を返します。地図・タイル・マーカー・ポップアップ・図形・GeoJSON は MapLibre GL を通して描かれ、
描く先は Ortho Earth の地球儀(@ortho-earth/globe/maplibre)でも、本物の maplibre-gl でも構いません。
Leaflet 向けに書いたコードは形がそのままで、変えるのは import だけです。Leaflet のスタイルシートも要りません。
// 地球儀の上で
import L from "@ortho-earth/leaflet/globe";
const map = L.map("map").setView([35.6812, 139.7671], 15);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { maxZoom: 19, attribution: "© OpenStreetMap" }).addTo(map);
L.marker([35.6812, 139.7671]).addTo(map).bindPopup("<b>東京駅</b>").openPopup();
L.geoJSON(parks, { style: f => ({ fillColor: f.properties.kind === "park" ? "green" : "gray" }) }).addTo(map);
@ortho-earth/leaflet/globe は Leaflet の名前付き export(map・tileLayer・marker …)も持つので、bundler の alias ひとつで、import に触らずにアプリ全体を移せます。
// vite.config.js
export default { resolve: { alias: { leaflet: "@ortho-earth/leaflet/globe" } } };
平らな地図のままにしたいときは、@ortho-earth/leaflet の createLeaflet(maplibregl, { style }) に maplibre-gl を渡します。window.L を読むスクリプトやプラグインには installGlobal(L) を使います。
| Leaflet | 地球儀の上では |
|---|---|
L.map とその option、setView・flyTo・fitBounds・panTo、点の変換、handler(map.dragging.disable() …) | カメラ。ズームは 1 ずれます(Leaflet の z = MapLibre の z − 1。256 px と 512 px のタイルの違い)。fitBounds は Leaflet と同じ計算なので、移したコードは同じズームに着きます。回転と傾きは、頼まない限り(rotate: true)切ったままです |
地図のイベント(click・move・zoomend・popupopen …) | Leaflet のイベントの形(latlng・containerPoint・layerPoint)で届く MapLibre のイベント。図形のマウスのイベントは、Leaflet と同じく group へ、それから地図へ伝わります |
L.tileLayer({s}・{r}・tms・自分の {keys}・maxNativeZoom・bounds・opacity)、L.tileLayer.wms、createTile を持つ L.GridLayer | raster の source。GridLayer の canvas と <img> のタイルは protocol を通して描きます |
L.marker・L.icon・L.divIcon、ポップアップとツールチップ(bindPopup・bindTooltip・permanent・sticky・direction) | MapLibre のマーカーとポップアップを、Leaflet が置く位置に置きます。既定のアイコンは Leaflet の青いピンの SVG で、画像ファイルを用意する必要はありません |
L.polyline・L.polygon・L.rectangle・L.circle(メートル)・L.circleMarker(ピクセル)、setStyle・toGeoJSON | pane ごとに GeoJSON の source を 1 つ(Leaflet の pane ごとの renderer と同じ)。1 万の地物でも source は 1 つです |
L.geoJSON(style・pointToLayer・onEachFeature・filter)、L.layerGroup・L.featureGroup | Leaflet と同じく、地物ごとに layer を 1 つ |
L.imageOverlay・L.videoOverlay | 画像と動画の source |
L.control.zoom・attribution・scale・layers・L.Control.extend、pane(createPane・zIndex) | MapLibre の四隅の control。pane は layer の重ね順になります |
L.Class・L.Evented・L.Util・L.DomUtil・L.DomEvent・L.latLng・L.latLngBounds・L.CRS … | ただの値と道具。L.Class.extend で作ったプラグインも読み込めます |
L.CRS.Simple、EPSG:4326 の地図):地球儀は WGS84 で、平らな MapLibre の地図は Web メルカトルで描きます。path.getElement() は null を返します(図形は MapLibre の地物です)。マーカーのクラスタリングや Leaflet.draw のように、Leaflet の pane や renderer に描くプラグインは描かれません。GridLayer タイル、detectRetina、zoomanim イベント。
訳さないものは、コンソールに [lfshim] unsupported: … と一度だけ出ます(例外にはしません)。
L.unsupportedReport() がその一覧を返すので、動かすだけで移植を確かめられます。ほかのことは、map.getMapLibre() が下の地図を返します。
地球儀の上では、その地図で エンジン の全部(地形・3D Tiles・共通の時計・夜の側)も使えます。
検定は、上の Leaflet の呼び出しを本物の地球儀で動かします(packages/globe で npm run verify:ui -- t-leaflet)。
MapLibre や CesiumJS と違い、Leaflet の公式例のギャラリーはまだ無いので、この頁の表が対応の一覧です。
ほかの道具から来た人は Google マップから・MapLibre GL JS から・CesiumJS から も見てください。