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));
            }
예제 #2
0
        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), }));
        }
예제 #3
0
        public SpatialDistanceSortField(string field, bool reverse, SpatialIndexQuery qry)
            : base(field, CUSTOM, reverse)
        {
            var shape = SpatialIndex.ReadShape(qry.QueryShape);

            center = shape.GetCenter();
        }
예제 #4
0
        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), }));
        }
예제 #5
0
        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()));
        }