private double CalculateDistance(int doc) { var document = currentIndexReader.Document(doc); if (document == null) { return(double.NaN); } var field = document.GetField(Constants.SpatialShapeFieldName); if (field == null) { return(double.NaN); } var shapeAsText = field.StringValue; Shape shape; try { shape = SpatialIndex.ReadShape(shapeAsText); } catch (InvalidOperationException) { return(double.NaN); } var pt = shape as Point; if (pt == null) { pt = shape.GetCenter(); } return(SpatialIndex.Context.GetDistCalc().Distance(pt, originPt)); }
public IEnumerable <IFieldable> SpatialGenerate(string fieldName, string shapeWKT, SpatialSearchStrategy spatialSearchStrategy = SpatialSearchStrategy.GeohashPrefixTree, int maxTreeLevel = 0, double distanceErrorPct = 0.025) { if (string.IsNullOrEmpty(shapeWKT)) { return(Enumerable.Empty <IFieldable>()); } if (maxTreeLevel == 0) { switch (spatialSearchStrategy) { case SpatialSearchStrategy.GeohashPrefixTree: maxTreeLevel = 9; // about 2 meters, should be good enough (see: http://unterbahn.com/2009/11/metric-dimensions-of-geohash-partitions-at-the-equator/) break; case SpatialSearchStrategy.QuadPrefixTree: maxTreeLevel = 25; // about 1 meter, should be good enough break; default: throw new ArgumentOutOfRangeException("spatialSearchStrategy"); } } var strategy = SpatialStrategies.GetOrAdd(fieldName, s => SpatialIndex.CreateStrategy(fieldName, spatialSearchStrategy, maxTreeLevel)); var shape = SpatialIndex.ReadShape(shapeWKT); return(strategy.CreateIndexableFields(shape) .Concat(new[] { new Field(Constants.SpatialShapeFieldName, SpatialIndex.WriteShape(shape), Field.Store.YES, Field.Index.NO), })); }
public SpatialDistanceSortField(string field, bool reverse, SpatialIndexQuery qry) : base(field, CUSTOM, reverse) { var shape = SpatialIndex.ReadShape(qry.QueryShape); center = shape.GetCenter(); }
public IEnumerable <IFieldable> SpatialGenerate(string fieldName, string shapeWKT, SpatialSearchStrategy spatialSearchStrategy = SpatialSearchStrategy.GeohashPrefixTree, int maxTreeLevel = 0, double distanceErrorPct = 0.025) { if (maxTreeLevel == 0) { maxTreeLevel = GeohashPrefixTree.GetMaxLevelsPossible(); } var strategy = SpatialStrategies.GetOrAdd(fieldName, s => SpatialIndex.CreateStrategy(fieldName, spatialSearchStrategy, maxTreeLevel)); var shape = SpatialIndex.ReadShape(shapeWKT); return(strategy.CreateIndexableFields(shape) .Concat(new[] { new Field(Constants.SpatialShapeFieldName, SpatialIndex.WriteShape(shape), Field.Store.YES, Field.Index.NO), })); }
public static Sort GetSort(this IndexQuery self, IndexDefinition indexDefinition) { var spatialQuery = self as SpatialIndexQuery; var sortedFields = self.SortedFields; if (sortedFields == null || sortedFields.Length <= 0) { if (spatialQuery == null || string.IsNullOrEmpty(self.Query) == false) { return(null); } sortedFields = new[] { new SortedField(Constants.DistanceFieldName), }; } return(new Sort(sortedFields .Select(sortedField => { if (sortedField.Field == Constants.TemporaryScoreValue) { return SortField.FIELD_SCORE; } if (sortedField.Field.StartsWith(Constants.RandomFieldName)) { var parts = sortedField.Field.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 2) // truly random { return new RandomSortField(Guid.NewGuid().ToString()); } return new RandomSortField(parts[1]); } if (spatialQuery != null && sortedField.Field == Constants.DistanceFieldName) { var shape = SpatialIndex.ReadShape(spatialQuery.QueryShape); var dsort = new SpatialDistanceFieldComparatorSource(shape.GetCenter()); return new SortField(Constants.DistanceFieldName, dsort, sortedField.Descending); } var sortOptions = GetSortOption(indexDefinition, sortedField.Field); if (sortOptions == null || sortOptions == SortOptions.None) { return new SortField(sortedField.Field, CultureInfo.InvariantCulture, sortedField.Descending); } return new SortField(sortedField.Field, (int)sortOptions.Value, sortedField.Descending); }) .ToArray())); }