public IList <SearchItem> SearchByLocation(string queryString, double longitude, double latitude, double searchRadiusKm, int maxHits = 10)
        {
            IList <SearchItem> results;

            using (var searcher = new IndexSearcher(Directory, true))
                using (var analyser = new StandardAnalyzer(LuceneVersion))
                {
                    var distance   = DistanceUtils.Dist2Degrees(searchRadiusKm, DistanceUtils.EARTH_MEAN_RADIUS_KM);
                    var searchArea = _spatialContext.MakeCircle(longitude, latitude, distance);

                    var fields = new[] { Name };
                    var parser = new MultiFieldQueryParser(LuceneVersion, fields, analyser);
                    parser.DefaultOperator = QueryParser.Operator.OR; // Allow multiple terms.
                    var query = ParseQuery(queryString, parser);

                    var spatialArgs       = new SpatialArgs(SpatialOperation.Intersects, searchArea);
                    var spatialQuery      = _strategy.MakeQuery(spatialArgs);
                    var valueSource       = _strategy.MakeRecipDistanceValueSource(searchArea);
                    var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1);

                    var filteredSpatial     = new FilteredQuery(query, valueSourceFilter);
                    var spatialRankingQuery = new FunctionQuery(valueSource);

                    BooleanQuery bq = new BooleanQuery();
                    bq.Add(filteredSpatial, Occur.MUST);
                    bq.Add(spatialRankingQuery, Occur.MUST);

                    var hits = searcher.Search(bq, maxHits).ScoreDocs;

                    results = MapResultsToSearchItems(hits, searcher);
                }

            return(results);
        }
예제 #2
0
        public Query MakeQuery(Query existingQuery, SpatialStrategy spatialStrategy, string shapeWKT, SpatialRelation relation,
                               double distanceErrorPct = 0.025, SpatialUnits?unitOverride = null)
        {
            SpatialOperation spatialOperation;
            var shape = ReadShape(shapeWKT, unitOverride);

            switch (relation)
            {
            case SpatialRelation.Within:
                spatialOperation = SpatialOperation.IsWithin;
                break;

            case SpatialRelation.Contains:
                spatialOperation = SpatialOperation.Contains;
                break;

            case SpatialRelation.Disjoint:
                spatialOperation = SpatialOperation.IsDisjointTo;
                break;

            case SpatialRelation.Intersects:
                spatialOperation = SpatialOperation.Intersects;
                break;

            case SpatialRelation.Nearby:
                // only sort by this, do not filter
                return(new FunctionQuery(spatialStrategy.MakeDistanceValueSource(shape.GetCenter())));

            default:
                throw new ArgumentOutOfRangeException("relation");
            }
            var args = new SpatialArgs(spatialOperation, shape)
            {
                DistErrPct = distanceErrorPct
            };

            if (existingQuery is MatchAllDocsQuery)
            {
                return(new CustomScoreQuery(spatialStrategy.MakeQuery(args), new ValueSourceQuery(spatialStrategy.MakeRecipDistanceValueSource(shape))));
            }
            return(spatialStrategy.MakeQuery(args));
        }