ジャコ Lab

プログラミング関連のメモ帳的ブログです

Tips:React で緯度経度の2地点間の距離を計算したい (2) - geolib 編

github.com

geolib っていうモジュールもスターが多くて良さそうだぞ?
ということで、本日は Turf.js とは異なる緯度経度計算モジュールを使ってみようと思います。

モジュール選定大事

geolib というモジュールでやってみる

モジュールのインストール

$ yarn add geolib

使い方

import * as geolib from "geolib";

const from = { lat: "35.65862055760233", lng: "139.74543043734087" };
const to = { lat: "35.71013065861893", lng: "139.81068527858596" };
const d = geolib.getDistance(geo1, geo2);

console.log(`${d} m`)

const converted = geolib.convertDistance(d, "km");
console.log(`${d} km`)
geolib はメートルで出力されるみたいなので、キロメートルにするためには変換を噛ます必要がある

React で書いてみる

  const onClick = () => {
    if (!geo1.lat || !geo1.lng || !geo2.lat || !geo2.lng) {
      return;
    }

    const d = geolib.getDistance(geo1, geo2);
    const converted = geolib.convertDistance(d, "km");
    setDistance(converted);
  };
前回の記事と比べて計算モジュールが変わっただけなので、変化点はここだけ
前回の記事はこちら

スクリプト全体

(折りたたみ)

import reactLogo from "./assets/react.svg";
import viteLogo from "/vite.svg";

import "./App.css";
import { useState } from "react";
import * as geolib from "geolib";
import { Box, Button, TextField, Typography } from "@mui/material";

function App() {
  const [geo1, setGeo1] = useState({ lat: "35.65862055760233", lng: "139.74543043734087" });
  const [geo2, setGeo2] = useState({ lat: "35.71013065861893", lng: "139.81068527858596" });
  const [distance, setDistance] = useState(0);

  const onClick = () => {
    if (!geo1.lat || !geo1.lng || !geo2.lat || !geo2.lng) {
      return;
    }

    const d = geolib.getDistance(geo1, geo2);
    const converted = geolib.convertDistance(d, "km");
    setDistance(converted);
  };

  return (
    <>
      <Box sx={{ marginBottom: "1em" }}>
        <a href="https://vitejs.dev" target="_blank">
          <img src={viteLogo} className="logo" alt="Vite logo" />
        </a>
        <a href="https://react.dev" target="_blank">
          <img src={reactLogo} className="logo react" alt="React logo" />
        </a>
      </Box>
      <Box sx={{ marginBottom: "1em" }}>
        <TextField
          type="number"
          label="緯度"
          variant="outlined"
          value={geo1.lat}
          onChange={(evt) => {
            setGeo1({ ...geo1, lat: evt.target.value });
          }}
          sx={{ marginRight: "1em" }}
        />
        <TextField
          type="number"
          label="経度"
          variant="outlined"
          value={geo1.lng}
          onChange={(evt) => {
            setGeo1({ ...geo1, lng: evt.target.value });
          }}
        />
      </Box>
      <Box sx={{ marginBottom: "1em" }}>
        <TextField
          type="number"
          label="緯度"
          variant="outlined"
          value={geo2.lat}
          onChange={(evt) => {
            setGeo2({ ...geo2, lat: evt.target.value });
          }}
          sx={{ marginRight: "1em" }}
        />
        <TextField
          type="number"
          label="経度"
          variant="outlined"
          value={geo2.lng}
          onChange={(evt) => {
            setGeo2({ ...geo2, lng: evt.target.value });
          }}
        />
      </Box>
      <Box>
        <Button
          variant="outlined"
          onClick={onClick}
          sx={{ marginBottom: "1em" }}
        >
          距離を計算する
        </Button>
        <Typography variant="body1" textAlign="left">
          距離:{distance} km
        </Typography>
      </Box>
    </>
  );
}

export default App;

動作確認

動作確認
動作確認

上手く動いた!

まとめ

無事、このモジュールも動いた