Move geo shapes to domain specific package.
Original Pull Request: #2113
This commit is contained in:
@@ -53,6 +53,9 @@ import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.data.redis.core.types.RedisClientInfo;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference.GeoMemberReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -2122,9 +2125,9 @@ public class DefaultStringRedisConnection implements StringRedisConnection, Deco
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private GeoReference<byte[]> serialize(GeoReference<String> data) {
|
||||
return data instanceof GeoReference.GeoSearchMemberReference
|
||||
return data instanceof GeoReference.GeoMemberReference
|
||||
? GeoReference
|
||||
.fromMember(serializer.serialize(((GeoReference.GeoSearchMemberReference<String>) data).getMember()))
|
||||
.fromMember(serializer.serialize(((GeoMemberReference<String>) data).getMember()))
|
||||
: (GeoReference) data;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,6 +44,8 @@ import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.data.redis.core.types.RedisClientInfo;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,8 @@ package org.springframework.data.redis.connection;
|
||||
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.*;
|
||||
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.data.domain.Sort.Direction;
|
||||
import org.springframework.data.geo.Circle;
|
||||
@@ -28,10 +29,10 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Geo-specific Redis commands.
|
||||
@@ -251,139 +252,84 @@ public interface RedisGeoCommands {
|
||||
GeoSearchStoreCommandArgs args);
|
||||
|
||||
/**
|
||||
* Search predicate for {@code GEOSEARCH} and {@code GEOSEARCHSTORE} commands.
|
||||
* Arguments to be used with {@link RedisGeoCommands}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.6
|
||||
*/
|
||||
interface GeoShape extends Shape {
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a {@link Distance radius} around the query center point.
|
||||
*
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byRadius(Distance radius) {
|
||||
return new RadiusShape(radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a bounding box with specified by {@code width} and
|
||||
* {@code height}.
|
||||
*
|
||||
* @param width must not be {@literal null}.
|
||||
* @param height must not be {@literal null}.
|
||||
* @param distanceUnit must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byBox(double width, double height, DistanceUnit distanceUnit) {
|
||||
return byBox(new BoundingBox(width, height, distanceUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a {@link BoundingBox}.
|
||||
*
|
||||
* @param boundingBox must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byBox(BoundingBox boundingBox) {
|
||||
return new BoxShape(boundingBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* The metric used for this geo predicate.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Metric getMetric();
|
||||
}
|
||||
|
||||
/**
|
||||
* Radius defined by {@link Distance}.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class RadiusShape implements GeoShape {
|
||||
|
||||
private final Distance radius;
|
||||
|
||||
public RadiusShape(Distance radius) {
|
||||
|
||||
Assert.notNull(radius, "Distance must not be null");
|
||||
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public Distance getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric getMetric() {
|
||||
return radius.getMetric();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bounding box defined by width and height.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
class BoxShape implements GeoShape {
|
||||
|
||||
private final BoundingBox boundingBox;
|
||||
|
||||
public BoxShape(BoundingBox boundingBox) {
|
||||
|
||||
Assert.notNull(boundingBox, "BoundingBox must not be null");
|
||||
|
||||
this.boundingBox = boundingBox;
|
||||
}
|
||||
|
||||
public BoundingBox getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric getMetric() {
|
||||
return boundingBox.getHeight().getMetric();
|
||||
}
|
||||
}
|
||||
|
||||
interface GeoCommandArgs {
|
||||
|
||||
/**
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
public Direction getSortDirection();
|
||||
|
||||
/**
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
@Nullable
|
||||
Long getLimit();
|
||||
|
||||
/**
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
Set<? extends GeoCommandFlag> getFlags();
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@literal limit} has been set.
|
||||
*/
|
||||
default boolean hasLimit() {
|
||||
return getLimit() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@literal sort} has been set.
|
||||
*/
|
||||
default boolean hasSortDirection() {
|
||||
return getSortDirection() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@literal true} if {@literal flags} is not empty.
|
||||
*/
|
||||
default boolean hasFlags() {
|
||||
return !getFlags().isEmpty();
|
||||
}
|
||||
|
||||
public interface GeoCommandFlag {}
|
||||
/**
|
||||
* A flag to be used.
|
||||
*/
|
||||
interface GeoCommandFlag {
|
||||
|
||||
static GeoCommandFlag any() {
|
||||
return Flag.ANY;
|
||||
}
|
||||
|
||||
static GeoCommandFlag withCord() {
|
||||
return Flag.WITHCOORD;
|
||||
}
|
||||
|
||||
static GeoCommandFlag withDist() {
|
||||
return Flag.WITHDIST;
|
||||
}
|
||||
|
||||
static GeoCommandFlag storeDist() {
|
||||
return Flag.STOREDIST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional arguments (like count/sort/...) to be used with {@link RedisGeoCommands}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 2.6
|
||||
*/
|
||||
class GeoSearchCommandArgs implements GeoCommandArgs, Cloneable {
|
||||
|
||||
protected final Set<Flag> flags = new LinkedHashSet<>(2, 1);
|
||||
protected final Set<GeoCommandFlag> flags = new LinkedHashSet<>(2, 1);
|
||||
|
||||
@Nullable protected Long limit;
|
||||
|
||||
@@ -407,7 +353,7 @@ public interface RedisGeoCommands {
|
||||
*/
|
||||
public GeoSearchCommandArgs includeCoordinates() {
|
||||
|
||||
flags.add(Flag.WITHCOORD);
|
||||
flags.add(GeoCommandFlag.withCord());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -418,7 +364,7 @@ public interface RedisGeoCommands {
|
||||
*/
|
||||
public GeoSearchCommandArgs includeDistance() {
|
||||
|
||||
flags.add(Flag.WITHDIST);
|
||||
flags.add(GeoCommandFlag.withDist());
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -475,7 +421,7 @@ public interface RedisGeoCommands {
|
||||
Assert.isTrue(count > 0, "Count has to positive value.");
|
||||
limit = count;
|
||||
if (any) {
|
||||
flags.add(Flag.ANY);
|
||||
flags.add(GeoCommandFlag.any());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -483,7 +429,7 @@ public interface RedisGeoCommands {
|
||||
/**
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
public Set<Flag> getFlags() {
|
||||
public Set<? extends GeoCommandFlag> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -504,7 +450,7 @@ public interface RedisGeoCommands {
|
||||
}
|
||||
|
||||
public boolean hasAnyLimit() {
|
||||
return hasLimit() && flags.contains(Flag.ANY);
|
||||
return hasLimit() && flags.contains(GeoCommandFlag.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -526,7 +472,7 @@ public interface RedisGeoCommands {
|
||||
*/
|
||||
class GeoSearchStoreCommandArgs implements GeoCommandArgs, Cloneable {
|
||||
|
||||
private final Set<Flag> flags = new LinkedHashSet<>(2, 1);
|
||||
private final Set<GeoCommandFlag> flags = new LinkedHashSet<>(2, 1);
|
||||
|
||||
@Nullable private Long limit;
|
||||
|
||||
@@ -607,7 +553,7 @@ public interface RedisGeoCommands {
|
||||
Assert.isTrue(count > 0, "Count has to positive value.");
|
||||
this.limit = count;
|
||||
if (any) {
|
||||
flags.add(Flag.ANY);
|
||||
flags.add(GeoCommandFlag.any());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -615,7 +561,7 @@ public interface RedisGeoCommands {
|
||||
/**
|
||||
* @return never {@literal null}.
|
||||
*/
|
||||
public Set<Flag> getFlags() {
|
||||
public Set<GeoCommandFlag> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
@@ -636,11 +582,11 @@ public interface RedisGeoCommands {
|
||||
}
|
||||
|
||||
public boolean isStoreDistance() {
|
||||
return flags.contains(Flag.STOREDIST);
|
||||
return flags.contains(GeoCommandFlag.storeDist());
|
||||
}
|
||||
|
||||
public boolean hasAnyLimit() {
|
||||
return hasLimit() && flags.contains(Flag.ANY);
|
||||
return hasLimit() && flags.contains(GeoCommandFlag.any());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -736,6 +682,10 @@ public interface RedisGeoCommands {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Set<Flag> getFlags() {
|
||||
return flags.stream().map(it -> (Flag) it).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public enum Flag implements GeoCommandFlag {
|
||||
WITHCOORD, WITHDIST, ANY, STOREDIST
|
||||
}
|
||||
@@ -751,193 +701,6 @@ public interface RedisGeoCommands {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference point for {@code GEOSEARCH} and {@code GEOSEARCHSTORE} commands. Provides factory methods to create
|
||||
* {@link GeoReference} from geo-set members or reference points.
|
||||
*
|
||||
* @param <T>
|
||||
* @since 2.6
|
||||
*/
|
||||
class GeoReference<T> {
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a geoset member.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromMember(T member) {
|
||||
|
||||
Assert.notNull(member, "Geoset member must not be null");
|
||||
|
||||
return new GeoSearchMemberReference<>(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a {@link GeoLocation geoset member}.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromMember(GeoLocation<T> member) {
|
||||
|
||||
Assert.notNull(member, "GeoLocation must not be null");
|
||||
|
||||
return new GeoSearchMemberReference<>(member.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a {@link Circle#getCenter() circle center point} .
|
||||
*
|
||||
* @param within must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromCircle(Circle within) {
|
||||
|
||||
Assert.notNull(within, "Circle must not be null");
|
||||
|
||||
return fromCoordinate(within.getCenter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param longitude
|
||||
* @param latitude
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromCoordinate(double longitude, double latitude) {
|
||||
return new GeoSearchCoordinateReference<>(longitude, latitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param location must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromCoordinate(GeoLocation<?> location) {
|
||||
|
||||
Assert.notNull(location, "GeoLocation must not be null");
|
||||
Assert.notNull(location.getPoint(), "GeoLocation point must not be null");
|
||||
|
||||
return fromCoordinate(location.getPoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param point must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> GeoReference<T> fromCoordinate(Point point) {
|
||||
|
||||
Assert.notNull(point, "Reference point must not be null");
|
||||
|
||||
return fromCoordinate(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
public static class GeoSearchMemberReference<T> extends GeoReference<T> {
|
||||
|
||||
private final T member;
|
||||
|
||||
public GeoSearchMemberReference(T member) {
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public T getMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoSearchMemberReference)) {
|
||||
return false;
|
||||
}
|
||||
GeoSearchMemberReference<?> that = (GeoSearchMemberReference<?>) o;
|
||||
return ObjectUtils.nullSafeEquals(member, that.member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [member=").append(member);
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class GeoSearchCoordinateReference<T> extends GeoReference<T> {
|
||||
|
||||
private final double longitude;
|
||||
private final double latitude;
|
||||
|
||||
public GeoSearchCoordinateReference(double longitude, double latitude) {
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoSearchCoordinateReference)) {
|
||||
return false;
|
||||
}
|
||||
GeoSearchCoordinateReference<?> that = (GeoSearchCoordinateReference<?>) o;
|
||||
if (longitude != that.longitude) {
|
||||
return false;
|
||||
}
|
||||
return latitude == that.latitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(longitude);
|
||||
result = (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(latitude);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [").append(longitude);
|
||||
sb.append(",").append(latitude);
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link GeoLocation} representing a {@link Point} associated with a {@literal name}.
|
||||
*
|
||||
@@ -945,53 +708,10 @@ public interface RedisGeoCommands {
|
||||
* @param <T>
|
||||
* @since 1.8
|
||||
*/
|
||||
class GeoLocation<T> {
|
||||
|
||||
private final T name;
|
||||
private final Point point;
|
||||
class GeoLocation<T> extends org.springframework.data.redis.domain.geo.GeoLocation<T> {
|
||||
|
||||
public GeoLocation(T name, Point point) {
|
||||
this.name = name;
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public T getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Point getPoint() {
|
||||
return this.point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof GeoLocation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoLocation<?> that = (GeoLocation<?>) o;
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(name, that.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ObjectUtils.nullSafeEquals(point, that.point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(name);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(point);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected boolean canEqual(Object other) {
|
||||
return other instanceof GeoLocation;
|
||||
super(name, point);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
@@ -1040,100 +760,4 @@ public interface RedisGeoCommands {
|
||||
return abbreviation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a geospatial bounding box defined by width and height.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.6
|
||||
*/
|
||||
class BoundingBox implements Shape {
|
||||
|
||||
private static final long serialVersionUID = 5215611530535947924L;
|
||||
|
||||
private final Distance width;
|
||||
private final Distance height;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoundingBox} from the given width and height. Both distances must use the same
|
||||
* {@link Metric}.
|
||||
*
|
||||
* @param width must not be {@literal null}.
|
||||
* @param height must not be {@literal null}.
|
||||
*/
|
||||
public BoundingBox(Distance width, Distance height) {
|
||||
|
||||
Assert.notNull(width, "Width must not be null!");
|
||||
Assert.notNull(height, "Height must not be null!");
|
||||
Assert.isTrue(width.getMetric().equals(height.getMetric()), "Metric for width and height must be the same!");
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoundingBox} from the given width, height and {@link Metric}.
|
||||
*
|
||||
* @param width
|
||||
* @param height
|
||||
* @param metric must not be {@literal null}.
|
||||
*/
|
||||
public BoundingBox(double width, double height, Metric metric) {
|
||||
this(new Distance(width, metric), new Distance(height, metric));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of this bounding box.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Distance getWidth() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of this bounding box.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Distance getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(width);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(height);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BoundingBox)) {
|
||||
return false;
|
||||
}
|
||||
BoundingBox that = (BoundingBox) o;
|
||||
if (!ObjectUtils.nullSafeEquals(width, that.width)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(height, that.height);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Bounding box: [width=%s, height=%s]", width, height);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.data.redis.core.types.RedisClientInfo;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -2428,7 +2430,7 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
/**
|
||||
* Return the members of a geo set which are within the borders of the area specified by a given {@link GeoShape
|
||||
* shape}. The query's center point is provided by
|
||||
* {@link org.springframework.data.redis.connection.RedisGeoCommands.GeoReference}.
|
||||
* {@link GeoReference}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param reference must not be {@literal null}.
|
||||
@@ -2445,7 +2447,7 @@ public interface StringRedisConnection extends RedisConnection {
|
||||
/**
|
||||
* Query the members of a geo set which are within the borders of the area specified by a given {@link GeoShape shape}
|
||||
* and store the result at {@code destKey}. The query's center point is provided by
|
||||
* {@link org.springframework.data.redis.connection.RedisGeoCommands.GeoReference}.
|
||||
* {@link GeoReference}.
|
||||
*
|
||||
* @param key must not be {@literal null}.
|
||||
* @param reference must not be {@literal null}.
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.connection.jedis;
|
||||
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import redis.clients.jedis.BinaryJedis;
|
||||
import redis.clients.jedis.GeoCoordinate;
|
||||
import redis.clients.jedis.GeoUnit;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package org.springframework.data.redis.connection.lettuce;
|
||||
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.*;
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.GeoReference.*;
|
||||
import static org.springframework.data.redis.domain.geo.GeoReference.*;
|
||||
|
||||
import io.lettuce.core.*;
|
||||
import io.lettuce.core.cluster.models.partitions.Partitions;
|
||||
@@ -30,7 +30,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
@@ -61,6 +60,11 @@ import org.springframework.data.redis.core.KeyScanOptions;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.data.redis.core.types.Expiration;
|
||||
import org.springframework.data.redis.core.types.RedisClientInfo;
|
||||
import org.springframework.data.redis.domain.geo.BoundingBox;
|
||||
import org.springframework.data.redis.domain.geo.BoxShape;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.data.redis.domain.geo.RadiusShape;
|
||||
import org.springframework.data.redis.util.ByteUtils;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -1147,13 +1151,13 @@ public abstract class LettuceConverters extends Converters {
|
||||
|
||||
static <T> GeoSearch.GeoRef<T> toGeoRef(GeoReference<T> reference) {
|
||||
|
||||
if (reference instanceof GeoSearchMemberReference) {
|
||||
return GeoSearch.fromMember(((GeoSearchMemberReference<T>) reference).getMember());
|
||||
if (reference instanceof GeoReference.GeoMemberReference) {
|
||||
return GeoSearch.fromMember(((GeoMemberReference<T>) reference).getMember());
|
||||
}
|
||||
|
||||
if (reference instanceof GeoSearchCoordinateReference) {
|
||||
if (reference instanceof GeoReference.GeoCoordinateReference) {
|
||||
|
||||
GeoSearchCoordinateReference<?> coordinates = (GeoSearchCoordinateReference<?>) reference;
|
||||
GeoCoordinateReference<?> coordinates = (GeoCoordinateReference<?>) reference;
|
||||
return GeoSearch.fromCoordinates(coordinates.getLongitude(), coordinates.getLatitude());
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.domain.geo.BoundingBox;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -437,7 +439,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default GeoResults<GeoLocation<M>> search(GeoReference<M> reference, Distance radius) {
|
||||
return search(reference, radius, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
|
||||
@@ -453,7 +455,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default GeoResults<GeoLocation<M>> search(GeoReference<M> reference, Distance radius,
|
||||
GeoSearchCommandArgs args) {
|
||||
return search(reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -469,7 +471,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
default GeoResults<GeoLocation<M>> search(GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
return search(reference, boundingBox, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
|
||||
@@ -485,7 +487,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox,
|
||||
default GeoResults<GeoLocation<M>> search(GeoReference<M> reference, BoundingBox boundingBox,
|
||||
GeoSearchCommandArgs args) {
|
||||
return search(reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -502,7 +504,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoResults<GeoLocation<M>> search(GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoSearchCommandArgs args);
|
||||
|
||||
/**
|
||||
@@ -530,7 +532,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default Long searchAndStore(K destKey, GeoReference<M> reference, Distance radius) {
|
||||
return searchAndStore(destKey, reference, radius, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
|
||||
@@ -546,7 +548,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default Long searchAndStore(K destKey, GeoReference<M> reference, Distance radius,
|
||||
GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(destKey, reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -562,7 +564,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
default Long searchAndStore(K destKey, GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
return searchAndStore(destKey, reference, boundingBox, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
|
||||
@@ -578,7 +580,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox,
|
||||
default Long searchAndStore(K destKey, GeoReference<M> reference, BoundingBox boundingBox,
|
||||
GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(destKey, reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -595,7 +597,7 @@ public interface BoundGeoOperations<K, M> extends BoundKeyOperations<K> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference, GeoShape geoPredicate,
|
||||
Long searchAndStore(K destKey, GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoSearchStoreCommandArgs args);
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.springframework.data.redis.connection.DataType;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link BoundGeoOperations}.
|
||||
@@ -183,8 +185,8 @@ class DefaultBoundGeoOperations<K, M> extends DefaultBoundKeyOperations<K> imple
|
||||
* @see org.springframework.data.redis.core.BoundGeoOperations#search(org.springframework.data.redis.connection.RedisGeoCommands.GeoReference, org.springframework.data.redis.connection.RedisGeoCommands.GeoShape, org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> search(RedisGeoCommands.GeoReference<M> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
public GeoResults<GeoLocation<M>> search(GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
return ops.search(getKey(), reference, geoPredicate, args);
|
||||
}
|
||||
|
||||
@@ -193,8 +195,8 @@ class DefaultBoundGeoOperations<K, M> extends DefaultBoundKeyOperations<K> imple
|
||||
* @see org.springframework.data.redis.core.BoundGeoOperations#searchAndStore(java.lang.Object, org.springframework.data.redis.connection.RedisGeoCommands.GeoReference, org.springframework.data.redis.connection.RedisGeoCommands.GeoShape, org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long searchAndStore(K destKey, RedisGeoCommands.GeoReference<M> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
public Long searchAndStore(K destKey, GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
return ops.searchAndStore(getKey(), destKey, reference, geoPredicate, args);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference.GeoMemberReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link GeoOperations}.
|
||||
@@ -248,11 +251,11 @@ class DefaultGeoOperations<K, M> extends AbstractOperations<K, M> implements Geo
|
||||
* @see org.springframework.data.redis.core.GeoOperations#search(java.lang.Object, org.springframework.data.redis.connection.RedisGeoCommands.GeoReference, org.springframework.data.redis.connection.RedisGeoCommands.GeoShape, org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
public GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
RedisGeoCommands.GeoReference<byte[]> rawMember = getGeoReference(reference);
|
||||
GeoReference<byte[]> rawMember = getGeoReference(reference);
|
||||
|
||||
GeoResults<GeoLocation<byte[]>> raw = execute(
|
||||
connection -> connection.geoSearch(rawKey, rawMember, geoPredicate, args), true);
|
||||
@@ -265,21 +268,21 @@ class DefaultGeoOperations<K, M> extends AbstractOperations<K, M> implements Geo
|
||||
* @see org.springframework.data.redis.core.GeoOperations#searchAndStore(java.lang.Object, java.lang.Object, org.springframework.data.redis.connection.RedisGeoCommands.GeoReference, org.springframework.data.redis.connection.RedisGeoCommands.GeoShape, org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
public Long searchAndStore(K key, K destKey, GeoReference<M> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
|
||||
byte[] rawKey = rawKey(key);
|
||||
byte[] rawDestKey = rawKey(destKey);
|
||||
RedisGeoCommands.GeoReference<byte[]> rawMember = getGeoReference(reference);
|
||||
GeoReference<byte[]> rawMember = getGeoReference(reference);
|
||||
|
||||
return execute(connection -> connection.geoSearchStore(rawDestKey, rawKey, rawMember, geoPredicate, args), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RedisGeoCommands.GeoReference<byte[]> getGeoReference(RedisGeoCommands.GeoReference<M> reference) {
|
||||
return reference instanceof RedisGeoCommands.GeoReference.GeoSearchMemberReference
|
||||
? RedisGeoCommands.GeoReference
|
||||
.fromMember(rawValue(((RedisGeoCommands.GeoReference.GeoSearchMemberReference<M>) reference).getMember()))
|
||||
: (RedisGeoCommands.GeoReference<byte[]>) reference;
|
||||
private GeoReference<byte[]> getGeoReference(GeoReference<M> reference) {
|
||||
return reference instanceof GeoReference.GeoMemberReference
|
||||
? GeoReference
|
||||
.fromMember(rawValue(((GeoMemberReference<M>) reference).getMember()))
|
||||
: (GeoReference<byte[]>) reference;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference.GeoMemberReference;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
@@ -35,6 +37,7 @@ import org.springframework.data.redis.connection.ReactiveGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -340,12 +343,12 @@ class DefaultReactiveGeoOperations<K, V> implements ReactiveGeoOperations<K, V>
|
||||
* @see org.springframework.data.redis.core.ReactiveGeoOperations#search(K, RedisGeoCommands.GeoReference, GeoShape, GeoSearchCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public Flux<GeoResult<GeoLocation<V>>> search(K key, RedisGeoCommands.GeoReference<V> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
public Flux<GeoResult<GeoLocation<V>>> search(K key, GeoReference<V> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchCommandArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(reference, "GeoReference must not be null!");
|
||||
RedisGeoCommands.GeoReference<ByteBuffer> rawReference = getGeoReference(reference);
|
||||
GeoReference<ByteBuffer> rawReference = getGeoReference(reference);
|
||||
|
||||
return template.createFlux(connection -> connection.geoCommands()
|
||||
.geoSearch(rawKey(key), rawReference, geoPredicate, args).map(this::readGeoResult));
|
||||
@@ -356,12 +359,12 @@ class DefaultReactiveGeoOperations<K, V> implements ReactiveGeoOperations<K, V>
|
||||
* @see org.springframework.data.redis.core.ReactiveGeoOperations#searchAndStore(K, K, RedisGeoCommands.GeoReference, GeoShape, GeoSearchStoreCommandArgs)
|
||||
*/
|
||||
@Override
|
||||
public Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<V> reference,
|
||||
RedisGeoCommands.GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
public Mono<Long> searchAndStore(K key, K destKey, GeoReference<V> reference,
|
||||
GeoShape geoPredicate, RedisGeoCommands.GeoSearchStoreCommandArgs args) {
|
||||
|
||||
Assert.notNull(key, "Key must not be null!");
|
||||
Assert.notNull(reference, "GeoReference must not be null!");
|
||||
RedisGeoCommands.GeoReference<ByteBuffer> rawReference = getGeoReference(reference);
|
||||
GeoReference<ByteBuffer> rawReference = getGeoReference(reference);
|
||||
|
||||
return template.createMono(connection -> connection.geoCommands().geoSearchStore(rawKey(destKey), rawKey(key),
|
||||
rawReference, geoPredicate, args));
|
||||
@@ -382,11 +385,11 @@ class DefaultReactiveGeoOperations<K, V> implements ReactiveGeoOperations<K, V>
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private RedisGeoCommands.GeoReference<ByteBuffer> getGeoReference(RedisGeoCommands.GeoReference<V> reference) {
|
||||
return reference instanceof RedisGeoCommands.GeoReference.GeoSearchMemberReference
|
||||
? RedisGeoCommands.GeoReference
|
||||
.fromMember(rawValue(((RedisGeoCommands.GeoReference.GeoSearchMemberReference<V>) reference).getMember()))
|
||||
: (RedisGeoCommands.GeoReference<ByteBuffer>) reference;
|
||||
private GeoReference<ByteBuffer> getGeoReference(GeoReference<V> reference) {
|
||||
return reference instanceof GeoReference.GeoMemberReference
|
||||
? GeoReference
|
||||
.fromMember(rawValue(((GeoMemberReference<V>) reference).getMember()))
|
||||
: (GeoReference<ByteBuffer>) reference;
|
||||
}
|
||||
|
||||
private ByteBuffer rawKey(K key) {
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.redis.core;
|
||||
|
||||
import static org.springframework.data.redis.connection.RedisGeoCommands.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -25,8 +23,13 @@ import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResults;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.*;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoLocation;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoRadiusCommandArgs;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchCommandArgs;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.GeoSearchStoreCommandArgs;
|
||||
import org.springframework.data.redis.domain.geo.BoundingBox;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -467,7 +470,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference, Distance radius) {
|
||||
return search(key, reference, radius, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
|
||||
@@ -484,7 +487,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference, Distance radius,
|
||||
GeoSearchCommandArgs args) {
|
||||
return search(key, reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -501,7 +504,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference,
|
||||
default GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference,
|
||||
BoundingBox boundingBox) {
|
||||
return search(key, reference, boundingBox, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
@@ -519,7 +522,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
default GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox,
|
||||
default GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference, BoundingBox boundingBox,
|
||||
GeoSearchCommandArgs args) {
|
||||
return search(key, reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -537,7 +540,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
@Nullable
|
||||
GeoResults<GeoLocation<M>> search(K key, RedisGeoCommands.GeoReference<M> reference,
|
||||
GeoResults<GeoLocation<M>> search(K key, GeoReference<M> reference,
|
||||
GeoShape geoPredicate, GeoSearchCommandArgs args);
|
||||
|
||||
/**
|
||||
@@ -567,7 +570,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default Long searchAndStore(K key, K destKey, GeoReference<M> reference, Distance radius) {
|
||||
return searchAndStore(key, destKey, reference, radius, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
|
||||
@@ -584,7 +587,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default Long searchAndStore(K key, K destKey, GeoReference<M> reference, Distance radius,
|
||||
GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(key, destKey, reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -601,7 +604,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
default Long searchAndStore(K key, K destKey, GeoReference<M> reference, BoundingBox boundingBox) {
|
||||
return searchAndStore(key, destKey, reference, boundingBox, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
|
||||
@@ -618,7 +621,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
default Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, BoundingBox boundingBox,
|
||||
default Long searchAndStore(K key, K destKey, GeoReference<M> reference, BoundingBox boundingBox,
|
||||
GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(key, destKey, reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -636,7 +639,7 @@ public interface GeoOperations<K, M> {
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
@Nullable
|
||||
Long searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, GeoShape geoPredicate,
|
||||
Long searchAndStore(K key, K destKey, GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoSearchStoreCommandArgs args);
|
||||
|
||||
}
|
||||
|
||||
@@ -25,13 +25,14 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.GeoResult;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.domain.geo.BoundingBox;
|
||||
import org.springframework.data.redis.domain.geo.GeoReference;
|
||||
import org.springframework.data.redis.domain.geo.GeoShape;
|
||||
|
||||
/**
|
||||
* Reactive Redis operations for geo commands.
|
||||
@@ -256,7 +257,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, GeoReference<M> reference, Distance radius) {
|
||||
return search(key, reference, radius, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
|
||||
@@ -272,7 +273,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, GeoReference<M> reference, Distance radius,
|
||||
GeoSearchCommandArgs args) {
|
||||
return search(key, reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -288,7 +289,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, RedisGeoCommands.GeoReference<M> reference,
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, GeoReference<M> reference,
|
||||
BoundingBox boundingBox) {
|
||||
return search(key, reference, boundingBox, GeoSearchCommandArgs.newGeoSearchArgs());
|
||||
}
|
||||
@@ -305,7 +306,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, RedisGeoCommands.GeoReference<M> reference,
|
||||
default Flux<GeoResult<GeoLocation<M>>> search(K key, GeoReference<M> reference,
|
||||
BoundingBox boundingBox, GeoSearchCommandArgs args) {
|
||||
return search(key, reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -322,7 +323,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearch">Redis Documentation: GEOSEARCH</a>
|
||||
*/
|
||||
Flux<GeoResult<GeoLocation<M>>> search(K key, RedisGeoCommands.GeoReference<M> reference, GeoShape geoPredicate,
|
||||
Flux<GeoResult<GeoLocation<M>>> search(K key, GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoSearchCommandArgs args);
|
||||
|
||||
/**
|
||||
@@ -350,7 +351,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
default Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius) {
|
||||
default Mono<Long> searchAndStore(K key, K destKey, GeoReference<M> reference, Distance radius) {
|
||||
return searchAndStore(key, destKey, reference, radius, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
|
||||
@@ -366,7 +367,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
default Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, Distance radius,
|
||||
default Mono<Long> searchAndStore(K key, K destKey, GeoReference<M> reference, Distance radius,
|
||||
GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(key, destKey, reference, GeoShape.byRadius(radius), args);
|
||||
}
|
||||
@@ -382,7 +383,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
default Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference,
|
||||
default Mono<Long> searchAndStore(K key, K destKey, GeoReference<M> reference,
|
||||
BoundingBox boundingBox) {
|
||||
return searchAndStore(key, destKey, reference, boundingBox, GeoSearchStoreCommandArgs.newGeoSearchStoreArgs());
|
||||
}
|
||||
@@ -399,7 +400,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
default Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference,
|
||||
default Mono<Long> searchAndStore(K key, K destKey, GeoReference<M> reference,
|
||||
BoundingBox boundingBox, GeoSearchStoreCommandArgs args) {
|
||||
return searchAndStore(key, destKey, reference, GeoShape.byBox(boundingBox), args);
|
||||
}
|
||||
@@ -416,7 +417,7 @@ public interface ReactiveGeoOperations<K, M> {
|
||||
* @since 2.6
|
||||
* @see <a href="https://redis.io/commands/geosearchstore">Redis Documentation: GEOSEARCHSTORE</a>
|
||||
*/
|
||||
Mono<Long> searchAndStore(K key, K destKey, RedisGeoCommands.GeoReference<M> reference, GeoShape geoPredicate,
|
||||
Mono<Long> searchAndStore(K key, K destKey, GeoReference<M> reference, GeoShape geoPredicate,
|
||||
GeoSearchStoreCommandArgs args);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Represents a geospatial bounding box defined by width and height.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.6
|
||||
*/
|
||||
public class BoundingBox implements Shape {
|
||||
|
||||
private static final long serialVersionUID = 5215611530535947924L;
|
||||
|
||||
private final Distance width;
|
||||
private final Distance height;
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoundingBox} from the given width and height. Both distances must use the same
|
||||
* {@link Metric}.
|
||||
*
|
||||
* @param width must not be {@literal null}.
|
||||
* @param height must not be {@literal null}.
|
||||
*/
|
||||
public BoundingBox(Distance width, Distance height) {
|
||||
|
||||
Assert.notNull(width, "Width must not be null!");
|
||||
Assert.notNull(height, "Height must not be null!");
|
||||
Assert.isTrue(width.getMetric().equals(height.getMetric()), "Metric for width and height must be the same!");
|
||||
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BoundingBox} from the given width, height and {@link Metric}.
|
||||
*
|
||||
* @param width
|
||||
* @param height
|
||||
* @param metric must not be {@literal null}.
|
||||
*/
|
||||
public BoundingBox(double width, double height, Metric metric) {
|
||||
this(new Distance(width, metric), new Distance(height, metric));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of this bounding box.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Distance getWidth() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the height of this bounding box.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
*/
|
||||
public Distance getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#hashCode()
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(width);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(height);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof BoundingBox)) {
|
||||
return false;
|
||||
}
|
||||
BoundingBox that = (BoundingBox) o;
|
||||
if (!ObjectUtils.nullSafeEquals(width, that.width)) {
|
||||
return false;
|
||||
}
|
||||
return ObjectUtils.nullSafeEquals(height, that.height);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Bounding box: [width=%s, height=%s]", width, height);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Bounding box defined by width and height.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.6
|
||||
*
|
||||
*/
|
||||
public class BoxShape implements GeoShape {
|
||||
|
||||
private final BoundingBox boundingBox;
|
||||
|
||||
public BoxShape(BoundingBox boundingBox) {
|
||||
|
||||
Assert.notNull(boundingBox, "BoundingBox must not be null");
|
||||
|
||||
this.boundingBox = boundingBox;
|
||||
}
|
||||
|
||||
public BoundingBox getBoundingBox() {
|
||||
return boundingBox;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric getMetric() {
|
||||
return boundingBox.getHeight().getMetric();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* @author Christoph Strobl
|
||||
* @since 2.6
|
||||
*/
|
||||
public class GeoLocation<T> {
|
||||
|
||||
private final T name;
|
||||
private final Point point;
|
||||
|
||||
public GeoLocation(T name, Point point) {
|
||||
this.name = name;
|
||||
this.point = point;
|
||||
}
|
||||
|
||||
public T getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Point getPoint() {
|
||||
return this.point;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof GeoLocation)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GeoLocation<?> that = (GeoLocation<?>) o;
|
||||
|
||||
if (!ObjectUtils.nullSafeEquals(name, that.name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ObjectUtils.nullSafeEquals(point, that.point);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = ObjectUtils.nullSafeHashCode(name);
|
||||
result = 31 * result + ObjectUtils.nullSafeHashCode(point);
|
||||
return result;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "GeoLocation(name=" + this.getName() + ", point=" + this.getPoint() + ")";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Circle;
|
||||
import org.springframework.data.geo.Point;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Reference point for {@code GEOSEARCH} and {@code GEOSEARCHSTORE} commands. Provides factory methods to create
|
||||
* {@link GeoReference} from geo-set members or reference points.
|
||||
*
|
||||
* @param <T>
|
||||
* @author Mark Paluch
|
||||
* @author Christoph Strobl
|
||||
* @since 2.6
|
||||
*/
|
||||
public interface GeoReference<T> {
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a geoset member.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromMember(T member) {
|
||||
|
||||
Assert.notNull(member, "Geoset member must not be null");
|
||||
|
||||
return new GeoMemberReference<>(member);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a {@link RedisGeoCommands.GeoLocation geoset member}.
|
||||
*
|
||||
* @param member must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromMember(RedisGeoCommands.GeoLocation<T> member) {
|
||||
|
||||
Assert.notNull(member, "GeoLocation must not be null");
|
||||
|
||||
return new GeoMemberReference<>(member.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a {@link Circle#getCenter() circle center point} .
|
||||
*
|
||||
* @param within must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromCircle(Circle within) {
|
||||
|
||||
Assert.notNull(within, "Circle must not be null");
|
||||
|
||||
return fromCoordinate(within.getCenter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param longitude
|
||||
* @param latitude
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromCoordinate(double longitude, double latitude) {
|
||||
return new GeoCoordinateReference<>(longitude, latitude);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param location must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromCoordinate(RedisGeoCommands.GeoLocation<?> location) {
|
||||
|
||||
Assert.notNull(location, "GeoLocation must not be null");
|
||||
Assert.notNull(location.getPoint(), "GeoLocation point must not be null");
|
||||
|
||||
return fromCoordinate(location.getPoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link GeoReference} from a WGS84 longitude/latitude coordinate.
|
||||
*
|
||||
* @param point must not be {@literal null}.
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
static <T> GeoReference<T> fromCoordinate(Point point) {
|
||||
|
||||
Assert.notNull(point, "Reference point must not be null");
|
||||
|
||||
return fromCoordinate(point.getX(), point.getY());
|
||||
}
|
||||
|
||||
class GeoMemberReference<T> implements GeoReference<T> {
|
||||
|
||||
private final T member;
|
||||
|
||||
public GeoMemberReference(T member) {
|
||||
this.member = member;
|
||||
}
|
||||
|
||||
public T getMember() {
|
||||
return member;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoReference.GeoMemberReference)) {
|
||||
return false;
|
||||
}
|
||||
GeoMemberReference<?> that = (GeoMemberReference<?>) o;
|
||||
return ObjectUtils.nullSafeEquals(member, that.member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ObjectUtils.nullSafeHashCode(member);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [member=").append(member);
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class GeoCoordinateReference<T> implements GeoReference<T> {
|
||||
|
||||
private final double longitude;
|
||||
private final double latitude;
|
||||
|
||||
public GeoCoordinateReference(double longitude, double latitude) {
|
||||
this.longitude = longitude;
|
||||
this.latitude = latitude;
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof GeoReference.GeoCoordinateReference)) {
|
||||
return false;
|
||||
}
|
||||
GeoCoordinateReference<?> that = (GeoCoordinateReference<?>) o;
|
||||
if (longitude != that.longitude) {
|
||||
return false;
|
||||
}
|
||||
return latitude == that.latitude;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(longitude);
|
||||
result = (int) (temp ^ (temp >>> 32));
|
||||
temp = Double.doubleToLongBits(latitude);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
sb.append(getClass().getSimpleName());
|
||||
sb.append(" [").append(longitude);
|
||||
sb.append(",").append(latitude);
|
||||
sb.append(']');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.geo.Shape;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands.DistanceUnit;
|
||||
|
||||
/**
|
||||
* Search predicate for {@code GEOSEARCH} and {@code GEOSEARCHSTORE} commands.
|
||||
*
|
||||
* @since 2.6
|
||||
*/
|
||||
public interface GeoShape extends Shape {
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a {@link Distance radius} around the query center point.
|
||||
*
|
||||
* @param radius
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byRadius(Distance radius) {
|
||||
return new RadiusShape(radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a bounding box with specified by {@code width} and
|
||||
* {@code height}.
|
||||
*
|
||||
* @param width must not be {@literal null}.
|
||||
* @param height must not be {@literal null}.
|
||||
* @param distanceUnit must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byBox(double width, double height, DistanceUnit distanceUnit) {
|
||||
return byBox(new BoundingBox(width, height, distanceUnit));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shape used as predicate for geo queries from a {@link BoundingBox}.
|
||||
*
|
||||
* @param boundingBox must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
static GeoShape byBox(BoundingBox boundingBox) {
|
||||
return new BoxShape(boundingBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* The metric used for this geo predicate.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
Metric getMetric();
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.data.redis.connection.RedisGeoCommands;
|
||||
|
||||
/**
|
||||
* {@link Metric}s supported by Redis.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.6
|
||||
*/
|
||||
public enum Metrics implements Metric {
|
||||
|
||||
METERS(6378137, "m"), KILOMETERS(6378.137, "km"), MILES(3963.191, "mi"), FEET(20925646.325, "ft");
|
||||
|
||||
private final double multiplier;
|
||||
private final String abbreviation;
|
||||
|
||||
/**
|
||||
* Creates a new {@link RedisGeoCommands.DistanceUnit} using the given muliplier.
|
||||
*
|
||||
* @param multiplier the earth radius at equator.
|
||||
*/
|
||||
Metrics(double multiplier, String abbreviation) {
|
||||
|
||||
this.multiplier = multiplier;
|
||||
this.abbreviation = abbreviation;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.geo.Metric#getMultiplier()
|
||||
*/
|
||||
public double getMultiplier() {
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.geo.Metric#getAbbreviation()
|
||||
*/
|
||||
@Override
|
||||
public String getAbbreviation() {
|
||||
return abbreviation;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.redis.domain.geo;
|
||||
|
||||
import org.springframework.data.geo.Distance;
|
||||
import org.springframework.data.geo.Metric;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Radius defined by {@link Distance}.
|
||||
*
|
||||
* @author Mark Paluch
|
||||
* @since 2.6
|
||||
*/
|
||||
public class RadiusShape implements GeoShape {
|
||||
|
||||
private final Distance radius;
|
||||
|
||||
public RadiusShape(Distance radius) {
|
||||
|
||||
Assert.notNull(radius, "Distance must not be null");
|
||||
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
public Distance getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Metric getMetric() {
|
||||
return radius.getMetric();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user