有人有过使用 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/