Skip to content

Add Type Polygon to Schema and PolygonContains to query #696

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 2 commits into from
Aug 15, 2017
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
26 changes: 26 additions & 0 deletions Parse/src/main/java/com/parse/OfflineQueryLogic.java
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,12 @@ private static boolean matchesEqualConstraint(Object constraint, Object value) {
&& lhs.getLongitude() == rhs.getLongitude();
}

if (constraint instanceof ParsePolygon && value instanceof ParsePolygon) {
ParsePolygon lhs = (ParsePolygon) constraint;
ParsePolygon rhs = (ParsePolygon) value;
return lhs.equals(rhs);
}

return compare(constraint, value, new Decider() {
@Override
public boolean decide(Object constraint, Object value) {
Expand Down Expand Up @@ -457,6 +463,23 @@ private static boolean matchesWithinConstraint(Object constraint, Object value)
&& target.getLongitude() <= northeast.getLongitude());
}

/**
* Matches $geoIntersects constraints.
*/
private static boolean matchesGeoIntersectsConstraint(Object constraint, Object value)
throws ParseException {
if (value == null || value == JSONObject.NULL) {
return false;
}

@SuppressWarnings("unchecked")
HashMap<String, ParseGeoPoint> constraintMap =
(HashMap<String, ParseGeoPoint>) constraint;
ParseGeoPoint point = constraintMap.get("$point");
ParsePolygon target = (ParsePolygon) value;
return target.containsPoint(point);
}

/**
* Returns true iff the given value matches the given operator and constraint.
*
Expand Down Expand Up @@ -512,6 +535,9 @@ private static boolean matchesStatelessConstraint(String operator, Object constr
case "$within":
return matchesWithinConstraint(constraint, value);

case "$geoIntersects":
return matchesGeoIntersectsConstraint(constraint, value);

default:
throw new UnsupportedOperationException(String.format(
"The offline store does not yet support the %s operator.", operator));
Expand Down
24 changes: 19 additions & 5 deletions Parse/src/main/java/com/parse/ParseDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,24 +57,24 @@ protected ParseDecoder() {
}
return outputMap;
}

/**
* Gets the <code>ParseObject</code> another object points to. By default a new
* object will be created.
*/
protected ParseObject decodePointer(String className, String objectId) {
return ParseObject.createWithoutData(className, objectId);
return ParseObject.createWithoutData(className, objectId);
}

public Object decode(Object object) {
if (object instanceof JSONArray) {
return convertJSONArrayToList((JSONArray) object);
}

if (!(object instanceof JSONObject)) {
return object;
}

JSONObject jsonObject = (JSONObject) object;

String opString = jsonObject.optString("__op", null);
Expand Down Expand Up @@ -121,6 +121,20 @@ public Object decode(Object object) {
return new ParseGeoPoint(latitude, longitude);
}

if (typeString.equals("Polygon")) {
List<ParseGeoPoint> coordinates = new ArrayList<ParseGeoPoint>();
try {
JSONArray array = jsonObject.getJSONArray("coordinates");
for (int i = 0; i < array.length(); ++i) {
JSONArray point = array.getJSONArray(i);
coordinates.add(new ParseGeoPoint(point.getDouble(0), point.getDouble(1)));
}
} catch (JSONException e) {
throw new RuntimeException(e);
}
return new ParsePolygon(coordinates);
}

if (typeString.equals("Object")) {
return ParseObject.fromJSON(jsonObject, null, this);
}
Expand All @@ -132,7 +146,7 @@ public Object decode(Object object) {
if (typeString.equals("OfflineObject")) {
throw new RuntimeException("An unexpected offline pointer was encountered.");
}

return null;
}
}
9 changes: 9 additions & 0 deletions Parse/src/main/java/com/parse/ParseEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
|| value instanceof ParseACL
|| value instanceof ParseFile
|| value instanceof ParseGeoPoint
|| value instanceof ParsePolygon
|| value instanceof ParseRelation;
}

Expand Down Expand Up @@ -84,6 +85,14 @@ public Object encode(Object object) {
return json;
}

if (object instanceof ParsePolygon) {
ParsePolygon polygon = (ParsePolygon) object;
JSONObject json = new JSONObject();
json.put("__type", "Polygon");
json.put("coordinates", polygon.coordinatesToJSONArray());
return json;
}

if (object instanceof ParseACL) {
ParseACL acl = (ParseACL) object;
return acl.toJSONObject(this);
Expand Down
26 changes: 19 additions & 7 deletions Parse/src/main/java/com/parse/ParseGeoPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public ParseGeoPoint() {

/**
* Creates a new point with the specified latitude and longitude.
*
*
* @param latitude
* The point's latitude.
* @param longitude
Expand Down Expand Up @@ -96,7 +96,7 @@ protected ParseGeoPoint(Parcel source) {

/**
* Set latitude. Valid range is (-90.0, 90.0). Extremes should not be used.
*
*
* @param latitude
* The point's latitude.
*/
Expand All @@ -116,7 +116,7 @@ public double getLatitude() {

/**
* Set longitude. Valid range is (-180.0, 180.0). Extremes should not be used.
*
*
* @param longitude
* The point's longitude.
*/
Expand All @@ -137,7 +137,7 @@ public double getLongitude() {
/**
* Get distance in radians between this point and another {@code ParseGeoPoint}. This is the
* smallest angular distance between the two points.
*
*
* @param point
* {@code ParseGeoPoint} describing the other point being measured against.
*/
Expand All @@ -162,7 +162,7 @@ public double distanceInRadiansTo(ParseGeoPoint point) {

/**
* Get distance between this point and another {@code ParseGeoPoint} in kilometers.
*
*
* @param point
* {@code ParseGeoPoint} describing the other point being measured against.
*/
Expand All @@ -172,7 +172,7 @@ public double distanceInKilometersTo(ParseGeoPoint point) {

/**
* Get distance between this point and another {@code ParseGeoPoint} in kilometers.
*
*
* @param point
* {@code ParseGeoPoint} describing the other point being measured against.
*/
Expand Down Expand Up @@ -274,7 +274,7 @@ public ParseGeoPoint then(Task<Location> task) throws Exception {
* times for a fix.
* * For better battery efficiency and faster location fixes, you can set
* {@link Criteria#setPowerRequirement(int)}, however, this will result in lower accuracy.
*
*
* @param timeout
* The number of milliseconds to allow before timing out.
* @param criteria
Expand All @@ -290,6 +290,18 @@ public static void getCurrentLocationInBackground(long timeout, Criteria criteri
ParseTaskUtils.callbackOnMainThreadAsync(getCurrentLocationInBackground(timeout, criteria), callback);
}

@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof ParseGeoPoint)) {
return false;
}
if (obj == this) {
return true;
}
return ((ParseGeoPoint) obj).getLatitude() == latitude &&
((ParseGeoPoint) obj).getLongitude() == longitude;
}

@Override
public String toString() {
return String.format(Locale.US, "ParseGeoPoint[%.6f,%.6f]", latitude, longitude);
Expand Down
18 changes: 18 additions & 0 deletions Parse/src/main/java/com/parse/ParseObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -3457,6 +3457,24 @@ public ParseGeoPoint getParseGeoPoint(String key) {
}
}

/**
* Access a {@link ParsePolygon} value.
*
* @param key
* The key to access the value for
* @return {@code null} if there is no such key or if it is not a {@link ParsePolygon}.
*/
public ParsePolygon getParsePolygon(String key) {
synchronized (mutex) {
checkGetAccess(key);
Object value = estimatedData.get(key);
if (!(value instanceof ParsePolygon)) {
return null;
}
return (ParsePolygon) value;
}
}

/**
* Access the {@link ParseACL} governing this object.
*/
Expand Down
3 changes: 3 additions & 0 deletions Parse/src/main/java/com/parse/ParseParcelDecoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public Object decode(Parcel source) {
case ParseParcelEncoder.TYPE_GEOPOINT:
return new ParseGeoPoint(source, this);

case ParseParcelEncoder.TYPE_POLYGON:
return new ParsePolygon(source, this);

case ParseParcelEncoder.TYPE_ACL:
return new ParseACL(source, this);

Expand Down
5 changes: 5 additions & 0 deletions Parse/src/main/java/com/parse/ParseParcelEncoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ private static boolean isValidType(Object value) {
/* package */ final static String TYPE_OP = "Operation";
/* package */ final static String TYPE_FILE = "File";
/* package */ final static String TYPE_GEOPOINT = "GeoPoint";
/* package */ final static String TYPE_POLYGON = "Polygon";

public void encode(Object object, Parcel dest) {
try {
Expand Down Expand Up @@ -84,6 +85,10 @@ public void encode(Object object, Parcel dest) {
dest.writeString(TYPE_GEOPOINT);
((ParseGeoPoint) object).writeToParcel(dest, this);

} else if (object instanceof ParsePolygon) {
dest.writeString(TYPE_POLYGON);
((ParsePolygon) object).writeToParcel(dest, this);

} else if (object instanceof ParseACL) {
dest.writeString(TYPE_ACL);
((ParseACL) object).writeToParcel(dest, this);
Expand Down
Loading