VPSサーバーでWebサイト公開 備忘録 ~Linux、MySQLからAJAXまで

AngularJSを使ってGoogleマップ(25)プレイスライブラリで店や施設を表示(4)オートコンプリート

プレイスライブラリの検索結果に対し、より詳細な情報を取得しマーカーウィンドウに表示するサンプルコードを作成しました。

(1)サンプルコード


 
デモ表示へ
 

(2)サンプルコードの内容


 
1)全体
 
①placesライブラリを使用する
 
var mapApp = angular.module('googleMapApp', ['uiGmapgoogle-maps']);

mapApp.config(
    ['uiGmapGoogleMapApiProvider', function(GoogleMapApiProviders) {
        GoogleMapApiProviders.configure({
          key: 'your Google Map api key',
          v: '3', //defaults to latest 3.X anyhow
          libraries: 'weather,geometry,visualization,places'
        });
    }]
);

 
②テキスト入力ボックスを作成
 
(HTML)
<input id=”pac-input” type=”text” class=”form-control” placeholder=”Enter a location”>
 
(スクリプト)
図の左上部に表示します。
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
 
③Autocompleteインスタンス生成
 
var input = document.getElementById(‘pac-input’);
var autocomplete = new google.maps.places.Autocomplete(input);
 
④オートコンプリートのユーザ入力変化をリッスンするイベントリスナー定義

google.maps.event.addListener(autocomplete, 'place_changed', function() {
 :

※place_changedイベント
・ユーザーがプレイスを選択してPlaceResultが利用できる状態になると発行
 
・コントロールによって推測されていなかった場所を新たに入力した場合や詳細なリクエストが失敗した場合、name属性にユーザー入力値が含まれる形でイベントが発行される。
 
※上記イベント内の処理内容
 
1.getPlace()でユーザー入力に応じて取得された結果(PlaceResultオブジェクト)を取得
var place = autocomplete.getPlace();
 
2.取得したPlaceResultオブジェクトの属性に応じて処理実行
 
位置、ビューポート、名前、住所などの情報を取得し、地図の中心の設定、Boundsの設定、ズームアップを行う。

if (!place.geometry) {
  return;
}

if (place.geometry.viewport) {
  map.fitBounds(place.geometry.viewport);
} else {
  map.setCenter(place.geometry.location);
  map.setZoom(17);.
}

 
2)マーカー表示
 
①HTMLにui-gmap-markerディレクティブ追加
 

<ui-gmap-marker idKey="map.marker.id" 
                   coords="map.marker"
                   icon="map.marker.icon"  
                   options="map.marker.options">

 
②スクリプトにマーカーの定義追加

google.maps.event.addListener(autocomplete, 'place_changed', function() {
  var place = autocomplete.getPlace();
  :
  $scope.map.marker.latitude = place.geometry.location.lat();
  $scope.map.marker.longitude = place.geometry.location.lng();
  $scope.map.marker.icon = place.icon;
});

※マップマーカーアイコンの属性設定について
angular-google-mapsのmarkerディレクティブのicon属性にはURLしか設定できません。その他のアイコンの設定を行おうとマーカーオプションを使って下記のように設定してみましたがうまくいきませんでした。
 
$scope.map.marker.options.iocn.url = place.icon;
$scope.map.marker.options.iocn.size = new google.maps.Size(71, 71);
$scope.map.marker.options.iocn.origin =new google.maps.Point(0, 0);
$scope.map.marker.options.iocn.anchor = new google.maps.Point(17, 34);
$scope.map.marker.options.iocn.scaledSize = new google.maps.Size(35, 35);
 
3)情報ウィンドウを表示
 
①HTMLのui-gmap-markerディレクティブ内にui-gmap-windowディレクティブを追加

<ui-gmap-marker idKey="map.marker.id"
                   coords="map.marker"
                   icon="map.marker.icon"  
                   options="map.marker.options">
  <ui-gmap-window show="map.marker.showWindow"
                     options="map.window.options"
                     templateUrl="map.window.templateUrl"
                     templateParameter="map.window.templateParameter">
  </ui-gmap-window>
</ui-gmap-marker>

 
②情報ウィンドウのテンプレートファイルを作成
 
オートコンプリートをクリックして取得したplaceの名前と住所を情報ウィンドウに設定して表示します。
 
(assets/templates/place4.html)

<div>
  <strong>{{ parameter.name }}</strong><br />
  {{ parameter.address }}
</div>

 
③スクリプト内で情報ウィンドウの表示内容を定義
 
ウィンドウのオプションpixelOffsetで情報ウィンドウの表示する位置を設定します。マーカーと重ならないようにオフセットを設定しています。
 
オートコンプリートで取得したplace(PlaceResultオプジェクト)から名前と住所を取得して情報ウィンドウで表示するパラメータに設定します。

window: {
  showWindow: '',
  templateUrl: 'assets/templates/place4.html',
  templateParameter: {
    name: '',
    address: ''
  },
  options: {
    pixelOffset: {
      height: -50,
      width: 20
    }
  }
},

$scope.map.window.showWindow = true;
var address = '';
if (place.address_components) {
  address = [
   (place.address_components[0] && place.address_components[0].short_name || ''),
   (place.address_components[1] && place.address_components[1].short_name || ''),
   (place.address_components[2] && place.address_components[2].short_name || '')
  ].join(' ');
}
$scope.map.window.templateParameter.name = place.name;
$scope.map.window.templateParameter.address = address;

 
4)オートコンプリートのタイプを選択
 
①HTMLにラジオボタン追加
 
・マップ上に表示するように設定する際に識別するIDとして”type-selector”を指定
 
・3つのラジオボタンを横に並べるためにブートストラップ3の”form-inline”クラスを使用。

<div id="type-selector" class="well well-sm">
  <form class="form-inline">
    <div class="radio">
      <label>
        <input type="radio" name="type" id="changetype-all" checked>
        All
      </label>
    </div>
    <div class="radio">
      <label>
        <input type="radio" name="type" id="changetype-establishment">
        Establishments
      </label>
    </div>
    <div class="radio">
      <label>
        <input type="radio" name="type" id="changetype-geocode">
        Geocodes
      </label>
    </div>
  </form>
</div>

 
②スクリプトでラジオボタンをマップ上に表示するように設定
 
var types = document.getElementById(‘type-selector’);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);
 
③ユーザーがラジオボタンで選択したタイプをAutocompleteのsetTypesメソッドで設定
 
ここで”geocode”を選択すると住所の結果のみ返し、”establishment”を指定するとお店やサービスの結果のみ返します。

var setupClickListener = function (id, types) {
  var radioButton = document.getElementById(id);
  google.maps.event.addDomListener(radioButton, 'click', function() {
    autocomplete.setTypes(types);
  });
}
setupClickListener('changetype-all', []);
setupClickListener('changetype-establishment', ['establishment']);
setupClickListener('changetype-geocode', ['geocode']);

 
5)プレイス検索でオートコンプリートで検索範囲を指定
 
Autocompleteのコンストラクタにはオプションを引数として指定でき、”bounds”属性でプレイスを検索する範囲を指定できます。

検索結果はこの領域内のプレイスが優先されたものとなるようですが、この領域内に限定されるわけではないようです。
 

  var defaultBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(35.690903370337175, 139.74145889282227),
    new google.maps.LatLng(35.67166118960477, 139.780855178833));
  var options = {
    bounds: defaultBounds,
    types: ['establishment']
  };
  var autocomplete = new google.maps.places.Autocomplete(input,options);

 
AngularJS、Googleマップの他の記事の目次

モバイルバージョンを終了