3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

React-Nativeで地図を表示する(react-native-maps)

Last updated at Posted at 2021-12-12

目的

Expoアプリケーションに地図を導入する
ライブラリの選定。導入手順を整理する

環境

  • Expo 4.13.0
  • react@17.0.2
  • reactNative 4.9.0

目標

  • ReactNativeアプリケーションに地図を導入する
  • 地図は、現在位置の取得やカスタマイズ可能なラベルを配置できる
  • GoogleMapは有償であるため、Open Street Mapを利用する
     →断念。詳細はこの記事の最後「OpenStreetMapの導入について」をご確認ください。
     もし、みなさんどうしているのか、知見があるようでしたら、共有いただけますと、 大変ありがたいです。

地図の導入方針

React-leafletがをそのままNativeでは使う方法はない。以下のライブラリを候補に検討した

【React Native】「react-native-maps」ライブラリを使ってOpenStreetMapを表示する
https://cpoint-lab.co.jp/article/202011/17919/

  • ピンなどの応用
  • ピンの代わりにコンポーネントを渡すことも可能

ー> react-native-maps を利用することにした

導入手順 Expo

1) インストール

expo install react-native-maps

2) サンプル画面を設置

  • この時点で、標準の地図は表示される
App.js
import * as React from 'react';
import MapView from 'react-native-maps';
import { StyleSheet, Text, View, Dimensions } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <MapView style={styles.map} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  map: {
    width: Dimensions.get('window').width,
    height: Dimensions.get('window').height,
  },
});

3) APIキーを設定

  • Open street mapを利用する場合
    (要確認) APIキーはGoogle Mapを利用するために必要なものであり、OpenStreetMapを利用する場合は設定不要?

  • Google Mapを利用する場合

Expo公式
https://docs.expo.dev/versions/latest/sdk/map-view/#deploying-google-maps-to-an-android-standalone
Android Maps SDK for Android
https://developers.google.com/maps/documentation/android-sdk/get-api-key

  • app.jsonにapiキーを設置
app.json
  "android": {
      "config": {
        "googleMaps" :{
          "apiKey" : "{APIKEYを設定する}"
        }
      }

※ ストアリリースしていないため、実際に本番で正しく動くか確認できていません。リリース時に詳細追記します

4) Mapのカスタマイズ

  • MapView周りを作り込みます
  • インポートを追加し、UrlTile, Markerを追加します
  • 初期表示位置を region にステートで持たせます
  • urlTemplate に、Opem Street Mapのタイルを設定します(設定する場合)
  • MapViewの中に、Markerコンポーネントを配置することでマーカーを設置します
  • onRegionChangeは画面表示位置の変更を検知します。regionで受け取った値を、位置をもつstatenregionに設定することで、表示位置を更新します
app.js
import MapView, { UrlTile, Marker } from 'react-native-maps';

class Map extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // 初期表示位置を設定
      region: {
        latitude: 35.645736,
        longitude: 139.747575,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      },
      urlTemplate: 'http://c.tile.openstreetmap.org/{z}/{x}/{y}.jpg',
      markers: [
        {
          key: 'tamachiStation',
          latlng: {
            latitude: 35.645736,
            longitude: 139.747575,
          },
          title: '田町駅',
          description: '田町ニューデイズ',
        },
      ],
    };

  }

   onRegionChange(region) {
    console.log("onReasionChange");
    console.log(region);
    this.setState({ region });
  }

  

  render() {
    return (
      <View style={styles.container}>

        <MapView
        style={styles.map}
        region={this.state.region}
        onRegionChange={this.onRegionChange.bind(this)}
        >
        <UrlTile
            urlTemplate={this.state.urlTemplate}
            maximumZ={19}
            mapType={'none'}
          />

          {this.state.markers.map(marker => (
            <Marker
              key={marker.key}
              coordinate={marker.latlng}
              title={marker.title}
              description={marker.description}
            />
          ))}

        </MapView>
      </View>
    );
  }
}

5) 現在位置の取得

  • パーミッションを追加
app.json
"android": {
      "versionCode": 1,
      "package": "com.miraiyamaneko.samplepackagename",
      "googleServicesFile": "./google-services.json",
      "permissions": [
        "CAMERA",
        "WRITE_EXTERNAL_STORAGE",
        "CAMERA_ROLL"
      ],
  • 以下のコードを追加
import * as Location from 'expo-location';
  • 画面読み込み後に現在位置を取得するメソッド実行
  • パーミッションを確認し、Grandなら位置情報を取得しStateに設定
App.js
componentDidMount() {
    console.log("画面起動")
    // 現在位置を読み込む
    this._getLocationAsync();
  }

  // 現在位置の取得
  _getLocationAsync = async () => {
    let { status } = await Location.requestForegroundPermissionsAsync();
    console.log("Status");
    console.log(status);
    if (status !== 'granted') {
      this.setState({
      submitMessage: '位置情報の取得が許可されませんでした。',
      });
    }else if(status === 'granted'){
      console.log("getCurrentPositionAsync");
      await Location.getCurrentPositionAsync({}).then((location) => {
        let longitude = '経度:' + JSON.stringify(location.coords.longitude);
        let latitude = '緯度:' + JSON.stringify(location.coords.latitude);
        console.log(longitude);
        console.log(latitude);
        // 現在位置をMap Viewの中心に更新
        this.setState({
          region: {
            latitude: location.coords.latitude,
            longitude: location.coords.longitude,
            latitudeDelta: 0.01,
            longitudeDelta: 0.01,
          }
        })

      }).catch((e) => {
        console.log("現在位置取得失敗");
        console.log(e);
      });

    }
  };
  • iOSSimulator利用の場合は、シミュレータに位置情報を設定する
    Location.getCurrentPositionAsync({})実行時に、レスポンスがない、または次のエラーが発生する場合は、シミュレータに現在位置が設定されていない
    Cannot obtain current location: Error Domain=kCLErrorDomain Code=0 "(null)"
    シミュレータのfeatures>Location>CustomLocationを選択し、緯度・軽度を設定する

  • コード全体

OpenStreetMapの導入について

  • 問題事象
App.js
<UrlTile
  urlTemplate={this.state.urlTemplate}
  maximumZ={19}
/>

mapタイルを定義する上記を設定しても、OpenStreetMapの画面が表示されない
Androidでのみ発生する

参考資料

react-native-mapsを使って地図を表示
https://honmushi.com/2019/12/13/expo-map/

【React Native】「react-native-maps」ライブラリを使ってOpenStreetMapを表示する
https://cpoint-lab.co.jp/article/202011/17919/

React Native と OpenStreetMap で散歩用のiOS地図アプリを作ってみた
https://qiita.com/lfcd85/items/248d944592b93c2c009e

Expo 公式ドキュメント
https://docs.expo.dev/versions/latest/sdk/map-view/

現在位置の取得方法
Expoを使ったGPS情報取得の実装
https://honmushi.com/2019/12/10/expo-location/

通常のReactへのleafletの導入

React-leafletの使い方メモ
https://qiita.com/studio_haneya/items/fbb52fa03ab4f212ced0

Leaflet + OpenStreetMap で地図情報を扱うサンプルコード
https://qiita.com/TakeshiNickOsanai/items/783caa9f31bcf762da16

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?