]> git.openstreetmap.org Git - nominatim.git/blob - lib-php/TokenHousenumber.php
Merge pull request #2511 from lonvia/fix-combination-error-needs-address
[nominatim.git] / lib-php / TokenHousenumber.php
1 <?php
2
3 namespace Nominatim\Token;
4
5 /**
6  * A house number token.
7  */
8 class HouseNumber
9 {
10     /// Database word id, if available.
11     private $iId;
12     /// Normalized house number.
13     private $sToken;
14
15     public function __construct($iId, $sToken)
16     {
17         $this->iId = $iId;
18         $this->sToken = $sToken;
19     }
20
21     public function getId()
22     {
23         return $this->iId;
24     }
25
26     /**
27      * Check if the token can be added to the given search.
28      * Derive new searches by adding this token to an existing search.
29      *
30      * @param object  $oSearch      Partial search description derived so far.
31      * @param object  $oPosition    Description of the token position within
32                                     the query.
33      *
34      * @return True if the token is compatible with the search configuration
35      *         given the position.
36      */
37     public function isExtendable($oSearch, $oPosition)
38     {
39         return !$oSearch->hasHousenumber()
40                && !$oSearch->hasOperator(\Nominatim\Operator::POSTCODE)
41                && $oPosition->maybePhrase('street');
42     }
43
44     /**
45      * Derive new searches by adding this token to an existing search.
46      *
47      * @param object  $oSearch      Partial search description derived so far.
48      * @param object  $oPosition    Description of the token position within
49                                     the query.
50      *
51      * @return SearchDescription[] List of derived search descriptions.
52      */
53     public function extendSearch($oSearch, $oPosition)
54     {
55         $aNewSearches = array();
56
57         // sanity check: if the housenumber is not mainly made
58         // up of numbers, add a penalty
59         $iSearchCost = 1;
60         if (preg_match('/\\d/', $this->sToken) === 0
61             || preg_match_all('/[^0-9]/', $this->sToken, $aMatches) > 2) {
62             $iSearchCost += strlen($this->sToken) - 1;
63         }
64         if (!$oSearch->hasOperator(\Nominatim\Operator::NONE)) {
65             $iSearchCost++;
66         }
67         if (empty($this->iId)) {
68             $iSearchCost++;
69         }
70         // also must not appear in the middle of the address
71         if ($oSearch->hasAddress() || $oSearch->hasPostcode()) {
72             $iSearchCost++;
73         }
74
75         $oNewSearch = $oSearch->clone($iSearchCost);
76         $oNewSearch->setHousenumber($this->sToken);
77         $aNewSearches[] = $oNewSearch;
78
79         // Housenumbers may appear in the name when the place has its own
80         // address terms.
81         if ($this->iId !== null
82             && ($oSearch->getNamePhrase() >= 0 || !$oSearch->hasName())
83             && !$oSearch->hasAddress()
84         ) {
85             $oNewSearch = $oSearch->clone($iSearchCost);
86             $oNewSearch->setHousenumberAsName($this->iId);
87
88             $aNewSearches[] = $oNewSearch;
89         }
90
91         return $aNewSearches;
92     }
93
94
95     public function debugInfo()
96     {
97         return array(
98                 'ID' => $this->iId,
99                 'Type' => 'house number',
100                 'Info' => array('nr' => $this->sToken)
101                );
102     }
103
104     public function debugCode()
105     {
106         return 'H';
107     }
108 }