Example #1
0
        private void GenerateRandomDocs(Random rng, int numDocs)
        {
            SpatialContext ctx = _spatialStrategy.GetSpatialContext();

            base.addDocumentsAndCommit(Enumerable.Range(1, numDocs)
                                       .Select(a => CreateRandomDoc(a, rng, ctx)).ToList());
        }
Example #2
0
        private void RunTest(SpatialContext ctx, SpatialStrategy strategy, Func <SpatialArgs, Query> createQuery)
        {
            var analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);

            using (var luceneDir = new RandomIdRAMDirectory())
            {
                string id1 = 1.ToString();
                string id2 = 2.ToString();
                string id3 = 3.ToString();
                string id4 = 4.ToString();

                using (var indexer = new TestIndex(luceneDir, analyzer))
                {
                    indexer.DocumentWriting += (sender, args) => Indexer_DocumentWriting(args, ctx, strategy);

                    indexer.IndexItems(new[] {
                        ValueSet.FromObject(id1, "content",
                                            new { nodeName = "location 1", bodyText = "Zanzibar is in Africa", lat = -6.1357, lng = 39.3621 }),
                        ValueSet.FromObject(id2, "content",
                                            new { nodeName = "location 2", bodyText = "In Canada there is a town called Sydney in Nova Scotia", lat = 46.1368, lng = -60.1942 }),
                        ValueSet.FromObject(id3, "content",
                                            new { nodeName = "location 3", bodyText = "Sydney is the capital of NSW in Australia", lat = -33.8688, lng = 151.2093 }),
                        ValueSet.FromObject(id4, "content",
                                            new { nodeName = "location 4", bodyText = "Somewhere unknown", lat = 50, lng = 50 })
                    });

                    DoSpatialSearch(ctx, strategy, indexer, SearchRadius, id3, createQuery, lat: -33, lng: 151);
                    DoSpatialSearch(ctx, strategy, indexer, SearchRadius, id2, createQuery, lat: 46, lng: -60);
                    DoSpatialSearch(ctx, strategy, indexer, SearchRadius, id1, createQuery, lat: -6, lng: 39);
                    DoSpatialSearch(ctx, strategy, indexer, SearchRadius, id4, createQuery, lat: 50, lng: 50);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Computes the distance given a shape and the <paramref name="distErrPct"/>.  The
        /// algorithm is the fraction of the distance from the center of the query
        /// shape to its furthest bounding box corner.
        /// </summary>
        /// <param name="shape">Mandatory.</param>
        /// <param name="distErrPct">0 to 0.5</param>
        /// <param name="ctx">Mandatory</param>
        /// <returns>A distance (in degrees).</returns>
        public static double CalcDistanceFromErrPct(IShape shape, double distErrPct, SpatialContext ctx)
        {
            // LUCENENET: Added null guard clauses
            if (shape is null)
            {
                throw new ArgumentNullException(nameof(shape));
            }
            if (ctx is null)
            {
                throw new ArgumentNullException(nameof(ctx));
            }

            if (distErrPct < 0 || distErrPct > 0.5)
            {
                throw new ArgumentOutOfRangeException(nameof(distErrPct), $"distErrPct {distErrPct} must be between [0 to 0.5]", nameof(distErrPct));// LUCENENET specific - changed from IllegalArgumentException to ArgumentOutOfRangeException (.NET convention)
            }
            if (distErrPct == 0 || shape is IPoint)
            {
                return(0);
            }
            IRectangle bbox = shape.BoundingBox;

            //Compute the distance from the center to a corner.  Because the distance
            // to a bottom corner vs a top corner can vary in a geospatial scenario,
            // take the closest one (greater precision).
            IPoint ctr          = bbox.Center;
            double y            = (ctr.Y >= 0 ? bbox.MaxY : bbox.MinY);
            double diagonalDist = ctx.DistanceCalculator.Distance(ctr, bbox.MaxX, y);

            return(diagonalDist * distErrPct);
        }
Example #4
0
        public void testNGramPrefixGridLosAngeles()
        {
            SpatialContext ctx = SpatialContext.GEO;
            TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");

            Shape point = ctx.MakePoint(-118.243680, 34.052230);

            Document losAngeles = new Document();

            losAngeles.Add(new Field("name", "Los Angeles", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
            foreach (var indexableField in prefixGridStrategy.CreateIndexableFields(point))
            {
                losAngeles.Add(indexableField);
            }
            losAngeles.Add(new Field(prefixGridStrategy.GetFieldName(), ctx.ToString(point), Field.Store.YES, Field.Index.NO));

            addDocumentsAndCommit(new List <Document> {
                losAngeles
            });

            // This won't work with simple spatial context...
            SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
            // TODO... use a non polygon query
            //    SpatialArgs spatialArgs = spatialArgsParser.parse(
            //        "Intersects(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
            //        new SimpleSpatialContext());

            //    Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);
            //    SearchResults searchResults = executeQuery(query, 1);
            //    assertEquals(1, searchResults.numFound);
        }
Example #5
0
        /// <summary>
        /// WARNING: geoms is copied by reference.
        /// </summary>
        /// <param name="geoms"></param>
        /// <param name="ctx"></param>
        public MultiShape(IEnumerable <Shape> geoms, SpatialContext ctx)
        {
            if (!geoms.Any())
            {
                throw new ArgumentException("must be given at least 1 shape", "geoms");
            }

            this.geoms = geoms;

            //compute and cache bbox
            double minX = Double.PositiveInfinity;
            double minY = Double.PositiveInfinity;
            double maxX = Double.NegativeInfinity;
            double maxY = Double.NegativeInfinity;

            foreach (var geom in geoms)
            {
                Rectangle r = geom.GetBoundingBox();
                minX = Math.Min(minX, r.GetMinX());
                minY = Math.Min(minY, r.GetMinY());
                maxX = Math.Max(maxX, r.GetMaxX());
                maxY = Math.Max(maxY, r.GetMaxY());
            }
            this.bbox = ctx.MakeRectangle(minX, maxX, minY, maxY);
        }
Example #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="points">ordered control points. If empty then this shape is empty.</param>
        /// <param name="buf">Buffer &gt;= 0</param>
        /// <param name="expandBufForLongitudeSkew">
        /// See <see cref="BufferedLine.ExpandBufForLongitudeSkew(IPoint, IPoint, double)"/>
        /// If true then the buffer for each segment is computed.
        /// </param>
        /// <param name="ctx"></param>
        public BufferedLineString(IList <IPoint> points, double buf, bool expandBufForLongitudeSkew,
                                  SpatialContext ctx)
        {
            this.buf = buf;

            if (!points.Any())
            {
                this.segments = ctx.MakeCollection(new List <IShape>());
            }
            else
            {
                List <IShape> segments = new List <IShape>(points.Count - 1);

                IPoint prevPoint = null;
                foreach (IPoint point in points)
                {
                    if (prevPoint != null)
                    {
                        double segBuf = buf;
                        if (expandBufForLongitudeSkew)
                        {
                            //TODO this is faulty in that it over-buffers.  See Issue#60.
                            segBuf = BufferedLine.ExpandBufForLongitudeSkew(prevPoint, point, buf);
                        }
                        segments.Add(new BufferedLine(prevPoint, point, segBuf, ctx));
                    }
                    prevPoint = point;
                }
                if (!segments.Any())
                {//TODO throw exception instead?
                    segments.Add(new BufferedLine(prevPoint, prevPoint, buf, ctx));
                }
                this.segments = ctx.MakeCollection(segments);
            }
        }
Example #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="docId"></param>
        /// <param name="rng"></param>
        /// <param name="ctx"></param>
        /// <param name="percentageWithSpatialFields">ensures that some documents are missing spatial fields. This forces the cache to use FixedBitSet rather than MatchAllBits or MatchNoBits</param>
        /// <returns></returns>
        private Document CreateRandomDoc(int docId, Random rng, SpatialContext ctx, double percentageWithSpatialFields)
        {
            var doc = new Document();

            var idField = new NumericField("locationId", Field.Store.YES, true);

            idField.SetIntValue(docId);

            doc.Add(idField);

            if (rng.NextDouble() > percentageWithSpatialFields)
            {
                return(doc);
            }

            Point shape = ctx.MakePoint(DistanceUtils.NormLonDEG(rng.NextDouble() * 360.0), DistanceUtils.NormLatDEG(rng.NextDouble() * 180.0));

            foreach (AbstractField field in _spatialStrategy.CreateIndexableFields(shape))
            {
                doc.Add(field);
            }

            doc.Add(_spatialStrategy.CreateStoredField(shape));

            return(doc);
        }
Example #8
0
 public QuadPrefixTree(SpatialContext ctx, Rectangle bounds, int maxLevels)
     : base(ctx, maxLevels)
 {
     //not really sure how big this should be
     // side
     // number
     xmin      = bounds.GetMinX();
     xmax      = bounds.GetMaxX();
     ymin      = bounds.GetMinY();
     ymax      = bounds.GetMaxY();
     levelW    = new double[maxLevels];
     levelH    = new double[maxLevels];
     levelS    = new int[maxLevels];
     levelN    = new int[maxLevels];
     gridW     = xmax - xmin;
     gridH     = ymax - ymin;
     xmid      = xmin + gridW / 2.0;
     ymid      = ymin + gridH / 2.0;
     levelW[0] = gridW / 2.0;
     levelH[0] = gridH / 2.0;
     levelS[0] = 2;
     levelN[0] = 4;
     for (int i = 1; i < levelW.Length; i++)
     {
         levelW[i] = levelW[i - 1] / 2.0;
         levelH[i] = levelH[i - 1] / 2.0;
         levelS[i] = levelS[i - 1] * 2;
         levelN[i] = levelN[i - 1] * 4;
     }
 }
Example #9
0
        public void TestSimpleRectangle(SpatialContext ctx)
        {
            base.ctx = ctx;

            double v = 2001 * (random.NextDouble() > 0.5 ? -1 : 1);

            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(v, 0, 0, 0));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(0, v, 0, 0));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(0, 0, v, 0));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(0, 0, 0, v));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(0, 0, 10, -10));
            Assert.Throws <InvalidShapeException>(() => ctx.MakeRectangle(10, -10, 0, 0));

            double[] minXs = new double[] { -1000, -360, -180, -20, 0, 20, 180, 1000 };
            foreach (double minX in minXs)
            {
                double[] widths = new double[] { 0, 10, 180, 360, 400 };
                foreach (double width in widths)
                {
                    TestRectangle(minX, width, 0, 0);
                    TestRectangle(minX, width, -10, 10);
                    TestRectangle(minX, width, 5, 10);
                }
            }

            Rectangle r = ctx.MakeRectangle(0, 0, 0, 0);

            r.Reset(1, 2, 3, 4);
            Assert.Equal(ctx.MakeRectangle(1, 2, 3, 4), r);

            testRectIntersect();
        }
Example #10
0
        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);
        }
Example #11
0
        public void TestSimplePoint(SpatialContext ctx)
        {
            base.ctx = ctx;

            Assert.Throws <InvalidShapeException>(() => ctx.MakePoint(2001, 0));
            Assert.Throws <InvalidShapeException>(() => ctx.MakePoint(0, -301));

            Point  pt  = ctx.MakePoint(0, 0);
            String msg = pt.ToString();

            //test equals & hashcode
            Point pt2 = ctx.MakePoint(0, 0);

            Assert.Equal(/*msg,*/ pt, pt2);
            Assert.Equal(/*msg,*/ pt.GetHashCode(), pt2.GetHashCode());

            Assert.False(pt.HasArea(), msg);
            Assert.Equal(/*msg,*/ pt.GetCenter(), pt);
            Rectangle bbox = pt.GetBoundingBox();

            Assert.False(bbox.HasArea(), msg);

            var center = bbox.GetCenter();

            Assert.True(pt.Equals(center));
            //Assert.Equal(/*msg,*/ pt, center);

            assertRelation(msg, SpatialRelation.CONTAINS, pt, pt2);
            assertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(0, 1));
            assertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(1, 0));
            assertRelation(msg, SpatialRelation.DISJOINT, pt, ctx.MakePoint(1, 1));

            pt.Reset(1, 2);
            Assert.Equal(ctx.MakePoint(1, 2), pt);
        }
Example #12
0
        public void TestSimpleCircle(SpatialContext ctx)
        {
            base.ctx = ctx;

            double[] theXs = new double[] { -10, 0, 10 };
            foreach (double x in theXs)
            {
                double[] theYs = new double[] { -20, 0, 20 };
                foreach (double y in theYs)
                {
                    TestCircle(x, y, 0);
                    TestCircle(x, y, 5);
                }
            }

            testCircleReset(ctx);

            //INTERSECTION:
            //Start with some static tests that have shown to cause failures at some point:
            Assert.Equal(             /*"getX not getY",*/
                SpatialRelation.INTERSECTS,
                ctx.MakeCircle(107, -81, 147).Relate(ctx.MakeRectangle(92, 121, -89, 74)));

            TestCircleIntersect();
        }
Example #13
0
        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);
        }
Example #14
0
        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();
        }
Example #15
0
 protected internal virtual void Init(IDictionary <string, string> args, SpatialContext ctx)
 {
     // LUCENENET specific - added guard clauses
     this.m_args = args ?? throw new ArgumentNullException(nameof(args));
     this.m_ctx  = ctx ?? throw new ArgumentNullException(nameof(ctx));
     InitMaxLevels();
 }
Example #16
0
 protected internal virtual void Init(IDictionary <string, string> args, SpatialContext
                                      ctx)
 {
     this.args = args;
     this.ctx  = ctx;
     InitMaxLevels();
 }
Example #17
0
        static void Main(string[] args)
        {
            const Version version = Lucene.Net.Util.Version.LUCENE_30;

            Directory dir      = new RAMDirectory();
            Analyzer  analyzer = new StandardAnalyzer(version);

            var indexWriter = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);

            SpatialContext ctx = SpatialContext.GEO;

            // BBoxStrategy
            //var strategy = new BBoxStrategy(ctx, "spartial"); // Can only index and search by retangle

            // TermQueryPrefixTreeStrategy
            //SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 8);
            //var strategy = new TermQueryPrefixTreeStrategy(grid, "spartial"); // Only supports SpatialOperation.Intersects

            // RecursivePrefixTreeStrategy
            SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 8);
            var strategy           = new RecursivePrefixTreeStrategy(grid, "spartial");



            // PointVectorStrategy
            //var strategy = new PointVectorStrategy(ctx, "pointvector");

            foreach (var doc in CreateDocuments(strategy))
            {
                indexWriter.AddDocument(doc);
            }
            indexWriter.Commit();
            indexWriter.Dispose();


            var searcher = new IndexSearcher(dir, true);

            Point littleMermaid = ctx.MakePoint(12.599239, 55.692848);



            // PointVectorStrategy
            //TopDocs hits = DistanceQueryAndSort_PointVectorStrategy(searcher, strategy, littleMermaid);
            //TopDocs hits = DistanceFilter_PointVectorStrategy(searcher, strategy, littleMermaid);
            //TopDocs hits = DistranceScore_PointVectorStrategy(searcher, strategy, littleMermaid);

            // TermQueryPrefixTreeStrategy
            //TopDocs hits = DistanceFilter_TermQueryPrefixTreeStrategy(searcher, strategy, littleMermaid);

            // RecursivePrefixTreeStrategy
            TopDocs hits = DistanceFilter_RecursivePrefixTreeStrategy(searcher, strategy, littleMermaid);

            Console.WriteLine("Found {0} document(s) that matched query:", hits.TotalHits);
            foreach (ScoreDoc match in hits.ScoreDocs)
            {
                Document doc = searcher.Doc(match.Doc);
                Console.WriteLine("Matched {0} (score: {1})", doc.Get("id"), match.Score);
            }
            searcher.Dispose();
        }
        /// <summary>
        /// The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
        /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
        /// </summary>
        /// <param name="args"></param>
        /// <param name="ctx"></param>
        /// <returns></returns>
        public static SpatialPrefixTree MakeSPT(Dictionary <String, String> args, SpatialContext ctx)
        {
            SpatialPrefixTreeFactory instance;
            String cname;

            if (!args.TryGetValue(PREFIX_TREE, out cname) || cname == null)
            {
                cname = ctx.IsGeo() ? "geohash" : "quad";
            }
            if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase))
            {
                instance = new GeohashPrefixTree.Factory();
            }
            else if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase))
            {
                instance = new QuadPrefixTree.Factory();
            }
            else
            {
                Type t = Type.GetType(cname);
                instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(t);
            }
            instance.Init(args, ctx);
            return(instance.NewSPT());
        }
Example #19
0
        //1m
        /// <summary>The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
        ///     </summary>
        /// <remarks>
        /// The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
        /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
        /// </remarks>
        public static SpatialPrefixTree MakeSPT(IDictionary <string, string> args, SpatialContext ctx)
        {
            SpatialPrefixTreeFactory instance;
            string cname = args[PrefixTree];

            if (cname == null)
            {
                cname = ctx.IsGeo() ? "geohash" : "quad";
            }
            if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase))
            {
                instance = new GeohashPrefixTree.Factory();
            }
            else
            {
                if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase))
                {
                    instance = new QuadPrefixTree.Factory();
                }
                else
                {
                    try
                    {
                        Type c = Type.GetType(cname);
                        instance = (SpatialPrefixTreeFactory)System.Activator.CreateInstance(c);
                    }
                    catch (Exception e)
                    {
                        throw new Exception(string.Empty, e);
                    }
                }
            }
            instance.Init(args, ctx);
            return(instance.NewSPT());
        }
Example #20
0
        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");
        }
Example #21
0
        internal readonly int[] levelN; // number

        public QuadPrefixTree(SpatialContext ctx, IRectangle bounds, int maxLevels)
            : base(ctx, maxLevels)
        {
            xmin = bounds.MinX;
            xmax = bounds.MaxX;
            ymin = bounds.MinY;
            ymax = bounds.MaxY;

            levelW = new double[maxLevels];
            levelH = new double[maxLevels];
            levelS = new int[maxLevels];
            levelN = new int[maxLevels];

            gridW     = xmax - xmin;
            gridH     = ymax - ymin;
            this.xmid = xmin + gridW / 2.0;
            this.ymid = ymin + gridH / 2.0;
            levelW[0] = gridW / 2.0;
            levelH[0] = gridH / 2.0;
            levelS[0] = 2;
            levelN[0] = 4;

            for (int i = 1; i < levelW.Length; i++)
            {
                levelW[i] = levelW[i - 1] / 2.0;
                levelH[i] = levelH[i - 1] / 2.0;
                levelS[i] = levelS[i - 1] * 2;
                levelN[i] = levelN[i - 1] * 4;
            }
        }
Example #22
0
        //@ParametersFactory
        public static IList <Object[]> Parameters()
        {
            List <Object[]> ctorArgs = new List <object[]>();

            SpatialContext    ctx = SpatialContext.GEO;
            SpatialPrefixTree grid;
            SpatialStrategy   strategy;

            grid     = new GeohashPrefixTree(ctx, 12);
            strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            grid     = new QuadPrefixTree(ctx, 25);
            strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            grid     = new GeohashPrefixTree(ctx, 12);
            strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            strategy = new PointVectorStrategy(ctx, "pointvector");
            ctorArgs.Add(new Object[] { new Param(strategy) });

            return(ctorArgs);
        }
Example #23
0
        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);
        }
        public virtual void TestNGramPrefixGridLosAngeles()
        {
            SpatialContext ctx = SpatialContext.GEO;
            TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");

            Spatial4n.Core.Shapes.IShape point = ctx.MakePoint(-118.243680, 34.052230);

            Document losAngeles = new Document();

            losAngeles.Add(new StringField("name", "Los Angeles", Field.Store.YES));
            foreach (IndexableField field in prefixGridStrategy.CreateIndexableFields(point))
            {
                losAngeles.Add(field);
            }
            losAngeles.Add(new StoredField(prefixGridStrategy.FieldName, point.toString()));//just for diagnostics

            addDocumentsAndCommit(Arrays.AsList(losAngeles));

            // This won't work with simple spatial context...
            SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
            // TODO... use a non polygon query
            //    SpatialArgs spatialArgs = spatialArgsParser.parse(
            //        "Intersects(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
            //        new SimpleSpatialContext());

            //    Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);
            //    SearchResults searchResults = executeQuery(query, 1);
            //    assertEquals(1, searchResults.numFound);
        }
        public LuceneIndexManager(
            IClock clock,
            IOptions <ShellOptions> shellOptions,
            ShellSettings shellSettings,
            ILogger <LuceneIndexManager> logger,
            LuceneAnalyzerManager luceneAnalyzerManager,
            LuceneIndexSettingsService luceneIndexSettingsService
            )
        {
            _clock    = clock;
            _logger   = logger;
            _rootPath = PathExtensions.Combine(
                shellOptions.Value.ShellsApplicationDataPath,
                shellOptions.Value.ShellsContainerName,
                shellSettings.Name, "Lucene");
            Directory.CreateDirectory(_rootPath);
            _luceneAnalyzerManager      = luceneAnalyzerManager;
            _luceneIndexSettingsService = luceneIndexSettingsService;

            // Typical geospatial context
            // These can also be constructed from SpatialContextFactory
            _ctx = SpatialContext.Geo;

            var maxLevels = 11; // Results in sub-meter precision for geohash

            // TODO demo lookup by detail distance
            // This can also be constructed from SpatialPrefixTreeFactory
            _grid = new GeohashPrefixTree(_ctx, maxLevels);
        }
Example #26
0
 public override void TearDown()
 {
     base.TearDown();
     ctx        = null;
     strategy   = null;
     storeShape = true;
 }
        protected void Init(SpatialContext ctx, Rectangle bounds, int maxLevels)
        {
            this.xmin = bounds.GetMinX();
            this.xmax = bounds.GetMaxX();
            this.ymin = bounds.GetMinY();
            this.ymax = bounds.GetMaxY();

            levelW = new double[maxLevels];
            levelH = new double[maxLevels];
            levelS = new int[maxLevels];
            levelN = new int[maxLevels];

            gridW     = xmax - xmin;
            gridH     = ymax - ymin;
            xmid      = xmin + gridW / 2.0;
            ymid      = ymin + gridH / 2.0;
            levelW[0] = gridW / 2.0;
            levelH[0] = gridH / 2.0;
            levelS[0] = 2;
            levelN[0] = 4;

            for (int i = 1; i < levelW.Length; i++)
            {
                levelW[i] = levelW[i - 1] / 2.0;
                levelH[i] = levelH[i - 1] / 2.0;
                levelS[i] = levelS[i - 1] * 2;
                levelN[i] = levelN[i - 1] * 4;
            }
        }
        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");
        }
Example #29
0
        /// <summary>The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".</summary>
        /// <remarks>
        /// The factory  is looked up via "prefixTree" in args, expecting "geohash" or "quad".
        /// If its neither of these, then "geohash" is chosen for a geo context, otherwise "quad" is chosen.
        /// </remarks>
        public static SpatialPrefixTree MakeSPT(IDictionary <string, string> args, SpatialContext ctx)
        {
            SpatialPrefixTreeFactory instance;
            string cname;

            if (!args.TryGetValue(PREFIX_TREE, out cname))
            {
                cname = ctx.IsGeo ? "geohash" : "quad";
            }
            if ("geohash".Equals(cname, StringComparison.OrdinalIgnoreCase))
            {
                instance = new GeohashPrefixTree.Factory();
            }
            else if ("quad".Equals(cname, StringComparison.OrdinalIgnoreCase))
            {
                instance = new QuadPrefixTree.Factory();
            }
            else
            {
                try
                {
                    Type c = Type.GetType(cname);
                    instance = (SpatialPrefixTreeFactory)Activator.CreateInstance(c);
                }
                catch (Exception e)
                {
                    throw new ApplicationException(string.Empty, e);
                }
            }
            instance.Init(args, ctx);
            return(instance.NewSPT());
        }
        public virtual void TestSimpleCircle(SpatialContext ctx)
        {
            base.ctx = ctx;

            double[] theXs = new double[] { -10, 0, 10 };
            foreach (double x in theXs)
            {
                double[] theYs = new double[] { -20, 0, 20 };
                foreach (double y in theYs)
                {
                    TestCircle(x, y, 0);
                    TestCircle(x, y, 5);
                }
            }

            TestCircleReset(ctx);

            //INTERSECTION:
            //Start with some static tests that have shown to cause failures at some point:
            Assert.Equal( /*"getX not getY",*/
                SpatialRelation.INTERSECTS,
                ctx.MakeCircle(107, -81, 147).Relate(ctx.MakeRectangle(92, 121, -89, 74)));

            TestCircleIntersect();

            Assert.Equal(ctx.MakeCircle(1, 2, 10), ctx.MakeCircle(1, 2, 6).GetBuffered(4, ctx));

            TestEmptiness(ctx.MakeCircle(double.NaN, double.NaN, random.nextBoolean() ? 0 : double.NaN));
        }
Example #31
0
 /// <summary>
 /// Gets the error distance that specifies how precise the query shape is. This
 /// looks at {@link #getDistErr()}, {@link #getDistErrPct()}, and {@code
 /// defaultDistErrPct}.
 /// </summary>
 /// <param name="ctx"></param>
 /// <param name="defaultDistErrPct">0 to 0.5</param>
 /// <returns>>= 0</returns>
 public double ResolveDistErr(SpatialContext ctx, double defaultDistErrPct)
 {
     if (DistErr != null)
         return DistErr.Value;
     double? distErrPct = (this.distErrPct ?? defaultDistErrPct);
     return CalcDistanceFromErrPct(Shape, distErrPct.Value, ctx);
 }
Example #32
0
 /// <summary>
 /// Computes the distance given a shape and the {@code distErrPct}.  The
 /// algorithm is the fraction of the distance from the center of the query
 /// shape to its furthest bounding box corner.
 /// </summary>
 /// <param name="shape">Mandatory.</param>
 /// <param name="distErrPct">0 to 0.5</param>
 /// <param name="ctx">Mandatory</param>
 /// <returns>A distance (in degrees).</returns>
 public static double CalcDistanceFromErrPct(Shape shape, double distErrPct, SpatialContext ctx)
 {
     if (distErrPct < 0 || distErrPct > 0.5)
     {
         throw new ArgumentException("distErrPct " + distErrPct + " must be between [0 to 0.5]", "distErrPct");
     }
     if (distErrPct == 0 || shape is Point)
     {
         return 0;
     }
     Rectangle bbox = shape.GetBoundingBox();
     //The diagonal distance should be the same computed from any opposite corner,
     // and this is the longest distance that might be occurring within the shape.
     double diagonalDist = ctx.GetDistCalc().Distance(
         ctx.MakePoint(bbox.GetMinX(), bbox.GetMinY()), bbox.GetMaxX(), bbox.GetMaxY());
     return diagonalDist * 0.5 * distErrPct;
 }