geolocation - Lucene.net 邻近搜索

标签 geolocation lucene.net

有人有过使用 lucene.net 索引纬度和经度值然后根据距单个点的距离返回一组有序结果的经验吗?

Lucene.Net.Spatial 库能帮我解决这个问题吗?

最佳答案

虽然有点晚了,但是,空间库是开始的地方。其背后的基本原理是:

1) 将纬度和经度字段添加到文档中

doc.Add(new Field("Latitude", 
                  NumericUtils.DoubleToPrefixCoded(Latitude), 
                  Field.Store.YES, Field.Index.NOT_ANALYZED));

doc.Add(new Field("Longitude", 
                  NumericUtils.DoubleToPrefixCoded(Longitude), 
                  Field.Store.YES, Field.Index.NOT_ANALYZED));

2) 为您的搜索需要支持的每一层粒度创建绘图仪

IProjector projector = new SinusoidalProjector();
var ctp = new CartesianTierPlotter(0, projector, 
                                   Fields.LocationTierPrefix);
StartTier = ctp.BestFit(MaxKms);
EndTier = ctp.BestFit(MinKms);

Plotters = new Dictionary<int, CartesianTierPlotter>();
for (var tier = StartTier; tier <= EndTier; tier++)
{
    Plotters.Add(tier, new CartesianTierPlotter(tier, 
                                            projector, 
                                            Fields.LocationTierPrefix));
}

3) 使用绘图仪为每一层的文档建立索引

private static void AddCartesianTiers(double latitude, 
                                      double longitude, 
                                      Document document)
{
    for (var tier = StartTier; tier <= EndTier; tier++)
    {
        var ctp = Plotters[tier];
        var boxId = ctp.GetTierBoxId(latitude, longitude);
        document.Add(new Field(ctp.GetTierFieldName(),
                        NumericUtils.DoubleToPrefixCoded(boxId),
                        Field.Store.YES,
                        Field.Index.NOT_ANALYZED_NO_NORMS));
    }
}

将文档编入索引后,您可以继续构建查询。此示例使用 ConstantScoreQuery,但您可以将其替换为范围评分:

/*  Builder allows us to build a polygon which we will use to limit  
 * search scope on our cartesian tiers, this is like putting a grid 
 * over a map */
var builder = new CartesianPolyFilterBuilder(Fields.LocationTierPrefix);

/*  Bounding area draws the polygon, this can be thought of as working  
 * out which squares of the grid over a map to search */
var boundingArea = builder.GetBoundingArea(Latitude, 
                Longitude, 
                DistanceInKilometres * ProductSearchEngine.KmsToMiles);

/*  We refine, this is the equivalent of drawing a circle on the map,  
 *  within our grid squares, ignoring the parts the squares we are  
 *  searching that aren't within the circle - ignoring extraneous corners 
 *  and such */
var distFilter = new LatLongDistanceFilter(boundingArea, 
                                    DistanceInKilometres * KmsToMiles,
                                    Latitude, 
                                    Longitude, 
                                    ProductSearchEngine.Fields.Latitude,
                                    ProductSearchEngine.Fields.Longitude);

/*  We add a query stating we will only search against products that have 
 * GeoCode information */
var query = new TermQuery(new Term(Fields.HasGeoCode, 
                                   FieldFlags.HasField));

/*  Add our filter, this will stream through our results and 
 * determine eligibility */
masterQuery.Add(new ConstantScoreQuery(distanceFilter), 
                BooleanClause.Occur.MUST);

所有这些都取 self 刚刚在查看类似问题时撰写的博客文章。您可以在 http://www.leapinggorilla.com/Blog/Read/1005/spatial-search-in-lucenenet 看到它

关于geolocation - Lucene.net 邻近搜索,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13865010/

相关文章:

android - 如何使用 FusedLocationProvider Api 和 Google 客户端检查位置是否可用?

c# - Windows Phone 8 Geolocator 无法设置 desiredAccuracy = High 并绑定(bind)到 PositionChanged 事件

windows-phone-7 - 如何使用 Windows Phone 7 在 map 中显示当前位置

c# - 良好的 Lucene .NET 替代 ASP.NET 网站

C# Lucene 标签搜索问题、转义问题?

android - 在 map 中检测电话

json - 查询 Geonames API 以仅获取城市国家名称

indexing - 如何使用 Lucene.NET 计算文档的 "OnTopicness"

lucene - 索引复制和负载均衡

full-text-search - 如何在 LuceneNet 中使用 indexWriter 删除文档