Sort results for near searches by proximity

If a reference coordinate is given, results really should be
sorted by distance to this point ignoring importance completely.

Fixes #796.
This commit is contained in:
Sarah Hoffmann
2017-10-10 22:42:23 +02:00
parent 97bc185152
commit 3da4c9c384

View File

@@ -398,6 +398,9 @@ class Geocode
$sSQL .= " avg(ST_X(centroid)) AS lon, "; $sSQL .= " avg(ST_X(centroid)) AS lon, ";
$sSQL .= " avg(ST_Y(centroid)) AS lat, "; $sSQL .= " avg(ST_Y(centroid)) AS lat, ";
$sSQL .= " COALESCE(importance,0.75-(rank_search::float/40)) $sImportanceSQL AS importance, "; $sSQL .= " COALESCE(importance,0.75-(rank_search::float/40)) $sImportanceSQL AS importance, ";
if ($oCtx->hasNearPoint()) {
$sSQL .= $oCtx->distanceSQL('ST_Collect(centroid)')." AS addressimportance,";
} else {
$sSQL .= " ( "; $sSQL .= " ( ";
$sSQL .= " SELECT max(p.importance*(p.rank_address+2))"; $sSQL .= " SELECT max(p.importance*(p.rank_address+2))";
$sSQL .= " FROM "; $sSQL .= " FROM ";
@@ -408,6 +411,7 @@ class Geocode
$sSQL .= " AND s.isaddress "; $sSQL .= " AND s.isaddress ";
$sSQL .= " AND p.importance is not null "; $sSQL .= " AND p.importance is not null ";
$sSQL .= " ) AS addressimportance, "; $sSQL .= " ) AS addressimportance, ";
}
$sSQL .= " (extratags->'place') AS extra_place "; $sSQL .= " (extratags->'place') AS extra_place ";
$sSQL .= " FROM placex"; $sSQL .= " FROM placex";
$sSQL .= " WHERE place_id in ($sPlaceIDs) "; $sSQL .= " WHERE place_id in ($sPlaceIDs) ";
@@ -457,6 +461,9 @@ class Geocode
if ($this->bIncludeNameDetails) $sSQL .= "null AS names,"; if ($this->bIncludeNameDetails) $sSQL .= "null AS names,";
$sSQL .= " ST_x(st_centroid(geometry)) AS lon, ST_y(st_centroid(geometry)) AS lat,"; $sSQL .= " ST_x(st_centroid(geometry)) AS lon, ST_y(st_centroid(geometry)) AS lat,";
$sSQL .= " (0.75-(rank_search::float/40)) $sImportanceSQLGeom AS importance, "; $sSQL .= " (0.75-(rank_search::float/40)) $sImportanceSQLGeom AS importance, ";
if ($oCtx->hasNearPoint()) {
$sSQL .= $oCtx->distanceSQL('geometry')." AS addressimportance,";
} else {
$sSQL .= " ("; $sSQL .= " (";
$sSQL .= " SELECT max(p.importance*(p.rank_address+2))"; $sSQL .= " SELECT max(p.importance*(p.rank_address+2))";
$sSQL .= " FROM "; $sSQL .= " FROM ";
@@ -467,6 +474,7 @@ class Geocode
$sSQL .= " AND s.isaddress"; $sSQL .= " AND s.isaddress";
$sSQL .= " AND p.importance is not null"; $sSQL .= " AND p.importance is not null";
$sSQL .= " ) AS addressimportance, "; $sSQL .= " ) AS addressimportance, ";
}
$sSQL .= " null AS extra_place "; $sSQL .= " null AS extra_place ";
$sSQL .= "FROM location_postcode lp"; $sSQL .= "FROM location_postcode lp";
$sSQL .= " WHERE place_id in ($sPlaceIDs) "; $sSQL .= " WHERE place_id in ($sPlaceIDs) ";
@@ -505,6 +513,9 @@ class Geocode
$sSQL .= " avg(st_x(centroid)) AS lon, "; $sSQL .= " avg(st_x(centroid)) AS lon, ";
$sSQL .= " avg(st_y(centroid)) AS lat,"; $sSQL .= " avg(st_y(centroid)) AS lat,";
$sSQL .= " -1.15".$sImportanceSQL." AS importance, "; $sSQL .= " -1.15".$sImportanceSQL." AS importance, ";
if ($oCtx->hasNearPoint()) {
$sSQL .= $oCtx->distanceSQL('ST_Collect(centroid)')." AS addressimportance,";
} else {
$sSQL .= " ("; $sSQL .= " (";
$sSQL .= " SELECT max(p.importance*(p.rank_address+2))"; $sSQL .= " SELECT max(p.importance*(p.rank_address+2))";
$sSQL .= " FROM "; $sSQL .= " FROM ";
@@ -515,6 +526,7 @@ class Geocode
$sSQL .= " AND s.isaddress"; $sSQL .= " AND s.isaddress";
$sSQL .= " AND p.importance is not null"; $sSQL .= " AND p.importance is not null";
$sSQL .= " ) AS addressimportance, "; $sSQL .= " ) AS addressimportance, ";
}
$sSQL .= " null AS extra_place "; $sSQL .= " null AS extra_place ";
$sSQL .= " FROM ("; $sSQL .= " FROM (";
$sSQL .= " SELECT place_id, "; // interpolate the Tiger housenumbers here $sSQL .= " SELECT place_id, "; // interpolate the Tiger housenumbers here
@@ -555,6 +567,9 @@ class Geocode
$sSQL .= " AVG(st_x(centroid)) AS lon, "; $sSQL .= " AVG(st_x(centroid)) AS lon, ";
$sSQL .= " AVG(st_y(centroid)) AS lat, "; $sSQL .= " AVG(st_y(centroid)) AS lat, ";
$sSQL .= " -0.1".$sImportanceSQL." AS importance, "; // slightly smaller than the importance for normal houses with rank 30, which is 0 $sSQL .= " -0.1".$sImportanceSQL." AS importance, "; // slightly smaller than the importance for normal houses with rank 30, which is 0
if ($oCtx->hasNearPoint()) {
$sSQL .= $oCtx->distanceSQL('ST_Collect(centroid)')." AS addressimportance,";
} else {
$sSQL .= " ("; $sSQL .= " (";
$sSQL .= " SELECT "; $sSQL .= " SELECT ";
$sSQL .= " MAX(p.importance*(p.rank_address+2)) "; $sSQL .= " MAX(p.importance*(p.rank_address+2)) ";
@@ -566,6 +581,7 @@ class Geocode
$sSQL .= " AND s.isaddress "; $sSQL .= " AND s.isaddress ";
$sSQL .= " AND p.importance is not null"; $sSQL .= " AND p.importance is not null";
$sSQL .= " ) AS addressimportance,"; $sSQL .= " ) AS addressimportance,";
}
$sSQL .= " null AS extra_place "; $sSQL .= " null AS extra_place ";
$sSQL .= " FROM ("; $sSQL .= " FROM (";
$sSQL .= " SELECT "; $sSQL .= " SELECT ";
@@ -614,6 +630,9 @@ class Geocode
$sSQL .= " avg(ST_X(centroid)) AS lon, "; $sSQL .= " avg(ST_X(centroid)) AS lon, ";
$sSQL .= " avg(ST_Y(centroid)) AS lat, "; $sSQL .= " avg(ST_Y(centroid)) AS lat, ";
$sSQL .= " -1.10".$sImportanceSQL." AS importance, "; $sSQL .= " -1.10".$sImportanceSQL." AS importance, ";
if ($oCtx->hasNearPoint()) {
$sSQL .= $oCtx->distanceSQL('ST_Collect(centroid)')." AS addressimportance,";
} else {
$sSQL .= " ( "; $sSQL .= " ( ";
$sSQL .= " SELECT max(p.importance*(p.rank_address+2))"; $sSQL .= " SELECT max(p.importance*(p.rank_address+2))";
$sSQL .= " FROM "; $sSQL .= " FROM ";
@@ -624,6 +643,7 @@ class Geocode
$sSQL .= " AND s.isaddress"; $sSQL .= " AND s.isaddress";
$sSQL .= " AND p.importance is not null"; $sSQL .= " AND p.importance is not null";
$sSQL .= " ) AS addressimportance, "; $sSQL .= " ) AS addressimportance, ";
}
$sSQL .= " null AS extra_place "; $sSQL .= " null AS extra_place ";
$sSQL .= " FROM location_property_aux "; $sSQL .= " FROM location_property_aux ";
$sSQL .= " WHERE place_id in ($sPlaceIDs) "; $sSQL .= " WHERE place_id in ($sPlaceIDs) ";
@@ -1266,6 +1286,13 @@ class Geocode
} }
} }
$aResult['name'] = $aResult['langaddress'];
if ($oCtx->hasNearPoint())
{
$aResult['importance'] = 0.001;
$aResult['foundorder'] = $aResult['addressimportance'];
} else {
// Adjust importance for the number of exact string matches in the result // Adjust importance for the number of exact string matches in the result
$aResult['importance'] = max(0.001, $aResult['importance']); $aResult['importance'] = max(0.001, $aResult['importance']);
$iCountWords = 0; $iCountWords = 0;
@@ -1279,7 +1306,6 @@ class Geocode
$aResult['importance'] = $aResult['importance'] + ($iCountWords*0.1); // 0.1 is a completely arbitrary number but something in the range 0.1 to 0.5 would seem right $aResult['importance'] = $aResult['importance'] + ($iCountWords*0.1); // 0.1 is a completely arbitrary number but something in the range 0.1 to 0.5 would seem right
$aResult['name'] = $aResult['langaddress'];
// secondary ordering (for results with same importance (the smaller the better): // secondary ordering (for results with same importance (the smaller the better):
// - approximate importance of address parts // - approximate importance of address parts
$aResult['foundorder'] = -$aResult['addressimportance']/10; $aResult['foundorder'] = -$aResult['addressimportance']/10;
@@ -1297,6 +1323,7 @@ class Geocode
} else { } else {
$aResult['foundorder'] += 0.01; $aResult['foundorder'] += 0.01;
} }
}
if (CONST_Debug) var_dump($aResult); if (CONST_Debug) var_dump($aResult);
$aSearchResults[$iResNum] = $aResult; $aSearchResults[$iResNum] = $aResult;
} }