Skip to content

Commit

Permalink
Polishing Geo-API #86
Browse files Browse the repository at this point in the history
- Use GeoWithin type for georadius
- Use GeoEncoded type for geoencode/geodecode
- Rename GeoTuple to GeoCoordinates to reflect the purpose
- API documentation
- Test against redis unstable branch

Motivation: The interface containing List of Objects or List of Lists of Objects makes it hard to use the Geo API, especially when the coordinates are provided as strings. GeoWithin and GeoEncoded reflect the data structures returned by Redis and allow operations in a convenient way.
  • Loading branch information
mp911de committed Jul 1, 2015
1 parent dd9c473 commit dcf8e91
Show file tree
Hide file tree
Showing 15 changed files with 674 additions and 284 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,8 @@ endif
endif

endif
[ ! -e work/redis-git ] && git clone https://github.com/antirez/redis.git --branch geo --single-branch work/redis-git && cd work/redis-git|| true
[ -e work/redis-git ] && cd work/redis-git && git reset --hard && git pull && git checkout geo || true
[ ! -e work/redis-git ] && git clone https://github.com/antirez/redis.git --branch unstable --single-branch work/redis-git && cd work/redis-git|| true
[ -e work/redis-git ] && cd work/redis-git && git reset --hard && git pull && git checkout unstable || true
make -C work/redis-git clean
make -C work/redis-git -j4

Expand Down
74 changes: 69 additions & 5 deletions src/main/java/com/lambdaworks/redis/GeoArgs.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.lambdaworks.redis;

import static com.google.common.base.Preconditions.checkArgument;

import com.lambdaworks.redis.protocol.CommandArgs;
import com.lambdaworks.redis.protocol.CommandKeyword;

Expand All @@ -16,30 +18,76 @@ public class GeoArgs {
private Long count;
private Sort sort = Sort.none;

/**
* Request distance for results.
*
* @return {@code this}
*/
public GeoArgs withDistance() {
withdistance = true;
return this;
}

/**
* Request coordinates for results.
*
* @return {@code this}
*/
public GeoArgs withCoordinates() {
withcoordinates = true;
return this;
}

/**
* Request geohash for results.
*
* @return {@code this}
*/
public GeoArgs withHash() {
withhash = true;
return this;
}

/**
* Limit results to {@code count} entries.
*
* @param count number greater 0
* @return {@code this}
*/
public GeoArgs withCount(long count) {
checkArgument(count > 0, "count must be greater 0");
this.count = count;
return this;
}

/**
*
* @return {@literal true} if distance is requested.
*/
public boolean isWithDistance() {
return withdistance;
}

/**
*
* @return {@literal true} if coordinates are requested.
*/
public boolean isWithCoordinates() {
return withcoordinates;
}

/**
*
* @return {@literal true} if geohash is requested.
*/
public boolean isWithHash() {
return withhash;
}

/**
* Sort results ascending.
*
* @return the current geo args.
* @return {@code this}
*/
public GeoArgs asc() {
return sort(Sort.asc);
Expand All @@ -48,7 +96,7 @@ public GeoArgs asc() {
/**
* Sort results descending.
*
* @return the current geo args.
* @return {@code this}
*/
public GeoArgs desc() {
return sort(Sort.desc);
Expand All @@ -57,10 +105,12 @@ public GeoArgs desc() {
/**
* Sort results.
*
* @param sort
* @return the current geo args.
* @param sort sort order, must not be {@literal null}
* @return {@code this}
*/
public GeoArgs sort(Sort sort) {
checkArgument(sort != null, "sort must not be null");

this.sort = sort;
return this;
}
Expand All @@ -69,7 +119,20 @@ public GeoArgs sort(Sort sort) {
* Sort order.
*/
public enum Sort {
asc, desc, none;
/**
* ascending.
*/
asc,

/**
* descending.
*/
desc,

/**
* no sort order.
*/
none;
}

/**
Expand All @@ -95,6 +158,7 @@ public enum Unit {
mi;
}


public <K, V> void build(CommandArgs<K, V> args) {
if (withdistance) {
args.add("withdist");
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/lambdaworks/redis/GeoCoordinates.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.lambdaworks.redis;

/**
* A tuple consisting of numerical geo data points to describe geo coordinates.
*
* @author <a href="mailto:[email protected]">Mark Paluch</a>
*/
public class GeoCoordinates {

public final Number x;
public final Number y;

public GeoCoordinates(Number x, Number y) {

this.x = x;
this.y = y;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof GeoCoordinates))
return false;

GeoCoordinates geoCoords = (GeoCoordinates) o;

if (x != null ? !x.equals(geoCoords.x) : geoCoords.x != null)
return false;
return !(y != null ? !y.equals(geoCoords.y) : geoCoords.y != null);
}

@Override
public int hashCode() {
int result = x != null ? x.hashCode() : 0;
result = 31 * result + (y != null ? y.hashCode() : 0);
return result;
}

@Override
public String toString() {
return String.format("(%f, %f)", x, y);
}

}
67 changes: 67 additions & 0 deletions src/main/java/com/lambdaworks/redis/GeoEncoded.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.lambdaworks.redis;

/**
* Geo-encoded object. Contains:
*
* <ul>
* <li>the 52-bit geohash integer for your longitude/latitude</li>
* <li>the minimum corner of your geohash {@link GeoCoordinates}</li>
* <li>the maximum corner of your geohash {@link GeoCoordinates}</li>
* <li>4: The averaged center of your geohash {@link GeoCoordinates}</li>
* </ul>
*
* @author <a href="mailto:[email protected]">Mark Paluch</a>
*/
public class GeoEncoded {

public final long geohash;
public final GeoCoordinates min;
public final GeoCoordinates max;
public final GeoCoordinates avg;

public GeoEncoded(long geohash, GeoCoordinates min, GeoCoordinates max, GeoCoordinates avg) {
this.geohash = geohash;
this.min = min;
this.max = max;
this.avg = avg;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof GeoEncoded))
return false;

GeoEncoded that = (GeoEncoded) o;

if (geohash != that.geohash)
return false;
if (min != null ? !min.equals(that.min) : that.min != null)
return false;
if (max != null ? !max.equals(that.max) : that.max != null)
return false;
return !(avg != null ? !avg.equals(that.avg) : that.avg != null);
}

@Override
public int hashCode() {
int result = (int) (geohash ^ (geohash >>> 32));
result = 31 * result + (min != null ? min.hashCode() : 0);
result = 31 * result + (max != null ? max.hashCode() : 0);
result = 31 * result + (avg != null ? avg.hashCode() : 0);
return result;
}

@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [geohash=").append(geohash);
sb.append(", min=").append(min);
sb.append(", max=").append(max);
sb.append(", avg=").append(avg);
sb.append(']');
return sb.toString();
}
}
31 changes: 0 additions & 31 deletions src/main/java/com/lambdaworks/redis/GeoTuple.java

This file was deleted.

67 changes: 67 additions & 0 deletions src/main/java/com/lambdaworks/redis/GeoWithin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.lambdaworks.redis;

/**
* Geo element within a certain radius. Contains:
* <ul>
* <li>the member</li>
* <li>the distance from the reference point (if requested)</li>
* <li>the geohash (if requested)</li>
* <li>the coordinates (if requested)</li>
* </ul>
*
* @param <V> Value type.
* @author <a href="mailto:[email protected]">Mark Paluch</a>
*/
public class GeoWithin<V> {

public final V member;
public final Double distance;
public final Long geohash;
public final GeoCoordinates coordinates;

public GeoWithin(V member, Double distance, Long geohash, GeoCoordinates coordinates) {
this.member = member;
this.distance = distance;
this.geohash = geohash;
this.coordinates = coordinates;
}

@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (!(o instanceof GeoWithin))
return false;

GeoWithin<?> geoWithin = (GeoWithin<?>) o;

if (member != null ? !member.equals(geoWithin.member) : geoWithin.member != null)
return false;
if (distance != null ? !distance.equals(geoWithin.distance) : geoWithin.distance != null)
return false;
if (geohash != null ? !geohash.equals(geoWithin.geohash) : geoWithin.geohash != null)
return false;
return !(coordinates != null ? !coordinates.equals(geoWithin.coordinates) : geoWithin.coordinates != null);
}

@Override
public int hashCode() {
int result = member != null ? member.hashCode() : 0;
result = 31 * result + (distance != null ? distance.hashCode() : 0);
result = 31 * result + (geohash != null ? geohash.hashCode() : 0);
result = 31 * result + (coordinates != null ? coordinates.hashCode() : 0);
return result;
}

@Override
public String toString() {
final StringBuffer sb = new StringBuffer();
sb.append(getClass().getSimpleName());
sb.append(" [member=").append(member);
sb.append(", distance=").append(distance);
sb.append(", geohash=").append(geohash);
sb.append(", coordinates=").append(coordinates);
sb.append(']');
return sb.toString();
}
}
Loading

0 comments on commit dcf8e91

Please sign in to comment.