You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -42,6 +39,8 @@ Node.js with the Firebase Admin SDK:
42
39
43
40
```js
44
41
constadmin=require('firebase-admin');
42
+
admin.initializeApp();
43
+
45
44
constgeo=require('geofirex').init(admin);
46
45
```
47
46
@@ -52,25 +51,24 @@ import * as geofirex from 'geofirex';
52
51
const geo =geofirex.init(firebase);
53
52
```
54
53
55
-
### Write Geo Data
54
+
### Write Geolocation Data
56
55
57
-
Next, add some geolocation data in your database. A `collection` creates a reference to Firestore (just like the SDK), but with some extra geolocation tools. The `point` method returns a class
56
+
Next, add some geolocation data in your database using the main Firebase SDK. You can add multiple points to a single doc. Calling `geo.point(lat, lng)` creates an object with a [geohash string](https://www.movable-type.co.uk/scripts/geohash.html) and a [Firestore GeoPoint](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/GeoPoint). Data must be saved in this format to be queried.
Calling `point.data()` returns an object that contains a [geohash string](https://www.movable-type.co.uk/scripts/geohash.html) and a [Firestore GeoPoint](https://firebase.google.com/docs/reference/android/com/google/firebase/firestore/GeoPoint). It should look like this in your database. You can name the object whatever you want and even save multiple points on a single document.
Creates reference to a Firestore collection that can be used to make geo-queries and perform writes If you pass an optional Firestore query function, all subsequent geo-queries will be limited to this subset of documents
96
+
Creates reference to a Firestore collection or query that can be used to make geo-queries.
@@ -113,60 +116,46 @@ Each doc also contains returns _distance_ and _bearing_ calculated on the query
113
116
114
117
**Returns:**`Observable<object[]>`
115
118
116
-
#### Write Data
117
-
118
-
Write data just like you would in Firestore
119
-
120
-
`collection.add(data)`
121
-
122
-
Or use one of the client's conveniece methods
123
-
124
-
-`collection.setDoc(id, data)` - Set a document in the collection with an ID.
125
-
-`collection.setPoint(id, field, lat, lng)`- Add a geohash to an existing doc
126
-
127
-
#### Read Data
128
-
129
-
In addition to Geo-Queries, you can also read the collection like you would normally in Firestore, but as an Observable
130
-
131
-
-`collection.data()`- Observable of document data
132
-
-`collection.snapshot()`- Observable of Firestore QuerySnapshot
133
119
134
120
### `point(latitude: number, longitude: number)`
135
121
136
122
Returns a GeoFirePoint allowing you to create geohashes, format data, and calculate relative distance/bearing.
137
123
138
124
Example: `const point = geo.point(38, -119)`
139
125
140
-
#### Get Data
141
-
142
-
A point can return data in a variety of formats.
126
+
A point is a plain JS object with two properties.
143
127
144
-
-`point.hash()` Returns a geohash string at precision 9
145
-
-`point.geoPoint()` Returns a Firestore GeoPoint
146
-
-`point.geoJSON()` Returns data as a GeoJSON `Feature<Point>`
147
-
-`point.coords()` Returns coordinates as `[latitude, longitude]`
148
-
-`point.data()` Returns data object suitable for saving to the Firestore database
128
+
-`point.geohash` Returns a geohash string at precision 9
129
+
-`point.geopoint` Returns a Firestore GeoPoint
149
130
150
-
#### Geo Calculations
151
-
152
-
-`point.distance(latitude, longitude)` Haversine distance to a point
153
-
-`point.bearing(latitude, longitude)` Haversine bearing to a point
154
131
155
132
## :pizza: Additional Features
156
133
157
134
The goal of this package is to facilitate rapid feature development with tools like MapBox, Google Maps, and D3.js. If you have an idea for a useful feature, open an issue.
158
135
159
136
### Logging
160
137
138
+
Each query runs on a set of geohash squares, so you may read more documents than actually exist inside the radius. Use the `log` option to examine the total query size and latency.
Convenience methods for calculating distance and bearing.
149
+
150
+
-`geo.distance(to, from)` Haversine distance
151
+
-`geo.bearing(to, from)` Haversine bearing
152
+
164
153
### `toGeoJSON` Operator
165
154
166
155
A custom RxJS operator that transforms a collection into a [GeoJSON FeatureCollection](https://macwright.org/2015/03/23/geojson-second-bite.html#featurecollection). Very useful for tools like [MapBox](https://blog.mapbox.com/real-time-maps-for-live-events-fad0b334e4e) that can use GeoJSON to update a realtime data source.
167
156
168
157
```ts
169
-
const query =geo.collection('cars').within(...)
158
+
const query =geo.query('cars').within(...)
170
159
171
160
query.pipe( toGeoJSON() )
172
161
@@ -185,29 +174,32 @@ Don't need a realtime stream? Convert any query observable to a promise by wrapp
185
174
import { get } from'geofirex';
186
175
187
176
asyncfunction getCars {
188
-
const query =geo.collection('cars').within(...)
177
+
const query =geo.query('cars').within(...)
189
178
const cars =awaitget(query)
190
179
}
191
180
```
192
181
193
182
## :zap: Tips
194
183
195
-
### Scale to Massive Collections
184
+
### Compound Queries
196
185
197
-
It's possibe to build Firestore collections with billions of documents. One of the main motivations of this project was to make geoqueries possible on a queried subset of data. You can make a regular Firestore query on collection by passing a callback as the second argument, then all geoqueries will scoped these contstraints.
186
+
The only well-supported type of compound query is `where`. A geoquery combines multiple smaller queries into a unified radius, so `limit` and pagination operators will not provide predictable results - a better approach is to search a smaller radius and do your sorting client-side.
198
187
199
-
Note: This query requires a composite index, which you will be prompted to create with an error from Firestore on the first request.
Note: This query requires a composite index, which you will be prompted to create with an error from Firestore on the first request.
201
+
202
+
211
203
### Usage with RxJS < 6.2, or Ionic v3
212
204
213
205
This package requires RxJS 6.2, but you can still use it with older versions without blowing up your app by installing rxjs-compat.
@@ -218,24 +210,11 @@ Example:
218
210
npm i rxjs@latest rxjs-compat
219
211
```
220
212
221
-
### Seeing this error: `DocumentReference.set() called with invalid data`
222
-
223
-
Firestore writes cannot use custom classes, so make sure to call the `data` getter on the point.
224
-
225
-
```ts
226
-
const point =geo.point(40, -50);
227
-
// This is an ERROR
228
-
ref.add({ location: point });
229
-
230
-
// This is GOOD
231
-
ref.add({ location: point.data() });
232
-
```
233
-
234
213
### Make Dynamic Queries the RxJS Way
235
214
236
215
```ts
237
216
const radius =newBehaviorSubject(1);
238
-
const cities =geo.collection('cities');
217
+
const cities =geo.query('cities');
239
218
240
219
const points =this.radius.pipe(
241
220
switchMap(rad=> {
@@ -249,4 +228,4 @@ radius.next(23);
249
228
250
229
### Always Order by `[Latitude, Longitude]`
251
230
252
-
The GeoJSON spec formats coords as `[Longitude, Latitude]` to represent an X/Y plane. However, the Firebase GeoPoint uses `[Latitude, Longitude]`. For consistency, this libary will always require you to use the latter format.
231
+
The GeoJSON spec formats coords as `[Longitude, Latitude]` to represent an X/Y plane. However, the Firebase GeoPoint uses `[Latitude, Longitude]`. For consistency, this library always requires to use the latter Firebase-style format.
0 commit comments