public override ConstantScoreQuery MakeQuery(SpatialArgs args) { if (!SpatialOperation.Is(args.Operation, SpatialOperation.Intersects, SpatialOperation.IsWithin)) { throw new UnsupportedSpatialOperation(args.Operation); } IShape shape = args.Shape; if (shape is IRectangle) { var bbox = (IRectangle)shape; return(new ConstantScoreQuery(MakeWithin(bbox))); } else if (shape is ICircle) { var circle = (ICircle)shape; var bbox = circle.BoundingBox; var vsf = new ValueSourceFilter( new QueryWrapperFilter(MakeWithin(bbox)), MakeDistanceValueSource(circle.Center), 0, circle.Radius); return(new ConstantScoreQuery(vsf)); } throw new NotSupportedException("Only IRectangles and ICircles are currently supported, " + "found [" + shape.GetType().Name + "]"); //TODO }
public virtual void TestInvalidQueryShape() { IPoint point = ctx.MakePoint(0, 0); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, point); Assert.Throws <NotSupportedException>(() => this.strategy.MakeQuery(args)); }
protected virtual Lucene.Net.Search.Query VisitWithinRadius(WithinRadiusNode node, LuceneQueryMapperState mappingState) { SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); if (node.Latitude is double && node.Longitude is double && node.Radius is double) { var distance = DistanceUtils.Dist2Degrees((double)node.Radius, DistanceUtils.EARTH_MEAN_RADIUS_MI); Circle circle = ctx.MakeCircle((double)node.Longitude, (double)node.Latitude, distance); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, circle); var dq = strategy.MakeQuery(spatialArgs); DistanceReverseValueSource valueSource = new DistanceReverseValueSource(strategy, circle.GetCenter(), distance); ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(dq), valueSource, 0, distance); var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf); Lucene.Net.Search.Query spatialRankingQuery = new FunctionQuery(valueSource); BooleanQuery bq = new BooleanQuery(); bq.Add(filteredSpatial, Occur.MUST); bq.Add(spatialRankingQuery, Occur.MUST); return(bq); } throw new NotSupportedException("Wrong parameters type, Radius, latitude and longitude must be of type double"); }
public void CalcDistanceFromErrPct() { SpatialContext ctx = SpatialContext.Geo; double DEP = 0.5;//distErrPct //the result is the diagonal distance from the center to the closest corner, // times distErrPct IShape superwide = ctx.MakeRectangle(-180, 180, 0, 0); // LUCENENET specific: Added delta to the first 3 asserts because it is not a // valid expectation that they are exactly on the nose when dealing with floating point // types. And in .NET Core 2.0, the implementation has changed which now makes this test // fail without delta. //0 distErrPct means 0 distance always assertEquals(0, SpatialArgs.CalcDistanceFromErrPct(superwide, 0, ctx), 0.0001); assertEquals(180 * DEP, SpatialArgs.CalcDistanceFromErrPct(superwide, DEP, ctx), 0.0001); IShape supertall = ctx.MakeRectangle(0, 0, -90, 90); assertEquals(90 * DEP, SpatialArgs.CalcDistanceFromErrPct(supertall, DEP, ctx), 0.0001); IShape upperhalf = ctx.MakeRectangle(-180, 180, 0, 90); assertEquals(45 * DEP, SpatialArgs.CalcDistanceFromErrPct(upperhalf, DEP, ctx), 0.0001); IShape midCircle = ctx.MakeCircle(0, 0, 45); assertEquals(60 * DEP, SpatialArgs.CalcDistanceFromErrPct(midCircle, DEP, ctx), 0.0001); }
// private Rectangle inset(Rectangle r) { // //typically inset by 1 (whole numbers are easy to read) // double d = Math.min(1.0, grid.getDistanceForLevel(grid.getMaxLevels()) / 4); // return ctx.makeRectangle(r.getMinX() + d, r.getMaxX() - d, r.getMinY() + d, r.getMaxY() - d); // } protected IShape gridSnap(IShape snapMe) { if (snapMe == null) { return(null); } if (snapMe is ShapePair) { ShapePair me = (ShapePair)snapMe; return(new ShapePair(gridSnap(me.shape1), gridSnap(me.shape2), me.biasContainsThenWithin, ctx)); } if (snapMe is IPoint) { snapMe = snapMe.BoundingBox; } //The next 4 lines mimic PrefixTreeStrategy.createIndexableFields() double distErrPct = ((PrefixTreeStrategy)strategy).DistErrPct; double distErr = SpatialArgs.CalcDistanceFromErrPct(snapMe, distErrPct, ctx); int detailLevel = grid.GetLevelForDistance(distErr); IList <Cell> cells = grid.GetCells(snapMe, detailLevel, false, true); //calc bounding box of cells. List <IShape> cellShapes = new List <IShape>(cells.size()); foreach (Cell cell in cells) { cellShapes.Add(cell.Shape); } return(new ShapeCollection(cellShapes, ctx).BoundingBox); }
private SpatialArgs GetArgs(int docId, int distanceInKms) { Document doc; int index = docId; //we may land at a document that has no spatial field. In which case we keep increasing the index until we find one that does have a spatial field. do { doc = base.indexSearcher.IndexReader.Document(index % indexSearcher.MaxDoc, null); index++; } while (doc.GetField(StrategyPrefix) == null); SpatialContext ctx = _spatialStrategy.GetSpatialContext(); string[] parts = doc.Get(StrategyPrefix, null) .Split(' '); Point pt = ctx.MakePoint(double.Parse(parts[0]), double.Parse(parts[1])); Circle circle = ctx.MakeCircle(pt, DistanceUtils.Dist2Degrees(distanceInKms, DistanceUtils.EARTH_MEAN_RADIUS_KM)); var args = new SpatialArgs(SpatialOperation.Intersects, circle); return(args); }
public void CalcDistanceFromErrPct() { SpatialContext ctx = SpatialContext.GEO; double DEP = 0.5;//distErrPct //the result is the diagonal distance from the center to the closest corner, // times distErrPct IShape superwide = ctx.MakeRectangle(-180, 180, 0, 0); //0 distErrPct means 0 distance always assertEquals(0, SpatialArgs.CalcDistanceFromErrPct(superwide, 0, ctx), 0); assertEquals(180 * DEP, SpatialArgs.CalcDistanceFromErrPct(superwide, DEP, ctx), 0); IShape supertall = ctx.MakeRectangle(0, 0, -90, 90); assertEquals(90 * DEP, SpatialArgs.CalcDistanceFromErrPct(supertall, DEP, ctx), 0); IShape upperhalf = ctx.MakeRectangle(-180, 180, 0, 90); assertEquals(45 * DEP, SpatialArgs.CalcDistanceFromErrPct(upperhalf, DEP, ctx), 0.0001); IShape midCircle = ctx.MakeCircle(0, 0, 45); assertEquals(60 * DEP, SpatialArgs.CalcDistanceFromErrPct(midCircle, DEP, ctx), 0.0001); }
public override ConstantScoreQuery MakeQuery(SpatialArgs args) { if (!SpatialOperation.Is(args.Operation, SpatialOperation.Intersects, SpatialOperation.IsWithin)) { throw new UnsupportedSpatialOperation(args.Operation); } Shape shape = args.Shape; var bbox = shape as Rectangle; if (bbox != null) { return(new ConstantScoreQuery(new QueryWrapperFilter(MakeWithin(bbox)))); } var circle = shape as Circle; if (circle != null) { bbox = circle.GetBoundingBox(); var vsf = new ValueSourceFilter( new QueryWrapperFilter(MakeWithin(bbox)), MakeDistanceValueSource(circle.GetCenter()), 0, circle.GetRadius()); return(new ConstantScoreQuery(vsf)); } throw new InvalidOperationException("Only Rectangles and Circles are currently supported, " + "found [" + shape.GetType().Name + "]"); //TODO }
public void testInvalidQueryShape() { Point point = ctx.MakePoint(0, 0); var args = new SpatialArgs(SpatialOperation.Intersects, point); Assert.Throws <InvalidOperationException>(() => this.strategy.MakeQuery(args)); }
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); }
protected virtual Lucene.Net.Search.Query VisitWithinRadius(WithinRadiusNode node, LuceneQueryMapperState mappingState) { SpatialContext ctx = SpatialContext.GEO; var strategy = new PointVectorStrategy(ctx, Sitecore.ContentSearch.Spatial.Common.Constants.LocationFieldName); if (node.Latitude is double && node.Longitude is double && node.Radius is double) { var distance = DistanceUtils.Dist2Degrees((double)node.Radius, DistanceUtils.EARTH_MEAN_RADIUS_MI); Circle circle = ctx.MakeCircle((double)node.Longitude, (double)node.Latitude, distance); var spatialArgs = new SpatialArgs(SpatialOperation.IsWithin, circle); var dq = strategy.MakeQuery(spatialArgs); DistanceReverseValueSource valueSource = new DistanceReverseValueSource(strategy, circle.GetCenter(), distance); ValueSourceFilter vsf = new ValueSourceFilter(new QueryWrapperFilter(dq), valueSource, 0, distance); var filteredSpatial = new FilteredQuery(new MatchAllDocsQuery(), vsf); mappingState.FilterQuery = filteredSpatial; Lucene.Net.Search.Query spatialRankingQuery = new FunctionQuery(valueSource); Random r = new Random(DateTime.Now.Millisecond); var randomNumber = r.Next(10000101, 11000101); Lucene.Net.Search.Query dummyQuery = Lucene.Net.Search.NumericRangeQuery.NewIntRange("__smallcreateddate", randomNumber, Int32.Parse(DateTime.Now.ToString("yyyyMMdd")), true, true); BooleanQuery bq = new BooleanQuery(); bq.Add(filteredSpatial, Occur.MUST); bq.Add(spatialRankingQuery, Occur.MUST); bq.Add(dummyQuery, Occur.SHOULD); return(bq); } throw new NotSupportedException("Wrong parameters type, Radius, latitude and longitude must be of type double"); }
public override Filter MakeFilter(SpatialArgs args) { SpatialOperation op = args.Operation; if (op == SpatialOperation.IsDisjointTo) { return(new DisjointSpatialFilter(this, args, FieldName)); } Shape shape = args.Shape; int detailLevel = grid.GetLevelForDistance(args.ResolveDistErr(ctx, distErrPct)); bool hasIndexedLeaves = true; if (op == SpatialOperation.Intersects) { return(new IntersectsPrefixTreeFilter(shape, FieldName, grid, detailLevel, prefixGridScanLevel , hasIndexedLeaves)); } else { if (op == SpatialOperation.IsWithin) { return(new WithinPrefixTreeFilter(shape, FieldName, grid, detailLevel, prefixGridScanLevel , -1)); } else { //-1 flag is slower but ensures correct results if (op == SpatialOperation.Contains) { return(new ContainsPrefixTreeFilter(shape, FieldName, grid, detailLevel)); } } } throw new UnsupportedSpatialOperation(op); }
protected virtual Query MakeQueryFromShape(IShape shape) { SpatialArgs args = new SpatialArgs(m_operation, shape); if (!double.IsNaN(m_distErrPct)) { args.DistErrPct = m_distErrPct; } if (m_score) { ValueSource valueSource = m_strategy.MakeDistanceValueSource(shape.Center); return(new CustomScoreQuery(m_strategy.MakeQuery(args), new FunctionQuery(valueSource))); } else { //strategy.makeQuery() could potentially score (isn't well defined) so instead we call // makeFilter() and wrap Filter filter = m_strategy.MakeFilter(args); if (filter is QueryWrapperFilter queryWrapperFilter) { return(queryWrapperFilter.Query); } else { return(new ConstantScoreQuery(filter)); } } }
public override Filter MakeFilter(SpatialArgs args) { SpatialOperation op = args.Operation; if (op == SpatialOperation.IsDisjointTo) { return(new DisjointSpatialFilter(this, args, FieldName)); } IShape shape = args.Shape; int detailLevel = m_grid.GetLevelForDistance(args.ResolveDistErr(m_ctx, m_distErrPct)); if (m_pointsOnly || op == SpatialOperation.Intersects) { return(new IntersectsPrefixTreeFilter( shape, FieldName, m_grid, detailLevel, prefixGridScanLevel, !m_pointsOnly)); } else if (op == SpatialOperation.IsWithin) { return(new WithinPrefixTreeFilter( shape, FieldName, m_grid, detailLevel, prefixGridScanLevel, -1)); //-1 flag is slower but ensures correct results } else if (op == SpatialOperation.Contains) { return(new ContainsPrefixTreeFilter(shape, FieldName, m_grid, detailLevel, m_multiOverlappingIndexedShapes)); } throw new UnsupportedSpatialOperation(op); }
public override Field[] CreateIndexableFields(Shape shape ) { double distErr = SpatialArgs.CalcDistanceFromErrPct(shape, distErrPct, ctx); return(CreateIndexableFields(shape, distErr)); }
public void PureLucene() { using (var dir = new RAMDirectory()) { using (var keywordAnalyzer = new KeywordAnalyzer()) using (var writer = new IndexWriter(dir, keywordAnalyzer, true, IndexWriter.MaxFieldLength.UNLIMITED)) { var doc = new Lucene.Net.Documents.Document(); var writeShape = NtsSpatialContext.GEO.ReadShape("LINESTRING (0 0, 1 1, 2 1)"); var writeStrategy = SpatialIndex.CreateStrategy("WKT", SpatialSearchStrategy.GeohashPrefixTree, GeohashPrefixTree.GetMaxLevelsPossible()); foreach (var f in writeStrategy.CreateIndexableFields(writeShape)) { doc.Add(f); } writer.AddDocument(doc); writer.Commit(); } var shape = NtsSpatialContext.GEO.ReadShape("LINESTRING (1 0, 1 1, 1 2)"); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape); var strategy = SpatialIndex.CreateStrategy("WKT", SpatialSearchStrategy.GeohashPrefixTree, GeohashPrefixTree.GetMaxLevelsPossible()); var makeQuery = strategy.MakeQuery(args); using (var search = new IndexSearcher(dir)) { var topDocs = search.Search(makeQuery, 5); Assert.Equal(1, topDocs.TotalHits); } } }
private void DoSpatialSearch( SpatialContext ctx, SpatialStrategy strategy, TestIndex indexer, double searchRadius, string idToMatch, Func <SpatialArgs, Query> createQuery, int lat, int lng) { var searcher = (LuceneSearcher)indexer.GetSearcher(); var luceneSearcher = searcher.GetLuceneSearcher(); GetXYFromCoords(lat, lng, out var x, out var y); // Make a circle around the search point var args = new SpatialArgs( SpatialOperation.Intersects, ctx.MakeCircle(x, y, DistanceUtils.Dist2Degrees(searchRadius, DistanceUtils.EARTH_MEAN_RADIUS_KM))); var filter = strategy.MakeFilter(args); var query = createQuery(args); // TODO: It doesn't make a whole lot of sense to sort by score when searching on only geo-coords, // typically you would sort by closest distance // Which can be done, see https://github.com/apache/lucene-solr/blob/branch_4x/lucene/spatial/src/test/org/apache/lucene/spatial/SpatialExample.java#L169 TopDocs docs = luceneSearcher.Search(query, filter, MaxResultDocs, new Sort(new SortField(null, SortField.SCORE))); AssertDocMatchedIds(luceneSearcher, docs, idToMatch); // TODO: We should make this possible and allow passing in a Lucene Filter // to the LuceneSearchQuery along with the Lucene Query, then we // don't need to manually perform the Lucene Search //var criteria = (LuceneSearchQuery)searcher.CreateQuery(); //criteria.LuceneQuery(q); //var results = criteria.Execute(); }
public override Filter MakeFilter(SpatialArgs args) { // LUCENENET specific - added guard clause if (args is null) { throw new ArgumentNullException(nameof(args)); } SpatialOperation op = args.Operation; if (op != SpatialOperation.Intersects) { throw new UnsupportedSpatialOperationException(op); } IShape shape = args.Shape; int detailLevel = m_grid.GetLevelForDistance(args.ResolveDistErr(m_ctx, m_distErrPct)); IList <Cell> cells = m_grid.GetCells(shape, detailLevel, false /*no parents*/, true /*simplify*/); var terms = new BytesRef[cells.Count]; int i = 0; foreach (Cell cell in cells) { terms[i++] = new BytesRef(cell.TokenString);//TODO use cell.getTokenBytes() } return(new TermsFilter(FieldName, terms)); }
private SpatialArgs q(Point pt, double dist, double distErrPct = 0.0) { Shape shape = ctx.MakeCircle(pt, dist); var args = new SpatialArgs(SpatialOperation.Intersects, shape); args.DistErrPct = distErrPct; return(args); }
public static Filter MakeFilter(IndexQuery indexQuery) { var spatialQry = indexQuery as SpatialIndexQuery; if (spatialQry == null) return null; var args = new SpatialArgs(SpatialOperation.IsWithin, RavenSpatialContext.MakeCircle(spatialQry.Longitude, spatialQry.Latitude, spatialQry.Radius)); return strategy.MakeFilter(args, fieldInfo); }
public void testCircleShapeSupport() { Circle circle = ctx.MakeCircle(ctx.MakePoint(0, 0), 10); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle); Query query = this.strategy.MakeQuery(args); Assert.NotNull(query); }
private SpatialArgs q(Spatial4n.Core.Shapes.IPoint pt, double distDEG, double distErrPct) { IShape shape = ctx.MakeCircle(pt, distDEG); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape); args.DistErrPct = (distErrPct); return(args); }
/// <summary> /// Returns a <see cref="Filter"/> that should be used with <see cref="FilteredQuery.QUERY_FIRST_FILTER_STRATEGY"/>. /// Use in another manner is likely to result in an <see cref="NotSupportedException"/> /// to prevent misuse because the filter can't efficiently work via iteration. /// </summary> public override Filter MakeFilter(SpatialArgs args) { ValueSource shapeValueSource = MakeShapeValueSource(); ShapePredicateValueSource predicateValueSource = new ShapePredicateValueSource( shapeValueSource, args.Operation, args.Shape); return(new PredicateValueSourceFilter(predicateValueSource)); }
private SpatialArgs q(String shapeStr, double distErrPct) { IShape shape = ctx.ReadShapeFromWkt(shapeStr); SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, shape); args.DistErrPct = (distErrPct); return(args); }
/// <summary> /// Returns distance of the document in km from the query target /// </summary> /// <param name="doc">Document</param> /// <param name="args">SpatialArgs data</param> /// <returns></returns> internal double DocumentDistance(Document doc, SpatialArgs args) { var dt = doc.Get(spatialStrategy.FieldName); var docPoint = (Point)SpatialContext.ReadShapeFromWkt(dt); double docDistDEG = SpatialContext.CalcDistance(args.Shape.Center, docPoint); double docDistInKM = DistanceUtils.Degrees2Dist(docDistDEG, DistanceUtils.EARTH_EQUATORIAL_RADIUS_KM); return(docDistInKM); }
private void TestEqualsHashcode(SpatialStrategy strategy) { SpatialArgs args1 = MakeArgs1(); SpatialArgs args2 = MakeArgs2(); TestEqualsHashcode(args1, args2, new ObjGeneratorQueryAnonymousClass(strategy)); TestEqualsHashcode(args1, args2, new ObjGeneratorFilterAnonymousClass(strategy)); TestEqualsHashcode(args1, args2, new ObjGeneratorDistanceValueSourceAnonymousClass(strategy)); }
public Filter ToFilter(SpatialContext spatialContext, SpatialPrefixTree tree) { var strategy = new RecursivePrefixTreeStrategy(tree, GeoFieldName); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, spatialContext.MakeCircle(X, Y, DistanceUtils.Dist2Degrees(this.Distance, DistanceUtils.EARTH_MEAN_RADIUS_KM))); return(strategy.MakeFilter(spatialArgs)); }
public Filter ToFilter(SpatialContext spatialContext, SpatialPrefixTree tree) { var strategy = new RecursivePrefixTreeStrategy(tree, GeoFieldName); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, spatialContext.MakeRectangle(this.MinX, this.MaxX, this.MinY, this.MaxY)); return(strategy.MakeFilter(spatialArgs)); }
/// <param name="strategy">Needed to compute intersects</param> /// <param name="args">Used in spatial intersection</param> /// <param name="field"> /// This field is used to determine which docs have spatial data via /// <see cref="IFieldCache.GetDocsWithField(AtomicReader, string)"/>. /// Passing null will assume all docs have spatial data. /// </param> public DisjointSpatialFilter(SpatialStrategy strategy, SpatialArgs args, string field) { this.field = field; // TODO consider making SpatialArgs cloneable SpatialOperation origOp = args.Operation; //copy so we can restore args.Operation = SpatialOperation.Intersects; //temporarily set to intersects intersectsFilter = strategy.MakeFilter(args); args.Operation = origOp; }
public Filter ToFilter(SpatialContext spatialContext, SpatialPrefixTree tree) { var strategy = new RecursivePrefixTreeStrategy(tree, GeoFieldName); var spatialArgs = new SpatialArgs(SpatialOperation.Intersects, spatialContext.MakeBufferedLineString( this.Points.Select(p => (IPoint) new Point(p[0], p[1], spatialContext)).ToList(), DistanceUtils.Dist2Degrees(this.Distance, DistanceUtils.EARTH_MEAN_RADIUS_KM))); return(strategy.MakeFilter(spatialArgs)); }
private Query MakeSpatialQuery(SpatialArgs args) { var bbox = args.Shape as Rectangle; if (bbox == null) { throw new InvalidOperationException("Can only query by Rectangle, not " + args.Shape); } Query spatial = null; // Useful for understanding Relations: // http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm SpatialOperation op = args.Operation; if (op == SpatialOperation.BBoxIntersects) { spatial = MakeIntersects(bbox); } else if (op == SpatialOperation.BBoxWithin) { spatial = MakeWithin(bbox); } else if (op == SpatialOperation.Contains) { spatial = MakeContains(bbox); } else if (op == SpatialOperation.Intersects) { spatial = MakeIntersects(bbox); } else if (op == SpatialOperation.IsEqualTo) { spatial = MakeEquals(bbox); } else if (op == SpatialOperation.IsDisjointTo) { spatial = MakeDisjoint(bbox); } else if (op == SpatialOperation.IsWithin) { spatial = MakeWithin(bbox); } else if (op == SpatialOperation.Overlaps) { spatial = MakeIntersects(bbox); } else { throw new UnsupportedSpatialOperation(op); } return(spatial); }
public void CheckIfSortingCorrectly() { // Origin const double lat = 38.96939; const double lng = -77.386398; var radius = ctx.GetUnits().Convert(6.0, DistanceUnits.MILES); AddPoint(_writer, "c/1", 38.9579000, -77.3572000); // 1.76 Miles away AddPoint(_writer, "a/2", 38.9690000, -77.3862000); // 0.03 Miles away AddPoint(_writer, "b/3", 38.9510000, -77.4107000); // 1.82 Miles away _writer.Commit(); _writer.Close(); _searcher = new IndexSearcher(_directory, true); // create a distance query var args = new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(lng, lat, radius)); var vs = strategy.MakeValueSource(args, fieldInfo); var vals = vs.GetValues(_searcher.IndexReader); args.SetDistPrecision(0.0); var dq = strategy.MakeQuery(args, fieldInfo); Console.WriteLine(dq); TopDocs hits = _searcher.Search(dq, null, 1000, new Sort(new SortField("distance", SortField.SCORE, true))); var results = hits.TotalHits; Assert.AreEqual(3, results); var expectedOrder = new[] {"a/2", "c/1", "b/3"}; for (int i = 0; i < hits.TotalHits; i++) { Assert.AreEqual(expectedOrder[i], _searcher.Doc(hits.ScoreDocs[i].Doc).GetField("name").StringValue); } }
public void LUCENENET462() { Console.WriteLine("LUCENENET462"); // Origin const double _lat = 51.508129; const double _lng = -0.128005; // Locations AddPoint(_writer, "Location 1", 51.5073802128877, -0.124669075012207); AddPoint(_writer, "Location 2", 51.5091, -0.1235); AddPoint(_writer, "Location 3", 51.5093, -0.1232); AddPoint(_writer, "Location 4", 51.5112531582845, -0.12509822845459); AddPoint(_writer, "Location 5", 51.5107, -0.123); AddPoint(_writer, "Location 6", 51.512, -0.1246); AddPoint(_writer, "Location 8", 51.5088760101322, -0.143165588378906); AddPoint(_writer, "Location 9", 51.5087958793819, -0.143508911132813); _writer.Commit(); _writer.Close(); _searcher = new IndexSearcher(_directory, true); // create a distance query var radius = ctx.GetUnits().Convert(2.0, DistanceUnits.MILES); var dq = strategy.MakeQuery(new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(_lng, _lat, radius)), fieldInfo); Console.WriteLine(dq); //var dsort = new DistanceFieldComparatorSource(dq.DistanceFilter); //Sort sort = new Sort(new SortField("foo", dsort, false)); // Perform the search, using the term query, the distance filter, and the // distance sort TopDocs hits = _searcher.Search(dq, 1000); var results = hits.TotalHits; Assert.AreEqual(8, results); radius = ctx.GetUnits().Convert(1.0, DistanceUnits.MILES); var spatialArgs = new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(_lng, _lat, radius)); dq = strategy.MakeQuery(spatialArgs, fieldInfo); Console.WriteLine(dq); //var dsort = new DistanceFieldComparatorSource(dq.DistanceFilter); //Sort sort = new Sort(new SortField("foo", dsort, false)); // Perform the search, using the term query, the distance filter, and the // distance sort hits = _searcher.Search(dq, 1000); results = hits.TotalHits; Assert.AreEqual(8, results); _searcher.Close(); _directory.Close(); }