#何を作るか
googleMapAPIを使ってgooglemapっぽいのを作りましたので、そのまとめです。
React使いたいな〜って単純な理由でReactで作りましたが、差分更新が簡単にできたので嬉しかったです
長くなってしまうので、とりあえず
- map表示
- 現在地表示
- 吹き出し表示
まで!
#環境構築
create-react-appで作っていきます。
create-react-app map
cd map
yarn start
TSで作るなら
create-react-app map --typescript
cd map
yarn start
使用するライブラリはgoogle-map-react
です。
googlemapをReactで扱うにはいろんなライブラリがありますが、単純に参考記事の多さで選びました。
google-map-react 公式
yarn add -D google-map-react
// Typescript使うなら↓
yarn add -D @types/google-map-react
あとはAPIキーを取得しなきゃですが、そこは割愛…
Map表示
直接でも良いですがApp.jsはMapのレンダリングに使います。
import React, { Component } from "react";
import Maps from "./Maps";
class App extends Component {
render() {
return (
<div>
<Maps />
</div>
);
}
}
export default App;
import React, { useState, useEffect } from "react";
import GoogleMapReact from "google-map-react";
//APIKEYは""としていれば開発者モードで使えます
const APIKEY = "";
const Maps = () => {
const [center, setCenter] = useState({ lat: "", lng: "" });
const [zoom, setZoom] = useState(13);
return (
//高さ指定してあげないとMap出ません!
<div style={{ height: "100vh", width: "100%" }}>
//google-map-reactからimport!
//bootstrapURLKeys,center,zoom値があれば表示されます
<GoogleMapReact
bootstrapURLKeys={{ key: APIKEY }}
center={center}
defaultZoom={zoom}
>
</GoogleMapReact>
</div>
);
};
export default Maps;
#現在地表示
カスタムマーカーを作るのはgoogle-map-reactを使えば簡単にできました!
GoogleMapReactに子コンポーネントとして書き込み、緯度経度を持たせてあげるだけです
<GoogleMapReact
bootstrapURLKeys={{ key: APIKEY }}
center={center}
defaultZoom={zoom}
>
<Marker
lat={XXXXXXXXX}
lng={XXXXXXXXX}
/>
</GoogleMapReact>
これをgeolocationを使って現在地に反映させます。
const Maps = () => {
//centerなどの値もState管理に
const [center, setCenter] = useState({ lat: "", lng: "" });
const [zoom, setZoom] = useState(13);
const [currentPosition, setCurrentPosition] = useState();
// 初期表示地点
const success = data => {
const currentPosition = {
lat: data.coords.latitude,
lng: data.coords.longitude
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
//geolocation使えない場合の値を返す
const error = data => {
const currentPosition = {
lat: 34.673542,
lng: 135.433338
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
//初期読み込み時のみgeolocationを動かす
useEffect(() => {
navigator.geolocation.getCurrentPosition(success, error);
}, []);
return (
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{ key: APIKEY }}
center={center}
defaultZoom={zoom}
>
{currentPosition ? (
<Marker
lat={currentPosition.lat}
lng={currentPosition.lng}
/>
) : null}
</GoogleMapReact>
</div>
);
};
export default Maps;
#吹き出し表示
Openかどうかをstate管理し、trueであれば表示します
const Maps = () => {
const [isOpen, setIsOpen] = useState(false);
const changeState = () => {
setIsOpen(!isOpen);
};
return (
:
{isOpen ? (
<Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
) : null}
</GoogleMapReact>
</div>
);
};
export default Maps;
const Maps = () => {
const [center, setCenter] = useState({ lat: "", lng: "" });
const [zoom, setZoom] = useState(13);
const [currentPosition, setCurrentPosition] = useState();
const [isOpen, setIsOpen] = useState(false);
// 初期表示地点
const success = data => {
const currentPosition = {
lat: data.coords.latitude,
lng: data.coords.longitude
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
const error = data => {
const currentPosition = {
lat: 34.673542,
lng: 135.433338
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
useEffect(() => {
navigator.geolocation.getCurrentPosition(success, error);
}, []);
const changeState = () => {
setIsOpen(!isOpen);
};
return (
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{ key: APIKEY }}
center={center}
defaultZoom={zoom}
>
{currentPosition ? (
<Marker
lat={currentPosition.lat}
lng={currentPosition.lng}
text="My Marker"
color="blue"
changeState={changeState}
/>
) : null}
{isOpen ? (
<Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
) : null}
</GoogleMapReact>
</div>
);
};
export default Maps;
なので全体はこんな感じ↓
import React, { useState, useEffect } from "react";
import GoogleMapReact from "google-map-react";
import "../styles.css";
const APIKEY = "";
const Maps = () => {
const [center, setCenter] = useState({ lat: 34.665442, lng: 135.432338 });
const [zoom, setZoom] = useState(13);
const [currentPosition, setCurrentPosition] = useState();
const [isOpen, setIsOpen] = useState(false);
// 初期表示地点
const success = data => {
const currentPosition = {
lat: data.coords.latitude,
lng: data.coords.longitude
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
const error = data => {
const currentPosition = {
lat: 34.673542,
lng: 135.433338
};
setCurrentPosition(currentPosition);
setCenter(currentPosition);
};
useEffect(() => {
navigator.geolocation.getCurrentPosition(success, error);
}, []);
const changeState = () => {
setIsOpen(!isOpen);
};
return (
<div style={{ height: "100vh", width: "100%" }}>
<GoogleMapReact
bootstrapURLKeys={{ key: APIKEY }}
center={center}
defaultZoom={zoom}
>
{currentPosition ? (
<Marker
lat={currentPosition.lat}
lng={currentPosition.lng}
text="My Marker"
color="blue"
changeState={changeState}
/>
) : null}
{isOpen ? (
<Baloon lat={currentPosition.lat} lng={currentPosition.lng} />
) : null}
</GoogleMapReact>
</div>
);
};
export default Maps;
Markerとかは切り分けて普通に作ればOKです!
↓こんな感じに
https://codesandbox.io/embed/google-maps-react-9slxw?fontsize=14&hidenavigation=1&theme=dark
とりあえず基本のところまで書いてみました。
詰まったところいっぱいあるのでかいつまんで残していきます
参考記事
公式
https://github.com/google-map-react/google-map-react/blob/master/API.md#ondragend-map--void
基本表示まで
https://levelup.gitconnected.com/reactjs-google-maps-with-custom-marker-ece0c7d184c4
geolocationで現在地を初期表示に
https://medium.com/@allynak/how-to-use-google-map-api-in-react-app-edb59f64ac9d
高さ固定
https://github.com/tomchentw/react-google-maps/issues/323
googlemapAPIに関するヒントいろいろ
https://www.granfairs.com/blog/staff/google-maps-api-03