※このブログではサーバー運用、技術の検証等の費用のため広告をいれています。
記事が見づらいなどの問題がありましたらContactからお知らせください。

<前のページ
【React + TypeScript】GoogleMapReactコンポーネントを使う-Part1
次のページ>
【React + TypeScript】GoogleMapReactコンポーネントを使う-Part3

【React + TypeScript】GoogleMapReactコンポーネントを使う-Part2

web開発 フロント開発 Google Maps Google Geocoding API google-maps-react Google Maps API TypeScript

投稿日:2021年3月29日

このエントリーをはてなブックマークに追加

はじめに

この記事について

この記事では前回のPart1のMapの描画位置を動かした際に処理を追加する方法について解説しています。コードはPart1のものを使いまわします。
記事のサンプル中のコードは有料のAPIを使うことに注意してください。
Google Maps APIは月$200ドルまで無料枠として利用できるためローカルで動かす分にはほとんど問題になりませんがその都度GoogleMapsPlatformでAPIの利用回数は確認しておきましょう。

環境について

この記事のコードは以下の環境で確認されています。

  • node version 10.19.0
  • npm version 6.14.4
  • google-map-react version 2.1.9
  • react version 17.0.1

実践

onChangeプロパティ

はじめに簡単に解説します。

GoogleMapReactコンポーネントのonChangeプロパティに関数を渡すことでマウスやジェスチャで地図の描画位置などが変更された際にカスタムの処理を加えることができます。
表示している地図の位置や範囲などを取得したい場合にはこのプロパティを利用しましょう。
onBoundsChangeというプロパティもMapの状態が変更された際の処理を組み込めますが、これは現在非推奨です。onChangeを使ってください。

コンポーネントのstateを更新する

前回のPartで作成したコンポーネントに以下のような機能を追加します。

  • 地図の表示が変更された際にコンポーネントのstateを更新しその状態を描画

では早速onChangeプロパティを使って希望の機能を作成しましょう。

./SampleComponent.tsx
import React, { useEffect, useState } from "react";
import GoogleMapReact, { ChangeEventValue } from "google-map-react";

/**
 * Mapに使用するプロパティ
 */
interface MapProps {
  center: {
    lat: number;
    lng: number;
  };
  zoom: number;
}

/**
 * MapのPropsの初期値
 */
const initialMapProps: MapProps = {
  center: {
    lat: 35.39,
    lng: 139.44,
  },
  zoom: 18,
};

/**
 * APIキー
 */
const API_KEY = "************"; // TODO: 自分のキーをここに入力

/**
 * サンプルとして地図を表示するコンポーネント
 */
const SampleMap = () => {
  const [mapProps, setMapProps] = useState<MapProps>(initialMapProps);

  /**
   * 地図の状態が変更された際にstateを更新する
   * @param v
   */
  const changeMap = (v: ChangeEventValue) => {
    const nextMapProps = {
      center: v.center,
      zoom: v.zoom,
    };
    setMapProps(nextMapProps);
  };

  useEffect(() => {
    // TODO: 表示位置に合わせて処理を入れる
    console.log(mapProps);
  }, [mapProps]);
  return (
    <div style={{ width: "100vw", height: "100vh" }}>
      ({mapProps.center.lat},{mapProps.center.lng}),zoom:{mapProps.zoom}
      <GoogleMapReact
        bootstrapURLKeys={{ key: API_KEY }}
        defaultCenter={mapProps.center}
        defaultZoom={mapProps.zoom}
        onChange={changeMap}
      />
    </div>
  );
};

export default SampleMap;

これでMapの表示位置の変更にたいしてコンポーネントのstateが更新されるようになりました。

発展

更新されるstateとその他のGoogle Maps APIを活用することで様々な機能を実装できるようになります。
ここでは例としてGeoconding APIを使ってみます。

以下のコードを動かすにはGoogleMapPlatformGeocoding APIを有効化する必要があります。

./SampleComponent.tsx
import React, { useEffect, useState } from "react";
import GoogleMapReact, { ChangeEventValue } from "google-map-react";

/**
 * GeoLocationAPIのレスポンス
 * 今回使うな部分のみ
 */
interface GeocodingAPIResponse {
  plus_code: {
    compound_code: string;
    global_code: string;
  };
}

/**
 * Mapに使用するプロパティ
 */
interface MapProps {
  center: {
    lat: number;
    lng: number;
  };
  zoom: number;
}

/**
 * MapのPropsの初期値
 */
const initialMapProps: MapProps = {
  center: {
    lat: 35.39,
    lng: 139.44,
  },
  zoom: 18,
};

/**
 * APIキー
 */
const API_KEY = "********"; // TODO: 自分のキーをここに入力

/**
 * サンプルとして地図を表示するコンポーネント
 */
const SampleMap = () => {
  const [mapProps, setMapProps] = useState<MapProps>(initialMapProps);
  const [location, setLocation] = useState<string>("");

  /**
   * 地図の状態が変更された際にstateを更新する
   * @param v
   */
  const changeMap = (v: ChangeEventValue) => {
    const nextMapProps = {
      center: v.center,
      zoom: v.zoom,
    };
    setMapProps(nextMapProps);
  };

  /**
   * GeocodingAPIを使って現在の地図の中心を表す文字列を返す
   * @returns
   */
  async function callGeocodingAPI(): Promise<GeocodingAPIResponse> {
    const url = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${mapProps.center.lat},${mapProps.center.lng}&key=${API_KEY}`;
    const response = await fetch(url);
    const body = (await response.json()) as GeocodingAPIResponse;
    return body;
  }

  /**
   * 地図の表示が変更された時locationを更新する
   */
  useEffect(() => {
    const callAPI = async () => {
      const response = await callGeocodingAPI();
      setLocation(response.plus_code.compound_code);
    };
    callAPI();
  }, [mapProps]);

  /**
   * 描画
   */
  return (
    <div style={{ width: "100vw", height: "100vh" }}>
      ({mapProps.center.lat},{mapProps.center.lng}),zoom:{mapProps.zoom}
      {location}
      <GoogleMapReact
        bootstrapURLKeys={{ key: API_KEY }}
        defaultCenter={initialMapProps.center}
        center={mapProps.center}
        defaultZoom={initialMapProps.zoom}
        zoom={mapProps.zoom}
        onChange={changeMap}
      />
    </div>
  );
};

export default SampleMap;

このコンポーネントは下の様に中心の地名を表示してくれます。

▲地図の上に地名が表示される

上の例では地図をいじるたびに毎回有料のAPIが呼ばれてしまいます。
本来このような呼び方は無駄にお金がかかるため理想的では無いことに注意してください。


参考URL

このエントリーをはてなブックマークに追加

<前のページ
【React + TypeScript】GoogleMapReactコンポーネントを使う-Part1
次のページ>
【React + TypeScript】GoogleMapReactコンポーネントを使う-Part3

関連記事

記事へのコメント