LCOV - code coverage report
Current view: top level - include/xapian - geospatial.h (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 7822d31adece Lines: 45 45 100.0 %
Date: 2019-05-23 11:15:29 Functions: 22 22 100.0 %
Branches: 12 20 60.0 %

           Branch data     Line data    Source code
       1                 :            : /** @file geospatial.h
       2                 :            :  * @brief Geospatial search support routines.
       3                 :            :  */
       4                 :            : /* Copyright 2008,2009 Lemur Consulting Ltd
       5                 :            :  * Copyright 2010,2011 Richard Boulton
       6                 :            :  * Copyright 2012,2013,2014,2015,2016 Olly Betts
       7                 :            :  *
       8                 :            :  * This program is free software; you can redistribute it and/or
       9                 :            :  * modify it under the terms of the GNU General Public License as
      10                 :            :  * published by the Free Software Foundation; either version 2 of the
      11                 :            :  * License, or (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This program is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program; if not, write to the Free Software
      20                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
      21                 :            :  * USA
      22                 :            :  */
      23                 :            : 
      24                 :            : #ifndef XAPIAN_INCLUDED_GEOSPATIAL_H
      25                 :            : #define XAPIAN_INCLUDED_GEOSPATIAL_H
      26                 :            : 
      27                 :            : #if !defined XAPIAN_IN_XAPIAN_H && !defined XAPIAN_LIB_BUILD
      28                 :            : # error "Never use <xapian/geospatial.h> directly; include <xapian.h> instead."
      29                 :            : #endif
      30                 :            : 
      31                 :            : #include <iterator>
      32                 :            : #include <vector>
      33                 :            : #include <string>
      34                 :            : 
      35                 :            : #include <xapian/attributes.h>
      36                 :            : #include <xapian/derefwrapper.h>
      37                 :            : #include <xapian/keymaker.h>
      38                 :            : #include <xapian/postingsource.h>
      39                 :            : #include <xapian/queryparser.h> // For sortable_serialise
      40                 :            : #include <xapian/visibility.h>
      41                 :            : 
      42                 :            : namespace Xapian {
      43                 :            : 
      44                 :            : class Registry;
      45                 :            : 
      46                 :            : double
      47                 :            : XAPIAN_NOTHROW(miles_to_metres(double miles)) XAPIAN_CONST_FUNCTION;
      48                 :            : 
      49                 :            : /** Convert from miles to metres.
      50                 :            :  *
      51                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
      52                 :            :  */
      53                 :            : inline double
      54                 :            : miles_to_metres(double miles) XAPIAN_NOEXCEPT
      55                 :            : {
      56                 :            :     return 1609.344 * miles;
      57                 :            : }
      58                 :            : 
      59                 :            : double
      60                 :            : XAPIAN_NOTHROW(metres_to_miles(double metres)) XAPIAN_CONST_FUNCTION;
      61                 :            : 
      62                 :            : /** Convert from metres to miles.
      63                 :            :  *
      64                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
      65                 :            :  */
      66                 :            : inline double
      67                 :            : metres_to_miles(double metres) XAPIAN_NOEXCEPT
      68                 :            : {
      69                 :            :     return metres * (1.0 / 1609.344);
      70                 :            : }
      71                 :            : 
      72                 :            : /** A latitude-longitude coordinate.
      73                 :            :  *
      74                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
      75                 :            :  *
      76                 :            :  *  Note that latitude-longitude coordinates are only precisely meaningful if
      77                 :            :  *  the datum used to define them is specified.  This class ignores this
      78                 :            :  *  issue - it is up to the caller to ensure that the datum used for each
      79                 :            :  *  coordinate in a system is consistent.
      80                 :            :  */
      81                 :            : struct XAPIAN_VISIBILITY_DEFAULT LatLongCoord {
      82                 :            :     /** A latitude, as decimal degrees.
      83                 :            :      *
      84                 :            :      *  Should be in the range -90 <= latitude <= 90
      85                 :            :      *
      86                 :            :      *  Positive latitudes represent the northern hemisphere.
      87                 :            :      */
      88                 :            :     double latitude;
      89                 :            : 
      90                 :            :     /** A longitude, as decimal degrees.
      91                 :            :      *
      92                 :            :      *  Will be wrapped around, so for example, -150 is equal to 210.  When
      93                 :            :      *  obtained from a serialised form, will be in the range 0 <= longitude <
      94                 :            :      *  360.
      95                 :            :      *
      96                 :            :      *  Longitudes increase as coordinates move eastwards.
      97                 :            :      */
      98                 :            :     double longitude;
      99                 :            : 
     100                 :            :     /** Construct an uninitialised coordinate.
     101                 :            :      */
     102                 :         67 :     XAPIAN_NOTHROW(LatLongCoord()) {}
     103                 :            : 
     104                 :            :     /** Construct a coordinate.
     105                 :            :      *
     106                 :            :      *  If the supplied longitude is out of the standard range, it will be
     107                 :            :      *  normalised to the range 0 <= longitude < 360.
     108                 :            :      *
     109                 :            :      *  If you want to avoid the checks (for example, you know that your values
     110                 :            :      *  are already in range), you can use the alternate constructor to
     111                 :            :      *  construct an uninitialised coordinate, and then set the latitude and
     112                 :            :      *  longitude directly.
     113                 :            :      *
     114                 :            :      *  @exception InvalidArgumentError the supplied latitude is out of range.
     115                 :            :      */
     116                 :            :     LatLongCoord(double latitude_, double longitude_);
     117                 :            : 
     118                 :            :     /** Unserialise a string and set this object to its coordinate.
     119                 :            :      *
     120                 :            :      *  @param serialised the string to unserialise the coordinate from.
     121                 :            :      *
     122                 :            :      *  @exception Xapian::SerialisationError if the string does not contain
     123                 :            :      *  a valid serialised latitude-longitude pair, or contains extra data at
     124                 :            :      *  the end of it.
     125                 :            :      */
     126                 :            :     void unserialise(const std::string & serialised);
     127                 :            : 
     128                 :            :     /** Unserialise a buffer and set this object to its coordinate.
     129                 :            :      *
     130                 :            :      *  The buffer may contain further data after that for the coordinate.
     131                 :            :      *
     132                 :            :      *  @param ptr A pointer to the start of the string.  This will be updated
     133                 :            :      *  to point to the end of the data representing the coordinate.
     134                 :            :      *  @param end A pointer to the end of the string.
     135                 :            :      *
     136                 :            :      *  @exception Xapian::SerialisationError if the string does not start with
     137                 :            :      *  a valid serialised latitude-longitude pair.
     138                 :            :      */
     139                 :            :     void unserialise(const char ** ptr, const char * end);
     140                 :            : 
     141                 :            :     /** Return a serialised representation of the coordinate.
     142                 :            :      */
     143                 :            :     std::string serialise() const;
     144                 :            : 
     145                 :            :     /** Compare with another LatLongCoord.
     146                 :            :      *
     147                 :            :      *  This is mostly provided so that things like std::map<LatLongCoord> work
     148                 :            :      *  - the ordering isn't particularly meaningful.
     149                 :            :      */
     150                 :          8 :     bool XAPIAN_NOTHROW(operator<(const LatLongCoord & other) const)
     151                 :            :     {
     152         [ +  + ]:          8 :         if (latitude < other.latitude) return true;
     153         [ +  + ]:          6 :         if (latitude > other.latitude) return false;
     154                 :          4 :         return (longitude < other.longitude);
     155                 :            :     }
     156                 :            : 
     157                 :            :     /// Return a string describing this object.
     158                 :            :     std::string get_description() const;
     159                 :            : };
     160                 :            : 
     161                 :            : /** An iterator across the values in a LatLongCoords object.
     162                 :            :  *
     163                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     164                 :            :  */
     165                 :            : class XAPIAN_VISIBILITY_DEFAULT LatLongCoordsIterator {
     166                 :            :     /// Friend class which needs to be able to construct us.
     167                 :            :     friend class LatLongCoords;
     168                 :            : 
     169                 :            :     /// The current position of the iterator.
     170                 :            :     std::vector<LatLongCoord>::const_iterator iter;
     171                 :            : 
     172                 :            :     /// Constructor used by LatLongCoords.
     173                 :        287 :     LatLongCoordsIterator(std::vector<LatLongCoord>::const_iterator iter_)
     174                 :        287 :             : iter(iter_) {}
     175                 :            : 
     176                 :            :   public:
     177                 :            :     /// Default constructor.  Produces an uninitialised iterator.
     178                 :          2 :     LatLongCoordsIterator() {}
     179                 :            : 
     180                 :            :     /** Get the LatLongCoord for the current position. */
     181                 :        103 :     const LatLongCoord & operator*() const {
     182                 :        103 :         return *iter;
     183                 :            :     }
     184                 :            : 
     185                 :            :     /// Advance the iterator to the next position.
     186                 :        100 :     LatLongCoordsIterator & operator++() {
     187                 :        100 :         ++iter;
     188                 :        100 :         return *this;
     189                 :            :     }
     190                 :            : 
     191                 :            :     /// Advance the iterator to the next position (postfix version).
     192                 :            :     DerefWrapper_<LatLongCoord> operator++(int) {
     193                 :            :         const LatLongCoord & tmp = **this;
     194                 :            :         ++iter;
     195                 :            :         return DerefWrapper_<LatLongCoord>(tmp);
     196                 :            :     }
     197                 :            : 
     198                 :            :     /// Equality test for LatLongCoordsIterator objects.
     199                 :        193 :     bool operator==(const LatLongCoordsIterator &other) const
     200                 :            :     {
     201                 :        193 :         return iter == other.iter;
     202                 :            :     }
     203                 :            : 
     204                 :            :     /** @private @internal LatLongCoordsIterator is what the C++ STL calls an
     205                 :            :      *  input_iterator.
     206                 :            :      *
     207                 :            :      *  The following typedefs allow std::iterator_traits<> to work so that
     208                 :            :      *  this iterator can be used with the STL.
     209                 :            :      *
     210                 :            :      *  These are deliberately hidden from the Doxygen-generated docs, as the
     211                 :            :      *  machinery here isn't interesting to API users.  They just need to know
     212                 :            :      *  that Xapian iterator classes are compatible with the STL.
     213                 :            :      */
     214                 :            :     // @{
     215                 :            :     /// @private
     216                 :            :     typedef std::input_iterator_tag iterator_category;
     217                 :            :     /// @private
     218                 :            :     typedef LatLongCoord value_type;
     219                 :            :     /// @private
     220                 :            :     typedef size_t difference_type;
     221                 :            :     /// @private
     222                 :            :     typedef LatLongCoord * pointer;
     223                 :            :     /// @private
     224                 :            :     typedef LatLongCoord & reference;
     225                 :            :     // @}
     226                 :            : };
     227                 :            : 
     228                 :            : /** A sequence of latitude-longitude coordinates.
     229                 :            :  *
     230                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     231                 :            :  */
     232                 :       8832 : class XAPIAN_VISIBILITY_DEFAULT LatLongCoords {
     233                 :            :     /// The coordinates.
     234                 :            :     std::vector<LatLongCoord> coords;
     235                 :            : 
     236                 :            :   public:
     237                 :            :     /// Get a begin iterator for the coordinates.
     238                 :         94 :     LatLongCoordsIterator begin() const {
     239                 :         94 :         return LatLongCoordsIterator(coords.begin());
     240                 :            :     }
     241                 :            : 
     242                 :            :     /// Get an end iterator for the coordinates.
     243                 :        193 :     LatLongCoordsIterator end() const {
     244                 :        193 :         return LatLongCoordsIterator(coords.end());
     245                 :            :     }
     246                 :            : 
     247                 :            :     /// Get the number of coordinates in the container.
     248                 :          4 :     size_t size() const
     249                 :            :     {
     250                 :          4 :         return coords.size();
     251                 :            :     }
     252                 :            : 
     253                 :            :     /// Return true if and only if there are no coordinates in the container.
     254                 :         89 :     bool empty() const
     255                 :            :     {
     256                 :         89 :         return coords.empty();
     257                 :            :     }
     258                 :            : 
     259                 :            :     /// Append a coordinate to the end of the sequence.
     260                 :          5 :     void append(const LatLongCoord & coord)
     261                 :            :     {
     262                 :          5 :         coords.push_back(coord);
     263                 :          5 :     }
     264                 :            : 
     265                 :            :     /// Construct an empty container.
     266                 :       2908 :     LatLongCoords() : coords() {}
     267                 :            : 
     268                 :            :     /// Construct a container holding one coordinate.
     269                 :         48 :     LatLongCoords(const LatLongCoord & coord) : coords()
     270                 :            :     {
     271         [ +  - ]:         24 :         coords.push_back(coord);
     272                 :         24 :     }
     273                 :            : 
     274                 :            :     /** Unserialise a string and set this object to the coordinates in it.
     275                 :            :      *
     276                 :            :      *  @param serialised the string to unserialise the coordinates from.
     277                 :            :      *
     278                 :            :      *  @exception Xapian::SerialisationError if the string does not contain
     279                 :            :      *  a valid serialised latitude-longitude pair, or contains junk at the end
     280                 :            :      *  of it.
     281                 :            :      */
     282                 :            :     void unserialise(const std::string & serialised);
     283                 :            : 
     284                 :            :     /** Return a serialised form of the coordinate list.
     285                 :            :      */
     286                 :            :     std::string serialise() const;
     287                 :            : 
     288                 :            :     /// Return a string describing this object.
     289                 :            :     std::string get_description() const;
     290                 :            : };
     291                 :            : 
     292                 :            : /// Inequality test for LatLongCoordsIterator objects.
     293                 :            : inline bool
     294                 :        191 : operator!=(const LatLongCoordsIterator &a, const LatLongCoordsIterator &b)
     295                 :            : {
     296                 :        191 :     return !(a == b);
     297                 :            : }
     298                 :            : 
     299                 :            : /** Base class for calculating distances between two lat/long coordinates.
     300                 :            :  *
     301                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     302                 :            :  */
     303                 :       4370 : class XAPIAN_VISIBILITY_DEFAULT LatLongMetric {
     304                 :            :   public:
     305                 :            :     /// Destructor.
     306                 :            :     virtual ~LatLongMetric();
     307                 :            : 
     308                 :            :     /** Return the distance between two coordinates, in metres.
     309                 :            :      */
     310                 :            :     virtual double pointwise_distance(const LatLongCoord & a,
     311                 :            :                                       const LatLongCoord & b) const = 0;
     312                 :            : 
     313                 :            :     /** Return the distance between two coordinate lists, in metres.
     314                 :            :      *
     315                 :            :      *  The distance between the coordinate lists is defined to be the minimum
     316                 :            :      *  pairwise distance between coordinates in the lists.
     317                 :            :      *
     318                 :            :      *  @exception InvalidArgumentError either of the lists is empty.
     319                 :            :      *
     320                 :            :      *  @param a The first coordinate list.
     321                 :            :      *  @param b The second coordinate list.
     322                 :            :      */
     323                 :            :     double operator()(const LatLongCoords & a, const LatLongCoords & b) const;
     324                 :            : 
     325                 :            :     /** Return the distance between two coordinate lists, in metres.
     326                 :            :      *
     327                 :            :      *  One of the coordinate lists is supplied in serialised form.
     328                 :            :      *
     329                 :            :      *  The distance between the coordinate lists is defined to be the minimum
     330                 :            :      *  pairwise distance between coordinates in the lists.
     331                 :            :      *
     332                 :            :      *  @exception InvalidArgumentError either of the lists is empty.
     333                 :            :      *
     334                 :            :      *  @param a The first coordinate list.
     335                 :            :      *  @param b The second coordinate list, in serialised form.
     336                 :            :      */
     337                 :         61 :     double operator()(const LatLongCoords & a, const std::string & b) const
     338                 :            :     {
     339                 :         61 :         return (*this)(a, b.data(), b.size());
     340                 :            :     }
     341                 :            : 
     342                 :            :     /** Return the distance between two coordinate lists, in metres.
     343                 :            :      *
     344                 :            :      *  One of the coordinate lists is supplied in serialised form.
     345                 :            :      *
     346                 :            :      *  The distance between the coordinate lists is defined to be the minimum
     347                 :            :      *  pairwise distance between coordinates in the lists.
     348                 :            :      *
     349                 :            :      *  @exception InvalidArgumentError either of the lists is empty.
     350                 :            :      *
     351                 :            :      *  @param a The first coordinate list.
     352                 :            :      *  @param b_ptr The start of the serialised form of the second coordinate
     353                 :            :      *               list.
     354                 :            :      *  @param b_len The length of the serialised form of the second coordinate
     355                 :            :      *               list.
     356                 :            :      */
     357                 :            :     double operator()(const LatLongCoords & a,
     358                 :            :                       const char * b_ptr, size_t b_len) const;
     359                 :            : 
     360                 :            :     /** Clone the metric. */
     361                 :            :     virtual LatLongMetric * clone() const = 0;
     362                 :            : 
     363                 :            :     /** Return the full name of the metric.
     364                 :            :      *
     365                 :            :      *  This is used when serialising and unserialising metrics; for example,
     366                 :            :      *  for performing remote searches.
     367                 :            :      *
     368                 :            :      *  If the subclass is in a C++ namespace, the namespace should be included
     369                 :            :      *  in the name, using "::" as a separator.  For example, for a
     370                 :            :      *  LatLongMetric subclass called "FooLatLongMetric" in the "Xapian"
     371                 :            :      *  namespace the result of this call should be "Xapian::FooLatLongMetric".
     372                 :            :      */
     373                 :            :     virtual std::string name() const = 0;
     374                 :            : 
     375                 :            :     /** Serialise object parameters into a string.
     376                 :            :      *
     377                 :            :      *  The serialised parameters should represent the configuration of the
     378                 :            :      *  metric.
     379                 :            :      */
     380                 :            :     virtual std::string serialise() const = 0;
     381                 :            : 
     382                 :            :     /** Create object given string serialisation returned by serialise().
     383                 :            :      *
     384                 :            :      *  @param serialised A serialised instance of this LatLongMetric subclass.
     385                 :            :      */
     386                 :            :     virtual LatLongMetric * unserialise(const std::string & serialised) const = 0;
     387                 :            : };
     388                 :            : 
     389                 :            : /** Calculate the great-circle distance between two coordinates on a sphere.
     390                 :            :  *
     391                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     392                 :            :  *
     393                 :            :  *  This uses the haversine formula to calculate the distance.  Note that this
     394                 :            :  *  formula is subject to inaccuracy due to numerical errors for coordinates on
     395                 :            :  *  the opposite side of the sphere.
     396                 :            :  *
     397                 :            :  *  See https://en.wikipedia.org/wiki/Haversine_formula
     398                 :            :  */
     399         [ -  + ]:      14574 : class XAPIAN_VISIBILITY_DEFAULT GreatCircleMetric : public LatLongMetric {
     400                 :            :     /** The radius of the sphere in metres.
     401                 :            :      */
     402                 :            :     double radius;
     403                 :            : 
     404                 :            :   public:
     405                 :            :     /** Construct a GreatCircleMetric.
     406                 :            :      *
     407                 :            :      *  The (quadratic mean) radius of the Earth will be used by this
     408                 :            :      *  calculator.
     409                 :            :      */
     410                 :            :     GreatCircleMetric();
     411                 :            : 
     412                 :            :     /** Construct a GreatCircleMetric using a specified radius.
     413                 :            :      *
     414                 :            :      *  This is useful for data sets in which the points are not on Earth (eg,
     415                 :            :      *  a database of features on Mars).
     416                 :            :      *
     417                 :            :      *  @param radius_ The radius of the sphere to use, in metres.
     418                 :            :      */
     419                 :            :     explicit GreatCircleMetric(double radius_);
     420                 :            : 
     421                 :            :     /** Return the great-circle distance between points on the sphere.
     422                 :            :      */
     423                 :            :     double pointwise_distance(const LatLongCoord & a,
     424                 :            :                               const LatLongCoord &b) const;
     425                 :            : 
     426                 :            :     LatLongMetric * clone() const;
     427                 :            :     std::string name() const;
     428                 :            :     std::string serialise() const;
     429                 :            :     LatLongMetric * unserialise(const std::string & serialised) const;
     430                 :            : };
     431                 :            : 
     432                 :            : /** Posting source which returns a weight based on geospatial distance.
     433                 :            :  *
     434                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     435                 :            :  *
     436                 :            :  *  Results are weighted by the distance from a fixed point, or list of points,
     437                 :            :  *  calculated according to the metric supplied.  If multiple points are
     438                 :            :  *  supplied (either in the constructor, or in the coordinates stored in a
     439                 :            :  *  document), the closest pointwise distance is used.
     440                 :            :  *
     441                 :            :  *  Documents further away than a specified maximum range (or with no location
     442                 :            :  *  stored in the specified slot) will not be returned.
     443                 :            :  *
     444                 :            :  *  The weight returned is computed from the distance using the formula:
     445                 :            :  *
     446                 :            :  *  k1 * pow(distance + k1, -k2)
     447                 :            :  *
     448                 :            :  *  (Where k1 and k2 are (strictly) positive, floating point constants, which
     449                 :            :  *  default to 1000 and 1, respectively.  Distance is measured in metres, so
     450                 :            :  *  this means that something at the centre gets a weight of 1.0, something 1km
     451                 :            :  *  away gets a weight of 0.5, and something 3km away gets a weight of 0.25,
     452                 :            :  *  etc)
     453                 :            :  */
     454                 :            : class XAPIAN_VISIBILITY_DEFAULT LatLongDistancePostingSource : public ValuePostingSource
     455                 :            : {
     456                 :            :     /// Current distance from centre.
     457                 :            :     double dist;
     458                 :            : 
     459                 :            :     /// Centre, to compute distance from.
     460                 :            :     LatLongCoords centre;
     461                 :            : 
     462                 :            :     /// Metric to compute the distance with.
     463                 :            :     const LatLongMetric * metric;
     464                 :            : 
     465                 :            :     /// Maximum range to allow.  If set to 0, there is no maximum range.
     466                 :            :     double max_range;
     467                 :            : 
     468                 :            :     /// Constant used in weighting function.
     469                 :            :     double k1;
     470                 :            : 
     471                 :            :     /// Constant used in weighting function.
     472                 :            :     double k2;
     473                 :            : 
     474                 :            :     /// Calculate the distance for the current document.
     475                 :            :     void calc_distance();
     476                 :            : 
     477                 :            :     /// Internal constructor; used by clone() and serialise().
     478                 :            :     LatLongDistancePostingSource(Xapian::valueno slot_,
     479                 :            :                                  const LatLongCoords & centre_,
     480                 :            :                                  const LatLongMetric * metric_,
     481                 :            :                                  double max_range_,
     482                 :            :                                  double k1_,
     483                 :            :                                  double k2_);
     484                 :            : 
     485                 :            :   public:
     486                 :            :     /** Construct a new posting source which returns only documents within
     487                 :            :      *  range of one of the central coordinates.
     488                 :            :      *
     489                 :            :      *  @param slot_ The value slot to read values from.
     490                 :            :      *  @param centre_ The centre point to use for distance calculations.
     491                 :            :      *  @param metric_ The metric to use for distance calculations.
     492                 :            :      *  @param max_range_ The maximum distance for documents which are returned.
     493                 :            :      *  @param k1_ The k1 constant to use in the weighting function.
     494                 :            :      *  @param k2_ The k2 constant to use in the weighting function.
     495                 :            :      */
     496                 :            :     LatLongDistancePostingSource(Xapian::valueno slot_,
     497                 :            :                                  const LatLongCoords & centre_,
     498                 :            :                                  const LatLongMetric & metric_,
     499                 :            :                                  double max_range_ = 0.0,
     500                 :            :                                  double k1_ = 1000.0,
     501                 :            :                                  double k2_ = 1.0);
     502                 :            : 
     503                 :            :     /** Construct a new posting source which returns only documents within
     504                 :            :      *  range of one of the central coordinates.
     505                 :            :      *
     506                 :            :      *  @param slot_ The value slot to read values from.
     507                 :            :      *  @param centre_ The centre point to use for distance calculations.
     508                 :            :      *  @param max_range_ The maximum distance for documents which are returned.
     509                 :            :      *  @param k1_ The k1 constant to use in the weighting function.
     510                 :            :      *  @param k2_ The k2 constant to use in the weighting function.
     511                 :            :      *
     512                 :            :      *  Xapian::GreatCircleMetric is used as the metric.
     513                 :            :      */
     514                 :            :     LatLongDistancePostingSource(Xapian::valueno slot_,
     515                 :            :                                  const LatLongCoords & centre_,
     516                 :            :                                  double max_range_ = 0.0,
     517                 :            :                                  double k1_ = 1000.0,
     518                 :            :                                  double k2_ = 1.0);
     519                 :            :     ~LatLongDistancePostingSource();
     520                 :            : 
     521                 :            :     void next(double min_wt);
     522                 :            :     void skip_to(Xapian::docid min_docid, double min_wt);
     523                 :            :     bool check(Xapian::docid min_docid, double min_wt);
     524                 :            : 
     525                 :            :     double get_weight() const;
     526                 :            :     LatLongDistancePostingSource * clone() const;
     527                 :            :     std::string name() const;
     528                 :            :     std::string serialise() const;
     529                 :            :     LatLongDistancePostingSource *
     530                 :            :             unserialise_with_registry(const std::string &serialised,
     531                 :            :                                       const Registry & registry) const;
     532                 :            :     void init(const Database & db_);
     533                 :            : 
     534                 :            :     std::string get_description() const;
     535                 :            : };
     536                 :            : 
     537                 :            : /** KeyMaker subclass which sorts by distance from a latitude/longitude.
     538                 :            :  *
     539                 :            :  *  Experimental - see https://xapian.org/docs/deprecation#experimental-features
     540                 :            :  *
     541                 :            :  *  Results are ordered by the distance from a fixed point, or list of points,
     542                 :            :  *  calculated according to the metric supplied.  If multiple points are
     543                 :            :  *  supplied (either in the constructor, or in the coordinates stored in a
     544                 :            :  *  document), the closest pointwise distance is used.
     545                 :            :  *
     546                 :            :  *  If a document contains no coordinate stored in the specified slot, a
     547                 :            :  *  special value for the distance will be used.  This defaults to a large
     548                 :            :  *  number, so that such results get a low rank, but may be specified by a
     549                 :            :  *  constructor parameter.
     550                 :            :  */
     551                 :            : class XAPIAN_VISIBILITY_DEFAULT LatLongDistanceKeyMaker : public KeyMaker {
     552                 :            : 
     553                 :            :     /// The value slot to read.
     554                 :            :     Xapian::valueno slot;
     555                 :            : 
     556                 :            :     /// The centre point (or points) for distance calculation.
     557                 :            :     LatLongCoords centre;
     558                 :            : 
     559                 :            :     /// The metric to use when calculating distances.
     560                 :            :     const LatLongMetric * metric;
     561                 :            : 
     562                 :            :     /// The default key to return, for documents with no value stored.
     563                 :            :     std::string defkey;
     564                 :            : 
     565                 :            :   public:
     566                 :            :     /** Construct a LatLongDistanceKeyMaker.
     567                 :            :      *
     568                 :            :      *  @param slot_            Value slot to use.
     569                 :            :      *  @param centre_          List of points to calculate distance from
     570                 :            :      *                          (closest distance is used).
     571                 :            :      *  @param metric_          LatLongMetric to use.
     572                 :            :      *  @param defdistance      Distance to use for docs with no value set.
     573                 :            :      */
     574                 :          1 :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     575                 :            :                             const LatLongCoords & centre_,
     576                 :            :                             const LatLongMetric & metric_,
     577                 :            :                             double defdistance)
     578                 :            :             : slot(slot_),
     579                 :            :               centre(centre_),
     580         [ +  - ]:          1 :               metric(metric_.clone()),
     581 [ +  - ][ +  - ]:          2 :               defkey(sortable_serialise(defdistance))
     582                 :          1 :     {}
     583                 :            : 
     584                 :            :     /** Construct a LatLongDistanceKeyMaker.
     585                 :            :      *
     586                 :            :      *  @param slot_            Value slot to use.
     587                 :            :      *  @param centre_          List of points to calculate distance from
     588                 :            :      *                          (closest distance is used).
     589                 :            :      *  @param metric_          LatLongMetric to use.
     590                 :            :      *
     591                 :            :      *  Documents where no value is set are assumed to be a large distance
     592                 :            :      *  away.
     593                 :            :      */
     594                 :          1 :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     595                 :            :                             const LatLongCoords & centre_,
     596                 :            :                             const LatLongMetric & metric_)
     597                 :            :             : slot(slot_),
     598                 :            :               centre(centre_),
     599         [ +  - ]:          1 :               metric(metric_.clone()),
     600 [ +  - ][ +  - ]:          2 :               defkey(9, '\xff')
     601                 :          1 :     {}
     602                 :            : 
     603                 :            :     /** Construct a LatLongDistanceKeyMaker.
     604                 :            :      *
     605                 :            :      *  @param slot_            Value slot to use.
     606                 :            :      *  @param centre_          List of points to calculate distance from
     607                 :            :      *                          (closest distance is used).
     608                 :            :      *
     609                 :            :      *  Xapian::GreatCircleMetric is used as the metric.
     610                 :            :      *
     611                 :            :      *  Documents where no value is set are assumed to be a large distance
     612                 :            :      *  away.
     613                 :            :      */
     614                 :            :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     615                 :            :                             const LatLongCoords & centre_)
     616                 :            :             : slot(slot_),
     617                 :            :               centre(centre_),
     618                 :            :               metric(new Xapian::GreatCircleMetric()),
     619                 :            :               defkey(9, '\xff')
     620                 :            :     {}
     621                 :            : 
     622                 :            :     /** Construct a LatLongDistanceKeyMaker.
     623                 :            :      *
     624                 :            :      *  @param slot_            Value slot to use.
     625                 :            :      *  @param centre_          Point to calculate distance from.
     626                 :            :      *  @param metric_          LatLongMetric to use.
     627                 :            :      *  @param defdistance      Distance to use for docs with no value set.
     628                 :            :      */
     629                 :            :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     630                 :            :                             const LatLongCoord & centre_,
     631                 :            :                             const LatLongMetric & metric_,
     632                 :            :                             double defdistance)
     633                 :            :             : slot(slot_),
     634                 :            :               centre(),
     635                 :            :               metric(metric_.clone()),
     636                 :            :               defkey(sortable_serialise(defdistance))
     637                 :            :     {
     638                 :            :         centre.append(centre_);
     639                 :            :     }
     640                 :            : 
     641                 :            :     /** Construct a LatLongDistanceKeyMaker.
     642                 :            :      *
     643                 :            :      *  @param slot_            Value slot to use.
     644                 :            :      *  @param centre_          Point to calculate distance from.
     645                 :            :      *  @param metric_          LatLongMetric to use.
     646                 :            :      *
     647                 :            :      *  Documents where no value is set are assumed to be a large distance
     648                 :            :      *  away.
     649                 :            :      */
     650                 :            :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     651                 :            :                             const LatLongCoord & centre_,
     652                 :            :                             const LatLongMetric & metric_)
     653                 :            :             : slot(slot_),
     654                 :            :               centre(),
     655                 :            :               metric(metric_.clone()),
     656                 :            :               defkey(9, '\xff')
     657                 :            :     {
     658                 :            :         centre.append(centre_);
     659                 :            :     }
     660                 :            : 
     661                 :            :     /** Construct a LatLongDistanceKeyMaker.
     662                 :            :      *
     663                 :            :      *  @param slot_            Value slot to use.
     664                 :            :      *  @param centre_          Point to calculate distance from.
     665                 :            :      *
     666                 :            :      *  Xapian::GreatCircleMetric is used as the metric.
     667                 :            :      *
     668                 :            :      *  Documents where no value is set are assumed to be a large distance
     669                 :            :      *  away.
     670                 :            :      */
     671                 :            :     LatLongDistanceKeyMaker(Xapian::valueno slot_,
     672                 :            :                             const LatLongCoord & centre_)
     673                 :            :             : slot(slot_),
     674                 :            :               centre(),
     675                 :            :               metric(new Xapian::GreatCircleMetric()),
     676                 :            :               defkey(9, '\xff')
     677                 :            :     {
     678                 :            :         centre.append(centre_);
     679                 :            :     }
     680                 :            : 
     681                 :            :     ~LatLongDistanceKeyMaker();
     682                 :            : 
     683                 :            :     std::string operator()(const Xapian::Document & doc) const;
     684                 :            : };
     685                 :            : 
     686                 :            : }
     687                 :            : 
     688                 :            : #endif /* XAPIAN_INCLUDED_GEOSPATIAL_H */

Generated by: LCOV version 1.11