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:
IList<SpatialDoc> results = session
.Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
.Spatial(x => x.Shape, criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
IList<SpatialDoc> results = session
.Advanced
.DocumentQuery<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
.Spatial(x => x.Shape, criteria => criteria.WithinRadius(500, 30, 30))
.ToList();
public class SpatialDoc_ByShapeAndPoint : AbstractIndexCreationTask<SpatialDoc>
{
public SpatialDoc_ByShapeAndPoint()
{
Map = docs => from spatial in docs
select new
{
Shape = spatial.Shape,
Point = spatial.Point
};
Spatial(x => x.Shape, options => options.Geography.Default());
Spatial(x => x.Point, options => options.Cartesian.BoundingBoxIndex());
}
}
Under criteria
following methods are available:
SpatialCriteria RelatesToShape(object shape, SpatialRelation relation);
SpatialCriteria Intersects(object shape);
SpatialCriteria Contains(object shape);
SpatialCriteria Disjoint(object shape);
SpatialCriteria Within(object shape);
[Obsolete("Order of parameters in this method is inconsistent with the rest of the API (x = longitude, y = latitude). Please use 'WithinRadius'.")]
SpatialCriteria WithinRadiusOf(double radius, double x, double y);
SpatialCriteria WithinRadius(double radius, double latitude, double longitude);
Obsolete method
Since version 3.0.3699-Unstable WithinRadiusOf
method is marked as obsolete because of parameter order inconsistency. Use WithinRadius
instead.
Radius search
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.
IList<Event> results = session
.Query<Event, Events_ByNameAndCoordinates>()
.Customize(x => x
.WithinRadiusOf(
fieldName: "Coordinates",
radius: 10,
latitude: 32.1234,
longitude: 23.4321))
.ToList();
IList<Event> results = session
.Advanced
.DocumentQuery<Event, Events_ByNameAndCoordinates>()
.WithinRadiusOf(
fieldName: "Coordinates",
radius: 10,
latitude: 32.1234,
longitude: 23.4321)
.ToList();
public class Events_ByNameAndCoordinates : AbstractIndexCreationTask<Event>
{
public Events_ByNameAndCoordinates()
{
Map = events => from e in events
select new
{
Name = e.Name,
__ = SpatialGenerate("Coordinates", e.Latitude, e.Longitude)
};
}
}
Advanced search
The WithinRadiusOf
method is a wrapper around RelatesToShape
method.
IDocumentQueryCustomization RelatesToShape(string fieldName, string shapeWKT, SpatialRelation rel);
public enum SpatialRelation
{
Within,
Contains,
Disjoint,
Intersects,
/// <summary>
/// Does not filter the query, merely sort by the distance
/// </summary>
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
IList<Event> results = session
.Query<Event, Events_ByNameAndCoordinates>()
.Customize(x => x.RelatesToShape("Coordinates", "Circle(32.1234 23.4321 d=10.0000)", SpatialRelation.Within))
.ToList();
IList<Event> results = session
.Advanced
.DocumentQuery<Event, Events_ByNameAndCoordinates>()
.RelatesToShape("Coordinates", "Circle(32.1234 23.4321 d=10.0000)", SpatialRelation.Within)
.ToList();
public class Events_ByNameAndCoordinates : AbstractIndexCreationTask<Event>
{
public Events_ByNameAndCoordinates()
{
Map = events => from e in events
select new
{
Name = e.Name,
__ = SpatialGenerate("Coordinates", e.Latitude, e.Longitude)
};
}
}
Warning
Distance in RavenDB by default is measured in kilometers.