mBaaSお役立ちブログ

JavaScript SDKのキッチンシンクアプリを作る【位置情報の範囲検索】

キッチンシンクというのは、何かのフレームワークやライブラリがあった時に、その殆どの機能を体験できる仕組みになります。それがあることでフレームワークの全体像が分かったり、何か開発していて困った時に参考とできるコードになります。

元々MonacaとNCMBではアカウント連携機能があるのですが、NCMBからMonacaへ誘導した際にチュートリアルアプリを表示する機能は約1年ほど前になくなっています。チュートリアルアプリはデータの登録をしたり、写真を表示するアプリでした。つまりデータストアとファイルストアが体験できるというものです。アプリ自体はJavaScript SDKのver.1を使っていましたので、今となっては参考にはしづらいものでした。

この記事では旧チュートリアルアプリに変わるキッチンシンクアプリを作っていきたいと思います。ステップを踏んで紹介していきますので、実際に試す際の参考にしてください。今回は2点間における位置情報検索の実装です。

利用するフレームワーク

今回利用しているフレームワーク、ライブラリは次の通りです。

  • Onsen UI
  • Monaca CLI
  • NCMB
  • Bower

今回はOnsen UIをjQueryから使う形で進めています。ライブラリはBower経由でインストールしています。アプリのプレビュー表示を行うのに便利なのがMonaca CLIになります。インストールは Node.js をインストール後、 npm コマンドで行えます。

$ npm i monaca -g

ベースのコード

今回はNCMBMania/kitchensink-monaca: MonacaとJavaScript SDKを使ったキッチンシンクアプリです。にコードをアップロードしてあります。こちらを参考にしてください。ベースはOnsen UI V2 JS Navigationとなっています。

初期表示と地図をクリックした時のイベント

今回は2点間の検索なので、地図上のクリックした場所にマーカーを立てることにします。最初は現在位置に基づいて中心を決めます。

そしてクリックした際に、まだマーカーが0の場合、1つの場合、2つの場合で若干処理が変わります。0の場合は検索は実行しません。1または2つの場合は検索を行います。すでに2つのマーカーがあった場合は古い方のマーカーを消して、クリックされた場所をマーカーとして追加します。

// 初期の地図表示
navigator.geolocation.getCurrentPosition(
  (position) => {
    let geo = position.coords;
    map = new google.maps.Map(mapDiv, {
      center: new google.maps.LatLng(geo.latitude, geo.longitude),
      zoom: 16,
    });
    // マップをクリックした際のイベントです
    map.addListener('click', (argument) => {
      if (points.length < 2) {
        points.push({
          lat: argument.latLng.lat(),
          lng: argument.latLng.lng()
        });
      } else {
        points[0] = points[1];
        points[1] = {
          lat: argument.latLng.lat(),
          lng: argument.latLng.lng()
        }
      }
      
      // マーカーを立てます
      addMaker(points);
      
      // 2点あっったら検索します
      if (points.length == 2) {
        searchMap(points);
      }
    });
  },
  (error) => {
    
});

検索の基準となるマーカーを立てる処理はシンプルです。既存のマーカー(検索結果含め)を一度すべてリセットします。

// 2点のマーカーを立てます
let addMaker = (points) => {
  // 既存のマーカーはすべて消します
  for (let i = 0; i < markers.length; i++) {
    markers[i].setMap(null);
  }
  // マーカーを立てます
  for (let i = 0; i < points.length; i++) {
    let marker = new google.maps.Marker({
      map: map,
      position: new google.maps.LatLng(points[i].lat, points[i].lng)
    });
    markers.push(marker);
  }
}

検索処理になります。 withinSquare メソッドを使います。引数は二つの ncmb.GeoPoint になります。これで二つの位置情報に囲まれたデータが取得できます。

// 検索し、その結果にマーカーを立てます
let searchMap = (points) => {
  // 位置情報を取得
  let point = points[0];
  var geo1 = new ncmb.GeoPoint(point.lat, point.lng);
  point = points[1];
  var geo2 = new ncmb.GeoPoint(point.lat, point.lng);
  
  Station
    .withinSquare('geo', geo1, geo2)
    .fetchAll()
    .then((stations) => {
      // マーカーを立てる
      for (let i = 0; i < stations.length; i++) {
        let station = stations[i];
        let marker = new google.maps.Marker({
          map: map,
          label: '🚉',
          position: new google.maps.LatLng(
            station.geo.latitude,
            station.geo.longitude
          )
        });
        markers.push(marker);
      }
    })
    .catch((err) => {
      showDialog('検索失敗', `検索に失敗しました<br />${err}`);
    });
}

実行すると二つのマーカー間にある山手線の駅がマーカーで表示されます。少し分かりやすくするために駅の絵文字を付けています。

マーカーを離して立てれば検索結果に出る駅も増えます。


位置情報検索はとても簡単に実装できます。スマートフォンアプリでは現在位置を取得するのは簡単ですし、入力情報源として使うこともできます。コードは NCMBMania/kitchensink-monaca: MonacaとJavaScript SDKを使ったキッチンシンクアプリです。 にありますので参考にしてください。

バックナンバー