見出し画像

PYTHONではじめてのWEBサイトを作成 5


GoogleCloudPlatformでAPIを利用可能にする

GCPのgooglemapAPIをつかってgooglemapをhomeに表示していきます。

ステップ1: Google Maps APIキーの取得

  1. Google Cloud Platformにログインし、プロジェクトを作成または選択します。

  2. Google Maps JavaScript APIを有効にします。
    一番上の検索窓で「Maps JavaScript API」と検索すると早いです。

  3. APIとサービス > 認証情報 に移動し、新しいAPIキーを作成します。
    開発時は私は制限をつけませんでしたが制限をつけたほうが安全です。
    また、APIの利用は一定回数無料ですが、それを超えると有料になるので注意が必要です。APIキーを取得できたらWEBサイトに反映していきます。


APIs&Service
Maps Javascript API


API Keys
API Keys


ステップ2: home.htmlにマップを表示

homeを以下のように目指します。

Loveバインミー
  1. ユーザーの位置情報を取得

  2. 近くのバインミーショップを表示

  3. 検索ボックスでバインミーショップを検索


MAPの位置を定義

<div id="map" style="height: 400px;"></div> 


JavaScriptで地図の初期化関数

function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 15
    });

initMap関数は地図を初期化。google.maps.Mapコンストラクタは、指定したHTML要素(div)に地図を作成。初期ズームレベルを15に設定。


現在位置の取得と設定

navigator.geolocationを使用してユーザーの現在位置を取得。取得成功時に地図の中心をユーザーの位置に設定し、searchNearbyBanhMi関数を呼び出して周辺のバインミーレストランを検索。失敗時にはhandleLocationError関数が呼び出される。

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(function(position) {
            var pos = {
                lat: position.coords.latitude,
                lng: position.coords.longitude
            };
            map.setCenter(pos);
            searchNearbyBanhMi(map, pos);
        }, function() {
            handleLocationError(true, map);
        });
    } else {
        handleLocationError(false, map);
    }


検索ボックスの設定

検索ボックスを設定し、ユーザーが入力した場所に応じて地図を更新。SearchBoxはGoogle Maps Placesライブラリを使用して場所の自動補完をしてくれる。

    var input = document.getElementById('location-search').getElementsByTagName('input')[0];
    var searchBox = new google.maps.places.SearchBox(input);

    map.addListener('bounds_changed', function() {
        searchBox.setBounds(map.getBounds());
    });

    searchBox.addListener('places_changed', function() {
        var places = searchBox.getPlaces();
        if (places.length === 0) return;

        map.setCenter(places[0].geometry.location);
        searchNearbyBanhMi(map, places[0].geometry.location);
    });


近くのバインミーの検索

searchNearbyBanhMi関数で、指定した位置周辺でバインミーを検索。nearbySearchメソッドを使用し、半径5000メートル以内を検索。

function searchNearbyBanhMi(map, location) {
    var service = new google.maps.places.PlacesService(map);
    service.nearbySearch({
        location: location,
        radius: 5000,
        type: ['restaurant'],
        keyword: 'Banh Mi'
    }, function(results, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
            clearMarkers();
            results.forEach(function(place) {
                createMarker(place, map);
            });
        }
    });
}


Google Mapに表示されるアイコン(マーカー)をバインミーの画像にする

static/images/Banhmiicon.jpgにバインミーの画像を置く。 createMarker関数は、検索結果の場所にバインミーのマーカーを作成。情報ウィンドウも設定。情報ウィンドウには場所の名前と評価が表示。

function createMarker(place, map) {
    var icon = {
        url: 'static/images/Banhmiicon.jpg',
        scaledSize: new google.maps.Size(32, 32),
        origin: new google.maps.Point(0, 0),
        anchor: new google.maps.Point(16, 16)
    };

    var marker = new google.maps.Marker({
        position: place.geometry.location,
        map: map,
        icon: icon,
        title: place.name
    });

    var infowindow = new google.maps.InfoWindow({
        content: '<div style="font-size: 16px;"><strong>' + place.name + '</strong><br>Rating: ' + (place.rating || "Not available") + '</div>'
    });

    marker.addListener('click', function() {
        infowindow.open(map, marker);
    });
    infowindow.open(map, marker);
}


エラーハンドリング

function handleLocationError(browserHasGeolocation, map) {
var defaultPos = {lat: 35.662889, lng: 139.665778};
map.setCenter(defaultPos);
alert(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn't support geolocation.');
}

handleLocationError関数は、現在位置の取得が失敗した場合にデフォルトの位置(指定された座標)に地図を設定し、エラーメッセージを表示。


Google Maps APIのスクリプトロード

<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap"></script>

Google Maps APIを非同期で読み込み、initMap関数をコールバックとして設定。また、libraries=placesを指定することでPlacesライブラリもロード。

key=YOUR_API_KEY

GCPのAPI KEYを入れます。

現状のソース

home.html

{% extends 'banhmilove_app/base.html' %}

{% block content %}


<h1>LOVE<img src="static/images/Banhmiicon.jpg" alt="Banh Mi Icon" class="banhmi-icon">バインミー</h1>
<div class="search-area">
    <form id="location-search" class="input-group mb-3">
        <input type="text" class="form-control" placeholder="近くのバインミー" aria-label="Search for nearby Banh Mi">
        <button class="btn btn-outline-secondary" type="submit"><i class="bi bi-search-heart"></i>検索</button>
    </form>
</div>

<div id="map" style="height: 400px;"></div> 
<!-- Set a height for your map container -->

<script>
    function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 15
        });
    
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function(position) {
                var pos = {
                    lat: position.coords.latitude,
                    lng: position.coords.longitude
                };
                map.setCenter(pos);
                searchNearbyBanhMi(map, pos);
            }, function() {
                handleLocationError(true, map);
            });
        } else {
            handleLocationError(false, map);
        }
    
        var input = document.getElementById('location-search').getElementsByTagName('input')[0];
        var searchBox = new google.maps.places.SearchBox(input);
    
        map.addListener('bounds_changed', function() {
            searchBox.setBounds(map.getBounds());
        });
    
        searchBox.addListener('places_changed', function() {
            var places = searchBox.getPlaces();
            if (places.length === 0) return;
    
            map.setCenter(places[0].geometry.location);
            searchNearbyBanhMi(map, places[0].geometry.location);
        });
    }
    
    function searchNearbyBanhMi(map, location) {
        var service = new google.maps.places.PlacesService(map);
        service.nearbySearch({
            location: location,
            radius: 5000,
            type: ['restaurant'],
            keyword: 'Banh Mi'
        }, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
                clearMarkers();
                results.forEach(function(place) {
                    createMarker(place, map);
                });
            }
        });
    }
    
    function createMarker(place, map) {
        var icon = {
            url: 'static/images/Banhmiicon.jpg', // アイコンのURL
            scaledSize: new google.maps.Size(32, 32), // アイコンのサイズを設定
            origin: new google.maps.Point(0, 0),
            anchor: new google.maps.Point(16, 16)
        };
    
        var marker = new google.maps.Marker({
            position: place.geometry.location,
            map: map,
            icon: icon, // アイコンとして設定
            title: place.name
        });
    
        var infowindow = new google.maps.InfoWindow({
            content: '<div style="font-size: 16px;"><strong>' + place.name + '</strong><br>Rating: ' + (place.rating || "Not available") + '</div>'
        });
    
        marker.addListener('click', function() {
            infowindow.open(map, marker);
        });
        // デフォルトでインフォウィンドウを開く
        infowindow.open(map, marker);
    }
    
    function handleLocationError(browserHasGeolocation, map) {
        var defaultPos = {lat: 35.662889, lng: 139.665778};
        map.setCenter(defaultPos);
        alert(browserHasGeolocation ?
            'Error: The Geolocation service failed.' :
            'Error: Your browser doesn\'t support geolocation.');
    }
    
    function clearMarkers() {
        // Function to clear markers from the map
    }
    </script>

<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAbmK4hbGA--nhhpudFzbVKaNfoPp3dFdk&libraries=places&callback=initMap">
</script>
<hr>
<h3><i class="bi bi-trophy"></i>ランキング</h3>
<hr>
<h3>NEW OPEN</h3>
<hr>
<h3>#バインミー</h3>
<hr>

{% endblock %}

試行錯誤の末、表示できた

まとめ

今回は、GCPでMaps Javascript APIを設定して、home.htmlに以下を表示しました。

  • 位置情報を取得

  • 近くのバインミーを検索

  • 近くのバインミーをGoogle Mapで表示

  • バインミーアイコンを設置

  • レビューとお店の名前を表示

APIは面白い、色々やりたいな―

次回は全国のショップ情報を取得します。
おもろいな―

ここの代表をしています。


この記事が気に入ったらサポートをしてみませんか?