ハウツー ドラッグできるマーカーで座標を取得するには
マーカーをドラッグで動かし、離した位置の緯度と経度を受け取ります。地点を登録、編集する画面で、ユーザーにピンを置いてもらう用途に使えます。
コード
maps-suite の Marker はドラッグに対応していないため、読み込みを待ってから基盤の地図(maplibre)のマーカーを使います。dragend(ドラッグ終了)で位置を取り出します。
import "maplibre-gl/dist/maplibre-gl.css";
import "@geolonia/maps-core/css";
import { geolonia } from "@geolonia/maps-suite";
import maplibregl from "maplibre-gl";
const map = new geolonia.maps.Map(document.getElementById("map"), {
apiKey: "YOUR-API-KEY",
center: { lat: 35.6812, lng: 139.7671 },
zoom: 14,
});
await map.whenReady();
const marker = new maplibregl.Marker({ draggable: true })
.setLngLat([139.7671, 35.6812])
.addTo(map.getGeoloniaMap());
marker.on("dragend", () => {
const { lng, lat } = marker.getLngLat();
console.log("緯度:", lat, "経度:", lng);
});new maplibregl.Marker({ draggable: true }):ドラッグを有効にしてマーカーを作ります。setLngLatは[経度, 緯度]の順です。marker.on("dragend", ...):離した瞬間に一度だけ呼ばれます。動いている最中に追いたいときはdragを使います。marker.getLngLat():現在位置を返します。フォームの緯度と経度の欄に書き戻すなどして使います。
Marker に draggable を付け、onDragEnd で位置を受け取ります。
import "maplibre-gl/dist/maplibre-gl.css";
import "@geolonia/maps-core/css";
import { useState } from "react";
import { createRoot } from "react-dom/client";
import { Map, Marker } from "@geolonia/maps-react";
function App() {
const [pos, setPos] = useState({ lat: 35.6812, lng: 139.7671 });
return (
<div style={{ display: "flex", flexDirection: "column", height: "100vh" }}>
<p>緯度: {pos.lat.toFixed(6)} / 経度: {pos.lng.toFixed(6)}</p>
<Map
apiKey="YOUR-API-KEY"
center={[139.7671, 35.6812]}
zoom={14}
containerStyle={{ flex: 1 }}
>
<Marker
lat={pos.lat}
lng={pos.lng}
draggable
onDragEnd={(e) => {
const { lng, lat } = e.target.getLngLat();
setPos({ lat, lng });
}}
/>
</Map>
</div>
);
}
createRoot(document.getElementById("root")).render(<App />);draggable:マーカーをドラッグで動かせるようにします。onDragEnd:ドラッグを離したときに呼ばれます。e.target.getLngLat()で離した位置を取り出せます。- 取り出した座標を state に入れておけば、フォームの送信値としてそのまま使えます。
結果
上のコードは、それぞれのタブの下でそのまま動いています。マーカーをドラッグして離すと、その位置の緯度と経度が取得できます(suite の例はコンソールに出力、react の例は地図の上に表示します)。取得した座標は、フォームの入力欄に書き戻したり、サーバーへ送信したりして使います。
うまくいかないとき
- ドラッグできない →
draggable(suite はnew maplibregl.Marker({ draggable: true }))を付け忘れていないか確認します。 - 座標が
[経度, 緯度]で混乱する →getLngLat()は{ lng, lat }のオブジェクトを返します。配列に直すときは[経度, 緯度]の順です。 - ドラッグ中は座標が更新されない →
dragend(onDragEnd)は離したときだけ呼ばれます。移動中も追いたいときはdrag(onDrag)を使います。