]> git.openstreetmap.org Git - nominatim.git/blob - lib-php/TokenPostcode.php
avoid near searches in very large areas
[nominatim.git] / lib-php / TokenPostcode.php
1 <?php
2 /**
3  * SPDX-License-Identifier: GPL-2.0-only
4  *
5  * This file is part of Nominatim. (https://nominatim.org)
6  *
7  * Copyright (C) 2022 by the Nominatim developer community.
8  * For a full list of authors see the git log.
9  */
10
11 namespace Nominatim\Token;
12
13 /**
14  * A postcode token.
15  */
16 class Postcode
17 {
18     /// Database word id, if available.
19     private $iId;
20     /// Full normalized postcode (upper cased).
21     private $sPostcode;
22     // Optional country code the postcode belongs to (currently unused).
23     private $sCountryCode;
24
25     public function __construct($iId, $sPostcode, $sCountryCode = '')
26     {
27         $this->iId = $iId;
28         $this->sPostcode = $sPostcode;
29         $this->sCountryCode = empty($sCountryCode) ? '' : $sCountryCode;
30     }
31
32     public function getId()
33     {
34         return $this->iId;
35     }
36
37     /**
38      * Check if the token can be added to the given search.
39      * Derive new searches by adding this token to an existing search.
40      *
41      * @param object  $oSearch      Partial search description derived so far.
42      * @param object  $oPosition    Description of the token position within
43                                     the query.
44      *
45      * @return True if the token is compatible with the search configuration
46      *         given the position.
47      */
48     public function isExtendable($oSearch, $oPosition)
49     {
50         return !$oSearch->hasPostcode() && $oPosition->maybePhrase('postalcode');
51     }
52
53     /**
54      * Derive new searches by adding this token to an existing search.
55      *
56      * @param object  $oSearch      Partial search description derived so far.
57      * @param object  $oPosition    Description of the token position within
58                                     the query.
59      *
60      * @return SearchDescription[] List of derived search descriptions.
61      */
62     public function extendSearch($oSearch, $oPosition)
63     {
64         $aNewSearches = array();
65
66         // If we have structured search or this is the first term,
67         // make the postcode the primary search element.
68         if ($oSearch->hasOperator(\Nominatim\Operator::NONE) && $oPosition->isFirstToken()) {
69             $oNewSearch = $oSearch->clone(1);
70             $oNewSearch->setPostcodeAsName($this->iId, $this->sPostcode);
71
72             $aNewSearches[] = $oNewSearch;
73         }
74
75         // If we have a structured search or this is not the first term,
76         // add the postcode as an addendum.
77         if (!$oSearch->hasOperator(\Nominatim\Operator::POSTCODE)
78             && ($oPosition->isPhrase('postalcode') || $oSearch->hasName())
79         ) {
80             $iPenalty = 1;
81             if (strlen($this->sPostcode) < 4) {
82                 $iPenalty += 4 - strlen($this->sPostcode);
83             }
84             $oNewSearch = $oSearch->clone($iPenalty);
85             $oNewSearch->setPostcode($this->sPostcode);
86
87             $aNewSearches[] = $oNewSearch;
88         }
89
90         return $aNewSearches;
91     }
92
93     public function debugInfo()
94     {
95         return array(
96                 'ID' => $this->iId,
97                 'Type' => 'postcode',
98                 'Info' => $this->sPostcode.'('.$this->sCountryCode.')'
99                );
100     }
101
102     public function debugCode()
103     {
104         return 'P';
105     }
106 }