如何在Lucene 4.0.0中使用地理(空间)搜索获取距离?

6
我正在尝试使用最新版本的Lucene(4.0.0)进行地理搜索功能,要求很简单:获取圆形内的点(中心和半径作为查询条件传入)。我找不到输出每个结果到中心距离的API,必须在获取每个结果的纬度和经度后计算距离。有人可以帮忙吗?以下是代码:
SpatialContext sc = SpatialContext.GEO;
SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects,
              sc.makeCircle(lo, la, DistanceUtils.dist2Degrees(dist, DistanceUtils.EARTH_MEAN_RADIUS_KM)));
Filter geo_filter = strategy.makeFilter(args);
try {
    Sort chainedSort = new Sort(sfArray).rewrite(searcher);
    TopDocs docs = searcher.search(new MatchAllDocsQuery(), geo_filter, 10000, chainedSort);
    logger.debug("search finished, num: " + docs.totalHits);
    for (ScoreDoc scoreDoc : docs.scoreDocs){
        Document doc = searcher.doc(scoreDoc.doc);
        double la1 = Double.parseDouble(doc.get("la"));
        double lo1 = Double.parseDouble(doc.get("lo"));
        double distance = getDistance(la1, lo1, la, lo); // have to calc distance by myself here, not cool
    }
} catch (IOException e) {
    logger.error("fail to get the search result!", e);
}

使用Lucene 3.X很容易实现距离搜索,但对于熟悉Lucene 4.0.0的地理(空间)搜索有什么建议吗?

1个回答

7

您已经从字段中获取了纬度和经度信息,现在需要计算距离查询圆的中心点的距离。在您的代码中,这将如下所示:

double distDEG = sc.getDistCalc().distance(args.getShape().getCenter(), lo1, la1);
double distKM = DistanceUtils.degrees2Dist(distDEG, DistanceUtils.EARTH_MEAN_RADIUS_KM);

不错吧?嗯?(顺便说一句,我写了很多Lucene 4空间相关的内容)

谢谢,David,这真的很有帮助。这是否意味着系统要计算两次距离?一次用于过滤和排序结果,另一次用于输出距离。我记得在Lucene 3.X中,用户只需要从DistanceFilter(或类似的东西)获取距离,以前的API设计更加明确。 - Jet Yang
无论是否计算两次取决于您选择的SpatialStrategy。如果您使用带有Circle查询形状的PointVectorStrategy,则我认为它只会被计算两次。但是,我建议人们使用RecursivePrefixTreeStrategy进行过滤,这不会在内部计算距离。如果您还想查看每个文档的距离,则双重计算将不幸发生在排序时。但是我敢打赌,您只需要“查看”前20个左右的文档,而不是全部。 - David Smiley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接