Spatial

Information

This article focuses only on querying side of spatial search. If you want to read how to index spatial data, click here.

To perform a spatial search you can use spatial method:

QSpatialIndexes_SpatialDoc s = QSpatialIndexes_SpatialDoc.spatialDoc;
List<SpatialDoc> results = session
  .query(SpatialDoc.class, SpatialDoc_ByShapeAndPoint.class)
  .spatial(s.shape, new SpatialCriteriaFactory().withinRadius(500, 30, 30))
  .toList();
QSpatialIndexes_SpatialDoc s = QSpatialIndexes_SpatialDoc.spatialDoc;
List<SpatialDoc> results = session
  .advanced()
  .documentQuery(SpatialDoc.class, SpatialDoc_ByShapeAndPoint.class)
  .spatial(s.shape, new SpatialCriteriaFactory().withinRadius(500, 30, 30))
  .toList();
public static class SpatialDoc_ByShapeAndPoint extends AbstractIndexCreationTask {
  public SpatialDoc_ByShapeAndPoint() {
    QSpatialIndexes_SpatialDoc s = QSpatialIndexes_SpatialDoc.spatialDoc;
    map =
     " from spatial in docs        " +
     " select new                  " +
     " {                           " +
     "     Shape = spatial.Shape,  " +
     "     Point = spatial.Point   " +
     " }; ";

    spatial(s.shape, new SpatialOptionsFactory().getGeography().defaultOptions());
    spatial(s.point, new SpatialOptionsFactory().getCartesian().boundingBoxIndex());
  }
}

Under criteria following methods are available:

public SpatialCriteria relatesToShape(Object shape, SpatialRelation relation);

public SpatialCriteria intersects(Object shape);

public SpatialCriteria contains(Object shape);

public SpatialCriteria disjoint(Object shape);

public SpatialCriteria within(Object shape);

public SpatialCriteria withinRadius(double radius, double latitude, double longitude);

/**
 * Order of parameters in this method is inconsistent with the rest of the API (x = longitude, y = latitude). Please use 'withinRadius'.
 */
@Deprecated
public SpatialCriteria withinRadiusOf(double radius, double x, double y);

Obsolete method

Since version 3.0.3699-Unstable withinRadiusOf method is marked as obsolete because of parameter order inconsistency. Use withinRadius instead.

The most basic usage and probably most common one is to search for all points or shapes within provided distance from the given center point. To perform this search we will use withinRadiusOf method that is a part of query customizations.

List<Event> results = session
  .query(Event.class, Events_ByNameAndCoordinates.class)
  .customize(new DocumentQueryCustomizationFactory().withinRadiusOf("Coordinates", 10, 32.1234, 23.4321))
  .toList();
List<Event> results = session
  .advanced()
  .documentQuery(Event.class, Events_ByNameAndCoordinates.class)
  .withinRadiusOf("Coordinates", 10, 32.1234, 23.4321)
  .toList();
public static class Events_ByNameAndCoordinates extends AbstractIndexCreationTask {
  public Events_ByNameAndCoordinates() {
    map =
     " from e in docs.Events                                             " +
     " select new                                                        " +
     " {                                                                 " +
     "     Name = e.Name,                                                " +
     "     __ = SpatialGenerate(\"Coordinates\", e.Latitude, e.Longitude)" +
     " }; ";
  }
}

The withinRadiusOf method is a wrapper around relatesToShape method.

public DocumentQueryCustomizationFactory relatesToShape(final String fieldName, final String shapeWKT, final SpatialRelation rel);

@UseSharpEnum
public enum SpatialRelation {
  WITHIN, CONTAINS, DISJOINT, INTERSECTS,

  /**
   * Does not filter the query, merely sort by the distance
   */
  NEARBY
}

where first parameter is a name of the field containing the shape to use for filtering, next one is a shape in WKT format and the last one is a spatial relation type.

So to perform a radius search from the above example and use relatesToShape method, we do as follows

List<Event> results = session
  .query(Event.class, Events_ByNameAndCoordinates.class)
  .customize(new DocumentQueryCustomizationFactory()
    .relatesToShape("Coordinates", "Circle(32.1234 23.4321 d=10.0000)",
      net.ravendb.abstractions.indexing.SpatialOptions.SpatialRelation.WITHIN))
  .toList();
List<Event> results = session
  .advanced()
  .documentQuery(Event.class, Events_ByNameAndCoordinates.class)
  .relatesToShape("Coordinates", "Circle(32.1234 23.4321 d=10.0000)",
      net.ravendb.abstractions.indexing.SpatialOptions.SpatialRelation.WITHIN)
  .toList();
public static class Events_ByNameAndCoordinates extends AbstractIndexCreationTask {
  public Events_ByNameAndCoordinates() {
    map =
     " from e in docs.Events                                             " +
     " select new                                                        " +
     " {                                                                 " +
     "     Name = e.Name,                                                " +
     "     __ = SpatialGenerate(\"Coordinates\", e.Latitude, e.Longitude)" +
     " }; ";
  }
}

Warning

Distance in RavenDB by default is measured in kilometers.