mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-03-12 05:44:06 +00:00
fix handling of near queries with special search
Make sure to use the classtype tables with near search and allow to search for arbitrary key/values (forbidding it for viewbox searches). Add tests for near queries.
This commit is contained in:
@@ -1274,8 +1274,8 @@ class Geocode
|
|||||||
}
|
}
|
||||||
|
|
||||||
// No location term?
|
// No location term?
|
||||||
if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['oNear']) {
|
if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress'])) {
|
||||||
if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber']) {
|
if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber'] && !$aSearch['oNear']) {
|
||||||
// Just looking for a country by code - look it up
|
// Just looking for a country by code - look it up
|
||||||
if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) {
|
if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) {
|
||||||
$sSQL = "SELECT place_id FROM placex WHERE country_code='".$aSearch['sCountryCode']."' AND rank_search = 4";
|
$sSQL = "SELECT place_id FROM placex WHERE country_code='".$aSearch['sCountryCode']."' AND rank_search = 4";
|
||||||
@@ -1295,39 +1295,32 @@ class Geocode
|
|||||||
if (chksql($this->oDB->getOne($sSQL))) {
|
if (chksql($this->oDB->getOne($sSQL))) {
|
||||||
$sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct";
|
$sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct";
|
||||||
if ($sCountryCodesSQL) $sSQL .= " JOIN placex USING (place_id)";
|
if ($sCountryCodesSQL) $sSQL .= " JOIN placex USING (place_id)";
|
||||||
$sSQL .= " WHERE st_contains($this->sViewboxSmallSQL, ct.centroid)";
|
if ($aSearch['oNear']) {
|
||||||
|
$sSQL .= " WHERE ".$aSearch['oNear']->withinSQL('ct.centroid');
|
||||||
|
} else {
|
||||||
|
$sSQL .= " WHERE st_contains($this->sViewboxSmallSQL, ct.centroid)";
|
||||||
|
}
|
||||||
if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
|
if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
|
||||||
if (sizeof($this->aExcludePlaceIDs)) {
|
if (sizeof($this->aExcludePlaceIDs)) {
|
||||||
$sSQL .= " AND place_id not in (".join(',', $this->aExcludePlaceIDs).")";
|
$sSQL .= " AND place_id not in (".join(',', $this->aExcludePlaceIDs).")";
|
||||||
}
|
}
|
||||||
if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
|
if ($this->sViewboxCentreSQL) {
|
||||||
|
$sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
|
||||||
|
} elseif ($aSearch['oNear']) {
|
||||||
|
$sSQL .= " ORDER BY ".$aSearch['oNear']->distanceSQL('ct.centroid').' ASC';
|
||||||
|
}
|
||||||
$sSQL .= " limit $this->iLimit";
|
$sSQL .= " limit $this->iLimit";
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
|
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
|
||||||
|
} else if ($aSearch['oNear']) {
|
||||||
// If excluded place IDs are given, it is fair to assume that
|
|
||||||
// there have been results in the small box, so no further
|
|
||||||
// expansion in that case.
|
|
||||||
// Also don't expand if bounded results were requested.
|
|
||||||
if (!sizeof($aPlaceIDs) && !sizeof($this->aExcludePlaceIDs) && !$this->bBoundedSearch) {
|
|
||||||
$sSQL = "SELECT place_id FROM place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct";
|
|
||||||
if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)";
|
|
||||||
$sSQL .= " WHERE ST_Contains($this->sViewboxLargeSQL, ct.centroid)";
|
|
||||||
if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
|
|
||||||
if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, ct.centroid) ASC";
|
|
||||||
$sSQL .= " LIMIT $this->iLimit";
|
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
|
||||||
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$sSQL = "SELECT place_id ";
|
$sSQL = "SELECT place_id ";
|
||||||
$sSQL .= "FROM placex ";
|
$sSQL .= "FROM placex ";
|
||||||
$sSQL .= "WHERE class='".$aSearch['sClass']."' ";
|
$sSQL .= "WHERE class='".$aSearch['sClass']."' ";
|
||||||
$sSQL .= " AND type='".$aSearch['sType']."'";
|
$sSQL .= " AND type='".$aSearch['sType']."'";
|
||||||
$sSQL .= " AND ST_Contains($this->sViewboxSmallSQL, geometry) ";
|
$sSQL .= " AND ".$aSearch['oNear']->withinSQL('geometry');
|
||||||
$sSQL .= " AND linked_place_id is null";
|
$sSQL .= " AND linked_place_id is null";
|
||||||
if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
|
if ($sCountryCodesSQL) $sSQL .= " AND country_code in ($sCountryCodesSQL)";
|
||||||
if ($this->sViewboxCentreSQL) $sSQL .= " ORDER BY ST_Distance($this->sViewboxCentreSQL, centroid) ASC";
|
$sSQL .= " ORDER BY ".$aSearch['oNear']->distanceSQL('centroid')." ASC";
|
||||||
$sSQL .= " LIMIT $this->iLimit";
|
$sSQL .= " LIMIT $this->iLimit";
|
||||||
if (CONST_Debug) var_dump($sSQL);
|
if (CONST_Debug) var_dump($sSQL);
|
||||||
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
|
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
|
||||||
|
|||||||
@@ -73,6 +73,12 @@ Feature: Search queries
|
|||||||
| city |
|
| city |
|
||||||
| Montevideo |
|
| Montevideo |
|
||||||
|
|
||||||
|
Scenario: Country search with bounded viewbox remain in the area
|
||||||
|
When sending json search query "" with address
|
||||||
|
| bounded | viewbox | country |
|
||||||
|
| 1 | -56.16786,-34.84061,-56.12525,-34.86526 | de |
|
||||||
|
Then less than 1 result is returned
|
||||||
|
|
||||||
Scenario: Search with bounded viewboxlbrt in right area
|
Scenario: Search with bounded viewboxlbrt in right area
|
||||||
When sending json search query "bar" with address
|
When sending json search query "bar" with address
|
||||||
| bounded | viewboxlbrt |
|
| bounded | viewboxlbrt |
|
||||||
@@ -90,7 +96,7 @@ Feature: Search queries
|
|||||||
| ^[^,]*[Rr]estaurant.* |
|
| ^[^,]*[Rr]estaurant.* |
|
||||||
|
|
||||||
Scenario: bounded search remains within viewbox, even with no results
|
Scenario: bounded search remains within viewbox, even with no results
|
||||||
When sending json search query "restaurant"
|
When sending json search query "[restaurant]"
|
||||||
| bounded | viewbox |
|
| bounded | viewbox |
|
||||||
| 1 | 43.5403125,-5.6563282,43.54285,-5.662003 |
|
| 1 | 43.5403125,-5.6563282,43.54285,-5.662003 |
|
||||||
Then less than 1 result is returned
|
Then less than 1 result is returned
|
||||||
|
|||||||
@@ -84,6 +84,18 @@ Feature: Search queries
|
|||||||
| class | type |
|
| class | type |
|
||||||
| amenity | place_of_worship |
|
| amenity | place_of_worship |
|
||||||
|
|
||||||
|
Scenario: POI search near given coordinate
|
||||||
|
When sending json search query "restaurant near 47.16712,9.51100"
|
||||||
|
Then results contain
|
||||||
|
| class | type |
|
||||||
|
| amenity | restaurant |
|
||||||
|
|
||||||
|
Scenario: Arbitrary key/value search near given coordinate
|
||||||
|
When sending json search query "[man_made=mast] 47.15739,9.61264"
|
||||||
|
Then results contain
|
||||||
|
| class | type |
|
||||||
|
| man_made | mast |
|
||||||
|
|
||||||
# https://trac.openstreetmap.org/ticket/5094
|
# https://trac.openstreetmap.org/ticket/5094
|
||||||
Scenario: housenumbers are ordered by complete match first
|
Scenario: housenumbers are ordered by complete match first
|
||||||
When sending json search query "6395 geminis, montevideo" with address
|
When sending json search query "6395 geminis, montevideo" with address
|
||||||
|
|||||||
Reference in New Issue
Block a user