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:
Sarah Hoffmann 2017-09-19 00:07:11 +02:00
parent ce95c55d65
commit 15a215729e
3 changed files with 34 additions and 23 deletions

View File

@ -1274,8 +1274,8 @@ class Geocode
}
// No location term?
if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['oNear']) {
if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber']) {
if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress'])) {
if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber'] && !$aSearch['oNear']) {
// Just looking for a country by code - look it up
if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank) {
$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))) {
$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->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 (sizeof($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";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));
// 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 {
} else if ($aSearch['oNear']) {
$sSQL = "SELECT place_id ";
$sSQL .= "FROM placex ";
$sSQL .= "WHERE class='".$aSearch['sClass']."' ";
$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";
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";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = chksql($this->oDB->getCol($sSQL));

View File

@ -73,6 +73,12 @@ Feature: Search queries
| city |
| 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
When sending json search query "bar" with address
| bounded | viewboxlbrt |
@ -90,7 +96,7 @@ Feature: Search queries
| ^[^,]*[Rr]estaurant.* |
Scenario: bounded search remains within viewbox, even with no results
When sending json search query "restaurant"
When sending json search query "[restaurant]"
| bounded | viewbox |
| 1 | 43.5403125,-5.6563282,43.54285,-5.662003 |
Then less than 1 result is returned

View File

@ -84,6 +84,18 @@ Feature: Search queries
| class | type |
| 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
Scenario: housenumbers are ordered by complete match first
When sending json search query "6395 geminis, montevideo" with address