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.

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)
						};
	}
}

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.