blob: c3be98e3f15f0651984ce16e6d2146e3301ad02f [file] [log] [blame]
using Lucene.Net.Spatial.Prefix.Tree;
using Lucene.Net.Spatial.Queries;
using NUnit.Framework;
using Spatial4n.Core.Context;
using Spatial4n.Core.Distance;
using Spatial4n.Core.Shapes;
using System.Collections.Generic;
using System.Globalization;
using JCG = J2N.Collections.Generic;
namespace Lucene.Net.Spatial.Prefix
{
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class TestRecursivePrefixTreeStrategy : StrategyTestCase
{
private int maxLength;
//Tests should call this first.
private void init(int maxLength)
{
this.maxLength = maxLength;
this.ctx = SpatialContext.GEO;
GeohashPrefixTree grid = new GeohashPrefixTree(ctx, maxLength);
this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
}
[Test]
public virtual void TestFilterWithVariableScanLevel()
{
init(GeohashPrefixTree.MaxLevelsPossible);
getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
//execute queries for each prefix grid scan level
for (int i = 0; i <= maxLength; i++)
{
((RecursivePrefixTreeStrategy)strategy).PrefixGridScanLevel = (i);
executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
}
}
[Test]
public virtual void TestOneMeterPrecision()
{
init(GeohashPrefixTree.MaxLevelsPossible);
GeohashPrefixTree grid = (GeohashPrefixTree)((RecursivePrefixTreeStrategy)strategy).Grid;
//DWS: I know this to be true. 11 is needed for one meter
double degrees = DistanceUtils.Dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
assertEquals(11, grid.GetLevelForDistance(degrees));
}
[Test]
public virtual void TestPrecision()
{
init(GeohashPrefixTree.MaxLevelsPossible);
Spatial4n.Core.Shapes.IPoint iPt = ctx.MakePoint(2.8028712999999925, 48.3708044);//lon, lat
AddDocument(newDoc("iPt", iPt));
Commit();
Spatial4n.Core.Shapes.IPoint qPt = ctx.MakePoint(2.4632387000000335, 48.6003516);
double KM2DEG = DistanceUtils.Dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
double DEG2KM = 1 / KM2DEG;
double DIST = 35.75;//35.7499...
assertEquals(DIST, ctx.DistCalc.Distance(iPt, qPt) * DEG2KM, 0.001);
//distErrPct will affect the query shape precision. The indexed precision
// was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
double distErrPct = 0.025; //the suggested default, by the way
double distMult = 1 + distErrPct;
assertTrue(35.74 * distMult >= DIST);
checkHits(q(qPt, 35.74 * KM2DEG, distErrPct), 1, null);
assertTrue(30 * distMult < DIST);
checkHits(q(qPt, 30 * KM2DEG, distErrPct), 0, null);
assertTrue(33 * distMult < DIST);
checkHits(q(qPt, 33 * KM2DEG, distErrPct), 0, null);
assertTrue(34 * distMult < DIST);
checkHits(q(qPt, 34 * KM2DEG, distErrPct), 0, null);
}
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;
}
private void checkHits(SpatialArgs args, int assertNumFound, int[] assertIds)
{
SearchResults got = executeQuery(strategy.MakeQuery(args), 100);
assertEquals("" + args, assertNumFound, got.numFound);
if (assertIds != null)
{
ISet<int?> gotIds = new JCG.HashSet<int?>();
foreach (SearchResult result in got.results)
{
gotIds.add(int.Parse(result.document.Get("id"), CultureInfo.InvariantCulture));
}
foreach (int assertId in assertIds)
{
assertTrue("has " + assertId, gotIds.contains(assertId));
}
}
}
}
}