本記事を作成したきっかけ
職業訓練の学校での卒業制作で、React Native(Expo)アプリを作成しました。
アプリでMap画面を作成し、振り返りの意味を込めて
本記事を作成しようと思った次第です。
本記事で使用しているライブラリは
- react-native-maps(MAP表示用)
- expo-location(現在地表示用)
です。
expo-mapsなるライブラリもあるのですが、
まだ正式版ではないのと、
Expo Goアプリでは利用できないと書いてあったので、
上記ライブラリを使用しております。
MAP画面作成準備
react-native-maps
react-native-mapsとは、
React NativeでMAP表示させるために使用するライブラリです。
1.ライブラリのインストール
npx expo install expo-maps
2.app.json修正(パッケージフィールド追加)
"android": {
"config": {
"googleMaps": {
"apiKey": "process.env.GOOGLE_MAPS_API_KEY",
},
},
}
"ios": {
"config": {
"googleMapsApiKey": "process.env.GOOGLE_MAPS_API_KEY",
},
}
※react-native-mapsを使用するには、
Google CloudのAPIキーが必須となりますので、
使用前にAPIキーの作成をお願いします。
具体的な手順は上記の公式ドキュメントを御確認ください。
expo-location
expo-locationとは、
React Nativeアプリで位置情報に関する機能を
簡単に扱えるようにするライブラリです。
ユーザーの現在地を取得したり、
位置情報の変化を監視したり、
ジオコーディング(住所⇔座標の相互変換)などが出来ます。
1.ライブラリのインストール
npx expo install expo-location
2.Androidエミュレータの現在地設定
サイドバーの一番下にある設定メニュー「...」を押下。
設定画面の右側にある「Location」メニューを押下。
Single pointsタブのMap画面で任意の場所をクリックし、
「SAVE POINT」を押下して現在地情報として保存。
保存すると、右側に保存した現在地情報が表示されるので、
クリックして「SET LOCATION」を押下。
3.iOSシミュレーターの現在地設定
Simulator の上部メニューから「Features」を選択。
「Location」を選択。
「Custom Location」を選択。
「Latitude(緯度)」と「Longitude(経度)」を入力。
「OK」ボタンを押下。
実装例
import { useEffect, useState } from "react"
import { StyleSheet, View, Text, Dimensions } from "react-native"
import MapView, { Marker, Region } from "react-native-maps"
import * as Location from "expo-location"
// マーカーのデータ型
// 経度・緯度の情報と一意キー用のidで構成
type Marker = {
id: number;
latitude: number;
longitude: number;
}
// マーカー表示用データ
const markersData: Marker[] =
[
{
id: 1,
latitude: 35.662346819815305,
longitude: 139.6991631860567
},
{
id: 2,
latitude: 35.6640117157159,
longitude: 139.6993884915927
},
{
id: 3,
latitude: 35.663218497391604,
longitude: 139.69760750497448
},
{
id: 4,
latitude: 35.661762790515354,
longitude: 139.69710324972715
},
{
id: 5,
latitude: 35.66078649319146,
longitude: 139.69840143876814
}
]
export default function MapSample() {
// 現在地
const [initRegion, setInitRegion] = useState<Region | null>(null)
// マーカー
const [markers, setMarkers] = useState<Marker[]>([])
// エラーメッセージ
const [errorMsg, setErrorMsg] = useState<string | null>(null)
useEffect(() => {
// 位置情報のアクセス許可を取り、現在地情報を取得する
const getCurrentLocation = async () => {
const { status } = await Location.requestForegroundPermissionsAsync()
if (status !== "granted") {
setErrorMsg("位置情報へのアクセスが拒否されました")
return
}
try {
const location = await Location.getCurrentPositionAsync({})
// 緯度・経度はgetCurrentPositionAsyncで取得した緯度・経度
// 緯度・経度の表示範囲の縮尺は固定値にしてます
setInitRegion({
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 0.05,
longitudeDelta: 0.05
})
} catch (error) {
console.error("現在地情報取得エラー:", error)
}
}
getCurrentLocation()
// 固定で設定したマーカー情報を設定する
setMarkers(markersData)
}, [])
return (
<>
<View style={styles.container}>
{errorMsg ? (
<Text>{errorMsg}</Text>
)
:
// MapViewではstyle設定は必須です。
// (設定しないとMAP表示されません)
// regionはinitRegion(Region型)を設定
// showsUserLocationはtrueにすると、現在地が青い点で表示します。
// providerをgoogleにするとiOSでもGoogleMapで表示してくれます。
// (デフォルトはapple map)
(<MapView
style={styles.mapContainer}
region={initRegion || undefined}
showsUserLocation={true}
provider="google"
>
{markers.map((marker) => (
// key指定は必須。
// coordinateは緯度・経度を設定する。
// pinColorでマーカーの色指定可能
<Marker
key={marker.id}
coordinate={{
latitude: marker.latitude,
longitude: marker.longitude
}}
pinColor="blue"
>
</Marker>
))}
</MapView>
)}
</View>
</>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
mapContainer: {
width: "100%",
height: "100%"
}
})
シミュレーターでの動作確認
現在地はスクランブル交差点
マーカーの情報は、渋谷にあるラーメン屋の
緯度・経度を設定して表示しております。
iOS
Android
注意点
初めての現在地表示の際は、
位置情報取得可否の確認が出てきますので、
許可するようにしてください。