【Google Places API】google mapの写真をFlutterで表示させてみた

image

この記事は、【 可茂IT塾 Advent Calendar 2022 】の8日目の記事です。

FlutterでGoogle places apiを使い、google mapの特定の場所の写真を取得し表示してみました。

岐阜県美濃加茂市にコワーキングスペース「coyane〜こやぁね〜」という可茂IT塾のアジトがあるのですが、自分は福岡在住のリモート組でこやぁねには一度も行ったことがないので、今回は、せっかくなのでこやぁねの写真を取得してのぞいてみたいと思います!

初めに

Google maps platformのapiキーが必要になるので、発行しておきましょう! https://developers.google.com/maps

取得の流れ

まず、大まかな取得の流れはこんな感じです。
ワード検索 > 場所情報取得 > 写真一覧抜き出す > URLから写真を表示

コード全体

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  
  State<StatefulWidget> createState() {
    return _HomePage();
  }
}

class _HomePage extends State<HomePage> {
  var urls = [];
  final API_KEY = "APIキー";
  final KEY_WORD = "〒505-0041 岐阜県美濃加茂市太田町2689 30 コミュニティ&コワーキングスペース co・ya^ne";

  Future<void> fetchPhoto() async {
    final searchRes = await http.get(Uri.parse(
        'https://maps.googleapis.com/maps/api/place/textsearch/json?query=$KEY_WORD&language=ja&key=$API_KEY'));

    final Map<String, dynamic> body = jsonDecode(searchRes.body);
    final place_id = body['results'][0]['place_id'];

    final placeRes = await http.get(Uri.parse(
        'https://maps.googleapis.com/maps/api/place/details/json?place_id=$place_id&key=$API_KEY'));

    final Map<String, dynamic> placeData = jsonDecode(placeRes.body);

    final List photos = placeData['result']["photos"];

    for (var photo in photos) {
      final photo_reference = photo['photo_reference'];
      final url =
          "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=$photo_reference&key=$API_KEY";
      urls.add(url);
      print(url);
    }
    setState(() {});
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
          child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const SizedBox(
            height: 50,
          ),
          SizedBox(
            height: 50,
            child: ElevatedButton(
                onPressed: () async {
                  await fetchPhoto();
                },
                child: const Text('done')),
          ),
          Expanded(
            child: urls.isEmpty
                ? Container()
                : GridView.builder(
                    itemCount: urls.length,
                    gridDelegate:
                        const SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2,
                    ),
                    itemBuilder: (BuildContext context, int index) {
                      final image = urls[index];

                      return _photoItem(image);
                    }),
          )
        ],
      )),
    );
  }

  Widget _photoItem(String image) {
    return Image.network(
      image,
      fit: BoxFit.cover,
    );
  }
}

めちゃめちゃ雑なコードですがどうかご了承ください🙇

解説

fetchPhoto()でapiの取得をまとめて行なっています。 中身を細かく解説していきます。

TextSearch

final searchRes = await http.get(Uri.parse(
        'https://maps.googleapis.com/maps/api/place/textsearch/json?query=$KEY_WORD&language=ja&key=$API_KEY'));

final Map<String, dynamic> body = jsonDecode(searchRes.body);

final place_id = body['results'][0]['place_id'];

TextSearchリクエストでは、フリー検索でヒットした場所IDを取得できます。
jsonはresultsのなかに検索ヒットしたデータが格納されています。今回は、住所と場所名で検索しているため、おそらくデータは一つしかないので0を指定して取得しています。次のリクエストでplace_idが必要になるのでここで抜き出します。

PlaceDetail

final placeRes = await http.get(Uri.parse(
        'https://maps.googleapis.com/maps/api/place/details/json?place_id=$place_id&key=$API_KEY'));

final Map<String, dynamic> placeData = jsonDecode(placeRes.body);

final List photos = placeData['result']["photos"];

PlaceDetailリクエストではplace_idを指定することで特定の場所情報取得できます。
jsonのresultの中のphotosに場所の写真情報が格納されているので抜き出します。

PlacePhotos

for (var photo in photos) {
 final PHOTO_REFERENCE = photo['photo_reference'];
 final url = "https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=$PHOTO_REFERENCE&key=$API_KEY";
 urls.add(url);

PlacePhotosリクエストは、photo_referenceを指定することでURLとして写真を取得できます。 PlaceDetailリクエストで取得したphotosを繰り返し処理でURLを一つずつ抽出していきます。 photo_referencephotoのjson内に格納されています。

ビルド


結果はこんな感じで表示されました
こやぁねめちゃめちゃ綺麗ですね!ここで作業したら生産性爆上がりしそうです。

最後に

今回は、こんな感じでFlutterでgoogle place apiを使ってこやぁねの写真を取得してみました。
他の検索リクエストを使えば、近くのラーメン屋の写真一覧みたいなのも取得できたりします。
月$200分のリクエストまで無料で使えるので、個人開発などで使う分には十分無料で使えるのではないでしょうか。

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (113)初心者向け (28)イベント (18)Google Apps Script (15)Nextjs (12)可茂IT塾 (9)Firebase (7)riverpod (6)React (6)ChatGPT (5)vscode (5)デザイン (5)新卒 (4)就活 (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)コード生成 (1)GitHub Copilot (1)オンラインオフィス (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)Freezed (1)ヒーター (1)作業効率 (1) (1)Flutter実践開発 (1) (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)VRChat (1)API (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)FlutterFlow (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)経験談 (1)フリーランス (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!

可茂IT塾ではFlutterインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More