+ // If we have a structured search or this is not the first term,
+ // add the postcode as an addendum.
+ if ($this->iOperator != Operator::POSTCODE
+ && ($sPhraseType == 'postalcode' || !empty($this->aName))
+ ) {
+ $oSearch = clone $this;
+ $oSearch->iSearchRank++;
+ if (strlen($oSearchTerm->sPostcode) < 4) {
+ $oSearch->iSearchRank += 4 - strlen($oSearchTerm->sPostcode);
+ }
+ $oSearch->sPostcode = $oSearchTerm->sPostcode;
+ $aNewSearches[] = $oSearch;
+ }
+ }
+ } elseif (($sPhraseType == '' || $sPhraseType == 'street')
+ && is_a($oSearchTerm, '\Nominatim\Token\HouseNumber')
+ ) {
+ if (!$this->sHouseNumber && $this->iOperator != Operator::POSTCODE) {
+ $oSearch = clone $this;
+ $oSearch->iSearchRank++;
+ $oSearch->sHouseNumber = $oSearchTerm->sToken;
+ // sanity check: if the housenumber is not mainly made
+ // up of numbers, add a penalty
+ if (preg_match('/\\d/', $oSearch->sHouseNumber) === 0
+ || preg_match_all('/[^0-9]/', $oSearch->sHouseNumber, $aMatches) > 2) {
+ $oSearch->iSearchRank++;
+ }
+ if (empty($oSearchTerm->iId)) {
+ $oSearch->iSearchRank++;
+ }
+ // also must not appear in the middle of the address
+ if (!empty($this->aAddress)
+ || (!empty($this->aAddressNonSearch))
+ || $this->sPostcode
+ ) {
+ $oSearch->iSearchRank++;
+ }
+ $aNewSearches[] = $oSearch;
+ // Housenumbers may appear in the name when the place has its own
+ // address terms.
+ if ($oSearchTerm->iId !== null
+ && ($this->iNamePhrase >= 0 || empty($this->aName))
+ && empty($this->aAddress)
+ ) {
+ $oSearch = clone $this;
+ $oSearch->iSearchRank++;
+ $oSearch->aAddress = $this->aName;
+ $oSearch->bRareName = false;
+ $oSearch->aName = array($oSearchTerm->iId => $oSearchTerm->iId);
+ $aNewSearches[] = $oSearch;
+ }
+ }
+ } elseif ($sPhraseType == ''
+ && is_a($oSearchTerm, '\Nominatim\Token\SpecialTerm')
+ ) {
+ if ($this->iOperator == Operator::NONE) {
+ $oSearch = clone $this;
+ $oSearch->iSearchRank++;
+
+ $iOp = $oSearchTerm->iOperator;
+ if ($iOp == Operator::NONE) {
+ if (!empty($this->aName) || $this->oContext->isBoundedSearch()) {
+ $iOp = Operator::NAME;
+ } else {
+ $iOp = Operator::NEAR;
+ }
+ $oSearch->iSearchRank += 2;
+ }