protected $bIncludePolygonAsGeoJSON = false;
protected $bIncludePolygonAsKML = false;
protected $bIncludePolygonAsSVG = false;
+ protected $fPolygonSimplificationThreshold = 0.0;
protected $aExcludePlaceIDs = array();
protected $bDeDupe = true;
- protected $bReverseInPlan = false;
+ protected $bReverseInPlan = true;
protected $iLimit = 20;
protected $iFinalLimit = 10;
$this->bIncludePolygonAsSVG = $b;
}
+ function setPolygonSimplificationThreshold($f)
+ {
+ $this->fPolygonSimplificationThreshold = $f;
+ }
+
function setDeDupe($bDeDupe = true)
{
$this->bDeDupe = (bool)$bDeDupe;
$sSQL .= "and 30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
$sSQL .= "group by place_id";
if (!$this->bDeDupe) $sSQL .= ",place_id ";
+ /*
$sSQL .= " union ";
$sSQL .= "select 'L' as osm_type,place_id as osm_id,'place' as class,'house' as type,null as admin_level,30 as rank_search,30 as rank_address,min(place_id) as place_id, min(parent_place_id) as parent_place_id,'us' as country_code,";
$sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,";
$sSQL .= "group by place_id";
if (!$this->bDeDupe) $sSQL .= ",place_id";
$sSQL .= ",get_address_by_language(place_id, $sLanguagePrefArraySQL) ";
+ */
}
$sSQL .= " order by importance desc";
else $aSearch['sOperator'] = 'near'; // near = in for the moment
if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
- // Do we have a shortcut id?
- if ($aSearch['sOperator'] == 'name')
- {
- $sSQL = "select get_tagpair('".$aSearch['sClass']."', '".$aSearch['sType']."')";
- if ($iAmenityID = $this->oDB->getOne($sSQL))
- {
- $aValidTokens[$aSearch['sClass'].':'.$aSearch['sType']] = array('word_id' => $iAmenityID);
- $aSearch['aName'][$iAmenityID] = $iAmenityID;
- $aSearch['sClass'] = '';
- $aSearch['sType'] = '';
- }
- }
if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
}
}
if (!$this->sQuery && !$this->aStructuredQuery) return false;
$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
-
$sCountryCodesSQL = false;
if ($this->aCountryCodes && sizeof($this->aCountryCodes))
{
preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
$aSpecialTerms = array();
- if (isset($aStructuredQuery['amenity']) && $aStructuredQuery['amenity'])
+ if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity'])
{
- $aSpecialTermsRaw[] = array('['.$aStructuredQuery['amenity'].']', $aStructuredQuery['amenity']);
- unset($aStructuredQuery['amenity']);
+ $aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']);
+ unset($this->aStructuredQuery['amenity']);
}
foreach($aSpecialTermsRaw as $aSpecialTerm)
{
foreach($aDatabaseWords as $aToken)
{
// Very special case - require 2 letter country param to match the country code found
- if ($bStructuredPhrases && $aToken['country_code'] && !empty($aStructuredQuery['country'])
- && strlen($aStructuredQuery['country']) == 2 && strtolower($aStructuredQuery['country']) != $aToken['country_code'])
+ if ($bStructuredPhrases && $aToken['country_code'] && !empty($this->aStructuredQuery['country'])
+ && strlen($this->aStructuredQuery['country']) == 2 && strtolower($this->aStructuredQuery['country']) != $aToken['country_code'])
{
continue;
}
if (CONST_Debug) var_Dump($aGroupedSearches);
- if (CONST_Search_TryDroppedAddressTerms && sizeof($aStructuredQuery) > 0)
+ if (CONST_Search_TryDroppedAddressTerms && sizeof($this->aStructuredQuery) > 0)
{
$aCopyGroupedSearches = $aGroupedSearches;
foreach($aCopyGroupedSearches as $iGroup => $aSearches)
// TODO: filter out the pointless search terms (2 letter name tokens and less)
// they might be right - but they are just too darned expensive to run
if (sizeof($aSearch['aName'])) $aTerms[] = "name_vector @> ARRAY[".join($aSearch['aName'],",")."]";
- if (sizeof($aSearch['aNameNonSearch'])) $aTerms[] = "array_cat(name_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aNameNonSearch'],",")."]";
+ //if (sizeof($aSearch['aNameNonSearch'])) $aTerms[] = "array_cat(name_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aNameNonSearch'],",")."]";
if (sizeof($aSearch['aAddress']) && $aSearch['aName'] != $aSearch['aAddress'])
{
// For infrequent name terms disable index usage for address
sizeof($aSearch['aName']) == 1 &&
$aWordFrequencyScores[$aSearch['aName'][reset($aSearch['aName'])]] < CONST_Search_NameOnlySearchFrequencyThreshold)
{
- $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join(array_merge($aSearch['aAddress'],$aSearch['aAddressNonSearch']),",")."]";
+ //$aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join(array_merge($aSearch['aAddress'],$aSearch['aAddressNonSearch']),",")."]";
+ $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddress'],",")."]";
}
else
{
$aTerms[] = "nameaddress_vector @> ARRAY[".join($aSearch['aAddress'],",")."]";
- if (sizeof($aSearch['aAddressNonSearch'])) $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddressNonSearch'],",")."]";
+ //if (sizeof($aSearch['aAddressNonSearch'])) $aTerms[] = "array_cat(nameaddress_vector,ARRAY[]::integer[]) @> ARRAY[".join($aSearch['aAddressNonSearch'],",")."]";
}
}
if ($aSearch['sCountryCode']) $aTerms[] = "country_code = '".pg_escape_string($aSearch['sCountryCode'])."'";
$aPlaceIDs = $this->oDB->getCol($sSQL);
// If not try the aux fallback table
+ /*
if (!sizeof($aPlaceIDs))
{
$sSQL = "select place_id from location_property_aux where parent_place_id in (".$sPlaceIDs.") and housenumber = '".pg_escape_string($aSearch['sHouseNumber'])."'";
if (CONST_Debug) var_dump($sSQL);
$aPlaceIDs = $this->oDB->getCol($sSQL);
}
+ */
if (!sizeof($aPlaceIDs))
{
foreach($aSearchResults as $iResNum => $aResult)
{
+ // Default
+ $fDiameter = 0.0001;
+
+ if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
+ && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
+ {
+ $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defzoom'];
+ }
+ elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
+ && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
+ {
+ $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
+ }
+ $fRadius = $fDiameter / 2;
+
if (CONST_Search_AreaPolygons)
{
// Get the bounding box and outline polygon
if ($this->bIncludePolygonAsKML) $sSQL .= ",ST_AsKML(geometry) as askml";
if ($this->bIncludePolygonAsSVG) $sSQL .= ",ST_AsSVG(geometry) as assvg";
if ($this->bIncludePolygonAsText || $this->bIncludePolygonAsPoints) $sSQL .= ",ST_AsText(geometry) as astext";
- $sSQL .= " from placex where place_id = ".$aResult['place_id'];
+ $sFrom = " from placex where place_id = ".$aResult['place_id'];
+ if ($this->fPolygonSimplificationThreshold > 0)
+ {
+ $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
+ }
+ else
+ {
+ $sSQL .= $sFrom;
+ }
+
$aPointPolygon = $this->oDB->getRow($sSQL);
if (PEAR::IsError($aPointPolygon))
{
{
preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
}
+ /*
elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch))
{
preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
}
+ */
elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['astext'],$aMatch))
{
- $fRadius = 0.01;
$iSteps = ($fRadius * 40000)^2;
$fStepSize = (2*pi())/$iSteps;
$aPolyPoints = array();
{
$aPolyPoints[] = array('',$aMatch[1]+($fRadius*sin($f)),$aMatch[2]+($fRadius*cos($f)));
}
- $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
- $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
- $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
- $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
}
}
$aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
}
}
+
+ if (abs($aPointPolygon['minlat'] - $aPointPolygon['maxlat']) < 0.0000001)
+ {
+ $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
+ $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
+ }
+ if (abs($aPointPolygon['minlon'] - $aPointPolygon['maxlon']) < 0.0000001)
+ {
+ $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
+ $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
+ }
$aResult['aBoundingBox'] = array($aPointPolygon['minlat'],$aPointPolygon['maxlat'],$aPointPolygon['minlon'],$aPointPolygon['maxlon']);
}
}
if (!isset($aResult['aBoundingBox']))
{
- // Default
- $fDiameter = 0.0001;
-
- if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
- && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
- {
- $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defzoom'];
- }
- elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
- && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
- {
- $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
- }
- $fRadius = $fDiameter / 2;
-
$iSteps = max(8,min(100,$fRadius * 3.14 * 100000));
$fStepSize = (2*pi())/$iSteps;
- $aPolyPoints = array();
- for($f = 0; $f < 2*pi(); $f += $fStepSize)
- {
- $aPolyPoints[] = array('',$aResult['lon']+($fRadius*sin($f)),$aResult['lat']+($fRadius*cos($f)));
- }
$aPointPolygon['minlat'] = $aResult['lat'] - $fRadius;
$aPointPolygon['maxlat'] = $aResult['lat'] + $fRadius;
$aPointPolygon['minlon'] = $aResult['lon'] - $fRadius;
// Output data suitable for display (points and a bounding box)
if ($this->bIncludePolygonAsPoints)
{
+ $aPolyPoints = array();
+ for($f = 0; $f < 2*pi(); $f += $fStepSize)
+ {
+ $aPolyPoints[] = array('',$aResult['lon']+($fRadius*sin($f)),$aResult['lat']+($fRadius*cos($f)));
+ }
$aResult['aPolyPoints'] = array();
foreach($aPolyPoints as $aPoint)
{
if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
&& $aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
{
- $aResult['foundorder'] = $aResult['foundorder'] + 0.000001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
+ $aResult['foundorder'] += 0.0001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
}
else
{
- $aResult['foundorder'] = $aResult['foundorder'] + 0.001;
+ $aResult['foundorder'] += 0.01;
}
$aSearchResults[$iResNum] = $aResult;
}