Featured image of post GeoFireXを使ってCloud Firestoreで位置情報の検索を行う

GeoFireXを使ってCloud Firestoreで位置情報の検索を行う

Twitter ツイート Hatena Bookmark ブックマーク

Cloud Firestore便利ですよね。
Cloud Firestoreで「半径〇km以内にあるスポットを検索する」みたいな実装をしたかったのでGeoFireXを使って実装してみました。

https://github.com/codediodeio/geofirex

Cloud Firestoreでの緯度経度の情報の取扱について

Cloud FirestoreにはGeoPoint型あって、緯度経度の情報はGeoPoint型として保存する必要があります。

1
2
3
4
5
6
import firebase from 'firebase'

const spot = {
    name: 'spot1',
    location: new firebase.firestore.GeoPoint(latitude, longitude)
}

geohashの設定について

GeoFireXを利用する場合は位置情報のデータだけじゃだめでGeohashも用意する必要があります。
https://ja.wikipedia.org/wiki/%E3%82%B8%E3%82%AA%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5

僕の場合はngeohashを使ってhashを生成しました。

1
2
3
4
5
6
7
8
const geohash = require('ngeohash');

const spot = {
    "name": "Spot A",
    "location": {
      geohash: geohash.encode(latitude, longitude)
      geopoint: new firebase.firestore.GeoPoint(latitude, longitude)
}

このようにGeoPoint,Geohashの両方を用意しないとGeoFireXを使って検索しても結果が取得出来ません。

GeoFireXを利用して検索を行う

半径〇キロ以内の検索にはGeoFireXを利用しました。

以下のサンプルコードを見てもらえればわかりますが、簡単に「半径〇km以内にあるスポットを検索する」みたいな実装ができます。

例: 半径100km以内のスポットを検索する。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Init Firebase
import firebase from 'firebase';
const firestore = firebase.firestore({
  timestampsInSnapshots: true
})

// Init GeoFireX
import * as geofirex from 'geofirex';
const geo = geofirex.init(firestore);


const spot = geo.collection('spot')

const now = {
  lat: 40.1
  lng: -119.1
}

const center = geo.point(now.lat, now.lng);
const radius = 100; // 100km
const field = 'location';

const query = spot.within(center, radius, field);
query.subscribe((spots) => {
  console.log(spots)
})

検索時に取得条件、ソート、取得数などを設定する

collectionを取得する段階でwhere,orderBy,limitなどの指定ができます。

1
  const spot = geo.collection('spot', ref => ref.where("star", ">", 3).limit(4))

最後に

GeoFireXを使えばFirestoreでの緯度経度の検索は簡単に実装できるのでますね。
そこまでハマることも無いのでおすすめです。
ちなみに同じようなライブラリでgeofirestore-jsもありますが、GeoFireXのほうが簡単に実装できる印象があります。
ただ、リアルタイムに位置情報が変わっていくのを反映したい場合にはgeofirestore-jsのほうが良さそうです。

comments powered by Disqus
Built with Hugo
テーマ StackJimmy によって設計されています。