From 8eb066c6928b03fd4cef46a8ea4da5149d4d1fd9 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Mon, 18 Sep 2017 22:07:08 +0200 Subject: [PATCH] reinstate key-value amenity search Reenable search by the secret special term [key=value] matching against the given main tag. Note that for most cases that works only for tags that also have a special search table. --- lib/Geocode.php | 45 ++++++++++++++++------------- test/bdd/api/search/queries.feature | 18 ++++++++++++ 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/lib/Geocode.php b/lib/Geocode.php index 5a8ff199..314d20bc 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -1021,15 +1021,24 @@ class Geocode // Any 'special' terms in the search? $bSpecialTerms = false; - preg_match_all('/\\[(.*)=(.*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER); - $aSpecialTerms = array(); + preg_match_all('/\\[([\\w_]*)=([\\w_]*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER); foreach ($aSpecialTermsRaw as $aSpecialTerm) { $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery); - $aSpecialTerms[strtolower($aSpecialTerm[1])] = $aSpecialTerm[2]; + if (!$bSpecialTerms) { + $aNewSearches = array(); + foreach ($aSearches as $aSearch) { + $aNewSearch = $aSearch; + $aNewSearch['sClass'] = $aSpecialTerm[1]; + $aNewSearch['sType'] = $aSpecialTerm[2]; + $aNewSearches[] = $aNewSearch; + } + + $aSearches = $aNewSearches; + $bSpecialTerms = true; + } } preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER); - $aSpecialTerms = array(); if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity']) { $aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']); unset($this->aStructuredQuery['amenity']); @@ -1037,6 +1046,10 @@ class Geocode foreach ($aSpecialTermsRaw as $aSpecialTerm) { $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery); + if ($bSpecialTerms) { + continue; + } + $sToken = chksql($this->oDB->getOne("SELECT make_standard_name('".$aSpecialTerm[1]."') AS string")); $sSQL = 'SELECT * '; $sSQL .= 'FROM ( '; @@ -1044,25 +1057,17 @@ class Geocode $sSQL .= ' FROM word '; $sSQL .= ' WHERE word_token in (\' '.$sToken.'\')'; $sSQL .= ') AS x '; - $sSQL .= ' WHERE (class is not null AND class not in (\'place\')) '; - $sSQL .= ' OR country_code is not null'; + $sSQL .= ' WHERE (class is not null AND class not in (\'place\'))'; if (CONST_Debug) var_Dump($sSQL); $aSearchWords = chksql($this->oDB->getAll($sSQL)); $aNewSearches = array(); foreach ($aSearches as $aSearch) { foreach ($aSearchWords as $aSearchTerm) { $aNewSearch = $aSearch; - if ($aSearchTerm['country_code']) { - $aNewSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']); - $aNewSearches[] = $aNewSearch; - $bSpecialTerms = true; - } - if ($aSearchTerm['class']) { - $aNewSearch['sClass'] = $aSearchTerm['class']; - $aNewSearch['sType'] = $aSearchTerm['type']; - $aNewSearches[] = $aNewSearch; - $bSpecialTerms = true; - } + $aNewSearch['sClass'] = $aSearchTerm['class']; + $aNewSearch['sType'] = $aSearchTerm['type']; + $aNewSearches[] = $aNewSearch; + $bSpecialTerms = true; } } $aSearches = $aNewSearches; @@ -1646,7 +1651,7 @@ class Geocode } elseif ($sPlaceIDs) { $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)"; } elseif ($sPlaceGeom) { - $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)"; + $sOrderBySQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)"; } $sSQL = "select distinct i.place_id".($sOrderBySQL?', i.order_term':'')." from ("; @@ -1682,7 +1687,7 @@ class Geocode $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)"; } - $sSQL = "SELECT distinct l.place_id".($sOrderBysSQL?','.$sOrderBysSQL:''); + $sSQL = "SELECT distinct l.place_id".($sOrderBySQL?','.$sOrderBySQL:''); $sSQL .= " FROM placex as l, placex as f "; $sSQL .= " WHERE f.place_id in ($sPlaceIDs) "; $sSQL .= " AND ST_DWithin(l.geometry, f.centroid, $fRange) "; @@ -1692,7 +1697,7 @@ class Geocode $sSQL .= " AND l.place_id not in (".join(',', $this->aExcludePlaceIDs).")"; } if ($sCountryCodesSQL) $sSQL .= " AND l.country_code in ($sCountryCodesSQL)"; - if ($sOrderBy) $sSQL .= "ORDER BY ".$OrderBysSQL." ASC"; + if ($sOrderBySQL) $sSQL .= "ORDER BY ".$sOrderBySQL." ASC"; if ($this->iOffset) $sSQL .= " OFFSET $this->iOffset"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); diff --git a/test/bdd/api/search/queries.feature b/test/bdd/api/search/queries.feature index dc30dc89..ccfeac40 100644 --- a/test/bdd/api/search/queries.feature +++ b/test/bdd/api/search/queries.feature @@ -66,6 +66,24 @@ Feature: Search queries | class | type | | amenity | restaurant | + Scenario: Search with key-value amenity + When sending json search query "[shop=hifi] hamburg" + Then results contain + | class | type | + | shop | hifi | + + Scenario: With multiple amenity search only the first is used + When sending json search query "[shop=hifi] [church] hamburg" + Then results contain + | class | type | + | shop | hifi | + + Scenario: With multiple amenity search only the first is used + When sending json search query "[church] [restaurant] hamburg" + Then results contain + | class | type | + | amenity | place_of_worship | + # https://trac.openstreetmap.org/ticket/5094 Scenario: housenumbers are ordered by complete match first When sending json search query "6395 geminis, montevideo" with address -- 2.39.5