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 = spatialField.ReadShape(shapeAsText);
                }
                catch (InvalidOperationException)
                {
                    return(double.NaN);
                }
                var pt = shape as Point;

                if (pt == null)
                {
                    pt = shape.GetCenter();
                }
                return(spatialField.GetContext().GetDistCalc().Distance(pt, originPt));
            }
Exemple #2
0
        internal static IEnumerable <AbstractField> CreateSpatialField(SpatialField spatialField, double?lat, double?lng)
        {
            if (lng == null || double.IsNaN(lng.Value))
            {
                return(Enumerable.Empty <AbstractField>());
            }
            if (lat == null || double.IsNaN(lat.Value))
            {
                return(Enumerable.Empty <AbstractField>());
            }

            Shape shape = spatialField.GetContext().MakePoint(lng.Value, lat.Value);

            return(spatialField.CreateIndexableFields(shape));
        }
Exemple #3
0
        public static Sort GetSort(this IndexQuery self, IndexDefinition indexDefinition, AbstractViewGenerator viewGenerator)
        {
            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 (sortedField.Field.StartsWith(Constants.CustomSortFieldName))
                {
                    var parts = sortedField.Field.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length < 2)                 // truly random
                    {
                        throw new InvalidOperationException("Cannot figure out type for custom sort");
                    }
                    return new CustomSortField(parts[1], self, parts[0][parts[0].Length - 1] == '-');
                }
                if (sortedField.Field.StartsWith(Constants.DistanceFieldName))
                {
                    SpatialField spatialField = null;
                    Shape shape;

                    if (sortedField.Field.Length == Constants.DistanceFieldName.Length)
                    {
                        if (spatialQuery == null)
                        {
                            throw new InvalidOperationException("Illegal Spatial Sort Parameter: Blank Spatial sort cannot be used without a spatial query");
                        }

                        spatialField = viewGenerator.GetSpatialField(spatialQuery.SpatialFieldName);

                        shape = spatialField.ReadShape(spatialQuery.QueryShape);
                    }
                    else
                    {
                        var sortParams = sortedField.Field.Split(';');
                        double lat, lng;

                        if (sortParams.Length < 3 || !double.TryParse(sortParams[1], out lat) || !double.TryParse(sortParams[2], out lng))
                        {
                            throw new InvalidOperationException("Illegal Spatial Sort Parameter");
                        }


                        string spatialFieldName;

                        if (sortParams.Length >= 4)
                        {
                            spatialFieldName = sortParams[3];
                        }
                        else
                        {
                            if (spatialQuery == null)
                            {
                                spatialFieldName = Constants.DefaultSpatialFieldName;
                            }
                            else
                            {
                                spatialFieldName = spatialQuery.SpatialFieldName;
                            }
                        }

                        spatialField = viewGenerator.GetSpatialField(spatialFieldName);

                        shape = new PointImpl(lng, lat, spatialField.GetContext());
                    }
                    var dsort = new SpatialDistanceFieldComparatorSource(spatialField, shape.GetCenter());
                    return new SortField(sortedField.Field, dsort, sortedField.Descending);
                }
                var sortOptions = GetSortOption(indexDefinition, sortedField.Field, self);

                if (sortOptions == null || sortOptions == SortOptions.None)
                {
                    return new SortField(sortedField.Field, CultureInfo.InvariantCulture, sortedField.Descending);
                }

                if (sortOptions.Value == SortOptions.Short)
                {
                    sortOptions = SortOptions.Int;
                }
                return new SortField(sortedField.Field, (int)sortOptions.Value, sortedField.Descending);
            })
                            .ToArray()));
        }