mirror of
https://github.com/osm-search/Nominatim.git
synced 2026-03-11 13:24:07 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user