React-Leafletでマップを表示


はじめに

React で地図を表示させ、その上にマーカーを表示させる。React Leaflet を参考に進めた。React の基本的な知識は知っている前提とする。

React-Leaflet のインストール

以下コマンドで、インストールできる。

$ npm install react react-dom leaflet
$ npm install react-leaflet

leaflet コンポーネントの作成

指定座標を中心に地図を表示させ、さらにマーカーを配置するコンポーネントを作成する。任意のディレクトリで SimpleLeaflet.js というファイルを作成し、以下コードを書く。ここでは components/Leaflet ディレクトリの直下に置いた。useState を使うことで指定位置やズームを変更することを見据えて position や zoom を作成しているが、この記事ではとくに用いていない。

SimpleLeaflet.js
import React, { useState } from "react";
import "leaflet/dist/leaflet.css";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";

const SimpleLeaflet = () => {
  const [position, setPosition] = useState({
    lat: 51.505,
    lng: -0.09,
  });
  const [zoom, setZoom] = useState(13);

  return (
    <div>
      <MapContainer center={position} zoom={zoom} style={{ height: "50vh" }}>
        <TileLayer
          attribution='&amp;copy <a href="http://osm.org/copyright";>OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Marker position={position}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </MapContainer>
    </div>
  );
};

export default SimpleLeaflet;

上記コンポーネントを作成後、App.js などに import SimpleLeaflet from "components/Leaflet/SimpleLeaflet.js"; でコンポーネントを読み込み、出力したい場所で <SimpleLeaflet /> とすれば以下のように地図を表示することができる。

import "leaflet/dist/leaflet.css"; での CSS を読み込みや、<MapContainer ... style={{ height: "50vh" }}> で高さの指定をしない場合は地図が適切に表示されないので注意。

上記ではマーカーがまだ表示されていない。調べたところ、Marker not appearing for simple example #453 を発見。これを参考にコードを追記したところ、マーカーを表示できた。

SimpleLeaflet.js
import React, { useState } from "react";
import "leaflet/dist/leaflet.css";
import { MapContainer, TileLayer, Marker, Popup } from "react-leaflet";
// add icons
import Leaflet from "leaflet";
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";

// marker setting
let DefaultIcon = Leaflet.icon({
  iconUrl: icon,
  shadowUrl: iconShadow,
});
Leaflet.Marker.prototype.options.icon = DefaultIcon;

const SimpleLeaflet = () => {
  const [lat, setLat] = useState(51.505);
  const [lng, setLng] = useState(-0.09);
  const [zoom, setZoom] = useState(13);
  const [position, setPosition] = useState({
    lat: 51.505,
    lng: -0.09,
  });

  return (
    <div>
      <MapContainer center={position} zoom={zoom} style={{ height: "50vh" }}>
        <TileLayer
          attribution='&amp;copy <a href="http://osm.org/copyright";>OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <Marker position={position}>
          <Popup>
            A pretty CSS3 popup. <br /> Easily customizable.
          </Popup>
        </Marker>
      </MapContainer>
    </div>
  );
};

export default SimpleLeaflet;

クリックすると、ポップアップが表示されることも確認できる。