GeoShapeFieldsUsageInRediSearch.java
package redis.clients.jedis.examples;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Polygon;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisPooled;
import redis.clients.jedis.UnifiedJedis;
import redis.clients.jedis.search.FTSearchParams;
import redis.clients.jedis.search.SearchResult;
import redis.clients.jedis.search.schemafields.GeoShapeField;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* As of RediSearch 2.8.4, advanced GEO querying with GEOSHAPE fields is supported.
* <p>
* Notes:
* <ul>
* <li>As of RediSearch 2.8.4, only POLYGON and POINT objects are supported.</li>
* <li>As of RediSearch 2.8.4, only WITHIN and CONTAINS conditions are supported.</li>
* <li>As of RedisStack 7.4.0, support for INTERSECTS and DISJOINT conditions are added.</li>
* </ul>
*
* Any object/library producing a <a href="https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry">
* well-known text (WKT)</a> in {@code toString()} method can be used.
*
* This example uses the <a href="https://github.com/locationtech/jts">JTS</a> library.
* <pre>
* {@code
* <dependency>
* <groupId>org.locationtech.jts</groupId>
* <artifactId>jts-core</artifactId>
* <version>1.19.0</version>
* </dependency>
* }
* </pre>
*/
public class GeoShapeFieldsUsageInRediSearch {
public static void main(String[] args) {
// We'll create geometry objects with GeometryFactory
final GeometryFactory factory = new GeometryFactory();
final String host = "localhost";
final int port = 6379;
final HostAndPort address = new HostAndPort(host, port);
UnifiedJedis client = new JedisPooled(address);
// client.setDefaultSearchDialect(3); // we can set default search dialect for the client (UnifiedJedis) object
// to avoid setting dialect in every query.
// creating index
client.ftCreate("geometry-index",
GeoShapeField.of("geometry", GeoShapeField.CoordinateSystem.SPHERICAL) // 'SPHERICAL' is for geographic (lon, lat).
// 'FLAT' coordinate system also available for cartesian (X,Y).
);
// preparing data
final Polygon small = factory.createPolygon(
new Coordinate[]{new Coordinate(34.9001, 29.7001),
new Coordinate(34.9001, 29.7100), new Coordinate(34.9100, 29.7100),
new Coordinate(34.9100, 29.7001), new Coordinate(34.9001, 29.7001)}
);
// client.hset("small", RediSearchUtil.toStringMap(Collections.singletonMap("geometry", small))); // setting data
// client.hset("small", "geometry", small.toString()); // simplified setting data
client.hsetObject("small", "geometry", small); // more simplified setting data
final Polygon large = factory.createPolygon(
new Coordinate[]{new Coordinate(34.9001, 29.7001),
new Coordinate(34.9001, 29.7200), new Coordinate(34.9200, 29.7200),
new Coordinate(34.9200, 29.7001), new Coordinate(34.9001, 29.7001)}
);
// client.hset("large", RediSearchUtil.toStringMap(Collections.singletonMap("geometry", large))); // setting data
// client.hset("large", "geometry", large.toString()); // simplified setting data
client.hsetObject("large", "geometry", large); // more simplified setting data
// searching
final Polygon within = factory.createPolygon(
new Coordinate[]{new Coordinate(34.9000, 29.7000),
new Coordinate(34.9000, 29.7150), new Coordinate(34.9150, 29.7150),
new Coordinate(34.9150, 29.7000), new Coordinate(34.9000, 29.7000)}
);
SearchResult res = client.ftSearch("geometry-index",
"@geometry:[within $poly]", // query string
FTSearchParams.searchParams()
.addParam("poly", within)
.dialect(3) // DIALECT '3' is required for this query
);
assertEquals(1, res.getTotalResults());
assertEquals(1, res.getDocuments().size());
// We can parse geometry objects with WKTReader
try {
final WKTReader reader = new WKTReader();
Geometry object = reader.read(res.getDocuments().get(0).getString("geometry"));
assertEquals(small, object);
} catch (ParseException ex) { // WKTReader#read throws ParseException
ex.printStackTrace(System.err);
}
}
}