Leaflet は地図を描画してその上で様々なことができるライブラリです。react-leaflet はこの Leaflet を React 上で使える様にするライブラリです。
Leaflet – a JavaScript library for interactive maps
React Leaflet | React Leaflet
この react-leaflet 上でよくある運用として地図の上に図形を描画するというものがあります。またこの図形を入出力する時もしばしばあります。そういった時に楽に図形の情報を得られると便利です。その取得方法を紹介します。
使うのは FeatureGroup というコンポーネントで、その名の通り leaflet の FeatureGroup に対応するコンポーネントです。
Child components | React Leaflet#FeatureGroup
Documentation – Leaflet – a JavaScript library for interactive maps#FeatureGroup
これは次の様に地図内の Layer オブジェクトに対応するコンポーネントを括るコンポーネントです。
const center = [51.505, -0.09] const rectangle = [ [51.49, -0.08], [51.5, -0.06], ] const fillBlueOptions = { fillColor: 'blue' } const fillRedOptions = { fillColor: 'red' } const greenOptions = { color: 'green', fillColor: 'green' } const purpleOptions = { color: 'purple' } render( <MapContainer center={center} zoom={13} scrollWheelZoom={false}> <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> <LayerGroup> <Circle center={center} pathOptions={fillBlueOptions} radius={200} /> <Circle center={center} pathOptions={fillRedOptions} radius={100} stroke={false} /> <LayerGroup> <Circle center={[51.51, -0.08]} pathOptions={greenOptions} radius={100} /> </LayerGroup> </LayerGroup> <FeatureGroup pathOptions={purpleOptions}> <Popup>Popup in FeatureGroup</Popup> <Circle center={[51.51, -0.06]} radius={200} /> <Rectangle bounds={rectangle} /> </FeatureGroup> </MapContainer>, )
この FeatureGroup コンポーネントの ref から Leaflet 側の FeatureGroup オブジェクトを参照でき、FeatureGroup オブジェクトの toGeoJSON メソッドから図形の情報を取得できます。具体的には次の様にできます。
import "./styles.css"; import "leaflet/dist/leaflet.css"; import { useRef, useState } from "react"; import { MapContainer, TileLayer, Circle, FeatureGroup } from "react-leaflet"; export default function App() { const fgRef = useRef(); const [geo, setGeo] = useState(""); const dump = () => { // FeatureGroup の ref を経由して toGeoJSON を呼び出して // FeatureGroup の子コンポーネントの Layer 全部を GeoJSON 化 setGeo(JSON.stringify(fgRef.current.toGeoJSON())); }; return ( <> <button onClick={dump}>出力</button> {geo} <MapContainer center={{ lat: 34.7, lng: 137.7 }} zoom={13} scrollWheelZoom={false} > <TileLayer attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" /> {/* ここで FetureGroup の ref を定義*/} <FeatureGroup ref={fgRef}> <Circle center={{ lat: 34.7, lng: 137.7 }} radius={200} /> </FeatureGroup> </MapContainer> </> ); }