Try Playground
Show / Hide Table of Contents

Geo-Spatial API

Note

This feature is available for the NCache Enterprise.

The Distributed Lucene supports indexing the documents with the Geo-Spatial coordinates and later on querying these indexed documents for location-based searching. For this purpose, the Distributed Lucene uses the Spatial4n library.

Prerequisites

  • .NET/.NET Core
  • To learn about the standard prerequisites required to work with all NCache client-side features please refer to the given page on Client Side API Prerequisites.
  • Make sure that you have created and started a Lucene cache through the NCache Management Center or PowerShell.
  • Make sure that your application is not using any native Lucene DLL/Reference.
  • For API details refer to: SpatialDocument, Spatial Strategy, GeohashPrefixTree, RecursivePrefixTreeStrategy, NCacheDirectory, IndexWriterConfig, LuceneVersion, StandardAnalyzer, IndexWriter, SpatialContext, ReadShapeFromWkt, IndexSearcher, IndexReader, DirectoryReader, Class SortField, SortFieldType, SpatialArgs, SpatialOperation, DistanceUtils, MakeCircle, Dist2Degrees, MakeFilter, TopDocs, MatchAllDocsQuery, Dispose.

Spatial Document

The spatial documents are created using the SpatialDocument class. These documents are later used for indexing purposes. This class is specific to the Distributed Lucene.

The SpatialDocument consists of the shapes of the IShape class along with a Document. These shapes will then transform into the indexable fields on the server side via a Strategy. The indexable fields will be added to the Document via IndexWriter.

In the following example, a method for a spatial document is created with the return type of the SpatialDocument class, this method is then used in the next example.

  • .NET/.NET Core
public static SpatialDocument CreateSpatialDocument(int id, SpatialStrategy strategy, params IShape[] shapes)
{
        Document doc = new Document();
        doc.Add(new Int32Field("id", id, Field.Store.YES));

        foreach (IShape shape in shapes)
        {
            IPoint pt = (IPoint)shape;
            doc.Add(new StoredField(strategy.FieldName,
            pt.X.ToString(CultureInfo.InvariantCulture) + " " +
            pt.Y.ToString(CultureInfo.InvariantCulture)));
        }

        return new SpatialDocument()
        {
            Document = doc,
            Shapes = shapes
        };
}

Spatial API Example

The SpatialStrategy class encapsulates an approach to indexing and searching the documents based on the shapes. The Distributed Lucene supports all the spatial strategies supported by the Lucene. The working of the spatial API is the same in both, the Distributed Lucene and the Lucene, except for the concept of a SpatialDocument class that is present in the Distributed Lucene only.

In the following example, spatial documents are defined using the CreateSpatialDocument method created in the earlier example and then added to the IndexWriter with the SpatialStrategy defined. The documents are later searched with the IndexSearcher, and the results are verified afterward.

  • .NET/.NET Core
// Precondition: Lucene cache is already connected
string cache = "luceneCache";
string index = "normalIndex";

IndexReader indexReader = null;
IndexSearcher indexSearcher = null;

// Initialize prefix tree with depth level
var maxLevels = 11;
var grid = new GeohashPrefixTree(SpatialContext.GEO,
maxLevels);

// Define strategy
var strategy = new RecursivePrefixTreeStrategy(grid,
"myGeoField");

// Open NCache directory on index
var directory = NCacheDirectory.Open(cache, index);

// Configure and initalize index writer
var indexWriterConfig = new IndexWriterConfig
(LuceneVersion.LUCENE_48, new StandardAnalyzer
(LuceneVersion.LUCENE_48));
IndexWriter writer = new IndexWriter(directory,
indexWriterConfig);

// Add spatial documents to document with index writer
writer.AddDocument(CreateSpatialDocument(2, strategy,
SpatialContext.GEO.MakePoint(-80.93, 33.77)), strategy);
writer.AddDocument(CreateSpatialDocument(4, strategy,
SpatialContext.GEO.ReadShapeFromWkt("POINT(60.9289094
-50.7693246)")), strategy);
writer.AddDocument(CreateSpatialDocument(20,
strategy, SpatialContext.GEO.MakePoint(0.1, 0.1),
SpatialContext.GEO.MakePoint(0, 0)), strategy);


// Open index reader on directory
indexReader = DirectoryReader.Open(directory);

// Open index searcher on index reader
indexSearcher = new IndexSearcher(indexReader);

// Define sorting strategy
Sort idSort = new Sort(new SortField("id",
SortFieldType.INT32));

// Define spatial arguments
SpatialArgs args = new SpatialArgs(SpatialOperation.
Intersects, SpatialContext.GEO.MakeCircle(-80.0, 33.
0, DistanceUtils.Dist2Degrees(200, DistanceUtils.
EARTH_MEAN_RADIUS_KM)));

// Define the filter with spatial arguments
Filter filter = strategy.MakeFilter(args);

// Search top docs
TopDocs docs = indexSearcher.Search(new
MatchAllDocsQuery(), filter, 10, idSort);

if (indexSearcher != null) indexSearcher.Dispose();
if (indexReader != null) indexReader.Dispose();
Note

Not disposing of the NCacheDirectory, IndexReader, IndexWriter, IndexSearcher, and DirectoryTaxonomyReader will lead to extra memory consumption on the server side.

Additional Resources

NCache also provides a sample application for the Geo-Spatial API in the Distributed Lucene on GitHub

See Also

Distributed Lucene Overview
Distributed Lucene Facets
Searching in Distributed Lucene
Distributed Lucene Indexing

Back to top Copyright © 2017 Alachisoft