Skip to content

Add Android Polygon and Full Text #499

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 92 additions & 2 deletions _includes/android/geopoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@ This point is then stored in the object as a regular field.
placeObject.put("location", point);
```

To retrieve a `ParseGeoPoint` from an object.

```java
placeObject.getParseGeoPoint("location");
```

## ParsePolygon

Parse allows you to associate polygon coordinates with an object. Adding a `ParsePolygon` to a `ParseObject` allows queries to determine whether a `ParseGeoPoint` is within a `ParsePolygon` or if a `ParsePolygon` contains a `ParseGeoPoint` .

* `ParsePolygon` must contain at least three coordinates.

For example, to create a polygon with coordinates (0, 0), (0, 1), (1, 1), (1, 0).

```java
List<ParseGeoPoint> points = new ArrayList<ParseGeoPoint>();
points.add(new ParseGeoPoint(0,0));
points.add(new ParseGeoPoint(0,1));
points.add(new ParseGeoPoint(1,1));
points.add(new ParseGeoPoint(1,0));

ParsePolygon polygon = new ParsePolygon(points);
```

This point is then stored in the object as a regular field.

```java
placeObject.put("bounds", polygon);
```

To retrieve a `ParsePolygon` from an object.

```java
placeObject.getParsePolygon("bounds");
```

## Geo Queries

Now that you have a bunch of objects with spatial coordinates, it would be nice to find out which objects are closest to a point. This can be done by adding another restriction to `ParseQuery` using `whereNear`. Getting a list of ten places that are closest to a user may look something like:
Expand All @@ -42,9 +78,46 @@ query.whereWithinGeoBox("location", southwestOfSF, northeastOfSF);
query.findInBackground(new FindCallback<ParseObject>() { ... });
```

You can query for whether an object lies within or on a polygon of `Parse.GeoPoint`.

```java
ParseGeoPoint point = new ParseGeoPoint(0.5, 0.5);
ParseQuery<ParseObject> query = ParseQuery.getQuery("PlaceObject");
query.wherePolygonContains("location", point);
```

You can also query for whether an object `Parse.Polygon` contains a `Parse.GeoPoint`.

```java
ParseGeoPoint point = new ParseGeoPoint(0.5, 0.5);
ParseQuery<ParseObject> query = ParseQuery.getQuery("PlaceObject");
query.wherePolygonContains("location", point);
```

To efficiently find if a `ParsePolygon` contains a `ParseGeoPoint` without querying use `containsPoint`.

```java
List<ParseGeoPoint> points = new ArrayList<ParseGeoPoint>();
points.add(new ParseGeoPoint(0, 0));
points.add(new ParseGeoPoint(0, 1));
points.add(new ParseGeoPoint(1, 1));
points.add(new ParseGeoPoint(1, 0));

ParseGeoPoint inside = new ParseGeoPoint(0.5, 0.5);
ParseGeoPoint outside = new ParseGeoPoint(10, 10);

ParsePolygon polygon = new ParsePolygon(points);

// Returns True
polygon.containsPoint(inside);

// Returns False
polygon.containsPoint(outside);
```

## Parcelable

As most public facing components of the SDK, `ParseGeoPoint` implements the `Parcelable` interface. This means you can retain a `ParseGeoPoint` during configuration changes, or pass it to other components of the app through `Bundles`. To achieve this, depending on the context, use either `Parcel#writeParcelable(Parcelable, int)` or `Bundle#putParcelable(String, Parcelable)`. For instance, in an Activity,
As most public facing components of the SDK, `ParseGeoPoint` and `ParsePolygon` implements the `Parcelable` interface. This means you can retain a `ParseGeoPoint` and `ParsePolygon` during configuration changes, or pass it to other components of the app through `Bundles`. To achieve this, depending on the context, use either `Parcel#writeParcelable(Parcelable, int)` or `Bundle#putParcelable(String, Parcelable)`. For instance, in an Activity,

```java
private ParseGeoPoint point;
Expand All @@ -54,7 +127,7 @@ protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("point", point);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
Expand All @@ -63,6 +136,23 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
}
```

```java
private ParsePolygon polygon;

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("polygon", polygon);
}

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
polygon = (ParsePolygon) savedInstanceState.getParcelable("polygon");
}
}
```

## Caveats

At the moment there are a couple of things to watch out for:
Expand Down
31 changes: 30 additions & 1 deletion _includes/android/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,35 @@ The above example will match any `BarbecueSauce` objects where the value in the

Queries that have regular expression constraints are very expensive. Refer to the [Performance Guide](#regular-expressions) for more details.

### Full Text Search

You can use `whereFullText` for efficient search capabilities. Text indexes are automatically created for you. Your strings are turned into tokens for fast searching.

* Note: Full Text Search can be resource intensive. Ensure the cost of using indexes is worth the benefit, see [storage requirements & performance costs of text indexes.](https://docs.mongodb.com/manual/core/index-text/#storage-requirements-and-performance-costs).

* Requires Parse Server 2.5.0+

```java
// Finds barbecue sauces that start with 'Big Daddy's'.
ParseQuery<ParseObject> query = ParseQuery.getQuery("BarbecueSauce");
query.whereFullText("name", "Big Daddy's");
```

The above example will match any `BarbecueSauce` objects where the value in the "name" String key contains "bbq". For example, both "Big Daddy's BBQ", "Big Daddy's bbq" and "Big BBQ Daddy" will match.

```java
// You can sort by weight / rank. orderByAscending() and selectKeys()
ParseQuery<ParseObject> query = ParseQuery.getQuery("BarbecueSauce");
query.whereFullText("name", "Big Daddy's");
query.orderByAscending("$score");
query.selectKeys(Arrays.asList("$score"));
// results will contain $score, results[0].getInt("$score");
List<ParseObject> results = query.find();
```


For Case or Diacritic Sensitive search, please use the [REST API](http://docs.parseplatform.org/rest/guide/#queries-on-string-values).


## Relational Queries

Expand Down Expand Up @@ -365,7 +394,7 @@ final ParseQuery query = ...
query.fromLocalDatastore().findInBackground().continueWithTask((task) -> {
Exception error = task.getError();
if (error instanceof ParseException && ((ParseException) error).getCode() == ParseException.CACHE_MISS) {
// No results from cache. Let's query the network.
// No results from cache. Let's query the network.
return query.fromNetwork().findInBackground();
}
return task;
Expand Down
6 changes: 3 additions & 3 deletions _includes/rest/queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -1020,7 +1020,7 @@ curl -X GET \
-H "X-Parse-Master-Key: ${MASTER_KEY}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'group:{objectId:null,total:{$sum:'$score'}}' \
--data-urlencode 'group:{"objectId":null,"total":{"$sum":"$score"}}' \
<span class="custom-parse-server-protocol">https</span>://<span class="custom-parse-server-url">YOUR.PARSE-SERVER.HERE</span><span class="custom-parse-server-mount">/parse/</span>aggregate/Player
</code></pre>
<pre><code class="python">
Expand Down Expand Up @@ -1050,7 +1050,7 @@ curl -X GET \
-H "X-Parse-Master-Key: ${MASTER_KEY}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'project:{score:1}' \
--data-urlencode 'project={"score":1}' \
<span class="custom-parse-server-protocol">https</span>://<span class="custom-parse-server-url">YOUR.PARSE-SERVER.HERE</span><span class="custom-parse-server-mount">/parse/</span>aggregate/Player
</code></pre>
<pre><code class="python">
Expand All @@ -1077,7 +1077,7 @@ curl -X GET \
-H "X-Parse-Master-Key: ${MASTER_KEY}" \
-H "X-Parse-REST-API-Key: ${REST_API_KEY}" \
-G \
--data-urlencode 'match:{score:{$gt:15}}' \
--data-urlencode 'match={"score":{"$gt":15}}' \
<span class="custom-parse-server-protocol">https</span>://<span class="custom-parse-server-url">YOUR.PARSE-SERVER.HERE</span><span class="custom-parse-server-mount">/parse/</span>aggregate/Player
</code></pre>
<pre><code class="python">
Expand Down