Một chút muộn cho bữa tiệc nhưng có, thư viện không gian là nơi để bắt đầu với điều này. Những điều cơ bản đằng sau nó là:
1) Thêm lĩnh vực Lạt và Long để tài liệu của bạn
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) Tạo máy vẽ cho mỗi tầng của granularity rằng tìm kiếm của bạn cần hỗ trợ
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) Sử dụng máy vẽ của bạn để lập chỉ mục tài liệu cho mỗi tầng
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));
}
}
Với tài liệu được lập chỉ mục, bạn có thể chuyển sang xây dựng một truy vấn. Ví dụ này sử dụng một ConstantScoreQuery nhưng bạn có thể trao đổi đó ra cho điểm dao động của bạn:
/* 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);
Tất cả điều này được lấy từ một bài đăng blog tôi chỉ viết khi nhìn vào một vấn đề tương tự. Bạn có thể xem nó tại http://www.leapinggorilla.com/Blog/Read/1005/spatial-search-in-lucenenet
Câu hỏi hay. Tôi cũng muốn được biết. –