1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React Native(Expo)】MAP表示と現在地表示

Posted at

本記事を作成したきっかけ

職業訓練の学校での卒業制作で、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修正(パッケージフィールド追加)

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」ボタンを押下。

実装例

mapsample.tsx
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

スクリーンショット 2025-04-09 16.14.48.png

Android

スクリーンショット 2025-04-09 16.17.14.png

注意点

初めての現在地表示の際は、
位置情報取得可否の確認が出てきますので、
許可するようにしてください。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?