From 531f660c2bfe209d9570ab56484aaa87dbe94e35 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Wed, 23 Mar 2016 15:36:54 +1300 Subject: [PATCH] Don't force the user to specify the metric There's a sensible default choice which is what most users will want, so default to that. --- xapian-core/geospatial/latlong_posting_source.cc | 17 ++++ xapian-core/include/xapian/geospatial.h | 23 ++++++ xapian-core/tests/api_geospatial.cc | 100 ++++++++++++++++++++++- 3 files changed, 139 insertions(+), 1 deletion(-) diff --git a/xapian-core/geospatial/latlong_posting_source.cc b/xapian-core/geospatial/latlong_posting_source.cc index 5dd936cfe..ea34f92bf 100644 --- a/xapian-core/geospatial/latlong_posting_source.cc +++ b/xapian-core/geospatial/latlong_posting_source.cc @@ -102,6 +102,23 @@ LatLongDistancePostingSource::LatLongDistancePostingSource( set_maxweight(weight_from_distance(0, k1, k2)); } +LatLongDistancePostingSource::LatLongDistancePostingSource( + valueno slot_, + const LatLongCoords & centre_, + double max_range_, + double k1_, + double k2_) + : ValuePostingSource(slot_), + centre(centre_), + metric(new Xapian::GreatCircleMetric()), + max_range(max_range_), + k1(k1_), + k2(k2_) +{ + validate_postingsource_params(k1, k2); + set_maxweight(weight_from_distance(0, k1, k2)); +} + LatLongDistancePostingSource::~LatLongDistancePostingSource() { delete metric; diff --git a/xapian-core/include/xapian/geospatial.h b/xapian-core/include/xapian/geospatial.h index 8a81ce2e1..04c9b5d02 100644 --- a/xapian-core/include/xapian/geospatial.h +++ b/xapian-core/include/xapian/geospatial.h @@ -476,6 +476,11 @@ class XAPIAN_VISIBILITY_DEFAULT LatLongDistancePostingSource : public ValuePosti double max_range_ = 0.0, double k1_ = 1000.0, double k2_ = 1.0); + LatLongDistancePostingSource(Xapian::valueno slot_, + const LatLongCoords & centre_, + double max_range_ = 0.0, + double k1_ = 1000.0, + double k2_ = 1.0); ~LatLongDistancePostingSource(); void next(double min_wt); @@ -543,6 +548,14 @@ class XAPIAN_VISIBILITY_DEFAULT LatLongDistanceKeyMaker : public KeyMaker { {} LatLongDistanceKeyMaker(Xapian::valueno slot_, + const LatLongCoords & centre_) + : slot(slot_), + centre(centre_), + metric(new Xapian::GreatCircleMetric()), + defkey(9, '\xff') + {} + + LatLongDistanceKeyMaker(Xapian::valueno slot_, const LatLongCoord & centre_, const LatLongMetric & metric_, double defdistance) @@ -565,6 +578,16 @@ class XAPIAN_VISIBILITY_DEFAULT LatLongDistanceKeyMaker : public KeyMaker { centre.append(centre_); } + LatLongDistanceKeyMaker(Xapian::valueno slot_, + const LatLongCoord & centre_) + : slot(slot_), + centre(), + metric(new Xapian::GreatCircleMetric()), + defkey(9, '\xff') + { + centre.append(centre_); + } + ~LatLongDistanceKeyMaker(); std::string operator()(const Xapian::Document & doc) const; diff --git a/xapian-core/tests/api_geospatial.cc b/xapian-core/tests/api_geospatial.cc index a36b97758..4d1fa5b8a 100644 --- a/xapian-core/tests/api_geospatial.cc +++ b/xapian-core/tests/api_geospatial.cc @@ -3,7 +3,7 @@ */ /* Copyright 2008 Lemur Consulting Ltd * Copyright 2010,2011 Richard Boulton - * Copyright 2012 Olly Betts + * Copyright 2012,2016 Olly Betts * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -92,6 +92,30 @@ DEFINE_TESTCASE(latlongpostingsource1, backend && writable && !remote && !inmemo TEST_EQUAL(ps.at_end(), true); } + // Test a search with no range restriction and implicit metric. + { + Xapian::LatLongDistancePostingSource ps(0, coord1); + ps.init(db); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1.0); + TEST_EQUAL(ps.get_docid(), 1); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist)); + TEST_EQUAL(ps.get_docid(), 2); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist * 2)); + TEST_EQUAL(ps.get_docid(), 3); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), true); + } + // Test a search with a tight range restriction { Xapian::LatLongDistancePostingSource ps(0, centre, metric, coorddist * 0.5); @@ -105,6 +129,19 @@ DEFINE_TESTCASE(latlongpostingsource1, backend && writable && !remote && !inmemo TEST_EQUAL(ps.at_end(), true); } + // Test a search with a tight range restriction and implicit metric. + { + Xapian::LatLongDistancePostingSource ps(0, centre, coorddist * 0.5); + ps.init(db); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1.0); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), true); + } + // Test a search with a looser range restriction { Xapian::LatLongDistancePostingSource ps(0, centre, metric, coorddist); @@ -123,6 +160,24 @@ DEFINE_TESTCASE(latlongpostingsource1, backend && writable && !remote && !inmemo TEST_EQUAL(ps.at_end(), true); } + // Test a search with a looser range restriction and implicit metric. + { + Xapian::LatLongDistancePostingSource ps(0, centre, coorddist); + ps.init(db); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1.0); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist)); + TEST_EQUAL(ps.get_docid(), 2); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), true); + } + // Test a search with a looser range restriction, but not enough to return // the next document. { @@ -142,6 +197,25 @@ DEFINE_TESTCASE(latlongpostingsource1, backend && writable && !remote && !inmemo TEST_EQUAL(ps.at_end(), true); } + // Test a search with a looser range restriction, but not enough to return + // the next document and implicit metric. + { + Xapian::LatLongDistancePostingSource ps(0, centre, coorddist * 1.5); + ps.init(db); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1.0); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist)); + TEST_EQUAL(ps.get_docid(), 2); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), true); + } + // Test a search with a loose enough range restriction that all docs should // be returned. { @@ -166,6 +240,30 @@ DEFINE_TESTCASE(latlongpostingsource1, backend && writable && !remote && !inmemo TEST_EQUAL(ps.at_end(), true); } + // Test a search with a loose enough range restriction that all docs should + // be returned and implicit metric. + { + Xapian::LatLongDistancePostingSource ps(0, centre, coorddist * 2.5); + ps.init(db); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1.0); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist)); + TEST_EQUAL(ps.get_docid(), 2); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), false); + TEST_EQUAL_DOUBLE(ps.get_weight(), 1000.0 / (1000.0 + coorddist * 2)); + TEST_EQUAL(ps.get_docid(), 3); + + ps.next(0.0); + TEST_EQUAL(ps.at_end(), true); + } + return true; } -- 2.11.4.GIT