ジャコ Lab

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

Tips:React で緯度経度の2地点間の距離を計算したい - Turf.js 編

zako-lab929.hatenablog.com

昨日、 Google Map 上で距離が測れることを知りましたが、
本日は React 上で 緯度経度 を指示して距離を計算してみたいと思います。

React で2地点間の距離を計算するには?

Turf.js が良さそうな雰囲気

Turf.js
Turf.js

Simple : Modular, simple-to-understand JavaScript functions that speak GeoJSON.

Modular : Turf is a collection of small modules, you only need to take what you want to use .

Fast : Takes advantage of the newest algorithms and doesn't require you to send data to a server.

この辺を謳っているみたい

使ってみる

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

$ yarn add @turf/turf

使い方

import * as turf from "@turf/turf"

const from = turf.point([139.74543043734087, 35.65862055760233])
const to = turf.point([139.81068527858596, 35.71013065861893])
const d = turf.distance(from, to, { units: "kilometers" })

console.log(`${d} km`)
ふむふむ。簡単
ところで、緯度・経度なの?経度・緯度なの?

Google Map で得た座標は 緯度経度 の順番だったと思いますが、
ここでは 経度 , 緯度 の順番で設定するようです。

React で書いてみる

import { useState } from "react";
import * as turf from "@turf/turf";
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 from = turf.point([Number(geo1.lng), Number(geo1.lat)]);
    const to = turf.point([Number(geo2.lng), Number(geo2.lat)]);
    const d = turf.distance(from, to, { units: "kilometers" });

    setDistance(d);
  };

  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;

実行結果

実行結果
実行結果

うんうん、いい感じ

まとめ

React...というか、Web フロント上でも計算できた