]> git.openstreetmap.org Git - nominatim.git/commitdiff
tabs-to-spaces
authorMarc Tobias Metten <mtmail@gmx.net>
Sun, 4 Sep 2016 01:19:48 +0000 (03:19 +0200)
committerMarc Tobias Metten <mtmail@gmx.net>
Sun, 4 Sep 2016 01:19:48 +0000 (03:19 +0200)
55 files changed:
COPYING
lib/Geocode.php
lib/ParameterParser.php
lib/PlaceLookup.php
lib/ReverseGeocode.php
lib/cmd.php
lib/db.php
lib/init-cmd.php
lib/init-website.php
lib/init.php
lib/lib.php
lib/log.php
lib/output.php
lib/template/address-html.php
lib/template/address-json.php
lib/template/address-jsonv2.php
lib/template/address-xml.php
lib/template/details-error-html.php
lib/template/details-html.php
lib/template/includes/html-footer.php
lib/template/includes/html-header.php
lib/template/includes/html-top-navigation.php
lib/template/includes/report-errors.php
lib/template/search-batch-json.php
lib/template/search-html.php
lib/template/search-json.php
lib/template/search-jsonv2.php
lib/template/search-xml.php
settings/defaults.php
settings/phrase_settings.php
settings/settings.php
tests-php/Nominatim/NominatimTest.php
utils/blocks.php
utils/country_languages.php
utils/importWikipedia.php
utils/import_wikipedia.sh
utils/imports.php
utils/query.php
utils/server_compare.php
utils/setup.php
utils/specialphrases.php
utils/update.php
utils/warm.php
website/deletable.php
website/details.php
website/hierarchy.php
website/js/nominatim-ui.js
website/js/theme/default/style.css
website/lookup.php
website/polygons.php
website/reverse.php
website/search.php
website/status.php
wikidata/parse.php
wikidata/pull_wikipedia_logs.php

diff --git a/COPYING b/COPYING
index d511905c1647a1e311e8b20d5930a37a9c2531cd..d159169d1050894d3ea3b98e1c965c4058208fe1 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -1,12 +1,12 @@
-                   GNU GENERAL PUBLIC LICENSE
-                      Version 2, June 1991
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
-                           Preamble
+                            Preamble
 
   The licenses for most software are designed to take away your
 freedom to share and change it.  By contrast, the GNU General Public
@@ -56,7 +56,7 @@ patent must be licensed for everyone's free use or not licensed at all.
   The precise terms and conditions for copying, distribution and
 modification follow.
 
-                   GNU GENERAL PUBLIC LICENSE
+                    GNU GENERAL PUBLIC LICENSE
    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
 
   0. This License applies to any program or other work which contains
@@ -255,7 +255,7 @@ make exceptions for this.  Our decision will be guided by the two goals
 of preserving the free status of all derivatives of our free software and
 of promoting the sharing and reuse of software generally.
 
-                           NO WARRANTY
+                            NO WARRANTY
 
   11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
 FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
 PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
 POSSIBILITY OF SUCH DAMAGES.
 
-                    END OF TERMS AND CONDITIONS
+                     END OF TERMS AND CONDITIONS
 
-           How to Apply These Terms to Your New Programs
+            How to Apply These Terms to Your New Programs
 
   If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
index b102c4b210ddd1b1eb7dd56a5a4d9f2f724feb4c..f228bf7f1f3ec48c5e8d1261db122e06de5cb57c 100644 (file)
 <?php
-       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
-       require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
-
-       class Geocode
-       {
-               protected $oDB;
-
-               protected $aLangPrefOrder = array();
-
-               protected $bIncludeAddressDetails = false;
-               protected $bIncludeExtraTags = false;
-               protected $bIncludeNameDetails = false;
-
-               protected $bIncludePolygonAsPoints = false;
-               protected $bIncludePolygonAsText = false;
-               protected $bIncludePolygonAsGeoJSON = false;
-               protected $bIncludePolygonAsKML = false;
-               protected $bIncludePolygonAsSVG = false;
-               protected $fPolygonSimplificationThreshold = 0.0;
-
-               protected $aExcludePlaceIDs = array();
-               protected $bDeDupe = true;
-               protected $bReverseInPlan = false;
-
-               protected $iLimit = 20;
-               protected $iFinalLimit = 10;
-               protected $iOffset = 0;
-               protected $bFallback = false;
-
-               protected $aCountryCodes = false;
-               protected $aNearPoint = false;
-
-               protected $bBoundedSearch = false;
-               protected $aViewBox = false;
-               protected $sViewboxCentreSQL = false;
-               protected $sViewboxSmallSQL = false;
-               protected $sViewboxLargeSQL = false;
-
-               protected $iMaxRank = 20;
-               protected $iMinAddressRank = 0;
-               protected $iMaxAddressRank = 30;
-               protected $aAddressRankList = array();
-               protected $exactMatchCache = array();
-
-               protected $sAllowedTypesSQLList = false;
-
-               protected $sQuery = false;
-               protected $aStructuredQuery = false;
-
-               function Geocode(&$oDB)
-               {
-                       $this->oDB =& $oDB;
-               }
-
-               function setReverseInPlan($bReverse)
-               {
-                       $this->bReverseInPlan = $bReverse;
-               }
-
-               function setLanguagePreference($aLangPref)
-               {
-                       $this->aLangPrefOrder = $aLangPref;
-               }
-
-               function getIncludeAddressDetails()
-               {
-                       return $this->bIncludeAddressDetails;
-               }
-
-               function getIncludeExtraTags()
-               {
-                       return $this->bIncludeExtraTags;
-               }
-
-               function getIncludeNameDetails()
-               {
-                       return $this->bIncludeNameDetails;
-               }
-
-               function setIncludePolygonAsPoints($b = true)
-               {
-                       $this->bIncludePolygonAsPoints = $b;
-               }
-
-               function setIncludePolygonAsText($b = true)
-               {
-                       $this->bIncludePolygonAsText = $b;
-               }
-
-               function setIncludePolygonAsGeoJSON($b = true)
-               {
-                       $this->bIncludePolygonAsGeoJSON = $b;
-               }
-
-               function setIncludePolygonAsKML($b = true)
-               {
-                       $this->bIncludePolygonAsKML = $b;
-               }
-
-               function setIncludePolygonAsSVG($b = true)
-               {
-                       $this->bIncludePolygonAsSVG = $b;
-               }
-
-               function setPolygonSimplificationThreshold($f)
-               {
-                       $this->fPolygonSimplificationThreshold = $f;
-               }
-
-               function setLimit($iLimit = 10)
-               {
-                       if ($iLimit > 50) $iLimit = 50;
-                       if ($iLimit < 1) $iLimit = 1;
-
-                       $this->iFinalLimit = $iLimit;
-                       $this->iLimit = $iLimit + min($iLimit, 10);
-               }
-
-               function getExcludedPlaceIDs()
-               {
-                       return $this->aExcludePlaceIDs;
-               }
-
-               function getViewBoxString()
-               {
-                       if (!$this->aViewBox) return null;
-                       return $this->aViewBox[0].','.$this->aViewBox[3].','.$this->aViewBox[2].','.$this->aViewBox[1];
-               }
-
-               function setFeatureType($sFeatureType)
-               {
-                       switch($sFeatureType)
-                       {
-                       case 'country':
-                               $this->setRankRange(4, 4);
-                               break;
-                       case 'state':
-                               $this->setRankRange(8, 8);
-                               break;
-                       case 'city':
-                               $this->setRankRange(14, 16);
-                               break;
-                       case 'settlement':
-                               $this->setRankRange(8, 20);
-                               break;
-                       }
-               }
-
-               function setRankRange($iMin, $iMax)
-               {
-                       $this->iMinAddressRank = $iMin;
-                       $this->iMaxAddressRank = $iMax;
-               }
-
-               function setRoute($aRoutePoints, $fRouteWidth)
-               {
-                       $this->aViewBox = false;
-
-                       $this->sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
-                       $sSep = '';
-                       foreach($this->aRoutePoints as $aPoint)
-                       {
-                               $fPoint = (float)$aPoint;
-                               $this->sViewboxCentreSQL .= $sSep.$fPoint;
-                               $sSep = ($sSep == ' ') ? ',' : ' ';
-                       }
-                       $this->sViewboxCentreSQL .= ")'::geometry,4326)";
-
-                       $this->sViewboxSmallSQL = 'st_buffer('.$this->sViewboxCentreSQL;
-                       $this->sViewboxSmallSQL .= ','.($fRouteWidth/69).')';
-
-                       $this->sViewboxLargeSQL = 'st_buffer('.$this->sViewboxCentreSQL;
-                       $this->sViewboxLargeSQL .= ','.($fRouteWidth/30).')';
-               }
-
-               function setViewbox($aViewbox)
-               {
-                       $this->aViewBox = array_map('floatval', $aViewbox);
-
-                       $fHeight = $this->aViewBox[0] - $this->aViewBox[2];
-                       $fWidth = $this->aViewBox[1] - $this->aViewBox[3];
-                       $aBigViewBox[0] = $this->aViewBox[0] + $fHeight;
-                       $aBigViewBox[2] = $this->aViewBox[2] - $fHeight;
-                       $aBigViewBox[1] = $this->aViewBox[1] + $fWidth;
-                       $aBigViewBox[3] = $this->aViewBox[3] - $fWidth;
-
-                       $this->sViewboxCentreSQL = false;
-                       $this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$this->aViewBox[0].",".$this->aViewBox[1]."),ST_Point(".$this->aViewBox[2].",".$this->aViewBox[3].")),4326)";
-                       $this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$aBigViewBox[0].",".$aBigViewBox[1]."),ST_Point(".$aBigViewBox[2].",".$aBigViewBox[3].")),4326)";
-               }
-
-               function setNearPoint($aNearPoint, $fRadiusDeg = 0.1)
-               {
-                       $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg);
-               }
-
-               function setQuery($sQueryString)
-               {
-                       $this->sQuery = $sQueryString;
-                       $this->aStructuredQuery = false;
-               }
-
-               function getQueryString()
-               {
-                       return $this->sQuery;
-               }
-
-
-               function loadParamArray($oParams)
-               {
-                       $this->bIncludeAddressDetails = $oParams->getBool('addressdetails',
-                                                                         $this->bIncludeAddressDetails);
-                       $this->bIncludeExtraTags = $oParams->getBool('extratags',
-                                                                    $this->bIncludeExtraTags);
-                       $this->bIncludeNameDetails = $oParams->getBool('namedetails',
-                                                                      $this->bIncludeNameDetails);
-
-                       $this->bBoundedSearch = $oParams->getBool('bounded', $this->bBoundedSearch);
-                       $this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe);
-
-                       $this->setLimit($oParams->getInt('limit', $this->iFinalLimit));
-                       $this->iOffset = $oParams->getInt('offset', $this->iOffset);
-
-                       $this->bFallback = $oParams->getBool('fallback', $this->bFallback);
-
-                       // List of excluded Place IDs - used for more acurate pageing
-                       $sExcluded = $oParams->getStringList('exclude_place_ids');
-                       if ($sExcluded)
-                       {
-                               foreach($sExcluded as $iExcludedPlaceID)
-                               {
-                                       $iExcludedPlaceID = (int)$iExcludedPlaceID;
-                                       if ($iExcludedPlaceID)
-                                               $aExcludePlaceIDs[$iExcludedPlaceID] = $iExcludedPlaceID;
-                               }
-
-                               if (isset($aExcludePlaceIDs))
-                                       $this->aExcludePlaceIDs = $aExcludePlaceIDs;
-                       }
-
-                       // Only certain ranks of feature
-                       $sFeatureType = $oParams->getString('featureType');
-                       if (!$sFeatureType) $sFeatureType = $oParams->getString('featuretype');
-                       if ($sFeatureType) $this->setFeatureType($sFeatureType);
-
-                       // Country code list
-                       $sCountries = $oParams->getStringList('countrycodes');
-                       if ($sCountries)
-                       {
-                               foreach($sCountries as $sCountryCode)
-                               {
-                                       if (preg_match('/^[a-zA-Z][a-zA-Z]$/', $sCountryCode))
-                                       {
-                                               $aCountries[] = strtolower($sCountryCode);
-                                       }
-                               }
-                               if (isset($aCountryCodes))
-                                       $this->aCountryCodes = $aCountries;
-                       }
-
-                       $aViewbox = $oParams->getStringList('viewboxlbrt');
-                       if ($aViewbox)
-                       {
-                               $this->setViewbox($aViewbox);
-                       }
-                       else
-                       {
-                               $aViewbox = $oParams->getStringList('viewbox');
-                               if ($aViewbox)
-                               {
-                                       $this->setViewBox(array($aViewbox[0], $aViewbox[3],
-                                                               $aViewbox[2], $aViewbox[1]));
-                               }
-                               else
-                               {
-                                       $aRoute = $oParams->getStringList('route');
-                                       $fRouteWidth = $oParams->getFloat('routewidth');
-                                       if ($aRoute && $fRouteWidth)
-                                       {
-                                               $this->setRoute($aRoute, $fRouteWidth);
-                                       }
-                               }
-                       }
-               }
-
-               function setQueryFromParams($oParams)
-               {
-                       // Search query
-                       $sQuery = $oParams->getString('q');
-                       if (!$sQuery)
-                       {
-                               $this->setStructuredQuery($oParams->getString('amenity'),
-                                                         $oParams->getString('street'),
-                                                         $oParams->getString('city'),
-                                                         $oParams->getString('county'),
-                                                         $oParams->getString('state'),
-                                                         $oParams->getString('country'),
-                                                         $oParams->getString('postalcode'));
-                               $this->setReverseInPlan(false);
-                       }
-                       else
-                       {
-                               $this->setQuery($sQuery);
-                       }
-               }
-
-               function loadStructuredAddressElement($sValue, $sKey, $iNewMinAddressRank, $iNewMaxAddressRank, $aItemListValues)
-               {
-                       $sValue = trim($sValue);
-                       if (!$sValue) return false;
-                       $this->aStructuredQuery[$sKey] = $sValue;
-                       if ($this->iMinAddressRank == 0 && $this->iMaxAddressRank == 30)
-                       {
-                               $this->iMinAddressRank = $iNewMinAddressRank;
-                               $this->iMaxAddressRank = $iNewMaxAddressRank;
-                       }
-                       if ($aItemListValues) $this->aAddressRankList = array_merge($this->aAddressRankList, $aItemListValues);
-                       return true;
-               }
-
-               function setStructuredQuery($sAmentiy = false, $sStreet = false, $sCity = false, $sCounty = false, $sState = false, $sCountry = false, $sPostalCode = false)
-               {
-                       $this->sQuery = false;
-
-                       // Reset
-                       $this->iMinAddressRank = 0;
-                       $this->iMaxAddressRank = 30;
-                       $this->aAddressRankList = array();
-
-                       $this->aStructuredQuery = array();
-                       $this->sAllowedTypesSQLList = '';
-
-                       $this->loadStructuredAddressElement($sAmentiy, 'amenity', 26, 30, false);
-                       $this->loadStructuredAddressElement($sStreet, 'street', 26, 30, false);
-                       $this->loadStructuredAddressElement($sCity, 'city', 14, 24, false);
-                       $this->loadStructuredAddressElement($sCounty, 'county', 9, 13, false);
-                       $this->loadStructuredAddressElement($sState, 'state', 8, 8, false);
-                       $this->loadStructuredAddressElement($sPostalCode, 'postalcode' , 5, 11, array(5, 11));
-                       $this->loadStructuredAddressElement($sCountry, 'country', 4, 4, false);
-
-                       if (sizeof($this->aStructuredQuery) > 0)
-                       {
-                               $this->sQuery = join(', ', $this->aStructuredQuery);
-                               if ($this->iMaxAddressRank < 30)
-                               {
-                                       $sAllowedTypesSQLList = '(\'place\',\'boundary\')';
-                               }
-                       }
-               }
-
-               function fallbackStructuredQuery()
-               {
-                       if (!$this->aStructuredQuery) return false;
-
-                       $aParams = $this->aStructuredQuery;
-
-                       if (sizeof($aParams) == 1) return false;
-
-                       $aOrderToFallback = array('postalcode', 'street', 'city', 'county', 'state');
-
-                       foreach($aOrderToFallback as $sType)
-                       {
-                               if (isset($aParams[$sType]))
-                               {
-                                       unset($aParams[$sType]);
-                                       $this->setStructuredQuery(@$aParams['amenity'], @$aParams['street'], @$aParams['city'], @$aParams['county'], @$aParams['state'], @$aParams['country'], @$aParams['postalcode']);
-                                       return true;
-                               }
-                       }
-
-                       return false;
-               }
-
-               function getDetails($aPlaceIDs)
-               {
-                       //$aPlaceIDs is an array with key: placeID and value: tiger-housenumber, if found, else -1
-                       if (sizeof($aPlaceIDs) == 0)  return array();
-
-                       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
-
-                       // Get the details for display (is this a redundant extra step?)
-                       $sPlaceIDs = join(',', array_keys($aPlaceIDs));
-
-                       $sImportanceSQL = '';
-                       if ($this->sViewboxSmallSQL) $sImportanceSQL .= " case when ST_Contains($this->sViewboxSmallSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * ";
-                       if ($this->sViewboxLargeSQL) $sImportanceSQL .= " case when ST_Contains($this->sViewboxLargeSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * ";
-
-                       $sSQL = "select osm_type,osm_id,class,type,admin_level,rank_search,rank_address,min(place_id) as place_id, min(parent_place_id) as parent_place_id, calculated_country_code as country_code,";
-                       $sSQL .= "get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress,";
-                       $sSQL .= "get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
-                       $sSQL .= "get_name_by_language(name, ARRAY['ref']) as ref,";
-                       if ($this->bIncludeExtraTags) $sSQL .= "hstore_to_json(extratags)::text as extra,";
-                       if ($this->bIncludeNameDetails) $sSQL .= "hstore_to_json(name)::text as names,";
-                       $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, ";
-                       $sSQL .= $sImportanceSQL."coalesce(importance,0.75-(rank_search::float/40)) as importance, ";
-                       $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(CASE WHEN placex.rank_search < 28 THEN placex.place_id ELSE placex.parent_place_id END) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
-                       $sSQL .= "(extratags->'place') as extra_place ";
-                       $sSQL .= "from placex where place_id in ($sPlaceIDs) ";
-                       $sSQL .= "and (placex.rank_address between $this->iMinAddressRank and $this->iMaxAddressRank ";
-                       if (14 >= $this->iMinAddressRank && 14 <= $this->iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'";
-                       if ($this->aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$this->aAddressRankList).")";
-                       $sSQL .= ") ";
-                       if ($this->sAllowedTypesSQLList) $sSQL .= "and placex.class in $this->sAllowedTypesSQLList ";
-                       $sSQL .= "and linked_place_id is null ";
-                       $sSQL .= "group by osm_type,osm_id,class,type,admin_level,rank_search,rank_address,calculated_country_code,importance";
-                       if (!$this->bDeDupe) $sSQL .= ",place_id";
-                       $sSQL .= ",langaddress ";
-                       $sSQL .= ",placename ";
-                       $sSQL .= ",ref ";
-                       if ($this->bIncludeExtraTags) $sSQL .= ",extratags";
-                       if ($this->bIncludeNameDetails) $sSQL .= ",name";
-                       $sSQL .= ",extratags->'place' ";
-
-                       if (30 >= $this->iMinAddressRank && 30 <= $this->iMaxAddressRank)
-                       {
-                               //only Tiger housenumbers and interpolation lines need to be interpolated, because they are saved as lines 
-                               // with start- and endnumber, the common osm housenumbers are usually saved as points
-                               $sHousenumbers = "";
-                               $i = 0;
-                               $length = count($aPlaceIDs);
-                               foreach($aPlaceIDs as $placeID => $housenumber)
-                               {
-                                       $i++;
-                                       $sHousenumbers .= "(".$placeID.", ".$housenumber.")";
-                                       if($i<$length)
-                                               $sHousenumbers .= ", ";
-                               }
-                               if (CONST_Use_US_Tiger_Data)
-                               {
-                                       //Tiger search only if a housenumber was searched and if it was found (i.e. aPlaceIDs[placeID] = housenumber != -1) (realized through a join)
-                                       $sSQL .= " union";
-                                       $sSQL .= " select 'T' 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, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress ";
-                                       $sSQL .= ", null as placename";
-                                       $sSQL .= ", null as ref";
-                                       if ($this->bIncludeExtraTags) $sSQL .= ", null as extra";
-                                       if ($this->bIncludeNameDetails) $sSQL .= ", null as names";
-                                       $sSQL .= ", avg(st_x(centroid)) as lon, avg(st_y(centroid)) as lat,";
-                                       $sSQL .= $sImportanceSQL."-1.15 as importance ";
-                                       $sSQL .= ", (select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance ";
-                                       $sSQL .= ", null as extra_place ";
-                                       $sSQL .= " from (select place_id";
-                                       //interpolate the Tiger housenumbers here
-                                       $sSQL .= ", ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) as centroid, parent_place_id, housenumber_for_place";
-                                       $sSQL .= " from (location_property_tiger ";
-                                       $sSQL .= " join (values ".$sHousenumbers.") as housenumbers(place_id, housenumber_for_place) using(place_id)) ";
-                                       $sSQL .= " where housenumber_for_place>=0 and 30 between $this->iMinAddressRank and $this->iMaxAddressRank) as blub"; //postgres wants an alias here
-                                       $sSQL .= " group by place_id, housenumber_for_place"; //is this group by really needed?, place_id + housenumber (in combination) are unique
-                                       if (!$this->bDeDupe) $sSQL .= ", place_id ";
-                               }
-                               // osmline
-                               // interpolation line search only if a housenumber was searched and if it was found (i.e. aPlaceIDs[placeID] = housenumber != -1) (realized through a join)
-                               $sSQL .= " union ";
-                               $sSQL .= "select 'W' 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, calculated_country_code as country_code, ";
-                               $sSQL .= "get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress, ";
-                               $sSQL .= "null as placename, ";
-                               $sSQL .= "null as ref, ";
-                               if ($this->bIncludeExtraTags) $sSQL .= "null as extra, ";
-                               if ($this->bIncludeNameDetails) $sSQL .= "null as names, ";
-                               $sSQL .= " avg(st_x(centroid)) as lon, avg(st_y(centroid)) as lat,";
-                               $sSQL .= $sImportanceSQL."-0.1 as importance, ";  // slightly smaller than the importance for normal houses with rank 30, which is 0
-                               $sSQL .= " (select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p";
-                               $sSQL .= " where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance,";
-                               $sSQL .= " null as extra_place ";
-                               $sSQL .= " from (select place_id, calculated_country_code ";
-                               //interpolate the housenumbers here
-                               $sSQL .= ", CASE WHEN startnumber != endnumber THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) ";
-                               $sSQL .= " ELSE ST_LineInterpolatePoint(linegeo, 0.5) END as centroid";
-                               $sSQL .= ", parent_place_id, housenumber_for_place ";
-                               $sSQL .= " from (location_property_osmline ";
-                               $sSQL .= " join (values ".$sHousenumbers.") as housenumbers(place_id, housenumber_for_place) using(place_id)) ";
-                               $sSQL .= " where housenumber_for_place>=0 and 30 between $this->iMinAddressRank and $this->iMaxAddressRank) as blub"; //postgres wants an alias here
-                               $sSQL .= " group by place_id, housenumber_for_place, calculated_country_code "; //is this group by really needed?, place_id + housenumber (in combination) are unique
-                               if (!$this->bDeDupe) $sSQL .= ", place_id ";
-
-                               if (CONST_Use_Aux_Location_data)
-                               {
-                                       $sSQL .= " union ";
-                                       $sSQL .= "select 'L' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, 0 as rank_search, 0 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, -1, $sLanguagePrefArraySQL) as langaddress, ";
-                                       $sSQL .= "null as placename, ";
-                                       $sSQL .= "null as ref, ";
-                                       if ($this->bIncludeExtraTags) $sSQL .= "null as extra, ";
-                                       if ($this->bIncludeNameDetails) $sSQL .= "null as names, ";
-                                       $sSQL .= "avg(ST_X(centroid)) as lon, avg(ST_Y(centroid)) as lat, ";
-                                       $sSQL .= $sImportanceSQL."-1.10 as importance, ";
-                                       $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_aux.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
-                                       $sSQL .= "null as extra_place ";
-                                       $sSQL .= "from location_property_aux where place_id in ($sPlaceIDs) ";
-                                       $sSQL .= "and 30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
-                                       $sSQL .= "group by place_id";
-                                       if (!$this->bDeDupe) $sSQL .= ", place_id";
-                                       $sSQL .= ", get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) ";
-                               }
-                       }
-
-                       $sSQL .= " order by importance desc";
-                       if (CONST_Debug) { echo "<hr>"; var_dump($sSQL); }
-                       $aSearchResults = chksql($this->oDB->getAll($sSQL),
-                                                "Could not get details for place.");
-
-                       return $aSearchResults;
-               }
-
-               function getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases)
-               {
-                       /*
-                                Calculate all searches using aValidTokens i.e.
-                                'Wodsworth Road, Sheffield' =>
-
-                                Phrase Wordset
-                                0      0       (wodsworth road)
-                                0      1       (wodsworth)(road)
-                                1      0       (sheffield)
-
-                                Score how good the search is so they can be ordered
-                        */
-                       foreach($aPhrases as $iPhrase => $sPhrase)
-                       {
-                               $aNewPhraseSearches = array();
-                               if ($bStructuredPhrases) $sPhraseType = $aPhraseTypes[$iPhrase];
-                               else $sPhraseType = '';
-
-                               foreach($aPhrases[$iPhrase]['wordsets'] as $iWordSet => $aWordset)
-                               {
-                                       // Too many permutations - too expensive
-                                       if ($iWordSet > 120) break;
-
-                                       $aWordsetSearches = $aSearches;
-
-                                       // Add all words from this wordset
-                                       foreach($aWordset as $iToken => $sToken)
-                                       {
-                                               //echo "<br><b>$sToken</b>";
-                                               $aNewWordsetSearches = array();
-
-                                               foreach($aWordsetSearches as $aCurrentSearch)
-                                               {
-                                                       //echo "<i>";
-                                                       //var_dump($aCurrentSearch);
-                                                       //echo "</i>";
-
-                                                       // If the token is valid
-                                                       if (isset($aValidTokens[' '.$sToken]))
-                                                       {
-                                                               foreach($aValidTokens[' '.$sToken] as $aSearchTerm)
-                                                               {
-                                                                       $aSearch = $aCurrentSearch;
-                                                                       $aSearch['iSearchRank']++;
-                                                                       if (($sPhraseType == '' || $sPhraseType == 'country') && !empty($aSearchTerm['country_code']) && $aSearchTerm['country_code'] != '0')
-                                                                       {
-                                                                               if ($aSearch['sCountryCode'] === false)
-                                                                               {
-                                                                                       $aSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
-                                                                                       // Country is almost always at the end of the string - increase score for finding it anywhere else (optimisation)
-                                                                                       if (($iToken+1 != sizeof($aWordset) || $iPhrase+1 != sizeof($aPhrases)))
-                                                                                       {
-                                                                                               $aSearch['iSearchRank'] += 5;
-                                                                                       }
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                               }
-                                                                       }
-                                                                       elseif (isset($aSearchTerm['lat']) && $aSearchTerm['lat'] !== '' && $aSearchTerm['lat'] !== null)
-                                                                       {
-                                                                               if ($aSearch['fLat'] === '')
-                                                                               {
-                                                                                       $aSearch['fLat'] = $aSearchTerm['lat'];
-                                                                                       $aSearch['fLon'] = $aSearchTerm['lon'];
-                                                                                       $aSearch['fRadius'] = $aSearchTerm['radius'];
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                               }
-                                                                       }
-                                                                       elseif ($sPhraseType == 'postalcode')
-                                                                       {
-                                                                               // We need to try the case where the postal code is the primary element (i.e. no way to tell if it is (postalcode, city) OR (city, postalcode) so try both
-                                                                               if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
-                                                                               {
-                                                                                       // If we already have a name try putting the postcode first
-                                                                                       if (sizeof($aSearch['aName']))
-                                                                                       {
-                                                                                               $aNewSearch = $aSearch;
-                                                                                               $aNewSearch['aAddress'] = array_merge($aNewSearch['aAddress'], $aNewSearch['aName']);
-                                                                                               $aNewSearch['aName'] = array();
-                                                                                               $aNewSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aNewSearch;
-                                                                                       }
-
-                                                                                       if (sizeof($aSearch['aName']))
-                                                                                       {
-                                                                                               if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
-                                                                                               {
-                                                                                                       $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               }
-                                                                                               else
-                                                                                               {
-                                                                                                       $aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                                       $aSearch['iSearchRank'] += 1000; // skip;
-                                                                                               }
-                                                                                       }
-                                                                                       else
-                                                                                       {
-                                                                                               $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               //$aSearch['iNamePhrase'] = $iPhrase;
-                                                                                       }
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                               }
-
-                                                                       }
-                                                                       elseif (($sPhraseType == '' || $sPhraseType == 'street') && $aSearchTerm['class'] == 'place' && $aSearchTerm['type'] == 'house')
-                                                                       {
-                                                                               if ($aSearch['sHouseNumber'] === '')
-                                                                               {
-                                                                                       $aSearch['sHouseNumber'] = $sToken;
-                                                                                       // sanity check: if the housenumber is not mainly made
-                                                                                       // up of numbers, add a penalty
-                                                                                       if (preg_match_all("/[^0-9]/", $sToken, $aMatches) > 2) $aSearch['iSearchRank']++;
-                                                                                       // also housenumbers should appear in the first or second phrase
-                                                                                       if ($iPhrase > 1) $aSearch['iSearchRank'] += 1;
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                       /*
-                                                                                       // Fall back to not searching for this item (better than nothing)
-                                                                                       $aSearch = $aCurrentSearch;
-                                                                                       $aSearch['iSearchRank'] += 1;
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                        */
-                                                                               }
-                                                                       }
-                                                                       elseif ($sPhraseType == '' && $aSearchTerm['class'] !== '' && $aSearchTerm['class'] !== null)
-                                                                       {
-                                                                               if ($aSearch['sClass'] === '')
-                                                                               {
-                                                                                       $aSearch['sOperator'] = $aSearchTerm['operator'];
-                                                                                       $aSearch['sClass'] = $aSearchTerm['class'];
-                                                                                       $aSearch['sType'] = $aSearchTerm['type'];
-                                                                                       if (sizeof($aSearch['aName'])) $aSearch['sOperator'] = 'name';
-                                                                                       else $aSearch['sOperator'] = 'near'; // near = in for the moment
-                                                                                       if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
-
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                               }
-                                                                       }
-                                                                       elseif (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
-                                                                       {
-                                                                               if (sizeof($aSearch['aName']))
-                                                                               {
-                                                                                       if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
-                                                                                       {
-                                                                                               $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                       }
-                                                                                       else
-                                                                                       {
-                                                                                               $aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               $aSearch['iSearchRank'] += 1000; // skip;
-                                                                                       }
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                       //$aSearch['iNamePhrase'] = $iPhrase;
-                                                                               }
-                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                       }
-                                                               }
-                                                       }
-                                                       // Look for partial matches.
-                                                       // Note that there is no point in adding country terms here
-                                                       // because country are omitted in the address.
-                                                       if (isset($aValidTokens[$sToken]) && $sPhraseType != 'country')
-                                                       {
-                                                               // Allow searching for a word - but at extra cost
-                                                               foreach($aValidTokens[$sToken] as $aSearchTerm)
-                                                               {
-                                                                       if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
-                                                                       {
-                                                                               if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strpos($sToken, ' ') === false)
-                                                                               {
-                                                                                       $aSearch = $aCurrentSearch;
-                                                                                       $aSearch['iSearchRank'] += 1;
-                                                                                       if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
-                                                                                       {
-                                                                                               $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                       }
-                                                                                       elseif (isset($aValidTokens[' '.$sToken])) // revert to the token version?
-                                                                                       {
-                                                                                               $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               $aSearch['iSearchRank'] += 1;
-                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                               foreach($aValidTokens[' '.$sToken] as $aSearchTermToken)
-                                                                                               {
-                                                                                                       if (empty($aSearchTermToken['country_code'])
-                                                                                                                       && empty($aSearchTermToken['lat'])
-                                                                                                                       && empty($aSearchTermToken['class']))
-                                                                                                       {
-                                                                                                               $aSearch = $aCurrentSearch;
-                                                                                                               $aSearch['iSearchRank'] += 1;
-                                                                                                               $aSearch['aAddress'][$aSearchTermToken['word_id']] = $aSearchTermToken['word_id'];
-                                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                                       }
-                                                                                               }
-                                                                                       }
-                                                                                       else
-                                                                                       {
-                                                                                               $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                               if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
-                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                                       }
-                                                                               }
-
-                                                                               if (!sizeof($aCurrentSearch['aName']) || $aCurrentSearch['iNamePhrase'] == $iPhrase)
-                                                                               {
-                                                                                       $aSearch = $aCurrentSearch;
-                                                                                       $aSearch['iSearchRank'] += 1;
-                                                                                       if (!sizeof($aCurrentSearch['aName'])) $aSearch['iSearchRank'] += 1;
-                                                                                       if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
-                                                                                       if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
-                                                                                               $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                       else
-                                                                                               $aSearch['aNameNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
-                                                                                       $aSearch['iNamePhrase'] = $iPhrase;
-                                                                                       if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
-                                                                               }
-                                                                       }
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               // Allow skipping a word - but at EXTREAM cost
-                                                               //$aSearch = $aCurrentSearch;
-                                                               //$aSearch['iSearchRank']+=100;
-                                                               //$aNewWordsetSearches[] = $aSearch;
-                                                       }
-                                               }
-                                               // Sort and cut
-                                               usort($aNewWordsetSearches, 'bySearchRank');
-                                               $aWordsetSearches = array_slice($aNewWordsetSearches, 0, 50);
-                                       }
-                                       //var_Dump('<hr>',sizeof($aWordsetSearches)); exit;
-
-                                       $aNewPhraseSearches = array_merge($aNewPhraseSearches, $aNewWordsetSearches);
-                                       usort($aNewPhraseSearches, 'bySearchRank');
-
-                                       $aSearchHash = array();
-                                       foreach($aNewPhraseSearches as $iSearch => $aSearch)
-                                       {
-                                               $sHash = serialize($aSearch);
-                                               if (isset($aSearchHash[$sHash])) unset($aNewPhraseSearches[$iSearch]);
-                                               else $aSearchHash[$sHash] = 1;
-                                       }
-
-                                       $aNewPhraseSearches = array_slice($aNewPhraseSearches, 0, 50);
-                               }
-
-                               // Re-group the searches by their score, junk anything over 20 as just not worth trying
-                               $aGroupedSearches = array();
-                               foreach($aNewPhraseSearches as $aSearch)
-                               {
-                                       if ($aSearch['iSearchRank'] < $this->iMaxRank)
-                                       {
-                                               if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
-                                               $aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
-                                       }
-                               }
-                               ksort($aGroupedSearches);
-
-                               $iSearchCount = 0;
-                               $aSearches = array();
-                               foreach($aGroupedSearches as $iScore => $aNewSearches)
-                               {
-                                       $iSearchCount += sizeof($aNewSearches);
-                                       $aSearches = array_merge($aSearches, $aNewSearches);
-                                       if ($iSearchCount > 50) break;
-                               }
-
-                               //if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
-
-                       }
-                       return $aGroupedSearches;
-
-               }
-
-               /* Perform the actual query lookup.
-
-                       Returns an ordered list of results, each with the following fields:
-                               osm_type: type of corresponding OSM object
-                                                       N - node
-                                                       W - way
-                                                       R - relation
-                                                       P - postcode (internally computed)
-                               osm_id: id of corresponding OSM object
-                               class: general object class (corresponds to tag key of primary OSM tag)
-                               type: subclass of object (corresponds to tag value of primary OSM tag)
-                               admin_level: see http://wiki.openstreetmap.org/wiki/Admin_level
-                               rank_search: rank in search hierarchy
-                                                       (see also http://wiki.openstreetmap.org/wiki/Nominatim/Development_overview#Country_to_street_level)
-                               rank_address: rank in address hierarchy (determines orer in address)
-                               place_id: internal key (may differ between different instances)
-                               country_code: ISO country code
-                               langaddress: localized full address
-                               placename: localized name of object
-                               ref: content of ref tag (if available)
-                               lon: longitude
-                               lat: latitude
-                               importance: importance of place based on Wikipedia link count
-                               addressimportance: cumulated importance of address elements
-                               extra_place: type of place (for admin boundaries, if there is a place tag)
-                               aBoundingBox: bounding Box
-                               label: short description of the object class/type (English only)
-                               name: full name (currently the same as langaddress)
-                               foundorder: secondary ordering for places with same importance
-               */
-               function lookup()
-               {
-                       if (!$this->sQuery && !$this->aStructuredQuery) return false;
-
-                       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
-                       $sCountryCodesSQL = false;
-                       if ($this->aCountryCodes)
-                       {
-                               $sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes));
-                       }
-
-                       $sQuery = $this->sQuery;
-
-                       // Conflicts between US state abreviations and various words for 'the' in different languages
-                       if (isset($this->aLangPrefOrder['name:en']))
-                       {
-                               $sQuery = preg_replace('/(^|,)\s*il\s*(,|$)/','\1illinois\2', $sQuery);
-                               $sQuery = preg_replace('/(^|,)\s*al\s*(,|$)/','\1alabama\2', $sQuery);
-                               $sQuery = preg_replace('/(^|,)\s*la\s*(,|$)/','\1louisiana\2', $sQuery);
-                       }
-
-                       $bBoundingBoxSearch = $this->bBoundedSearch && $this->sViewboxSmallSQL;
-                       if ($this->sViewboxCentreSQL)
-                       {
-                               // For complex viewboxes (routes) precompute the bounding geometry
-                               $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxSmallSQL),
-                                               "Could not get small viewbox");
-                               $this->sViewboxSmallSQL = "'".$sGeom."'::geometry";
-
-                               $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxLargeSQL),
-                                               "Could not get large viewbox");
-                               $this->sViewboxLargeSQL = "'".$sGeom."'::geometry";
-                       }
-
-                       // Do we have anything that looks like a lat/lon pair?
-                       if ( $aLooksLike = looksLikeLatLonPair($sQuery) )
-                       {
-                               $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon']));
-                               $sQuery = $aLooksLike['query'];
-                       }
-
-                       $aSearchResults = array();
-                       if ($sQuery || $this->aStructuredQuery)
-                       {
-                               // Start with a blank search
-                               $aSearches = array(
-                                       array('iSearchRank' => 0,
-                                                               'iNamePhrase' => -1,
-                                                               'sCountryCode' => false,
-                                                               'aName' => array(),
-                                                               'aAddress' => array(),
-                                                               'aFullNameAddress' => array(),
-                                                               'aNameNonSearch' => array(),
-                                                               'aAddressNonSearch' => array(),
-                                                               'sOperator' => '',
-                                                               'aFeatureName' => array(),
-                                                               'sClass' => '',
-                                                               'sType' => '',
-                                                               'sHouseNumber' => '',
-                                                               'fLat' => '',
-                                                               'fLon' => '',
-                                                               'fRadius' => ''
-                                                       )
-                               );
-
-                               // Do we have a radius search?
-                               $sNearPointSQL = false;
-                               if ($this->aNearPoint)
-                               {
-                                       $sNearPointSQL = "ST_SetSRID(ST_Point(".(float)$this->aNearPoint[1].",".(float)$this->aNearPoint[0]."),4326)";
-                                       $aSearches[0]['fLat'] = (float)$this->aNearPoint[0];
-                                       $aSearches[0]['fLon'] = (float)$this->aNearPoint[1];
-                                       $aSearches[0]['fRadius'] = (float)$this->aNearPoint[2];
-                               }
-
-                               // Any 'special' terms in the search?
-                               $bSpecialTerms = false;
-                               preg_match_all('/\\[(.*)=(.*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
-                               $aSpecialTerms = array();
-                               foreach($aSpecialTermsRaw as $aSpecialTerm)
-                               {
-                                       $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
-                                       $aSpecialTerms[strtolower($aSpecialTerm[1])] = $aSpecialTerm[2];
-                               }
-
-                               preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
-                               $aSpecialTerms = array();
-                               if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity'])
-                               {
-                                       $aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']);
-                                       unset($this->aStructuredQuery['amenity']);
-                               }
-                               foreach($aSpecialTermsRaw as $aSpecialTerm)
-                               {
-                                       $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
-                                       $sToken = chksql($this->oDB->getOne("select make_standard_name('".$aSpecialTerm[1]."') as string"));
-                                       $sSQL = 'select * from (select word_id,word_token, word, class, type, country_code, operator';
-                                       $sSQL .= ' from word where word_token in (\' '.$sToken.'\')) as x where (class is not null and class not in (\'place\')) or country_code is not null';
-                                       if (CONST_Debug) var_Dump($sSQL);
-                                       $aSearchWords = chksql($this->oDB->getAll($sSQL));
-                                       $aNewSearches = array();
-                                       foreach($aSearches as $aSearch)
-                                       {
-                                               foreach($aSearchWords as $aSearchTerm)
-                                               {
-                                                       $aNewSearch = $aSearch;
-                                                       if ($aSearchTerm['country_code'])
-                                                       {
-                                                               $aNewSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
-                                                               $aNewSearches[] = $aNewSearch;
-                                                               $bSpecialTerms = true;
-                                                       }
-                                                       if ($aSearchTerm['class'])
-                                                       {
-                                                               $aNewSearch['sClass'] = $aSearchTerm['class'];
-                                                               $aNewSearch['sType'] = $aSearchTerm['type'];
-                                                               $aNewSearches[] = $aNewSearch;
-                                                               $bSpecialTerms = true;
-                                                       }
-                                               }
-                                       }
-                                       $aSearches = $aNewSearches;
-                               }
-
-                               // Split query into phrases
-                               // Commas are used to reduce the search space by indicating where phrases split
-                               if ($this->aStructuredQuery)
-                               {
-                                       $aPhrases = $this->aStructuredQuery;
-                                       $bStructuredPhrases = true;
-                               }
-                               else
-                               {
-                                       $aPhrases = explode(',',$sQuery);
-                                       $bStructuredPhrases = false;
-                               }
-
-                               // Convert each phrase to standard form
-                               // Create a list of standard words
-                               // Get all 'sets' of words
-                               // Generate a complete list of all
-                               $aTokens = array();
-                               foreach($aPhrases as $iPhrase => $sPhrase)
-                               {
-                                       $aPhrase = chksql($this->oDB->getRow("select make_standard_name('".pg_escape_string($sPhrase)."') as string"),
-                                                         "Cannot nomralize query string (is it an UTF-8 string?)");
-                                       if (trim($aPhrase['string']))
-                                       {
-                                               $aPhrases[$iPhrase] = $aPhrase;
-                                               $aPhrases[$iPhrase]['words'] = explode(' ',$aPhrases[$iPhrase]['string']);
-                                               $aPhrases[$iPhrase]['wordsets'] = getWordSets($aPhrases[$iPhrase]['words'], 0);
-                                               $aTokens = array_merge($aTokens, getTokensFromSets($aPhrases[$iPhrase]['wordsets']));
-                                       }
-                                       else
-                                       {
-                                               unset($aPhrases[$iPhrase]);
-                                       }
-                               }
-
-                               // Reindex phrases - we make assumptions later on that they are numerically keyed in order
-                               $aPhraseTypes = array_keys($aPhrases);
-                               $aPhrases = array_values($aPhrases);
-
-                               if (sizeof($aTokens))
-                               {
-                                       // Check which tokens we have, get the ID numbers
-                                       $sSQL = 'select word_id,word_token, word, class, type, country_code, operator, search_name_count';
-                                       $sSQL .= ' from word where word_token in ('.join(',',array_map("getDBQuoted",$aTokens)).')';
-
-                                       if (CONST_Debug) var_Dump($sSQL);
-
-                                       $aValidTokens = array();
-                                       if (sizeof($aTokens))
-                                       {
-                                               $aDatabaseWords = chksql($this->oDB->getAll($sSQL),
-                                                                        "Could not get word tokens.");
-                                       }
-                                       else
-                                       {
-                                               $aDatabaseWords = array();
-                                       }
-                                       $aPossibleMainWordIDs = array();
-                                       $aWordFrequencyScores = array();
-                                       foreach($aDatabaseWords as $aToken)
-                                       {
-                                               // Very special case - require 2 letter country param to match the country code found
-                                               if ($bStructuredPhrases && $aToken['country_code'] && !empty($this->aStructuredQuery['country'])
-                                                               && strlen($this->aStructuredQuery['country']) == 2 && strtolower($this->aStructuredQuery['country']) != $aToken['country_code'])
-                                               {
-                                                       continue;
-                                               }
-
-                                               if (isset($aValidTokens[$aToken['word_token']]))
-                                               {
-                                                       $aValidTokens[$aToken['word_token']][] = $aToken;
-                                               }
-                                               else
-                                               {
-                                                       $aValidTokens[$aToken['word_token']] = array($aToken);
-                                               }
-                                               if (!$aToken['class'] && !$aToken['country_code']) $aPossibleMainWordIDs[$aToken['word_id']] = 1;
-                                               $aWordFrequencyScores[$aToken['word_id']] = $aToken['search_name_count'] + 1;
-                                       }
-                                       if (CONST_Debug) var_Dump($aPhrases, $aValidTokens);
-
-                                       // Try and calculate GB postcodes we might be missing
-                                       foreach($aTokens as $sToken)
-                                       {
-                                               // Source of gb postcodes is now definitive - always use
-                                               if (preg_match('/^([A-Z][A-Z]?[0-9][0-9A-Z]? ?[0-9])([A-Z][A-Z])$/', strtoupper(trim($sToken)), $aData))
-                                               {
-                                                       if (substr($aData[1],-2,1) != ' ')
-                                                       {
-                                                               $aData[0] = substr($aData[0],0,strlen($aData[1])-1).' '.substr($aData[0],strlen($aData[1])-1);
-                                                               $aData[1] = substr($aData[1],0,-1).' '.substr($aData[1],-1,1);
-                                                       }
-                                                       $aGBPostcodeLocation = gbPostcodeCalculate($aData[0], $aData[1], $aData[2], $this->oDB);
-                                                       if ($aGBPostcodeLocation)
-                                                       {
-                                                               $aValidTokens[$sToken] = $aGBPostcodeLocation;
-                                                       }
-                                               }
-                                               // US ZIP+4 codes - if there is no token,
-                                               //      merge in the 5-digit ZIP code
-                                               else if (!isset($aValidTokens[$sToken]) && preg_match('/^([0-9]{5}) [0-9]{4}$/', $sToken, $aData))
-                                               {
-                                                       if (isset($aValidTokens[$aData[1]]))
-                                                       {
-                                                               foreach($aValidTokens[$aData[1]] as $aToken)
-                                                               {
-                                                                       if (!$aToken['class'])
-                                                                       {
-                                                                               if (isset($aValidTokens[$sToken]))
-                                                                               {
-                                                                                       $aValidTokens[$sToken][] = $aToken;
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       $aValidTokens[$sToken] = array($aToken);
-                                                                               }
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-
-                                       foreach($aTokens as $sToken)
-                                       {
-                                               // Unknown single word token with a number - assume it is a house number
-                                               if (!isset($aValidTokens[' '.$sToken]) && strpos($sToken,' ') === false && preg_match('/[0-9]/', $sToken))
-                                               {
-                                                       $aValidTokens[' '.$sToken] = array(array('class'=>'place','type'=>'house'));
-                                               }
-                                       }
-
-                                       // Any words that have failed completely?
-                                       // TODO: suggestions
-
-                                       // Start the search process
-                                       // array with: placeid => -1 | tiger-housenumber
-                                       $aResultPlaceIDs = array();
-
-                                       $aGroupedSearches = $this->getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases);
-
-                                       if ($this->bReverseInPlan)
-                                       {
-                                               // Reverse phrase array and also reverse the order of the wordsets in
-                                               // the first and final phrase. Don't bother about phrases in the middle
-                                               // because order in the address doesn't matter.
-                                               $aPhrases = array_reverse($aPhrases);
-                                               $aPhrases[0]['wordsets'] = getInverseWordSets($aPhrases[0]['words'], 0);
-                                               if (sizeof($aPhrases) > 1)
-                                               {
-                                                       $aFinalPhrase = end($aPhrases);
-                                                       $aPhrases[sizeof($aPhrases)-1]['wordsets'] = getInverseWordSets($aFinalPhrase['words'], 0);
-                                               }
-                                               $aReverseGroupedSearches = $this->getGroupedSearches($aSearches, null, $aPhrases, $aValidTokens, $aWordFrequencyScores, false);
-
-                                               foreach($aGroupedSearches as $aSearches)
-                                               {
-                                                       foreach($aSearches as $aSearch)
-                                                       {
-                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank)
-                                                               {
-                                                                       if (!isset($aReverseGroupedSearches[$aSearch['iSearchRank']])) $aReverseGroupedSearches[$aSearch['iSearchRank']] = array();
-                                                                       $aReverseGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
-                                                               }
-
-                                                       }
-                                               }
-
-                                               $aGroupedSearches = $aReverseGroupedSearches;
-                                               ksort($aGroupedSearches);
-                                       }
-                               }
-                               else
-                               {
-                                       // Re-group the searches by their score, junk anything over 20 as just not worth trying
-                                       $aGroupedSearches = array();
-                                       foreach($aSearches as $aSearch)
-                                       {
-                                               if ($aSearch['iSearchRank'] < $this->iMaxRank)
-                                               {
-                                                       if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
-                                                       $aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
-                                               }
-                                       }
-                                       ksort($aGroupedSearches);
-                               }
-
-                               if (CONST_Debug) var_Dump($aGroupedSearches);
-
-                               if (CONST_Search_TryDroppedAddressTerms && sizeof($this->aStructuredQuery) > 0)
-                               {
-                                       $aCopyGroupedSearches = $aGroupedSearches;
-                                       foreach($aCopyGroupedSearches as $iGroup => $aSearches)
-                                       {
-                                               foreach($aSearches as $iSearch => $aSearch)
-                                               {
-                                                       $aReductionsList = array($aSearch['aAddress']);
-                                                       $iSearchRank = $aSearch['iSearchRank'];
-                                                       while(sizeof($aReductionsList) > 0)
-                                                       {
-                                                               $iSearchRank += 5;
-                                                               if ($iSearchRank > iMaxRank) break 3;
-                                                               $aNewReductionsList = array();
-                                                               foreach($aReductionsList as $aReductionsWordList)
-                                                               {
-                                                                       for ($iReductionWord = 0; $iReductionWord < sizeof($aReductionsWordList); $iReductionWord++)
-                                                                       {
-                                                                               $aReductionsWordListResult = array_merge(array_slice($aReductionsWordList, 0, $iReductionWord), array_slice($aReductionsWordList, $iReductionWord+1));
-                                                                               $aReverseSearch = $aSearch;
-                                                                               $aSearch['aAddress'] = $aReductionsWordListResult;
-                                                                               $aSearch['iSearchRank'] = $iSearchRank;
-                                                                               $aGroupedSearches[$iSearchRank][] = $aReverseSearch;
-                                                                               if (sizeof($aReductionsWordListResult) > 0)
-                                                                               {
-                                                                                       $aNewReductionsList[] = $aReductionsWordListResult;
-                                                                               }
-                                                                       }
-                                                               }
-                                                               $aReductionsList = $aNewReductionsList;
-                                                       }
-                                               }
-                                       }
-                                       ksort($aGroupedSearches);
-                               }
-
-                               // Filter out duplicate searches
-                               $aSearchHash = array();
-                               foreach($aGroupedSearches as $iGroup => $aSearches)
-                               {
-                                       foreach($aSearches as $iSearch => $aSearch)
-                                       {
-                                               $sHash = serialize($aSearch);
-                                               if (isset($aSearchHash[$sHash]))
-                                               {
-                                                       unset($aGroupedSearches[$iGroup][$iSearch]);
-                                                       if (sizeof($aGroupedSearches[$iGroup]) == 0) unset($aGroupedSearches[$iGroup]);
-                                               }
-                                               else
-                                               {
-                                                       $aSearchHash[$sHash] = 1;
-                                               }
-                                       }
-                               }
-
-                               if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
-
-                               $iGroupLoop = 0;
-                               $iQueryLoop = 0;
-                               foreach($aGroupedSearches as $iGroupedRank => $aSearches)
-                               {
-                                       $iGroupLoop++;
-                                       foreach($aSearches as $aSearch)
-                                       {
-                                               $iQueryLoop++;
-                                               $searchedHousenumber = -1;
-
-                                               if (CONST_Debug) { echo "<hr><b>Search Loop, group $iGroupLoop, loop $iQueryLoop</b>"; }
-                                               if (CONST_Debug) _debugDumpGroupedSearches(array($iGroupedRank => array($aSearch)), $aValidTokens);
-
-                                               // No location term?
-                                               if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['fLon'])
-                                               {
-                                                       if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber'])
-                                                       {
-                                                               // Just looking for a country by code - look it up
-                                                               if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank)
-                                                               {
-                                                                       $sSQL = "select place_id from placex where calculated_country_code='".$aSearch['sCountryCode']."' and rank_search = 4";
-                                                                       if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
-                                                                       if ($bBoundingBoxSearch)
-                                                                               $sSQL .= " and _st_intersects($this->sViewboxSmallSQL, geometry)";
-                                                                       $sSQL .= " order by st_area(geometry) desc limit 1";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                               }
-                                                               else
-                                                               {
-                                                                       $aPlaceIDs = array();
-                                                               }
-                                                       }
-                                                       else
-                                                       {
-                                                               if (!$bBoundingBoxSearch && !$aSearch['fLon']) continue;
-                                                               if (!$aSearch['sClass']) continue;
-                                                               $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'";
-                                                               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 ($sCountryCodesSQL) $sSQL .= " and calculated_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";
-                                                                       $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 calculated_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 from placex where class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'";
-                                                                       $sSQL .= " and st_contains($this->sViewboxSmallSQL, geometry) and linked_place_id is null";
-                                                                       if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
-                                                                       if ($this->sViewboxCentreSQL)   $sSQL .= " order by st_distance($this->sViewboxCentreSQL, centroid) asc";
-                                                                       $sSQL .= " limit $this->iLimit";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                               }
-                                                       }
-                                               }
-                                               // If a coordinate is given, the search must either
-                                               // be for a name or a special search. Ignore everythin else.
-                                               else if ($aSearch['fLon'] && !sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['sClass'])
-                                               {
-                                                       $aPlaceIDs = array();
-                                               }
-                                               else
-                                               {
-                                                       $aPlaceIDs = array();
-
-                                                       // First we need a position, either aName or fLat or both
-                                                       $aTerms = array();
-                                                       $aOrder = array();
-
-                                                       if ($aSearch['sHouseNumber'] && sizeof($aSearch['aAddress']))
-                                                       {
-                                                               $sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
-                                $aOrder[] = "";
-                                                               $aOrder[0] = " (exists(select place_id from placex where parent_place_id = search_name.place_id";
-                                $aOrder[0] .= " and transliteration(housenumber) ~* E'".$sHouseNumberRegex."' limit 1) ";
-                                                               // also housenumbers from interpolation lines table are needed
-                                                               $aOrder[0] .= " or exists(select place_id from location_property_osmline where parent_place_id = search_name.place_id";
-                                $aOrder[0] .= " and ".intval($aSearch['sHouseNumber']).">=startnumber and ".intval($aSearch['sHouseNumber'])."<=endnumber limit 1))";
-                                                               $aOrder[0] .= " desc";
-                                                       }
-
-                                                       // 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['aAddress']) && $aSearch['aName'] != $aSearch['aAddress'])
-                                                       {
-                                                               // For infrequent name terms disable index usage for address
-                                                               if (CONST_Search_NameOnlySearchFrequencyThreshold &&
-                                                                               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']),",")."]";
-                                                               }
-                                                               else
-                                                               {
-                                                                       $aTerms[] = "nameaddress_vector @> ARRAY[".join($aSearch['aAddress'],",")."]";
-                                                                       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'])."'";
-                                                       if ($aSearch['sHouseNumber'])
-                                                       {
-                                                               $aTerms[] = "address_rank between 16 and 27";
-                                                       }
-                                                       else
-                                                       {
-                                                               if ($this->iMinAddressRank > 0)
-                                                               {
-                                                                       $aTerms[] = "address_rank >= ".$this->iMinAddressRank;
-                                                               }
-                                                               if ($this->iMaxAddressRank < 30)
-                                                               {
-                                                                       $aTerms[] = "address_rank <= ".$this->iMaxAddressRank;
-                                                               }
-                                                       }
-                                                       if ($aSearch['fLon'] && $aSearch['fLat'])
-                                                       {
-                                                               $aTerms[] = "ST_DWithin(centroid, ST_SetSRID(ST_Point(".$aSearch['fLon'].",".$aSearch['fLat']."),4326), ".$aSearch['fRadius'].")";
-                                                               $aOrder[] = "ST_Distance(centroid, ST_SetSRID(ST_Point(".$aSearch['fLon'].",".$aSearch['fLat']."),4326)) ASC";
-                                                       }
-                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                       {
-                                                               $aTerms[] = "place_id not in (".join(',',$this->aExcludePlaceIDs).")";
-                                                       }
-                                                       if ($sCountryCodesSQL)
-                                                       {
-                                                               $aTerms[] = "country_code in ($sCountryCodesSQL)";
-                                                       }
-
-                                                       if ($bBoundingBoxSearch) $aTerms[] = "centroid && $this->sViewboxSmallSQL";
-                                                       if ($sNearPointSQL) $aOrder[] = "ST_Distance($sNearPointSQL, centroid) asc";
-
-                                                       if ($aSearch['sHouseNumber'])
-                                                       {
-                                                               $sImportanceSQL = '- abs(26 - address_rank) + 3';
-                                                       }
-                                                       else
-                                                       {
-                                                               $sImportanceSQL = '(case when importance = 0 OR importance IS NULL then 0.75-(search_rank::float/40) else importance end)';
-                                                       }
-                                                       if ($this->sViewboxSmallSQL) $sImportanceSQL .= " * case when ST_Contains($this->sViewboxSmallSQL, centroid) THEN 1 ELSE 0.5 END";
-                                                       if ($this->sViewboxLargeSQL) $sImportanceSQL .= " * case when ST_Contains($this->sViewboxLargeSQL, centroid) THEN 1 ELSE 0.5 END";
-
-                                                       $aOrder[] = "$sImportanceSQL DESC";
-                                                       if (sizeof($aSearch['aFullNameAddress']))
-                                                       {
-                                                               $sExactMatchSQL = '(select count(*) from (select unnest(ARRAY['.join($aSearch['aFullNameAddress'],",").']) INTERSECT select unnest(nameaddress_vector))s) as exactmatch';
-                                                               $aOrder[] = 'exactmatch DESC';
-                                                       } else {
-                                                               $sExactMatchSQL = '0::int as exactmatch';
-                                                       }
-
-                                                       if (sizeof($aTerms))
-                                                       {
-                                                               $sSQL = "select place_id, ";
-                                                               $sSQL .= $sExactMatchSQL;
-                                                               $sSQL .= " from search_name";
-                                                               $sSQL .= " where ".join(' and ',$aTerms);
-                                                               $sSQL .= " order by ".join(', ',$aOrder);
-                                                               if ($aSearch['sHouseNumber'] || $aSearch['sClass'])
-                                                                       $sSQL .= " limit 20";
-                                                               elseif (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && $aSearch['sClass'])
-                                                                       $sSQL .= " limit 1";
-                                                               else
-                                                                       $sSQL .= " limit ".$this->iLimit;
-
-                                                               if (CONST_Debug) { var_dump($sSQL); }
-                                                               $aViewBoxPlaceIDs = chksql($this->oDB->getAll($sSQL),
-                                                                                          "Could not get places for search terms.");
-                                                               //var_dump($aViewBoxPlaceIDs);
-                                                               // Did we have an viewbox matches?
-                                                               $aPlaceIDs = array();
-                                                               $bViewBoxMatch = false;
-                                                               foreach($aViewBoxPlaceIDs as $aViewBoxRow)
-                                                               {
-                                                                       //if ($bViewBoxMatch == 1 && $aViewBoxRow['in_small'] == 'f') break;
-                                                                       //if ($bViewBoxMatch == 2 && $aViewBoxRow['in_large'] == 'f') break;
-                                                                       //if ($aViewBoxRow['in_small'] == 't') $bViewBoxMatch = 1;
-                                                                       //else if ($aViewBoxRow['in_large'] == 't') $bViewBoxMatch = 2;
-                                                                       $aPlaceIDs[] = $aViewBoxRow['place_id'];
-                                                                       $this->exactMatchCache[$aViewBoxRow['place_id']] = $aViewBoxRow['exactmatch'];
-                                                               }
-                                                       }
-                                                       //var_Dump($aPlaceIDs);
-                                                       //exit;
-
-                                                       //now search for housenumber, if housenumber provided
-                                                       if ($aSearch['sHouseNumber'] && sizeof($aPlaceIDs))
-                                                       {
-                                                               $searchedHousenumber = intval($aSearch['sHouseNumber']);
-                                                               $aRoadPlaceIDs = $aPlaceIDs;
-                                                               $sPlaceIDs = join(',',$aPlaceIDs);
-
-                                                               // Now they are indexed, look for a house attached to a street we found
-                                                               $sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
-                                                               $sSQL = "select place_id from placex where parent_place_id in (".$sPlaceIDs.") and transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
-                                                               if (sizeof($this->aExcludePlaceIDs))
-                                                               {
-                                                                       $sSQL .= " and place_id not in (".join(',',$this->aExcludePlaceIDs).")";
-                                                               }
-                                                               $sSQL .= " limit $this->iLimit";
-                                                               if (CONST_Debug) var_dump($sSQL);
-                                                               $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                               
-                                                               // if nothing found, search in the interpolation line table
-                                                               if(!sizeof($aPlaceIDs))
-                                                               {
-                                                                       // do we need to use transliteration and the regex for housenumbers???
-                                                                       //new query for lines, not housenumbers anymore
-                                                                       if($searchedHousenumber%2 == 0){
-                                                                               //if housenumber is even, look for housenumber in streets with interpolationtype even or all
-                                                                               $sSQL = "select distinct place_id from location_property_osmline where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='even' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
-                                                                       }else{
-                                                                               //look for housenumber in streets with interpolationtype odd or all
-                                                                               $sSQL = "select distinct place_id from location_property_osmline where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='odd' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
-                                                                       }
-
-                                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                                       {
-                                                                               $sSQL .= " and place_id not in (".join(',', $this->aExcludePlaceIDs).")";
-                                                                       }
-                                                                       //$sSQL .= " limit $this->iLimit";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       //get place IDs
-                                                                       $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0));
-                                                               }
-                                                                       
-                                                               // If nothing found try the aux fallback table
-                                                               if (CONST_Use_Aux_Location_data && !sizeof($aPlaceIDs))
-                                                               {
-                                                                       $sSQL = "select place_id from location_property_aux where parent_place_id in (".$sPlaceIDs.") and housenumber = '".pg_escape_string($aSearch['sHouseNumber'])."'";
-                                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                                       {
-                                                                               $sSQL .= " and parent_place_id not in (".join(',',$this->aExcludePlaceIDs).")";
-                                                                       }
-                                                                       //$sSQL .= " limit $this->iLimit";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                               }
-
-                                                               //if nothing was found in placex or location_property_aux, then search in Tiger data for this housenumber(location_property_tiger)
-                                                               if (CONST_Use_US_Tiger_Data && !sizeof($aPlaceIDs))
-                                                               {
-                                                                       //new query for lines, not housenumbers anymore
-                                                                       if($searchedHousenumber%2 == 0){
-                                                                               //if housenumber is even, look for housenumber in streets with interpolationtype even or all
-                                                                               $sSQL = "select distinct place_id from location_property_tiger where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='even' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
-                                                                       }else{
-                                                                               //look for housenumber in streets with interpolationtype odd or all
-                                                                               $sSQL = "select distinct place_id from location_property_tiger where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='odd' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
-                                                                       }
-
-                                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                                       {
-                                                                               $sSQL .= " and place_id not in (".join(',', $this->aExcludePlaceIDs).")";
-                                                                       }
-                                                                       //$sSQL .= " limit $this->iLimit";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       //get place IDs
-                                                                       $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0));
-                                                               }
-
-                                                               // Fallback to the road (if no housenumber was found)
-                                                               if (!sizeof($aPlaceIDs) && preg_match('/[0-9]+/', $aSearch['sHouseNumber']))
-                                                               {
-                                                                       $aPlaceIDs = $aRoadPlaceIDs;
-                                                                       //set to -1, if no housenumbers were found
-                                                                       $searchedHousenumber = -1;
-                                                               }
-                                                               //else: housenumber was found, remains saved in searchedHousenumber
-                                                       }
-
-
-                                                       if ($aSearch['sClass'] && sizeof($aPlaceIDs))
-                                                       {
-                                                               $sPlaceIDs = join(',', $aPlaceIDs);
-                                                               $aClassPlaceIDs = array();
-
-                                                               if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'name')
-                                                               {
-                                                                       // If they were searching for a named class (i.e. 'Kings Head pub') then we might have an extra match
-                                                                       $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'";
-                                                                       $sSQL .= " and linked_place_id is null";
-                                                                       if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
-                                                                       $sSQL .= " order by rank_search asc limit $this->iLimit";
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       $aClassPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                               }
-
-                                                               if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'near') // & in
-                                                               {
-                                                                       $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'";
-                                                                       $bCacheTable = chksql($this->oDB->getOne($sSQL));
-
-                                                                       $sSQL = "select min(rank_search) from placex where place_id in ($sPlaceIDs)";
-
-                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                       $this->iMaxRank = ((int)chksql($this->oDB->getOne($sSQL)));
-
-                                                                       // For state / country level searches the normal radius search doesn't work very well
-                                                                       $sPlaceGeom = false;
-                                                                       if ($this->iMaxRank < 9 && $bCacheTable)
-                                                                       {
-                                                                               // Try and get a polygon to search in instead
-                                                                               $sSQL = "select geometry from placex where place_id in ($sPlaceIDs) and rank_search < $this->iMaxRank + 5 and st_geometrytype(geometry) in ('ST_Polygon','ST_MultiPolygon') order by rank_search asc limit 1";
-                                                                               if (CONST_Debug) var_dump($sSQL);
-                                                                               $sPlaceGeom = chksql($this->oDB->getOne($sSQL));
-                                                                       }
-
-                                                                       if ($sPlaceGeom)
-                                                                       {
-                                                                               $sPlaceIDs = false;
-                                                                       }
-                                                                       else
-                                                                       {
-                                                                               $this->iMaxRank += 5;
-                                                                               $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and rank_search < $this->iMaxRank";
-                                                                               if (CONST_Debug) var_dump($sSQL);
-                                                                               $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                                                               $sPlaceIDs = join(',',$aPlaceIDs);
-                                                                       }
-
-                                                                       if ($sPlaceIDs || $sPlaceGeom)
-                                                                       {
-
-                                                                               $fRange = 0.01;
-                                                                               if ($bCacheTable)
-                                                                               {
-                                                                                       // More efficient - can make the range bigger
-                                                                                       $fRange = 0.05;
-
-                                                                                       $sOrderBySQL = '';
-                                                                                       if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.centroid)";
-                                                                                       else if ($sPlaceIDs) $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)";
-                                                                                       else if ($sPlaceGeom) $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)";
-
-                                                                                       $sSQL = "select distinct l.place_id".($sOrderBySQL?','.$sOrderBySQL:'')." from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." as l";
-                                                                                       if ($sCountryCodesSQL) $sSQL .= " join placex as lp using (place_id)";
-                                                                                       if ($sPlaceIDs)
-                                                                                       {
-                                                                                               $sSQL .= ",placex as f where ";
-                                                                                               $sSQL .= "f.place_id in ($sPlaceIDs) and ST_DWithin(l.centroid, f.centroid, $fRange) ";
-                                                                                       }
-                                                                                       if ($sPlaceGeom)
-                                                                                       {
-                                                                                               $sSQL .= " where ";
-                                                                                               $sSQL .= "ST_Contains('".$sPlaceGeom."', l.centroid) ";
-                                                                                       }
-                                                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                                                       {
-                                                                                               $sSQL .= " and l.place_id not in (".join(',',$this->aExcludePlaceIDs).")";
-                                                                                       }
-                                                                                       if ($sCountryCodesSQL) $sSQL .= " and lp.calculated_country_code in ($sCountryCodesSQL)";
-                                                                                       if ($sOrderBySQL) $sSQL .= "order by ".$sOrderBySQL." asc";
-                                                                                       if ($this->iOffset) $sSQL .= " offset $this->iOffset";
-                                                                                       $sSQL .= " limit $this->iLimit";
-                                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                                       $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL)));
-                                                                               }
-                                                                               else
-                                                                               {
-                                                                                       if (isset($aSearch['fRadius']) && $aSearch['fRadius']) $fRange = $aSearch['fRadius'];
-
-                                                                                       $sOrderBySQL = '';
-                                                                                       if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.geometry)";
-                                                                                       else $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)";
-
-                                                                                       $sSQL = "select distinct l.place_id".($sOrderBysSQL?','.$sOrderBysSQL:'')." from placex as l,placex as f where ";
-                                                                                       $sSQL .= "f.place_id in ( $sPlaceIDs) and ST_DWithin(l.geometry, f.centroid, $fRange) ";
-                                                                                       $sSQL .= "and l.class='".$aSearch['sClass']."' and l.type='".$aSearch['sType']."' ";
-                                                                                       if (sizeof($this->aExcludePlaceIDs))
-                                                                                       {
-                                                                                               $sSQL .= " and l.place_id not in (".join(',',$this->aExcludePlaceIDs).")";
-                                                                                       }
-                                                                                       if ($sCountryCodesSQL) $sSQL .= " and l.calculated_country_code in ($sCountryCodesSQL)";
-                                                                                       if ($sOrderBy) $sSQL .= "order by ".$OrderBysSQL." asc";
-                                                                                       if ($this->iOffset) $sSQL .= " offset $this->iOffset";
-                                                                                       $sSQL .= " limit $this->iLimit";
-                                                                                       if (CONST_Debug) var_dump($sSQL);
-                                                                                       $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL)));
-                                                                               }
-                                                                       }
-                                                               }
-
-                                                               $aPlaceIDs = $aClassPlaceIDs;
-
-                                                       }
-
-                                               }
-
-                                               if (CONST_Debug) { echo "<br><b>Place IDs:</b> "; var_Dump($aPlaceIDs); }
-
-                                               foreach($aPlaceIDs as $iPlaceID)
-                                               {
-                                                       // array for placeID => -1 | Tiger housenumber
-                                                       $aResultPlaceIDs[$iPlaceID] = $searchedHousenumber;
-                                               }
-                                               if ($iQueryLoop > 20) break;
-                                       }
-
-                                       if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs) && ($this->iMinAddressRank != 0 || $this->iMaxAddressRank != 30))
-                                       {
-                                               // Need to verify passes rank limits before dropping out of the loop (yuk!)
-                                               // reduces the number of place ids, like a filter
-                                               // rank_address is 30 for interpolated housenumbers
-                                               $sSQL = "select place_id from placex where place_id in (".join(',',array_keys($aResultPlaceIDs)).") ";
-                                               $sSQL .= "and (placex.rank_address between $this->iMinAddressRank and $this->iMaxAddressRank ";
-                                               if (14 >= $this->iMinAddressRank && 14 <= $this->iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'";
-                                               if ($this->aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$this->aAddressRankList).")";
-                                               if (CONST_Use_US_Tiger_Data)
-                                               {
-                                                       $sSQL .= ") UNION select place_id from location_property_tiger where place_id in (".join(',',array_keys($aResultPlaceIDs)).") ";
-                                                       $sSQL .= "and (30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
-                                                       if ($this->aAddressRankList) $sSQL .= " OR 30 in (".join(',',$this->aAddressRankList).")";
-                                               }
-                                               $sSQL .= ") UNION select place_id from location_property_osmline where place_id in (".join(',',array_keys($aResultPlaceIDs)).")";
-                                               $sSQL .= " and (30 between $this->iMinAddressRank and $this->iMaxAddressRank)";
-                                               if (CONST_Debug) var_dump($sSQL);
-                                               $aFilteredPlaceIDs = chksql($this->oDB->getCol($sSQL));
-                                               $tempIDs = array();
-                                               foreach($aFilteredPlaceIDs as $placeID)
-                                               {
-                                                       $tempIDs[$placeID] = $aResultPlaceIDs[$placeID];  //assign housenumber to placeID
-                                               }
-                                               $aResultPlaceIDs = $tempIDs;
-                                       }
-
-                                       //exit;
-                                       if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) break;
-                                       if ($iGroupLoop > 4) break;
-                                       if ($iQueryLoop > 30) break;
-                               }
-
-                               // Did we find anything?
-                               if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs))
-                               {
-                                       $aSearchResults = $this->getDetails($aResultPlaceIDs);
-                               }
-
-                       }
-                       else
-                       {
-                               // Just interpret as a reverse geocode
-                               $oReverse = new ReverseGeocode($this->oDB);
-                               $oReverse->setZoom(18);
-
-                               $aLookup = $oReverse->lookup((float)$this->aNearPoint[0],
-                                                            (float)$this->aNearPoint[1],
-                                                            false);
-
-                               if (CONST_Debug) var_dump("Reverse search", $aLookup);
-
-                               if ($aLookup['place_id'])
-                                       $aSearchResults = $this->getDetails(array($aLookup['place_id'] => -1));
-                               else
-                                       $aSearchResults = array();
-                       }
-
-                       // No results? Done
-                       if (!sizeof($aSearchResults))
-                       {
-                               if ($this->bFallback)
-                               {
-                                       if ($this->fallbackStructuredQuery())
-                                       {
-                                               return $this->lookup();
-                                       }
-                               }
-
-                               return array();
-                       }
-
-                       $aClassType = getClassTypesWithImportance();
-                       $aRecheckWords = preg_split('/\b[\s,\\-]*/u',$sQuery);
-                       foreach($aRecheckWords as $i => $sWord)
-                       {
-                               if (!preg_match('/\pL/', $sWord)) unset($aRecheckWords[$i]);
-                       }
-
-                       if (CONST_Debug) { echo '<i>Recheck words:<\i>'; var_dump($aRecheckWords); }
-
-                       $oPlaceLookup = new PlaceLookup($this->oDB);
-                       $oPlaceLookup->setIncludePolygonAsPoints($this->bIncludePolygonAsPoints);
-                       $oPlaceLookup->setIncludePolygonAsText($this->bIncludePolygonAsText);
-                       $oPlaceLookup->setIncludePolygonAsGeoJSON($this->bIncludePolygonAsGeoJSON);
-                       $oPlaceLookup->setIncludePolygonAsKML($this->bIncludePolygonAsKML);
-                       $oPlaceLookup->setIncludePolygonAsSVG($this->bIncludePolygonAsSVG);
-                       $oPlaceLookup->setPolygonSimplificationThreshold($this->fPolygonSimplificationThreshold);
-
-                       foreach($aSearchResults as $iResNum => $aResult)
-                       {
-                               // Default
-                               $fDiameter = getResultDiameter($aResult);
-
-                               $aOutlineResult = $oPlaceLookup->getOutlines($aResult['place_id'], $aResult['lon'], $aResult['lat'], $fDiameter/2);
-                               if ($aOutlineResult)
-                               {
-                                       $aResult = array_merge($aResult, $aOutlineResult);
-                               }
-                               
-                               if ($aResult['extra_place'] == 'city')
-                               {
-                                       $aResult['class'] = 'place';
-                                       $aResult['type'] = 'city';
-                                       $aResult['rank_search'] = 16;
-                               }
-
-                               // Is there an icon set for this type of result?
-                               if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
-                                               && $aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
-                               {
-                                       $aResult['icon'] = CONST_Website_BaseURL.'images/mapicons/'.$aClassType[$aResult['class'].':'.$aResult['type']]['icon'].'.p.20.png';
-                               }
-
-                               if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'])
-                                               && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'])
-                               {
-                                       $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'];
-                               }
-                               elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['label'])
-                                               && $aClassType[$aResult['class'].':'.$aResult['type']]['label'])
-                               {
-                                       $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type']]['label'];
-                               }
-                               // if tag '&addressdetails=1' is set in query
-                               if ($this->bIncludeAddressDetails)
-                               {
-                                       // getAddressDetails() is defined in lib.php and uses the SQL function get_addressdata in functions.sql
-                                       $aResult['address'] = getAddressDetails($this->oDB, $sLanguagePrefArraySQL, $aResult['place_id'], $aResult['country_code'], $aResultPlaceIDs[$aResult['place_id']]);
-                                       if ($aResult['extra_place'] == 'city' && !isset($aResult['address']['city']))
-                                       {
-                                               $aResult['address'] = array_merge(array('city' => array_shift(array_values($aResult['address']))), $aResult['address']);
-                                       }
-                               }
-                               if ($this->bIncludeExtraTags)
-                               {
-                                       if ($aResult['extra'])
-                                       {
-                                               $aResult['sExtraTags'] = json_decode($aResult['extra']);
-                                       }
-                                       else
-                                       {
-                                               $aResult['sExtraTags'] = (object) array();
-                                       }
-                               }
-
-                               if ($this->bIncludeNameDetails)
-                               {
-                                       if ($aResult['names'])
-                                       {
-                                               $aResult['sNameDetails'] = json_decode($aResult['names']);
-                                       }
-                                       else
-                                       {
-                                               $aResult['sNameDetails'] = (object) array();
-                                       }
-                               }
-
-                               // Adjust importance for the number of exact string matches in the result
-                               $aResult['importance'] = max(0.001,$aResult['importance']);
-                               $iCountWords = 0;
-                               $sAddress = $aResult['langaddress'];
-                               foreach($aRecheckWords as $i => $sWord)
-                               {
-                                       if (stripos($sAddress, $sWord)!==false)
-                                       {
-                                               $iCountWords++;
-                                               if (preg_match("/(^|,)\s*".preg_quote($sWord, '/')."\s*(,|$)/", $sAddress)) $iCountWords += 0.1;
-                                       }
-                               }
-
-                               $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):
-                               //   - approximate importance of address parts
-                               $aResult['foundorder'] = -$aResult['addressimportance']/10;
-                               //   - number of exact matches from the query
-                               if (isset($this->exactMatchCache[$aResult['place_id']]))
-                                       $aResult['foundorder'] -= $this->exactMatchCache[$aResult['place_id']];
-                               else if (isset($this->exactMatchCache[$aResult['parent_place_id']]))
-                                       $aResult['foundorder'] -= $this->exactMatchCache[$aResult['parent_place_id']];
-                               //  - importance of the class/type
-                               if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
-                                       && $aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
-                               {
-                                       $aResult['foundorder'] += 0.0001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
-                               }
-                               else
-                               {
-                                       $aResult['foundorder'] += 0.01;
-                               }
-                               if (CONST_Debug) { var_dump($aResult); }
-                               $aSearchResults[$iResNum] = $aResult;
-                       }
-                       uasort($aSearchResults, 'byImportance');
-
-                       $aOSMIDDone = array();
-                       $aClassTypeNameDone = array();
-                       $aToFilter = $aSearchResults;
-                       $aSearchResults = array();
-
-                       $bFirst = true;
-                       foreach($aToFilter as $iResNum => $aResult)
-                       {
-                               $this->aExcludePlaceIDs[$aResult['place_id']] = $aResult['place_id'];
-                               if ($bFirst)
-                               {
-                                       $fLat = $aResult['lat'];
-                                       $fLon = $aResult['lon'];
-                                       if (isset($aResult['zoom'])) $iZoom = $aResult['zoom'];
-                                       $bFirst = false;
-                               }
-                               if (!$this->bDeDupe || (!isset($aOSMIDDone[$aResult['osm_type'].$aResult['osm_id']])
-                                                       && !isset($aClassTypeNameDone[$aResult['osm_type'].$aResult['class'].$aResult['type'].$aResult['name'].$aResult['admin_level']])))
-                               {
-                                       $aOSMIDDone[$aResult['osm_type'].$aResult['osm_id']] = true;
-                                       $aClassTypeNameDone[$aResult['osm_type'].$aResult['class'].$aResult['type'].$aResult['name'].$aResult['admin_level']] = true;
-                                       $aSearchResults[] = $aResult;
-                               }
-
-                               // Absolute limit on number of results
-                               if (sizeof($aSearchResults) >= $this->iFinalLimit) break;
-                       }
-
-                       return $aSearchResults;
-
-               } // end lookup()
-
-
-       } // end class
+require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
+
+class Geocode
+{
+    protected $oDB;
+
+    protected $aLangPrefOrder = array();
+
+    protected $bIncludeAddressDetails = false;
+    protected $bIncludeExtraTags = false;
+    protected $bIncludeNameDetails = false;
+
+    protected $bIncludePolygonAsPoints = false;
+    protected $bIncludePolygonAsText = false;
+    protected $bIncludePolygonAsGeoJSON = false;
+    protected $bIncludePolygonAsKML = false;
+    protected $bIncludePolygonAsSVG = false;
+    protected $fPolygonSimplificationThreshold = 0.0;
+
+    protected $aExcludePlaceIDs = array();
+    protected $bDeDupe = true;
+    protected $bReverseInPlan = false;
+
+    protected $iLimit = 20;
+    protected $iFinalLimit = 10;
+    protected $iOffset = 0;
+    protected $bFallback = false;
+
+    protected $aCountryCodes = false;
+    protected $aNearPoint = false;
+
+    protected $bBoundedSearch = false;
+    protected $aViewBox = false;
+    protected $sViewboxCentreSQL = false;
+    protected $sViewboxSmallSQL = false;
+    protected $sViewboxLargeSQL = false;
+
+    protected $iMaxRank = 20;
+    protected $iMinAddressRank = 0;
+    protected $iMaxAddressRank = 30;
+    protected $aAddressRankList = array();
+    protected $exactMatchCache = array();
+
+    protected $sAllowedTypesSQLList = false;
+
+    protected $sQuery = false;
+    protected $aStructuredQuery = false;
+
+    function Geocode(&$oDB)
+    {
+        $this->oDB =& $oDB;
+    }
+
+    function setReverseInPlan($bReverse)
+    {
+        $this->bReverseInPlan = $bReverse;
+    }
+
+    function setLanguagePreference($aLangPref)
+    {
+        $this->aLangPrefOrder = $aLangPref;
+    }
+
+    function getIncludeAddressDetails()
+    {
+        return $this->bIncludeAddressDetails;
+    }
+
+    function getIncludeExtraTags()
+    {
+        return $this->bIncludeExtraTags;
+    }
+
+    function getIncludeNameDetails()
+    {
+        return $this->bIncludeNameDetails;
+    }
+
+    function setIncludePolygonAsPoints($b = true)
+    {
+        $this->bIncludePolygonAsPoints = $b;
+    }
+
+    function setIncludePolygonAsText($b = true)
+    {
+        $this->bIncludePolygonAsText = $b;
+    }
+
+    function setIncludePolygonAsGeoJSON($b = true)
+    {
+        $this->bIncludePolygonAsGeoJSON = $b;
+    }
+
+    function setIncludePolygonAsKML($b = true)
+    {
+        $this->bIncludePolygonAsKML = $b;
+    }
+
+    function setIncludePolygonAsSVG($b = true)
+    {
+        $this->bIncludePolygonAsSVG = $b;
+    }
+
+    function setPolygonSimplificationThreshold($f)
+    {
+        $this->fPolygonSimplificationThreshold = $f;
+    }
+
+    function setLimit($iLimit = 10)
+    {
+        if ($iLimit > 50) $iLimit = 50;
+        if ($iLimit < 1) $iLimit = 1;
+
+        $this->iFinalLimit = $iLimit;
+        $this->iLimit = $iLimit + min($iLimit, 10);
+    }
+
+    function getExcludedPlaceIDs()
+    {
+        return $this->aExcludePlaceIDs;
+    }
+
+    function getViewBoxString()
+    {
+        if (!$this->aViewBox) return null;
+        return $this->aViewBox[0].','.$this->aViewBox[3].','.$this->aViewBox[2].','.$this->aViewBox[1];
+    }
+
+    function setFeatureType($sFeatureType)
+    {
+        switch($sFeatureType)
+        {
+        case 'country':
+            $this->setRankRange(4, 4);
+            break;
+        case 'state':
+            $this->setRankRange(8, 8);
+            break;
+        case 'city':
+            $this->setRankRange(14, 16);
+            break;
+        case 'settlement':
+            $this->setRankRange(8, 20);
+            break;
+        }
+    }
+
+    function setRankRange($iMin, $iMax)
+    {
+        $this->iMinAddressRank = $iMin;
+        $this->iMaxAddressRank = $iMax;
+    }
+
+    function setRoute($aRoutePoints, $fRouteWidth)
+    {
+        $this->aViewBox = false;
+
+        $this->sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
+        $sSep = '';
+        foreach($this->aRoutePoints as $aPoint)
+        {
+            $fPoint = (float)$aPoint;
+            $this->sViewboxCentreSQL .= $sSep.$fPoint;
+            $sSep = ($sSep == ' ') ? ',' : ' ';
+        }
+        $this->sViewboxCentreSQL .= ")'::geometry,4326)";
+
+        $this->sViewboxSmallSQL = 'st_buffer('.$this->sViewboxCentreSQL;
+        $this->sViewboxSmallSQL .= ','.($fRouteWidth/69).')';
+
+        $this->sViewboxLargeSQL = 'st_buffer('.$this->sViewboxCentreSQL;
+        $this->sViewboxLargeSQL .= ','.($fRouteWidth/30).')';
+    }
+
+    function setViewbox($aViewbox)
+    {
+        $this->aViewBox = array_map('floatval', $aViewbox);
+
+        $fHeight = $this->aViewBox[0] - $this->aViewBox[2];
+        $fWidth = $this->aViewBox[1] - $this->aViewBox[3];
+        $aBigViewBox[0] = $this->aViewBox[0] + $fHeight;
+        $aBigViewBox[2] = $this->aViewBox[2] - $fHeight;
+        $aBigViewBox[1] = $this->aViewBox[1] + $fWidth;
+        $aBigViewBox[3] = $this->aViewBox[3] - $fWidth;
+
+        $this->sViewboxCentreSQL = false;
+        $this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$this->aViewBox[0].",".$this->aViewBox[1]."),ST_Point(".$this->aViewBox[2].",".$this->aViewBox[3].")),4326)";
+        $this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$aBigViewBox[0].",".$aBigViewBox[1]."),ST_Point(".$aBigViewBox[2].",".$aBigViewBox[3].")),4326)";
+    }
+
+    function setNearPoint($aNearPoint, $fRadiusDeg = 0.1)
+    {
+        $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg);
+    }
+
+    function setQuery($sQueryString)
+    {
+        $this->sQuery = $sQueryString;
+        $this->aStructuredQuery = false;
+    }
+
+    function getQueryString()
+    {
+        return $this->sQuery;
+    }
+
+
+    function loadParamArray($oParams)
+    {
+        $this->bIncludeAddressDetails = $oParams->getBool('addressdetails',
+                                                          $this->bIncludeAddressDetails);
+        $this->bIncludeExtraTags = $oParams->getBool('extratags',
+                                                     $this->bIncludeExtraTags);
+        $this->bIncludeNameDetails = $oParams->getBool('namedetails',
+                                                       $this->bIncludeNameDetails);
+
+        $this->bBoundedSearch = $oParams->getBool('bounded', $this->bBoundedSearch);
+        $this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe);
+
+        $this->setLimit($oParams->getInt('limit', $this->iFinalLimit));
+        $this->iOffset = $oParams->getInt('offset', $this->iOffset);
+
+        $this->bFallback = $oParams->getBool('fallback', $this->bFallback);
+
+        // List of excluded Place IDs - used for more acurate pageing
+        $sExcluded = $oParams->getStringList('exclude_place_ids');
+        if ($sExcluded)
+        {
+            foreach($sExcluded as $iExcludedPlaceID)
+            {
+                $iExcludedPlaceID = (int)$iExcludedPlaceID;
+                if ($iExcludedPlaceID)
+                    $aExcludePlaceIDs[$iExcludedPlaceID] = $iExcludedPlaceID;
+            }
+
+            if (isset($aExcludePlaceIDs))
+                $this->aExcludePlaceIDs = $aExcludePlaceIDs;
+        }
+
+        // Only certain ranks of feature
+        $sFeatureType = $oParams->getString('featureType');
+        if (!$sFeatureType) $sFeatureType = $oParams->getString('featuretype');
+        if ($sFeatureType) $this->setFeatureType($sFeatureType);
+
+        // Country code list
+        $sCountries = $oParams->getStringList('countrycodes');
+        if ($sCountries)
+        {
+            foreach($sCountries as $sCountryCode)
+            {
+                if (preg_match('/^[a-zA-Z][a-zA-Z]$/', $sCountryCode))
+                {
+                    $aCountries[] = strtolower($sCountryCode);
+                }
+            }
+            if (isset($aCountryCodes))
+                $this->aCountryCodes = $aCountries;
+        }
+
+        $aViewbox = $oParams->getStringList('viewboxlbrt');
+        if ($aViewbox)
+        {
+            $this->setViewbox($aViewbox);
+        }
+        else
+        {
+            $aViewbox = $oParams->getStringList('viewbox');
+            if ($aViewbox)
+            {
+                $this->setViewBox(array($aViewbox[0], $aViewbox[3],
+                                        $aViewbox[2], $aViewbox[1]));
+            }
+            else
+            {
+                $aRoute = $oParams->getStringList('route');
+                $fRouteWidth = $oParams->getFloat('routewidth');
+                if ($aRoute && $fRouteWidth)
+                {
+                    $this->setRoute($aRoute, $fRouteWidth);
+                }
+            }
+        }
+    }
+
+    function setQueryFromParams($oParams)
+    {
+        // Search query
+        $sQuery = $oParams->getString('q');
+        if (!$sQuery)
+        {
+            $this->setStructuredQuery($oParams->getString('amenity'),
+                                      $oParams->getString('street'),
+                                      $oParams->getString('city'),
+                                      $oParams->getString('county'),
+                                      $oParams->getString('state'),
+                                      $oParams->getString('country'),
+                                      $oParams->getString('postalcode'));
+            $this->setReverseInPlan(false);
+        }
+        else
+        {
+            $this->setQuery($sQuery);
+        }
+    }
+
+    function loadStructuredAddressElement($sValue, $sKey, $iNewMinAddressRank, $iNewMaxAddressRank, $aItemListValues)
+    {
+        $sValue = trim($sValue);
+        if (!$sValue) return false;
+        $this->aStructuredQuery[$sKey] = $sValue;
+        if ($this->iMinAddressRank == 0 && $this->iMaxAddressRank == 30)
+        {
+            $this->iMinAddressRank = $iNewMinAddressRank;
+            $this->iMaxAddressRank = $iNewMaxAddressRank;
+        }
+        if ($aItemListValues) $this->aAddressRankList = array_merge($this->aAddressRankList, $aItemListValues);
+        return true;
+    }
+
+    function setStructuredQuery($sAmentiy = false, $sStreet = false, $sCity = false, $sCounty = false, $sState = false, $sCountry = false, $sPostalCode = false)
+    {
+        $this->sQuery = false;
+
+        // Reset
+        $this->iMinAddressRank = 0;
+        $this->iMaxAddressRank = 30;
+        $this->aAddressRankList = array();
+
+        $this->aStructuredQuery = array();
+        $this->sAllowedTypesSQLList = '';
+
+        $this->loadStructuredAddressElement($sAmentiy, 'amenity', 26, 30, false);
+        $this->loadStructuredAddressElement($sStreet, 'street', 26, 30, false);
+        $this->loadStructuredAddressElement($sCity, 'city', 14, 24, false);
+        $this->loadStructuredAddressElement($sCounty, 'county', 9, 13, false);
+        $this->loadStructuredAddressElement($sState, 'state', 8, 8, false);
+        $this->loadStructuredAddressElement($sPostalCode, 'postalcode' , 5, 11, array(5, 11));
+        $this->loadStructuredAddressElement($sCountry, 'country', 4, 4, false);
+
+        if (sizeof($this->aStructuredQuery) > 0)
+        {
+            $this->sQuery = join(', ', $this->aStructuredQuery);
+            if ($this->iMaxAddressRank < 30)
+            {
+                $sAllowedTypesSQLList = '(\'place\',\'boundary\')';
+            }
+        }
+    }
+
+    function fallbackStructuredQuery()
+    {
+        if (!$this->aStructuredQuery) return false;
+
+        $aParams = $this->aStructuredQuery;
+
+        if (sizeof($aParams) == 1) return false;
+
+        $aOrderToFallback = array('postalcode', 'street', 'city', 'county', 'state');
+
+        foreach($aOrderToFallback as $sType)
+        {
+            if (isset($aParams[$sType]))
+            {
+                unset($aParams[$sType]);
+                $this->setStructuredQuery(@$aParams['amenity'], @$aParams['street'], @$aParams['city'], @$aParams['county'], @$aParams['state'], @$aParams['country'], @$aParams['postalcode']);
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    function getDetails($aPlaceIDs)
+    {
+        //$aPlaceIDs is an array with key: placeID and value: tiger-housenumber, if found, else -1
+        if (sizeof($aPlaceIDs) == 0)  return array();
+
+        $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
+
+        // Get the details for display (is this a redundant extra step?)
+        $sPlaceIDs = join(',', array_keys($aPlaceIDs));
+
+        $sImportanceSQL = '';
+        if ($this->sViewboxSmallSQL) $sImportanceSQL .= " case when ST_Contains($this->sViewboxSmallSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * ";
+        if ($this->sViewboxLargeSQL) $sImportanceSQL .= " case when ST_Contains($this->sViewboxLargeSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * ";
+
+        $sSQL = "select osm_type,osm_id,class,type,admin_level,rank_search,rank_address,min(place_id) as place_id, min(parent_place_id) as parent_place_id, calculated_country_code as country_code,";
+        $sSQL .= "get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress,";
+        $sSQL .= "get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
+        $sSQL .= "get_name_by_language(name, ARRAY['ref']) as ref,";
+        if ($this->bIncludeExtraTags) $sSQL .= "hstore_to_json(extratags)::text as extra,";
+        if ($this->bIncludeNameDetails) $sSQL .= "hstore_to_json(name)::text as names,";
+        $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, ";
+        $sSQL .= $sImportanceSQL."coalesce(importance,0.75-(rank_search::float/40)) as importance, ";
+        $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(CASE WHEN placex.rank_search < 28 THEN placex.place_id ELSE placex.parent_place_id END) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
+        $sSQL .= "(extratags->'place') as extra_place ";
+        $sSQL .= "from placex where place_id in ($sPlaceIDs) ";
+        $sSQL .= "and (placex.rank_address between $this->iMinAddressRank and $this->iMaxAddressRank ";
+        if (14 >= $this->iMinAddressRank && 14 <= $this->iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'";
+        if ($this->aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$this->aAddressRankList).")";
+        $sSQL .= ") ";
+        if ($this->sAllowedTypesSQLList) $sSQL .= "and placex.class in $this->sAllowedTypesSQLList ";
+        $sSQL .= "and linked_place_id is null ";
+        $sSQL .= "group by osm_type,osm_id,class,type,admin_level,rank_search,rank_address,calculated_country_code,importance";
+        if (!$this->bDeDupe) $sSQL .= ",place_id";
+        $sSQL .= ",langaddress ";
+        $sSQL .= ",placename ";
+        $sSQL .= ",ref ";
+        if ($this->bIncludeExtraTags) $sSQL .= ",extratags";
+        if ($this->bIncludeNameDetails) $sSQL .= ",name";
+        $sSQL .= ",extratags->'place' ";
+
+        if (30 >= $this->iMinAddressRank && 30 <= $this->iMaxAddressRank)
+        {
+            //only Tiger housenumbers and interpolation lines need to be interpolated, because they are saved as lines 
+            // with start- and endnumber, the common osm housenumbers are usually saved as points
+            $sHousenumbers = "";
+            $i = 0;
+            $length = count($aPlaceIDs);
+            foreach($aPlaceIDs as $placeID => $housenumber)
+            {
+                $i++;
+                $sHousenumbers .= "(".$placeID.", ".$housenumber.")";
+                if($i<$length)
+                    $sHousenumbers .= ", ";
+            }
+            if (CONST_Use_US_Tiger_Data)
+            {
+                //Tiger search only if a housenumber was searched and if it was found (i.e. aPlaceIDs[placeID] = housenumber != -1) (realized through a join)
+                $sSQL .= " union";
+                $sSQL .= " select 'T' 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, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress ";
+                $sSQL .= ", null as placename";
+                $sSQL .= ", null as ref";
+                if ($this->bIncludeExtraTags) $sSQL .= ", null as extra";
+                if ($this->bIncludeNameDetails) $sSQL .= ", null as names";
+                $sSQL .= ", avg(st_x(centroid)) as lon, avg(st_y(centroid)) as lat,";
+                $sSQL .= $sImportanceSQL."-1.15 as importance ";
+                $sSQL .= ", (select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance ";
+                $sSQL .= ", null as extra_place ";
+                $sSQL .= " from (select place_id";
+                //interpolate the Tiger housenumbers here
+                $sSQL .= ", ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) as centroid, parent_place_id, housenumber_for_place";
+                $sSQL .= " from (location_property_tiger ";
+                $sSQL .= " join (values ".$sHousenumbers.") as housenumbers(place_id, housenumber_for_place) using(place_id)) ";
+                $sSQL .= " where housenumber_for_place>=0 and 30 between $this->iMinAddressRank and $this->iMaxAddressRank) as blub"; //postgres wants an alias here
+                $sSQL .= " group by place_id, housenumber_for_place"; //is this group by really needed?, place_id + housenumber (in combination) are unique
+                if (!$this->bDeDupe) $sSQL .= ", place_id ";
+            }
+            // osmline
+            // interpolation line search only if a housenumber was searched and if it was found (i.e. aPlaceIDs[placeID] = housenumber != -1) (realized through a join)
+            $sSQL .= " union ";
+            $sSQL .= "select 'W' 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, calculated_country_code as country_code, ";
+            $sSQL .= "get_address_by_language(place_id, housenumber_for_place, $sLanguagePrefArraySQL) as langaddress, ";
+            $sSQL .= "null as placename, ";
+            $sSQL .= "null as ref, ";
+            if ($this->bIncludeExtraTags) $sSQL .= "null as extra, ";
+            if ($this->bIncludeNameDetails) $sSQL .= "null as names, ";
+            $sSQL .= " avg(st_x(centroid)) as lon, avg(st_y(centroid)) as lat,";
+            $sSQL .= $sImportanceSQL."-0.1 as importance, ";  // slightly smaller than the importance for normal houses with rank 30, which is 0
+            $sSQL .= " (select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p";
+            $sSQL .= " where s.place_id = min(blub.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance,";
+            $sSQL .= " null as extra_place ";
+            $sSQL .= " from (select place_id, calculated_country_code ";
+            //interpolate the housenumbers here
+            $sSQL .= ", CASE WHEN startnumber != endnumber THEN ST_LineInterpolatePoint(linegeo, (housenumber_for_place-startnumber::float)/(endnumber-startnumber)::float) ";
+            $sSQL .= " ELSE ST_LineInterpolatePoint(linegeo, 0.5) END as centroid";
+            $sSQL .= ", parent_place_id, housenumber_for_place ";
+            $sSQL .= " from (location_property_osmline ";
+            $sSQL .= " join (values ".$sHousenumbers.") as housenumbers(place_id, housenumber_for_place) using(place_id)) ";
+            $sSQL .= " where housenumber_for_place>=0 and 30 between $this->iMinAddressRank and $this->iMaxAddressRank) as blub"; //postgres wants an alias here
+            $sSQL .= " group by place_id, housenumber_for_place, calculated_country_code "; //is this group by really needed?, place_id + housenumber (in combination) are unique
+            if (!$this->bDeDupe) $sSQL .= ", place_id ";
+
+            if (CONST_Use_Aux_Location_data)
+            {
+                $sSQL .= " union ";
+                $sSQL .= "select 'L' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, 0 as rank_search, 0 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, -1, $sLanguagePrefArraySQL) as langaddress, ";
+                $sSQL .= "null as placename, ";
+                $sSQL .= "null as ref, ";
+                if ($this->bIncludeExtraTags) $sSQL .= "null as extra, ";
+                if ($this->bIncludeNameDetails) $sSQL .= "null as names, ";
+                $sSQL .= "avg(ST_X(centroid)) as lon, avg(ST_Y(centroid)) as lat, ";
+                $sSQL .= $sImportanceSQL."-1.10 as importance, ";
+                $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_aux.parent_place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, ";
+                $sSQL .= "null as extra_place ";
+                $sSQL .= "from location_property_aux where place_id in ($sPlaceIDs) ";
+                $sSQL .= "and 30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
+                $sSQL .= "group by place_id";
+                if (!$this->bDeDupe) $sSQL .= ", place_id";
+                $sSQL .= ", get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) ";
+            }
+        }
+
+        $sSQL .= " order by importance desc";
+        if (CONST_Debug) { echo "<hr>"; var_dump($sSQL); }
+        $aSearchResults = chksql($this->oDB->getAll($sSQL),
+                                 "Could not get details for place.");
+
+        return $aSearchResults;
+    }
+
+    function getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases)
+    {
+        /*
+             Calculate all searches using aValidTokens i.e.
+             'Wodsworth Road, Sheffield' =>
+
+             Phrase Wordset
+             0      0       (wodsworth road)
+             0      1       (wodsworth)(road)
+             1      0       (sheffield)
+
+             Score how good the search is so they can be ordered
+         */
+        foreach($aPhrases as $iPhrase => $sPhrase)
+        {
+            $aNewPhraseSearches = array();
+            if ($bStructuredPhrases) $sPhraseType = $aPhraseTypes[$iPhrase];
+            else $sPhraseType = '';
+
+            foreach($aPhrases[$iPhrase]['wordsets'] as $iWordSet => $aWordset)
+            {
+                // Too many permutations - too expensive
+                if ($iWordSet > 120) break;
+
+                $aWordsetSearches = $aSearches;
+
+                // Add all words from this wordset
+                foreach($aWordset as $iToken => $sToken)
+                {
+                    //echo "<br><b>$sToken</b>";
+                    $aNewWordsetSearches = array();
+
+                    foreach($aWordsetSearches as $aCurrentSearch)
+                    {
+                        //echo "<i>";
+                        //var_dump($aCurrentSearch);
+                        //echo "</i>";
+
+                        // If the token is valid
+                        if (isset($aValidTokens[' '.$sToken]))
+                        {
+                            foreach($aValidTokens[' '.$sToken] as $aSearchTerm)
+                            {
+                                $aSearch = $aCurrentSearch;
+                                $aSearch['iSearchRank']++;
+                                if (($sPhraseType == '' || $sPhraseType == 'country') && !empty($aSearchTerm['country_code']) && $aSearchTerm['country_code'] != '0')
+                                {
+                                    if ($aSearch['sCountryCode'] === false)
+                                    {
+                                        $aSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
+                                        // Country is almost always at the end of the string - increase score for finding it anywhere else (optimisation)
+                                        if (($iToken+1 != sizeof($aWordset) || $iPhrase+1 != sizeof($aPhrases)))
+                                        {
+                                            $aSearch['iSearchRank'] += 5;
+                                        }
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                    }
+                                }
+                                elseif (isset($aSearchTerm['lat']) && $aSearchTerm['lat'] !== '' && $aSearchTerm['lat'] !== null)
+                                {
+                                    if ($aSearch['fLat'] === '')
+                                    {
+                                        $aSearch['fLat'] = $aSearchTerm['lat'];
+                                        $aSearch['fLon'] = $aSearchTerm['lon'];
+                                        $aSearch['fRadius'] = $aSearchTerm['radius'];
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                    }
+                                }
+                                elseif ($sPhraseType == 'postalcode')
+                                {
+                                    // We need to try the case where the postal code is the primary element (i.e. no way to tell if it is (postalcode, city) OR (city, postalcode) so try both
+                                    if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
+                                    {
+                                        // If we already have a name try putting the postcode first
+                                        if (sizeof($aSearch['aName']))
+                                        {
+                                            $aNewSearch = $aSearch;
+                                            $aNewSearch['aAddress'] = array_merge($aNewSearch['aAddress'], $aNewSearch['aName']);
+                                            $aNewSearch['aName'] = array();
+                                            $aNewSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aNewSearch;
+                                        }
+
+                                        if (sizeof($aSearch['aName']))
+                                        {
+                                            if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
+                                            {
+                                                $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            }
+                                            else
+                                            {
+                                                $aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                                $aSearch['iSearchRank'] += 1000; // skip;
+                                            }
+                                        }
+                                        else
+                                        {
+                                            $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            //$aSearch['iNamePhrase'] = $iPhrase;
+                                        }
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                    }
+
+                                }
+                                elseif (($sPhraseType == '' || $sPhraseType == 'street') && $aSearchTerm['class'] == 'place' && $aSearchTerm['type'] == 'house')
+                                {
+                                    if ($aSearch['sHouseNumber'] === '')
+                                    {
+                                        $aSearch['sHouseNumber'] = $sToken;
+                                        // sanity check: if the housenumber is not mainly made
+                                        // up of numbers, add a penalty
+                                        if (preg_match_all("/[^0-9]/", $sToken, $aMatches) > 2) $aSearch['iSearchRank']++;
+                                        // also housenumbers should appear in the first or second phrase
+                                        if ($iPhrase > 1) $aSearch['iSearchRank'] += 1;
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                        /*
+                                        // Fall back to not searching for this item (better than nothing)
+                                        $aSearch = $aCurrentSearch;
+                                        $aSearch['iSearchRank'] += 1;
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                         */
+                                    }
+                                }
+                                elseif ($sPhraseType == '' && $aSearchTerm['class'] !== '' && $aSearchTerm['class'] !== null)
+                                {
+                                    if ($aSearch['sClass'] === '')
+                                    {
+                                        $aSearch['sOperator'] = $aSearchTerm['operator'];
+                                        $aSearch['sClass'] = $aSearchTerm['class'];
+                                        $aSearch['sType'] = $aSearchTerm['type'];
+                                        if (sizeof($aSearch['aName'])) $aSearch['sOperator'] = 'name';
+                                        else $aSearch['sOperator'] = 'near'; // near = in for the moment
+                                        if (strlen($aSearchTerm['operator']) == 0) $aSearch['iSearchRank'] += 1;
+
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                    }
+                                }
+                                elseif (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
+                                {
+                                    if (sizeof($aSearch['aName']))
+                                    {
+                                        if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strpos($sToken, ' ') !== false))
+                                        {
+                                            $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                        }
+                                        else
+                                        {
+                                            $aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            $aSearch['iSearchRank'] += 1000; // skip;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                        //$aSearch['iNamePhrase'] = $iPhrase;
+                                    }
+                                    if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                }
+                            }
+                        }
+                        // Look for partial matches.
+                        // Note that there is no point in adding country terms here
+                        // because country are omitted in the address.
+                        if (isset($aValidTokens[$sToken]) && $sPhraseType != 'country')
+                        {
+                            // Allow searching for a word - but at extra cost
+                            foreach($aValidTokens[$sToken] as $aSearchTerm)
+                            {
+                                if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
+                                {
+                                    if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strpos($sToken, ' ') === false)
+                                    {
+                                        $aSearch = $aCurrentSearch;
+                                        $aSearch['iSearchRank'] += 1;
+                                        if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
+                                        {
+                                            $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                        }
+                                        elseif (isset($aValidTokens[' '.$sToken])) // revert to the token version?
+                                        {
+                                            $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            $aSearch['iSearchRank'] += 1;
+                                            if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                            foreach($aValidTokens[' '.$sToken] as $aSearchTermToken)
+                                            {
+                                                if (empty($aSearchTermToken['country_code'])
+                                                        && empty($aSearchTermToken['lat'])
+                                                        && empty($aSearchTermToken['class']))
+                                                {
+                                                    $aSearch = $aCurrentSearch;
+                                                    $aSearch['iSearchRank'] += 1;
+                                                    $aSearch['aAddress'][$aSearchTermToken['word_id']] = $aSearchTermToken['word_id'];
+                                                    if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                                }
+                                            }
+                                        }
+                                        else
+                                        {
+                                            $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                            if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
+                                            if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                        }
+                                    }
+
+                                    if (!sizeof($aCurrentSearch['aName']) || $aCurrentSearch['iNamePhrase'] == $iPhrase)
+                                    {
+                                        $aSearch = $aCurrentSearch;
+                                        $aSearch['iSearchRank'] += 1;
+                                        if (!sizeof($aCurrentSearch['aName'])) $aSearch['iSearchRank'] += 1;
+                                        if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
+                                        if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
+                                            $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                        else
+                                            $aSearch['aNameNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                        $aSearch['iNamePhrase'] = $iPhrase;
+                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            // Allow skipping a word - but at EXTREAM cost
+                            //$aSearch = $aCurrentSearch;
+                            //$aSearch['iSearchRank']+=100;
+                            //$aNewWordsetSearches[] = $aSearch;
+                        }
+                    }
+                    // Sort and cut
+                    usort($aNewWordsetSearches, 'bySearchRank');
+                    $aWordsetSearches = array_slice($aNewWordsetSearches, 0, 50);
+                }
+                //var_Dump('<hr>',sizeof($aWordsetSearches)); exit;
+
+                $aNewPhraseSearches = array_merge($aNewPhraseSearches, $aNewWordsetSearches);
+                usort($aNewPhraseSearches, 'bySearchRank');
+
+                $aSearchHash = array();
+                foreach($aNewPhraseSearches as $iSearch => $aSearch)
+                {
+                    $sHash = serialize($aSearch);
+                    if (isset($aSearchHash[$sHash])) unset($aNewPhraseSearches[$iSearch]);
+                    else $aSearchHash[$sHash] = 1;
+                }
+
+                $aNewPhraseSearches = array_slice($aNewPhraseSearches, 0, 50);
+            }
+
+            // Re-group the searches by their score, junk anything over 20 as just not worth trying
+            $aGroupedSearches = array();
+            foreach($aNewPhraseSearches as $aSearch)
+            {
+                if ($aSearch['iSearchRank'] < $this->iMaxRank)
+                {
+                    if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
+                    $aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
+                }
+            }
+            ksort($aGroupedSearches);
+
+            $iSearchCount = 0;
+            $aSearches = array();
+            foreach($aGroupedSearches as $iScore => $aNewSearches)
+            {
+                $iSearchCount += sizeof($aNewSearches);
+                $aSearches = array_merge($aSearches, $aNewSearches);
+                if ($iSearchCount > 50) break;
+            }
+
+            //if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
+
+        }
+        return $aGroupedSearches;
+
+    }
+
+    /* Perform the actual query lookup.
+
+        Returns an ordered list of results, each with the following fields:
+            osm_type: type of corresponding OSM object
+                        N - node
+                        W - way
+                        R - relation
+                        P - postcode (internally computed)
+            osm_id: id of corresponding OSM object
+            class: general object class (corresponds to tag key of primary OSM tag)
+            type: subclass of object (corresponds to tag value of primary OSM tag)
+            admin_level: see http://wiki.openstreetmap.org/wiki/Admin_level
+            rank_search: rank in search hierarchy
+                        (see also http://wiki.openstreetmap.org/wiki/Nominatim/Development_overview#Country_to_street_level)
+            rank_address: rank in address hierarchy (determines orer in address)
+            place_id: internal key (may differ between different instances)
+            country_code: ISO country code
+            langaddress: localized full address
+            placename: localized name of object
+            ref: content of ref tag (if available)
+            lon: longitude
+            lat: latitude
+            importance: importance of place based on Wikipedia link count
+            addressimportance: cumulated importance of address elements
+            extra_place: type of place (for admin boundaries, if there is a place tag)
+            aBoundingBox: bounding Box
+            label: short description of the object class/type (English only)
+            name: full name (currently the same as langaddress)
+            foundorder: secondary ordering for places with same importance
+    */
+    function lookup()
+    {
+        if (!$this->sQuery && !$this->aStructuredQuery) return false;
+
+        $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]";
+        $sCountryCodesSQL = false;
+        if ($this->aCountryCodes)
+        {
+            $sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes));
+        }
+
+        $sQuery = $this->sQuery;
+
+        // Conflicts between US state abreviations and various words for 'the' in different languages
+        if (isset($this->aLangPrefOrder['name:en']))
+        {
+            $sQuery = preg_replace('/(^|,)\s*il\s*(,|$)/','\1illinois\2', $sQuery);
+            $sQuery = preg_replace('/(^|,)\s*al\s*(,|$)/','\1alabama\2', $sQuery);
+            $sQuery = preg_replace('/(^|,)\s*la\s*(,|$)/','\1louisiana\2', $sQuery);
+        }
+
+        $bBoundingBoxSearch = $this->bBoundedSearch && $this->sViewboxSmallSQL;
+        if ($this->sViewboxCentreSQL)
+        {
+            // For complex viewboxes (routes) precompute the bounding geometry
+            $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxSmallSQL),
+                            "Could not get small viewbox");
+            $this->sViewboxSmallSQL = "'".$sGeom."'::geometry";
+
+            $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxLargeSQL),
+                            "Could not get large viewbox");
+            $this->sViewboxLargeSQL = "'".$sGeom."'::geometry";
+        }
+
+        // Do we have anything that looks like a lat/lon pair?
+        if ( $aLooksLike = looksLikeLatLonPair($sQuery) )
+        {
+            $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon']));
+            $sQuery = $aLooksLike['query'];
+        }
+
+        $aSearchResults = array();
+        if ($sQuery || $this->aStructuredQuery)
+        {
+            // Start with a blank search
+            $aSearches = array(
+                array('iSearchRank' => 0,
+                            'iNamePhrase' => -1,
+                            'sCountryCode' => false,
+                            'aName' => array(),
+                            'aAddress' => array(),
+                            'aFullNameAddress' => array(),
+                            'aNameNonSearch' => array(),
+                            'aAddressNonSearch' => array(),
+                            'sOperator' => '',
+                            'aFeatureName' => array(),
+                            'sClass' => '',
+                            'sType' => '',
+                            'sHouseNumber' => '',
+                            'fLat' => '',
+                            'fLon' => '',
+                            'fRadius' => ''
+                        )
+            );
+
+            // Do we have a radius search?
+            $sNearPointSQL = false;
+            if ($this->aNearPoint)
+            {
+                $sNearPointSQL = "ST_SetSRID(ST_Point(".(float)$this->aNearPoint[1].",".(float)$this->aNearPoint[0]."),4326)";
+                $aSearches[0]['fLat'] = (float)$this->aNearPoint[0];
+                $aSearches[0]['fLon'] = (float)$this->aNearPoint[1];
+                $aSearches[0]['fRadius'] = (float)$this->aNearPoint[2];
+            }
+
+            // Any 'special' terms in the search?
+            $bSpecialTerms = false;
+            preg_match_all('/\\[(.*)=(.*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
+            $aSpecialTerms = array();
+            foreach($aSpecialTermsRaw as $aSpecialTerm)
+            {
+                $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
+                $aSpecialTerms[strtolower($aSpecialTerm[1])] = $aSpecialTerm[2];
+            }
+
+            preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
+            $aSpecialTerms = array();
+            if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity'])
+            {
+                $aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']);
+                unset($this->aStructuredQuery['amenity']);
+            }
+            foreach($aSpecialTermsRaw as $aSpecialTerm)
+            {
+                $sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
+                $sToken = chksql($this->oDB->getOne("select make_standard_name('".$aSpecialTerm[1]."') as string"));
+                $sSQL = 'select * from (select word_id,word_token, word, class, type, country_code, operator';
+                $sSQL .= ' from word where word_token in (\' '.$sToken.'\')) as x where (class is not null and class not in (\'place\')) or country_code is not null';
+                if (CONST_Debug) var_Dump($sSQL);
+                $aSearchWords = chksql($this->oDB->getAll($sSQL));
+                $aNewSearches = array();
+                foreach($aSearches as $aSearch)
+                {
+                    foreach($aSearchWords as $aSearchTerm)
+                    {
+                        $aNewSearch = $aSearch;
+                        if ($aSearchTerm['country_code'])
+                        {
+                            $aNewSearch['sCountryCode'] = strtolower($aSearchTerm['country_code']);
+                            $aNewSearches[] = $aNewSearch;
+                            $bSpecialTerms = true;
+                        }
+                        if ($aSearchTerm['class'])
+                        {
+                            $aNewSearch['sClass'] = $aSearchTerm['class'];
+                            $aNewSearch['sType'] = $aSearchTerm['type'];
+                            $aNewSearches[] = $aNewSearch;
+                            $bSpecialTerms = true;
+                        }
+                    }
+                }
+                $aSearches = $aNewSearches;
+            }
+
+            // Split query into phrases
+            // Commas are used to reduce the search space by indicating where phrases split
+            if ($this->aStructuredQuery)
+            {
+                $aPhrases = $this->aStructuredQuery;
+                $bStructuredPhrases = true;
+            }
+            else
+            {
+                $aPhrases = explode(',',$sQuery);
+                $bStructuredPhrases = false;
+            }
+
+            // Convert each phrase to standard form
+            // Create a list of standard words
+            // Get all 'sets' of words
+            // Generate a complete list of all
+            $aTokens = array();
+            foreach($aPhrases as $iPhrase => $sPhrase)
+            {
+                $aPhrase = chksql($this->oDB->getRow("select make_standard_name('".pg_escape_string($sPhrase)."') as string"),
+                                  "Cannot nomralize query string (is it an UTF-8 string?)");
+                if (trim($aPhrase['string']))
+                {
+                    $aPhrases[$iPhrase] = $aPhrase;
+                    $aPhrases[$iPhrase]['words'] = explode(' ',$aPhrases[$iPhrase]['string']);
+                    $aPhrases[$iPhrase]['wordsets'] = getWordSets($aPhrases[$iPhrase]['words'], 0);
+                    $aTokens = array_merge($aTokens, getTokensFromSets($aPhrases[$iPhrase]['wordsets']));
+                }
+                else
+                {
+                    unset($aPhrases[$iPhrase]);
+                }
+            }
+
+            // Reindex phrases - we make assumptions later on that they are numerically keyed in order
+            $aPhraseTypes = array_keys($aPhrases);
+            $aPhrases = array_values($aPhrases);
+
+            if (sizeof($aTokens))
+            {
+                // Check which tokens we have, get the ID numbers
+                $sSQL = 'select word_id,word_token, word, class, type, country_code, operator, search_name_count';
+                $sSQL .= ' from word where word_token in ('.join(',',array_map("getDBQuoted",$aTokens)).')';
+
+                if (CONST_Debug) var_Dump($sSQL);
+
+                $aValidTokens = array();
+                if (sizeof($aTokens))
+                {
+                    $aDatabaseWords = chksql($this->oDB->getAll($sSQL),
+                                             "Could not get word tokens.");
+                }
+                else
+                {
+                    $aDatabaseWords = array();
+                }
+                $aPossibleMainWordIDs = array();
+                $aWordFrequencyScores = array();
+                foreach($aDatabaseWords as $aToken)
+                {
+                    // Very special case - require 2 letter country param to match the country code found
+                    if ($bStructuredPhrases && $aToken['country_code'] && !empty($this->aStructuredQuery['country'])
+                            && strlen($this->aStructuredQuery['country']) == 2 && strtolower($this->aStructuredQuery['country']) != $aToken['country_code'])
+                    {
+                        continue;
+                    }
+
+                    if (isset($aValidTokens[$aToken['word_token']]))
+                    {
+                        $aValidTokens[$aToken['word_token']][] = $aToken;
+                    }
+                    else
+                    {
+                        $aValidTokens[$aToken['word_token']] = array($aToken);
+                    }
+                    if (!$aToken['class'] && !$aToken['country_code']) $aPossibleMainWordIDs[$aToken['word_id']] = 1;
+                    $aWordFrequencyScores[$aToken['word_id']] = $aToken['search_name_count'] + 1;
+                }
+                if (CONST_Debug) var_Dump($aPhrases, $aValidTokens);
+
+                // Try and calculate GB postcodes we might be missing
+                foreach($aTokens as $sToken)
+                {
+                    // Source of gb postcodes is now definitive - always use
+                    if (preg_match('/^([A-Z][A-Z]?[0-9][0-9A-Z]? ?[0-9])([A-Z][A-Z])$/', strtoupper(trim($sToken)), $aData))
+                    {
+                        if (substr($aData[1],-2,1) != ' ')
+                        {
+                            $aData[0] = substr($aData[0],0,strlen($aData[1])-1).' '.substr($aData[0],strlen($aData[1])-1);
+                            $aData[1] = substr($aData[1],0,-1).' '.substr($aData[1],-1,1);
+                        }
+                        $aGBPostcodeLocation = gbPostcodeCalculate($aData[0], $aData[1], $aData[2], $this->oDB);
+                        if ($aGBPostcodeLocation)
+                        {
+                            $aValidTokens[$sToken] = $aGBPostcodeLocation;
+                        }
+                    }
+                    // US ZIP+4 codes - if there is no token,
+                    //  merge in the 5-digit ZIP code
+                    else if (!isset($aValidTokens[$sToken]) && preg_match('/^([0-9]{5}) [0-9]{4}$/', $sToken, $aData))
+                    {
+                        if (isset($aValidTokens[$aData[1]]))
+                        {
+                            foreach($aValidTokens[$aData[1]] as $aToken)
+                            {
+                                if (!$aToken['class'])
+                                {
+                                    if (isset($aValidTokens[$sToken]))
+                                    {
+                                        $aValidTokens[$sToken][] = $aToken;
+                                    }
+                                    else
+                                    {
+                                        $aValidTokens[$sToken] = array($aToken);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+
+                foreach($aTokens as $sToken)
+                {
+                    // Unknown single word token with a number - assume it is a house number
+                    if (!isset($aValidTokens[' '.$sToken]) && strpos($sToken,' ') === false && preg_match('/[0-9]/', $sToken))
+                    {
+                        $aValidTokens[' '.$sToken] = array(array('class'=>'place','type'=>'house'));
+                    }
+                }
+
+                // Any words that have failed completely?
+                // TODO: suggestions
+
+                // Start the search process
+                // array with: placeid => -1 | tiger-housenumber
+                $aResultPlaceIDs = array();
+
+                $aGroupedSearches = $this->getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases);
+
+                if ($this->bReverseInPlan)
+                {
+                    // Reverse phrase array and also reverse the order of the wordsets in
+                    // the first and final phrase. Don't bother about phrases in the middle
+                    // because order in the address doesn't matter.
+                    $aPhrases = array_reverse($aPhrases);
+                    $aPhrases[0]['wordsets'] = getInverseWordSets($aPhrases[0]['words'], 0);
+                    if (sizeof($aPhrases) > 1)
+                    {
+                        $aFinalPhrase = end($aPhrases);
+                        $aPhrases[sizeof($aPhrases)-1]['wordsets'] = getInverseWordSets($aFinalPhrase['words'], 0);
+                    }
+                    $aReverseGroupedSearches = $this->getGroupedSearches($aSearches, null, $aPhrases, $aValidTokens, $aWordFrequencyScores, false);
+
+                    foreach($aGroupedSearches as $aSearches)
+                    {
+                        foreach($aSearches as $aSearch)
+                        {
+                            if ($aSearch['iSearchRank'] < $this->iMaxRank)
+                            {
+                                if (!isset($aReverseGroupedSearches[$aSearch['iSearchRank']])) $aReverseGroupedSearches[$aSearch['iSearchRank']] = array();
+                                $aReverseGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
+                            }
+
+                        }
+                    }
+
+                    $aGroupedSearches = $aReverseGroupedSearches;
+                    ksort($aGroupedSearches);
+                }
+            }
+            else
+            {
+                // Re-group the searches by their score, junk anything over 20 as just not worth trying
+                $aGroupedSearches = array();
+                foreach($aSearches as $aSearch)
+                {
+                    if ($aSearch['iSearchRank'] < $this->iMaxRank)
+                    {
+                        if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array();
+                        $aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
+                    }
+                }
+                ksort($aGroupedSearches);
+            }
+
+            if (CONST_Debug) var_Dump($aGroupedSearches);
+
+            if (CONST_Search_TryDroppedAddressTerms && sizeof($this->aStructuredQuery) > 0)
+            {
+                $aCopyGroupedSearches = $aGroupedSearches;
+                foreach($aCopyGroupedSearches as $iGroup => $aSearches)
+                {
+                    foreach($aSearches as $iSearch => $aSearch)
+                    {
+                        $aReductionsList = array($aSearch['aAddress']);
+                        $iSearchRank = $aSearch['iSearchRank'];
+                        while(sizeof($aReductionsList) > 0)
+                        {
+                            $iSearchRank += 5;
+                            if ($iSearchRank > iMaxRank) break 3;
+                            $aNewReductionsList = array();
+                            foreach($aReductionsList as $aReductionsWordList)
+                            {
+                                for ($iReductionWord = 0; $iReductionWord < sizeof($aReductionsWordList); $iReductionWord++)
+                                {
+                                    $aReductionsWordListResult = array_merge(array_slice($aReductionsWordList, 0, $iReductionWord), array_slice($aReductionsWordList, $iReductionWord+1));
+                                    $aReverseSearch = $aSearch;
+                                    $aSearch['aAddress'] = $aReductionsWordListResult;
+                                    $aSearch['iSearchRank'] = $iSearchRank;
+                                    $aGroupedSearches[$iSearchRank][] = $aReverseSearch;
+                                    if (sizeof($aReductionsWordListResult) > 0)
+                                    {
+                                        $aNewReductionsList[] = $aReductionsWordListResult;
+                                    }
+                                }
+                            }
+                            $aReductionsList = $aNewReductionsList;
+                        }
+                    }
+                }
+                ksort($aGroupedSearches);
+            }
+
+            // Filter out duplicate searches
+            $aSearchHash = array();
+            foreach($aGroupedSearches as $iGroup => $aSearches)
+            {
+                foreach($aSearches as $iSearch => $aSearch)
+                {
+                    $sHash = serialize($aSearch);
+                    if (isset($aSearchHash[$sHash]))
+                    {
+                        unset($aGroupedSearches[$iGroup][$iSearch]);
+                        if (sizeof($aGroupedSearches[$iGroup]) == 0) unset($aGroupedSearches[$iGroup]);
+                    }
+                    else
+                    {
+                        $aSearchHash[$sHash] = 1;
+                    }
+                }
+            }
+
+            if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens);
+
+            $iGroupLoop = 0;
+            $iQueryLoop = 0;
+            foreach($aGroupedSearches as $iGroupedRank => $aSearches)
+            {
+                $iGroupLoop++;
+                foreach($aSearches as $aSearch)
+                {
+                    $iQueryLoop++;
+                    $searchedHousenumber = -1;
+
+                    if (CONST_Debug) { echo "<hr><b>Search Loop, group $iGroupLoop, loop $iQueryLoop</b>"; }
+                    if (CONST_Debug) _debugDumpGroupedSearches(array($iGroupedRank => array($aSearch)), $aValidTokens);
+
+                    // No location term?
+                    if (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['fLon'])
+                    {
+                        if ($aSearch['sCountryCode'] && !$aSearch['sClass'] && !$aSearch['sHouseNumber'])
+                        {
+                            // Just looking for a country by code - look it up
+                            if (4 >= $this->iMinAddressRank && 4 <= $this->iMaxAddressRank)
+                            {
+                                $sSQL = "select place_id from placex where calculated_country_code='".$aSearch['sCountryCode']."' and rank_search = 4";
+                                if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
+                                if ($bBoundingBoxSearch)
+                                    $sSQL .= " and _st_intersects($this->sViewboxSmallSQL, geometry)";
+                                $sSQL .= " order by st_area(geometry) desc limit 1";
+                                if (CONST_Debug) var_dump($sSQL);
+                                $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                            }
+                            else
+                            {
+                                $aPlaceIDs = array();
+                            }
+                        }
+                        else
+                        {
+                            if (!$bBoundingBoxSearch && !$aSearch['fLon']) continue;
+                            if (!$aSearch['sClass']) continue;
+                            $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'";
+                            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 ($sCountryCodesSQL) $sSQL .= " and calculated_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";
+                                $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 calculated_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 from placex where class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'";
+                                $sSQL .= " and st_contains($this->sViewboxSmallSQL, geometry) and linked_place_id is null";
+                                if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
+                                if ($this->sViewboxCentreSQL)   $sSQL .= " order by st_distance($this->sViewboxCentreSQL, centroid) asc";
+                                $sSQL .= " limit $this->iLimit";
+                                if (CONST_Debug) var_dump($sSQL);
+                                $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                            }
+                        }
+                    }
+                    // If a coordinate is given, the search must either
+                    // be for a name or a special search. Ignore everythin else.
+                    else if ($aSearch['fLon'] && !sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && !$aSearch['sClass'])
+                    {
+                        $aPlaceIDs = array();
+                    }
+                    else
+                    {
+                        $aPlaceIDs = array();
+
+                        // First we need a position, either aName or fLat or both
+                        $aTerms = array();
+                        $aOrder = array();
+
+                        if ($aSearch['sHouseNumber'] && sizeof($aSearch['aAddress']))
+                        {
+                            $sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
+                            $aOrder[] = "";
+                            $aOrder[0] = " (exists(select place_id from placex where parent_place_id = search_name.place_id";
+                            $aOrder[0] .= " and transliteration(housenumber) ~* E'".$sHouseNumberRegex."' limit 1) ";
+                            // also housenumbers from interpolation lines table are needed
+                            $aOrder[0] .= " or exists(select place_id from location_property_osmline where parent_place_id = search_name.place_id";
+                            $aOrder[0] .= " and ".intval($aSearch['sHouseNumber']).">=startnumber and ".intval($aSearch['sHouseNumber'])."<=endnumber limit 1))";
+                            $aOrder[0] .= " desc";
+                        }
+
+                        // 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['aAddress']) && $aSearch['aName'] != $aSearch['aAddress'])
+                        {
+                            // For infrequent name terms disable index usage for address
+                            if (CONST_Search_NameOnlySearchFrequencyThreshold &&
+                                    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']),",")."]";
+                            }
+                            else
+                            {
+                                $aTerms[] = "nameaddress_vector @> ARRAY[".join($aSearch['aAddress'],",")."]";
+                                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'])."'";
+                        if ($aSearch['sHouseNumber'])
+                        {
+                            $aTerms[] = "address_rank between 16 and 27";
+                        }
+                        else
+                        {
+                            if ($this->iMinAddressRank > 0)
+                            {
+                                $aTerms[] = "address_rank >= ".$this->iMinAddressRank;
+                            }
+                            if ($this->iMaxAddressRank < 30)
+                            {
+                                $aTerms[] = "address_rank <= ".$this->iMaxAddressRank;
+                            }
+                        }
+                        if ($aSearch['fLon'] && $aSearch['fLat'])
+                        {
+                            $aTerms[] = "ST_DWithin(centroid, ST_SetSRID(ST_Point(".$aSearch['fLon'].",".$aSearch['fLat']."),4326), ".$aSearch['fRadius'].")";
+                            $aOrder[] = "ST_Distance(centroid, ST_SetSRID(ST_Point(".$aSearch['fLon'].",".$aSearch['fLat']."),4326)) ASC";
+                        }
+                        if (sizeof($this->aExcludePlaceIDs))
+                        {
+                            $aTerms[] = "place_id not in (".join(',',$this->aExcludePlaceIDs).")";
+                        }
+                        if ($sCountryCodesSQL)
+                        {
+                            $aTerms[] = "country_code in ($sCountryCodesSQL)";
+                        }
+
+                        if ($bBoundingBoxSearch) $aTerms[] = "centroid && $this->sViewboxSmallSQL";
+                        if ($sNearPointSQL) $aOrder[] = "ST_Distance($sNearPointSQL, centroid) asc";
+
+                        if ($aSearch['sHouseNumber'])
+                        {
+                            $sImportanceSQL = '- abs(26 - address_rank) + 3';
+                        }
+                        else
+                        {
+                            $sImportanceSQL = '(case when importance = 0 OR importance IS NULL then 0.75-(search_rank::float/40) else importance end)';
+                        }
+                        if ($this->sViewboxSmallSQL) $sImportanceSQL .= " * case when ST_Contains($this->sViewboxSmallSQL, centroid) THEN 1 ELSE 0.5 END";
+                        if ($this->sViewboxLargeSQL) $sImportanceSQL .= " * case when ST_Contains($this->sViewboxLargeSQL, centroid) THEN 1 ELSE 0.5 END";
+
+                        $aOrder[] = "$sImportanceSQL DESC";
+                        if (sizeof($aSearch['aFullNameAddress']))
+                        {
+                            $sExactMatchSQL = '(select count(*) from (select unnest(ARRAY['.join($aSearch['aFullNameAddress'],",").']) INTERSECT select unnest(nameaddress_vector))s) as exactmatch';
+                            $aOrder[] = 'exactmatch DESC';
+                        } else {
+                            $sExactMatchSQL = '0::int as exactmatch';
+                        }
+
+                        if (sizeof($aTerms))
+                        {
+                            $sSQL = "select place_id, ";
+                            $sSQL .= $sExactMatchSQL;
+                            $sSQL .= " from search_name";
+                            $sSQL .= " where ".join(' and ',$aTerms);
+                            $sSQL .= " order by ".join(', ',$aOrder);
+                            if ($aSearch['sHouseNumber'] || $aSearch['sClass'])
+                                $sSQL .= " limit 20";
+                            elseif (!sizeof($aSearch['aName']) && !sizeof($aSearch['aAddress']) && $aSearch['sClass'])
+                                $sSQL .= " limit 1";
+                            else
+                                $sSQL .= " limit ".$this->iLimit;
+
+                            if (CONST_Debug) { var_dump($sSQL); }
+                            $aViewBoxPlaceIDs = chksql($this->oDB->getAll($sSQL),
+                                                       "Could not get places for search terms.");
+                            //var_dump($aViewBoxPlaceIDs);
+                            // Did we have an viewbox matches?
+                            $aPlaceIDs = array();
+                            $bViewBoxMatch = false;
+                            foreach($aViewBoxPlaceIDs as $aViewBoxRow)
+                            {
+                                //if ($bViewBoxMatch == 1 && $aViewBoxRow['in_small'] == 'f') break;
+                                //if ($bViewBoxMatch == 2 && $aViewBoxRow['in_large'] == 'f') break;
+                                //if ($aViewBoxRow['in_small'] == 't') $bViewBoxMatch = 1;
+                                //else if ($aViewBoxRow['in_large'] == 't') $bViewBoxMatch = 2;
+                                $aPlaceIDs[] = $aViewBoxRow['place_id'];
+                                $this->exactMatchCache[$aViewBoxRow['place_id']] = $aViewBoxRow['exactmatch'];
+                            }
+                        }
+                        //var_Dump($aPlaceIDs);
+                        //exit;
+
+                        //now search for housenumber, if housenumber provided
+                        if ($aSearch['sHouseNumber'] && sizeof($aPlaceIDs))
+                        {
+                            $searchedHousenumber = intval($aSearch['sHouseNumber']);
+                            $aRoadPlaceIDs = $aPlaceIDs;
+                            $sPlaceIDs = join(',',$aPlaceIDs);
+
+                            // Now they are indexed, look for a house attached to a street we found
+                            $sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
+                            $sSQL = "select place_id from placex where parent_place_id in (".$sPlaceIDs.") and transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
+                            if (sizeof($this->aExcludePlaceIDs))
+                            {
+                                $sSQL .= " and place_id not in (".join(',',$this->aExcludePlaceIDs).")";
+                            }
+                            $sSQL .= " limit $this->iLimit";
+                            if (CONST_Debug) var_dump($sSQL);
+                            $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                            
+                            // if nothing found, search in the interpolation line table
+                            if(!sizeof($aPlaceIDs))
+                            {
+                                // do we need to use transliteration and the regex for housenumbers???
+                                //new query for lines, not housenumbers anymore
+                                if($searchedHousenumber%2 == 0){
+                                    //if housenumber is even, look for housenumber in streets with interpolationtype even or all
+                                    $sSQL = "select distinct place_id from location_property_osmline where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='even' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
+                                }else{
+                                    //look for housenumber in streets with interpolationtype odd or all
+                                    $sSQL = "select distinct place_id from location_property_osmline where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='odd' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
+                                }
+
+                                if (sizeof($this->aExcludePlaceIDs))
+                                {
+                                    $sSQL .= " and place_id not in (".join(',', $this->aExcludePlaceIDs).")";
+                                }
+                                //$sSQL .= " limit $this->iLimit";
+                                if (CONST_Debug) var_dump($sSQL);
+                                //get place IDs
+                                $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0));
+                            }
+                                
+                            // If nothing found try the aux fallback table
+                            if (CONST_Use_Aux_Location_data && !sizeof($aPlaceIDs))
+                            {
+                                $sSQL = "select place_id from location_property_aux where parent_place_id in (".$sPlaceIDs.") and housenumber = '".pg_escape_string($aSearch['sHouseNumber'])."'";
+                                if (sizeof($this->aExcludePlaceIDs))
+                                {
+                                    $sSQL .= " and parent_place_id not in (".join(',',$this->aExcludePlaceIDs).")";
+                                }
+                                //$sSQL .= " limit $this->iLimit";
+                                if (CONST_Debug) var_dump($sSQL);
+                                $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                            }
+
+                            //if nothing was found in placex or location_property_aux, then search in Tiger data for this housenumber(location_property_tiger)
+                            if (CONST_Use_US_Tiger_Data && !sizeof($aPlaceIDs))
+                            {
+                                //new query for lines, not housenumbers anymore
+                                if($searchedHousenumber%2 == 0){
+                                    //if housenumber is even, look for housenumber in streets with interpolationtype even or all
+                                    $sSQL = "select distinct place_id from location_property_tiger where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='even' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
+                                }else{
+                                    //look for housenumber in streets with interpolationtype odd or all
+                                    $sSQL = "select distinct place_id from location_property_tiger where parent_place_id in (".$sPlaceIDs.") and (interpolationtype='odd' or interpolationtype='all') and ".$searchedHousenumber.">=startnumber and ".$searchedHousenumber."<=endnumber";
+                                }
+
+                                if (sizeof($this->aExcludePlaceIDs))
+                                {
+                                    $sSQL .= " and place_id not in (".join(',', $this->aExcludePlaceIDs).")";
+                                }
+                                //$sSQL .= " limit $this->iLimit";
+                                if (CONST_Debug) var_dump($sSQL);
+                                //get place IDs
+                                $aPlaceIDs = chksql($this->oDB->getCol($sSQL, 0));
+                            }
+
+                            // Fallback to the road (if no housenumber was found)
+                            if (!sizeof($aPlaceIDs) && preg_match('/[0-9]+/', $aSearch['sHouseNumber']))
+                            {
+                                $aPlaceIDs = $aRoadPlaceIDs;
+                                //set to -1, if no housenumbers were found
+                                $searchedHousenumber = -1;
+                            }
+                            //else: housenumber was found, remains saved in searchedHousenumber
+                        }
+
+
+                        if ($aSearch['sClass'] && sizeof($aPlaceIDs))
+                        {
+                            $sPlaceIDs = join(',', $aPlaceIDs);
+                            $aClassPlaceIDs = array();
+
+                            if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'name')
+                            {
+                                // If they were searching for a named class (i.e. 'Kings Head pub') then we might have an extra match
+                                $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'";
+                                $sSQL .= " and linked_place_id is null";
+                                if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)";
+                                $sSQL .= " order by rank_search asc limit $this->iLimit";
+                                if (CONST_Debug) var_dump($sSQL);
+                                $aClassPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                            }
+
+                            if (!$aSearch['sOperator'] || $aSearch['sOperator'] == 'near') // & in
+                            {
+                                $sSQL = "select count(*) from pg_tables where tablename = 'place_classtype_".$aSearch['sClass']."_".$aSearch['sType']."'";
+                                $bCacheTable = chksql($this->oDB->getOne($sSQL));
+
+                                $sSQL = "select min(rank_search) from placex where place_id in ($sPlaceIDs)";
+
+                                if (CONST_Debug) var_dump($sSQL);
+                                $this->iMaxRank = ((int)chksql($this->oDB->getOne($sSQL)));
+
+                                // For state / country level searches the normal radius search doesn't work very well
+                                $sPlaceGeom = false;
+                                if ($this->iMaxRank < 9 && $bCacheTable)
+                                {
+                                    // Try and get a polygon to search in instead
+                                    $sSQL = "select geometry from placex where place_id in ($sPlaceIDs) and rank_search < $this->iMaxRank + 5 and st_geometrytype(geometry) in ('ST_Polygon','ST_MultiPolygon') order by rank_search asc limit 1";
+                                    if (CONST_Debug) var_dump($sSQL);
+                                    $sPlaceGeom = chksql($this->oDB->getOne($sSQL));
+                                }
+
+                                if ($sPlaceGeom)
+                                {
+                                    $sPlaceIDs = false;
+                                }
+                                else
+                                {
+                                    $this->iMaxRank += 5;
+                                    $sSQL = "select place_id from placex where place_id in ($sPlaceIDs) and rank_search < $this->iMaxRank";
+                                    if (CONST_Debug) var_dump($sSQL);
+                                    $aPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                                    $sPlaceIDs = join(',',$aPlaceIDs);
+                                }
+
+                                if ($sPlaceIDs || $sPlaceGeom)
+                                {
+
+                                    $fRange = 0.01;
+                                    if ($bCacheTable)
+                                    {
+                                        // More efficient - can make the range bigger
+                                        $fRange = 0.05;
+
+                                        $sOrderBySQL = '';
+                                        if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.centroid)";
+                                        else if ($sPlaceIDs) $sOrderBySQL = "ST_Distance(l.centroid, f.geometry)";
+                                        else if ($sPlaceGeom) $sOrderBysSQL = "ST_Distance(st_centroid('".$sPlaceGeom."'), l.centroid)";
+
+                                        $sSQL = "select distinct l.place_id".($sOrderBySQL?','.$sOrderBySQL:'')." from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." as l";
+                                        if ($sCountryCodesSQL) $sSQL .= " join placex as lp using (place_id)";
+                                        if ($sPlaceIDs)
+                                        {
+                                            $sSQL .= ",placex as f where ";
+                                            $sSQL .= "f.place_id in ($sPlaceIDs) and ST_DWithin(l.centroid, f.centroid, $fRange) ";
+                                        }
+                                        if ($sPlaceGeom)
+                                        {
+                                            $sSQL .= " where ";
+                                            $sSQL .= "ST_Contains('".$sPlaceGeom."', l.centroid) ";
+                                        }
+                                        if (sizeof($this->aExcludePlaceIDs))
+                                        {
+                                            $sSQL .= " and l.place_id not in (".join(',',$this->aExcludePlaceIDs).")";
+                                        }
+                                        if ($sCountryCodesSQL) $sSQL .= " and lp.calculated_country_code in ($sCountryCodesSQL)";
+                                        if ($sOrderBySQL) $sSQL .= "order by ".$sOrderBySQL." asc";
+                                        if ($this->iOffset) $sSQL .= " offset $this->iOffset";
+                                        $sSQL .= " limit $this->iLimit";
+                                        if (CONST_Debug) var_dump($sSQL);
+                                        $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL)));
+                                    }
+                                    else
+                                    {
+                                        if (isset($aSearch['fRadius']) && $aSearch['fRadius']) $fRange = $aSearch['fRadius'];
+
+                                        $sOrderBySQL = '';
+                                        if ($sNearPointSQL) $sOrderBySQL = "ST_Distance($sNearPointSQL, l.geometry)";
+                                        else $sOrderBySQL = "ST_Distance(l.geometry, f.geometry)";
+
+                                        $sSQL = "select distinct l.place_id".($sOrderBysSQL?','.$sOrderBysSQL:'')." from placex as l,placex as f where ";
+                                        $sSQL .= "f.place_id in ( $sPlaceIDs) and ST_DWithin(l.geometry, f.centroid, $fRange) ";
+                                        $sSQL .= "and l.class='".$aSearch['sClass']."' and l.type='".$aSearch['sType']."' ";
+                                        if (sizeof($this->aExcludePlaceIDs))
+                                        {
+                                            $sSQL .= " and l.place_id not in (".join(',',$this->aExcludePlaceIDs).")";
+                                        }
+                                        if ($sCountryCodesSQL) $sSQL .= " and l.calculated_country_code in ($sCountryCodesSQL)";
+                                        if ($sOrderBy) $sSQL .= "order by ".$OrderBysSQL." asc";
+                                        if ($this->iOffset) $sSQL .= " offset $this->iOffset";
+                                        $sSQL .= " limit $this->iLimit";
+                                        if (CONST_Debug) var_dump($sSQL);
+                                        $aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($this->oDB->getCol($sSQL)));
+                                    }
+                                }
+                            }
+
+                            $aPlaceIDs = $aClassPlaceIDs;
+
+                        }
+
+                    }
+
+                    if (CONST_Debug) { echo "<br><b>Place IDs:</b> "; var_Dump($aPlaceIDs); }
+
+                    foreach($aPlaceIDs as $iPlaceID)
+                    {
+                        // array for placeID => -1 | Tiger housenumber
+                        $aResultPlaceIDs[$iPlaceID] = $searchedHousenumber;
+                    }
+                    if ($iQueryLoop > 20) break;
+                }
+
+                if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs) && ($this->iMinAddressRank != 0 || $this->iMaxAddressRank != 30))
+                {
+                    // Need to verify passes rank limits before dropping out of the loop (yuk!)
+                    // reduces the number of place ids, like a filter
+                    // rank_address is 30 for interpolated housenumbers
+                    $sSQL = "select place_id from placex where place_id in (".join(',',array_keys($aResultPlaceIDs)).") ";
+                    $sSQL .= "and (placex.rank_address between $this->iMinAddressRank and $this->iMaxAddressRank ";
+                    if (14 >= $this->iMinAddressRank && 14 <= $this->iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'";
+                    if ($this->aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$this->aAddressRankList).")";
+                    if (CONST_Use_US_Tiger_Data)
+                    {
+                        $sSQL .= ") UNION select place_id from location_property_tiger where place_id in (".join(',',array_keys($aResultPlaceIDs)).") ";
+                        $sSQL .= "and (30 between $this->iMinAddressRank and $this->iMaxAddressRank ";
+                        if ($this->aAddressRankList) $sSQL .= " OR 30 in (".join(',',$this->aAddressRankList).")";
+                    }
+                    $sSQL .= ") UNION select place_id from location_property_osmline where place_id in (".join(',',array_keys($aResultPlaceIDs)).")";
+                    $sSQL .= " and (30 between $this->iMinAddressRank and $this->iMaxAddressRank)";
+                    if (CONST_Debug) var_dump($sSQL);
+                    $aFilteredPlaceIDs = chksql($this->oDB->getCol($sSQL));
+                    $tempIDs = array();
+                    foreach($aFilteredPlaceIDs as $placeID)
+                    {
+                        $tempIDs[$placeID] = $aResultPlaceIDs[$placeID];  //assign housenumber to placeID
+                    }
+                    $aResultPlaceIDs = $tempIDs;
+                }
+
+                //exit;
+                if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) break;
+                if ($iGroupLoop > 4) break;
+                if ($iQueryLoop > 30) break;
+            }
+
+            // Did we find anything?
+            if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs))
+            {
+                $aSearchResults = $this->getDetails($aResultPlaceIDs);
+            }
+
+        }
+        else
+        {
+            // Just interpret as a reverse geocode
+            $oReverse = new ReverseGeocode($this->oDB);
+            $oReverse->setZoom(18);
+
+            $aLookup = $oReverse->lookup((float)$this->aNearPoint[0],
+                                         (float)$this->aNearPoint[1],
+                                         false);
+
+            if (CONST_Debug) var_dump("Reverse search", $aLookup);
+
+            if ($aLookup['place_id'])
+                $aSearchResults = $this->getDetails(array($aLookup['place_id'] => -1));
+            else
+                $aSearchResults = array();
+        }
+
+        // No results? Done
+        if (!sizeof($aSearchResults))
+        {
+            if ($this->bFallback)
+            {
+                if ($this->fallbackStructuredQuery())
+                {
+                    return $this->lookup();
+                }
+            }
+
+            return array();
+        }
+
+        $aClassType = getClassTypesWithImportance();
+        $aRecheckWords = preg_split('/\b[\s,\\-]*/u',$sQuery);
+        foreach($aRecheckWords as $i => $sWord)
+        {
+            if (!preg_match('/\pL/', $sWord)) unset($aRecheckWords[$i]);
+        }
+
+        if (CONST_Debug) { echo '<i>Recheck words:<\i>'; var_dump($aRecheckWords); }
+
+        $oPlaceLookup = new PlaceLookup($this->oDB);
+        $oPlaceLookup->setIncludePolygonAsPoints($this->bIncludePolygonAsPoints);
+        $oPlaceLookup->setIncludePolygonAsText($this->bIncludePolygonAsText);
+        $oPlaceLookup->setIncludePolygonAsGeoJSON($this->bIncludePolygonAsGeoJSON);
+        $oPlaceLookup->setIncludePolygonAsKML($this->bIncludePolygonAsKML);
+        $oPlaceLookup->setIncludePolygonAsSVG($this->bIncludePolygonAsSVG);
+        $oPlaceLookup->setPolygonSimplificationThreshold($this->fPolygonSimplificationThreshold);
+
+        foreach($aSearchResults as $iResNum => $aResult)
+        {
+            // Default
+            $fDiameter = getResultDiameter($aResult);
+
+            $aOutlineResult = $oPlaceLookup->getOutlines($aResult['place_id'], $aResult['lon'], $aResult['lat'], $fDiameter/2);
+            if ($aOutlineResult)
+            {
+                $aResult = array_merge($aResult, $aOutlineResult);
+            }
+            
+            if ($aResult['extra_place'] == 'city')
+            {
+                $aResult['class'] = 'place';
+                $aResult['type'] = 'city';
+                $aResult['rank_search'] = 16;
+            }
+
+            // Is there an icon set for this type of result?
+            if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
+                    && $aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
+            {
+                $aResult['icon'] = CONST_Website_BaseURL.'images/mapicons/'.$aClassType[$aResult['class'].':'.$aResult['type']]['icon'].'.p.20.png';
+            }
+
+            if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'])
+                    && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'])
+            {
+                $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'];
+            }
+            elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['label'])
+                    && $aClassType[$aResult['class'].':'.$aResult['type']]['label'])
+            {
+                $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type']]['label'];
+            }
+            // if tag '&addressdetails=1' is set in query
+            if ($this->bIncludeAddressDetails)
+            {
+                // getAddressDetails() is defined in lib.php and uses the SQL function get_addressdata in functions.sql
+                $aResult['address'] = getAddressDetails($this->oDB, $sLanguagePrefArraySQL, $aResult['place_id'], $aResult['country_code'], $aResultPlaceIDs[$aResult['place_id']]);
+                if ($aResult['extra_place'] == 'city' && !isset($aResult['address']['city']))
+                {
+                    $aResult['address'] = array_merge(array('city' => array_shift(array_values($aResult['address']))), $aResult['address']);
+                }
+            }
+            if ($this->bIncludeExtraTags)
+            {
+                if ($aResult['extra'])
+                {
+                    $aResult['sExtraTags'] = json_decode($aResult['extra']);
+                }
+                else
+                {
+                    $aResult['sExtraTags'] = (object) array();
+                }
+            }
+
+            if ($this->bIncludeNameDetails)
+            {
+                if ($aResult['names'])
+                {
+                    $aResult['sNameDetails'] = json_decode($aResult['names']);
+                }
+                else
+                {
+                    $aResult['sNameDetails'] = (object) array();
+                }
+            }
+
+            // Adjust importance for the number of exact string matches in the result
+            $aResult['importance'] = max(0.001,$aResult['importance']);
+            $iCountWords = 0;
+            $sAddress = $aResult['langaddress'];
+            foreach($aRecheckWords as $i => $sWord)
+            {
+                if (stripos($sAddress, $sWord)!==false)
+                {
+                    $iCountWords++;
+                    if (preg_match("/(^|,)\s*".preg_quote($sWord, '/')."\s*(,|$)/", $sAddress)) $iCountWords += 0.1;
+                }
+            }
+
+            $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):
+            //   - approximate importance of address parts
+            $aResult['foundorder'] = -$aResult['addressimportance']/10;
+            //   - number of exact matches from the query
+            if (isset($this->exactMatchCache[$aResult['place_id']]))
+                $aResult['foundorder'] -= $this->exactMatchCache[$aResult['place_id']];
+            else if (isset($this->exactMatchCache[$aResult['parent_place_id']]))
+                $aResult['foundorder'] -= $this->exactMatchCache[$aResult['parent_place_id']];
+            //  - importance of the class/type
+            if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
+                && $aClassType[$aResult['class'].':'.$aResult['type']]['importance'])
+            {
+                $aResult['foundorder'] += 0.0001 * $aClassType[$aResult['class'].':'.$aResult['type']]['importance'];
+            }
+            else
+            {
+                $aResult['foundorder'] += 0.01;
+            }
+            if (CONST_Debug) { var_dump($aResult); }
+            $aSearchResults[$iResNum] = $aResult;
+        }
+        uasort($aSearchResults, 'byImportance');
+
+        $aOSMIDDone = array();
+        $aClassTypeNameDone = array();
+        $aToFilter = $aSearchResults;
+        $aSearchResults = array();
+
+        $bFirst = true;
+        foreach($aToFilter as $iResNum => $aResult)
+        {
+            $this->aExcludePlaceIDs[$aResult['place_id']] = $aResult['place_id'];
+            if ($bFirst)
+            {
+                $fLat = $aResult['lat'];
+                $fLon = $aResult['lon'];
+                if (isset($aResult['zoom'])) $iZoom = $aResult['zoom'];
+                $bFirst = false;
+            }
+            if (!$this->bDeDupe || (!isset($aOSMIDDone[$aResult['osm_type'].$aResult['osm_id']])
+                        && !isset($aClassTypeNameDone[$aResult['osm_type'].$aResult['class'].$aResult['type'].$aResult['name'].$aResult['admin_level']])))
+            {
+                $aOSMIDDone[$aResult['osm_type'].$aResult['osm_id']] = true;
+                $aClassTypeNameDone[$aResult['osm_type'].$aResult['class'].$aResult['type'].$aResult['name'].$aResult['admin_level']] = true;
+                $aSearchResults[] = $aResult;
+            }
+
+            // Absolute limit on number of results
+            if (sizeof($aSearchResults) >= $this->iFinalLimit) break;
+        }
+
+        return $aSearchResults;
+
+    } // end lookup()
+
+
+} // end class
 
index 95a3281ba3aaa54e545cacef01b339934f8a3e87..601bae5b28f922e16709eb831c8a330c8faad431 100644 (file)
 
 class ParameterParser
 {
-       private $aParams;
-
-       function __construct($aParams=NULL)
-       {
-               $this->aParams = ($aParams === NULL) ? $_GET : $aParams;
-       }
-
-       function getBool($sName, $bDefault=false)
-       {
-               if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
-               {
-                       return $bDefault;
-               }
-
-               return (bool) $this->aParams[$sName];
-       }
-
-       function getInt($sName, $bDefault=false)
-       {
-               if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
-               {
-                       return $bDefault;
-               }
-
-               if (!preg_match('/^[+-]?[0-9]+$/', $this->aParams[$sName]))
-               {
-                       userError("Integer number expected for parameter '$sName'");
-               }
-
-               return (int) $this->aParams[$sName];
-       }
-
-       function getFloat($sName, $bDefault=false)
-       {
-               if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
-               {
-                       return $bDefault;
-               }
-
-               if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $this->aParams[$sName]))
-               {
-                       userError("Floating-point number expected for parameter '$sName'");
-               }
-
-               return (float) $this->aParams[$sName];
-       }
-
-       function getString($sName, $bDefault=false)
-       {
-               if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
-               {
-                       return $bDefault;
-               }
-
-               return $this->aParams[$sName];
-       }
-
-       function getSet($sName, $aValues, $sDefault=false)
-       {
-               if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
-               {
-                       return $sDefault;
-               }
-
-               if (!in_array($this->aParams[$sName], $aValues))
-               {
-                       userError("Parameter '$sName' must be one of: ".join(', ', $aValues));
-               }
-
-               return $this->aParams[$sName];
-       }
-
-       function getStringList($sName, $aDefault=false)
-       {
-               $sValue = $this->getString($sName);
-
-               if ($sValue)
-               {
-                       return explode(',', $sValue);
-               }
-
-               return $aDefault;
-       }
-
-       function getPreferredLanguages($sFallback=NULL)
-       {
-               if ($sFallback === NULL && isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
-               {
-                       $sFallback = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
-               }
-
-               $aLanguages = array();
-               $sLangString = $this->getString('accept-language', $sFallback);
-
-               if ($sLangString)
-               {
-                       if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER))
-                       {
-                               foreach($aLanguagesParse as $iLang => $aLanguage)
-                               {
-                                       $aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100);
-                                       if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10;
-                               }
-                               arsort($aLanguages);
-                       }
-               }
-               if (!sizeof($aLanguages) && CONST_Default_Language)
-               {
-                       $aLanguages[CONST_Default_Language] = 1;
-               }
-
-               foreach($aLanguages as $sLanguage => $fLanguagePref)
-               {
-                       $aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage;
-                       $aLangPrefOrder['name:'.$sLanguage] = 'name:'.$sLanguage;
-               }
-               $aLangPrefOrder['short_name'] = 'short_name';
-               $aLangPrefOrder['name'] = 'name';
-               $aLangPrefOrder['brand'] = 'brand';
-               foreach($aLanguages as $sLanguage => $fLanguagePref)
-               {
-                       $aLangPrefOrder['official_name:'.$sLanguage] = 'official_name:'.$sLanguage;
-               }
-               $aLangPrefOrder['official_name'] = 'official_name';
-               $aLangPrefOrder['ref'] = 'ref';
-               $aLangPrefOrder['type'] = 'type';
-               return $aLangPrefOrder;
-       }
+    private $aParams;
+
+    function __construct($aParams=NULL)
+    {
+        $this->aParams = ($aParams === NULL) ? $_GET : $aParams;
+    }
+
+    function getBool($sName, $bDefault=false)
+    {
+        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
+        {
+            return $bDefault;
+        }
+
+        return (bool) $this->aParams[$sName];
+    }
+
+    function getInt($sName, $bDefault=false)
+    {
+        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
+        {
+            return $bDefault;
+        }
+
+        if (!preg_match('/^[+-]?[0-9]+$/', $this->aParams[$sName]))
+        {
+            userError("Integer number expected for parameter '$sName'");
+        }
+
+        return (int) $this->aParams[$sName];
+    }
+
+    function getFloat($sName, $bDefault=false)
+    {
+        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
+        {
+            return $bDefault;
+        }
+
+        if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $this->aParams[$sName]))
+        {
+            userError("Floating-point number expected for parameter '$sName'");
+        }
+
+        return (float) $this->aParams[$sName];
+    }
+
+    function getString($sName, $bDefault=false)
+    {
+        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
+        {
+            return $bDefault;
+        }
+
+        return $this->aParams[$sName];
+    }
+
+    function getSet($sName, $aValues, $sDefault=false)
+    {
+        if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0)
+        {
+            return $sDefault;
+        }
+
+        if (!in_array($this->aParams[$sName], $aValues))
+        {
+            userError("Parameter '$sName' must be one of: ".join(', ', $aValues));
+        }
+
+        return $this->aParams[$sName];
+    }
+
+    function getStringList($sName, $aDefault=false)
+    {
+        $sValue = $this->getString($sName);
+
+        if ($sValue)
+        {
+            return explode(',', $sValue);
+        }
+
+        return $aDefault;
+    }
+
+    function getPreferredLanguages($sFallback=NULL)
+    {
+        if ($sFallback === NULL && isset($_SERVER["HTTP_ACCEPT_LANGUAGE"]))
+        {
+            $sFallback = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
+        }
+
+        $aLanguages = array();
+        $sLangString = $this->getString('accept-language', $sFallback);
+
+        if ($sLangString)
+        {
+            if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER))
+            {
+                foreach($aLanguagesParse as $iLang => $aLanguage)
+                {
+                    $aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100);
+                    if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10;
+                }
+                arsort($aLanguages);
+            }
+        }
+        if (!sizeof($aLanguages) && CONST_Default_Language)
+        {
+            $aLanguages[CONST_Default_Language] = 1;
+        }
+
+        foreach($aLanguages as $sLanguage => $fLanguagePref)
+        {
+            $aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage;
+            $aLangPrefOrder['name:'.$sLanguage] = 'name:'.$sLanguage;
+        }
+        $aLangPrefOrder['short_name'] = 'short_name';
+        $aLangPrefOrder['name'] = 'name';
+        $aLangPrefOrder['brand'] = 'brand';
+        foreach($aLanguages as $sLanguage => $fLanguagePref)
+        {
+            $aLangPrefOrder['official_name:'.$sLanguage] = 'official_name:'.$sLanguage;
+        }
+        $aLangPrefOrder['official_name'] = 'official_name';
+        $aLangPrefOrder['ref'] = 'ref';
+        $aLangPrefOrder['type'] = 'type';
+        return $aLangPrefOrder;
+    }
 }
index 7ba192d72fc044168a1b5ec2d738c9d928674dde..fb38d4955874f3bc4bd8f5ed2abcd66759d76d92 100644 (file)
 <?php
-       class PlaceLookup
-       {
-               protected $oDB;
-
-               protected $aLangPrefOrder = array();
-
-               protected $bAddressDetails = false;
-               protected $bExtraTags = false;
-               protected $bNameDetails = false;
-
-               protected $bIncludePolygonAsPoints = false;
-               protected $bIncludePolygonAsText = false;
-               protected $bIncludePolygonAsGeoJSON = false;
-               protected $bIncludePolygonAsKML = false;
-               protected $bIncludePolygonAsSVG = false;
-               protected $fPolygonSimplificationThreshold = 0.0;
-
-
-               function PlaceLookup(&$oDB)
-               {
-                       $this->oDB =& $oDB;
-               }
-
-               function setLanguagePreference($aLangPrefOrder)
-               {
-                       $this->aLangPrefOrder = $aLangPrefOrder;
-               }
-
-               function setIncludeAddressDetails($bAddressDetails = true)
-               {
-                       $this->bAddressDetails = $bAddressDetails;
-               }
-
-               function setIncludeExtraTags($bExtraTags = false)
-               {
-                       $this->bExtraTags = $bExtraTags;
-               }
-
-               function setIncludeNameDetails($bNameDetails = false)
-               {
-                       $this->bNameDetails = $bNameDetails;
-               }
-
-
-               function setIncludePolygonAsPoints($b = true)
-               {
-                       $this->bIncludePolygonAsPoints = $b;
-               }
-
-               function getIncludePolygonAsPoints()
-               {
-                       return $this->bIncludePolygonAsPoints;
-               }
-
-               function setIncludePolygonAsText($b = true)
-               {
-                       $this->bIncludePolygonAsText = $b;
-               }
-
-               function getIncludePolygonAsText()
-               {
-                       return $this->bIncludePolygonAsText;
-               }
-
-               function setIncludePolygonAsGeoJSON($b = true)
-               {
-                       $this->bIncludePolygonAsGeoJSON = $b;
-               }
-
-               function setIncludePolygonAsKML($b = true)
-               {
-                       $this->bIncludePolygonAsKML = $b;
-               }
-
-               function setIncludePolygonAsSVG($b = true)
-               {
-                       $this->bIncludePolygonAsSVG = $b;
-               }
-
-               function setPolygonSimplificationThreshold($f)
-               {
-                       $this->fPolygonSimplificationThreshold = $f;
-               }
-
-               function lookupOSMID($sType, $iID)
-               {
-                       $sSQL = "select place_id from placex where osm_type = '".pg_escape_string($sType)."' and osm_id = ".(int)$iID." order by type = 'postcode' asc";
-                       $iPlaceID = chksql($this->oDB->getOne($sSQL));
-
-                       return $this->lookup((int)$iPlaceID);
-               }
-
-               function lookup($iPlaceID, $sType = '', $fInterpolFraction = 0.0)
-               {
-                       if (!$iPlaceID) return null;
-
-                       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted", $this->aLangPrefOrder))."]";
-                       $bIsTiger = CONST_Use_US_Tiger_Data && $sType == 'tiger';
-                       $bIsInterpolation = $sType == 'interpolation';
-
-                       if ($bIsTiger)
-                       {
-                               $sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, null as street, null as isin, postcode,";
-                               $sSQL .= " 'us' as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
-                               $sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, ";
-                               $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,";
-                               $sSQL .= " null as placename,";
-                               $sSQL .= " null as ref,";
-                               if ($this->bExtraTags) $sSQL .= " null as extra,";
-                               if ($this->bNameDetails) $sSQL .= " null as names,";
-                               $sSQL .= " ST_X(point) as lon, ST_Y(point) as lat from (select *, ST_LineInterpolatePoint(linegeo, (housenumber-startnumber::float)/(endnumber-startnumber)::float) as point from ";
-                               $sSQL .= " (select *, ";
-                               $sSQL .= " CASE WHEN interpolationtype='odd' THEN floor((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2+1";
-                               $sSQL .= " WHEN interpolationtype='even' THEN ((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2";
-                               $sSQL .= " WHEN interpolationtype='all' THEN (".$fInterpolFraction."*(endnumber-startnumber)+startnumber)::int";
-                               $sSQL .= " END as housenumber";
-                               $sSQL .= " from location_property_tiger where place_id = ".$iPlaceID.") as blub1) as blub2";
-                       }
-                       else if ($bIsInterpolation)
-                       {
-                               $sSQL = "select place_id, partition, 'W' as osm_type, osm_id, 'place' as class, 'house' as type, null admin_level, housenumber, null as street, null as isin, postcode,";
-                               $sSQL .= " calculated_country_code as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
-                               $sSQL .= " (0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, calculated_country_code, ";
-                               $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,";
-                               $sSQL .= " null as placename,";
-                               $sSQL .= " null as ref,";
-                               if ($this->bExtraTags) $sSQL .= " null as extra,";
-                               if ($this->bNameDetails) $sSQL .= " null as names,";
-                               $sSQL .= " ST_X(point) as lon, ST_Y(point) as lat from (select *, ST_LineInterpolatePoint(linegeo, (housenumber-startnumber::float)/(endnumber-startnumber)::float) as point from ";
-                               $sSQL .= " (select *, ";
-                               $sSQL .= " CASE WHEN interpolationtype='odd' THEN floor((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2+1";
-                               $sSQL .= " WHEN interpolationtype='even' THEN ((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2";
-                               $sSQL .= " WHEN interpolationtype='all' THEN (".$fInterpolFraction."*(endnumber-startnumber)+startnumber)::int";
-                               $sSQL .= " END as housenumber";
-                               $sSQL .= " from location_property_osmline where place_id = ".$iPlaceID.") as blub1) as blub2";
-                               // testcase: interpolationtype=odd, startnumber=1000, endnumber=1006, fInterpolFraction=1 => housenumber=1007 => error in st_lineinterpolatepoint
-                               // but this will never happen, because if the searched point is that close to the endnumber, the endnumber house will be directly taken from placex (in ReverseGeocode.php line 220)
-                               // and not interpolated
-                       }
-                       else
-                       {
-                               $sSQL = "select placex.place_id, partition, osm_type, osm_id, class, type, admin_level, housenumber, street, isin, postcode, country_code, parent_place_id, linked_place_id, rank_address, rank_search, ";
-                               $sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, calculated_country_code, ";
-                               $sSQL .= " get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress,";
-                               $sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
-                               $sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,";
-                               if ($this->bExtraTags) $sSQL .= " hstore_to_json(extratags) as extra,";
-                               if ($this->bNameDetails) $sSQL .= " hstore_to_json(name) as names,";
-                               $sSQL .= " (case when centroid is null then st_y(st_centroid(geometry)) else st_y(centroid) end) as lat,";
-                               $sSQL .= " (case when centroid is null then st_x(st_centroid(geometry)) else st_x(centroid) end) as lon";
-                               $sSQL .= " from placex where place_id = ".$iPlaceID;
-                       }
-
-                       $aPlace = chksql($this->oDB->getRow($sSQL), "Could not lookup place");
-
-                       if (!$aPlace['place_id']) return null;
-
-                       if ($this->bAddressDetails)
-                       {
-                               // to get addressdetails for tiger data, the housenumber is needed
-                               $iHousenumber = ($bIsTiger || $bIsInterpolation) ? $aPlace['housenumber'] : -1;
-                               $aPlace['aAddress'] = $this->getAddressNames($aPlace['place_id'],
-                                                                            $iHousenumber);
-                       }
-
-                       if ($this->bExtraTags)
-                       {
-                               if ($aPlace['extra'])
-                               {
-                                       $aPlace['sExtraTags'] = json_decode($aPlace['extra']);
-                               }
-                               else
-                               {
-                                       $aPlace['sExtraTags'] = (object) array();
-                               }
-                       }
-
-                       if ($this->bNameDetails)
-                       {
-                               if ($aPlace['names'])
-                               {
-                                       $aPlace['sNameDetails'] = json_decode($aPlace['names']);
-                               }
-                               else
-                               {
-                                       $aPlace['sNameDetails'] = (object) array();
-                               }
-                       }
-
-                       $aClassType = getClassTypes();
-                       $sAddressType = '';
-                       $sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
-                       if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel']))
-                       {
-                               $sAddressType = $aClassType[$aClassType]['simplelabel'];
-                       }
-                       else
-                       {
-                               $sClassType = $aPlace['class'].':'.$aPlace['type'];
-                               if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel']))
-                                       $sAddressType = $aClassType[$sClassType]['simplelabel'];
-                               else $sAddressType = $aPlace['class'];
-                       }
-
-                       $aPlace['addresstype'] = $sAddressType;
-
-                       return $aPlace;
-               }
-
-               function getAddressDetails($iPlaceID, $bAll = false, $housenumber = -1)
-               {
-                       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted", $this->aLangPrefOrder))."]";
-
-                       $sSQL = "select *,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata(".$iPlaceID.",".$housenumber.")";
-                       if (!$bAll) $sSQL .= " WHERE isaddress OR type = 'country_code'";
-                       $sSQL .= " order by rank_address desc,isaddress desc";
-
-                       return chksql($this->oDB->getAll($sSQL));
-               }
-
-               function getAddressNames($iPlaceID, $housenumber = -1)
-               {
-                       $aAddressLines = $this->getAddressDetails($iPlaceID, false, $housenumber);
-
-                       $aAddress = array();
-                       $aFallback = array();
-                       $aClassType = getClassTypes();
-                       foreach($aAddressLines as $aLine)
-                       {
-                               $bFallback = false;
-                               $aTypeLabel = false;
-                               if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
-                               elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
-                               elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))]))
-                               {
-                                       $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
-                                       $bFallback = true;
-                               }
-                               else
-                               {
-                                       $aTypeLabel = array('simplelabel'=>'address'.$aLine['rank_address']);
-                                       $bFallback = true;
-                               }
-                               if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber'])))
-                               {
-                                       $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
-                                       $sTypeLabel = str_replace(' ','_',$sTypeLabel);
-                                       if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place')
-                                       {
-                                               $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
-                                       }
-                                       $aFallback[$sTypeLabel] = $bFallback;
-                               }
-                       }
-                       return $aAddress;
-               }
-
-
-
-               // returns an array which will contain the keys
-               //   aBoundingBox
-               // and may also contain one or more of the keys
-               //   asgeojson
-               //   askml
-               //   assvg
-               //   astext
-               //   lat
-               //   lon
-               function getOutlines($iPlaceID, $fLon=null, $fLat=null, $fRadius=null)
-               {
-
-                       $aOutlineResult = array();
-                       if (!$iPlaceID) return $aOutlineResult;
-
-                       if (CONST_Search_AreaPolygons)
-                       {
-                               // Get the bounding box and outline polygon
-                               $sSQL  = "select place_id,0 as numfeatures,st_area(geometry) as area,";
-                               $sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
-                               $sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
-                               $sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
-                               if ($this->bIncludePolygonAsGeoJSON) $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson";
-                               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";
-                               $sFrom = " from placex where place_id = ".$iPlaceID;
-                               if ($this->fPolygonSimplificationThreshold > 0)
-                               {
-                                       $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
-                               }
-                               else
-                               {
-                                       $sSQL .= $sFrom;
-                               }
-
-                               $aPointPolygon = chksql($this->oDB->getRow($sSQL),
-                                                       "Could not get outline");
-
-                               if ($aPointPolygon['place_id'])
-                               {
-                                       if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null )
-                                       {
-                                               $aOutlineResult['lat'] = $aPointPolygon['centrelat'];
-                                               $aOutlineResult['lon'] = $aPointPolygon['centrelon'];
-                                       }
-
-                                       if ($this->bIncludePolygonAsGeoJSON) $aOutlineResult['asgeojson'] = $aPointPolygon['asgeojson'];
-                                       if ($this->bIncludePolygonAsKML) $aOutlineResult['askml'] = $aPointPolygon['askml'];
-                                       if ($this->bIncludePolygonAsSVG) $aOutlineResult['assvg'] = $aPointPolygon['assvg'];
-                                       if ($this->bIncludePolygonAsText) $aOutlineResult['astext'] = $aPointPolygon['astext'];
-                                       if ($this->bIncludePolygonAsPoints) $aOutlineResult['aPolyPoints'] = geometryText2Points($aPointPolygon['astext'], $fRadius);
-
-
-                                       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;
-                                       }
-
-                                       $aOutlineResult['aBoundingBox'] = array(
-                                                                         (string)$aPointPolygon['minlat'],
-                                                                         (string)$aPointPolygon['maxlat'],
-                                                                         (string)$aPointPolygon['minlon'],
-                                                                         (string)$aPointPolygon['maxlon']
-                                                                        );
-                               }
-                       } // CONST_Search_AreaPolygons
-
-                       // as a fallback we generate a bounding box without knowing the size of the geometry
-                       if ( (!isset($aOutlineResult['aBoundingBox'])) && isset($fLon) )
-                       {
-
-                               if ($this->bIncludePolygonAsPoints)
-                               {
-                                       $sGeometryText = 'POINT('.$fLon.','.$fLat.')';
-                                       $aOutlineResult['aPolyPoints'] = geometryText2Points($sGeometryText, $fRadius);
-                               }
-
-                               $aBounds = array();
-                               $aBounds['minlat'] = $fLat - $fRadius;
-                               $aBounds['maxlat'] = $fLat + $fRadius;
-                               $aBounds['minlon'] = $fLon - $fRadius;
-                               $aBounds['maxlon'] = $fLon + $fRadius;
-
-                               $aOutlineResult['aBoundingBox'] = array(
-                                                                 (string)$aBounds['minlat'],
-                                                                 (string)$aBounds['maxlat'],
-                                                                 (string)$aBounds['minlon'],
-                                                                 (string)$aBounds['maxlon']
-                                                                );
-                       }
-                       return $aOutlineResult;
-               }
-       }
-?>
+
+class PlaceLookup
+{
+    protected $oDB;
+
+    protected $aLangPrefOrder = array();
+
+    protected $bAddressDetails = false;
+    protected $bExtraTags = false;
+    protected $bNameDetails = false;
+
+    protected $bIncludePolygonAsPoints = false;
+    protected $bIncludePolygonAsText = false;
+    protected $bIncludePolygonAsGeoJSON = false;
+    protected $bIncludePolygonAsKML = false;
+    protected $bIncludePolygonAsSVG = false;
+    protected $fPolygonSimplificationThreshold = 0.0;
+
+
+    function PlaceLookup(&$oDB)
+    {
+        $this->oDB =& $oDB;
+    }
+
+    function setLanguagePreference($aLangPrefOrder)
+    {
+        $this->aLangPrefOrder = $aLangPrefOrder;
+    }
+
+    function setIncludeAddressDetails($bAddressDetails = true)
+    {
+        $this->bAddressDetails = $bAddressDetails;
+    }
+
+    function setIncludeExtraTags($bExtraTags = false)
+    {
+        $this->bExtraTags = $bExtraTags;
+    }
+
+    function setIncludeNameDetails($bNameDetails = false)
+    {
+        $this->bNameDetails = $bNameDetails;
+    }
+
+
+    function setIncludePolygonAsPoints($b = true)
+    {
+        $this->bIncludePolygonAsPoints = $b;
+    }
+
+    function getIncludePolygonAsPoints()
+    {
+        return $this->bIncludePolygonAsPoints;
+    }
+
+    function setIncludePolygonAsText($b = true)
+    {
+        $this->bIncludePolygonAsText = $b;
+    }
+
+    function getIncludePolygonAsText()
+    {
+        return $this->bIncludePolygonAsText;
+    }
+
+    function setIncludePolygonAsGeoJSON($b = true)
+    {
+        $this->bIncludePolygonAsGeoJSON = $b;
+    }
+
+    function setIncludePolygonAsKML($b = true)
+    {
+        $this->bIncludePolygonAsKML = $b;
+    }
+
+    function setIncludePolygonAsSVG($b = true)
+    {
+        $this->bIncludePolygonAsSVG = $b;
+    }
+
+    function setPolygonSimplificationThreshold($f)
+    {
+        $this->fPolygonSimplificationThreshold = $f;
+    }
+
+    function lookupOSMID($sType, $iID)
+    {
+        $sSQL = "select place_id from placex where osm_type = '".pg_escape_string($sType)."' and osm_id = ".(int)$iID." order by type = 'postcode' asc";
+        $iPlaceID = chksql($this->oDB->getOne($sSQL));
+
+        return $this->lookup((int)$iPlaceID);
+    }
+
+    function lookup($iPlaceID, $sType = '', $fInterpolFraction = 0.0)
+    {
+        if (!$iPlaceID) return null;
+
+        $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted", $this->aLangPrefOrder))."]";
+        $bIsTiger = CONST_Use_US_Tiger_Data && $sType == 'tiger';
+        $bIsInterpolation = $sType == 'interpolation';
+
+        if ($bIsTiger)
+        {
+            $sSQL = "select place_id,partition, 'T' as osm_type, place_id as osm_id, 'place' as class, 'house' as type, null as admin_level, housenumber, null as street, null as isin, postcode,";
+            $sSQL .= " 'us' as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
+            $sSQL .= " coalesce(null,0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, 'us' as calculated_country_code, ";
+            $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,";
+            $sSQL .= " null as placename,";
+            $sSQL .= " null as ref,";
+            if ($this->bExtraTags) $sSQL .= " null as extra,";
+            if ($this->bNameDetails) $sSQL .= " null as names,";
+            $sSQL .= " ST_X(point) as lon, ST_Y(point) as lat from (select *, ST_LineInterpolatePoint(linegeo, (housenumber-startnumber::float)/(endnumber-startnumber)::float) as point from ";
+            $sSQL .= " (select *, ";
+            $sSQL .= " CASE WHEN interpolationtype='odd' THEN floor((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2+1";
+            $sSQL .= " WHEN interpolationtype='even' THEN ((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2";
+            $sSQL .= " WHEN interpolationtype='all' THEN (".$fInterpolFraction."*(endnumber-startnumber)+startnumber)::int";
+            $sSQL .= " END as housenumber";
+            $sSQL .= " from location_property_tiger where place_id = ".$iPlaceID.") as blub1) as blub2";
+        }
+        else if ($bIsInterpolation)
+        {
+            $sSQL = "select place_id, partition, 'W' as osm_type, osm_id, 'place' as class, 'house' as type, null admin_level, housenumber, null as street, null as isin, postcode,";
+            $sSQL .= " calculated_country_code as country_code, parent_place_id, null as linked_place_id, 30 as rank_address, 30 as rank_search,";
+            $sSQL .= " (0.75-(30::float/40)) as importance, null as indexed_status, null as indexed_date, null as wikipedia, calculated_country_code, ";
+            $sSQL .= " get_address_by_language(place_id, housenumber, $sLanguagePrefArraySQL) as langaddress,";
+            $sSQL .= " null as placename,";
+            $sSQL .= " null as ref,";
+            if ($this->bExtraTags) $sSQL .= " null as extra,";
+            if ($this->bNameDetails) $sSQL .= " null as names,";
+            $sSQL .= " ST_X(point) as lon, ST_Y(point) as lat from (select *, ST_LineInterpolatePoint(linegeo, (housenumber-startnumber::float)/(endnumber-startnumber)::float) as point from ";
+            $sSQL .= " (select *, ";
+            $sSQL .= " CASE WHEN interpolationtype='odd' THEN floor((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2+1";
+            $sSQL .= " WHEN interpolationtype='even' THEN ((".$fInterpolFraction."*(endnumber-startnumber)+startnumber)/2)::int*2";
+            $sSQL .= " WHEN interpolationtype='all' THEN (".$fInterpolFraction."*(endnumber-startnumber)+startnumber)::int";
+            $sSQL .= " END as housenumber";
+            $sSQL .= " from location_property_osmline where place_id = ".$iPlaceID.") as blub1) as blub2";
+            // testcase: interpolationtype=odd, startnumber=1000, endnumber=1006, fInterpolFraction=1 => housenumber=1007 => error in st_lineinterpolatepoint
+            // but this will never happen, because if the searched point is that close to the endnumber, the endnumber house will be directly taken from placex (in ReverseGeocode.php line 220)
+            // and not interpolated
+        }
+        else
+        {
+            $sSQL = "select placex.place_id, partition, osm_type, osm_id, class, type, admin_level, housenumber, street, isin, postcode, country_code, parent_place_id, linked_place_id, rank_address, rank_search, ";
+            $sSQL .= " coalesce(importance,0.75-(rank_search::float/40)) as importance, indexed_status, indexed_date, wikipedia, calculated_country_code, ";
+            $sSQL .= " get_address_by_language(place_id, -1, $sLanguagePrefArraySQL) as langaddress,";
+            $sSQL .= " get_name_by_language(name, $sLanguagePrefArraySQL) as placename,";
+            $sSQL .= " get_name_by_language(name, ARRAY['ref']) as ref,";
+            if ($this->bExtraTags) $sSQL .= " hstore_to_json(extratags) as extra,";
+            if ($this->bNameDetails) $sSQL .= " hstore_to_json(name) as names,";
+            $sSQL .= " (case when centroid is null then st_y(st_centroid(geometry)) else st_y(centroid) end) as lat,";
+            $sSQL .= " (case when centroid is null then st_x(st_centroid(geometry)) else st_x(centroid) end) as lon";
+            $sSQL .= " from placex where place_id = ".$iPlaceID;
+        }
+
+        $aPlace = chksql($this->oDB->getRow($sSQL), "Could not lookup place");
+
+        if (!$aPlace['place_id']) return null;
+
+        if ($this->bAddressDetails)
+        {
+            // to get addressdetails for tiger data, the housenumber is needed
+            $iHousenumber = ($bIsTiger || $bIsInterpolation) ? $aPlace['housenumber'] : -1;
+            $aPlace['aAddress'] = $this->getAddressNames($aPlace['place_id'],
+                                                         $iHousenumber);
+        }
+
+        if ($this->bExtraTags)
+        {
+            if ($aPlace['extra'])
+            {
+                $aPlace['sExtraTags'] = json_decode($aPlace['extra']);
+            }
+            else
+            {
+                $aPlace['sExtraTags'] = (object) array();
+            }
+        }
+
+        if ($this->bNameDetails)
+        {
+            if ($aPlace['names'])
+            {
+                $aPlace['sNameDetails'] = json_decode($aPlace['names']);
+            }
+            else
+            {
+                $aPlace['sNameDetails'] = (object) array();
+            }
+        }
+
+        $aClassType = getClassTypes();
+        $sAddressType = '';
+        $sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
+        if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel']))
+        {
+            $sAddressType = $aClassType[$aClassType]['simplelabel'];
+        }
+        else
+        {
+            $sClassType = $aPlace['class'].':'.$aPlace['type'];
+            if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel']))
+                $sAddressType = $aClassType[$sClassType]['simplelabel'];
+            else $sAddressType = $aPlace['class'];
+        }
+
+        $aPlace['addresstype'] = $sAddressType;
+
+        return $aPlace;
+    }
+
+    function getAddressDetails($iPlaceID, $bAll = false, $housenumber = -1)
+    {
+        $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted", $this->aLangPrefOrder))."]";
+
+        $sSQL = "select *,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata(".$iPlaceID.",".$housenumber.")";
+        if (!$bAll) $sSQL .= " WHERE isaddress OR type = 'country_code'";
+        $sSQL .= " order by rank_address desc,isaddress desc";
+
+        return chksql($this->oDB->getAll($sSQL));
+    }
+
+    function getAddressNames($iPlaceID, $housenumber = -1)
+    {
+        $aAddressLines = $this->getAddressDetails($iPlaceID, false, $housenumber);
+
+        $aAddress = array();
+        $aFallback = array();
+        $aClassType = getClassTypes();
+        foreach($aAddressLines as $aLine)
+        {
+            $bFallback = false;
+            $aTypeLabel = false;
+            if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
+            elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
+            elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))]))
+            {
+                $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
+                $bFallback = true;
+            }
+            else
+            {
+                $aTypeLabel = array('simplelabel'=>'address'.$aLine['rank_address']);
+                $bFallback = true;
+            }
+            if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber'])))
+            {
+                $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
+                $sTypeLabel = str_replace(' ','_',$sTypeLabel);
+                if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place')
+                {
+                    $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
+                }
+                $aFallback[$sTypeLabel] = $bFallback;
+            }
+        }
+        return $aAddress;
+    }
+
+
+
+    // returns an array which will contain the keys
+    //   aBoundingBox
+    // and may also contain one or more of the keys
+    //   asgeojson
+    //   askml
+    //   assvg
+    //   astext
+    //   lat
+    //   lon
+    function getOutlines($iPlaceID, $fLon=null, $fLat=null, $fRadius=null)
+    {
+
+        $aOutlineResult = array();
+        if (!$iPlaceID) return $aOutlineResult;
+
+        if (CONST_Search_AreaPolygons)
+        {
+            // Get the bounding box and outline polygon
+            $sSQL  = "select place_id,0 as numfeatures,st_area(geometry) as area,";
+            $sSQL .= "ST_Y(centroid) as centrelat,ST_X(centroid) as centrelon,";
+            $sSQL .= "ST_YMin(geometry) as minlat,ST_YMax(geometry) as maxlat,";
+            $sSQL .= "ST_XMin(geometry) as minlon,ST_XMax(geometry) as maxlon";
+            if ($this->bIncludePolygonAsGeoJSON) $sSQL .= ",ST_AsGeoJSON(geometry) as asgeojson";
+            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";
+            $sFrom = " from placex where place_id = ".$iPlaceID;
+            if ($this->fPolygonSimplificationThreshold > 0)
+            {
+                $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
+            }
+            else
+            {
+                $sSQL .= $sFrom;
+            }
+
+            $aPointPolygon = chksql($this->oDB->getRow($sSQL),
+                                    "Could not get outline");
+
+            if ($aPointPolygon['place_id'])
+            {
+                if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null )
+                {
+                    $aOutlineResult['lat'] = $aPointPolygon['centrelat'];
+                    $aOutlineResult['lon'] = $aPointPolygon['centrelon'];
+                }
+
+                if ($this->bIncludePolygonAsGeoJSON) $aOutlineResult['asgeojson'] = $aPointPolygon['asgeojson'];
+                if ($this->bIncludePolygonAsKML) $aOutlineResult['askml'] = $aPointPolygon['askml'];
+                if ($this->bIncludePolygonAsSVG) $aOutlineResult['assvg'] = $aPointPolygon['assvg'];
+                if ($this->bIncludePolygonAsText) $aOutlineResult['astext'] = $aPointPolygon['astext'];
+                if ($this->bIncludePolygonAsPoints) $aOutlineResult['aPolyPoints'] = geometryText2Points($aPointPolygon['astext'], $fRadius);
+
+
+                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;
+                }
+
+                $aOutlineResult['aBoundingBox'] = array(
+                                                  (string)$aPointPolygon['minlat'],
+                                                  (string)$aPointPolygon['maxlat'],
+                                                  (string)$aPointPolygon['minlon'],
+                                                  (string)$aPointPolygon['maxlon']
+                                                 );
+            }
+        } // CONST_Search_AreaPolygons
+
+        // as a fallback we generate a bounding box without knowing the size of the geometry
+        if ( (!isset($aOutlineResult['aBoundingBox'])) && isset($fLon) )
+        {
+
+            if ($this->bIncludePolygonAsPoints)
+            {
+                $sGeometryText = 'POINT('.$fLon.','.$fLat.')';
+                $aOutlineResult['aPolyPoints'] = geometryText2Points($sGeometryText, $fRadius);
+            }
+
+            $aBounds = array();
+            $aBounds['minlat'] = $fLat - $fRadius;
+            $aBounds['maxlat'] = $fLat + $fRadius;
+            $aBounds['minlon'] = $fLon - $fRadius;
+            $aBounds['maxlon'] = $fLon + $fRadius;
+
+            $aOutlineResult['aBoundingBox'] = array(
+                                              (string)$aBounds['minlat'],
+                                              (string)$aBounds['maxlat'],
+                                              (string)$aBounds['minlon'],
+                                              (string)$aBounds['maxlon']
+                                             );
+        }
+        return $aOutlineResult;
+    }
+}
index b523d0aaa9b54a726389691596d28eea5c2a9d31..3d1a51ceb751d18e682333a4c99dd9467e73c202 100644 (file)
 <?php
-       class ReverseGeocode
-       {
-               protected $oDB;
-               protected $iMaxRank = 28;
 
-               function ReverseGeocode(&$oDB)
-               {
-                       $this->oDB =& $oDB;
-               }
+class ReverseGeocode
+{
+    protected $oDB;
+    protected $iMaxRank = 28;
 
-               function setZoom($iZoom)
-               {
-                       // Zoom to rank, this could probably be calculated but a lookup gives fine control
-                       $aZoomRank = array(
-                               0 => 2, // Continent / Sea
-                               1 => 2,
-                               2 => 2,
-                               3 => 4, // Country
-                               4 => 4,
-                               5 => 8, // State
-                               6 => 10, // Region
-                               7 => 10,
-                               8 => 12, // County
-                               9 => 12,
-                               10 => 17, // City
-                               11 => 17,
-                               12 => 18, // Town / Village
-                               13 => 18,
-                               14 => 22, // Suburb
-                               15 => 22,
-                               16 => 26, // Street, TODO: major street?
-                               17 => 26,
-                               18 => 30, // or >, Building
-                               19 => 30, // or >, Building
-                               );
-                       $this->iMaxRank = (isset($iZoom) && isset($aZoomRank[$iZoom]))?$aZoomRank[$iZoom]:28;
-               }
+    function ReverseGeocode(&$oDB)
+    {
+        $this->oDB =& $oDB;
+    }
 
-               // returns { place_id =>, type => '(osm|tiger)' }
-               // fails if no place was found
-               function lookup($fLat, $fLon, $bDoInterpolation = true)
-               {
-                       $sPointSQL = 'ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326)';
-                       $iMaxRank = $this->iMaxRank;
+    function setZoom($iZoom)
+    {
+        // Zoom to rank, this could probably be calculated but a lookup gives fine control
+        $aZoomRank = array(
+            0 => 2, // Continent / Sea
+            1 => 2,
+            2 => 2,
+            3 => 4, // Country
+            4 => 4,
+            5 => 8, // State
+            6 => 10, // Region
+            7 => 10,
+            8 => 12, // County
+            9 => 12,
+            10 => 17, // City
+            11 => 17,
+            12 => 18, // Town / Village
+            13 => 18,
+            14 => 22, // Suburb
+            15 => 22,
+            16 => 26, // Street, TODO: major street?
+            17 => 26,
+            18 => 30, // or >, Building
+            19 => 30, // or >, Building
+            );
+        $this->iMaxRank = (isset($iZoom) && isset($aZoomRank[$iZoom]))?$aZoomRank[$iZoom]:28;
+    }
 
-                       // Find the nearest point
-                       $fSearchDiam = 0.0004;
-                       $iPlaceID = null;
-                       $aArea = false;
-                       $fMaxAreaDistance = 1;
-                       $bIsInUnitedStates = false;
-                       $bPlaceIsTiger = false;
-                       $bPlaceIsLine = false;
-                       while(!$iPlaceID && $fSearchDiam < $fMaxAreaDistance)
-                       {
-                               $fSearchDiam = $fSearchDiam * 2;
+    // returns { place_id =>, type => '(osm|tiger)' }
+    // fails if no place was found
+    function lookup($fLat, $fLon, $bDoInterpolation = true)
+    {
+        $sPointSQL = 'ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326)';
+        $iMaxRank = $this->iMaxRank;
 
-                               // If we have to expand the search area by a large amount then we need a larger feature
-                               // then there is a limit to how small the feature should be
-                               if ($fSearchDiam > 2 && $iMaxRank > 4) $iMaxRank = 4;
-                               if ($fSearchDiam > 1 && $iMaxRank > 9) $iMaxRank = 8;
-                               if ($fSearchDiam > 0.8 && $iMaxRank > 10) $iMaxRank = 10;
-                               if ($fSearchDiam > 0.6 && $iMaxRank > 12) $iMaxRank = 12;
-                               if ($fSearchDiam > 0.2 && $iMaxRank > 17) $iMaxRank = 17;
-                               if ($fSearchDiam > 0.1 && $iMaxRank > 18) $iMaxRank = 18;
-                               if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
-                               if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
+        // Find the nearest point
+        $fSearchDiam = 0.0004;
+        $iPlaceID = null;
+        $aArea = false;
+        $fMaxAreaDistance = 1;
+        $bIsInUnitedStates = false;
+        $bPlaceIsTiger = false;
+        $bPlaceIsLine = false;
+        while(!$iPlaceID && $fSearchDiam < $fMaxAreaDistance)
+        {
+            $fSearchDiam = $fSearchDiam * 2;
 
-                               $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code';
-                               $sSQL .= ' FROM placex';
-                               $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
-                               $sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank;
-                               $sSQL .= ' and (name is not null or housenumber is not null)';
-                               $sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\',\'man_made\')';
-                               $sSQL .= ' and indexed_status = 0 ';
-                               $sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ';
-                               $sSQL .= ' OR ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.'))';
-                               $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', geometry) ASC limit 1';
-                               if (CONST_Debug) var_dump($sSQL);
-                               $aPlace = chksql($this->oDB->getRow($sSQL),
-                                                "Could not determine closest place.");
-                               $iPlaceID = $aPlace['place_id'];
-                               $iParentPlaceID = $aPlace['parent_place_id'];
-                               $bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us');
-                       }
-                       // if a street or house was found, look in interpolation lines table
-                       if ($bDoInterpolation && $this->iMaxRank >= 28 && $aPlace && $aPlace['rank_search'] >= 26)
-                       {
-                               // if a house was found, search the interpolation line that is at least as close as the house
-                               $sSQL = 'SELECT place_id, parent_place_id, 30 as rank_search, ST_line_locate_point(linegeo,'.$sPointSQL.') as fraction';
-                               $sSQL .= ' FROM location_property_osmline';
-                               $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';
-                               $sSQL .= ' and indexed_status = 0 ';
-                               $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', linegeo) ASC limit 1';
-                               
-                               if (CONST_Debug)
-                               {
-                                       $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
-                                       var_dump($sSQL);
+            // If we have to expand the search area by a large amount then we need a larger feature
+            // then there is a limit to how small the feature should be
+            if ($fSearchDiam > 2 && $iMaxRank > 4) $iMaxRank = 4;
+            if ($fSearchDiam > 1 && $iMaxRank > 9) $iMaxRank = 8;
+            if ($fSearchDiam > 0.8 && $iMaxRank > 10) $iMaxRank = 10;
+            if ($fSearchDiam > 0.6 && $iMaxRank > 12) $iMaxRank = 12;
+            if ($fSearchDiam > 0.2 && $iMaxRank > 17) $iMaxRank = 17;
+            if ($fSearchDiam > 0.1 && $iMaxRank > 18) $iMaxRank = 18;
+            if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
+            if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
 
-                                       $aAllHouses = chksql($this->oDB->getAll($sSQL));
-                                       foreach($aAllHouses as $i)
-                                       {
-                                               echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
-                                       }
-                               }
-                               $aPlaceLine = chksql($this->oDB->getRow($sSQL),
-                                                    "Could not determine closest housenumber on an osm interpolation line.");
-                               if ($aPlaceLine)
-                               {
-                                       if (CONST_Debug) var_dump('found housenumber in interpolation lines table', $aPlaceLine);
-                                       if ($aPlace['rank_search'] == 30)
-                                       {
-                                               // if a house was already found in placex, we have to find out, 
-                                               // if the placex house or the interpolated house are closer to the searched point
-                                               // distance between point and placex house
-                                               $sSQL = 'SELECT ST_distance('.$sPointSQL.', house.geometry) as distance FROM placex as house WHERE house.place_id='.$iPlaceID;
-                                               $aDistancePlacex = chksql($this->oDB->getRow($sSQL),
-                                                                         "Could not determine distance between searched point and placex house.");
-                                               $fDistancePlacex = $aDistancePlacex['distance'];
-                                               // distance between point and interpolated house (fraction on interpolation line)
-                                               $sSQL = 'SELECT ST_distance('.$sPointSQL.', ST_LineInterpolatePoint(linegeo, '.$aPlaceLine['fraction'].')) as distance';
-                                               $sSQL .= ' FROM location_property_osmline WHERE place_id = '.$aPlaceLine['place_id'];
-                                               $aDistanceInterpolation = chksql($this->oDB->getRow($sSQL),
-                                                                                "Could not determine distance between searched point and interpolated house.");
-                                               $fDistanceInterpolation = $aDistanceInterpolation['distance'];
-                                               if ($fDistanceInterpolation < $fDistancePlacex)
-                                               {
-                                                       // interpolation is closer to point than placex house
-                                                       $bPlaceIsLine = true;
-                                                       $aPlace = $aPlaceLine;
-                                                       $iPlaceID = $aPlaceLine['place_id'];
-                                                       $iParentPlaceID = $aPlaceLine['parent_place_id']; // the street
-                                                       $fFraction = $aPlaceLine['fraction'];
-                                                       $iMaxRank = 30;
-                                               }
-                                               // else: nothing to do, take placex house from above
-                                       }
-                                       else
-                                       {
-                                               $bPlaceIsLine = true;
-                                               $aPlace = $aPlaceLine;
-                                               $iPlaceID = $aPlaceLine['place_id'];
-                                               $iParentPlaceID = $aPlaceLine['parent_place_id']; // the street
-                                               $fFraction = $aPlaceLine['fraction'];
-                                               $iMaxRank = 30;
-                                       }
-                               }
-                       }
-                       
-                       // Only street found? If it's in the US we can check TIGER data for nearest housenumber
-                       if (CONST_Use_US_Tiger_Data && $bDoInterpolation && $bIsInUnitedStates && $this->iMaxRank >= 28 && $iPlaceID && ($aPlace['rank_search'] == 26 || $aPlace['rank_search'] == 27 ))
-                       {
-                               $fSearchDiam = 0.001;
-                               $sSQL = 'SELECT place_id,parent_place_id,30 as rank_search, ST_line_locate_point(linegeo,'.$sPointSQL.') as fraction';
-                               //if (CONST_Debug) { $sSQL .= ', housenumber, ST_distance('.$sPointSQL.', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon'; }
-                               $sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$iPlaceID;
-                               $sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';  //no centroid anymore in Tiger data, now we have lines
-                               $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', linegeo) ASC limit 1';
+            $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code';
+            $sSQL .= ' FROM placex';
+            $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')';
+            $sSQL .= ' and rank_search != 28 and rank_search >= '.$iMaxRank;
+            $sSQL .= ' and (name is not null or housenumber is not null)';
+            $sSQL .= ' and class not in (\'waterway\',\'railway\',\'tunnel\',\'bridge\',\'man_made\')';
+            $sSQL .= ' and indexed_status = 0 ';
+            $sSQL .= ' and (ST_GeometryType(geometry) not in (\'ST_Polygon\',\'ST_MultiPolygon\') ';
+            $sSQL .= ' OR ST_DWithin('.$sPointSQL.', centroid, '.$fSearchDiam.'))';
+            $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', geometry) ASC limit 1';
+            if (CONST_Debug) var_dump($sSQL);
+            $aPlace = chksql($this->oDB->getRow($sSQL),
+                             "Could not determine closest place.");
+            $iPlaceID = $aPlace['place_id'];
+            $iParentPlaceID = $aPlace['parent_place_id'];
+            $bIsInUnitedStates = ($aPlace['calculated_country_code'] == 'us');
+        }
+        // if a street or house was found, look in interpolation lines table
+        if ($bDoInterpolation && $this->iMaxRank >= 28 && $aPlace && $aPlace['rank_search'] >= 26)
+        {
+            // if a house was found, search the interpolation line that is at least as close as the house
+            $sSQL = 'SELECT place_id, parent_place_id, 30 as rank_search, ST_line_locate_point(linegeo,'.$sPointSQL.') as fraction';
+            $sSQL .= ' FROM location_property_osmline';
+            $sSQL .= ' WHERE ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';
+            $sSQL .= ' and indexed_status = 0 ';
+            $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', linegeo) ASC limit 1';
+            
+            if (CONST_Debug)
+            {
+                $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
+                var_dump($sSQL);
 
-                               if (CONST_Debug)
-                               {
-                                       $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
-                                       var_dump($sSQL);
+                $aAllHouses = chksql($this->oDB->getAll($sSQL));
+                foreach($aAllHouses as $i)
+                {
+                    echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
+                }
+            }
+            $aPlaceLine = chksql($this->oDB->getRow($sSQL),
+                                 "Could not determine closest housenumber on an osm interpolation line.");
+            if ($aPlaceLine)
+            {
+                if (CONST_Debug) var_dump('found housenumber in interpolation lines table', $aPlaceLine);
+                if ($aPlace['rank_search'] == 30)
+                {
+                    // if a house was already found in placex, we have to find out, 
+                    // if the placex house or the interpolated house are closer to the searched point
+                    // distance between point and placex house
+                    $sSQL = 'SELECT ST_distance('.$sPointSQL.', house.geometry) as distance FROM placex as house WHERE house.place_id='.$iPlaceID;
+                    $aDistancePlacex = chksql($this->oDB->getRow($sSQL),
+                                              "Could not determine distance between searched point and placex house.");
+                    $fDistancePlacex = $aDistancePlacex['distance'];
+                    // distance between point and interpolated house (fraction on interpolation line)
+                    $sSQL = 'SELECT ST_distance('.$sPointSQL.', ST_LineInterpolatePoint(linegeo, '.$aPlaceLine['fraction'].')) as distance';
+                    $sSQL .= ' FROM location_property_osmline WHERE place_id = '.$aPlaceLine['place_id'];
+                    $aDistanceInterpolation = chksql($this->oDB->getRow($sSQL),
+                                                     "Could not determine distance between searched point and interpolated house.");
+                    $fDistanceInterpolation = $aDistanceInterpolation['distance'];
+                    if ($fDistanceInterpolation < $fDistancePlacex)
+                    {
+                        // interpolation is closer to point than placex house
+                        $bPlaceIsLine = true;
+                        $aPlace = $aPlaceLine;
+                        $iPlaceID = $aPlaceLine['place_id'];
+                        $iParentPlaceID = $aPlaceLine['parent_place_id']; // the street
+                        $fFraction = $aPlaceLine['fraction'];
+                        $iMaxRank = 30;
+                    }
+                    // else: nothing to do, take placex house from above
+                }
+                else
+                {
+                    $bPlaceIsLine = true;
+                    $aPlace = $aPlaceLine;
+                    $iPlaceID = $aPlaceLine['place_id'];
+                    $iParentPlaceID = $aPlaceLine['parent_place_id']; // the street
+                    $fFraction = $aPlaceLine['fraction'];
+                    $iMaxRank = 30;
+                }
+            }
+        }
+        
+        // Only street found? If it's in the US we can check TIGER data for nearest housenumber
+        if (CONST_Use_US_Tiger_Data && $bDoInterpolation && $bIsInUnitedStates && $this->iMaxRank >= 28 && $iPlaceID && ($aPlace['rank_search'] == 26 || $aPlace['rank_search'] == 27 ))
+        {
+            $fSearchDiam = 0.001;
+            $sSQL = 'SELECT place_id,parent_place_id,30 as rank_search, ST_line_locate_point(linegeo,'.$sPointSQL.') as fraction';
+            //if (CONST_Debug) { $sSQL .= ', housenumber, ST_distance('.$sPointSQL.', centroid) as distance, st_y(centroid) as lat, st_x(centroid) as lon'; }
+            $sSQL .= ' FROM location_property_tiger WHERE parent_place_id = '.$iPlaceID;
+            $sSQL .= ' AND ST_DWithin('.$sPointSQL.', linegeo, '.$fSearchDiam.')';  //no centroid anymore in Tiger data, now we have lines
+            $sSQL .= ' ORDER BY ST_distance('.$sPointSQL.', linegeo) ASC limit 1';
 
-                                       $aAllHouses = chksql($this->oDB->getAll($sSQL));
-                                       foreach($aAllHouses as $i)
-                                       {
-                                               echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
-                                       }
-                               }
+            if (CONST_Debug)
+            {
+                $sSQL = preg_replace('/limit 1/', 'limit 100', $sSQL);
+                var_dump($sSQL);
 
-                               $aPlaceTiger = chksql($this->oDB->getRow($sSQL),
-                                                     "Could not determine closest Tiger place.");
-                               if ($aPlaceTiger)
-                               {
-                                       if (CONST_Debug) var_dump('found Tiger housenumber', $aPlaceTiger);
-                                       $bPlaceIsTiger = true;
-                                       $aPlace = $aPlaceTiger;
-                                       $iPlaceID = $aPlaceTiger['place_id'];
-                                       $iParentPlaceID = $aPlaceTiger['parent_place_id']; // the street
-                                       $fFraction = $aPlaceTiger['fraction'];
-                                       $iMaxRank = 30;
-                               }
-                       }
+                $aAllHouses = chksql($this->oDB->getAll($sSQL));
+                foreach($aAllHouses as $i)
+                {
+                    echo $i['housenumber'] . ' | ' . $i['distance'] * 1000 . ' | ' . $i['lat'] . ' | ' . $i['lon']. ' | '. "<br>\n";
+                }
+            }
 
-                       // The point we found might be too small - use the address to find what it is a child of
-                       if ($iPlaceID && $iMaxRank < 28)
-                       {
-                               if (($aPlace['rank_search'] > 28 || $bPlaceIsTiger || $bPlaceIsLine) && $iParentPlaceID)
-                               {
-                                       $iPlaceID = $iParentPlaceID;
-                               }
-                               $sSQL  = 'select address_place_id';
-                               $sSQL .= ' FROM place_addressline';
-                               $sSQL .= " WHERE place_id = $iPlaceID";
-                               $sSQL .= " ORDER BY abs(cached_rank_address - $iMaxRank) asc,cached_rank_address desc,isaddress desc,distance desc";
-                               $sSQL .= ' LIMIT 1';
-                               $iPlaceID = chksql($this->oDB->getOne($sSQL),
-                                                  "Could not get parent for place.");
-                               if (!$iPlaceID)
-                               {
-                                       $iPlaceID = $aPlace['place_id'];
-                               }
-                       }
-                       return array('place_id' => $iPlaceID,
-                                               'type' => $bPlaceIsTiger ? 'tiger' : ($bPlaceIsLine ? 'interpolation' : 'osm'),
-                                               'fraction' => ($bPlaceIsTiger || $bPlaceIsLine) ? $fFraction : -1);
-               }
-               
-       }
-?>
+            $aPlaceTiger = chksql($this->oDB->getRow($sSQL),
+                                  "Could not determine closest Tiger place.");
+            if ($aPlaceTiger)
+            {
+                if (CONST_Debug) var_dump('found Tiger housenumber', $aPlaceTiger);
+                $bPlaceIsTiger = true;
+                $aPlace = $aPlaceTiger;
+                $iPlaceID = $aPlaceTiger['place_id'];
+                $iParentPlaceID = $aPlaceTiger['parent_place_id']; // the street
+                $fFraction = $aPlaceTiger['fraction'];
+                $iMaxRank = 30;
+            }
+        }
+
+        // The point we found might be too small - use the address to find what it is a child of
+        if ($iPlaceID && $iMaxRank < 28)
+        {
+            if (($aPlace['rank_search'] > 28 || $bPlaceIsTiger || $bPlaceIsLine) && $iParentPlaceID)
+            {
+                $iPlaceID = $iParentPlaceID;
+            }
+            $sSQL  = 'select address_place_id';
+            $sSQL .= ' FROM place_addressline';
+            $sSQL .= " WHERE place_id = $iPlaceID";
+            $sSQL .= " ORDER BY abs(cached_rank_address - $iMaxRank) asc,cached_rank_address desc,isaddress desc,distance desc";
+            $sSQL .= ' LIMIT 1';
+            $iPlaceID = chksql($this->oDB->getOne($sSQL),
+                               "Could not get parent for place.");
+            if (!$iPlaceID)
+            {
+                $iPlaceID = $aPlace['place_id'];
+            }
+        }
+        return array('place_id' => $iPlaceID,
+                    'type' => $bPlaceIsTiger ? 'tiger' : ($bPlaceIsLine ? 'interpolation' : 'osm'),
+                    'fraction' => ($bPlaceIsTiger || $bPlaceIsLine) ? $fFraction : -1);
+    }
+    
+}
index c73074a18517d2674e8fc80debdf7caa89b72ea6..a5a6ba5bca7c4a7ec10a38eb9c963b7191e4804e 100644 (file)
 <?php
 
-       function getCmdOpt($aArg, $aSpec, &$aResult, $bExitOnError = false, $bExitOnUnknown = false)
-       {
-               $aQuick = array();
-               $aCounts = array();
+function getCmdOpt($aArg, $aSpec, &$aResult, $bExitOnError = false, $bExitOnUnknown = false)
+{
+    $aQuick = array();
+    $aCounts = array();
 
-               foreach($aSpec as $aLine)
-               {
-                       if (is_array($aLine))
-                       {
-                               if ($aLine[0]) $aQuick['--'.$aLine[0]] = $aLine;
-                               if ($aLine[1]) $aQuick['-'.$aLine[1]] = $aLine;
-                               $aCounts[$aLine[0]] = 0;
-                       }
-               }
+    foreach($aSpec as $aLine)
+    {
+        if (is_array($aLine))
+        {
+            if ($aLine[0]) $aQuick['--'.$aLine[0]] = $aLine;
+            if ($aLine[1]) $aQuick['-'.$aLine[1]] = $aLine;
+            $aCounts[$aLine[0]] = 0;
+        }
+    }
 
-               $aResult = array();
-               $bUnknown = false;
-               $iSize = sizeof($aArg);
-               for ($i = 1; $i < $iSize; $i++)
-               {
-                       if (isset($aQuick[$aArg[$i]]))
-                       {
-                               $aLine = $aQuick[$aArg[$i]];
-                               $aCounts[$aLine[0]]++;
-                               $xVal = null;
-                               if ($aLine[4] == $aLine[5])
-                               {
-                                       if ($aLine[4])
-                                       {
-                                               $xVal = array();
-                                               for($n = $aLine[4]; $i < $iSize && $n; $n--)
-                                               {
-                                                       $i++;
-                                                       if ($i >= $iSize || $aArg[$i][0] == '-') showUsage($aSpec, $bExitOnError, 'Parameter of  \''.$aLine[0].'\' is missing');
+    $aResult = array();
+    $bUnknown = false;
+    $iSize = sizeof($aArg);
+    for ($i = 1; $i < $iSize; $i++)
+    {
+        if (isset($aQuick[$aArg[$i]]))
+        {
+            $aLine = $aQuick[$aArg[$i]];
+            $aCounts[$aLine[0]]++;
+            $xVal = null;
+            if ($aLine[4] == $aLine[5])
+            {
+                if ($aLine[4])
+                {
+                    $xVal = array();
+                    for($n = $aLine[4]; $i < $iSize && $n; $n--)
+                    {
+                        $i++;
+                        if ($i >= $iSize || $aArg[$i][0] == '-') showUsage($aSpec, $bExitOnError, 'Parameter of  \''.$aLine[0].'\' is missing');
 
-                                                       switch ($aLine[6])
-                                                       {
-                                                       case 'realpath':
-                                                               $xVal[] = realpath($aArg[$i]);
-                                                               break;
-                                                       case 'realdir':
-                                                               $sPath = realpath(dirname($aArg[$i]));
-                                                               if ($sPath)
-                                                                       $xVal[] = $sPath . '/' . basename($aArg[$i]);
-                                                               else
-                                                                       $xVal[] = $sPath;
-                                                               break;
-                                                       case 'bool':
-                                                               $xVal[] = (bool)$aArg[$i];
-                                                               break;
-                                                       case 'int':
-                                                               $xVal[] = (int)$aArg[$i];
-                                                               break;
-                                                       case 'float':
-                                                               $xVal[] = (float)$aArg[$i];
-                                                               break;
-                                                       default:
-                                                               $xVal[] = $aArg[$i];
-                                                               break;
-                                                       }
-                                               }
-                                               if ($aLine[4] == 1) $xVal = $xVal[0];
-                                       }
-                                       else
-                                       {
-                                               $xVal = true;
-                                       }
-                               }
-                               else
-                               {
-                                       fail('Variable numbers of params not yet supported');
-                               }
+                        switch ($aLine[6])
+                        {
+                        case 'realpath':
+                            $xVal[] = realpath($aArg[$i]);
+                            break;
+                        case 'realdir':
+                            $sPath = realpath(dirname($aArg[$i]));
+                            if ($sPath)
+                                $xVal[] = $sPath . '/' . basename($aArg[$i]);
+                            else
+                                $xVal[] = $sPath;
+                            break;
+                        case 'bool':
+                            $xVal[] = (bool)$aArg[$i];
+                            break;
+                        case 'int':
+                            $xVal[] = (int)$aArg[$i];
+                            break;
+                        case 'float':
+                            $xVal[] = (float)$aArg[$i];
+                            break;
+                        default:
+                            $xVal[] = $aArg[$i];
+                            break;
+                        }
+                    }
+                    if ($aLine[4] == 1) $xVal = $xVal[0];
+                }
+                else
+                {
+                    $xVal = true;
+                }
+            }
+            else
+            {
+                fail('Variable numbers of params not yet supported');
+            }
 
-                               if ($aLine[3] > 1)
-                               {
-                                       if (!array_key_exists($aLine[0], $aResult)) $aResult[$aLine[0]] = array();
-                                       $aResult[$aLine[0]][] = $xVal;
-                               }
-                               else
-                               {
-                                       $aResult[$aLine[0]] = $xVal;
-                               }
-                       }
-                       else
-                       {
-                               $bUnknown = $aArg[$i];
-                       }
-               }
+            if ($aLine[3] > 1)
+            {
+                if (!array_key_exists($aLine[0], $aResult)) $aResult[$aLine[0]] = array();
+                $aResult[$aLine[0]][] = $xVal;
+            }
+            else
+            {
+                $aResult[$aLine[0]] = $xVal;
+            }
+        }
+        else
+        {
+            $bUnknown = $aArg[$i];
+        }
+    }
 
-               if (array_key_exists('help', $aResult)) showUsage($aSpec);
-               if ($bUnknown && $bExitOnUnknown) showUsage($aSpec, $bExitOnError, 'Unknown option \''.$bUnknown.'\'');
+    if (array_key_exists('help', $aResult)) showUsage($aSpec);
+    if ($bUnknown && $bExitOnUnknown) showUsage($aSpec, $bExitOnError, 'Unknown option \''.$bUnknown.'\'');
 
-               foreach($aSpec as $aLine)
-               {
-                       if (is_array($aLine))
-                       {
-                               if ($aCounts[$aLine[0]] < $aLine[2]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is missing');
-                               if ($aCounts[$aLine[0]] > $aLine[3]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is pressent too many times');
-                               switch ($aLine[6])
-                               {
-                               case 'bool':
-                                       if (!array_key_exists($aLine[0], $aResult))
-                                               $aResult[$aLine[0]] = false;
-                                       break;
-                               }
-                       }
-               }
-               return $bUnknown;
-       }
+    foreach($aSpec as $aLine)
+    {
+        if (is_array($aLine))
+        {
+            if ($aCounts[$aLine[0]] < $aLine[2]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is missing');
+            if ($aCounts[$aLine[0]] > $aLine[3]) showUsage($aSpec, $bExitOnError, 'Option \''.$aLine[0].'\' is pressent too many times');
+            switch ($aLine[6])
+            {
+            case 'bool':
+                if (!array_key_exists($aLine[0], $aResult))
+                    $aResult[$aLine[0]] = false;
+                break;
+            }
+        }
+    }
+    return $bUnknown;
+}
 
-       function showUsage($aSpec, $bExit = false, $sError = false)
-       {
-               if ($sError)
-               {
-                       echo basename($_SERVER['argv'][0]).': '.$sError."\n";
-                       echo 'Try `'.basename($_SERVER['argv'][0]).' --help` for more information.'."\n";
-                       exit;
-               }
-               echo "Usage: ".basename($_SERVER['argv'][0])."\n";
-               $bFirst = true;
-               foreach($aSpec as $aLine)
-               {
-                       if (is_array($aLine))
-                       {
-                               if ($bFirst)
-                               {
-                                       $bFirst = false;
-                                       echo "\n";
-                               }
-                               $aNames = array();
-                               if ($aLine[1]) $aNames[] = '-'.$aLine[1];
-                               if ($aLine[0]) $aNames[] = '--'.$aLine[0];
-                               $sName = join(', ',$aNames);
-                               echo '  '.$sName.str_repeat(' ',30-strlen($sName)).$aLine[7]."\n";
-                       }
-                       else
-                       {
-                               echo $aLine."\n";
-                       }
-               }
-               echo "\n";
-               exit;
-       }
+function showUsage($aSpec, $bExit = false, $sError = false)
+{
+    if ($sError)
+    {
+        echo basename($_SERVER['argv'][0]).': '.$sError."\n";
+        echo 'Try `'.basename($_SERVER['argv'][0]).' --help` for more information.'."\n";
+        exit;
+    }
+    echo "Usage: ".basename($_SERVER['argv'][0])."\n";
+    $bFirst = true;
+    foreach($aSpec as $aLine)
+    {
+        if (is_array($aLine))
+        {
+            if ($bFirst)
+            {
+                $bFirst = false;
+                echo "\n";
+            }
+            $aNames = array();
+            if ($aLine[1]) $aNames[] = '-'.$aLine[1];
+            if ($aLine[0]) $aNames[] = '--'.$aLine[0];
+            $sName = join(', ',$aNames);
+            echo '  '.$sName.str_repeat(' ',30-strlen($sName)).$aLine[7]."\n";
+        }
+        else
+        {
+            echo $aLine."\n";
+        }
+    }
+    echo "\n";
+    exit;
+}
 
-       function chksql($oSql, $sMsg = false)
-       {
-               if (PEAR::isError($oSql))
-               {
-                       fail($sMsg || $oSql->getMessage(), $oSql->userinfo);
-               }
+function chksql($oSql, $sMsg = false)
+{
+    if (PEAR::isError($oSql))
+    {
+        fail($sMsg || $oSql->getMessage(), $oSql->userinfo);
+    }
 
-               return $oSql;
-       }
+    return $oSql;
+}
index 822acc37d4997f64bca66bc7ea506dcb3ab0f9e3..87868e5e5d2c36b38a1ca81a7efbae69d31976e9 100644 (file)
@@ -1,34 +1,35 @@
 <?php
-       require_once('DB.php');
 
-       function &getDB($bNew = false, $bPersistent = false)
-       {
-               // Get the database object
-               $oDB = chksql(DB::connect(CONST_Database_DSN.($bNew?'?new_link=true':''), $bPersistent),
-                             "Failed to establish database connection");
-               $oDB->setFetchMode(DB_FETCHMODE_ASSOC);
-               $oDB->query("SET DateStyle TO 'sql,european'");
-               $oDB->query("SET client_encoding TO 'utf-8'");
-               $iMaxExecution = ini_get('max_execution_time') * 1000;
-               if ($iMaxExecution > 0) $oDB->query("SET statement_timeout TO $iMaxExecution");
-               return $oDB;
-       }
+require_once('DB.php');
 
-       function getDBQuoted($s)
-       {
-               return "'".pg_escape_string($s)."'";
-       }
+function &getDB($bNew = false, $bPersistent = false)
+{
+    // Get the database object
+    $oDB = chksql(DB::connect(CONST_Database_DSN.($bNew?'?new_link=true':''), $bPersistent),
+                  "Failed to establish database connection");
+    $oDB->setFetchMode(DB_FETCHMODE_ASSOC);
+    $oDB->query("SET DateStyle TO 'sql,european'");
+    $oDB->query("SET client_encoding TO 'utf-8'");
+    $iMaxExecution = ini_get('max_execution_time') * 1000;
+    if ($iMaxExecution > 0) $oDB->query("SET statement_timeout TO $iMaxExecution");
+    return $oDB;
+}
 
-       function getPostgresVersion(&$oDB)
-       {
-               $sVersionString = $oDB->getOne('select version()');
-               preg_match('#PostgreSQL ([0-9]+)[.]([0-9]+)[^0-9]#', $sVersionString, $aMatches);
-               return (float) ($aMatches[1].'.'.$aMatches[2]);
-       }
+function getDBQuoted($s)
+{
+    return "'".pg_escape_string($s)."'";
+}
 
-       function getPostgisVersion(&$oDB)
-       {
-               $sVersionString = $oDB->getOne('select postgis_full_version()');
-               preg_match('#POSTGIS="([0-9]+)[.]([0-9]+)[.]([0-9]+)( r([0-9]+))?"#', $sVersionString, $aMatches);
-               return (float) ($aMatches[1].'.'.$aMatches[2]);
-       }
+function getPostgresVersion(&$oDB)
+{
+    $sVersionString = $oDB->getOne('select version()');
+    preg_match('#PostgreSQL ([0-9]+)[.]([0-9]+)[^0-9]#', $sVersionString, $aMatches);
+    return (float) ($aMatches[1].'.'.$aMatches[2]);
+}
+
+function getPostgisVersion(&$oDB)
+{
+    $sVersionString = $oDB->getOne('select postgis_full_version()');
+    preg_match('#POSTGIS="([0-9]+)[.]([0-9]+)[.]([0-9]+)( r([0-9]+))?"#', $sVersionString, $aMatches);
+    return (float) ($aMatches[1].'.'.$aMatches[2]);
+}
index 274256a642e96bd58339dec1f50de75d9ae1e636..d8521ed76991421c51a83a3f4504b300d38091dc 100644 (file)
@@ -1,26 +1,27 @@
 <?php
-       require_once('init.php');
-       require_once('cmd.php');
 
-       // handle http proxy when using file_get_contents
-       if (CONST_HTTP_Proxy) {
-         $proxy = 'tcp://' . CONST_HTTP_Proxy_Host . ':' . CONST_HTTP_Proxy_Port;
-         $aHeaders = array();
-         if(CONST_HTTP_Proxy_Login != null && CONST_HTTP_Proxy_Login != '' && CONST_HTTP_Proxy_Password != null && CONST_HTTP_Proxy_Password != '') {
-           $auth = base64_encode(CONST_HTTP_Proxy_Login . ':' . CONST_HTTP_Proxy_Password);
-           $aHeaders = array("Proxy-Authorization: Basic $auth");
-         }
-         $aContext = array(
-           'http' => array(
-             'proxy' => $proxy,
-             'request_fulluri' => true,
-             'header' => $aHeaders
-           ),
-           'https' => array(
-             'proxy' => $proxy,
-             'request_fulluri' => true,
-             'header' => $aHeaders
-           )
-         );
-         stream_context_set_default($aContext);
-       }
+require_once('init.php');
+require_once('cmd.php');
+
+// handle http proxy when using file_get_contents
+if (CONST_HTTP_Proxy) {
+    $proxy = 'tcp://' . CONST_HTTP_Proxy_Host . ':' . CONST_HTTP_Proxy_Port;
+    $aHeaders = array();
+    if(CONST_HTTP_Proxy_Login != null && CONST_HTTP_Proxy_Login != '' && CONST_HTTP_Proxy_Password != null && CONST_HTTP_Proxy_Password != '') {
+        $auth = base64_encode(CONST_HTTP_Proxy_Login . ':' . CONST_HTTP_Proxy_Password);
+        $aHeaders = array("Proxy-Authorization: Basic $auth");
+    }
+    $aContext = array(
+        'http' => array(
+            'proxy' => $proxy,
+            'request_fulluri' => true,
+            'header' => $aHeaders
+        ),
+        'https' => array(
+            'proxy' => $proxy,
+            'request_fulluri' => true,
+            'header' => $aHeaders
+        )
+    );
+    stream_context_set_default($aContext);
+}
index 9d66a9ac122aaf5b97d8f54c2dcb994481eb0237..ed95297d56507fa8c0eff6e563c6dc0a1245eca3 100644 (file)
 <?php
-       require_once('init.php');
-       require_once('ParameterParser.php');
+
+require_once('init.php');
+require_once('ParameterParser.php');
 
 /***************************************************************************
  *
  * Error handling functions
  *
  */
-       function chksql($oSql, $sMsg = "Database request failed")
-       {
-               if (!PEAR::isError($oSql)) return $oSql;
-
-               header('HTTP/1.0 500 Internal Server Error');
-               header('Content-type: text/html; charset=utf-8');
-
-               $sSqlError = $oSql->getMessage();
-
-               echo <<<INTERNALFAIL
-       <html>
-         <head><title>Internal Server Error</title></head>
-         <body>
-               <h1>Internal Server Error</h1>
-               <p>Nominatim has encountered an internal error while accessing the database.
-                  This may happen because the database is broken or because of a bug in
-                  the software. If you think it is a bug, feel free to report
-                  it over on <a href="https://github.com/twain47/Nominatim/issues">
-                  Github</a>. Please include the URL that caused the problem and the
-                  complete error details below.</p>
-               <p><b>Message:</b> $sMsg</p>
-               <p><b>SQL Error:</b> $sSqlError</p>
-               <p><b>Details:</b> <pre>
+
+function chksql($oSql, $sMsg = "Database request failed")
+{
+    if (!PEAR::isError($oSql)) return $oSql;
+
+    header('HTTP/1.0 500 Internal Server Error');
+    header('Content-type: text/html; charset=utf-8');
+
+    $sSqlError = $oSql->getMessage();
+
+    echo <<<INTERNALFAIL
+<html>
+  <head><title>Internal Server Error</title></head>
+  <body>
+    <h1>Internal Server Error</h1>
+    <p>Nominatim has encountered an internal error while accessing the database.
+       This may happen because the database is broken or because of a bug in
+       the software. If you think it is a bug, feel free to report
+       it over on <a href="https://github.com/twain47/Nominatim/issues">
+       Github</a>. Please include the URL that caused the problem and the
+       complete error details below.</p>
+    <p><b>Message:</b> $sMsg</p>
+    <p><b>SQL Error:</b> $sSqlError</p>
+    <p><b>Details:</b> <pre>
 INTERNALFAIL;
 
-               if (CONST_Debug)
-               {
-                       var_dump($oSql);
-               }
-               else
-               {
-                       echo "<pre>\n".$oSql->getUserInfo()."</pre>";
-               }
-
-               echo "</pre></p></body></html>";
-               exit;
-       }
-
-       function failInternalError($sError, $sSQL = false, $vDumpVar = false)
-       {
-               header('HTTP/1.0 500 Internal Server Error');
-               header('Content-type: text/html; charset=utf-8');
-               echo "<html><body><h1>Internal Server Error</h1>";
-               echo '<p>Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.</p>';
-               echo "<p><b>Details:</b> ".$sError,"</p>";
-               echo '<p>Feel free to file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
-               if (CONST_Debug)
-               {
-                       echo "<hr><h2>Debugging Information</h2><br>";
-                       if ($sSQL)
-                       {
-                               echo "<h3>SQL query</h3><code>".$sSQL."</code>";
-                       }
-                       if ($vDumpVar)
-                       {
-                               echo "<h3>Result</h3> <code>";
-                               var_dump($vDumpVar);
-                               echo "</code>";
-                       }
-               }
-               echo "\n</body></html>\n";
-               exit;
-       }
-
-
-       function userError($sError)
-       {
-               header('HTTP/1.0 400 Bad Request');
-               header('Content-type: text/html; charset=utf-8');
-               echo "<html><body><h1>Bad Request</h1>";
-               echo '<p>Nominatim has encountered an error with your request.</p>';
-               echo "<p><b>Details:</b> ".$sError."</p>";
-               echo '<p>If you feel this error is incorrect feel file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
-               echo "\n</body></html>\n";
-               exit;
-       }
+    if (CONST_Debug)
+    {
+        var_dump($oSql);
+    }
+    else
+    {
+        echo "<pre>\n".$oSql->getUserInfo()."</pre>";
+    }
+
+    echo "</pre></p></body></html>";
+    exit;
+}
+
+function failInternalError($sError, $sSQL = false, $vDumpVar = false)
+{
+    header('HTTP/1.0 500 Internal Server Error');
+    header('Content-type: text/html; charset=utf-8');
+    echo "<html><body><h1>Internal Server Error</h1>";
+    echo '<p>Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.</p>';
+    echo "<p><b>Details:</b> ".$sError,"</p>";
+    echo '<p>Feel free to file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
+    if (CONST_Debug)
+    {
+        echo "<hr><h2>Debugging Information</h2><br>";
+        if ($sSQL)
+        {
+            echo "<h3>SQL query</h3><code>".$sSQL."</code>";
+        }
+        if ($vDumpVar)
+        {
+            echo "<h3>Result</h3> <code>";
+            var_dump($vDumpVar);
+            echo "</code>";
+        }
+    }
+    echo "\n</body></html>\n";
+    exit;
+}
+
+
+function userError($sError)
+{
+    header('HTTP/1.0 400 Bad Request');
+    header('Content-type: text/html; charset=utf-8');
+    echo "<html><body><h1>Bad Request</h1>";
+    echo '<p>Nominatim has encountered an error with your request.</p>';
+    echo "<p><b>Details:</b> ".$sError."</p>";
+    echo '<p>If you feel this error is incorrect feel file an issue on <a href="https://github.com/twain47/Nominatim/issues">Github</a>. Please include the error message above and the URL you used.</p>';
+    echo "\n</body></html>\n";
+    exit;
+}
 
 
 /***************************************************************************
  * HTTP Reply header setup
  */
 
-       if (CONST_NoAccessControl)
-       {
-               header("Access-Control-Allow-Origin: *");
-               header("Access-Control-Allow-Methods: OPTIONS,GET");
-               if (!empty($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
-               {
-                       header("Access-Control-Allow-Headers: ".$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
-               }
-       }
-       if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') exit;
-
-       if (CONST_Debug) header('Content-type: text/html; charset=utf-8');
+if (CONST_NoAccessControl)
+{
+    header("Access-Control-Allow-Origin: *");
+    header("Access-Control-Allow-Methods: OPTIONS,GET");
+    if (!empty($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
+    {
+        header("Access-Control-Allow-Headers: ".$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
+    }
+}
+if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') exit;
+
+if (CONST_Debug) header('Content-type: text/html; charset=utf-8');
 
index 1d47c98fb2e4a6f652a557af640352c315f1e97a..b7ce27c2ab0485bf580ca9b329fa42f516112f1a 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
-       require_once(CONST_BasePath.'/lib/lib.php');
-       require_once(CONST_BasePath.'/lib/db.php');
+require_once(CONST_BasePath.'/lib/lib.php');
+require_once(CONST_BasePath.'/lib/db.php');
 
-       if (get_magic_quotes_gpc())
-       {
-               echo "Please disable magic quotes in your php.ini configuration\n";
-               exit;
-       }
+if (get_magic_quotes_gpc())
+{
+    echo "Please disable magic quotes in your php.ini configuration\n";
+    exit;
+}
index 3aa80e80d6bb56d0f38d31aa938dd5048d4ad0a0..40574eaf2af93a3215116bfdd4e0cfe56ed09e39 100644 (file)
 <?php
 
-       function fail($sError, $sUserError = false)
-       {
-               if (!$sUserError) $sUserError = $sError;
-               error_log('ERROR: '.$sError);
-               echo $sUserError."\n";
-               exit(-1);
-       }
-
-
-       function getProcessorCount()
-       {
-               $sCPU = file_get_contents('/proc/cpuinfo');
-               preg_match_all('#processor\s+: [0-9]+#', $sCPU, $aMatches);
-               return sizeof($aMatches[0]);
-       }
-
-
-       function getTotalMemoryMB()
-       {
-               $sCPU = file_get_contents('/proc/meminfo');
-               preg_match('#MemTotal: +([0-9]+) kB#', $sCPU, $aMatches);
-               return (int)($aMatches[1]/1024);
-       }
-
-
-       function getCacheMemoryMB()
-       {
-               $sCPU = file_get_contents('/proc/meminfo');
-               preg_match('#Cached: +([0-9]+) kB#', $sCPU, $aMatches);
-               return (int)($aMatches[1]/1024);
-       }
-
-
-       function bySearchRank($a, $b)
-       {
-               if ($a['iSearchRank'] == $b['iSearchRank'])
-                       return strlen($a['sOperator']) + strlen($a['sHouseNumber']) - strlen($b['sOperator']) - strlen($b['sHouseNumber']);
-               return ($a['iSearchRank'] < $b['iSearchRank']?-1:1);
-       }
-
-
-       function byImportance($a, $b)
-       {
-               if ($a['importance'] != $b['importance'])
-                       return ($a['importance'] > $b['importance']?-1:1);
-
-               return ($a['foundorder'] < $b['foundorder']?-1:1);
-       }
-
-
-       function getWordSets($aWords, $iDepth)
-       {
-               $aResult = array(array(join(' ',$aWords)));
-               $sFirstToken = '';
-               if ($iDepth < 8) {
-                       while(sizeof($aWords) > 1)
-                       {
-                               $sWord = array_shift($aWords);
-                               $sFirstToken .= ($sFirstToken?' ':'').$sWord;
-                               $aRest = getWordSets($aWords, $iDepth+1);
-                               foreach($aRest as $aSet)
-                               {
-                                       $aResult[] = array_merge(array($sFirstToken),$aSet);
-                               }
-                       }
-               }
-               return $aResult;
-       }
-
-       function getInverseWordSets($aWords, $iDepth)
-       {
-               $aResult = array(array(join(' ',$aWords)));
-               $sFirstToken = '';
-               if ($iDepth < 8)
-               {
-                       while(sizeof($aWords) > 1)
-                       {
-                               $sWord = array_pop($aWords);
-                               $sFirstToken = $sWord.($sFirstToken?' ':'').$sFirstToken;
-                               $aRest = getInverseWordSets($aWords, $iDepth+1);
-                               foreach($aRest as $aSet)
-                               {
-                                       $aResult[] = array_merge(array($sFirstToken),$aSet);
-                               }
-                       }
-               }
-               return $aResult;
-       }
-
-
-       function getTokensFromSets($aSets)
-       {
-               $aTokens = array();
-               foreach($aSets as $aSet)
-               {
-                       foreach($aSet as $sWord)
-                       {
-                               $aTokens[' '.$sWord] = ' '.$sWord;
-                               $aTokens[$sWord] = $sWord;
-                       }
-               }
-               return $aTokens;
-       }
-
-
-       /*
-          GB Postcode functions
       */
-
-       function gbPostcodeCalculate($sPostcode, $sPostcodeSector, $sPostcodeEnd, &$oDB)
-       {
-               // Try an exact match on the gb_postcode table
-               $sSQL = 'select \'AA\', ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from gb_postcode where postcode = \''.$sPostcode.'\'';
-               $aNearPostcodes = chksql($oDB->getAll($sSQL));
-
-               if (sizeof($aNearPostcodes))
-               {
-                       $aPostcodes = array();
-                       foreach($aNearPostcodes as $aPostcode)
-                       {
-                               $aPostcodes[] = array('lat' => $aPostcode['lat'], 'lon' => $aPostcode['lon'], 'radius' => 0.005);
-                       }
-
-                       return $aPostcodes;
-               }
-
-               return false;
-       }
-
-
-       function getClassTypes()
-       {
-               return array(
- 'boundary:administrative:1' => array('label'=>'Continent','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:2' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:country' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>6, 'defdiameter' => 15,),
- 'boundary:administrative:3' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:4' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:state' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 5.12,),
- 'boundary:administrative:5' => array('label'=>'State District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:6' => array('label'=>'County','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:7' => array('label'=>'County','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:county' => array('label'=>'County','frequency'=>108,'icon'=>'poi_boundary_administrative','defzoom'=>10, 'defdiameter' => 1.28,),
- 'boundary:administrative:8' => array('label'=>'City','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:city' => array('label'=>'City','frequency'=>66,'icon'=>'poi_place_city','defzoom'=>12, 'defdiameter' => 0.32,),
- 'boundary:administrative:9' => array('label'=>'City District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:10' => array('label'=>'Suburb','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:administrative:11' => array('label'=>'Neighbourhood','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:region' => array('label'=>'Region','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 0.04,),
- 'place:island' => array('label'=>'Island','frequency'=>288,'icon'=>'','defzoom'=>11, 'defdiameter' => 0.64,),
- 'boundary:administrative' => array('label'=>'Administrative','frequency'=>413,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'boundary:postal_code' => array('label'=>'Postcode','frequency'=>413,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
- 'place:town' => array('label'=>'Town','frequency'=>1497,'icon'=>'poi_place_town','defzoom'=>14, 'defdiameter' => 0.08,),
- 'place:village' => array('label'=>'Village','frequency'=>11230,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
- 'place:hamlet' => array('label'=>'Hamlet','frequency'=>7075,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
- 'place:suburb' => array('label'=>'Suburb','frequency'=>2528,'icon'=>'poi_place_village', 'defdiameter' => 0.04,),
- 'place:locality' => array('label'=>'Locality','frequency'=>4113,'icon'=>'poi_place_village', 'defdiameter' => 0.02,),
- 'landuse:farm' => array('label'=>'Farm','frequency'=>1201,'icon'=>'', 'defdiameter' => 0.02,),
- 'place:farm' => array('label'=>'Farm','frequency'=>1162,'icon'=>'', 'defdiameter' => 0.02,),
-
- 'highway:motorway_junction' => array('label'=>'Motorway Junction','frequency'=>1126,'icon'=>'','simplelabel'=>'Junction',),
- 'highway:motorway' => array('label'=>'Motorway','frequency'=>4627,'icon'=>'','simplelabel'=>'Road',),
- 'highway:trunk' => array('label'=>'Trunk','frequency'=>23084,'icon'=>'','simplelabel'=>'Road',),
- 'highway:primary' => array('label'=>'Primary','frequency'=>32138,'icon'=>'','simplelabel'=>'Road',),
- 'highway:secondary' => array('label'=>'Secondary','frequency'=>25807,'icon'=>'','simplelabel'=>'Road',),
- 'highway:tertiary' => array('label'=>'Tertiary','frequency'=>29829,'icon'=>'','simplelabel'=>'Road',),
- 'highway:residential' => array('label'=>'Residential','frequency'=>361498,'icon'=>'','simplelabel'=>'Road',),
- 'highway:unclassified' => array('label'=>'Unclassified','frequency'=>66441,'icon'=>'','simplelabel'=>'Road',),
- 'highway:living_street' => array('label'=>'Living Street','frequency'=>710,'icon'=>'','simplelabel'=>'Road',),
- 'highway:service' => array('label'=>'Service','frequency'=>9963,'icon'=>'','simplelabel'=>'Road',),
- 'highway:track' => array('label'=>'Track','frequency'=>2565,'icon'=>'','simplelabel'=>'Road',),
- 'highway:road' => array('label'=>'Road','frequency'=>591,'icon'=>'','simplelabel'=>'Road',),
- 'highway:byway' => array('label'=>'Byway','frequency'=>346,'icon'=>'','simplelabel'=>'Road',),
- 'highway:bridleway' => array('label'=>'Bridleway','frequency'=>1556,'icon'=>'',),
- 'highway:cycleway' => array('label'=>'Cycleway','frequency'=>2419,'icon'=>'',),
- 'highway:pedestrian' => array('label'=>'Pedestrian','frequency'=>2757,'icon'=>'',),
- 'highway:footway' => array('label'=>'Footway','frequency'=>15008,'icon'=>'',),
- 'highway:steps' => array('label'=>'Steps','frequency'=>444,'icon'=>'','simplelabel'=>'Footway',),
- 'highway:motorway_link' => array('label'=>'Motorway Link','frequency'=>795,'icon'=>'','simplelabel'=>'Road',),
- 'highway:trunk_link' => array('label'=>'Trunk Link','frequency'=>1258,'icon'=>'','simplelabel'=>'Road',),
- 'highway:primary_link' => array('label'=>'Primary Link','frequency'=>313,'icon'=>'','simplelabel'=>'Road',),
-
- 'landuse:industrial' => array('label'=>'Industrial','frequency'=>1062,'icon'=>'',),
- 'landuse:residential' => array('label'=>'Residential','frequency'=>886,'icon'=>'',),
- 'landuse:retail' => array('label'=>'Retail','frequency'=>754,'icon'=>'',),
- 'landuse:commercial' => array('label'=>'Commercial','frequency'=>657,'icon'=>'',),
-
- 'place:airport' => array('label'=>'Airport','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
- 'aeroway:aerodrome' => array('label'=>'Aerodrome','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
- 'aeroway' => array('label'=>'Aeroway','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
- 'railway:station' => array('label'=>'Station','frequency'=>3431,'icon'=>'transport_train_station2', 'defdiameter' => 0.01,),
- 'amenity:place_of_worship' => array('label'=>'Place Of Worship','frequency'=>9049,'icon'=>'place_of_worship_unknown3',),
- 'amenity:pub' => array('label'=>'Pub','frequency'=>18969,'icon'=>'food_pub',),
- 'amenity:bar' => array('label'=>'Bar','frequency'=>164,'icon'=>'food_bar',),
- 'amenity:university' => array('label'=>'University','frequency'=>607,'icon'=>'education_university',),
- 'tourism:museum' => array('label'=>'Museum','frequency'=>543,'icon'=>'tourist_museum',),
- 'amenity:arts_centre' => array('label'=>'Arts Centre','frequency'=>136,'icon'=>'tourist_art_gallery2',),
- 'tourism:zoo' => array('label'=>'Zoo','frequency'=>47,'icon'=>'tourist_zoo',),
- 'tourism:theme_park' => array('label'=>'Theme Park','frequency'=>24,'icon'=>'poi_point_of_interest',),
- 'tourism:attraction' => array('label'=>'Attraction','frequency'=>1463,'icon'=>'poi_point_of_interest',),
- 'leisure:golf_course' => array('label'=>'Golf Course','frequency'=>712,'icon'=>'sport_golf',),
- 'historic:castle' => array('label'=>'Castle','frequency'=>316,'icon'=>'tourist_castle',),
- 'amenity:hospital' => array('label'=>'Hospital','frequency'=>879,'icon'=>'health_hospital',),
- 'amenity:school' => array('label'=>'School','frequency'=>8192,'icon'=>'education_school',),
- 'amenity:theatre' => array('label'=>'Theatre','frequency'=>371,'icon'=>'tourist_theatre',),
- 'amenity:public_building' => array('label'=>'Public Building','frequency'=>985,'icon'=>'',),
- 'amenity:library' => array('label'=>'Library','frequency'=>794,'icon'=>'amenity_library',),
- 'amenity:townhall' => array('label'=>'Townhall','frequency'=>242,'icon'=>'',),
- 'amenity:community_centre' => array('label'=>'Community Centre','frequency'=>157,'icon'=>'',),
- 'amenity:fire_station' => array('label'=>'Fire Station','frequency'=>221,'icon'=>'amenity_firestation3',),
- 'amenity:police' => array('label'=>'Police','frequency'=>334,'icon'=>'amenity_police2',),
- 'amenity:bank' => array('label'=>'Bank','frequency'=>1248,'icon'=>'money_bank2',),
- 'amenity:post_office' => array('label'=>'Post Office','frequency'=>859,'icon'=>'amenity_post_office',),
- 'leisure:park' => array('label'=>'Park','frequency'=>2378,'icon'=>'',),
- 'amenity:park' => array('label'=>'Park','frequency'=>53,'icon'=>'',),
- 'landuse:park' => array('label'=>'Park','frequency'=>50,'icon'=>'',),
- 'landuse:recreation_ground' => array('label'=>'Recreation Ground','frequency'=>517,'icon'=>'',),
- 'tourism:hotel' => array('label'=>'Hotel','frequency'=>2150,'icon'=>'accommodation_hotel2',),
- 'tourism:motel' => array('label'=>'Motel','frequency'=>43,'icon'=>'',),
- 'amenity:cinema' => array('label'=>'Cinema','frequency'=>277,'icon'=>'tourist_cinema',),
- 'tourism:artwork' => array('label'=>'Artwork','frequency'=>171,'icon'=>'tourist_art_gallery2',),
- 'historic:archaeological_site' => array('label'=>'Archaeological Site','frequency'=>407,'icon'=>'tourist_archaeological2',),
- 'amenity:doctors' => array('label'=>'Doctors','frequency'=>581,'icon'=>'health_doctors',),
- 'leisure:sports_centre' => array('label'=>'Sports Centre','frequency'=>767,'icon'=>'sport_leisure_centre',),
- 'leisure:swimming_pool' => array('label'=>'Swimming Pool','frequency'=>24,'icon'=>'sport_swimming_outdoor',),
- 'shop:supermarket' => array('label'=>'Supermarket','frequency'=>2673,'icon'=>'shopping_supermarket',),
- 'shop:convenience' => array('label'=>'Convenience','frequency'=>1469,'icon'=>'shopping_convenience',),
- 'amenity:restaurant' => array('label'=>'Restaurant','frequency'=>3179,'icon'=>'food_restaurant',),
- 'amenity:fast_food' => array('label'=>'Fast Food','frequency'=>2289,'icon'=>'food_fastfood',),
- 'amenity:cafe' => array('label'=>'Cafe','frequency'=>1780,'icon'=>'food_cafe',),
- 'tourism:guest_house' => array('label'=>'Guest House','frequency'=>223,'icon'=>'accommodation_bed_and_breakfast',),
- 'amenity:pharmacy' => array('label'=>'Pharmacy','frequency'=>733,'icon'=>'health_pharmacy_dispensing',),
- 'amenity:fuel' => array('label'=>'Fuel','frequency'=>1308,'icon'=>'transport_fuel',),
- 'natural:peak' => array('label'=>'Peak','frequency'=>3212,'icon'=>'poi_peak',),
- 'waterway:waterfall' => array('label'=>'Waterfall','frequency'=>24,'icon'=>'',),
- 'natural:wood' => array('label'=>'Wood','frequency'=>1845,'icon'=>'landuse_coniferous_and_deciduous',),
- 'natural:water' => array('label'=>'Water','frequency'=>1790,'icon'=>'',),
- 'landuse:forest' => array('label'=>'Forest','frequency'=>467,'icon'=>'',),
- 'landuse:cemetery' => array('label'=>'Cemetery','frequency'=>463,'icon'=>'',),
- 'landuse:allotments' => array('label'=>'Allotments','frequency'=>408,'icon'=>'',),
- 'landuse:farmyard' => array('label'=>'Farmyard','frequency'=>397,'icon'=>'',),
- 'railway:rail' => array('label'=>'Rail','frequency'=>4894,'icon'=>'',),
- 'waterway:canal' => array('label'=>'Canal','frequency'=>1723,'icon'=>'',),
- 'waterway:river' => array('label'=>'River','frequency'=>4089,'icon'=>'',),
- 'waterway:stream' => array('label'=>'Stream','frequency'=>2684,'icon'=>'',),
- 'shop:bicycle' => array('label'=>'Bicycle','frequency'=>349,'icon'=>'shopping_bicycle',),
- 'shop:clothes' => array('label'=>'Clothes','frequency'=>315,'icon'=>'shopping_clothes',),
- 'shop:hairdresser' => array('label'=>'Hairdresser','frequency'=>312,'icon'=>'shopping_hairdresser',),
- 'shop:doityourself' => array('label'=>'Doityourself','frequency'=>247,'icon'=>'shopping_diy',),
- 'shop:estate_agent' => array('label'=>'Estate Agent','frequency'=>162,'icon'=>'shopping_estateagent2',),
- 'shop:car' => array('label'=>'Car','frequency'=>159,'icon'=>'shopping_car',),
- 'shop:garden_centre' => array('label'=>'Garden Centre','frequency'=>143,'icon'=>'shopping_garden_centre',),
- 'shop:car_repair' => array('label'=>'Car Repair','frequency'=>141,'icon'=>'shopping_car_repair',),
- 'shop:newsagent' => array('label'=>'Newsagent','frequency'=>132,'icon'=>'',),
- 'shop:bakery' => array('label'=>'Bakery','frequency'=>129,'icon'=>'shopping_bakery',),
- 'shop:furniture' => array('label'=>'Furniture','frequency'=>124,'icon'=>'',),
- 'shop:butcher' => array('label'=>'Butcher','frequency'=>105,'icon'=>'shopping_butcher',),
- 'shop:apparel' => array('label'=>'Apparel','frequency'=>98,'icon'=>'shopping_clothes',),
- 'shop:electronics' => array('label'=>'Electronics','frequency'=>96,'icon'=>'',),
- 'shop:department_store' => array('label'=>'Department Store','frequency'=>86,'icon'=>'',),
- 'shop:books' => array('label'=>'Books','frequency'=>85,'icon'=>'',),
- 'shop:yes' => array('label'=>'Shop','frequency'=>68,'icon'=>'',),
- 'shop:outdoor' => array('label'=>'Outdoor','frequency'=>67,'icon'=>'',),
- 'shop:mall' => array('label'=>'Mall','frequency'=>63,'icon'=>'',),
- 'shop:florist' => array('label'=>'Florist','frequency'=>61,'icon'=>'',),
- 'shop:charity' => array('label'=>'Charity','frequency'=>60,'icon'=>'',),
- 'shop:hardware' => array('label'=>'Hardware','frequency'=>59,'icon'=>'',),
- 'shop:laundry' => array('label'=>'Laundry','frequency'=>51,'icon'=>'shopping_laundrette',),
- 'shop:shoes' => array('label'=>'Shoes','frequency'=>49,'icon'=>'',),
- 'shop:beverages' => array('label'=>'Beverages','frequency'=>48,'icon'=>'shopping_alcohol',),
- 'shop:dry_cleaning' => array('label'=>'Dry Cleaning','frequency'=>46,'icon'=>'',),
- 'shop:carpet' => array('label'=>'Carpet','frequency'=>45,'icon'=>'',),
- 'shop:computer' => array('label'=>'Computer','frequency'=>44,'icon'=>'',),
- 'shop:alcohol' => array('label'=>'Alcohol','frequency'=>44,'icon'=>'shopping_alcohol',),
- 'shop:optician' => array('label'=>'Optician','frequency'=>55,'icon'=>'health_opticians',),
- 'shop:chemist' => array('label'=>'Chemist','frequency'=>42,'icon'=>'health_pharmacy',),
- 'shop:gallery' => array('label'=>'Gallery','frequency'=>38,'icon'=>'tourist_art_gallery2',),
- 'shop:mobile_phone' => array('label'=>'Mobile Phone','frequency'=>37,'icon'=>'',),
- 'shop:sports' => array('label'=>'Sports','frequency'=>37,'icon'=>'',),
- 'shop:jewelry' => array('label'=>'Jewelry','frequency'=>32,'icon'=>'shopping_jewelry',),
- 'shop:pet' => array('label'=>'Pet','frequency'=>29,'icon'=>'',),
- 'shop:beauty' => array('label'=>'Beauty','frequency'=>28,'icon'=>'',),
- 'shop:stationery' => array('label'=>'Stationery','frequency'=>25,'icon'=>'',),
- 'shop:shopping_centre' => array('label'=>'Shopping Centre','frequency'=>25,'icon'=>'',),
- 'shop:general' => array('label'=>'General','frequency'=>25,'icon'=>'',),
- 'shop:electrical' => array('label'=>'Electrical','frequency'=>25,'icon'=>'',),
- 'shop:toys' => array('label'=>'Toys','frequency'=>23,'icon'=>'',),
- 'shop:jeweller' => array('label'=>'Jeweller','frequency'=>23,'icon'=>'',),
- 'shop:betting' => array('label'=>'Betting','frequency'=>23,'icon'=>'',),
- 'shop:household' => array('label'=>'Household','frequency'=>21,'icon'=>'',),
- 'shop:travel_agency' => array('label'=>'Travel Agency','frequency'=>21,'icon'=>'',),
- 'shop:hifi' => array('label'=>'Hifi','frequency'=>21,'icon'=>'',),
- 'amenity:shop' => array('label'=>'Shop','frequency'=>61,'icon'=>'',),
- 'tourism:information' => array('label'=>'Information','frequency'=>224,'icon'=>'amenity_information',),
-
- 'place:house' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
- 'place:house_name' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
- 'place:house_number' => array('label'=>'House Number','frequency'=>2086,'icon'=>'','defzoom'=>18,),
- 'place:country_code' => array('label'=>'Country Code','frequency'=>2086,'icon'=>'','defzoom'=>18,),
-
- //
-
- 'leisure:pitch' => array('label'=>'Pitch','frequency'=>762,'icon'=>'',),
- 'highway:unsurfaced' => array('label'=>'Unsurfaced','frequency'=>492,'icon'=>'',),
- 'historic:ruins' => array('label'=>'Ruins','frequency'=>483,'icon'=>'tourist_ruin',),
- 'amenity:college' => array('label'=>'College','frequency'=>473,'icon'=>'education_school',),
- 'historic:monument' => array('label'=>'Monument','frequency'=>470,'icon'=>'tourist_monument',),
- 'railway:subway' => array('label'=>'Subway','frequency'=>385,'icon'=>'',),
- 'historic:memorial' => array('label'=>'Memorial','frequency'=>382,'icon'=>'tourist_monument',),
- 'leisure:nature_reserve' => array('label'=>'Nature Reserve','frequency'=>342,'icon'=>'',),
- 'leisure:common' => array('label'=>'Common','frequency'=>322,'icon'=>'',),
- 'waterway:lock_gate' => array('label'=>'Lock Gate','frequency'=>321,'icon'=>'',),
- 'natural:fell' => array('label'=>'Fell','frequency'=>308,'icon'=>'',),
- 'amenity:nightclub' => array('label'=>'Nightclub','frequency'=>292,'icon'=>'',),
- 'highway:path' => array('label'=>'Path','frequency'=>287,'icon'=>'',),
- 'leisure:garden' => array('label'=>'Garden','frequency'=>285,'icon'=>'',),
- 'landuse:reservoir' => array('label'=>'Reservoir','frequency'=>276,'icon'=>'',),
- 'leisure:playground' => array('label'=>'Playground','frequency'=>264,'icon'=>'',),
- 'leisure:stadium' => array('label'=>'Stadium','frequency'=>212,'icon'=>'',),
- 'historic:mine' => array('label'=>'Mine','frequency'=>193,'icon'=>'poi_mine',),
- 'natural:cliff' => array('label'=>'Cliff','frequency'=>193,'icon'=>'',),
- 'tourism:caravan_site' => array('label'=>'Caravan Site','frequency'=>183,'icon'=>'accommodation_caravan_park',),
- 'amenity:bus_station' => array('label'=>'Bus Station','frequency'=>181,'icon'=>'transport_bus_station',),
- 'amenity:kindergarten' => array('label'=>'Kindergarten','frequency'=>179,'icon'=>'',),
- 'highway:construction' => array('label'=>'Construction','frequency'=>176,'icon'=>'',),
- 'amenity:atm' => array('label'=>'Atm','frequency'=>172,'icon'=>'money_atm2',),
- 'amenity:emergency_phone' => array('label'=>'Emergency Phone','frequency'=>164,'icon'=>'',),
- 'waterway:lock' => array('label'=>'Lock','frequency'=>146,'icon'=>'',),
- 'waterway:riverbank' => array('label'=>'Riverbank','frequency'=>143,'icon'=>'',),
- 'natural:coastline' => array('label'=>'Coastline','frequency'=>142,'icon'=>'',),
- 'tourism:viewpoint' => array('label'=>'Viewpoint','frequency'=>140,'icon'=>'tourist_view_point',),
- 'tourism:hostel' => array('label'=>'Hostel','frequency'=>140,'icon'=>'',),
- 'tourism:bed_and_breakfast' => array('label'=>'Bed And Breakfast','frequency'=>140,'icon'=>'accommodation_bed_and_breakfast',),
- 'railway:halt' => array('label'=>'Halt','frequency'=>135,'icon'=>'',),
- 'railway:platform' => array('label'=>'Platform','frequency'=>134,'icon'=>'',),
- 'railway:tram' => array('label'=>'Tram','frequency'=>130,'icon'=>'transport_tram_stop',),
- 'amenity:courthouse' => array('label'=>'Courthouse','frequency'=>129,'icon'=>'amenity_court',),
- 'amenity:recycling' => array('label'=>'Recycling','frequency'=>126,'icon'=>'amenity_recycling',),
- 'amenity:dentist' => array('label'=>'Dentist','frequency'=>124,'icon'=>'health_dentist',),
- 'natural:beach' => array('label'=>'Beach','frequency'=>121,'icon'=>'tourist_beach',),
- 'place:moor' => array('label'=>'Moor','frequency'=>118,'icon'=>'',),
- 'amenity:grave_yard' => array('label'=>'Grave Yard','frequency'=>110,'icon'=>'',),
- 'waterway:drain' => array('label'=>'Drain','frequency'=>108,'icon'=>'',),
- 'landuse:grass' => array('label'=>'Grass','frequency'=>106,'icon'=>'',),
- 'landuse:village_green' => array('label'=>'Village Green','frequency'=>106,'icon'=>'',),
- 'natural:bay' => array('label'=>'Bay','frequency'=>102,'icon'=>'',),
- 'railway:tram_stop' => array('label'=>'Tram Stop','frequency'=>101,'icon'=>'transport_tram_stop',),
- 'leisure:marina' => array('label'=>'Marina','frequency'=>98,'icon'=>'',),
- 'highway:stile' => array('label'=>'Stile','frequency'=>97,'icon'=>'',),
- 'natural:moor' => array('label'=>'Moor','frequency'=>95,'icon'=>'',),
- 'railway:light_rail' => array('label'=>'Light Rail','frequency'=>91,'icon'=>'',),
- 'railway:narrow_gauge' => array('label'=>'Narrow Gauge','frequency'=>90,'icon'=>'',),
- 'natural:land' => array('label'=>'Land','frequency'=>86,'icon'=>'',),
- 'amenity:village_hall' => array('label'=>'Village Hall','frequency'=>82,'icon'=>'',),
- 'waterway:dock' => array('label'=>'Dock','frequency'=>80,'icon'=>'',),
- 'amenity:veterinary' => array('label'=>'Veterinary','frequency'=>79,'icon'=>'',),
- 'landuse:brownfield' => array('label'=>'Brownfield','frequency'=>77,'icon'=>'',),
- 'leisure:track' => array('label'=>'Track','frequency'=>76,'icon'=>'',),
- 'railway:historic_station' => array('label'=>'Historic Station','frequency'=>74,'icon'=>'',),
- 'landuse:construction' => array('label'=>'Construction','frequency'=>72,'icon'=>'',),
- 'amenity:prison' => array('label'=>'Prison','frequency'=>71,'icon'=>'amenity_prison',),
- 'landuse:quarry' => array('label'=>'Quarry','frequency'=>71,'icon'=>'',),
- 'amenity:telephone' => array('label'=>'Telephone','frequency'=>70,'icon'=>'',),
- 'highway:traffic_signals' => array('label'=>'Traffic Signals','frequency'=>66,'icon'=>'',),
- 'natural:heath' => array('label'=>'Heath','frequency'=>62,'icon'=>'',),
- 'historic:house' => array('label'=>'House','frequency'=>61,'icon'=>'',),
- 'amenity:social_club' => array('label'=>'Social Club','frequency'=>61,'icon'=>'',),
- 'landuse:military' => array('label'=>'Military','frequency'=>61,'icon'=>'',),
- 'amenity:health_centre' => array('label'=>'Health Centre','frequency'=>59,'icon'=>'',),
- 'historic:building' => array('label'=>'Building','frequency'=>58,'icon'=>'',),
- 'amenity:clinic' => array('label'=>'Clinic','frequency'=>57,'icon'=>'',),
- 'highway:services' => array('label'=>'Services','frequency'=>56,'icon'=>'',),
- 'amenity:ferry_terminal' => array('label'=>'Ferry Terminal','frequency'=>55,'icon'=>'',),
- 'natural:marsh' => array('label'=>'Marsh','frequency'=>55,'icon'=>'',),
- 'natural:hill' => array('label'=>'Hill','frequency'=>54,'icon'=>'',),
- 'highway:raceway' => array('label'=>'Raceway','frequency'=>53,'icon'=>'',),
- 'amenity:taxi' => array('label'=>'Taxi','frequency'=>47,'icon'=>'',),
- 'amenity:take_away' => array('label'=>'Take Away','frequency'=>45,'icon'=>'',),
- 'amenity:car_rental' => array('label'=>'Car Rental','frequency'=>44,'icon'=>'',),
- 'place:islet' => array('label'=>'Islet','frequency'=>44,'icon'=>'',),
- 'amenity:nursery' => array('label'=>'Nursery','frequency'=>44,'icon'=>'',),
- 'amenity:nursing_home' => array('label'=>'Nursing Home','frequency'=>43,'icon'=>'',),
- 'amenity:toilets' => array('label'=>'Toilets','frequency'=>38,'icon'=>'',),
- 'amenity:hall' => array('label'=>'Hall','frequency'=>38,'icon'=>'',),
- 'waterway:boatyard' => array('label'=>'Boatyard','frequency'=>36,'icon'=>'',),
- 'highway:mini_roundabout' => array('label'=>'Mini Roundabout','frequency'=>35,'icon'=>'',),
- 'historic:manor' => array('label'=>'Manor','frequency'=>35,'icon'=>'',),
- 'tourism:chalet' => array('label'=>'Chalet','frequency'=>34,'icon'=>'',),
- 'amenity:bicycle_parking' => array('label'=>'Bicycle Parking','frequency'=>34,'icon'=>'',),
- 'amenity:hotel' => array('label'=>'Hotel','frequency'=>34,'icon'=>'',),
- 'waterway:weir' => array('label'=>'Weir','frequency'=>33,'icon'=>'',),
- 'natural:wetland' => array('label'=>'Wetland','frequency'=>33,'icon'=>'',),
- 'natural:cave_entrance' => array('label'=>'Cave Entrance','frequency'=>32,'icon'=>'',),
- 'amenity:crematorium' => array('label'=>'Crematorium','frequency'=>31,'icon'=>'',),
- 'tourism:picnic_site' => array('label'=>'Picnic Site','frequency'=>31,'icon'=>'',),
- 'landuse:wood' => array('label'=>'Wood','frequency'=>30,'icon'=>'',),
- 'landuse:basin' => array('label'=>'Basin','frequency'=>30,'icon'=>'',),
- 'natural:tree' => array('label'=>'Tree','frequency'=>30,'icon'=>'',),
- 'leisure:slipway' => array('label'=>'Slipway','frequency'=>29,'icon'=>'',),
- 'landuse:meadow' => array('label'=>'Meadow','frequency'=>29,'icon'=>'',),
- 'landuse:piste' => array('label'=>'Piste','frequency'=>28,'icon'=>'',),
- 'amenity:care_home' => array('label'=>'Care Home','frequency'=>28,'icon'=>'',),
- 'amenity:club' => array('label'=>'Club','frequency'=>28,'icon'=>'',),
- 'amenity:medical_centre' => array('label'=>'Medical Centre','frequency'=>27,'icon'=>'',),
- 'historic:roman_road' => array('label'=>'Roman Road','frequency'=>27,'icon'=>'',),
- 'historic:fort' => array('label'=>'Fort','frequency'=>26,'icon'=>'',),
- 'railway:subway_entrance' => array('label'=>'Subway Entrance','frequency'=>26,'icon'=>'',),
- 'historic:yes' => array('label'=>'Historic','frequency'=>25,'icon'=>'',),
- 'highway:gate' => array('label'=>'Gate','frequency'=>25,'icon'=>'',),
- 'leisure:fishing' => array('label'=>'Fishing','frequency'=>24,'icon'=>'',),
- 'historic:museum' => array('label'=>'Museum','frequency'=>24,'icon'=>'',),
- 'amenity:car_wash' => array('label'=>'Car Wash','frequency'=>24,'icon'=>'',),
- 'railway:level_crossing' => array('label'=>'Level Crossing','frequency'=>23,'icon'=>'',),
- 'leisure:bird_hide' => array('label'=>'Bird Hide','frequency'=>23,'icon'=>'',),
- 'natural:headland' => array('label'=>'Headland','frequency'=>21,'icon'=>'',),
- 'tourism:apartments' => array('label'=>'Apartments','frequency'=>21,'icon'=>'',),
- 'amenity:shopping' => array('label'=>'Shopping','frequency'=>21,'icon'=>'',),
- 'natural:scrub' => array('label'=>'Scrub','frequency'=>20,'icon'=>'',),
- 'natural:fen' => array('label'=>'Fen','frequency'=>20,'icon'=>'',),
- 'building:yes' => array('label'=>'Building','frequency'=>200,'icon'=>'',),
- 'mountain_pass:yes' => array('label'=>'Mountain Pass','frequency'=>200,'icon'=>'',),
-
- 'amenity:parking' => array('label'=>'Parking','frequency'=>3157,'icon'=>'',),
- 'highway:bus_stop' => array('label'=>'Bus Stop','frequency'=>35777,'icon'=>'transport_bus_stop2',),
- 'place:postcode' => array('label'=>'Postcode','frequency'=>27267,'icon'=>'',),
- 'amenity:post_box' => array('label'=>'Post Box','frequency'=>9613,'icon'=>'',),
-
- 'place:houses' => array('label'=>'Houses','frequency'=>85,'icon'=>'',),
- 'railway:preserved' => array('label'=>'Preserved','frequency'=>227,'icon'=>'',),
- 'waterway:derelict_canal' => array('label'=>'Derelict Canal','frequency'=>21,'icon'=>'',),
- 'amenity:dead_pub' => array('label'=>'Dead Pub','frequency'=>20,'icon'=>'',),
- 'railway:disused_station' => array('label'=>'Disused Station','frequency'=>114,'icon'=>'',),
- 'railway:abandoned' => array('label'=>'Abandoned','frequency'=>641,'icon'=>'',),
- 'railway:disused' => array('label'=>'Disused','frequency'=>72,'icon'=>'',),
-                               );
-       }
-
-
-       function getClassTypesWithImportance()
-       {
-               $aOrders = getClassTypes();
-               $i = 1;
-               foreach($aOrders as $sID => $a)
-               {
-                       $aOrders[$sID]['importance'] = $i++;
-               }
-               return $aOrders;
-       }
-
-       function getResultDiameter($aResult)
-       {
-               $aClassType = getClassTypes();
-
-               $fDiameter = 0.0001;
-
-               if (isset($aResult['class'])
-                         && isset($aResult['type'])
-                         && isset($aResult['admin_level'])
-                         && 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']]['defdiameter'];
-               }
-               elseif (isset($aResult['class'])
-                         && isset($aResult['type'])
-                         && isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
-                               && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
-               {
-                       $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
-               }
-
-               return $fDiameter;
-       }
-
-
-       function javascript_renderData($xVal, $iOptions = 0)
-       {
-               if (defined('PHP_VERSION_ID') && PHP_VERSION_ID > 50400)
-                       $iOptions |= JSON_UNESCAPED_UNICODE;
-               $jsonout = json_encode($xVal, $iOptions);
-
-               if( ! isset($_GET['json_callback']))
-               {
-                       header("Content-Type: application/json; charset=UTF-8");
-                       echo $jsonout;
-               } else
-               {
-                       if (preg_match('/^[$_\p{L}][$_\p{L}\p{Nd}.[\]]*$/u',$_GET['json_callback']))
-                       {
-                               header("Content-Type: application/javascript; charset=UTF-8");
-                               echo $_GET['json_callback'].'('.$jsonout.')';
-                       }
-                       else
-                       {
-                               header('HTTP/1.0 400 Bad Request');
-                       }
-               }
-       }
-
-
-       function _debugDumpGroupedSearches($aData, $aTokens)
-       {
-               $aWordsIDs = array();
-               if ($aTokens)
-               {
-                       foreach($aTokens as $sToken => $aWords)
-                       {
-                               if ($aWords)
-                               {
-                                       foreach($aWords as $aToken)
-                                       {
-                                               $aWordsIDs[$aToken['word_id']] = $sToken.'('.$aToken['word_id'].')';
-                                       }
-                               }
-                       }
-               }
-               echo "<table border=\"1\">";
-               echo "<tr><th>rank</th><th>Name Tokens</th><th>Name Not</th><th>Address Tokens</th><th>Address Not</th><th>country</th><th>operator</th><th>class</th><th>type</th><th>house#</th><th>Lat</th><th>Lon</th><th>Radius</th></tr>";
-               foreach($aData as $iRank => $aRankedSet)
-               {
-                       foreach($aRankedSet as $aRow)
-                       {
-                               echo "<tr>";
-                               echo "<td>$iRank</td>";
-
-                               echo "<td>";
-                               $sSep = '';
-                               foreach($aRow['aName'] as $iWordID)
-                               {
-                                       echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
-                                       $sSep = ', ';
-                               }
-                               echo "</td>";
-
-                               echo "<td>";
-                               $sSep = '';
-                               foreach($aRow['aNameNonSearch'] as $iWordID)
-                               {
-                                       echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
-                                       $sSep = ', ';
-                               }
-                               echo "</td>";
-
-                               echo "<td>";
-                               $sSep = '';
-                               foreach($aRow['aAddress'] as $iWordID)
-                               {
-                                       echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
-                                       $sSep = ', ';
-                               }
-                               echo "</td>";
-
-                               echo "<td>";
-                               $sSep = '';
-                               foreach($aRow['aAddressNonSearch'] as $iWordID)
-                               {
-                                       echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
-                                       $sSep = ', ';
-                               }
-                               echo "</td>";
-
-                               echo "<td>".$aRow['sCountryCode']."</td>";
-
-                               echo "<td>".$aRow['sOperator']."</td>";
-                               echo "<td>".$aRow['sClass']."</td>";
-                               echo "<td>".$aRow['sType']."</td>";
-
-                               echo "<td>".$aRow['sHouseNumber']."</td>";
-
-                               echo "<td>".$aRow['fLat']."</td>";
-                               echo "<td>".$aRow['fLon']."</td>";
-                               echo "<td>".$aRow['fRadius']."</td>";
-
-                               echo "</tr>";
-                       }
-               }
-               echo "</table>";
-       }
-
-
-       function getAddressDetails(&$oDB, $sLanguagePrefArraySQL, $iPlaceID, $sCountryCode = false, $housenumber = -1, $bRaw = false)
-       {
-               $sSQL = "select *,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata($iPlaceID, $housenumber)";
-               if (!$bRaw) $sSQL .= " WHERE isaddress OR type = 'country_code'";
-               $sSQL .= " order by rank_address desc,isaddress desc";
-
-               $aAddressLines = chksql($oDB->getAll($sSQL));
-               if ($bRaw) return $aAddressLines;
-               //echo "<pre>";
-               //var_dump($aAddressLines);
-               $aAddress = array();
-               $aFallback = array();
-               $aClassType = getClassTypes();
-               foreach($aAddressLines as $aLine)
-               {
-                       $bFallback = false;
-                       $aTypeLabel = false;
-                       if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
-                       elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
-                       elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))]))
-                       {
-                               $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
-                               $bFallback = true;
-                       }
-                       else
-                       {
-                               $aTypeLabel = array('simplelabel'=>'address'.$aLine['rank_address']);
-                               $bFallback = true;
-                       }
-                       if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber'])))
-                       {
-                               $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
-                               $sTypeLabel = str_replace(' ','_',$sTypeLabel);
-                               if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place')
-                               {
-                                       $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
-                               }
-                               $aFallback[$sTypeLabel] = $bFallback;
-                       }
-               }
-               return $aAddress;
-       }
-
-
-       function addQuotes($s)
-       {
-               return "'".$s."'";
-       }
-
-       // returns boolean
-       function validLatLon($fLat,$fLon)
-       {
-               return ($fLat <= 90.1 && $fLat >= -90.1 && $fLon <= 180.1 && $fLon >= -180.1);
-       }
-
-       // Do we have anything that looks like a lat/lon pair?
-       // returns array(lat,lon,query_with_lat_lon_removed)
-       // or null
-       function looksLikeLatLonPair($sQuery)
-       {
-               $sFound    = null;
-               $fQueryLat = null;
-               $fQueryLon = null;
-
-               // degrees decimal minutes
-               // N 40 26.767, W 79 58.933
-               // N 40°26.767′, W 79°58.933′
-               //                  1         2                   3                  4         5            6
-               if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[° ]+([0-9.]+)?[′\']*[, ]+([EW])[ ]+([0-9]+)[° ]+([0-9]+[0-9.]*)[′\']*?\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
-                       $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
-               }
-               // degrees decimal minutes
-               // 40 26.767 N, 79 58.933 W
-               // 40° 26.767′ N 79° 58.933′ W
-               //                      1             2                      3          4            5                    6
-               elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\']*[ ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\' ]+([EW])\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
-                       $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
-               }
-               // degrees decimal seconds
-               // N 40 26 46 W 79 58 56
-               // N 40° 26′ 46″, W 79° 58′ 56″
-               //                      1        2            3            4                5        6            7            8
-               elseif (preg_match('/\\b([NS])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*[, ]+([EW])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600);
-                       $fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600);
-               }
-               // degrees decimal seconds
-               // 40 26 46 N 79 58 56 W
-               // 40° 26′ 46″ N, 79° 58′ 56″ W
-               //                      1            2            3            4          5            6            7            8
-               elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([EW])\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600);
-                       $fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600);
-               }
-               // degrees decimal
-               // N 40.446° W 79.982°
-               //                      1        2                               3        4
-               elseif (preg_match('/\\b([NS])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*[, ]+([EW])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]);
-                       $fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]);
-               }
-               // degrees decimal
-               // 40.446° N 79.982° W
-               //                      1                           2          3                           4
-               elseif (preg_match('/\\b([0-9]+[0-9]*\\.[0-9]+)[° ]+([NS])[, ]+([0-9]+[0-9]*\\.[0-9]+)[° ]+([EW])\\b/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]);
-                       $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]);
-               }
-               // degrees decimal
-               // 12.34, 56.78
-               // [12.456,-78.90]
-               //                   1          2                             3                        4
-               elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData))
-               {
-                       $sFound    = $aData[0];
-                       $fQueryLat = $aData[2];
-                       $fQueryLon = $aData[3];
-               }
-
-               if (!validLatLon($fQueryLat, $fQueryLon)) return;
-               $sQuery = trim(str_replace($sFound, ' ', $sQuery));
-
-               return array('lat' => $fQueryLat, 'lon' => $fQueryLon, 'query' => $sQuery);
-       }
-
-
-       function geometryText2Points($geometry_as_text, $fRadius)
-       {
-               $aPolyPoints = NULL;
-               if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
-               {
-                       preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
-               }
-               elseif (preg_match('#LINESTRING\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
-               {
-                       preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
-               }
-               elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
-               {
-                       preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
-               }
-               elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#', $geometry_as_text, $aMatch))
-               {
-                       $aPolyPoints = createPointsAroundCenter($aMatch[1], $aMatch[2], $fRadius);
-               }
-
-               if (isset($aPolyPoints))
-               {
-                       $aResultPoints = array();
-                       foreach($aPolyPoints as $aPoint)
-                       {
-                               $aResultPoints[] = array($aPoint[1], $aPoint[2]);
-                       }
-                       return $aResultPoints;
-               }
-
-               return;
-       }
-
-       function createPointsAroundCenter($fLon, $fLat, $fRadius)
-       {
-                       $iSteps = max(8, min(100, ($fRadius * 40000)^2));
-                       $fStepSize = (2*pi())/$iSteps;
-                       $aPolyPoints = array();
-                       for($f = 0; $f < 2*pi(); $f += $fStepSize)
-                       {
-                               $aPolyPoints[] = array('', $fLon+($fRadius*sin($f)), $fLat+($fRadius*cos($f)) );
-                       }
-                       return $aPolyPoints;
-       }
+function fail($sError, $sUserError = false)
+{
+    if (!$sUserError) $sUserError = $sError;
+    error_log('ERROR: '.$sError);
+    echo $sUserError."\n";
+    exit(-1);
+}
+
+
+function getProcessorCount()
+{
+    $sCPU = file_get_contents('/proc/cpuinfo');
+    preg_match_all('#processor\s+: [0-9]+#', $sCPU, $aMatches);
+    return sizeof($aMatches[0]);
+}
+
+
+function getTotalMemoryMB()
+{
+    $sCPU = file_get_contents('/proc/meminfo');
+    preg_match('#MemTotal: +([0-9]+) kB#', $sCPU, $aMatches);
+    return (int)($aMatches[1]/1024);
+}
+
+
+function getCacheMemoryMB()
+{
+    $sCPU = file_get_contents('/proc/meminfo');
+    preg_match('#Cached: +([0-9]+) kB#', $sCPU, $aMatches);
+    return (int)($aMatches[1]/1024);
+}
+
+
+function bySearchRank($a, $b)
+{
+    if ($a['iSearchRank'] == $b['iSearchRank'])
+        return strlen($a['sOperator']) + strlen($a['sHouseNumber']) - strlen($b['sOperator']) - strlen($b['sHouseNumber']);
+    return ($a['iSearchRank'] < $b['iSearchRank']?-1:1);
+}
+
+
+function byImportance($a, $b)
+{
+    if ($a['importance'] != $b['importance'])
+        return ($a['importance'] > $b['importance']?-1:1);
+
+    return ($a['foundorder'] < $b['foundorder']?-1:1);
+}
+
+
+function getWordSets($aWords, $iDepth)
+{
+    $aResult = array(array(join(' ',$aWords)));
+    $sFirstToken = '';
+    if ($iDepth < 8) {
+        while(sizeof($aWords) > 1)
+        {
+            $sWord = array_shift($aWords);
+            $sFirstToken .= ($sFirstToken?' ':'').$sWord;
+            $aRest = getWordSets($aWords, $iDepth+1);
+            foreach($aRest as $aSet)
+            {
+                $aResult[] = array_merge(array($sFirstToken),$aSet);
+            }
+        }
+    }
+    return $aResult;
+}
+
+function getInverseWordSets($aWords, $iDepth)
+{
+    $aResult = array(array(join(' ',$aWords)));
+    $sFirstToken = '';
+    if ($iDepth < 8)
+    {
+        while(sizeof($aWords) > 1)
+        {
+            $sWord = array_pop($aWords);
+            $sFirstToken = $sWord.($sFirstToken?' ':'').$sFirstToken;
+            $aRest = getInverseWordSets($aWords, $iDepth+1);
+            foreach($aRest as $aSet)
+            {
+                $aResult[] = array_merge(array($sFirstToken),$aSet);
+            }
+        }
+    }
+    return $aResult;
+}
+
+
+function getTokensFromSets($aSets)
+{
+    $aTokens = array();
+    foreach($aSets as $aSet)
+    {
+        foreach($aSet as $sWord)
+        {
+            $aTokens[' '.$sWord] = ' '.$sWord;
+            $aTokens[$sWord] = $sWord;
+        }
+    }
+    return $aTokens;
+}
+
+
+/*
+   GB Postcode functions
+ */
+
+function gbPostcodeCalculate($sPostcode, $sPostcodeSector, $sPostcodeEnd, &$oDB)
+{
+    // Try an exact match on the gb_postcode table
+    $sSQL = 'select \'AA\', ST_X(ST_Centroid(geometry)) as lon,ST_Y(ST_Centroid(geometry)) as lat from gb_postcode where postcode = \''.$sPostcode.'\'';
+    $aNearPostcodes = chksql($oDB->getAll($sSQL));
+
+    if (sizeof($aNearPostcodes))
+    {
+        $aPostcodes = array();
+        foreach($aNearPostcodes as $aPostcode)
+        {
+            $aPostcodes[] = array('lat' => $aPostcode['lat'], 'lon' => $aPostcode['lon'], 'radius' => 0.005);
+        }
+
+        return $aPostcodes;
+    }
+
+    return false;
+}
+
+
+function getClassTypes()
+{
+    return array(
+'boundary:administrative:1' => array('label'=>'Continent','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:2' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:country' => array('label'=>'Country','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>6, 'defdiameter' => 15,),
+'boundary:administrative:3' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:4' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:state' => array('label'=>'State','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 5.12,),
+'boundary:administrative:5' => array('label'=>'State District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:6' => array('label'=>'County','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:7' => array('label'=>'County','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:county' => array('label'=>'County','frequency'=>108,'icon'=>'poi_boundary_administrative','defzoom'=>10, 'defdiameter' => 1.28,),
+'boundary:administrative:8' => array('label'=>'City','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:city' => array('label'=>'City','frequency'=>66,'icon'=>'poi_place_city','defzoom'=>12, 'defdiameter' => 0.32,),
+'boundary:administrative:9' => array('label'=>'City District','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:10' => array('label'=>'Suburb','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:administrative:11' => array('label'=>'Neighbourhood','frequency'=>0,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:region' => array('label'=>'Region','frequency'=>0,'icon'=>'poi_boundary_administrative','defzoom'=>8, 'defdiameter' => 0.04,),
+'place:island' => array('label'=>'Island','frequency'=>288,'icon'=>'','defzoom'=>11, 'defdiameter' => 0.64,),
+'boundary:administrative' => array('label'=>'Administrative','frequency'=>413,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'boundary:postal_code' => array('label'=>'Postcode','frequency'=>413,'icon'=>'poi_boundary_administrative', 'defdiameter' => 0.32,),
+'place:town' => array('label'=>'Town','frequency'=>1497,'icon'=>'poi_place_town','defzoom'=>14, 'defdiameter' => 0.08,),
+'place:village' => array('label'=>'Village','frequency'=>11230,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
+'place:hamlet' => array('label'=>'Hamlet','frequency'=>7075,'icon'=>'poi_place_village','defzoom'=>15, 'defdiameter' => 0.04,),
+'place:suburb' => array('label'=>'Suburb','frequency'=>2528,'icon'=>'poi_place_village', 'defdiameter' => 0.04,),
+'place:locality' => array('label'=>'Locality','frequency'=>4113,'icon'=>'poi_place_village', 'defdiameter' => 0.02,),
+'landuse:farm' => array('label'=>'Farm','frequency'=>1201,'icon'=>'', 'defdiameter' => 0.02,),
+'place:farm' => array('label'=>'Farm','frequency'=>1162,'icon'=>'', 'defdiameter' => 0.02,),
+
+'highway:motorway_junction' => array('label'=>'Motorway Junction','frequency'=>1126,'icon'=>'','simplelabel'=>'Junction',),
+'highway:motorway' => array('label'=>'Motorway','frequency'=>4627,'icon'=>'','simplelabel'=>'Road',),
+'highway:trunk' => array('label'=>'Trunk','frequency'=>23084,'icon'=>'','simplelabel'=>'Road',),
+'highway:primary' => array('label'=>'Primary','frequency'=>32138,'icon'=>'','simplelabel'=>'Road',),
+'highway:secondary' => array('label'=>'Secondary','frequency'=>25807,'icon'=>'','simplelabel'=>'Road',),
+'highway:tertiary' => array('label'=>'Tertiary','frequency'=>29829,'icon'=>'','simplelabel'=>'Road',),
+'highway:residential' => array('label'=>'Residential','frequency'=>361498,'icon'=>'','simplelabel'=>'Road',),
+'highway:unclassified' => array('label'=>'Unclassified','frequency'=>66441,'icon'=>'','simplelabel'=>'Road',),
+'highway:living_street' => array('label'=>'Living Street','frequency'=>710,'icon'=>'','simplelabel'=>'Road',),
+'highway:service' => array('label'=>'Service','frequency'=>9963,'icon'=>'','simplelabel'=>'Road',),
+'highway:track' => array('label'=>'Track','frequency'=>2565,'icon'=>'','simplelabel'=>'Road',),
+'highway:road' => array('label'=>'Road','frequency'=>591,'icon'=>'','simplelabel'=>'Road',),
+'highway:byway' => array('label'=>'Byway','frequency'=>346,'icon'=>'','simplelabel'=>'Road',),
+'highway:bridleway' => array('label'=>'Bridleway','frequency'=>1556,'icon'=>'',),
+'highway:cycleway' => array('label'=>'Cycleway','frequency'=>2419,'icon'=>'',),
+'highway:pedestrian' => array('label'=>'Pedestrian','frequency'=>2757,'icon'=>'',),
+'highway:footway' => array('label'=>'Footway','frequency'=>15008,'icon'=>'',),
+'highway:steps' => array('label'=>'Steps','frequency'=>444,'icon'=>'','simplelabel'=>'Footway',),
+'highway:motorway_link' => array('label'=>'Motorway Link','frequency'=>795,'icon'=>'','simplelabel'=>'Road',),
+'highway:trunk_link' => array('label'=>'Trunk Link','frequency'=>1258,'icon'=>'','simplelabel'=>'Road',),
+'highway:primary_link' => array('label'=>'Primary Link','frequency'=>313,'icon'=>'','simplelabel'=>'Road',),
+
+'landuse:industrial' => array('label'=>'Industrial','frequency'=>1062,'icon'=>'',),
+'landuse:residential' => array('label'=>'Residential','frequency'=>886,'icon'=>'',),
+'landuse:retail' => array('label'=>'Retail','frequency'=>754,'icon'=>'',),
+'landuse:commercial' => array('label'=>'Commercial','frequency'=>657,'icon'=>'',),
+
+'place:airport' => array('label'=>'Airport','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
+'aeroway:aerodrome' => array('label'=>'Aerodrome','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
+'aeroway' => array('label'=>'Aeroway','frequency'=>36,'icon'=>'transport_airport2', 'defdiameter' => 0.03,),
+'railway:station' => array('label'=>'Station','frequency'=>3431,'icon'=>'transport_train_station2', 'defdiameter' => 0.01,),
+'amenity:place_of_worship' => array('label'=>'Place Of Worship','frequency'=>9049,'icon'=>'place_of_worship_unknown3',),
+'amenity:pub' => array('label'=>'Pub','frequency'=>18969,'icon'=>'food_pub',),
+'amenity:bar' => array('label'=>'Bar','frequency'=>164,'icon'=>'food_bar',),
+'amenity:university' => array('label'=>'University','frequency'=>607,'icon'=>'education_university',),
+'tourism:museum' => array('label'=>'Museum','frequency'=>543,'icon'=>'tourist_museum',),
+'amenity:arts_centre' => array('label'=>'Arts Centre','frequency'=>136,'icon'=>'tourist_art_gallery2',),
+'tourism:zoo' => array('label'=>'Zoo','frequency'=>47,'icon'=>'tourist_zoo',),
+'tourism:theme_park' => array('label'=>'Theme Park','frequency'=>24,'icon'=>'poi_point_of_interest',),
+'tourism:attraction' => array('label'=>'Attraction','frequency'=>1463,'icon'=>'poi_point_of_interest',),
+'leisure:golf_course' => array('label'=>'Golf Course','frequency'=>712,'icon'=>'sport_golf',),
+'historic:castle' => array('label'=>'Castle','frequency'=>316,'icon'=>'tourist_castle',),
+'amenity:hospital' => array('label'=>'Hospital','frequency'=>879,'icon'=>'health_hospital',),
+'amenity:school' => array('label'=>'School','frequency'=>8192,'icon'=>'education_school',),
+'amenity:theatre' => array('label'=>'Theatre','frequency'=>371,'icon'=>'tourist_theatre',),
+'amenity:public_building' => array('label'=>'Public Building','frequency'=>985,'icon'=>'',),
+'amenity:library' => array('label'=>'Library','frequency'=>794,'icon'=>'amenity_library',),
+'amenity:townhall' => array('label'=>'Townhall','frequency'=>242,'icon'=>'',),
+'amenity:community_centre' => array('label'=>'Community Centre','frequency'=>157,'icon'=>'',),
+'amenity:fire_station' => array('label'=>'Fire Station','frequency'=>221,'icon'=>'amenity_firestation3',),
+'amenity:police' => array('label'=>'Police','frequency'=>334,'icon'=>'amenity_police2',),
+'amenity:bank' => array('label'=>'Bank','frequency'=>1248,'icon'=>'money_bank2',),
+'amenity:post_office' => array('label'=>'Post Office','frequency'=>859,'icon'=>'amenity_post_office',),
+'leisure:park' => array('label'=>'Park','frequency'=>2378,'icon'=>'',),
+'amenity:park' => array('label'=>'Park','frequency'=>53,'icon'=>'',),
+'landuse:park' => array('label'=>'Park','frequency'=>50,'icon'=>'',),
+'landuse:recreation_ground' => array('label'=>'Recreation Ground','frequency'=>517,'icon'=>'',),
+'tourism:hotel' => array('label'=>'Hotel','frequency'=>2150,'icon'=>'accommodation_hotel2',),
+'tourism:motel' => array('label'=>'Motel','frequency'=>43,'icon'=>'',),
+'amenity:cinema' => array('label'=>'Cinema','frequency'=>277,'icon'=>'tourist_cinema',),
+'tourism:artwork' => array('label'=>'Artwork','frequency'=>171,'icon'=>'tourist_art_gallery2',),
+'historic:archaeological_site' => array('label'=>'Archaeological Site','frequency'=>407,'icon'=>'tourist_archaeological2',),
+'amenity:doctors' => array('label'=>'Doctors','frequency'=>581,'icon'=>'health_doctors',),
+'leisure:sports_centre' => array('label'=>'Sports Centre','frequency'=>767,'icon'=>'sport_leisure_centre',),
+'leisure:swimming_pool' => array('label'=>'Swimming Pool','frequency'=>24,'icon'=>'sport_swimming_outdoor',),
+'shop:supermarket' => array('label'=>'Supermarket','frequency'=>2673,'icon'=>'shopping_supermarket',),
+'shop:convenience' => array('label'=>'Convenience','frequency'=>1469,'icon'=>'shopping_convenience',),
+'amenity:restaurant' => array('label'=>'Restaurant','frequency'=>3179,'icon'=>'food_restaurant',),
+'amenity:fast_food' => array('label'=>'Fast Food','frequency'=>2289,'icon'=>'food_fastfood',),
+'amenity:cafe' => array('label'=>'Cafe','frequency'=>1780,'icon'=>'food_cafe',),
+'tourism:guest_house' => array('label'=>'Guest House','frequency'=>223,'icon'=>'accommodation_bed_and_breakfast',),
+'amenity:pharmacy' => array('label'=>'Pharmacy','frequency'=>733,'icon'=>'health_pharmacy_dispensing',),
+'amenity:fuel' => array('label'=>'Fuel','frequency'=>1308,'icon'=>'transport_fuel',),
+'natural:peak' => array('label'=>'Peak','frequency'=>3212,'icon'=>'poi_peak',),
+'waterway:waterfall' => array('label'=>'Waterfall','frequency'=>24,'icon'=>'',),
+'natural:wood' => array('label'=>'Wood','frequency'=>1845,'icon'=>'landuse_coniferous_and_deciduous',),
+'natural:water' => array('label'=>'Water','frequency'=>1790,'icon'=>'',),
+'landuse:forest' => array('label'=>'Forest','frequency'=>467,'icon'=>'',),
+'landuse:cemetery' => array('label'=>'Cemetery','frequency'=>463,'icon'=>'',),
+'landuse:allotments' => array('label'=>'Allotments','frequency'=>408,'icon'=>'',),
+'landuse:farmyard' => array('label'=>'Farmyard','frequency'=>397,'icon'=>'',),
+'railway:rail' => array('label'=>'Rail','frequency'=>4894,'icon'=>'',),
+'waterway:canal' => array('label'=>'Canal','frequency'=>1723,'icon'=>'',),
+'waterway:river' => array('label'=>'River','frequency'=>4089,'icon'=>'',),
+'waterway:stream' => array('label'=>'Stream','frequency'=>2684,'icon'=>'',),
+'shop:bicycle' => array('label'=>'Bicycle','frequency'=>349,'icon'=>'shopping_bicycle',),
+'shop:clothes' => array('label'=>'Clothes','frequency'=>315,'icon'=>'shopping_clothes',),
+'shop:hairdresser' => array('label'=>'Hairdresser','frequency'=>312,'icon'=>'shopping_hairdresser',),
+'shop:doityourself' => array('label'=>'Doityourself','frequency'=>247,'icon'=>'shopping_diy',),
+'shop:estate_agent' => array('label'=>'Estate Agent','frequency'=>162,'icon'=>'shopping_estateagent2',),
+'shop:car' => array('label'=>'Car','frequency'=>159,'icon'=>'shopping_car',),
+'shop:garden_centre' => array('label'=>'Garden Centre','frequency'=>143,'icon'=>'shopping_garden_centre',),
+'shop:car_repair' => array('label'=>'Car Repair','frequency'=>141,'icon'=>'shopping_car_repair',),
+'shop:newsagent' => array('label'=>'Newsagent','frequency'=>132,'icon'=>'',),
+'shop:bakery' => array('label'=>'Bakery','frequency'=>129,'icon'=>'shopping_bakery',),
+'shop:furniture' => array('label'=>'Furniture','frequency'=>124,'icon'=>'',),
+'shop:butcher' => array('label'=>'Butcher','frequency'=>105,'icon'=>'shopping_butcher',),
+'shop:apparel' => array('label'=>'Apparel','frequency'=>98,'icon'=>'shopping_clothes',),
+'shop:electronics' => array('label'=>'Electronics','frequency'=>96,'icon'=>'',),
+'shop:department_store' => array('label'=>'Department Store','frequency'=>86,'icon'=>'',),
+'shop:books' => array('label'=>'Books','frequency'=>85,'icon'=>'',),
+'shop:yes' => array('label'=>'Shop','frequency'=>68,'icon'=>'',),
+'shop:outdoor' => array('label'=>'Outdoor','frequency'=>67,'icon'=>'',),
+'shop:mall' => array('label'=>'Mall','frequency'=>63,'icon'=>'',),
+'shop:florist' => array('label'=>'Florist','frequency'=>61,'icon'=>'',),
+'shop:charity' => array('label'=>'Charity','frequency'=>60,'icon'=>'',),
+'shop:hardware' => array('label'=>'Hardware','frequency'=>59,'icon'=>'',),
+'shop:laundry' => array('label'=>'Laundry','frequency'=>51,'icon'=>'shopping_laundrette',),
+'shop:shoes' => array('label'=>'Shoes','frequency'=>49,'icon'=>'',),
+'shop:beverages' => array('label'=>'Beverages','frequency'=>48,'icon'=>'shopping_alcohol',),
+'shop:dry_cleaning' => array('label'=>'Dry Cleaning','frequency'=>46,'icon'=>'',),
+'shop:carpet' => array('label'=>'Carpet','frequency'=>45,'icon'=>'',),
+'shop:computer' => array('label'=>'Computer','frequency'=>44,'icon'=>'',),
+'shop:alcohol' => array('label'=>'Alcohol','frequency'=>44,'icon'=>'shopping_alcohol',),
+'shop:optician' => array('label'=>'Optician','frequency'=>55,'icon'=>'health_opticians',),
+'shop:chemist' => array('label'=>'Chemist','frequency'=>42,'icon'=>'health_pharmacy',),
+'shop:gallery' => array('label'=>'Gallery','frequency'=>38,'icon'=>'tourist_art_gallery2',),
+'shop:mobile_phone' => array('label'=>'Mobile Phone','frequency'=>37,'icon'=>'',),
+'shop:sports' => array('label'=>'Sports','frequency'=>37,'icon'=>'',),
+'shop:jewelry' => array('label'=>'Jewelry','frequency'=>32,'icon'=>'shopping_jewelry',),
+'shop:pet' => array('label'=>'Pet','frequency'=>29,'icon'=>'',),
+'shop:beauty' => array('label'=>'Beauty','frequency'=>28,'icon'=>'',),
+'shop:stationery' => array('label'=>'Stationery','frequency'=>25,'icon'=>'',),
+'shop:shopping_centre' => array('label'=>'Shopping Centre','frequency'=>25,'icon'=>'',),
+'shop:general' => array('label'=>'General','frequency'=>25,'icon'=>'',),
+'shop:electrical' => array('label'=>'Electrical','frequency'=>25,'icon'=>'',),
+'shop:toys' => array('label'=>'Toys','frequency'=>23,'icon'=>'',),
+'shop:jeweller' => array('label'=>'Jeweller','frequency'=>23,'icon'=>'',),
+'shop:betting' => array('label'=>'Betting','frequency'=>23,'icon'=>'',),
+'shop:household' => array('label'=>'Household','frequency'=>21,'icon'=>'',),
+'shop:travel_agency' => array('label'=>'Travel Agency','frequency'=>21,'icon'=>'',),
+'shop:hifi' => array('label'=>'Hifi','frequency'=>21,'icon'=>'',),
+'amenity:shop' => array('label'=>'Shop','frequency'=>61,'icon'=>'',),
+'tourism:information' => array('label'=>'Information','frequency'=>224,'icon'=>'amenity_information',),
+
+'place:house' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
+'place:house_name' => array('label'=>'House','frequency'=>2086,'icon'=>'','defzoom'=>18,),
+'place:house_number' => array('label'=>'House Number','frequency'=>2086,'icon'=>'','defzoom'=>18,),
+'place:country_code' => array('label'=>'Country Code','frequency'=>2086,'icon'=>'','defzoom'=>18,),
+
+//
+
+'leisure:pitch' => array('label'=>'Pitch','frequency'=>762,'icon'=>'',),
+'highway:unsurfaced' => array('label'=>'Unsurfaced','frequency'=>492,'icon'=>'',),
+'historic:ruins' => array('label'=>'Ruins','frequency'=>483,'icon'=>'tourist_ruin',),
+'amenity:college' => array('label'=>'College','frequency'=>473,'icon'=>'education_school',),
+'historic:monument' => array('label'=>'Monument','frequency'=>470,'icon'=>'tourist_monument',),
+'railway:subway' => array('label'=>'Subway','frequency'=>385,'icon'=>'',),
+'historic:memorial' => array('label'=>'Memorial','frequency'=>382,'icon'=>'tourist_monument',),
+'leisure:nature_reserve' => array('label'=>'Nature Reserve','frequency'=>342,'icon'=>'',),
+'leisure:common' => array('label'=>'Common','frequency'=>322,'icon'=>'',),
+'waterway:lock_gate' => array('label'=>'Lock Gate','frequency'=>321,'icon'=>'',),
+'natural:fell' => array('label'=>'Fell','frequency'=>308,'icon'=>'',),
+'amenity:nightclub' => array('label'=>'Nightclub','frequency'=>292,'icon'=>'',),
+'highway:path' => array('label'=>'Path','frequency'=>287,'icon'=>'',),
+'leisure:garden' => array('label'=>'Garden','frequency'=>285,'icon'=>'',),
+'landuse:reservoir' => array('label'=>'Reservoir','frequency'=>276,'icon'=>'',),
+'leisure:playground' => array('label'=>'Playground','frequency'=>264,'icon'=>'',),
+'leisure:stadium' => array('label'=>'Stadium','frequency'=>212,'icon'=>'',),
+'historic:mine' => array('label'=>'Mine','frequency'=>193,'icon'=>'poi_mine',),
+'natural:cliff' => array('label'=>'Cliff','frequency'=>193,'icon'=>'',),
+'tourism:caravan_site' => array('label'=>'Caravan Site','frequency'=>183,'icon'=>'accommodation_caravan_park',),
+'amenity:bus_station' => array('label'=>'Bus Station','frequency'=>181,'icon'=>'transport_bus_station',),
+'amenity:kindergarten' => array('label'=>'Kindergarten','frequency'=>179,'icon'=>'',),
+'highway:construction' => array('label'=>'Construction','frequency'=>176,'icon'=>'',),
+'amenity:atm' => array('label'=>'Atm','frequency'=>172,'icon'=>'money_atm2',),
+'amenity:emergency_phone' => array('label'=>'Emergency Phone','frequency'=>164,'icon'=>'',),
+'waterway:lock' => array('label'=>'Lock','frequency'=>146,'icon'=>'',),
+'waterway:riverbank' => array('label'=>'Riverbank','frequency'=>143,'icon'=>'',),
+'natural:coastline' => array('label'=>'Coastline','frequency'=>142,'icon'=>'',),
+'tourism:viewpoint' => array('label'=>'Viewpoint','frequency'=>140,'icon'=>'tourist_view_point',),
+'tourism:hostel' => array('label'=>'Hostel','frequency'=>140,'icon'=>'',),
+'tourism:bed_and_breakfast' => array('label'=>'Bed And Breakfast','frequency'=>140,'icon'=>'accommodation_bed_and_breakfast',),
+'railway:halt' => array('label'=>'Halt','frequency'=>135,'icon'=>'',),
+'railway:platform' => array('label'=>'Platform','frequency'=>134,'icon'=>'',),
+'railway:tram' => array('label'=>'Tram','frequency'=>130,'icon'=>'transport_tram_stop',),
+'amenity:courthouse' => array('label'=>'Courthouse','frequency'=>129,'icon'=>'amenity_court',),
+'amenity:recycling' => array('label'=>'Recycling','frequency'=>126,'icon'=>'amenity_recycling',),
+'amenity:dentist' => array('label'=>'Dentist','frequency'=>124,'icon'=>'health_dentist',),
+'natural:beach' => array('label'=>'Beach','frequency'=>121,'icon'=>'tourist_beach',),
+'place:moor' => array('label'=>'Moor','frequency'=>118,'icon'=>'',),
+'amenity:grave_yard' => array('label'=>'Grave Yard','frequency'=>110,'icon'=>'',),
+'waterway:drain' => array('label'=>'Drain','frequency'=>108,'icon'=>'',),
+'landuse:grass' => array('label'=>'Grass','frequency'=>106,'icon'=>'',),
+'landuse:village_green' => array('label'=>'Village Green','frequency'=>106,'icon'=>'',),
+'natural:bay' => array('label'=>'Bay','frequency'=>102,'icon'=>'',),
+'railway:tram_stop' => array('label'=>'Tram Stop','frequency'=>101,'icon'=>'transport_tram_stop',),
+'leisure:marina' => array('label'=>'Marina','frequency'=>98,'icon'=>'',),
+'highway:stile' => array('label'=>'Stile','frequency'=>97,'icon'=>'',),
+'natural:moor' => array('label'=>'Moor','frequency'=>95,'icon'=>'',),
+'railway:light_rail' => array('label'=>'Light Rail','frequency'=>91,'icon'=>'',),
+'railway:narrow_gauge' => array('label'=>'Narrow Gauge','frequency'=>90,'icon'=>'',),
+'natural:land' => array('label'=>'Land','frequency'=>86,'icon'=>'',),
+'amenity:village_hall' => array('label'=>'Village Hall','frequency'=>82,'icon'=>'',),
+'waterway:dock' => array('label'=>'Dock','frequency'=>80,'icon'=>'',),
+'amenity:veterinary' => array('label'=>'Veterinary','frequency'=>79,'icon'=>'',),
+'landuse:brownfield' => array('label'=>'Brownfield','frequency'=>77,'icon'=>'',),
+'leisure:track' => array('label'=>'Track','frequency'=>76,'icon'=>'',),
+'railway:historic_station' => array('label'=>'Historic Station','frequency'=>74,'icon'=>'',),
+'landuse:construction' => array('label'=>'Construction','frequency'=>72,'icon'=>'',),
+'amenity:prison' => array('label'=>'Prison','frequency'=>71,'icon'=>'amenity_prison',),
+'landuse:quarry' => array('label'=>'Quarry','frequency'=>71,'icon'=>'',),
+'amenity:telephone' => array('label'=>'Telephone','frequency'=>70,'icon'=>'',),
+'highway:traffic_signals' => array('label'=>'Traffic Signals','frequency'=>66,'icon'=>'',),
+'natural:heath' => array('label'=>'Heath','frequency'=>62,'icon'=>'',),
+'historic:house' => array('label'=>'House','frequency'=>61,'icon'=>'',),
+'amenity:social_club' => array('label'=>'Social Club','frequency'=>61,'icon'=>'',),
+'landuse:military' => array('label'=>'Military','frequency'=>61,'icon'=>'',),
+'amenity:health_centre' => array('label'=>'Health Centre','frequency'=>59,'icon'=>'',),
+'historic:building' => array('label'=>'Building','frequency'=>58,'icon'=>'',),
+'amenity:clinic' => array('label'=>'Clinic','frequency'=>57,'icon'=>'',),
+'highway:services' => array('label'=>'Services','frequency'=>56,'icon'=>'',),
+'amenity:ferry_terminal' => array('label'=>'Ferry Terminal','frequency'=>55,'icon'=>'',),
+'natural:marsh' => array('label'=>'Marsh','frequency'=>55,'icon'=>'',),
+'natural:hill' => array('label'=>'Hill','frequency'=>54,'icon'=>'',),
+'highway:raceway' => array('label'=>'Raceway','frequency'=>53,'icon'=>'',),
+'amenity:taxi' => array('label'=>'Taxi','frequency'=>47,'icon'=>'',),
+'amenity:take_away' => array('label'=>'Take Away','frequency'=>45,'icon'=>'',),
+'amenity:car_rental' => array('label'=>'Car Rental','frequency'=>44,'icon'=>'',),
+'place:islet' => array('label'=>'Islet','frequency'=>44,'icon'=>'',),
+'amenity:nursery' => array('label'=>'Nursery','frequency'=>44,'icon'=>'',),
+'amenity:nursing_home' => array('label'=>'Nursing Home','frequency'=>43,'icon'=>'',),
+'amenity:toilets' => array('label'=>'Toilets','frequency'=>38,'icon'=>'',),
+'amenity:hall' => array('label'=>'Hall','frequency'=>38,'icon'=>'',),
+'waterway:boatyard' => array('label'=>'Boatyard','frequency'=>36,'icon'=>'',),
+'highway:mini_roundabout' => array('label'=>'Mini Roundabout','frequency'=>35,'icon'=>'',),
+'historic:manor' => array('label'=>'Manor','frequency'=>35,'icon'=>'',),
+'tourism:chalet' => array('label'=>'Chalet','frequency'=>34,'icon'=>'',),
+'amenity:bicycle_parking' => array('label'=>'Bicycle Parking','frequency'=>34,'icon'=>'',),
+'amenity:hotel' => array('label'=>'Hotel','frequency'=>34,'icon'=>'',),
+'waterway:weir' => array('label'=>'Weir','frequency'=>33,'icon'=>'',),
+'natural:wetland' => array('label'=>'Wetland','frequency'=>33,'icon'=>'',),
+'natural:cave_entrance' => array('label'=>'Cave Entrance','frequency'=>32,'icon'=>'',),
+'amenity:crematorium' => array('label'=>'Crematorium','frequency'=>31,'icon'=>'',),
+'tourism:picnic_site' => array('label'=>'Picnic Site','frequency'=>31,'icon'=>'',),
+'landuse:wood' => array('label'=>'Wood','frequency'=>30,'icon'=>'',),
+'landuse:basin' => array('label'=>'Basin','frequency'=>30,'icon'=>'',),
+'natural:tree' => array('label'=>'Tree','frequency'=>30,'icon'=>'',),
+'leisure:slipway' => array('label'=>'Slipway','frequency'=>29,'icon'=>'',),
+'landuse:meadow' => array('label'=>'Meadow','frequency'=>29,'icon'=>'',),
+'landuse:piste' => array('label'=>'Piste','frequency'=>28,'icon'=>'',),
+'amenity:care_home' => array('label'=>'Care Home','frequency'=>28,'icon'=>'',),
+'amenity:club' => array('label'=>'Club','frequency'=>28,'icon'=>'',),
+'amenity:medical_centre' => array('label'=>'Medical Centre','frequency'=>27,'icon'=>'',),
+'historic:roman_road' => array('label'=>'Roman Road','frequency'=>27,'icon'=>'',),
+'historic:fort' => array('label'=>'Fort','frequency'=>26,'icon'=>'',),
+'railway:subway_entrance' => array('label'=>'Subway Entrance','frequency'=>26,'icon'=>'',),
+'historic:yes' => array('label'=>'Historic','frequency'=>25,'icon'=>'',),
+'highway:gate' => array('label'=>'Gate','frequency'=>25,'icon'=>'',),
+'leisure:fishing' => array('label'=>'Fishing','frequency'=>24,'icon'=>'',),
+'historic:museum' => array('label'=>'Museum','frequency'=>24,'icon'=>'',),
+'amenity:car_wash' => array('label'=>'Car Wash','frequency'=>24,'icon'=>'',),
+'railway:level_crossing' => array('label'=>'Level Crossing','frequency'=>23,'icon'=>'',),
+'leisure:bird_hide' => array('label'=>'Bird Hide','frequency'=>23,'icon'=>'',),
+'natural:headland' => array('label'=>'Headland','frequency'=>21,'icon'=>'',),
+'tourism:apartments' => array('label'=>'Apartments','frequency'=>21,'icon'=>'',),
+'amenity:shopping' => array('label'=>'Shopping','frequency'=>21,'icon'=>'',),
+'natural:scrub' => array('label'=>'Scrub','frequency'=>20,'icon'=>'',),
+'natural:fen' => array('label'=>'Fen','frequency'=>20,'icon'=>'',),
+'building:yes' => array('label'=>'Building','frequency'=>200,'icon'=>'',),
+'mountain_pass:yes' => array('label'=>'Mountain Pass','frequency'=>200,'icon'=>'',),
+
+'amenity:parking' => array('label'=>'Parking','frequency'=>3157,'icon'=>'',),
+'highway:bus_stop' => array('label'=>'Bus Stop','frequency'=>35777,'icon'=>'transport_bus_stop2',),
+'place:postcode' => array('label'=>'Postcode','frequency'=>27267,'icon'=>'',),
+'amenity:post_box' => array('label'=>'Post Box','frequency'=>9613,'icon'=>'',),
+
+'place:houses' => array('label'=>'Houses','frequency'=>85,'icon'=>'',),
+'railway:preserved' => array('label'=>'Preserved','frequency'=>227,'icon'=>'',),
+'waterway:derelict_canal' => array('label'=>'Derelict Canal','frequency'=>21,'icon'=>'',),
+'amenity:dead_pub' => array('label'=>'Dead Pub','frequency'=>20,'icon'=>'',),
+'railway:disused_station' => array('label'=>'Disused Station','frequency'=>114,'icon'=>'',),
+'railway:abandoned' => array('label'=>'Abandoned','frequency'=>641,'icon'=>'',),
+'railway:disused' => array('label'=>'Disused','frequency'=>72,'icon'=>'',),
+            );
+}
+
+
+function getClassTypesWithImportance()
+{
+    $aOrders = getClassTypes();
+    $i = 1;
+    foreach($aOrders as $sID => $a)
+    {
+        $aOrders[$sID]['importance'] = $i++;
+    }
+    return $aOrders;
+}
+
+function getResultDiameter($aResult)
+{
+    $aClassType = getClassTypes();
+
+    $fDiameter = 0.0001;
+
+    if (isset($aResult['class'])
+          && isset($aResult['type'])
+          && isset($aResult['admin_level'])
+          && 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']]['defdiameter'];
+    }
+    elseif (isset($aResult['class'])
+          && isset($aResult['type'])
+          && isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
+            && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
+    {
+        $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
+    }
+
+    return $fDiameter;
+}
+
+
+function javascript_renderData($xVal, $iOptions = 0)
+{
+    if (defined('PHP_VERSION_ID') && PHP_VERSION_ID > 50400)
+        $iOptions |= JSON_UNESCAPED_UNICODE;
+    $jsonout = json_encode($xVal, $iOptions);
+
+    if( ! isset($_GET['json_callback']))
+    {
+        header("Content-Type: application/json; charset=UTF-8");
+        echo $jsonout;
+    } else
+    {
+        if (preg_match('/^[$_\p{L}][$_\p{L}\p{Nd}.[\]]*$/u',$_GET['json_callback']))
+        {
+            header("Content-Type: application/javascript; charset=UTF-8");
+            echo $_GET['json_callback'].'('.$jsonout.')';
+        }
+        else
+        {
+            header('HTTP/1.0 400 Bad Request');
+        }
+    }
+}
+
+
+function _debugDumpGroupedSearches($aData, $aTokens)
+{
+    $aWordsIDs = array();
+    if ($aTokens)
+    {
+        foreach($aTokens as $sToken => $aWords)
+        {
+            if ($aWords)
+            {
+                foreach($aWords as $aToken)
+                {
+                    $aWordsIDs[$aToken['word_id']] = $sToken.'('.$aToken['word_id'].')';
+                }
+            }
+        }
+    }
+    echo "<table border=\"1\">";
+    echo "<tr><th>rank</th><th>Name Tokens</th><th>Name Not</th><th>Address Tokens</th><th>Address Not</th><th>country</th><th>operator</th><th>class</th><th>type</th><th>house#</th><th>Lat</th><th>Lon</th><th>Radius</th></tr>";
+    foreach($aData as $iRank => $aRankedSet)
+    {
+        foreach($aRankedSet as $aRow)
+        {
+            echo "<tr>";
+            echo "<td>$iRank</td>";
+
+            echo "<td>";
+            $sSep = '';
+            foreach($aRow['aName'] as $iWordID)
+            {
+                echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
+                $sSep = ', ';
+            }
+            echo "</td>";
+
+            echo "<td>";
+            $sSep = '';
+            foreach($aRow['aNameNonSearch'] as $iWordID)
+            {
+                echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
+                $sSep = ', ';
+            }
+            echo "</td>";
+
+            echo "<td>";
+            $sSep = '';
+            foreach($aRow['aAddress'] as $iWordID)
+            {
+                echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
+                $sSep = ', ';
+            }
+            echo "</td>";
+
+            echo "<td>";
+            $sSep = '';
+            foreach($aRow['aAddressNonSearch'] as $iWordID)
+            {
+                echo $sSep.'#'.$aWordsIDs[$iWordID].'#';
+                $sSep = ', ';
+            }
+            echo "</td>";
+
+            echo "<td>".$aRow['sCountryCode']."</td>";
+
+            echo "<td>".$aRow['sOperator']."</td>";
+            echo "<td>".$aRow['sClass']."</td>";
+            echo "<td>".$aRow['sType']."</td>";
+
+            echo "<td>".$aRow['sHouseNumber']."</td>";
+
+            echo "<td>".$aRow['fLat']."</td>";
+            echo "<td>".$aRow['fLon']."</td>";
+            echo "<td>".$aRow['fRadius']."</td>";
+
+            echo "</tr>";
+        }
+    }
+    echo "</table>";
+}
+
+
+function getAddressDetails(&$oDB, $sLanguagePrefArraySQL, $iPlaceID, $sCountryCode = false, $housenumber = -1, $bRaw = false)
+{
+    $sSQL = "select *,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata($iPlaceID, $housenumber)";
+    if (!$bRaw) $sSQL .= " WHERE isaddress OR type = 'country_code'";
+    $sSQL .= " order by rank_address desc,isaddress desc";
+
+    $aAddressLines = chksql($oDB->getAll($sSQL));
+    if ($bRaw) return $aAddressLines;
+    //echo "<pre>";
+    //var_dump($aAddressLines);
+    $aAddress = array();
+    $aFallback = array();
+    $aClassType = getClassTypes();
+    foreach($aAddressLines as $aLine)
+    {
+        $bFallback = false;
+        $aTypeLabel = false;
+        if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
+        elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
+        elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))]))
+        {
+            $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
+            $bFallback = true;
+        }
+        else
+        {
+            $aTypeLabel = array('simplelabel'=>'address'.$aLine['rank_address']);
+            $bFallback = true;
+        }
+        if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber'])))
+        {
+            $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
+            $sTypeLabel = str_replace(' ','_',$sTypeLabel);
+            if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place')
+            {
+                $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
+            }
+            $aFallback[$sTypeLabel] = $bFallback;
+        }
+    }
+    return $aAddress;
+}
+
+
+function addQuotes($s)
+{
+    return "'".$s."'";
+}
+
+// returns boolean
+function validLatLon($fLat,$fLon)
+{
+    return ($fLat <= 90.1 && $fLat >= -90.1 && $fLon <= 180.1 && $fLon >= -180.1);
+}
+
+// Do we have anything that looks like a lat/lon pair?
+// returns array(lat,lon,query_with_lat_lon_removed)
+// or null
+function looksLikeLatLonPair($sQuery)
+{
+    $sFound    = null;
+    $fQueryLat = null;
+    $fQueryLon = null;
+
+    // degrees decimal minutes
+    // N 40 26.767, W 79 58.933
+    // N 40°26.767′, W 79°58.933′
+    //                  1         2                   3                  4         5            6
+    if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[° ]+([0-9.]+)?[′\']*[, ]+([EW])[ ]+([0-9]+)[° ]+([0-9]+[0-9.]*)[′\']*?\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60);
+        $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60);
+    }
+    // degrees decimal minutes
+    // 40 26.767 N, 79 58.933 W
+    // 40° 26.767′ N 79° 58.933′ W
+    //                      1             2                      3          4            5                    6
+    elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\']*[ ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+[0-9.]*)?[′\' ]+([EW])\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60);
+        $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60);
+    }
+    // degrees decimal seconds
+    // N 40 26 46 W 79 58 56
+    // N 40° 26′ 46″, W 79° 58′ 56″
+    //                      1        2            3            4                5        6            7            8
+    elseif (preg_match('/\\b([NS])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*[, ]+([EW])[ ]([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″"]*\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60 + $aData[4]/3600);
+        $fQueryLon = ($aData[5]=='E'?1:-1) * ($aData[6] + $aData[7]/60 + $aData[8]/3600);
+    }
+    // degrees decimal seconds
+    // 40 26 46 N 79 58 56 W
+    // 40° 26′ 46″ N, 79° 58′ 56″ W
+    //                      1            2            3            4          5            6            7            8
+    elseif (preg_match('/\\b([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([NS])[, ]+([0-9]+)[° ]+([0-9]+)[′\' ]+([0-9]+)[″" ]+([EW])\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[4]=='N'?1:-1) * ($aData[1] + $aData[2]/60 + $aData[3]/3600);
+        $fQueryLon = ($aData[8]=='E'?1:-1) * ($aData[5] + $aData[6]/60 + $aData[7]/3600);
+    }
+    // degrees decimal
+    // N 40.446° W 79.982°
+    //                      1        2                               3        4
+    elseif (preg_match('/\\b([NS])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*[, ]+([EW])[ ]([0-9]+[0-9]*\\.[0-9]+)[°]*\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2]);
+        $fQueryLon = ($aData[3]=='E'?1:-1) * ($aData[4]);
+    }
+    // degrees decimal
+    // 40.446° N 79.982° W
+    //                      1                           2          3                           4
+    elseif (preg_match('/\\b([0-9]+[0-9]*\\.[0-9]+)[° ]+([NS])[, ]+([0-9]+[0-9]*\\.[0-9]+)[° ]+([EW])\\b/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = ($aData[2]=='N'?1:-1) * ($aData[1]);
+        $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[3]);
+    }
+    // degrees decimal
+    // 12.34, 56.78
+    // [12.456,-78.90]
+    //                   1          2                             3                        4
+    elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData))
+    {
+        $sFound    = $aData[0];
+        $fQueryLat = $aData[2];
+        $fQueryLon = $aData[3];
+    }
+
+    if (!validLatLon($fQueryLat, $fQueryLon)) return;
+    $sQuery = trim(str_replace($sFound, ' ', $sQuery));
+
+    return array('lat' => $fQueryLat, 'lon' => $fQueryLon, 'query' => $sQuery);
+}
+
+
+function geometryText2Points($geometry_as_text, $fRadius)
+{
+    $aPolyPoints = NULL;
+    if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
+    {
+        preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
+    }
+    elseif (preg_match('#LINESTRING\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
+    {
+        preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
+    }
+    elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#', $geometry_as_text, $aMatch))
+    {
+        preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/', $aMatch[1], $aPolyPoints, PREG_SET_ORDER);
+    }
+    elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#', $geometry_as_text, $aMatch))
+    {
+        $aPolyPoints = createPointsAroundCenter($aMatch[1], $aMatch[2], $fRadius);
+    }
+
+    if (isset($aPolyPoints))
+    {
+        $aResultPoints = array();
+        foreach($aPolyPoints as $aPoint)
+        {
+            $aResultPoints[] = array($aPoint[1], $aPoint[2]);
+        }
+        return $aResultPoints;
+    }
+
+    return;
+}
+
+function createPointsAroundCenter($fLon, $fLat, $fRadius)
+{
+        $iSteps = max(8, min(100, ($fRadius * 40000)^2));
+        $fStepSize = (2*pi())/$iSteps;
+        $aPolyPoints = array();
+        for($f = 0; $f < 2*pi(); $f += $fStepSize)
+        {
+            $aPolyPoints[] = array('', $fLon+($fRadius*sin($f)), $fLat+($fRadius*cos($f)) );
+        }
+        return $aPolyPoints;
+}
index de19167bbb864294e07d8c0418ab51abe9fd7bf3..72619c0d06fc327a30f28b8483366acb134eb4eb 100644 (file)
@@ -1,74 +1,74 @@
 <?php
 
-       function logStart(&$oDB, $sType = '', $sQuery = '', $aLanguageList = array())
-       {
-               $fStartTime = microtime(true);
-               $aStartTime = explode('.', $fStartTime);
-               if (!isset($aStartTime[1])) $aStartTime[1] = '0';
+function logStart(&$oDB, $sType = '', $sQuery = '', $aLanguageList = array())
+{
+    $fStartTime = microtime(true);
+    $aStartTime = explode('.', $fStartTime);
+    if (!isset($aStartTime[1])) $aStartTime[1] = '0';
 
-               $sOutputFormat = '';
-               if (isset($_GET['format'])) $sOutputFormat = $_GET['format'];
+    $sOutputFormat = '';
+    if (isset($_GET['format'])) $sOutputFormat = $_GET['format'];
 
-               if ($sType == 'reverse')
-               {
-                       $sOutQuery = (isset($_GET['lat'])?$_GET['lat']:'').'/';
-                       if (isset($_GET['lon'])) $sOutQuery .= $_GET['lon'];
-                       if (isset($_GET['zoom'])) $sOutQuery .= '/'.$_GET['zoom'];
-               }
-               else
-                       $sOutQuery = $sQuery;
+    if ($sType == 'reverse')
+    {
+        $sOutQuery = (isset($_GET['lat'])?$_GET['lat']:'').'/';
+        if (isset($_GET['lon'])) $sOutQuery .= $_GET['lon'];
+        if (isset($_GET['zoom'])) $sOutQuery .= '/'.$_GET['zoom'];
+    }
+    else
+        $sOutQuery = $sQuery;
 
-               $hLog = array(
-                               date('Y-m-d H:i:s',$aStartTime[0]).'.'.$aStartTime[1],
-                               $_SERVER["REMOTE_ADDR"],
-                               $_SERVER['QUERY_STRING'],
-                               $sOutQuery,
-                               $sType,
-                               $fStartTime
-                               );
+    $hLog = array(
+            date('Y-m-d H:i:s',$aStartTime[0]).'.'.$aStartTime[1],
+            $_SERVER["REMOTE_ADDR"],
+            $_SERVER['QUERY_STRING'],
+            $sOutQuery,
+            $sType,
+            $fStartTime
+            );
 
-               if (CONST_Log_DB)
-               {
-                       if (isset($_GET['email']))
-                               $sUserAgent = $_GET['email'];
-                       elseif (isset($_SERVER['HTTP_REFERER']))
-                               $sUserAgent = $_SERVER['HTTP_REFERER'];
-                       elseif (isset($_SERVER['HTTP_USER_AGENT']))
-                               $sUserAgent = $_SERVER['HTTP_USER_AGENT'];
-                       else
-                               $sUserAgent = '';
-                       $sSQL = 'insert into new_query_log (type,starttime,query,ipaddress,useragent,language,format,searchterm)';
-                       $sSQL .= ' values ('.getDBQuoted($sType).','.getDBQuoted($hLog[0]).','.getDBQuoted($hLog[2]);
-                       $sSQL .= ','.getDBQuoted($hLog[1]).','.getDBQuoted($sUserAgent).','.getDBQuoted(join(',',$aLanguageList)).','.getDBQuoted($sOutputFormat).','.getDBQuoted($hLog[3]).')';
-                       $oDB->query($sSQL);
-               }
+    if (CONST_Log_DB)
+    {
+        if (isset($_GET['email']))
+            $sUserAgent = $_GET['email'];
+        elseif (isset($_SERVER['HTTP_REFERER']))
+            $sUserAgent = $_SERVER['HTTP_REFERER'];
+        elseif (isset($_SERVER['HTTP_USER_AGENT']))
+            $sUserAgent = $_SERVER['HTTP_USER_AGENT'];
+        else
+            $sUserAgent = '';
+        $sSQL = 'insert into new_query_log (type,starttime,query,ipaddress,useragent,language,format,searchterm)';
+        $sSQL .= ' values ('.getDBQuoted($sType).','.getDBQuoted($hLog[0]).','.getDBQuoted($hLog[2]);
+        $sSQL .= ','.getDBQuoted($hLog[1]).','.getDBQuoted($sUserAgent).','.getDBQuoted(join(',',$aLanguageList)).','.getDBQuoted($sOutputFormat).','.getDBQuoted($hLog[3]).')';
+        $oDB->query($sSQL);
+    }
 
-               return $hLog;
-       }
+    return $hLog;
+}
 
-       function logEnd(&$oDB, $hLog, $iNumResults)
-       {
-               $fEndTime = microtime(true);
+function logEnd(&$oDB, $hLog, $iNumResults)
+{
+    $fEndTime = microtime(true);
 
-               if (CONST_Log_DB)
-               {
-                       $aEndTime = explode('.', $fEndTime);
-                       if (!$aEndTime[1]) $aEndTime[1] = '0';
-                       $sEndTime = date('Y-m-d H:i:s',$aEndTime[0]).'.'.$aEndTime[1];
+    if (CONST_Log_DB)
+    {
+        $aEndTime = explode('.', $fEndTime);
+        if (!$aEndTime[1]) $aEndTime[1] = '0';
+        $sEndTime = date('Y-m-d H:i:s',$aEndTime[0]).'.'.$aEndTime[1];
 
-                       $sSQL = 'update new_query_log set endtime = '.getDBQuoted($sEndTime).', results = '.$iNumResults;
-                       $sSQL .= ' where starttime = '.getDBQuoted($hLog[0]);
-                       $sSQL .= ' and ipaddress = '.getDBQuoted($hLog[1]);
-                       $sSQL .= ' and query = '.getDBQuoted($hLog[2]);
-                       $oDB->query($sSQL);
-               }
+        $sSQL = 'update new_query_log set endtime = '.getDBQuoted($sEndTime).', results = '.$iNumResults;
+        $sSQL .= ' where starttime = '.getDBQuoted($hLog[0]);
+        $sSQL .= ' and ipaddress = '.getDBQuoted($hLog[1]);
+        $sSQL .= ' and query = '.getDBQuoted($hLog[2]);
+        $oDB->query($sSQL);
+    }
 
-               if (CONST_Log_File)
-               {
-                       $aOutdata = sprintf("[%s] %.4f %d %s \"%s\"\n",
-                                           $hLog[0], $fEndTime-$hLog[5], $iNumResults,
-                                           $hLog[4], $hLog[2]);
-                       file_put_contents(CONST_Log_File, $aOutdata, FILE_APPEND | LOCK_EX);
-               }
+    if (CONST_Log_File)
+    {
+        $aOutdata = sprintf("[%s] %.4f %d %s \"%s\"\n",
+                            $hLog[0], $fEndTime-$hLog[5], $iNumResults,
+                            $hLog[4], $hLog[2]);
+        file_put_contents(CONST_Log_File, $aOutdata, FILE_APPEND | LOCK_EX);
+    }
 
-       }
+}
index 722d73b18aa79e80b4509fc6a4c165b6f60bca48..6b427cf4d6c0bc970b0eebb3f6b01f5ddd8c991e 100644 (file)
@@ -1,43 +1,43 @@
 <?php
 
-       function formatOSMType($sType, $bIncludeExternal=true)
-       {
-               if ($sType == 'N') return 'node';
-               if ($sType == 'W') return 'way';
-               if ($sType == 'R') return 'relation';
-
-               if (!$bIncludeExternal) return '';
-
-               if ($sType == 'T') return 'tiger';
-               if ($sType == 'I') return 'way';
-
-               return '';
-       }
-
-       function osmLink($aFeature, $sRefText=false)
-       {
-               $sOSMType = formatOSMType($aFeature['osm_type'], false);
-               if ($sOSMType)
-               {
-                       return '<a href="//www.openstreetmap.org/'.$sOSMType.'/'.$aFeature['osm_id'].'">'.$sOSMType.' '.($sRefText?$sRefText:$aFeature['osm_id']).'</a>';
-               }
-               return '';
-       }
-
-       function wikipediaLink($aFeature)
-       {
-               if ($aFeature['wikipedia'])
-               {
-                       list($sLanguage, $sArticle) = explode(':',$aFeature['wikipedia']);
-                       return '<a href="https://'.$sLanguage.'.wikipedia.org/wiki/'.urlencode($sArticle).'" target="_blank">'.$aFeature['wikipedia'].'</a>';
-               }
-               return '';
-       }
-
-       function detailsLink($aFeature, $sTitle=false)
-       {
-               if (!$aFeature['place_id']) return '';
-
-               return '<a href="details.php?place_id='.$aFeature['place_id'].'">'.($sTitle?$sTitle:$aFeature['place_id']).'</a>';
-       }
+function formatOSMType($sType, $bIncludeExternal=true)
+{
+    if ($sType == 'N') return 'node';
+    if ($sType == 'W') return 'way';
+    if ($sType == 'R') return 'relation';
+
+    if (!$bIncludeExternal) return '';
+
+    if ($sType == 'T') return 'tiger';
+    if ($sType == 'I') return 'way';
+
+    return '';
+}
+
+function osmLink($aFeature, $sRefText=false)
+{
+    $sOSMType = formatOSMType($aFeature['osm_type'], false);
+    if ($sOSMType)
+    {
+        return '<a href="//www.openstreetmap.org/'.$sOSMType.'/'.$aFeature['osm_id'].'">'.$sOSMType.' '.($sRefText?$sRefText:$aFeature['osm_id']).'</a>';
+    }
+    return '';
+}
+
+function wikipediaLink($aFeature)
+{
+    if ($aFeature['wikipedia'])
+    {
+        list($sLanguage, $sArticle) = explode(':',$aFeature['wikipedia']);
+        return '<a href="https://'.$sLanguage.'.wikipedia.org/wiki/'.urlencode($sArticle).'" target="_blank">'.$aFeature['wikipedia'].'</a>';
+    }
+    return '';
+}
+
+function detailsLink($aFeature, $sTitle=false)
+{
+    if (!$aFeature['place_id']) return '';
+
+    return '<a href="details.php?place_id='.$aFeature['place_id'].'">'.($sTitle?$sTitle:$aFeature['place_id']).'</a>';
+}
 
index fef389543f6f064395fc0856c8eb6126f60c9f45..4a9f6325eb7463e67ad830db2ac79953507b2a29 100644 (file)
 <?php
-       header("content-type: text/html; charset=UTF-8");
+    header("content-type: text/html; charset=UTF-8");
 ?>
 <?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
-       <link href="css/common.css" rel="stylesheet" type="text/css" />
-       <link href="css/search.css" rel="stylesheet" type="text/css" />
+    <link href="css/common.css" rel="stylesheet" type="text/css" />
+    <link href="css/search.css" rel="stylesheet" type="text/css" />
 </head>
 
 <body id="reverse-page">
 
-       <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
-
-       <form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>reverse.php">
-               <div class="form-group">
-                       <input name="format" type="hidden" value="html">
-                       <input name="lat" type="text" class="form-control input-sm" placeholder="latitude"  value="<?php echo htmlspecialchars($_GET['lat']); ?>" >
-                       <input name="lon" type="text" class="form-control input-sm" placeholder="longitude" value="<?php echo htmlspecialchars($_GET['lon']); ?>" >
-                       max zoom
-
-                       <select name="zoom" class="form-control input-sm" value="<?php echo htmlspecialchars($_GET['zoom']); ?>">
-                               <option value="" <?php echo $_GET['zoom']==''?'selected':'' ?> >--</option>
-                               <?php
-
-                                       $aZoomLevels = array(
-                                                0 => "Continent / Sea",
-                                                1 => "",
-                                                2 => "",
-                                                3 => "Country",
-                                                4 => "",
-                                                5 => "State",
-                                                6 => "Region",
-                                                7 => "",
-                                                8 => "County",
-                                                9 => "",
-                                               10 => "City",
-                                               11 => "",
-                                               12 => "Town / Village",
-                                               13 => "",
-                                               14 => "Suburb",
-                                               15 => "",
-                                               16 => "Street",
-                                               17 => "",
-                                               18 => "Building",
-                                               19 => "",
-                                               20 => "",
-                                               21 => "",
-                                       );
-
-                                       foreach($aZoomLevels as $iZoomLevel => $sLabel)
-                                       {
-                                               $bSel = isset($_GET['zoom']) && ($_GET['zoom'] == (string)$iZoomLevel);
-                                               echo '<option value="'.$iZoomLevel.'"'.($bSel?'selected':'').'>'.$iZoomLevel.' '.$sLabel.'</option>'."\n";
-                                       }
-                               ?>
-                       </select>
-               </div>
-               <div class="form-group search-button-group">
-                       <button type="submit" class="btn btn-primary btn-sm">Search</button>
-               </div>
-               <div class="search-type-link">
-                       <a href="<?php echo CONST_Website_BaseURL; ?>search.php">forward search</a>
-               </div>
-       </form>
-
-
-       <div id="content">
+    <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
+
+    <form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>reverse.php">
+        <div class="form-group">
+            <input name="format" type="hidden" value="html">
+            <input name="lat" type="text" class="form-control input-sm" placeholder="latitude"  value="<?php echo htmlspecialchars($_GET['lat']); ?>" >
+            <input name="lon" type="text" class="form-control input-sm" placeholder="longitude" value="<?php echo htmlspecialchars($_GET['lon']); ?>" >
+            max zoom
+
+            <select name="zoom" class="form-control input-sm" value="<?php echo htmlspecialchars($_GET['zoom']); ?>">
+                <option value="" <?php echo $_GET['zoom']==''?'selected':'' ?> >--</option>
+                <?php
+
+                    $aZoomLevels = array(
+                         0 => "Continent / Sea",
+                         1 => "",
+                         2 => "",
+                         3 => "Country",
+                         4 => "",
+                         5 => "State",
+                         6 => "Region",
+                         7 => "",
+                         8 => "County",
+                         9 => "",
+                        10 => "City",
+                        11 => "",
+                        12 => "Town / Village",
+                        13 => "",
+                        14 => "Suburb",
+                        15 => "",
+                        16 => "Street",
+                        17 => "",
+                        18 => "Building",
+                        19 => "",
+                        20 => "",
+                        21 => "",
+                    );
+
+                    foreach($aZoomLevels as $iZoomLevel => $sLabel)
+                    {
+                        $bSel = isset($_GET['zoom']) && ($_GET['zoom'] == (string)$iZoomLevel);
+                        echo '<option value="'.$iZoomLevel.'"'.($bSel?'selected':'').'>'.$iZoomLevel.' '.$sLabel.'</option>'."\n";
+                    }
+                ?>
+            </select>
+        </div>
+        <div class="form-group search-button-group">
+            <button type="submit" class="btn btn-primary btn-sm">Search</button>
+        </div>
+        <div class="search-type-link">
+            <a href="<?php echo CONST_Website_BaseURL; ?>search.php">forward search</a>
+        </div>
+    </form>
+
+
+    <div id="content">
 
 <?php if ($aPlace) { ?>
 
-               <div id="searchresults" class="sidebar">
-               <?php
-                       $aResult = $aPlace;
-
-                       echo '<div class="result" data-position="0">';
-
-                       echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
-                       echo ' <span class="name">'.htmlspecialchars($aResult['langaddress']).'</span>';
-                       if (isset($aResult['label']))
-                               echo ' <span class="type">('.$aResult['label'].')</span>';
-                       else if ($aResult['type'] == 'yes')
-                               echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
-                       else
-                               echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
-                       echo '<p>'.$aResult['lat'].','.$aResult['lon'].'</p>';
-                       echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
-                       echo '</div>';
-               ?>
-               </div>
+        <div id="searchresults" class="sidebar">
+        <?php
+            $aResult = $aPlace;
+
+            echo '<div class="result" data-position="0">';
+
+            echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
+            echo ' <span class="name">'.htmlspecialchars($aResult['langaddress']).'</span>';
+            if (isset($aResult['label']))
+                echo ' <span class="type">('.$aResult['label'].')</span>';
+            else if ($aResult['type'] == 'yes')
+                echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
+            else
+                echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
+            echo '<p>'.$aResult['lat'].','.$aResult['lon'].'</p>';
+            echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
+            echo '</div>';
+        ?>
+        </div>
 
 <?php } else { ?>
 
-               <div id="intro" class="sidebar">
-                       Search for coordinates or click anywhere on the map.
-               </div>
+        <div id="intro" class="sidebar">
+            Search for coordinates or click anywhere on the map.
+        </div>
 
 <?php } ?>
 
-               <div id="map-wrapper">
-                       <div id="map-position">
-                               <div id="map-position-inner"></div>
-                               <div id="map-position-close"><a href="#">hide</a></div>
-                       </div>
-                       <div id="map"></div>
-               </div>
+        <div id="map-wrapper">
+            <div id="map-position">
+                <div id="map-position-inner"></div>
+                <div id="map-position-close"><a href="#">hide</a></div>
+            </div>
+            <div id="map"></div>
+        </div>
 
-       </div> <!-- /content -->
+    </div> <!-- /content -->
 
 
 
 
 
 
-       <script type="text/javascript">
-       <?php
+    <script type="text/javascript">
+    <?php
 
-               $aNominatimMapInit = array(
-                       'zoom' => isset($_GET['zoom']) ? htmlspecialchars($_GET['zoom']) : CONST_Default_Zoom,
-                       'lat'  => isset($_GET['lat']) ? htmlspecialchars($_GET['lat']) : CONST_Default_Lat,
-                       'lon'  => isset($_GET['lon']) ? htmlspecialchars($_GET['lon']) : CONST_Default_Lon,
-                       'tile_url' => $sTileURL,
-                       'tile_attribution' => $sTileAttribution
-               );
-               echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
+        $aNominatimMapInit = array(
+            'zoom' => isset($_GET['zoom']) ? htmlspecialchars($_GET['zoom']) : CONST_Default_Zoom,
+            'lat'  => isset($_GET['lat']) ? htmlspecialchars($_GET['lat']) : CONST_Default_Lat,
+            'lon'  => isset($_GET['lon']) ? htmlspecialchars($_GET['lon']) : CONST_Default_Lon,
+            'tile_url' => $sTileURL,
+            'tile_attribution' => $sTileAttribution
+        );
+        echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
 
-               echo 'var nominatim_results = ' . json_encode([$aPlace], JSON_PRETTY_PRINT) . ';'; 
-       ?>
-       </script>
-       <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
+        echo 'var nominatim_results = ' . json_encode([$aPlace], JSON_PRETTY_PRINT) . ';'; 
+    ?>
+    </script>
+    <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
 
 </body>
 </html>
index bf6c700bf580acaec788671cbf734a8167613db0..9cefe3ef15a6b6effab46118295f95d66c493f28 100644 (file)
@@ -1,55 +1,56 @@
 <?php
-       $aFilteredPlaces = array();
-
-       if (!sizeof($aPlace))
-       {
-               if (isset($sError))
-                       $aFilteredPlaces['error'] = $sError;
-               else
-                       $aFilteredPlaces['error'] = 'Unable to geocode';
-       }
-       else
-       {
-               if (isset($aPlace['place_id'])) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
-               $aFilteredPlaces['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
-               $sOSMType = formatOSMType($aPlace['osm_type']);
-               if ($sOSMType)
-               {
-                       $aFilteredPlaces['osm_type'] = $sOSMType;
-                       $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
-               }
-               if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
-               if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
-               $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
-               if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
-               if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
-               if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
-
-               if (isset($aPlace['aBoundingBox']))
-               {
-                       $aFilteredPlaces['boundingbox'] = $aPlace['aBoundingBox'];
-               }
-
-               if (isset($aPlace['asgeojson']))
-               {
-                       $aFilteredPlaces['geojson'] = json_decode($aPlace['asgeojson']);
-               }
-
-               if (isset($aPlace['assvg']))
-               {
-                       $aFilteredPlaces['svg'] = $aPlace['assvg'];
-               }
-
-               if (isset($aPlace['astext']))
-               {
-                       $aFilteredPlaces['geotext'] = $aPlace['astext'];
-               }
-
-               if (isset($aPlace['askml']))
-               {
-                       $aFilteredPlaces['geokml'] = $aPlace['askml'];
-               }
-       }
-
-       javascript_renderData($aFilteredPlaces);
+
+$aFilteredPlaces = array();
+
+if (!sizeof($aPlace))
+{
+    if (isset($sError))
+        $aFilteredPlaces['error'] = $sError;
+    else
+        $aFilteredPlaces['error'] = 'Unable to geocode';
+}
+else
+{
+    if (isset($aPlace['place_id'])) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
+    $aFilteredPlaces['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
+    $sOSMType = formatOSMType($aPlace['osm_type']);
+    if ($sOSMType)
+    {
+        $aFilteredPlaces['osm_type'] = $sOSMType;
+        $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
+    }
+    if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
+    if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
+    $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
+    if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
+    if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
+    if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
+
+    if (isset($aPlace['aBoundingBox']))
+    {
+        $aFilteredPlaces['boundingbox'] = $aPlace['aBoundingBox'];
+    }
+
+    if (isset($aPlace['asgeojson']))
+    {
+        $aFilteredPlaces['geojson'] = json_decode($aPlace['asgeojson']);
+    }
+
+    if (isset($aPlace['assvg']))
+    {
+        $aFilteredPlaces['svg'] = $aPlace['assvg'];
+    }
+
+    if (isset($aPlace['astext']))
+    {
+        $aFilteredPlaces['geotext'] = $aPlace['astext'];
+    }
+
+    if (isset($aPlace['askml']))
+    {
+        $aFilteredPlaces['geokml'] = $aPlace['askml'];
+    }
+}
+
+javascript_renderData($aFilteredPlaces);
 
index d62141769b89cc33ecc26e19fb6e03d585f95b74..b157ed56d5e75e9e5c27c0904f16170f1067be15 100644 (file)
@@ -1,67 +1,68 @@
 <?php
-       $aFilteredPlaces = array();
 
-       if (!sizeof($aPlace))
-       {
-               if (isset($sError))
-                       $aFilteredPlaces['error'] = $sError;
-               else
-                       $aFilteredPlaces['error'] = 'Unable to geocode';
-       }
-       else
-       {
-               if ($aPlace['place_id']) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
-               $aFilteredPlaces['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
-               $sOSMType = formatOSMType($aPlace['osm_type']);
-               if ($sOSMType)
-               {
-                       $aFilteredPlaces['osm_type'] = $sOSMType;
-                       $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
-               }
-               if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
-               if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
+$aFilteredPlaces = array();
 
-               $aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
+if (!sizeof($aPlace))
+{
+    if (isset($sError))
+        $aFilteredPlaces['error'] = $sError;
+    else
+        $aFilteredPlaces['error'] = 'Unable to geocode';
+}
+else
+{
+    if ($aPlace['place_id']) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
+    $aFilteredPlaces['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
+    $sOSMType = formatOSMType($aPlace['osm_type']);
+    if ($sOSMType)
+    {
+        $aFilteredPlaces['osm_type'] = $sOSMType;
+        $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
+    }
+    if (isset($aPlace['lat'])) $aFilteredPlaces['lat'] = $aPlace['lat'];
+    if (isset($aPlace['lon'])) $aFilteredPlaces['lon'] = $aPlace['lon'];
 
-               $aFilteredPlaces['category'] = $aPlace['class'];
-               $aFilteredPlaces['type'] = $aPlace['type'];
+    $aFilteredPlaces['place_rank'] = $aPlace['rank_search'];
 
-               $aFilteredPlaces['importance'] = $aPlace['importance'];
+    $aFilteredPlaces['category'] = $aPlace['class'];
+    $aFilteredPlaces['type'] = $aPlace['type'];
 
-               $aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
+    $aFilteredPlaces['importance'] = $aPlace['importance'];
 
-               $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
-               $aFilteredPlaces['name'] = $aPlace['placename'];
+    $aFilteredPlaces['addresstype'] = strtolower($aPlace['addresstype']);
 
-               if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
-               if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
-               if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
+    $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
+    $aFilteredPlaces['name'] = $aPlace['placename'];
 
-               if (isset($aPlace['aBoundingBox']))
-               {
-                       $aFilteredPlaces['boundingbox'] = $aPlace['aBoundingBox'];
-               }
+    if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
+    if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
+    if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
 
-               if (isset($aPlace['asgeojson']))
-               {
-                       $aFilteredPlaces['geojson'] = json_decode($aPlace['asgeojson']);
-               }
+    if (isset($aPlace['aBoundingBox']))
+    {
+        $aFilteredPlaces['boundingbox'] = $aPlace['aBoundingBox'];
+    }
 
-               if (isset($aPlace['assvg']))
-               {
-                       $aFilteredPlaces['svg'] = $aPlace['assvg'];
-               }
+    if (isset($aPlace['asgeojson']))
+    {
+        $aFilteredPlaces['geojson'] = json_decode($aPlace['asgeojson']);
+    }
 
-               if (isset($aPlace['astext']))
-               {
-                       $aFilteredPlaces['geotext'] = $aPlace['astext'];
-               }
+    if (isset($aPlace['assvg']))
+    {
+        $aFilteredPlaces['svg'] = $aPlace['assvg'];
+    }
 
-               if (isset($aPlace['askml']))
-               {
-                       $aFilteredPlaces['geokml'] = $aPlace['askml'];
-               }
+    if (isset($aPlace['astext']))
+    {
+        $aFilteredPlaces['geotext'] = $aPlace['astext'];
+    }
 
-       }
+    if (isset($aPlace['askml']))
+    {
+        $aFilteredPlaces['geokml'] = $aPlace['askml'];
+    }
 
-       javascript_renderData($aFilteredPlaces);
+}
+
+javascript_renderData($aFilteredPlaces);
index 2bfcffbf5ac0b3a3d8bb6b0e646e3139b5b90697..d3db2eddaeb04ac376e0535b1499587fc94c7470 100644 (file)
 <?php
-       header("content-type: text/xml; charset=UTF-8");
+header("content-type: text/xml; charset=UTF-8");
 
-       echo "<";
-       echo "?xml version=\"1.0\" encoding=\"UTF-8\" ?";
-       echo ">\n";
+echo "<";
+echo "?xml version=\"1.0\" encoding=\"UTF-8\" ?";
+echo ">\n";
 
-       echo "<reversegeocode";
-       echo " timestamp='".date(DATE_RFC822)."'";
-       echo " attribution='Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'";
-       echo " querystring='".htmlspecialchars($_SERVER['QUERY_STRING'], ENT_QUOTES)."'";
-       echo ">\n";
+echo "<reversegeocode";
+echo " timestamp='".date(DATE_RFC822)."'";
+echo " attribution='Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'";
+echo " querystring='".htmlspecialchars($_SERVER['QUERY_STRING'], ENT_QUOTES)."'";
+echo ">\n";
 
-       if (!sizeof($aPlace))
-       {
-               if (isset($sError))
-                       echo "<error>$sError</error>";
-               else
-                       echo "<error>Unable to geocode</error>";
-       }
-       else
-       {
-               echo "<result";
-               if ($aPlace['place_id']) echo ' place_id="'.$aPlace['place_id'].'"';
-               $sOSMType = formatOSMType($aPlace['osm_type']);
-               if ($sOSMType) echo ' osm_type="'.$sOSMType.'"'.' osm_id="'.$aPlace['osm_id'].'"';
-               if ($aPlace['ref']) echo ' ref="'.htmlspecialchars($aPlace['ref']).'"';
-               if (isset($aPlace['lat'])) echo ' lat="'.htmlspecialchars($aPlace['lat']).'"';
-               if (isset($aPlace['lon'])) echo ' lon="'.htmlspecialchars($aPlace['lon']).'"';
-               if (isset($aPlace['aBoundingBox']))
-               {
-                       echo ' boundingbox="';
-                       echo join(',', $aPlace['aBoundingBox']);
-                       echo '"';
-               }
+if (!sizeof($aPlace))
+{
+    if (isset($sError))
+        echo "<error>$sError</error>";
+    else
+        echo "<error>Unable to geocode</error>";
+}
+else
+{
+    echo "<result";
+    if ($aPlace['place_id']) echo ' place_id="'.$aPlace['place_id'].'"';
+    $sOSMType = formatOSMType($aPlace['osm_type']);
+    if ($sOSMType) echo ' osm_type="'.$sOSMType.'"'.' osm_id="'.$aPlace['osm_id'].'"';
+    if ($aPlace['ref']) echo ' ref="'.htmlspecialchars($aPlace['ref']).'"';
+    if (isset($aPlace['lat'])) echo ' lat="'.htmlspecialchars($aPlace['lat']).'"';
+    if (isset($aPlace['lon'])) echo ' lon="'.htmlspecialchars($aPlace['lon']).'"';
+    if (isset($aPlace['aBoundingBox']))
+    {
+        echo ' boundingbox="';
+        echo join(',', $aPlace['aBoundingBox']);
+        echo '"';
+    }
 
-               if (isset($aPlace['asgeojson']))
-               {
-                       echo ' geojson=\'';
-                       echo $aPlace['asgeojson'];
-                       echo '\'';
-               }
+    if (isset($aPlace['asgeojson']))
+    {
+        echo ' geojson=\'';
+        echo $aPlace['asgeojson'];
+        echo '\'';
+    }
 
-               if (isset($aPlace['assvg']))
-               {
-                       echo ' geosvg=\'';
-                       echo $aPlace['assvg'];
-                       echo '\'';
-               }
+    if (isset($aPlace['assvg']))
+    {
+        echo ' geosvg=\'';
+        echo $aPlace['assvg'];
+        echo '\'';
+    }
 
-               if (isset($aPlace['astext']))
-               {
-                       echo ' geotext=\'';
-                       echo $aPlace['astext'];
-                       echo '\'';
-               }
-               echo ">".htmlspecialchars($aPlace['langaddress'])."</result>";
+    if (isset($aPlace['astext']))
+    {
+        echo ' geotext=\'';
+        echo $aPlace['astext'];
+        echo '\'';
+    }
+    echo ">".htmlspecialchars($aPlace['langaddress'])."</result>";
 
-               if (isset($aPlace['aAddress']))
-               {
-                       echo "<addressparts>";
-                       foreach($aPlace['aAddress'] as $sKey => $sValue)
-                       {
-                               $sKey = str_replace(' ','_',$sKey);
-                               echo "<$sKey>";
-                               echo htmlspecialchars($sValue);
-                               echo "</$sKey>";
-                       }
-                       echo "</addressparts>";
-               }
+    if (isset($aPlace['aAddress']))
+    {
+        echo "<addressparts>";
+        foreach($aPlace['aAddress'] as $sKey => $sValue)
+        {
+            $sKey = str_replace(' ','_',$sKey);
+            echo "<$sKey>";
+            echo htmlspecialchars($sValue);
+            echo "</$sKey>";
+        }
+        echo "</addressparts>";
+    }
 
-               if (isset($aPlace['sExtraTags']))
-               {
-                       echo "<extratags>";
-                       foreach ($aPlace['sExtraTags'] as $sKey => $sValue)
-                       {
-                               echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
-                       }
-                       echo "</extratags>";
-               }
+    if (isset($aPlace['sExtraTags']))
+    {
+        echo "<extratags>";
+        foreach ($aPlace['sExtraTags'] as $sKey => $sValue)
+        {
+            echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
+        }
+        echo "</extratags>";
+    }
 
-               if (isset($aPlace['sNameDetails']))
-               {
-                       echo "<namedetails>";
-                       foreach ($aPlace['sNameDetails'] as $sKey => $sValue)
-                       {
-                               echo '<name desc="'.htmlspecialchars($sKey).'">';
-                               echo htmlspecialchars($sValue);
-                               echo "</name>";
-                       }
-                       echo "</namedetails>";
-               }
+    if (isset($aPlace['sNameDetails']))
+    {
+        echo "<namedetails>";
+        foreach ($aPlace['sNameDetails'] as $sKey => $sValue)
+        {
+            echo '<name desc="'.htmlspecialchars($sKey).'">';
+            echo htmlspecialchars($sValue);
+            echo "</name>";
+        }
+        echo "</namedetails>";
+    }
 
-               if (isset($aPlace['askml']))
-               {
-                       echo "\n<geokml>";
-                       echo $aPlace['askml'];
-                       echo "</geokml>";
-               }
+    if (isset($aPlace['askml']))
+    {
+        echo "\n<geokml>";
+        echo $aPlace['askml'];
+        echo "</geokml>";
+    }
 
-       }
+}
 
-       echo "</reversegeocode>";
+echo "</reversegeocode>";
index bc00f84d6e97d88639722850bfd68ce5e561fa17..0f5ae26db9217cdb53706f07133843c61168a33e 100644 (file)
 <?php
-       header("content-type: text/html; charset=UTF-8");
+    header("content-type: text/html; charset=UTF-8");
 ?>
 <?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
-       <link href="css/common.css" rel="stylesheet" type="text/css" />
-       <link href="css/details.css" rel="stylesheet" type="text/css" />
+    <link href="css/common.css" rel="stylesheet" type="text/css" />
+    <link href="css/details.css" rel="stylesheet" type="text/css" />
 </head>
 
 
 <?php
 
-       function osmMapUrl($aFeature)
-       {
-               if (isset($sFeature['error_x']) && isset($sFeature['error_y']))
-               {
-                       $sBaseUrl = '//www.openstreetmap.org/';
-                       $sOSMType = formatOSMType($aFeature['osm_type'], false);
-                       if ($sOSMType)
-                       {
-                               $sBaseUrl += $sOSMType.'/'.$aFeature['osm_id'];
-                       }
-
-                       return '<a href="'.$sBaseUrl.'?mlat='.$aFeature['error_y'].'&mlon='.$aFeature['error_x'].'">view on osm.org</a>';
-               }
-               return '';
-       }
-
-       function josm_edit_url($aFeature)
-       {
-               $fWidth = 0.0002;
-               $sLon = $aFeature['error_x'];
-               $sLat = $aFeature['error_y'];
-
-               if (isset($sLat))
-               {
-                       return "http://localhost:8111/load_and_zoom?left=".($sLon-$fWidth)."&right=".($sLon+$fWidth)."&top=".($sLat+$fWidth)."&bottom=".($sLat-$fWidth);
-               }
-
-               $sOSMType = formatOSMType($aFeature['osm_type'], false);
-               if ($sOSMType)
-               {
-                       return 'http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/'.$sOSMType.'/'.$aFeature['osm_id'].'/full';
-                       // Should be better to load by object id - but this doesn't seem to zoom correctly
-                       // return " <a href=\"http://localhost:8111/load_object?new_layer=true&objects=".strtolower($aFeature['osm_type']).$sOSMID."\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
-               }
-               return '';
-       }
-
-       function potlach_edit_url($aFeature)
-       {
-               $fWidth = 0.0002;
-               $sLat = $aFeature['error_y'];
-               $sLon = $aFeature['error_x'];
-
-               if (isset($sLat))
-               {
-                       return "//www.openstreetmap.org/edit?editor=potlatch2&bbox=".($sLon-$fWidth).",".($sLat-$fWidth).",".($sLon+$fWidth).",".($sLat+$fWidth);
-               }
-               return '';
-       }
+    function osmMapUrl($aFeature)
+    {
+        if (isset($sFeature['error_x']) && isset($sFeature['error_y']))
+        {
+            $sBaseUrl = '//www.openstreetmap.org/';
+            $sOSMType = formatOSMType($aFeature['osm_type'], false);
+            if ($sOSMType)
+            {
+                $sBaseUrl += $sOSMType.'/'.$aFeature['osm_id'];
+            }
+
+            return '<a href="'.$sBaseUrl.'?mlat='.$aFeature['error_y'].'&mlon='.$aFeature['error_x'].'">view on osm.org</a>';
+        }
+        return '';
+    }
+
+    function josm_edit_url($aFeature)
+    {
+        $fWidth = 0.0002;
+        $sLon = $aFeature['error_x'];
+        $sLat = $aFeature['error_y'];
+
+        if (isset($sLat))
+        {
+            return "http://localhost:8111/load_and_zoom?left=".($sLon-$fWidth)."&right=".($sLon+$fWidth)."&top=".($sLat+$fWidth)."&bottom=".($sLat-$fWidth);
+        }
+
+        $sOSMType = formatOSMType($aFeature['osm_type'], false);
+        if ($sOSMType)
+        {
+            return 'http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/'.$sOSMType.'/'.$aFeature['osm_id'].'/full';
+            // Should be better to load by object id - but this doesn't seem to zoom correctly
+            // return " <a href=\"http://localhost:8111/load_object?new_layer=true&objects=".strtolower($aFeature['osm_type']).$sOSMID."\" target=\"josm\">Remote Control (JOSM / Merkaartor)</a>";
+        }
+        return '';
+    }
+
+    function potlach_edit_url($aFeature)
+    {
+        $fWidth = 0.0002;
+        $sLat = $aFeature['error_y'];
+        $sLon = $aFeature['error_x'];
+
+        if (isset($sLat))
+        {
+            return "//www.openstreetmap.org/edit?editor=potlatch2&bbox=".($sLon-$fWidth).",".($sLat-$fWidth).",".($sLon+$fWidth).",".($sLat+$fWidth);
+        }
+        return '';
+    }
 
 
 
 ?>
 
 <body id="details-page">
-       <div class="container">
-               <div class="row">
-                       <div class="col-md-6">
+    <div class="container">
+        <div class="row">
+            <div class="col-md-6">
 
 
-                               <h1><?php echo $aPointDetails['localname'] ?></h1>
-                               <div class="locationdetails">
-                                       <h2 class="bg-danger">This object has an invalid geometry.</h2>
+                <h1><?php echo $aPointDetails['localname'] ?></h1>
+                <div class="locationdetails">
+                    <h2 class="bg-danger">This object has an invalid geometry.</h2>
 
-                                       <div>
-                                               Type: <span class="type"><?php echo $aPointDetails['class'].':'.$aPointDetails['type'];?></span>
-                                       </div>
+                    <div>
+                        Type: <span class="type"><?php echo $aPointDetails['class'].':'.$aPointDetails['type'];?></span>
+                    </div>
 
-                                       <div>
-                                               OSM: <span class="label"><?php echo osmLink($aPointDetails); ?><span>
-                                       </div>
+                    <div>
+                        OSM: <span class="label"><?php echo osmLink($aPointDetails); ?><span>
+                    </div>
 
 
-                                       <h4>Error</h4>
-                                       <p>
-                                               <?php echo $aPointDetails['errormessage']?$aPointDetails['errormessage']:'unknown'; ?>
-                                       </p>
-                                       <?php echo osmMapUrl($aPointDetails); ?>
+                    <h4>Error</h4>
+                    <p>
+                        <?php echo $aPointDetails['errormessage']?$aPointDetails['errormessage']:'unknown'; ?>
+                    </p>
+                    <?php echo osmMapUrl($aPointDetails); ?>
 
-                                       <h4>Edit</h4>
-                                       <ul>
-                                       <?php if (josm_edit_url($aPointDetails)) { ?>
-                                                       <li><a href="<?php echo josm_edit_url($aPointDetails); ?>" target="josm">Remote Control (JOSM / Merkaartor)</a></li>
-                                       <?php } ?>
-                                       <?php if (potlach_edit_url($aPointDetails)) { ?>
-                                                       <li><a href="<?php echo potlach_edit_url($aPointDetails); ?>" target="potlatch2">Potlatch 2</a></li>
-                                       <?php } ?>
-                                       </ul>
-                       </div>
-               </div>
-               <div class="col-md-6">
-                       <div id="map"></div>
-               </div>
+                    <h4>Edit</h4>
+                    <ul>
+                    <?php if (josm_edit_url($aPointDetails)) { ?>
+                            <li><a href="<?php echo josm_edit_url($aPointDetails); ?>" target="josm">Remote Control (JOSM / Merkaartor)</a></li>
+                    <?php } ?>
+                    <?php if (potlach_edit_url($aPointDetails)) { ?>
+                            <li><a href="<?php echo potlach_edit_url($aPointDetails); ?>" target="potlatch2">Potlatch 2</a></li>
+                    <?php } ?>
+                    </ul>
+            </div>
+        </div>
+        <div class="col-md-6">
+            <div id="map"></div>
+        </div>
 
-       </div>
+    </div>
 
 
-       <script type="text/javascript">
+    <script type="text/javascript">
 
-               var nominatim_result = {
-                       outlinestring: '<?php echo $aPointDetails['outlinestring'];?>',
-                       lon: <?php echo isset($aPointDetails['error_x']) ? $aPointDetails['error_x'] : 0; ?>,
-                       lat: <?php echo isset($aPointDetails['error_y']) ? $aPointDetails['error_y'] : 0; ?>
-               };
+        var nominatim_result = {
+            outlinestring: '<?php echo $aPointDetails['outlinestring'];?>',
+            lon: <?php echo isset($aPointDetails['error_x']) ? $aPointDetails['error_x'] : 0; ?>,
+            lat: <?php echo isset($aPointDetails['error_y']) ? $aPointDetails['error_y'] : 0; ?>
+        };
 
-       </script>
+    </script>
 
 
-       <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
-       </body>
+    <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
+    </body>
 </html>
index 71fcc7b3e0a0aa67c61151ce496e2c5dd02bba10..a1334740e3fffeb9a0042b33255c15cf3d61683c 100644 (file)
 <?php
-       header("content-type: text/html; charset=UTF-8");
+    header("content-type: text/html; charset=UTF-8");
 ?>
 <?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
-       <link href="css/common.css" rel="stylesheet" type="text/css" />
-       <link href="css/details.css" rel="stylesheet" type="text/css" />
+    <link href="css/common.css" rel="stylesheet" type="text/css" />
+    <link href="css/details.css" rel="stylesheet" type="text/css" />
 </head>
 
 
 <?php
 
-       function headline($sTitle)
-       {
-               echo "<tr class='all-columns'><td colspan='6'><h2>".$sTitle."</h2></td></tr>\n";
-       }
-
-       function headline3($sTitle)
-       {
-               echo "<tr class='all-columns'><td colspan='6'><h3>".$sTitle."</h3></td></tr>\n";
-       }
-
-
-       function format_distance($fDistance)
-       {
-               // $fDistance is in meters
-               if ($fDistance < 1)
-               {
-                       return '0';
-               }
-               elseif ($fDistance < 1000)
-               {
-                       return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance,0)).' m</abbr>';
-               }
-               else
-               {
-                       return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance/1000,1)).' km</abbr>';
-               }
-       }
-
-       function kv($sKey,$sValue)
-       {
-               echo ' <tr><td>' . $sKey . '</td><td>'.$sValue.'</td></tr>'. "\n";
-       }
-
-
-       function hash_to_subtable($aAssociatedList)
-       {
-               $sHTML = '';
-               foreach($aAssociatedList as $sKey => $sValue)
-               {
-                       $sHTML = $sHTML.' <div class="line"><span class="name">'.$sValue.'</span> ('.$sKey.')</div>'."\n";
-               }
-               return $sHTML;
-       }
-
-       function map_icon($sIcon)
-       {
-               if ($sIcon){
-                       echo '<img id="mapicon" src="'.CONST_Website_BaseURL.'images/mapicons/'.$sIcon.'.n.32.png'.'" alt="'.$sIcon.'" />';
-               }
-       }
-
-
-       function _one_row($aAddressLine){
-               $bNotUsed = (isset($aAddressLine['isaddress']) && $aAddressLine['isaddress'] == 'f');
-
-               echo '<tr class="' . ($bNotUsed?'notused':'') . '">'."\n";
-               echo '  <td class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>')."</td>\n";
-               echo '  <td>' . $aAddressLine['class'].':'.$aAddressLine['type'] . "</td>\n";
-               echo '  <td>' . osmLink($aAddressLine) . "</td>\n";
-               echo '  <td>' . (isset($aAddressLine['admin_level']) ? $aAddressLine['admin_level'] : '') . "</td>\n";
-               echo '  <td>' . format_distance($aAddressLine['distance'])."</td>\n";
-               echo '  <td>' . detailsLink($aAddressLine,'details &gt;') . "</td>\n";
-               echo "</tr>\n";
-       }
-
-       function _one_keyword_row($keyword_token,$word_id){
-               echo "<tr>\n";
-               echo '<td>';
-               // mark partial tokens (those starting with a space) with a star for readability
-               echo ($keyword_token[0]==' '?'*':'');
-               echo $keyword_token;
-               if (isset($word_id))
-               {
-                       echo '</td><td>word id: '.$word_id;
-               }
-               echo "</td></tr>\n";
-       }
+    function headline($sTitle)
+    {
+        echo "<tr class='all-columns'><td colspan='6'><h2>".$sTitle."</h2></td></tr>\n";
+    }
+
+    function headline3($sTitle)
+    {
+        echo "<tr class='all-columns'><td colspan='6'><h3>".$sTitle."</h3></td></tr>\n";
+    }
+
+
+    function format_distance($fDistance)
+    {
+        // $fDistance is in meters
+        if ($fDistance < 1)
+        {
+            return '0';
+        }
+        elseif ($fDistance < 1000)
+        {
+            return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance,0)).' m</abbr>';
+        }
+        else
+        {
+            return'<abbr class="distance" title="'.$fDistance.'">~'.(round($fDistance/1000,1)).' km</abbr>';
+        }
+    }
+
+    function kv($sKey,$sValue)
+    {
+        echo ' <tr><td>' . $sKey . '</td><td>'.$sValue.'</td></tr>'. "\n";
+    }
+
+
+    function hash_to_subtable($aAssociatedList)
+    {
+        $sHTML = '';
+        foreach($aAssociatedList as $sKey => $sValue)
+        {
+            $sHTML = $sHTML.' <div class="line"><span class="name">'.$sValue.'</span> ('.$sKey.')</div>'."\n";
+        }
+        return $sHTML;
+    }
+
+    function map_icon($sIcon)
+    {
+        if ($sIcon){
+            echo '<img id="mapicon" src="'.CONST_Website_BaseURL.'images/mapicons/'.$sIcon.'.n.32.png'.'" alt="'.$sIcon.'" />';
+        }
+    }
+
+
+    function _one_row($aAddressLine){
+        $bNotUsed = (isset($aAddressLine['isaddress']) && $aAddressLine['isaddress'] == 'f');
+
+        echo '<tr class="' . ($bNotUsed?'notused':'') . '">'."\n";
+        echo '  <td class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>')."</td>\n";
+        echo '  <td>' . $aAddressLine['class'].':'.$aAddressLine['type'] . "</td>\n";
+        echo '  <td>' . osmLink($aAddressLine) . "</td>\n";
+        echo '  <td>' . (isset($aAddressLine['admin_level']) ? $aAddressLine['admin_level'] : '') . "</td>\n";
+        echo '  <td>' . format_distance($aAddressLine['distance'])."</td>\n";
+        echo '  <td>' . detailsLink($aAddressLine,'details &gt;') . "</td>\n";
+        echo "</tr>\n";
+    }
+
+    function _one_keyword_row($keyword_token,$word_id){
+        echo "<tr>\n";
+        echo '<td>';
+        // mark partial tokens (those starting with a space) with a star for readability
+        echo ($keyword_token[0]==' '?'*':'');
+        echo $keyword_token;
+        if (isset($word_id))
+        {
+            echo '</td><td>word id: '.$word_id;
+        }
+        echo "</td></tr>\n";
+    }
 
 ?>
 
 
 
 <body id="details-page">
-       <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
-       <div class="container">
-               <div class="row">
-                       <div class="col-sm-10">
-                               <h1><?php echo $aPointDetails['localname'] ?></h1>
-                       </div>
-                       <div class="col-sm-2 text-right">
-                               <?php map_icon($aPointDetails['icon']) ?>
-                       </div>
-               </div>
-               <div class="row">
-                       <div class="col-md-6">
-                               <table id="locationdetails" class="table table-striped">
-
-                               <?php
-
-                                       kv('Name'            , hash_to_subtable($aPointDetails['aNames']) );
-                                       kv('Type'            , $aPointDetails['class'].':'.$aPointDetails['type'] );
-                                       kv('Last Updated'    , $aPointDetails['indexed_date'] );
-                                       kv('Admin Level'     , $aPointDetails['admin_level'] );
-                                       kv('Rank'            , $aPointDetails['rank_search_label'] );
-                                       if ($aPointDetails['calculated_importance']) {
-                                               kv('Importance'    , $aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)') );
-                                       }
-                                       kv('Coverage'        , ($aPointDetails['isarea']=='t'?'Polygon':'Point') );
-                                       kv('Centre Point'    , $aPointDetails['lat'].','.$aPointDetails['lon'] );
-                                       kv('OSM'             , osmLink($aPointDetails) );
-                                       if ($aPointDetails['wikipedia'])
-                                       {
-                                               kv('Wikipedia Calculated' , wikipediaLink($aPointDetails) );
-                                       }
-
-                                       kv('Extra Tags'      , hash_to_subtable($aPointDetails['aExtraTags']) );
-
-                               ?>
-
-                               </table>
-                       </div>
-
-                       <div class="col-md-6">
-                               <div id="map"></div>
-                       </div>
-
-               </div>
-               <div class="row">
-                       <div class="col-md-12">
-
-                       <h2>Address</h2>
-
-                       <table id="address" class="table table-striped table-responsive">
-                               <thead>
-                                       <tr>
-                                         <td>Local name</td>
-                                         <td>Type</td>
-                                         <td>OSM</td>
-                                         <td>Admin level</td>
-                                         <td>Distance</td>
-                                         <td></td>
-                                       </tr>
-                               </thead>
-                               <tbody>
-
-                               <?php
-
-                                       foreach($aAddressLines as $aAddressLine)
-                                       {       
-                                               _one_row($aAddressLine);
-                                       }
-                               ?>
-       
+    <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
+    <div class="container">
+        <div class="row">
+            <div class="col-sm-10">
+                <h1><?php echo $aPointDetails['localname'] ?></h1>
+            </div>
+            <div class="col-sm-2 text-right">
+                <?php map_icon($aPointDetails['icon']) ?>
+            </div>
+        </div>
+        <div class="row">
+            <div class="col-md-6">
+                <table id="locationdetails" class="table table-striped">
+
+                <?php
+
+                    kv('Name'            , hash_to_subtable($aPointDetails['aNames']) );
+                    kv('Type'            , $aPointDetails['class'].':'.$aPointDetails['type'] );
+                    kv('Last Updated'    , $aPointDetails['indexed_date'] );
+                    kv('Admin Level'     , $aPointDetails['admin_level'] );
+                    kv('Rank'            , $aPointDetails['rank_search_label'] );
+                    if ($aPointDetails['calculated_importance']) {
+                        kv('Importance'    , $aPointDetails['calculated_importance'].($aPointDetails['importance']?'':' (estimated)') );
+                    }
+                    kv('Coverage'        , ($aPointDetails['isarea']=='t'?'Polygon':'Point') );
+                    kv('Centre Point'    , $aPointDetails['lat'].','.$aPointDetails['lon'] );
+                    kv('OSM'             , osmLink($aPointDetails) );
+                    if ($aPointDetails['wikipedia'])
+                    {
+                        kv('Wikipedia Calculated' , wikipediaLink($aPointDetails) );
+                    }
+
+                    kv('Extra Tags'      , hash_to_subtable($aPointDetails['aExtraTags']) );
+
+                ?>
+
+                </table>
+            </div>
+
+            <div class="col-md-6">
+                <div id="map"></div>
+            </div>
+
+        </div>
+        <div class="row">
+            <div class="col-md-12">
+
+            <h2>Address</h2>
+
+            <table id="address" class="table table-striped table-responsive">
+                <thead>
+                    <tr>
+                      <td>Local name</td>
+                      <td>Type</td>
+                      <td>OSM</td>
+                      <td>Admin level</td>
+                      <td>Distance</td>
+                      <td></td>
+                    </tr>
+                </thead>
+                <tbody>
+
+                <?php
+
+                    foreach($aAddressLines as $aAddressLine)
+                    {   
+                        _one_row($aAddressLine);
+                    }
+                ?>
+    
 
 
 <?php
 
-       if ($aLinkedLines)
-       {
-               headline('Linked Places');
-               foreach($aLinkedLines as $aAddressLine)
-               {       
-                       _one_row($aAddressLine);
-               }
-       }
-
-
-
-       if ($aPlaceSearchNameKeywords)
-       {
-               headline('Name Keywords');
-               foreach($aPlaceSearchNameKeywords as $aRow)
-               {
-                       _one_keyword_row($aRow['word_token'], $aRow['word_id']);
-               }
-       }
-
-       if ($aPlaceSearchAddressKeywords)
-       {
-               headline('Address Keywords');
-               foreach($aPlaceSearchAddressKeywords as $aRow)
-               {
-                       _one_keyword_row($aRow['word_token'], $aRow['word_id']);
-               }
-       }
-       
-       if (sizeof($aParentOfLines))
-       {
-               headline('Parent Of');
-
-               $aGroupedAddressLines = array();
-               foreach($aParentOfLines as $aAddressLine)
-               {
-                       if ($aAddressLine['type'] == 'yes') $sType = $aAddressLine['class'];
-                       else $sType = $aAddressLine['type'];
-
-                       if (!isset($aGroupedAddressLines[$sType]))
-                               $aGroupedAddressLines[$sType] = array();
-                       $aGroupedAddressLines[$sType][] = $aAddressLine;
-               }
-               foreach($aGroupedAddressLines as $sGroupHeading => $aParentOfLines)
-               {
-                       $sGroupHeading = ucwords($sGroupHeading);
-                       headline3($sGroupHeading);
-
-                       foreach($aParentOfLines as $aAddressLine)
-                       {
-                               _one_row($aAddressLine);
-                       }
-               }
-               if (sizeof($aParentOfLines) >= 500) {
-                       echo '<p>There are more child objects which are not shown.</p>';
-               }
-       }
-
-       echo "</table>\n";
+    if ($aLinkedLines)
+    {
+        headline('Linked Places');
+        foreach($aLinkedLines as $aAddressLine)
+        {   
+            _one_row($aAddressLine);
+        }
+    }
+
+
+
+    if ($aPlaceSearchNameKeywords)
+    {
+        headline('Name Keywords');
+        foreach($aPlaceSearchNameKeywords as $aRow)
+        {
+            _one_keyword_row($aRow['word_token'], $aRow['word_id']);
+        }
+    }
+
+    if ($aPlaceSearchAddressKeywords)
+    {
+        headline('Address Keywords');
+        foreach($aPlaceSearchAddressKeywords as $aRow)
+        {
+            _one_keyword_row($aRow['word_token'], $aRow['word_id']);
+        }
+    }
+    
+    if (sizeof($aParentOfLines))
+    {
+        headline('Parent Of');
+
+        $aGroupedAddressLines = array();
+        foreach($aParentOfLines as $aAddressLine)
+        {
+            if ($aAddressLine['type'] == 'yes') $sType = $aAddressLine['class'];
+            else $sType = $aAddressLine['type'];
+
+            if (!isset($aGroupedAddressLines[$sType]))
+                $aGroupedAddressLines[$sType] = array();
+            $aGroupedAddressLines[$sType][] = $aAddressLine;
+        }
+        foreach($aGroupedAddressLines as $sGroupHeading => $aParentOfLines)
+        {
+            $sGroupHeading = ucwords($sGroupHeading);
+            headline3($sGroupHeading);
+
+            foreach($aParentOfLines as $aAddressLine)
+            {
+                _one_row($aAddressLine);
+            }
+        }
+        if (sizeof($aParentOfLines) >= 500) {
+            echo '<p>There are more child objects which are not shown.</p>';
+        }
+    }
+
+    echo "</table>\n";
 ?>
 
-                       </div>
-               </div>
-       </div>
+            </div>
+        </div>
+    </div>
 
-       <script type="text/javascript">
-       <?php
+    <script type="text/javascript">
+    <?php
 
-               $aNominatimMapInit = array(
-                 'tile_url' => $sTileURL,
-                 'tile_attribution' => $sTileAttribution
-               );
-               echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
+        $aNominatimMapInit = array(
+          'tile_url' => $sTileURL,
+          'tile_attribution' => $sTileAttribution
+        );
+        echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
 
-               $aPlace = array(
-                               'outlinestring' => $aPointDetails['outlinestring'],
-                               'lon' => $aPointDetails['lon'],
-                               'lat' => $aPointDetails['lat'],
-               );
-               echo 'var nominatim_result = ' . json_encode($aPlace, JSON_PRETTY_PRINT) . ';'; 
+        $aPlace = array(
+                'outlinestring' => $aPointDetails['outlinestring'],
+                'lon' => $aPointDetails['lon'],
+                'lat' => $aPointDetails['lat'],
+        );
+        echo 'var nominatim_result = ' . json_encode($aPlace, JSON_PRETTY_PRINT) . ';'; 
 
 
-       ?>
-       </script>
+    ?>
+    </script>
 
 
 
-       <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
+    <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
 </body>
 </html>
index 3d73b1e47cf81166131939b227f2a8766319d8d3..a38e45dd2e85fa233f60a438b6d95ff24e84f90f 100644 (file)
@@ -1,10 +1,10 @@
 <footer>
-       <p class="disclaimer">
-               Addresses and postcodes are approximate
-       </p>
-       <p class="copyright">
-               &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors
-       </p>
+    <p class="disclaimer">
+        Addresses and postcodes are approximate
+    </p>
+    <p class="copyright">
+        &copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors
+    </p>
 </footer>
 
 <script src="js/jquery.min.js"></script>
index 0832bff3a3a7ba3f8a2abb4daccbaa5d165cd2f5..405efd7f8439ce1a5f6f1a78abf867adf6dd7700 100644 (file)
@@ -1,11 +1,11 @@
 <!DOCTYPE html>
 <html lang="en">
 <head>
-       <title>OpenStreetMap Nominatim: Search</title>
-       <meta name="viewport" content="width=device-width, initial-scale=1">
+    <title>OpenStreetMap Nominatim: Search</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1">
 
-       <base href="<?php echo CONST_Website_BaseURL;?>" />
-       <link href="nominatim.xml" rel="search" title="Nominatim Search" type="application/opensearchdescription+xml" />
-       <link href="css/leaflet.css" rel="stylesheet" />
-       <link href="css/bootstrap-theme.min.css" rel="stylesheet" />
-       <link href="css/bootstrap.min.css" rel="stylesheet" />
+    <base href="<?php echo CONST_Website_BaseURL;?>" />
+    <link href="nominatim.xml" rel="search" title="Nominatim Search" type="application/opensearchdescription+xml" />
+    <link href="css/leaflet.css" rel="stylesheet" />
+    <link href="css/bootstrap-theme.min.css" rel="stylesheet" />
+    <link href="css/bootstrap.min.css" rel="stylesheet" />
index d72fcb7c1c91d1cee1625f8730a299e134ce6ac6..2f539cdb8a5573787a25086e96bfd44638ec8f7f 100644 (file)
@@ -1,49 +1,49 @@
-       <header class="container-fluid">
-               <div class="row">
-                       <div class="col-xs-4">
-                               <div class="brand">
-                                       <a href="<?php echo CONST_Website_BaseURL;?>">
-                                       <img alt="logo" src="images/osm_logo.120px.png" width="30" height="30"/>
-                                       <h1>Nominatim</h1>
-                                       </a>
-                               </div>
-                       </div>
-                       <div id="last-updated" class="col-xs-4 text-center">
-                               <?php if (isset($sDataDate)){ ?>
-                                       Data last updated:
-                                       <br>
-                                       <?php echo $sDataDate; ?>
-                               <?php } ?>
-                       </div>
-                       <div class="col-xs-4 text-right">
-                               <div class="btn-group">
-                                       <button class="dropdown-toggle btn btn-sm btn-default" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
-                                               About &amp; Help <span class="caret"></span>
-                                       </button>
-                                       <ul class="dropdown-menu dropdown-menu-right">
-                                               <li><a href="http://wiki.openstreetmap.org/wiki/Nominatim" target="_blank">Documentation</a></li>
-                                               <li><a href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ" target="_blank">FAQ</a></li>
-                                               <li role="separator" class="divider"></li>
-                                               <li><a href="#" class="" data-toggle="modal" data-target="#report-modal">Report problem with results</a></li>
-                                       </ul>
-                               </div>
-                       </div>
-               </div>
-       </header>
+<header class="container-fluid">
+    <div class="row">
+        <div class="col-xs-4">
+            <div class="brand">
+                <a href="<?php echo CONST_Website_BaseURL;?>">
+                <img alt="logo" src="images/osm_logo.120px.png" width="30" height="30"/>
+                <h1>Nominatim</h1>
+                </a>
+            </div>
+        </div>
+        <div id="last-updated" class="col-xs-4 text-center">
+            <?php if (isset($sDataDate)){ ?>
+                Data last updated:
+                <br>
+                <?php echo $sDataDate; ?>
+            <?php } ?>
+        </div>
+        <div class="col-xs-4 text-right">
+            <div class="btn-group">
+                <button class="dropdown-toggle btn btn-sm btn-default" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
+                    About &amp; Help <span class="caret"></span>
+                </button>
+                <ul class="dropdown-menu dropdown-menu-right">
+                    <li><a href="http://wiki.openstreetmap.org/wiki/Nominatim" target="_blank">Documentation</a></li>
+                    <li><a href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ" target="_blank">FAQ</a></li>
+                    <li role="separator" class="divider"></li>
+                    <li><a href="#" class="" data-toggle="modal" data-target="#report-modal">Report problem with results</a></li>
+                </ul>
+            </div>
+        </div>
+    </div>
+</header>
 
-       <div class="modal fade" id="report-modal">
-               <div class="modal-dialog">
-                       <div class="modal-content">
-                               <div class="modal-header">
-                                       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
-                                       <h4 class="modal-title">Report a problem</h4>
-                               </div>
-                               <div class="modal-body">
-                                       <?php include(CONST_BasePath.'/lib/template/includes/report-errors.php'); ?>
-                               </div>
-                               <div class="modal-footer">
-                                       <button type="button" class="btn btn-default" data-dismiss="modal">OK</button>
-                               </div>
-                       </div>
-               </div>
-       </div>
+<div class="modal fade" id="report-modal">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
+                <h4 class="modal-title">Report a problem</h4>
+            </div>
+            <div class="modal-body">
+                <?php include(CONST_BasePath.'/lib/template/includes/report-errors.php'); ?>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-default" data-dismiss="modal">OK</button>
+            </div>
+        </div>
+    </div>
+</div>
index f6b04e7e9a9236d6d4aa29fe358cf9b14aac49a1..a6a9be62a1afadac5e778ed586fc6bbcbd2d0877 100644 (file)
@@ -1,24 +1,24 @@
 <p>
-       Before reporting problems please read the <a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim">user documentation</a>
-       and
-       <a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ">FAQ</a>.
+    Before reporting problems please read the <a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim">user documentation</a>
+    and
+    <a target="_blank" href="http://wiki.openstreetmap.org/wiki/Nominatim/FAQ">FAQ</a>.
 
-       If your problem relates to the address of a particular search result please use the 'details' link 
-       to check how the address was generated before reporting a problem.
+    If your problem relates to the address of a particular search result please use the 'details' link 
+    to check how the address was generated before reporting a problem.
 </p>
 <p>
-       Use <a target="_blank" href="https://github.com/twain47/nominatim/issues">Nominatim issues on github</a>
-       to report problems.
-<!--   You can search for existing bug reports
-       <a href="http://trac.openstreetmap.org/query?status=new&amp;status=assigned&amp;status=reopened&amp;component=nominatim&amp;order=priority">here</a>.</p>
+    Use <a target="_blank" href="https://github.com/twain47/nominatim/issues">Nominatim issues on github</a>
+    to report problems.
+<!-- You can search for existing bug reports
+    <a href="http://trac.openstreetmap.org/query?status=new&amp;status=assigned&amp;status=reopened&amp;component=nominatim&amp;order=priority">here</a>.</p>
  -->
 </p>
 <p>
-       Please ensure that you include a full description of the problem, including the search
-       query that you used, the problem with the result and, if the problem relates to missing data,
-       the osm type (node, way, relation) and id of the item that is missing.
+    Please ensure that you include a full description of the problem, including the search
+    query that you used, the problem with the result and, if the problem relates to missing data,
+    the osm type (node, way, relation) and id of the item that is missing.
 </p>
 <p>
-       Problems that contain enough detail are likely to get looked at before ones that require
-       significant research.
+    Problems that contain enough detail are likely to get looked at before ones that require
+    significant research.
 </p>
index 60d380418d6f74e86f665173d16a112fe3600b2b..9fa83e2a22c854bb965dc43a2b2a69f7894861f3 100644 (file)
@@ -1,88 +1,88 @@
 <?php
 
-       $aOutput = array();
-       $aOutput['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
-       $aOutput['batch'] = array();
-
-       foreach($aBatchResults as $aSearchResults)
-       {
-               if (!$aSearchResults) $aSearchResults = array();
-               $aFilteredPlaces = array();
-               foreach($aSearchResults as $iResNum => $aPointDetails)
-               {
-                       $aPlace = array(
-                                               'place_id'=>$aPointDetails['place_id'],
-                                       );
-
-                       $sOSMType = formatOSMType($aPointDetails['osm_type']);
-                       if ($sOSMType)
-                       {
-                               $aPlace['osm_type'] = $sOSMType;
-                               $aPlace['osm_id'] = $aPointDetails['osm_id'];
-                       }
-
-                       if (isset($aPointDetails['aBoundingBox']))
-                       {
-                               $aPlace['boundingbox'] = array(
-                                       $aPointDetails['aBoundingBox'][0],
-                                       $aPointDetails['aBoundingBox'][1],
-                                       $aPointDetails['aBoundingBox'][2],
-                                       $aPointDetails['aBoundingBox'][3]);
-
-                               if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
-                               {
-                                       $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
-                               }
-                       }
-
-                       if (isset($aPointDetails['zoom']))
-                       {
-                               $aPlace['zoom'] = $aPointDetails['zoom'];
-                       }
-
-                       $aPlace['lat'] = $aPointDetails['lat'];
-                       $aPlace['lon'] = $aPointDetails['lon'];
-                       $aPlace['display_name'] = $aPointDetails['name'];
-                       $aPlace['place_rank'] = $aPointDetails['rank_search'];
-
-                       $aPlace['category'] = $aPointDetails['class'];
-                       $aPlace['type'] = $aPointDetails['type'];
-
-                       $aPlace['importance'] = $aPointDetails['importance'];
-
-                       if (isset($aPointDetails['icon']))
-                       {
-                               $aPlace['icon'] = $aPointDetails['icon'];
-                       }
-
-                       if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
-                       {
-                               $aPlace['address'] = $aPointDetails['address'];
-                       }
-
-                       if (isset($aPointDetails['asgeojson']))
-                       {
-                               $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-                       }
-
-                       if (isset($aPointDetails['assvg']))
-                       {
-                               $aPlace['svg'] = $aPointDetails['assvg'];
-                       }
-
-                       if (isset($aPointDetails['astext']))
-                       {
-                               $aPlace['geotext'] = $aPointDetails['astext'];
-                       }
-
-                       if (isset($aPointDetails['askml']))
-                       {
-                               $aPlace['geokml'] = $aPointDetails['askml'];
-                       }
-
-                       $aFilteredPlaces[] = $aPlace;
-               }
-               $aOutput['batch'][] = $aFilteredPlaces;
-       }
-
-       javascript_renderData($aOutput, array('geojson'));
+$aOutput = array();
+$aOutput['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
+$aOutput['batch'] = array();
+
+foreach($aBatchResults as $aSearchResults)
+{
+    if (!$aSearchResults) $aSearchResults = array();
+    $aFilteredPlaces = array();
+    foreach($aSearchResults as $iResNum => $aPointDetails)
+    {
+        $aPlace = array(
+                    'place_id'=>$aPointDetails['place_id'],
+                );
+
+        $sOSMType = formatOSMType($aPointDetails['osm_type']);
+        if ($sOSMType)
+        {
+            $aPlace['osm_type'] = $sOSMType;
+            $aPlace['osm_id'] = $aPointDetails['osm_id'];
+        }
+
+        if (isset($aPointDetails['aBoundingBox']))
+        {
+            $aPlace['boundingbox'] = array(
+                $aPointDetails['aBoundingBox'][0],
+                $aPointDetails['aBoundingBox'][1],
+                $aPointDetails['aBoundingBox'][2],
+                $aPointDetails['aBoundingBox'][3]);
+
+            if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
+            {
+                $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
+            }
+        }
+
+        if (isset($aPointDetails['zoom']))
+        {
+            $aPlace['zoom'] = $aPointDetails['zoom'];
+        }
+
+        $aPlace['lat'] = $aPointDetails['lat'];
+        $aPlace['lon'] = $aPointDetails['lon'];
+        $aPlace['display_name'] = $aPointDetails['name'];
+        $aPlace['place_rank'] = $aPointDetails['rank_search'];
+
+        $aPlace['category'] = $aPointDetails['class'];
+        $aPlace['type'] = $aPointDetails['type'];
+
+        $aPlace['importance'] = $aPointDetails['importance'];
+
+        if (isset($aPointDetails['icon']))
+        {
+            $aPlace['icon'] = $aPointDetails['icon'];
+        }
+
+        if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
+        {
+            $aPlace['address'] = $aPointDetails['address'];
+        }
+
+        if (isset($aPointDetails['asgeojson']))
+        {
+            $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
+        }
+
+        if (isset($aPointDetails['assvg']))
+        {
+            $aPlace['svg'] = $aPointDetails['assvg'];
+        }
+
+        if (isset($aPointDetails['astext']))
+        {
+            $aPlace['geotext'] = $aPointDetails['astext'];
+        }
+
+        if (isset($aPointDetails['askml']))
+        {
+            $aPlace['geokml'] = $aPointDetails['askml'];
+        }
+
+        $aFilteredPlaces[] = $aPlace;
+    }
+    $aOutput['batch'][] = $aFilteredPlaces;
+}
+
+javascript_renderData($aOutput, array('geojson'));
index d24eaaae212ebd7c7d84ff1388c80691048799af..58d3dbd7f2f033a9ac42a986a30994e9330b4953 100644 (file)
@@ -1,94 +1,94 @@
 <?php
-       header("content-type: text/html; charset=UTF-8");
+    header("content-type: text/html; charset=UTF-8");
 ?>
 <?php include(CONST_BasePath.'/lib/template/includes/html-header.php'); ?>
-       <link href="css/common.css" rel="stylesheet" type="text/css" />
-       <link href="css/search.css" rel="stylesheet" type="text/css" />
+    <link href="css/common.css" rel="stylesheet" type="text/css" />
+    <link href="css/search.css" rel="stylesheet" type="text/css" />
 </head>
 
 <body id="search-page">
 
-       <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
-
-       <form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>search.php">
-               <div class="form-group">
-                       <input id="q" name="q" type="text" class="form-control input-sm" placeholder="Search" value="<?php echo htmlspecialchars($sQuery); ?>" >
-               </div>
-               <div class="form-group search-button-group">
-                       <button type="submit" class="btn btn-primary btn-sm">Search</button>
-                       <?php if (CONST_Search_AreaPolygons) { ?>
-                               <!-- <input type="checkbox" value="1" name="polygon" <?php if ($bAsText) echo "checked='checked'"; ?>/> Highlight -->
-                               <input type="hidden" value="1" name="polygon" />
-                       <?php } ?>
-                       <input type="hidden" name="viewbox" value="<?php echo $sViewBox; ?>" />
-                       <div class="checkbox-inline">
-                               <label>
-                                       <input type="checkbox" id="use_viewbox" <?php if ($sViewBox) echo "checked='checked'"; ?>>
-                                       apply viewbox
-                               </label>
-                       </div>
-               </div>
-               <div class="search-type-link">
-                       <a href="<?php echo CONST_Website_BaseURL; ?>reverse.php?format=html">reverse search</a>
-               </div>
-       </form>
-
-
-       <div id="content">
+    <?php include(CONST_BasePath.'/lib/template/includes/html-top-navigation.php'); ?>
+
+    <form class="form-inline" role="search" accept-charset="UTF-8" action="<?php echo CONST_Website_BaseURL; ?>search.php">
+        <div class="form-group">
+            <input id="q" name="q" type="text" class="form-control input-sm" placeholder="Search" value="<?php echo htmlspecialchars($sQuery); ?>" >
+        </div>
+        <div class="form-group search-button-group">
+            <button type="submit" class="btn btn-primary btn-sm">Search</button>
+            <?php if (CONST_Search_AreaPolygons) { ?>
+                <!-- <input type="checkbox" value="1" name="polygon" <?php if ($bAsText) echo "checked='checked'"; ?>/> Highlight -->
+                <input type="hidden" value="1" name="polygon" />
+            <?php } ?>
+            <input type="hidden" name="viewbox" value="<?php echo $sViewBox; ?>" />
+            <div class="checkbox-inline">
+                <label>
+                    <input type="checkbox" id="use_viewbox" <?php if ($sViewBox) echo "checked='checked'"; ?>>
+                    apply viewbox
+                </label>
+            </div>
+        </div>
+        <div class="search-type-link">
+            <a href="<?php echo CONST_Website_BaseURL; ?>reverse.php?format=html">reverse search</a>
+        </div>
+    </form>
+
+
+    <div id="content">
 
 <?php if ($sQuery) { ?>
 
-               <div id="searchresults" class="sidebar">
-               <?php
-                       $i = 0;
-                       foreach($aSearchResults as $iResNum => $aResult)
-                       {
-
-                               echo '<div class="result" data-position=' . $i . '>';
-
-                               echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
-                               echo ' <span class="name">'.htmlspecialchars($aResult['name']).'</span>';
-                               // echo ' <span class="latlon">'.round($aResult['lat'],3).','.round($aResult['lon'],3).'</span>';
-                               // echo ' <span class="place_id">'.$aResult['place_id'].'</span>';
-                               if (isset($aResult['label']))
-                                       echo ' <span class="type">('.$aResult['label'].')</span>';
-                               else if ($aResult['type'] == 'yes')
-                                       echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
-                               else
-                                       echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
-                               echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
-                               echo '</div>';
-                               $i = $i+1;
-                       }
-                       if (sizeof($aSearchResults) && $sMoreURL)
-                       {
-                               echo '<div class="more"><a class="btn btn-primary" href="'.htmlentities($sMoreURL).'">Search for more results</a></div>';
-                       }
-                       else
-                       {
-                               echo '<div class="noresults">No search results found</div>';
-                       }
-
-               ?>
-               </div>
+        <div id="searchresults" class="sidebar">
+        <?php
+            $i = 0;
+            foreach($aSearchResults as $iResNum => $aResult)
+            {
+
+                echo '<div class="result" data-position=' . $i . '>';
+
+                echo (isset($aResult['icon'])?'<img alt="icon" src="'.$aResult['icon'].'"/>':'');
+                echo ' <span class="name">'.htmlspecialchars($aResult['name']).'</span>';
+                // echo ' <span class="latlon">'.round($aResult['lat'],3).','.round($aResult['lon'],3).'</span>';
+                // echo ' <span class="place_id">'.$aResult['place_id'].'</span>';
+                if (isset($aResult['label']))
+                    echo ' <span class="type">('.$aResult['label'].')</span>';
+                else if ($aResult['type'] == 'yes')
+                    echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['class'])).')</span>';
+                else
+                    echo ' <span class="type">('.ucwords(str_replace('_',' ',$aResult['type'])).')</span>';
+                echo ' <a class="btn btn-default btn-xs details" href="details.php?place_id='.$aResult['place_id'].'">details</a>';
+                echo '</div>';
+                $i = $i+1;
+            }
+            if (sizeof($aSearchResults) && $sMoreURL)
+            {
+                echo '<div class="more"><a class="btn btn-primary" href="'.htmlentities($sMoreURL).'">Search for more results</a></div>';
+            }
+            else
+            {
+                echo '<div class="noresults">No search results found</div>';
+            }
+
+        ?>
+        </div>
 
 <?php } else { ?>
 
-               <div id="intro" class="sidebar">
-                       <?php include(CONST_BasePath.'/lib/template/includes/introduction.php'); ?>
-               </div>
+        <div id="intro" class="sidebar">
+            <?php include(CONST_BasePath.'/lib/template/includes/introduction.php'); ?>
+        </div>
 
 <?php } ?>
 
-               <div id="map-wrapper">
-                       <div id="map-position">
-                               <div id="map-position-inner"></div>
-                               <div id="map-position-close"><a href="#">hide</a></div>
-                       </div>
-                       <div id="map"></div>
-               </div>
+        <div id="map-wrapper">
+            <div id="map-position">
+                <div id="map-position-inner"></div>
+                <div id="map-position-close"><a href="#">hide</a></div>
+            </div>
+            <div id="map"></div>
+        </div>
 
-       </div> <!-- /content -->
+    </div> <!-- /content -->
 
 
 
 
 
 
-       <script type="text/javascript">
-       <?php
+    <script type="text/javascript">
+    <?php
 
-               $aNominatimMapInit = array(
-                       'zoom' => CONST_Default_Zoom,
-                       'lat' => CONST_Default_Lat,
-                       'lon' => CONST_Default_Lon,
-                       'tile_url' => CONST_Map_Tile_URL,
-                       'tile_attribution' => CONST_Map_Tile_Attribution
-               );
-               echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
+        $aNominatimMapInit = array(
+            'zoom' => CONST_Default_Zoom,
+            'lat' => CONST_Default_Lat,
+            'lon' => CONST_Default_Lon,
+            'tile_url' => CONST_Map_Tile_URL,
+            'tile_attribution' => CONST_Map_Tile_Attribution
+        );
+        echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
 
-               echo 'var nominatim_results = ' . json_encode($aSearchResults, JSON_PRETTY_PRINT) . ';'; 
-       ?>
-       </script>
-       <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
+        echo 'var nominatim_results = ' . json_encode($aSearchResults, JSON_PRETTY_PRINT) . ';'; 
+    ?>
+    </script>
+    <?php include(CONST_BasePath.'/lib/template/includes/html-footer.php'); ?>
 
 </body>
 </html>
index d3dc00f3b505b497eb90f404d770f9ce2e2d0f56..ee2b4bd280b99e0d6df1dd9e45ee27226dde9202 100644 (file)
@@ -1,79 +1,79 @@
 <?php
-       header("content-type: application/json; charset=UTF-8");
-
-       $aFilteredPlaces = array();
-       foreach($aSearchResults as $iResNum => $aPointDetails)
-       {
-               $aPlace = array(
-                               'place_id'=>$aPointDetails['place_id'],
-                               'licence'=>"Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright",
-                       );
-        
-               $sOSMType = formatOSMType($aPointDetails['osm_type']);
-               if ($sOSMType)
-               {
-                       $aPlace['osm_type'] = $sOSMType;
-                       $aPlace['osm_id'] = $aPointDetails['osm_id'];
-               }
-
-               if (isset($aPointDetails['aBoundingBox']))
-               {
-                       $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
-
-                       if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
-                       {
-                               $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
-                       }
-               }
-
-               if (isset($aPointDetails['zoom']))
-               {
-                       $aPlace['zoom'] = $aPointDetails['zoom'];
-               }
-
-               $aPlace['lat'] = $aPointDetails['lat'];
-               $aPlace['lon'] = $aPointDetails['lon'];
-               $aPlace['display_name'] = $aPointDetails['name'];
-
-               $aPlace['class'] = $aPointDetails['class'];
-               $aPlace['type'] = $aPointDetails['type'];
-
-               $aPlace['importance'] = $aPointDetails['importance'];
-
-               if (isset($aPointDetails['icon']) && $aPointDetails['icon'])
-               {
-                       $aPlace['icon'] = $aPointDetails['icon'];
-               }
-
-               if (isset($aPointDetails['address']))
-               {
-                       $aPlace['address'] = $aPointDetails['address'];
-               }
-
-               if (isset($aPointDetails['asgeojson']))
-               {
-                       $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-               }
-
-               if (isset($aPointDetails['assvg']))
-               {
-                       $aPlace['svg'] = $aPointDetails['assvg'];
-               }
-
-               if (isset($aPointDetails['astext']))
-               {
-                       $aPlace['geotext'] = $aPointDetails['astext'];
-               }
-
-               if (isset($aPointDetails['askml']))
-               {
-                       $aPlace['geokml'] = $aPointDetails['askml'];
-               }
-
-               if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
-               if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
-
-               $aFilteredPlaces[] = $aPlace;
-       }
-
-       javascript_renderData($aFilteredPlaces);
+header("content-type: application/json; charset=UTF-8");
+
+$aFilteredPlaces = array();
+foreach($aSearchResults as $iResNum => $aPointDetails)
+{
+    $aPlace = array(
+            'place_id'=>$aPointDetails['place_id'],
+            'licence'=>"Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright",
+        );
+    
+    $sOSMType = formatOSMType($aPointDetails['osm_type']);
+    if ($sOSMType)
+    {
+        $aPlace['osm_type'] = $sOSMType;
+        $aPlace['osm_id'] = $aPointDetails['osm_id'];
+    }
+
+    if (isset($aPointDetails['aBoundingBox']))
+    {
+        $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
+
+        if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
+        {
+            $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
+        }
+    }
+
+    if (isset($aPointDetails['zoom']))
+    {
+        $aPlace['zoom'] = $aPointDetails['zoom'];
+    }
+
+    $aPlace['lat'] = $aPointDetails['lat'];
+    $aPlace['lon'] = $aPointDetails['lon'];
+    $aPlace['display_name'] = $aPointDetails['name'];
+
+    $aPlace['class'] = $aPointDetails['class'];
+    $aPlace['type'] = $aPointDetails['type'];
+
+    $aPlace['importance'] = $aPointDetails['importance'];
+
+    if (isset($aPointDetails['icon']) && $aPointDetails['icon'])
+    {
+        $aPlace['icon'] = $aPointDetails['icon'];
+    }
+
+    if (isset($aPointDetails['address']))
+    {
+        $aPlace['address'] = $aPointDetails['address'];
+    }
+
+    if (isset($aPointDetails['asgeojson']))
+    {
+        $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
+    }
+
+    if (isset($aPointDetails['assvg']))
+    {
+        $aPlace['svg'] = $aPointDetails['assvg'];
+    }
+
+    if (isset($aPointDetails['astext']))
+    {
+        $aPlace['geotext'] = $aPointDetails['astext'];
+    }
+
+    if (isset($aPointDetails['askml']))
+    {
+        $aPlace['geokml'] = $aPointDetails['askml'];
+    }
+
+    if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
+    if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
+
+    $aFilteredPlaces[] = $aPlace;
+}
+
+javascript_renderData($aFilteredPlaces);
index e907a081f206750ac1a7e37de321c796c9de9af8..35538797184808477ae7b96d9f33e7a69bac66bd 100644 (file)
@@ -1,78 +1,79 @@
 <?php
-       $aFilteredPlaces = array();
-       foreach($aSearchResults as $iResNum => $aPointDetails)
-       {
-               $aPlace = array(
-                               'place_id'=>$aPointDetails['place_id'],
-                               'licence'=>"Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright",
-                       );
-
-               $sOSMType = formatOSMType($aPointDetails['osm_type']);
-               if ($sOSMType)
-               {
-                       $aPlace['osm_type'] = $sOSMType;
-                       $aPlace['osm_id'] = $aPointDetails['osm_id'];
-               }
-
-               if (isset($aPointDetails['aBoundingBox']))
-               {
-                       $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
-
-                       if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
-                       {
-                               $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
-                       }
-               }
-
-               if (isset($aPointDetails['zoom']))
-               {
-                       $aPlace['zoom'] = $aPointDetails['zoom'];
-               }
-
-               $aPlace['lat'] = $aPointDetails['lat'];
-               $aPlace['lon'] = $aPointDetails['lon'];
-               $aPlace['display_name'] = $aPointDetails['name'];
-               $aPlace['place_rank'] = $aPointDetails['rank_search'];
-
-               $aPlace['category'] = $aPointDetails['class'];
-               $aPlace['type'] = $aPointDetails['type'];
-
-               $aPlace['importance'] = $aPointDetails['importance'];
-
-               if (isset($aPointDetails['icon']))
-               {
-                       $aPlace['icon'] = $aPointDetails['icon'];
-               }
-
-               if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
-               {
-                       $aPlace['address'] = $aPointDetails['address'];
-               }
-
-               if (isset($aPointDetails['asgeojson']))
-               {
-                       $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-               }
-
-               if (isset($aPointDetails['assvg']))
-               {
-                       $aPlace['svg'] = $aPointDetails['assvg'];
-               }
-
-               if (isset($aPointDetails['astext']))
-               {
-                       $aPlace['geotext'] = $aPointDetails['astext'];
-               }
-
-               if (isset($aPointDetails['askml']))
-               {
-                       $aPlace['geokml'] = $aPointDetails['askml'];
-               }
-
-               if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
-               if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
-
-               $aFilteredPlaces[] = $aPlace;
-       }
-
-       javascript_renderData($aFilteredPlaces);
+
+$aFilteredPlaces = array();
+foreach($aSearchResults as $iResNum => $aPointDetails)
+{
+    $aPlace = array(
+            'place_id'=>$aPointDetails['place_id'],
+            'licence'=>"Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright",
+        );
+
+    $sOSMType = formatOSMType($aPointDetails['osm_type']);
+    if ($sOSMType)
+    {
+        $aPlace['osm_type'] = $sOSMType;
+        $aPlace['osm_id'] = $aPointDetails['osm_id'];
+    }
+
+    if (isset($aPointDetails['aBoundingBox']))
+    {
+        $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
+
+        if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
+        {
+            $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
+        }
+    }
+
+    if (isset($aPointDetails['zoom']))
+    {
+        $aPlace['zoom'] = $aPointDetails['zoom'];
+    }
+
+    $aPlace['lat'] = $aPointDetails['lat'];
+    $aPlace['lon'] = $aPointDetails['lon'];
+    $aPlace['display_name'] = $aPointDetails['name'];
+    $aPlace['place_rank'] = $aPointDetails['rank_search'];
+
+    $aPlace['category'] = $aPointDetails['class'];
+    $aPlace['type'] = $aPointDetails['type'];
+
+    $aPlace['importance'] = $aPointDetails['importance'];
+
+    if (isset($aPointDetails['icon']))
+    {
+        $aPlace['icon'] = $aPointDetails['icon'];
+    }
+
+    if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
+    {
+        $aPlace['address'] = $aPointDetails['address'];
+    }
+
+    if (isset($aPointDetails['asgeojson']))
+    {
+        $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
+    }
+
+    if (isset($aPointDetails['assvg']))
+    {
+        $aPlace['svg'] = $aPointDetails['assvg'];
+    }
+
+    if (isset($aPointDetails['astext']))
+    {
+        $aPlace['geotext'] = $aPointDetails['astext'];
+    }
+
+    if (isset($aPointDetails['askml']))
+    {
+        $aPlace['geokml'] = $aPointDetails['askml'];
+    }
+
+    if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
+    if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
+
+    $aFilteredPlaces[] = $aPlace;
+}
+
+javascript_renderData($aFilteredPlaces);
index 7a5c997fddd1b35b222871b7cd160fdca161c0e3..80091b0aeedecc123c4ab0e3d4f7c2a2bacd7aed 100644 (file)
 <?php
-       header("content-type: text/xml; charset=UTF-8");
-
-       echo "<";
-       echo "?xml version=\"1.0\" encoding=\"UTF-8\" ?";
-       echo ">\n";
-
-       echo "<";
-       echo (isset($sXmlRootTag)?$sXmlRootTag:'searchresults');
-       echo " timestamp='".date(DATE_RFC822)."'";
-       echo " attribution='Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'";
-       echo " querystring='".htmlspecialchars($sQuery, ENT_QUOTES)."'";
-       if ($sViewBox) echo " viewbox='".htmlspecialchars($sViewBox, ENT_QUOTES)."'";
-       echo " polygon='".($bShowPolygons?'true':'false')."'";
-       if (sizeof($aExcludePlaceIDs))
-       {
-               echo " exclude_place_ids='".htmlspecialchars(join(',',$aExcludePlaceIDs))."'";
-       }
-       if ($sMoreURL)
-       {
-               echo " more_url='".htmlspecialchars($sMoreURL)."'";
-       }
-       echo ">\n";
-
-       foreach($aSearchResults as $iResNum => $aResult)
-       {
-               echo "<place place_id='".$aResult['place_id']."'";
-               $sOSMType = formatOSMType($aResult['osm_type']);
-               if ($sOSMType)
-               {
-                       echo " osm_type='$sOSMType'";
-                       echo " osm_id='".$aResult['osm_id']."'";
-               }
-               echo " place_rank='".$aResult['rank_search']."'";
-
-               if (isset($aResult['aBoundingBox']))
-               {
-                       echo ' boundingbox="';
-                       echo join(',',$aResult['aBoundingBox']);
-                       echo '"';
-
-                       if ($bShowPolygons && isset($aResult['aPolyPoints']))
-                       {
-                               echo ' polygonpoints=\'';
-                               echo json_encode($aResult['aPolyPoints']);
-                               echo '\'';
-                       }
-               }
-
-               if (isset($aResult['asgeojson']))
-               {
-                       echo ' geojson=\'';
-                       echo $aResult['asgeojson'];
-                       echo '\'';
-               }
-
-               if (isset($aResult['assvg']))
-               {
-                       echo ' geosvg=\'';
-                       echo $aResult['assvg'];
-                       echo '\'';
-               }
-
-               if (isset($aResult['astext']))
-               {
-                       echo ' geotext=\'';
-                       echo $aResult['astext'];
-                       echo '\'';
-               }
-
-               if (isset($aResult['zoom']))
-               {
-                       echo " zoom='".$aResult['zoom']."'";
-               }
-
-               echo " lat='".$aResult['lat']."'";
-               echo " lon='".$aResult['lon']."'";
-               echo " display_name='".htmlspecialchars($aResult['name'], ENT_QUOTES)."'";
-
-               echo " class='".htmlspecialchars($aResult['class'])."'";
-               echo " type='".htmlspecialchars($aResult['type'], ENT_QUOTES)."'";
-               echo " importance='".htmlspecialchars($aResult['importance'])."'";
-               if (isset($aResult['icon']) && $aResult['icon'])
-               {
-                       echo " icon='".htmlspecialchars($aResult['icon'], ENT_QUOTES)."'";
-               }
-
-               $bHasDelim = false;
-
-               if (isset($aResult['askml']))
-               {
-                       if (!$bHasDelim)
-                       {
-                               $bHasDelim = true;
-                               echo ">";
-                       }
-                       echo "\n<geokml>";
-                       echo $aResult['askml'];
-                       echo "</geokml>";
-               }
-
-               if (isset($aResult['sExtraTags']))
-               {
-                       if (!$bHasDelim)
-                       {
-                               $bHasDelim = true;
-                               echo ">";
-                       }
-                       echo "\n<extratags>";
-                       foreach ($aResult['sExtraTags'] as $sKey => $sValue)
-                       {
-                               echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
-                       }
-                       echo "</extratags>";
-               }
-
-               if (isset($aResult['sNameDetails']))
-               {
-                       if (!$bHasDelim)
-                       {
-                               $bHasDelim = true;
-                               echo ">";
-                       }
-                       echo "\n<namedetails>";
-                       foreach ($aResult['sNameDetails'] as $sKey => $sValue)
-                       {
-                               echo '<name desc="'.htmlspecialchars($sKey).'">';
-                               echo htmlspecialchars($sValue);
-                               echo "</name>";
-                       }
-                       echo "</namedetails>";
-               }
-
-               if (isset($aResult['address']))
-               {
-                       if (!$bHasDelim)
-                       {
-                               $bHasDelim = true;
-                               echo ">";
-                       }
-                       echo "\n";
-                       foreach($aResult['address'] as $sKey => $sValue)
-                       {
-                               $sKey = str_replace(' ','_',$sKey);
-                               echo "<$sKey>";
-                               echo htmlspecialchars($sValue);
-                               echo "</$sKey>";
-                       }
-               }
-
-               if ($bHasDelim)
-               {
-                       echo "</place>";
-               }
-               else
-               {
-                       echo "/>";
-               }
-       }
-       
-       echo "</" . (isset($sXmlRootTag)?$sXmlRootTag:'searchresults') . ">";
+header("content-type: text/xml; charset=UTF-8");
+
+echo "<";
+echo "?xml version=\"1.0\" encoding=\"UTF-8\" ?";
+echo ">\n";
+
+echo "<";
+echo (isset($sXmlRootTag)?$sXmlRootTag:'searchresults');
+echo " timestamp='".date(DATE_RFC822)."'";
+echo " attribution='Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright'";
+echo " querystring='".htmlspecialchars($sQuery, ENT_QUOTES)."'";
+if ($sViewBox) echo " viewbox='".htmlspecialchars($sViewBox, ENT_QUOTES)."'";
+echo " polygon='".($bShowPolygons?'true':'false')."'";
+if (sizeof($aExcludePlaceIDs))
+{
+    echo " exclude_place_ids='".htmlspecialchars(join(',',$aExcludePlaceIDs))."'";
+}
+if ($sMoreURL)
+{
+    echo " more_url='".htmlspecialchars($sMoreURL)."'";
+}
+echo ">\n";
+
+foreach($aSearchResults as $iResNum => $aResult)
+{
+    echo "<place place_id='".$aResult['place_id']."'";
+    $sOSMType = formatOSMType($aResult['osm_type']);
+    if ($sOSMType)
+    {
+        echo " osm_type='$sOSMType'";
+        echo " osm_id='".$aResult['osm_id']."'";
+    }
+    echo " place_rank='".$aResult['rank_search']."'";
+
+    if (isset($aResult['aBoundingBox']))
+    {
+        echo ' boundingbox="';
+        echo join(',',$aResult['aBoundingBox']);
+        echo '"';
+
+        if ($bShowPolygons && isset($aResult['aPolyPoints']))
+        {
+            echo ' polygonpoints=\'';
+            echo json_encode($aResult['aPolyPoints']);
+            echo '\'';
+        }
+    }
+
+    if (isset($aResult['asgeojson']))
+    {
+        echo ' geojson=\'';
+        echo $aResult['asgeojson'];
+        echo '\'';
+    }
+
+    if (isset($aResult['assvg']))
+    {
+        echo ' geosvg=\'';
+        echo $aResult['assvg'];
+        echo '\'';
+    }
+
+    if (isset($aResult['astext']))
+    {
+        echo ' geotext=\'';
+        echo $aResult['astext'];
+        echo '\'';
+    }
+
+    if (isset($aResult['zoom']))
+    {
+        echo " zoom='".$aResult['zoom']."'";
+    }
+
+    echo " lat='".$aResult['lat']."'";
+    echo " lon='".$aResult['lon']."'";
+    echo " display_name='".htmlspecialchars($aResult['name'], ENT_QUOTES)."'";
+
+    echo " class='".htmlspecialchars($aResult['class'])."'";
+    echo " type='".htmlspecialchars($aResult['type'], ENT_QUOTES)."'";
+    echo " importance='".htmlspecialchars($aResult['importance'])."'";
+    if (isset($aResult['icon']) && $aResult['icon'])
+    {
+        echo " icon='".htmlspecialchars($aResult['icon'], ENT_QUOTES)."'";
+    }
+
+    $bHasDelim = false;
+
+    if (isset($aResult['askml']))
+    {
+        if (!$bHasDelim)
+        {
+            $bHasDelim = true;
+            echo ">";
+        }
+        echo "\n<geokml>";
+        echo $aResult['askml'];
+        echo "</geokml>";
+    }
+
+    if (isset($aResult['sExtraTags']))
+    {
+        if (!$bHasDelim)
+        {
+            $bHasDelim = true;
+            echo ">";
+        }
+        echo "\n<extratags>";
+        foreach ($aResult['sExtraTags'] as $sKey => $sValue)
+        {
+            echo '<tag key="'.htmlspecialchars($sKey).'" value="'.htmlspecialchars($sValue).'"/>';
+        }
+        echo "</extratags>";
+    }
+
+    if (isset($aResult['sNameDetails']))
+    {
+        if (!$bHasDelim)
+        {
+            $bHasDelim = true;
+            echo ">";
+        }
+        echo "\n<namedetails>";
+        foreach ($aResult['sNameDetails'] as $sKey => $sValue)
+        {
+            echo '<name desc="'.htmlspecialchars($sKey).'">';
+            echo htmlspecialchars($sValue);
+            echo "</name>";
+        }
+        echo "</namedetails>";
+    }
+
+    if (isset($aResult['address']))
+    {
+        if (!$bHasDelim)
+        {
+            $bHasDelim = true;
+            echo ">";
+        }
+        echo "\n";
+        foreach($aResult['address'] as $sKey => $sValue)
+        {
+            $sKey = str_replace(' ','_',$sKey);
+            echo "<$sKey>";
+            echo htmlspecialchars($sValue);
+            echo "</$sKey>";
+        }
+    }
+
+    if ($bHasDelim)
+    {
+        echo "</place>";
+    }
+    else
+    {
+        echo "/>";
+    }
+}
+
+echo "</" . (isset($sXmlRootTag)?$sXmlRootTag:'searchresults') . ">";
index cdb02924a6c0dcfa9d76dce4f2e978dc3b36205d..4f8d58c5b66903f7857d6116c3e40ff991e15f9e 100644 (file)
 <?php
-       @define('CONST_BasePath', '@CMAKE_SOURCE_DIR@');
-       @define('CONST_InstallPath', '@CMAKE_BINARY_DIR@');
-       if (file_exists(getenv('NOMINATIM_SETTINGS'))) require_once(getenv('NOMINATIM_SETTINGS'));
-       if (file_exists(CONST_InstallPath.'/settings/local.php')) require_once(CONST_InstallPath.'/settings/local.php');
-       if (isset($_GET['debug']) && $_GET['debug']) @define('CONST_Debug', true);
-
-       // General settings
-       @define('CONST_Debug', false);
-       @define('CONST_Database_DSN', 'pgsql://@/nominatim'); // <driver>://<username>:<password>@<host>:<port>/<database>
-       @define('CONST_Database_Web_User', 'www-data');
-       @define('CONST_Max_Word_Frequency', '50000');
-       @define('CONST_Limit_Reindexing', true);
-       // Set to false to avoid importing extra postcodes for the US.
-       @define('CONST_Use_Extra_US_Postcodes', true);
-       // Set to true after importing Tiger house number data for the US.
-       // Note: The tables must already exist or queries will throw errors.
-       //       After changing this setting run ./utils/setup --create-functions
-       //       again.
-       @define('CONST_Use_US_Tiger_Data', false);
-       // Set to true after importing other external house number data.
-       // Note: the aux tables must already exist or queries will throw errors.
-       //       After changing this setting run ./utils/setup --create-functions
-       //       again.
-       @define('CONST_Use_Aux_Location_data', false);
-
-       // Proxy settings
-       @define('CONST_HTTP_Proxy', false);
-       @define('CONST_HTTP_Proxy_Host', 'proxy.mydomain.com');
-       @define('CONST_HTTP_Proxy_Port', '3128');
-       @define('CONST_HTTP_Proxy_Login', '');
-       @define('CONST_HTTP_Proxy_Password', '');
-
-       // Paths
-       @define('CONST_Osm2pgsql_Binary', CONST_InstallPath.'/osm2pgsql/osm2pgsql');
-       @define('CONST_Osmosis_Binary', '/usr/bin/osmosis');
-       @define('CONST_Tiger_Data_Path', CONST_BasePath.'/data/tiger');
-
-       // osm2pgsql settings
-       @define('CONST_Osm2pgsql_Flatnode_File', null);
-
-       // tablespace settings
-       // osm2pgsql caching tables (aka slim mode tables) - update only
-       @define('CONST_Tablespace_Osm2pgsql_Data', false);
-       @define('CONST_Tablespace_Osm2pgsql_Index', false);
-       // osm2pgsql output tables (aka main table) - update only
-       @define('CONST_Tablespace_Place_Data', false);
-       @define('CONST_Tablespace_Place_Index', false);
-       // address computation tables - update only
-       @define('CONST_Tablespace_Address_Data', false);
-       @define('CONST_Tablespace_Address_Index', false);
-       // search tables - needed for lookups
-       @define('CONST_Tablespace_Search_Data', false);
-       @define('CONST_Tablespace_Search_Index', false);
-       // additional data, e.g. TIGER data, type searches - needed for lookups
-       @define('CONST_Tablespace_Aux_Data', false);
-       @define('CONST_Tablespace_Aux_Index', false);
-
-       // Replication settings
-       @define('CONST_Replication_Url', 'http://planet.openstreetmap.org/replication/minute');
-       @define('CONST_Replication_MaxInterval', '3600');
-       @define('CONST_Replication_Update_Interval', '60');  // How often upstream publishes diffs
-       @define('CONST_Replication_Recheck_Interval', '60'); // How long to sleep if no update found yet
-
-       // Website settings
-       @define('CONST_NoAccessControl', true);
-
-       @define('CONST_Website_BaseURL', 'http://'.php_uname('n').'/');
-       // Language to assume when none is supplied with the query.
-       // When set to false, the local language (i.e. the name tag without suffix)
-       // will be used.
-       @define('CONST_Default_Language', false);
-       // Appearance of the map in the debug interface.
-       @define('CONST_Default_Lat', 20.0);
-       @define('CONST_Default_Lon', 0.0);
-       @define('CONST_Default_Zoom', 2);
-       @define('CONST_Map_Tile_URL', 'http://{s}.tile.osm.org/{z}/{x}/{y}.png');
-       @define('CONST_Map_Tile_Attribution', ''); // Set if tile source isn't osm.org
-
-       @define('CONST_Search_AreaPolygons', true);
-
-       @define('CONST_Search_BatchMode', false);
-
-       @define('CONST_Search_TryDroppedAddressTerms', false);
-       @define('CONST_Search_NameOnlySearchFrequencyThreshold', 500);
-       // If set to true, then reverse order of queries will be tried by default.
-       // When set to false only selected languages alloow reverse search.
-       @define('CONST_Search_ReversePlanForAll', true);
-
-       // Maximum number of OSM ids that may be queried at once
-       // for the places endpoint.
-       @define('CONST_Places_Max_ID_count', 50); 
-
-       // Number of different geometry formats that may be queried in parallel.
-       // Set to zero to disable polygon output.
-       @define('CONST_PolygonOutput_MaximumTypes', 1);
-
-       // Log settings
-       // Set to true to log into new_query_log table.
-       // You should set up a cron job that regularly clears out this table.
-       @define('CONST_Log_DB', false);
-       // Set to a file name to enable logging to a file.
-       @define('CONST_Log_File', false);
-
+@define('CONST_BasePath', '@CMAKE_SOURCE_DIR@');
+@define('CONST_InstallPath', '@CMAKE_BINARY_DIR@');
+if (file_exists(getenv('NOMINATIM_SETTINGS'))) require_once(getenv('NOMINATIM_SETTINGS'));
+if (file_exists(CONST_InstallPath.'/settings/local.php')) require_once(CONST_InstallPath.'/settings/local.php');
+if (isset($_GET['debug']) && $_GET['debug']) @define('CONST_Debug', true);
+
+// General settings
+@define('CONST_Debug', false);
+@define('CONST_Database_DSN', 'pgsql://@/nominatim'); // <driver>://<username>:<password>@<host>:<port>/<database>
+@define('CONST_Database_Web_User', 'www-data');
+@define('CONST_Max_Word_Frequency', '50000');
+@define('CONST_Limit_Reindexing', true);
+// Set to false to avoid importing extra postcodes for the US.
+@define('CONST_Use_Extra_US_Postcodes', true);
+// Set to true after importing Tiger house number data for the US.
+// Note: The tables must already exist or queries will throw errors.
+//       After changing this setting run ./utils/setup --create-functions
+//       again.
+@define('CONST_Use_US_Tiger_Data', false);
+// Set to true after importing other external house number data.
+// Note: the aux tables must already exist or queries will throw errors.
+//       After changing this setting run ./utils/setup --create-functions
+//       again.
+@define('CONST_Use_Aux_Location_data', false);
+
+// Proxy settings
+@define('CONST_HTTP_Proxy', false);
+@define('CONST_HTTP_Proxy_Host', 'proxy.mydomain.com');
+@define('CONST_HTTP_Proxy_Port', '3128');
+@define('CONST_HTTP_Proxy_Login', '');
+@define('CONST_HTTP_Proxy_Password', '');
+
+// Paths
+@define('CONST_Osm2pgsql_Binary', CONST_InstallPath.'/osm2pgsql/osm2pgsql');
+@define('CONST_Osmosis_Binary', '/usr/bin/osmosis');
+@define('CONST_Tiger_Data_Path', CONST_BasePath.'/data/tiger');
+
+// osm2pgsql settings
+@define('CONST_Osm2pgsql_Flatnode_File', null);
+
+// tablespace settings
+// osm2pgsql caching tables (aka slim mode tables) - update only
+@define('CONST_Tablespace_Osm2pgsql_Data', false);
+@define('CONST_Tablespace_Osm2pgsql_Index', false);
+// osm2pgsql output tables (aka main table) - update only
+@define('CONST_Tablespace_Place_Data', false);
+@define('CONST_Tablespace_Place_Index', false);
+// address computation tables - update only
+@define('CONST_Tablespace_Address_Data', false);
+@define('CONST_Tablespace_Address_Index', false);
+// search tables - needed for lookups
+@define('CONST_Tablespace_Search_Data', false);
+@define('CONST_Tablespace_Search_Index', false);
+// additional data, e.g. TIGER data, type searches - needed for lookups
+@define('CONST_Tablespace_Aux_Data', false);
+@define('CONST_Tablespace_Aux_Index', false);
+
+// Replication settings
+@define('CONST_Replication_Url', 'http://planet.openstreetmap.org/replication/minute');
+@define('CONST_Replication_MaxInterval', '3600');
+@define('CONST_Replication_Update_Interval', '60');  // How often upstream publishes diffs
+@define('CONST_Replication_Recheck_Interval', '60'); // How long to sleep if no update found yet
+
+// Website settings
+@define('CONST_NoAccessControl', true);
+
+@define('CONST_Website_BaseURL', 'http://'.php_uname('n').'/');
+// Language to assume when none is supplied with the query.
+// When set to false, the local language (i.e. the name tag without suffix)
+// will be used.
+@define('CONST_Default_Language', false);
+// Appearance of the map in the debug interface.
+@define('CONST_Default_Lat', 20.0);
+@define('CONST_Default_Lon', 0.0);
+@define('CONST_Default_Zoom', 2);
+@define('CONST_Map_Tile_URL', 'http://{s}.tile.osm.org/{z}/{x}/{y}.png');
+@define('CONST_Map_Tile_Attribution', ''); // Set if tile source isn't osm.org
+
+@define('CONST_Search_AreaPolygons', true);
+
+@define('CONST_Search_BatchMode', false);
+
+@define('CONST_Search_TryDroppedAddressTerms', false);
+@define('CONST_Search_NameOnlySearchFrequencyThreshold', 500);
+// If set to true, then reverse order of queries will be tried by default.
+// When set to false only selected languages alloow reverse search.
+@define('CONST_Search_ReversePlanForAll', true);
+
+// Maximum number of OSM ids that may be queried at once
+// for the places endpoint.
+@define('CONST_Places_Max_ID_count', 50); 
+
+// Number of different geometry formats that may be queried in parallel.
+// Set to zero to disable polygon output.
+@define('CONST_PolygonOutput_MaximumTypes', 1);
+
+// Log settings
+// Set to true to log into new_query_log table.
+// You should set up a cron job that regularly clears out this table.
+@define('CONST_Log_DB', false);
+// Set to a file name to enable logging to a file.
+@define('CONST_Log_File', false);
 
index 2e199ada0ffffe718934da125d297ef6f87ab330..a3447cc384b2e3270f19d7321105354b4c50309e 100644 (file)
@@ -3,49 +3,49 @@
 
 # Languages to download the special phrases for.
 $aLanguageIn = array(
-                       'af',
-                       'ar',
-                       'br',
-                       'ca',
-                       'cs',
-                       'de',
-                       'en',
-                       'es',
-                       'et',
-                       'eu',
-                       'fa',
-                       'fi',
-                       'fr',
-                       'gl',
-                       'hr',
-                       'hu',
-                       'ia',
-                       'is',
-                       'it',
-                       'ja',
-                       'mk',
-                       'nl',
-                       'no',
-                       'pl',
-                       'ps',
-                       'pt',
-                       'ru',
-                       'sk',
-                       'sv',
-                       'uk',
-                       'vi',
-               );
+                    'af',
+                    'ar',
+                    'br',
+                    'ca',
+                    'cs',
+                    'de',
+                    'en',
+                    'es',
+                    'et',
+                    'eu',
+                    'fa',
+                    'fi',
+                    'fr',
+                    'gl',
+                    'hr',
+                    'hu',
+                    'ia',
+                    'is',
+                    'it',
+                    'ja',
+                    'mk',
+                    'nl',
+                    'no',
+                    'pl',
+                    'ps',
+                    'pt',
+                    'ru',
+                    'sk',
+                    'sv',
+                    'uk',
+                    'vi',
+                );
 
 # class/type combinations to exclude
 $aTagsBlacklist = array(
-       'boundary' => array('administrative'),
-       'place' => array('house', 'houses'),
+    'boundary' => array('administrative'),
+    'place' => array('house', 'houses'),
 );
 # If a class is in the white list then all types will 
 # be ignored except the ones given in the list.
 # Also use this list to exclude an entire class from
 # special phrases.
 $aTagsWhitelist = array(
-       'highway' => array('bus_stop', 'rest_area', 'raceway'),
-       'building' => array(),
+    'highway' => array('bus_stop', 'rest_area', 'raceway'),
+    'building' => array(),
 );
index 3475ae7b309b0ba909146e62e28a3add5aef2b30..fcfc82950e6c21d196bb9517469e2e61837a85bf 100644 (file)
@@ -1,4 +1,5 @@
 <?php
-       echo "ERROR: Scripts must be run from build directory.\n";
-       exit;
+
+echo "ERROR: Scripts must be run from build directory.\n";
+exit;
 
index 00fdc132cd77c32ef8e29310d1646b890a79f5f0..4f27c41e3225feb3f3f8f5cdf4a7dbcf17a757ee 100644 (file)
@@ -7,255 +7,255 @@ require '../lib/lib.php';
 class NominatimTest extends \PHPUnit_Framework_TestCase
 {
 
-       protected function setUp()
-       {
-       }
-
-
-       public function test_getClassTypesWithImportance()
-       {
-               $aClasses = getClassTypesWithImportance();
-
-               $this->assertGreaterThan(
-                       200,
-                       count($aClasses)
-               );
-
-               $this->assertEquals(
-                       array(
-                               'label' => "Country",
-                               'frequency' => 0,
-                               'icon' => "poi_boundary_administrative",
-                               'defzoom' => 6,
-                               'defdiameter' => 15,
-                               'importance' => 3
-                       ),
-                       $aClasses['place:country']
-               );
-       }
-
-
-       public function test_getResultDiameter()
-       {
-               $aResult = array();
-               $this->assertEquals(
-                       0.0001,
-                       getResultDiameter($aResult)
-               );
-
-               $aResult = array('class' => 'place', 'type' => 'country');
-               $this->assertEquals(
-                       15,
-                       getResultDiameter($aResult)
-               );
-
-               $aResult = array('class' => 'boundary', 'type' => 'administrative', 'admin_level' => 6);
-               $this->assertEquals(
-                       0.32,
-                       getResultDiameter($aResult)
-               );
-       }
-
-
-       public function test_addQuotes()
-       {
-               // FIXME: not quoting existing quote signs is probably a bug
-               $this->assertSame("'St. John's'", addQuotes("St. John's"));
-               $this->assertSame("''", addQuotes(''));
-       }
-
-       public function test_looksLikeLatLonPair()
-       {
-               // no coordinates expected
-               $this->assertNull(looksLikeLatLonPair(''));
-               $this->assertNull(looksLikeLatLonPair('abc'));
-               $this->assertNull(looksLikeLatLonPair('12 34'));
-               $this->assertNull(looksLikeLatLonPair('200.1 89.9')); // because latitude > 180
-
-               // coordinates expected
-               $this->assertNotNull(looksLikeLatLonPair('0.0 -0.0'));
-
-               $this->assertEquals(
-                               array( 'lat' => 12.456, 'lon' => -78.90, 'query' => 'abc   def'),
-                               looksLikeLatLonPair(' abc 12.456 -78.90 def ')
-                       );
-
-               $this->assertEquals(
-                               array( 'lat' => 12.456, 'lon' => -78.90, 'query' => ''),
-                               looksLikeLatLonPair(' [12.456,-78.90] ')
-                       );
-
-               // http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
-               // these all represent the same location
-               $aQueries = array(
-                                       '40 26.767 N 79 58.933 W',
-                                       '40° 26.767′ N 79° 58.933′ W',
-                                       "40° 26.767' N 79° 58.933' W",
-                                       'N 40 26.767, W 79 58.933',
-                                       'N 40°26.767′, W 79°58.933′',
-                                       "N 40°26.767', W 79°58.933'",
-
-                                       '40 26 46 N 79 58 56 W',
-                                       '40° 26′ 46″ N 79° 58′ 56″ W',
-                                       'N 40 26 46 W 79 58 56',
-                                       'N 40° 26′ 46″, W 79° 58′ 56″',
-                                       'N 40° 26\' 46", W 79° 58\' 56"',
-
-                                       '40.446 -79.982',
-                                       '40.446,-79.982',
-                                       '40.446° N 79.982° W',
-                                       'N 40.446° W 79.982°',
-
-                                       '[40.446 -79.982]',
-                                       '       40.446  ,   -79.982     ',
-               );
-
-
-               foreach($aQueries as $sQuery){
-                       $aRes = looksLikeLatLonPair($sQuery);
-                       $this->assertEquals( 40.446, $aRes['lat'], 'degrees decimal ' . $sQuery, 0.01);
-                       $this->assertEquals(-79.982, $aRes['lon'], 'degrees decimal ' . $sQuery, 0.01);
-               }
-
-       }
-
-
-
-       public function test_getWordSets()
-       {
-
-               // given an array of arrays like
-               // array( array('a','b'), array('c','d') )
-               // returns a summary as string: '(a|b),(c|d)'
-               function serialize_sets($aSets)
-               {       
-                       $aParts = array();
-                       foreach($aSets as $aSet){
-                               $aParts[] = '(' . join('|', $aSet) . ')';
-                       }
-                       return join(',', $aParts);
-               }
-
-               $this->assertEquals(
-                       array(array('')),
-                       getWordSets(array(),0)
-               );
-
-               $this->assertEquals(
-                       '(a)',
-                       serialize_sets( getWordSets(array("a"),0) )
-               );
-
-               $this->assertEquals(
-                       '(a b),(a|b)',
-                       serialize_sets( getWordSets(array('a','b'),0) )
-               );
-
-               $this->assertEquals(
-                       '(a b c),(a|b c),(a|b|c),(a b|c)',
-                       serialize_sets( getWordSets(array('a','b','c'),0) )
-               );
-
-               $this->assertEquals(
-                       '(a b c d),(a|b c d),(a|b|c d),(a|b|c|d),(a|b c|d),(a b|c d),(a b|c|d),(a b c|d)',
-                       serialize_sets( getWordSets(array('a','b','c','d'),0) )
-               );
-
-
-               // Inverse
-               $this->assertEquals(
-                       '(a b c),(c|a b),(c|b|a),(b c|a)',
-                       serialize_sets( getInverseWordSets(array('a','b','c'),0) )
-               );
-
-
-               // make sure we don't create too many sets
-               // 4 words => 8 sets
-               // 10 words => 511 sets
-               // 15 words => 12911 sets
-               // 18 words => 65536 sets
-               // 20 words => 169766 sets
-               // 22 words => 401930 sets
-               // 28 words => 3505699 sets (needs more than 4GB via 'phpunit -d memory_limit=' to run)
-               $this->assertEquals(
-                       8,
-                       count( getWordSets(array_fill( 0, 4, 'a'),0) )
-               );
-
-
-               $this->assertEquals(
-                       65536,
-                       count( getWordSets(array_fill( 0, 18, 'a'),0) )
-               );
-       }
-
-
-
-       // you might say we're creating a circle
-       public function test_createPointsAroundCenter()
-       {
-               $aPoints = createPointsAroundCenter(0, 0, 2);
-
-               $this->assertEquals(
-                       101,
-                       count($aPoints)
-               );
-               $this->assertEquals(
-                       array(
-                               ['', 0, 2],
-                               ['', 0.12558103905863, 1.9960534568565],
-                               ['', 0.25066646712861, 1.984229402629]
-                       ),
-                       array_splice($aPoints, 0, 3)
-               );
-       }
-
-       public function test_geometryText2Points()
-       {
-               $fRadius = 1;
-               // invalid value
-               $this->assertEquals(
-                       NULL,
-                       geometryText2Points('', $fRadius)
-               );
-
-               // POINT
-               $aPoints = geometryText2Points('POINT(10 20)', $fRadius);
-               $this->assertEquals(
-                       101,
-                       count($aPoints)
-               );
-               $this->assertEquals(
-                       array(
-                               [10, 21],
-                               [10.062790519529, 20.998026728428],
-                               [10.125333233564, 20.992114701314]
-                       ),
-                       array_splice($aPoints, 0,3)
-               );
-
-               // POLYGON
-               $this->assertEquals(
-                       array(
-                               ['30', '10'],
-                               ['40', '40'],
-                               ['20', '40'],
-                               ['10', '20'],
-                               ['30', '10']
-                       ),
-                       geometryText2Points('POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))', $fRadius)
-               );
-
-               // MULTIPOLYGON
-               $this->assertEquals(
-                       array(
-                               ['30', '20'], // first polygon only
-                               ['45', '40'],
-                               ['10', '40'],
-                               ['30', '20'],
-                       ),
-                       geometryText2Points('MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))', $fRadius)
-               );
-       }
+    protected function setUp()
+    {
+    }
+
+
+    public function test_getClassTypesWithImportance()
+    {
+        $aClasses = getClassTypesWithImportance();
+
+        $this->assertGreaterThan(
+            200,
+            count($aClasses)
+        );
+
+        $this->assertEquals(
+            array(
+                'label' => "Country",
+                'frequency' => 0,
+                'icon' => "poi_boundary_administrative",
+                'defzoom' => 6,
+                'defdiameter' => 15,
+                'importance' => 3
+            ),
+            $aClasses['place:country']
+        );
+    }
+
+
+    public function test_getResultDiameter()
+    {
+        $aResult = array();
+        $this->assertEquals(
+            0.0001,
+            getResultDiameter($aResult)
+        );
+
+        $aResult = array('class' => 'place', 'type' => 'country');
+        $this->assertEquals(
+            15,
+            getResultDiameter($aResult)
+        );
+
+        $aResult = array('class' => 'boundary', 'type' => 'administrative', 'admin_level' => 6);
+        $this->assertEquals(
+            0.32,
+            getResultDiameter($aResult)
+        );
+    }
+
+
+    public function test_addQuotes()
+    {
+        // FIXME: not quoting existing quote signs is probably a bug
+        $this->assertSame("'St. John's'", addQuotes("St. John's"));
+        $this->assertSame("''", addQuotes(''));
+    }
+
+    public function test_looksLikeLatLonPair()
+    {
+        // no coordinates expected
+        $this->assertNull(looksLikeLatLonPair(''));
+        $this->assertNull(looksLikeLatLonPair('abc'));
+        $this->assertNull(looksLikeLatLonPair('12 34'));
+        $this->assertNull(looksLikeLatLonPair('200.1 89.9')); // because latitude > 180
+
+        // coordinates expected
+        $this->assertNotNull(looksLikeLatLonPair('0.0 -0.0'));
+
+        $this->assertEquals(
+                array( 'lat' => 12.456, 'lon' => -78.90, 'query' => 'abc   def'),
+                looksLikeLatLonPair(' abc 12.456 -78.90 def ')
+            );
+
+        $this->assertEquals(
+                array( 'lat' => 12.456, 'lon' => -78.90, 'query' => ''),
+                looksLikeLatLonPair(' [12.456,-78.90] ')
+            );
+
+        // http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
+        // these all represent the same location
+        $aQueries = array(
+                    '40 26.767 N 79 58.933 W',
+                    '40° 26.767′ N 79° 58.933′ W',
+                    "40° 26.767' N 79° 58.933' W",
+                    'N 40 26.767, W 79 58.933',
+                    'N 40°26.767′, W 79°58.933′',
+                    "N 40°26.767', W 79°58.933'",
+
+                    '40 26 46 N 79 58 56 W',
+                    '40° 26′ 46″ N 79° 58′ 56″ W',
+                    'N 40 26 46 W 79 58 56',
+                    'N 40° 26′ 46″, W 79° 58′ 56″',
+                    'N 40° 26\' 46", W 79° 58\' 56"',
+
+                    '40.446 -79.982',
+                    '40.446,-79.982',
+                    '40.446° N 79.982° W',
+                    'N 40.446° W 79.982°',
+
+                    '[40.446 -79.982]',
+                    '       40.446  ,   -79.982     ',
+        );
+
+
+        foreach($aQueries as $sQuery){
+            $aRes = looksLikeLatLonPair($sQuery);
+            $this->assertEquals( 40.446, $aRes['lat'], 'degrees decimal ' . $sQuery, 0.01);
+            $this->assertEquals(-79.982, $aRes['lon'], 'degrees decimal ' . $sQuery, 0.01);
+        }
+
+    }
+
+
+
+    public function test_getWordSets()
+    {
+
+        // given an array of arrays like
+        // array( array('a','b'), array('c','d') )
+        // returns a summary as string: '(a|b),(c|d)'
+        function serialize_sets($aSets)
+        {   
+            $aParts = array();
+            foreach($aSets as $aSet){
+                $aParts[] = '(' . join('|', $aSet) . ')';
+            }
+            return join(',', $aParts);
+        }
+
+        $this->assertEquals(
+            array(array('')),
+            getWordSets(array(),0)
+        );
+
+        $this->assertEquals(
+            '(a)',
+            serialize_sets( getWordSets(array("a"),0) )
+        );
+
+        $this->assertEquals(
+            '(a b),(a|b)',
+            serialize_sets( getWordSets(array('a','b'),0) )
+        );
+
+        $this->assertEquals(
+            '(a b c),(a|b c),(a|b|c),(a b|c)',
+            serialize_sets( getWordSets(array('a','b','c'),0) )
+        );
+
+        $this->assertEquals(
+            '(a b c d),(a|b c d),(a|b|c d),(a|b|c|d),(a|b c|d),(a b|c d),(a b|c|d),(a b c|d)',
+            serialize_sets( getWordSets(array('a','b','c','d'),0) )
+        );
+
+
+        // Inverse
+        $this->assertEquals(
+            '(a b c),(c|a b),(c|b|a),(b c|a)',
+            serialize_sets( getInverseWordSets(array('a','b','c'),0) )
+        );
+
+
+        // make sure we don't create too many sets
+        // 4 words => 8 sets
+        // 10 words => 511 sets
+        // 15 words => 12911 sets
+        // 18 words => 65536 sets
+        // 20 words => 169766 sets
+        // 22 words => 401930 sets
+        // 28 words => 3505699 sets (needs more than 4GB via 'phpunit -d memory_limit=' to run)
+        $this->assertEquals(
+            8,
+            count( getWordSets(array_fill( 0, 4, 'a'),0) )
+        );
+
+
+        $this->assertEquals(
+            65536,
+            count( getWordSets(array_fill( 0, 18, 'a'),0) )
+        );
+    }
+
+
+
+    // you might say we're creating a circle
+    public function test_createPointsAroundCenter()
+    {
+        $aPoints = createPointsAroundCenter(0, 0, 2);
+
+        $this->assertEquals(
+            101,
+            count($aPoints)
+        );
+        $this->assertEquals(
+            array(
+                ['', 0, 2],
+                ['', 0.12558103905863, 1.9960534568565],
+                ['', 0.25066646712861, 1.984229402629]
+            ),
+            array_splice($aPoints, 0, 3)
+        );
+    }
+
+    public function test_geometryText2Points()
+    {
+        $fRadius = 1;
+        // invalid value
+        $this->assertEquals(
+            NULL,
+            geometryText2Points('', $fRadius)
+        );
+
+        // POINT
+        $aPoints = geometryText2Points('POINT(10 20)', $fRadius);
+        $this->assertEquals(
+            101,
+            count($aPoints)
+        );
+        $this->assertEquals(
+            array(
+                [10, 21],
+                [10.062790519529, 20.998026728428],
+                [10.125333233564, 20.992114701314]
+            ),
+            array_splice($aPoints, 0,3)
+        );
+
+        // POLYGON
+        $this->assertEquals(
+            array(
+                ['30', '10'],
+                ['40', '40'],
+                ['20', '40'],
+                ['10', '20'],
+                ['30', '10']
+            ),
+            geometryText2Points('POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))', $fRadius)
+        );
+
+        // MULTIPOLYGON
+        $this->assertEquals(
+            array(
+                ['30', '20'], // first polygon only
+                ['45', '40'],
+                ['10', '40'],
+                ['30', '20'],
+            ),
+            geometryText2Points('MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))', $fRadius)
+        );
+    }
 
 }
index 28c48c588d03a6557c2de446d635034433c3dfc3..7388d2f4eb8e3fa72532e39d002cf40093523349 100755 (executable)
@@ -1,53 +1,53 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
 
-       $aCMDOptions = array(
-               "Manage service blocks / restrictions",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-               array('list', 'l', 0, 1, 0, 0, 'bool', 'List recent blocks'),
-               array('delete', 'd', 0, 1, 0, 0, 'bool', 'Clear recent blocks list'),
-               array('flush', '', 0, 1, 0, 0, 'bool', 'Flush all blocks / stats'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
+$aCMDOptions = array(
+    "Manage service blocks / restrictions",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+    array('list', 'l', 0, 1, 0, 0, 'bool', 'List recent blocks'),
+    array('delete', 'd', 0, 1, 0, 0, 'bool', 'Clear recent blocks list'),
+    array('flush', '', 0, 1, 0, 0, 'bool', 'Flush all blocks / stats'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
 
-       $m = getBucketMemcache();
-        if (!$m)
-       {
-               echo "ERROR: Bucket memcache is not configured\n";
-               exit;
-       }
+$m = getBucketMemcache();
+    if (!$m)
+{
+    echo "ERROR: Bucket memcache is not configured\n";
+    exit;
+}
 
-       if ($aResult['list'])
-       {
-               $iCurrentSleeping = $m->get('sleepCounter');
-               echo "\n Sleeping blocks count: $iCurrentSleeping\n";
+if ($aResult['list'])
+{
+    $iCurrentSleeping = $m->get('sleepCounter');
+    echo "\n Sleeping blocks count: $iCurrentSleeping\n";
 
-               $aBlocks = getBucketBlocks();
-               echo "\n";
-               printf(" %-40s | %12s | %7s | %13s | %31s | %8s\n", "Key", "Total Blocks", "Current", "Still Blocked", "Last Block Time", "Sleeping");
-               printf(" %'--40s-|-%'-12s-|-%'-7s-|-%'-13s-|-%'-31s-|-%'-8s\n", "", "", "", "", "", "");
-               foreach($aBlocks as $sKey => $aDetails)
-               {
-                       printf(" %-40s | %12s | %7s | %13s | %31s | %8s\n", $sKey, $aDetails['totalBlocks'], 
-                               (int)$aDetails['currentBucketSize'], $aDetails['currentlyBlocked']?'Y':'N', 
-                               date("r", $aDetails['lastBlockTimestamp']), $aDetails['isSleeping']?'Y':'N');
-               }
-               echo "\n";
-       }
+    $aBlocks = getBucketBlocks();
+    echo "\n";
+    printf(" %-40s | %12s | %7s | %13s | %31s | %8s\n", "Key", "Total Blocks", "Current", "Still Blocked", "Last Block Time", "Sleeping");
+    printf(" %'--40s-|-%'-12s-|-%'-7s-|-%'-13s-|-%'-31s-|-%'-8s\n", "", "", "", "", "", "");
+    foreach($aBlocks as $sKey => $aDetails)
+    {
+        printf(" %-40s | %12s | %7s | %13s | %31s | %8s\n", $sKey, $aDetails['totalBlocks'], 
+            (int)$aDetails['currentBucketSize'], $aDetails['currentlyBlocked']?'Y':'N', 
+            date("r", $aDetails['lastBlockTimestamp']), $aDetails['isSleeping']?'Y':'N');
+    }
+    echo "\n";
+}
 
-       if ($aResult['delete'])
-       {
-               $m->set('sleepCounter', 0);
-               clearBucketBlocks();
-       }
+if ($aResult['delete'])
+{
+    $m->set('sleepCounter', 0);
+    clearBucketBlocks();
+}
 
-       if ($aResult['flush'])
-       {
-               $m->flush();
-       }
+if ($aResult['flush'])
+{
+    $m->flush();
+}
index 5f890083122846eabe1f5e06cdead0997b2a9366..9d3b1e810c5ac4da3b97d24ef3047504ba38e66b 100755 (executable)
@@ -1,36 +1,36 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
 
-        ini_set('memory_limit', '800M');
-        ini_set('display_errors', 'stderr');
+    ini_set('memory_limit', '800M');
+    ini_set('display_errors', 'stderr');
 
-        $aCMDOptions = array(
-                "Import country language data from osm wiki",
-                array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-                array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-                array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-        );
-        getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+    $aCMDOptions = array(
+            "Import country language data from osm wiki",
+            array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+            array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+            array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+    );
+    getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
 
-       include(CONST_InstallPath.'/settings/phrase_settings.php');
+include(CONST_InstallPath.'/settings/phrase_settings.php');
 
-       if (true)
-       {
-               $sURL = 'http://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Country_Codes';
-               $sWikiPageXML = file_get_contents($sURL);
-               if (preg_match_all('#\\| ([a-z]{2}) \\|\\| [^|]+\\|\\| ([a-z,]+)#', $sWikiPageXML, $aMatches, PREG_SET_ORDER))
-               {
-                       foreach($aMatches as $aMatch)
-                       {
-                               $aLanguages = explode(',', $aMatch[2]);
-                               foreach($aLanguages as $i => $s)
-                               {
-                                       $aLanguages[$i] = '"'.pg_escape_string($s).'"';
-                               }
-                               echo "UPDATE country_name set country_default_language_codes = '{".join(',',$aLanguages)."}' where country_code = '".pg_escape_string($aMatch[1])."';\n";
-                       }
-               }
-       }
+if (true)
+{
+    $sURL = 'http://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Country_Codes';
+    $sWikiPageXML = file_get_contents($sURL);
+    if (preg_match_all('#\\| ([a-z]{2}) \\|\\| [^|]+\\|\\| ([a-z,]+)#', $sWikiPageXML, $aMatches, PREG_SET_ORDER))
+    {
+        foreach($aMatches as $aMatch)
+        {
+            $aLanguages = explode(',', $aMatch[2]);
+            foreach($aLanguages as $i => $s)
+            {
+                $aLanguages[$i] = '"'.pg_escape_string($s).'"';
+            }
+            echo "UPDATE country_name set country_default_language_codes = '{".join(',',$aLanguages)."}' where country_code = '".pg_escape_string($aMatch[1])."';\n";
+        }
+    }
+}
index 8e527467a8f01c6db1d64982a61c958514f1442f..86ec29e0e3af04907336a5a5f8237fe37de96828 100755 (executable)
@@ -1,21 +1,21 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
-
-       $aCMDOptions = array(
-               "Create and setup nominatim search system",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-
-               array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create wikipedia tables'),
-               array('parse-articles', '', 0, 1, 0, 0, 'bool', 'Parse wikipedia articles'),
-               array('link', '', 0, 1, 0, 0, 'bool', 'Try to link to existing OSM ids'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
+
+$aCMDOptions = array(
+    "Create and setup nominatim search system",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+
+    array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create wikipedia tables'),
+    array('parse-articles', '', 0, 1, 0, 0, 'bool', 'Parse wikipedia articles'),
+    array('link', '', 0, 1, 0, 0, 'bool', 'Try to link to existing OSM ids'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
 
 /*
 $sTestPageText = <<<EOD
@@ -46,21 +46,21 @@ exit;
 */
 /*
 
-       $a = array();
-       $a[] = 'test';
+    $a = array();
+    $a[] = 'test';
 
-       $oDB &= getDB();
+    $oDB &= getDB();
 
-       if ($aCMDResult['drop-tables'])
-       {
-               $oDB->query('DROP TABLE wikipedia_article');
-               $oDB->query('DROP TABLE wikipedia_link');
-       }
+    if ($aCMDResult['drop-tables'])
+    {
+        $oDB->query('DROP TABLE wikipedia_article');
+        $oDB->query('DROP TABLE wikipedia_link');
+    }
 */
 
-       if ($aCMDResult['create-tables'])
-       {
-               $sSQL = <<<'EOD'
+if ($aCMDResult['create-tables'])
+{
+    $sSQL = <<<'EOD'
 CREATE TABLE wikipedia_article (
     language text NOT NULL,
     title text NOT NULL,
@@ -77,518 +77,518 @@ CREATE TABLE wikipedia_article (
     population bigint,
     website text
 );
-               $oDB->query($sSQL);
+        $oDB->query($sSQL);
 
-               $oDB->query("SELECT AddGeometryColumn('wikipedia_article', 'location', 4326, 'GEOMETRY', 2)");
+        $oDB->query("SELECT AddGeometryColumn('wikipedia_article', 'location', 4326, 'GEOMETRY', 2)");
 
-               $sSQL = <<<'EOD'
+        $sSQL = <<<'EOD'
 CREATE TABLE wikipedia_link (
   from_id INTEGER,
   to_name text
   );
 EOD;
-               $oDB->query($sSQL);
-       }
-
-       function degreesAndMinutesToDecimal($iDegrees, $iMinutes=0, $fSeconds=0, $sNSEW='N')
-       {
-               $sNSEW = strtoupper($sNSEW);
-               return ($sNSEW == 'S' || $sNSEW == 'W'?-1:1) * ((float)$iDegrees + (float)$iMinutes/60 + (float)$fSeconds/3600);
-       }
-
-       function _parseWikipediaContent($sPageText)
-       {
-               $sPageText = str_replace("\n", ' ', $sPageText);
-               $sPageText = preg_replace('#<!--.*?-->#m', '', $sPageText);
-               $sPageText = preg_replace('#<math>.*?<\\/math>#m', '', $sPageText);
-
-               $aPageText = preg_split('#({{|}}|\\[\\[|\\]\\]|[|])#', $sPageText, -1, PREG_SPLIT_DELIM_CAPTURE);
-
-               $aPageProperties = array();
-               $sPageBody = '';
-               $aTemplates = array();
-               $aLinks = array();
-
-               $aTemplateStack = array();
-               $aState = array('body');
-               foreach($aPageText as $i => $sPart)
-               {
-                       switch($sPart)
-                       {
-                       case '{{':
-                               array_unshift($aTemplateStack, array('', array()));
-                               array_unshift($aState, 'template');
-                               break;
-                       case '}}':
-                               if ($aState[0] == 'template' || $aState[0] == 'templateparam')
-                               {
-                                       $aTemplate = array_shift($aTemplateStack);
-                                       array_shift($aState);
-
-                                       $aTemplates[] = $aTemplate;
-
-                               }
-                               break;
-                       case '[[':
-                               $sLinkPage = '';
-                               $sLinkSyn = '';
-                               array_unshift($aState, 'link');
-                               break;
-                       case ']]':
-                               if ($aState[0] == 'link' || $aState[0] == 'linksynonim')
-                               {
-                                       if (!$sLinkSyn) $sLinkSyn = $sLinkPage;
-                                       if (substr($sLinkPage, 0, 6) == 'Image:') $sLinkSyn = substr($sLinkPage, 6);
-
-                                       $aLinks[] = array($sLinkPage, $sLinkSyn);
-
-                                       array_shift($aState);
-                                       switch($aState[0])
-                                       {
-                                       case 'template':
-                                               $aTemplateStack[0][0] .= trim($sPart);
-                                               break;
-                                       case 'templateparam':
-                                               $aTemplateStack[0][1][0] .= $sLinkSyn;
-                                               break;
-                                       case 'link':
-                                               $sLinkPage .= trim($sPart);
-                                               break;
-                                       case 'linksynonim':
-                                               $sLinkSyn .= $sPart;
-                                               break;
-                                       case 'body':
-                                               $sPageBody .= $sLinkSyn;
-                                               break;
-                                       default:
-                                               var_dump($aState, $sPageName, $aTemplateStack, $sPart, $aPageText);
-                                               fail('unknown state');
-                                       }
-                               }
-                               break;
-                       case '|':
-                               if ($aState[0] == 'template' || $aState[0] == 'templateparam')
-                               {
-                                       // Create a new template paramater
-                                       $aState[0] = 'templateparam';
-                                       array_unshift($aTemplateStack[0][1], '');
-                               }
-                               if ($aState[0] == 'link') $aState[0] = 'linksynonim';
-                               break;
-                       default:
-                               switch($aState[0])
-                               {
-                               case 'template':
-                                       $aTemplateStack[0][0] .= trim($sPart);
-                                       break;
-                               case 'templateparam':
-                                       $aTemplateStack[0][1][0] .= $sPart;
-                                       break;
-                               case 'link':
-                                       $sLinkPage .= trim($sPart);
-                                       break;
-                               case 'linksynonim':
-                                       $sLinkSyn .= $sPart;
-                                       break;
-                               case 'body':
-                                       $sPageBody .= $sPart;
-                                       break;
-                               default:
-                                       var_dump($aState, $aPageText);
-                                       fail('unknown state');
-                               }
-                               break;
-                       }
-               }
-               return $aTemplates;
-       }
-
-       function _templatesToProperties($aTemplates)
-       {
-               $aPageProperties = array();
-               foreach($aTemplates as $iTemplate => $aTemplate)
-               {
-                       $aParams = array();
-                       foreach(array_reverse($aTemplate[1]) as $iParam => $sParam)
-                       {
-                               if (($iPos = strpos($sParam, '=')) === FALSE)
-                               {
-                                       $aParams[] = trim($sParam);
-                               }
-                               else
-                               {
-                                       $aParams[trim(substr($sParam, 0, $iPos))] = trim(substr($sParam, $iPos+1));
-                               }
-                       }
-                       $aTemplates[$iTemplate][1] = $aParams;
-                       if (!isset($aPageProperties['sOfficialName']) && isset($aParams['official_name']) && $aParams['official_name']) $aPageProperties['sOfficialName'] = $aParams['official_name'];
-                       if (!isset($aPageProperties['iPopulation']) && isset($aParams['population']) && $aParams['population'] && preg_match('#^[0-9.,]+#', $aParams['population']))
-                       {
-                               $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population']);
-                       }
-                       if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_total']) && $aParams['population_total'] && preg_match('#^[0-9.,]+#', $aParams['population_total']))
-                       {
-                               $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_total']);
-                       }
-                       if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_urban']) && $aParams['population_urban'] && preg_match('#^[0-9.,]+#', $aParams['population_urban']))
-                       {
-                               $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_urban']);
-                       }
-                       if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_estimate']) && $aParams['population_estimate'] && preg_match('#^[0-9.,]+#', $aParams['population_estimate']))
-                       {
-                               $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_estimate']);
-                       }
-                       if (!isset($aPageProperties['sWebsite']) && isset($aParams['website']) && $aParams['website'])
-                       {
-                               if (preg_match('#^\\[?([^ \\]]+)[^\\]]*\\]?$#', $aParams['website'], $aMatch))
-                               {
-                                       $aPageProperties['sWebsite'] = $aMatch[1];
-                                       if (strpos($aPageProperties['sWebsite'],':/'.'/') === FALSE)
-                                       {
-                                               $aPageProperties['sWebsite'] = 'http:/'.'/'.$aPageProperties['sWebsite'];
-                                       }
-                               }
-                       }
-                       if (!isset($aPageProperties['sTopLevelDomain']) && isset($aParams['cctld']) && $aParams['cctld'])
-                       {
-                               $aPageProperties['sTopLevelDomain'] = str_replace(array('[',']','.'),'', $aParams['cctld']);
-                       }
-
-                       if (!isset($aPageProperties['sInfoboxType']) && strtolower(substr($aTemplate[0],0,7)) == 'infobox')
-                       {
-                               $aPageProperties['sInfoboxType'] = trim(substr($aTemplate[0],8));
-                               // $aPageProperties['aInfoboxParams'] = $aParams;
-                       }
-
-                       // Assume the first template with lots of params is the type (fallback for infobox)
-                       if (!isset($aPageProperties['sPossibleInfoboxType']) && sizeof($aParams) > 10)
-                       {
-                               $aPageProperties['sPossibleInfoboxType'] = trim($aTemplate[0]);
-                               // $aPageProperties['aInfoboxParams'] = $aParams;
-                       }
-
-                       // do we have a lat/lon
-                       if (!isset($aPageProperties['fLat']))
-                       {
-                               if (isset($aParams['latd']) && isset($aParams['longd']))
-                               {
-                                       $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams['latd'], @$aParams['latm'], @$aParams['lats'], @$aParams['latNS']);
-                                       $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams['longd'], @$aParams['longm'], @$aParams['longs'], @$aParams['longEW']);
-                               }
-                               if (isset($aParams['lat_degrees']) && isset($aParams['lat_degrees']))
-                               {
-                                       $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams['lat_degrees'], @$aParams['lat_minutes'], @$aParams['lat_seconds'], @$aParams['lat_direction']);
-                                       $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams['long_degrees'], @$aParams['long_minutes'], @$aParams['long_seconds'], @$aParams['long_direction']);
-                               }
-                               if (isset($aParams['latitude']) && isset($aParams['longitude']))
-                               {
-                                       if (preg_match('#[0-9.]+#', $aParams['latitude']) && preg_match('#[0-9.]+#', $aParams['longitude']))
-                                       {
-                                               $aPageProperties['fLat'] = (float)$aParams['latitude'];
-                                               $aPageProperties['fLon'] = (float)$aParams['longitude'];
-                                       }
-                               }
-                               if (strtolower($aTemplate[0]) == 'coord')
-                               {
-                                       if (isset($aParams[3]) && (strtoupper($aParams[3]) == 'N' || strtoupper($aParams[3]) == 'S'))
-                                       {
-                                               $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams[0], $aParams[1], $aParams[2], $aParams[3]);
-                                               $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams[4], $aParams[5], $aParams[6], $aParams[7]);
-                                       }
-                                       elseif (isset($aParams[0]) && isset($aParams[1]) && isset($aParams[2]) && (strtoupper($aParams[2]) == 'N' || strtoupper($aParams[2]) == 'S'))
-                                       {
-                                               $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams[0], $aParams[1], 0, $aParams[2]);
-                                               $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams[3], $aParams[4], 0, $aParams[5]);
-                                       }
-                                       else if (isset($aParams[0]) && isset($aParams[1]) && (strtoupper($aParams[1]) == 'N' || strtoupper($aParams[1]) == 'S'))
-                                       {
-                                               $aPageProperties['fLat'] = (strtoupper($aParams[1]) == 'N'?1:-1) * (float)$aParams[0];
-                                               $aPageProperties['fLon'] = (strtoupper($aParams[3]) == 'E'?1:-1) * (float)$aParams[2];
-                                       }
-                                       else if (isset($aParams[0]) && is_numeric($aParams[0]) && isset($aParams[1]) && is_numeric($aParams[1]))
-                                       {
-                                               $aPageProperties['fLat'] = (float)$aParams[0];
-                                               $aPageProperties['fLon'] = (float)$aParams[1];
-                                       }
-                               }
-                               if (isset($aParams['Latitude']) && isset($aParams['Longitude']))
-                               {
-                                       $aParams['Latitude'] = str_replace('&nbsp;',' ',$aParams['Latitude']);
-                                       $aParams['Longitude'] = str_replace('&nbsp;',' ',$aParams['Longitude']);
-                                       if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([NS]) to ([0-9]+)°( ([0-9]+)′)? ([NS])#', $aParams['Latitude'], $aMatch))
-                                       {
-                                               $aPageProperties['fLat'] =
-                                                       (degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4])
-                                                       +degreesAndMinutesToDecimal($aMatch[5], $aMatch[7], 0, $aMatch[8])) / 2;
-                                       }
-                                       else if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([NS])#', $aParams['Latitude'], $aMatch))
-                                       {
-                                               $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4]);
-                                       }
-
-                                       if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([EW]) to ([0-9]+)°( ([0-9]+)′)? ([EW])#', $aParams['Longitude'], $aMatch))
-                                       {
-                                               $aPageProperties['fLon'] =
-                                                       (degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4])
-                                                       +degreesAndMinutesToDecimal($aMatch[5], $aMatch[7], 0, $aMatch[8])) / 2;
-                                       }
-                                       else if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([EW])#', $aParams['Longitude'], $aMatch))
-                                       {
-                                               $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4]);
-                                       }
-                               }
-                       }
-               }
-               if (isset($aPageProperties['sPossibleInfoboxType']))
-               {
-                       if (!isset($aPageProperties['sInfoboxType'])) $aPageProperties['sInfoboxType'] = '#'.$aPageProperties['sPossibleInfoboxType'];
-                       unset($aPageProperties['sPossibleInfoboxType']);
-               }
-               return $aPageProperties;
-       }
-
-       if (isset($aCMDResult['parse-wikipedia']))
-       {
-               $oDB =& getDB();
-               $aArticleNames = $oDB->getCol('select page_title from content where page_namespace = 0 and page_id %10 = '.$aCMDResult['parse-wikipedia'].' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))');
-//             $aArticleNames = $oDB->getCol($sSQL = 'select page_title from content where page_namespace = 0 and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\')) and page_title in (\'Virginia\')');
-               foreach($aArticleNames as $sArticleName)
-               {
-                       $sPageText = $oDB->getOne('select page_content from content where page_namespace = 0 and page_title = \''.pg_escape_string($sArticleName).'\'');
-                       $aP = _templatesToProperties(_parseWikipediaContent($sPageText));
-
-                       if (isset($aP['sInfoboxType']))
-                       {
-                               $aP['sInfoboxType'] = preg_replace('#\\s+#',' ',$aP['sInfoboxType']);
-                               $sSQL = 'update wikipedia_article set ';
-                               $sSQL .= 'infobox_type = \''.pg_escape_string($aP['sInfoboxType']).'\'';
-                               $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
-                               $oDB->query($sSQL);
-                       }
-                       if (isset($aP['iPopulation']))
-                       {
-                               $sSQL = 'update wikipedia_article set ';
-                               $sSQL .= 'population = \''.pg_escape_string($aP['iPopulation']).'\'';
-                               $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
-                               $oDB->query($sSQL);
-                       }
-                       if (isset($aP['sWebsite']))
-                       {
-                               $sSQL = 'update wikipedia_article set ';
-                               $sSQL .= 'website = \''.pg_escape_string($aP['sWebsite']).'\'';
-                               $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
-                               $oDB->query($sSQL);
-                       }
-                       if (isset($aP['fLat']) && ($aP['fLat']!='-0' || $aP['fLon']!='-0'))
-                       {
-                               if (!isset($aP['sInfoboxType'])) $aP['sInfoboxType'] = '';
-                               echo $sArticleName.'|'.$aP['sInfoboxType'].'|'.$aP['fLat'].'|'.$aP['fLon'] ."\n";
-                               $sSQL = 'update wikipedia_article set ';
-                               $sSQL .= 'lat = \''.pg_escape_string($aP['fLat']).'\',';
-                               $sSQL .= 'lon = \''.pg_escape_string($aP['fLon']).'\'';
-                               $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
-                               $oDB->query($sSQL);
-                       }
-               }
-       }
-
-       function nominatimXMLStart($hParser, $sName, $aAttr)
-       {
-               global $aNominatRecords;
-               switch($sName)
-               {
-               case 'PLACE':
-                       $aNominatRecords[] = $aAttr;
-                       break;
-               }
-       }
-
-       function nominatimXMLEnd($hParser, $sName)
-       {
-       }
-
-
-       if (isset($aCMDResult['link']))
-       {
-               $oDB =& getDB();
-               $aWikiArticles = $oDB->getAll("select * from wikipedia_article where language = 'en' and lat is not null and osm_type is null and totalcount < 31 order by importance desc limit 200000");
-
-               // If you point this script at production OSM you will be blocked
-               $sNominatimBaseURL = 'http://SEVERNAME/search.php';
-
-               foreach($aWikiArticles as $aRecord)
-               {
-                       $aRecord['name'] = str_replace('_',' ',$aRecord['title']);
-
-                       $sURL = $sNominatimBaseURL.'?format=xml&accept-language=en';
-
-                       echo "\n-- ".$aRecord['name'].", ".$aRecord['infobox_type']."\n";
-                       $fMaxDist = 0.0000001;
-                       $bUnknown = false;
-                       switch(strtolower($aRecord['infobox_type']))
-                       {
-                       case 'former country':
-                               continue 2;
-                       case 'sea':
-                               $fMaxDist = 60; // effectively turn it off
-                               $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
-                               break;
-                       case 'country':
-                       case 'island':
-                       case 'islands':
-                       case 'continent':
-                               $fMaxDist = 60; // effectively turn it off
-                               $sURL .= "&featuretype=country";
-                               $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
-                               break;
-                       case 'prefecture japan':
-                               $aRecord['name'] = trim(str_replace(' Prefecture',' ', $aRecord['name']));
-                       case 'state':
-                       case '#us state':
-                       case 'county':
-                       case 'u.s. state':
-                       case 'u.s. state symbols':
-                       case 'german state':
-                       case 'province or territory of canada';
-                       case 'indian jurisdiction';
-                       case 'province';
-                       case 'french region':
-                       case 'region of italy':
-                       case 'kommune':
-                       case '#australia state or territory':
-                       case 'russian federal subject':
-                               $fMaxDist = 4;
-                               $sURL .= "&featuretype=state";
-                               $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
-                               break;
-                       case 'protected area':
-                               $fMaxDist = 1;
-                               $sURL .= "&nearlat=".$aRecord['lat'];
-                               $sURL .= "&nearlon=".$aRecord['lon'];
-                               $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
-                               break;
-                       case 'settlement':
-                               $bUnknown = true;
-                       case 'french commune':
-                       case 'italian comune':
-                       case 'uk place':
-                       case 'italian comune':
-                       case 'australian place':
-                       case 'german place':
-                       case '#geobox':
-                       case 'u.s. county':
-                       case 'municipality':
-                       case 'city japan':
-                       case 'russian inhabited locality':
-                       case 'finnish municipality/land area':
-                       case 'england county':
-                       case 'israel municipality':
-                       case 'russian city':
-                       case 'city':
-                               $fMaxDist = 0.2;
-                               $sURL .= "&featuretype=settlement";
-                               $sURL .= "&viewbox=".($aRecord['lon']-0.5).",".($aRecord['lat']+0.5).",".($aRecord['lon']+0.5).",".($aRecord['lat']-0.5);
-                               break;
-                       case 'mountain':
-                       case 'mountain pass':
-                       case 'river':
-                       case 'lake':
-                       case 'airport':
-                               $fMaxDist = 0.2;
-                               $sURL .= "&viewbox=".($aRecord['lon']-0.5).",".($aRecord['lat']+0.5).",".($aRecord['lon']+0.5).",".($aRecord['lat']-0.5);
-
-                       case 'ship begin':
-                               $fMaxDist = 0.1;
-                               $aTypes = array('wreck');
-                               $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
-                               $sURL .= "&nearlat=".$aRecord['lat'];
-                               $sURL .= "&nearlon=".$aRecord['lon'];
-                               break;
-                       case 'road':
-                       case 'university':
-                       case 'company':
-                       case 'department':
-                               $fMaxDist = 0.005;
-                               $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
-                               $sURL .= "&bounded=1";
-                               $sURL .= "&nearlat=".$aRecord['lat'];
-                               $sURL .= "&nearlon=".$aRecord['lon'];
-                               break;
-                       default:
-                               $bUnknown = true;
-                               $fMaxDist = 0.005;
-                               $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
-//                             $sURL .= "&bounded=1";
-                               $sURL .= "&nearlat=".$aRecord['lat'];
-                               $sURL .= "&nearlon=".$aRecord['lon'];
-                               echo "-- Unknown: ".$aRecord['infobox_type']."\n";
-                               break;
-                       }
-                       $sNameURL = $sURL.'&q='.urlencode($aRecord['name']);
-
-                       var_Dump($sNameURL);
-                       $sXML = file_get_contents($sNameURL);
-
-                       $aNominatRecords = array();
-                       $hXMLParser = xml_parser_create();
-                       xml_set_element_handler($hXMLParser, 'nominatimXMLStart', 'nominatimXMLEnd');
-                       xml_parse($hXMLParser, $sXML, true);
-                       xml_parser_free($hXMLParser);
-
-                       if (!isset($aNominatRecords[0]))
-                       {
-                               $aNameParts = preg_split('#[(,]#',$aRecord['name']);
-                               if (sizeof($aNameParts) > 1)
-                               {
-                                       $sNameURL = $sURL.'&q='.urlencode(trim($aNameParts[0]));
-                                       var_Dump($sNameURL);
-                                       $sXML = file_get_contents($sNameURL);
-
-                                       $aNominatRecords = array();
-                                       $hXMLParser = xml_parser_create();
-                                       xml_set_element_handler($hXMLParser, 'nominatimXMLStart', 'nominatimXMLEnd');
-                                       xml_parse($hXMLParser, $sXML, true);
-                                       xml_parser_free($hXMLParser);#
-                               }
-                       }
-
-                       // assume first is best/right
-                       for($i = 0; $i < sizeof($aNominatRecords); $i++)
-                       {
-                               $fDiff = ($aRecord['lat']-$aNominatRecords[$i]['LAT']) * ($aRecord['lat']-$aNominatRecords[$i]['LAT']);
-                               $fDiff += ($aRecord['lon']-$aNominatRecords[$i]['LON']) * ($aRecord['lon']-$aNominatRecords[$i]['LON']);
-                               $fDiff = sqrt($fDiff);
-                               if ($bUnknown) {
-                                       // If it was an unknown type base it on the rank of the found result
-                                       $iRank = (int)$aNominatRecords[$i]['PLACE_RANK'];
-                                       if ($iRank <= 4) $fMaxDist = 2;
-                                       elseif ($iRank <= 8) $fMaxDist = 1;
-                                       elseif ($iRank <= 10) $fMaxDist = 0.8;
-                                       elseif ($iRank <= 12) $fMaxDist = 0.6;
-                                       elseif ($iRank <= 17) $fMaxDist = 0.2;
-                                       elseif ($iRank <= 18) $fMaxDist = 0.1;
-                                       elseif ($iRank <= 22) $fMaxDist = 0.02;
-                                       elseif ($iRank <= 26) $fMaxDist = 0.001;
-                                       else $fMaxDist = 0.001;
-                               }
-                               echo "-- FOUND \"".substr($aNominatRecords[$i]['DISPLAY_NAME'],0,50)."\", ".$aNominatRecords[$i]['CLASS'].", ".$aNominatRecords[$i]['TYPE'].", ".$aNominatRecords[$i]['PLACE_RANK'].", ".$aNominatRecords[$i]['OSM_TYPE']." (dist:$fDiff, max:$fMaxDist)\n";
-                               if ($fDiff > $fMaxDist)
-                               {
-                                       echo "-- Diff too big $fDiff (max: $fMaxDist)".$aRecord['lat'].','.$aNominatRecords[$i]['LAT'].' & '.$aRecord['lon'].','.$aNominatRecords[$i]['LON']." \n";
-                               }
-                               else
-                               {
-                                       $sSQL = "update wikipedia_article set osm_type=";
-                                       switch($aNominatRecords[$i]['OSM_TYPE'])
-                                       {
-                                       case 'relation': $sSQL .= "'R'"; break;
-                                       case 'way': $sSQL .= "'W'"; break;
-                                       case 'node': $sSQL .= "'N'"; break;
-                                       }
-                                       $sSQL .= ", osm_id=".$aNominatRecords[$i]['OSM_ID']." where language = '".pg_escape_string($aRecord['language'])."' and title = '".pg_escape_string($aRecord['title'])."'";
-                                       $oDB->query($sSQL);
-                                       break;
-                               }
-                       }
-               }
-       }
+    $oDB->query($sSQL);
+}
+
+function degreesAndMinutesToDecimal($iDegrees, $iMinutes=0, $fSeconds=0, $sNSEW='N')
+{
+    $sNSEW = strtoupper($sNSEW);
+    return ($sNSEW == 'S' || $sNSEW == 'W'?-1:1) * ((float)$iDegrees + (float)$iMinutes/60 + (float)$fSeconds/3600);
+}
+
+function _parseWikipediaContent($sPageText)
+{
+    $sPageText = str_replace("\n", ' ', $sPageText);
+    $sPageText = preg_replace('#<!--.*?-->#m', '', $sPageText);
+    $sPageText = preg_replace('#<math>.*?<\\/math>#m', '', $sPageText);
+
+    $aPageText = preg_split('#({{|}}|\\[\\[|\\]\\]|[|])#', $sPageText, -1, PREG_SPLIT_DELIM_CAPTURE);
+
+    $aPageProperties = array();
+    $sPageBody = '';
+    $aTemplates = array();
+    $aLinks = array();
+
+    $aTemplateStack = array();
+    $aState = array('body');
+    foreach($aPageText as $i => $sPart)
+    {
+        switch($sPart)
+        {
+        case '{{':
+            array_unshift($aTemplateStack, array('', array()));
+            array_unshift($aState, 'template');
+            break;
+        case '}}':
+            if ($aState[0] == 'template' || $aState[0] == 'templateparam')
+            {
+                $aTemplate = array_shift($aTemplateStack);
+                array_shift($aState);
+
+                $aTemplates[] = $aTemplate;
+
+            }
+            break;
+        case '[[':
+            $sLinkPage = '';
+            $sLinkSyn = '';
+            array_unshift($aState, 'link');
+            break;
+        case ']]':
+            if ($aState[0] == 'link' || $aState[0] == 'linksynonim')
+            {
+                if (!$sLinkSyn) $sLinkSyn = $sLinkPage;
+                if (substr($sLinkPage, 0, 6) == 'Image:') $sLinkSyn = substr($sLinkPage, 6);
+
+                $aLinks[] = array($sLinkPage, $sLinkSyn);
+
+                array_shift($aState);
+                switch($aState[0])
+                {
+                case 'template':
+                    $aTemplateStack[0][0] .= trim($sPart);
+                    break;
+                case 'templateparam':
+                    $aTemplateStack[0][1][0] .= $sLinkSyn;
+                    break;
+                case 'link':
+                    $sLinkPage .= trim($sPart);
+                    break;
+                case 'linksynonim':
+                    $sLinkSyn .= $sPart;
+                    break;
+                case 'body':
+                    $sPageBody .= $sLinkSyn;
+                    break;
+                default:
+                    var_dump($aState, $sPageName, $aTemplateStack, $sPart, $aPageText);
+                    fail('unknown state');
+                }
+            }
+            break;
+        case '|':
+            if ($aState[0] == 'template' || $aState[0] == 'templateparam')
+            {
+                // Create a new template paramater
+                $aState[0] = 'templateparam';
+                array_unshift($aTemplateStack[0][1], '');
+            }
+            if ($aState[0] == 'link') $aState[0] = 'linksynonim';
+            break;
+        default:
+            switch($aState[0])
+            {
+            case 'template':
+                $aTemplateStack[0][0] .= trim($sPart);
+                break;
+            case 'templateparam':
+                $aTemplateStack[0][1][0] .= $sPart;
+                break;
+            case 'link':
+                $sLinkPage .= trim($sPart);
+                break;
+            case 'linksynonim':
+                $sLinkSyn .= $sPart;
+                break;
+            case 'body':
+                $sPageBody .= $sPart;
+                break;
+            default:
+                var_dump($aState, $aPageText);
+                fail('unknown state');
+            }
+            break;
+        }
+    }
+    return $aTemplates;
+}
+
+function _templatesToProperties($aTemplates)
+{
+    $aPageProperties = array();
+    foreach($aTemplates as $iTemplate => $aTemplate)
+    {
+        $aParams = array();
+        foreach(array_reverse($aTemplate[1]) as $iParam => $sParam)
+        {
+            if (($iPos = strpos($sParam, '=')) === FALSE)
+            {
+                $aParams[] = trim($sParam);
+            }
+            else
+            {
+                $aParams[trim(substr($sParam, 0, $iPos))] = trim(substr($sParam, $iPos+1));
+            }
+        }
+        $aTemplates[$iTemplate][1] = $aParams;
+        if (!isset($aPageProperties['sOfficialName']) && isset($aParams['official_name']) && $aParams['official_name']) $aPageProperties['sOfficialName'] = $aParams['official_name'];
+        if (!isset($aPageProperties['iPopulation']) && isset($aParams['population']) && $aParams['population'] && preg_match('#^[0-9.,]+#', $aParams['population']))
+        {
+            $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population']);
+        }
+        if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_total']) && $aParams['population_total'] && preg_match('#^[0-9.,]+#', $aParams['population_total']))
+        {
+            $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_total']);
+        }
+        if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_urban']) && $aParams['population_urban'] && preg_match('#^[0-9.,]+#', $aParams['population_urban']))
+        {
+            $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_urban']);
+        }
+        if (!isset($aPageProperties['iPopulation']) && isset($aParams['population_estimate']) && $aParams['population_estimate'] && preg_match('#^[0-9.,]+#', $aParams['population_estimate']))
+        {
+            $aPageProperties['iPopulation'] = (int)str_replace(array(',','.'), '', $aParams['population_estimate']);
+        }
+        if (!isset($aPageProperties['sWebsite']) && isset($aParams['website']) && $aParams['website'])
+        {
+            if (preg_match('#^\\[?([^ \\]]+)[^\\]]*\\]?$#', $aParams['website'], $aMatch))
+            {
+                $aPageProperties['sWebsite'] = $aMatch[1];
+                if (strpos($aPageProperties['sWebsite'],':/'.'/') === FALSE)
+                {
+                    $aPageProperties['sWebsite'] = 'http:/'.'/'.$aPageProperties['sWebsite'];
+                }
+            }
+        }
+        if (!isset($aPageProperties['sTopLevelDomain']) && isset($aParams['cctld']) && $aParams['cctld'])
+        {
+            $aPageProperties['sTopLevelDomain'] = str_replace(array('[',']','.'),'', $aParams['cctld']);
+        }
+
+        if (!isset($aPageProperties['sInfoboxType']) && strtolower(substr($aTemplate[0],0,7)) == 'infobox')
+        {
+            $aPageProperties['sInfoboxType'] = trim(substr($aTemplate[0],8));
+            // $aPageProperties['aInfoboxParams'] = $aParams;
+        }
+
+        // Assume the first template with lots of params is the type (fallback for infobox)
+        if (!isset($aPageProperties['sPossibleInfoboxType']) && sizeof($aParams) > 10)
+        {
+            $aPageProperties['sPossibleInfoboxType'] = trim($aTemplate[0]);
+            // $aPageProperties['aInfoboxParams'] = $aParams;
+        }
+
+        // do we have a lat/lon
+        if (!isset($aPageProperties['fLat']))
+        {
+            if (isset($aParams['latd']) && isset($aParams['longd']))
+            {
+                $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams['latd'], @$aParams['latm'], @$aParams['lats'], @$aParams['latNS']);
+                $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams['longd'], @$aParams['longm'], @$aParams['longs'], @$aParams['longEW']);
+            }
+            if (isset($aParams['lat_degrees']) && isset($aParams['lat_degrees']))
+            {
+                $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams['lat_degrees'], @$aParams['lat_minutes'], @$aParams['lat_seconds'], @$aParams['lat_direction']);
+                $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams['long_degrees'], @$aParams['long_minutes'], @$aParams['long_seconds'], @$aParams['long_direction']);
+            }
+            if (isset($aParams['latitude']) && isset($aParams['longitude']))
+            {
+                if (preg_match('#[0-9.]+#', $aParams['latitude']) && preg_match('#[0-9.]+#', $aParams['longitude']))
+                {
+                    $aPageProperties['fLat'] = (float)$aParams['latitude'];
+                    $aPageProperties['fLon'] = (float)$aParams['longitude'];
+                }
+            }
+            if (strtolower($aTemplate[0]) == 'coord')
+            {
+                if (isset($aParams[3]) && (strtoupper($aParams[3]) == 'N' || strtoupper($aParams[3]) == 'S'))
+                {
+                    $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams[0], $aParams[1], $aParams[2], $aParams[3]);
+                    $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams[4], $aParams[5], $aParams[6], $aParams[7]);
+                }
+                elseif (isset($aParams[0]) && isset($aParams[1]) && isset($aParams[2]) && (strtoupper($aParams[2]) == 'N' || strtoupper($aParams[2]) == 'S'))
+                {
+                    $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aParams[0], $aParams[1], 0, $aParams[2]);
+                    $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aParams[3], $aParams[4], 0, $aParams[5]);
+                }
+                else if (isset($aParams[0]) && isset($aParams[1]) && (strtoupper($aParams[1]) == 'N' || strtoupper($aParams[1]) == 'S'))
+                {
+                    $aPageProperties['fLat'] = (strtoupper($aParams[1]) == 'N'?1:-1) * (float)$aParams[0];
+                    $aPageProperties['fLon'] = (strtoupper($aParams[3]) == 'E'?1:-1) * (float)$aParams[2];
+                }
+                else if (isset($aParams[0]) && is_numeric($aParams[0]) && isset($aParams[1]) && is_numeric($aParams[1]))
+                {
+                    $aPageProperties['fLat'] = (float)$aParams[0];
+                    $aPageProperties['fLon'] = (float)$aParams[1];
+                }
+            }
+            if (isset($aParams['Latitude']) && isset($aParams['Longitude']))
+            {
+                $aParams['Latitude'] = str_replace('&nbsp;',' ',$aParams['Latitude']);
+                $aParams['Longitude'] = str_replace('&nbsp;',' ',$aParams['Longitude']);
+                if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([NS]) to ([0-9]+)°( ([0-9]+)′)? ([NS])#', $aParams['Latitude'], $aMatch))
+                {
+                    $aPageProperties['fLat'] =
+                        (degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4])
+                        +degreesAndMinutesToDecimal($aMatch[5], $aMatch[7], 0, $aMatch[8])) / 2;
+                }
+                else if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([NS])#', $aParams['Latitude'], $aMatch))
+                {
+                    $aPageProperties['fLat'] = degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4]);
+                }
+
+                if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([EW]) to ([0-9]+)°( ([0-9]+)′)? ([EW])#', $aParams['Longitude'], $aMatch))
+                {
+                    $aPageProperties['fLon'] =
+                        (degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4])
+                        +degreesAndMinutesToDecimal($aMatch[5], $aMatch[7], 0, $aMatch[8])) / 2;
+                }
+                else if (preg_match('#^([0-9]+)°( ([0-9]+)′)? ([EW])#', $aParams['Longitude'], $aMatch))
+                {
+                    $aPageProperties['fLon'] = degreesAndMinutesToDecimal($aMatch[1], $aMatch[3], 0, $aMatch[4]);
+                }
+            }
+        }
+    }
+    if (isset($aPageProperties['sPossibleInfoboxType']))
+    {
+        if (!isset($aPageProperties['sInfoboxType'])) $aPageProperties['sInfoboxType'] = '#'.$aPageProperties['sPossibleInfoboxType'];
+        unset($aPageProperties['sPossibleInfoboxType']);
+    }
+    return $aPageProperties;
+}
+
+if (isset($aCMDResult['parse-wikipedia']))
+{
+    $oDB =& getDB();
+    $aArticleNames = $oDB->getCol('select page_title from content where page_namespace = 0 and page_id %10 = '.$aCMDResult['parse-wikipedia'].' and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\'))');
+//      $aArticleNames = $oDB->getCol($sSQL = 'select page_title from content where page_namespace = 0 and (page_content ilike \'%{{Coord%\' or (page_content ilike \'%lat%\' and page_content ilike \'%lon%\')) and page_title in (\'Virginia\')');
+    foreach($aArticleNames as $sArticleName)
+    {
+        $sPageText = $oDB->getOne('select page_content from content where page_namespace = 0 and page_title = \''.pg_escape_string($sArticleName).'\'');
+        $aP = _templatesToProperties(_parseWikipediaContent($sPageText));
+
+        if (isset($aP['sInfoboxType']))
+        {
+            $aP['sInfoboxType'] = preg_replace('#\\s+#',' ',$aP['sInfoboxType']);
+            $sSQL = 'update wikipedia_article set ';
+            $sSQL .= 'infobox_type = \''.pg_escape_string($aP['sInfoboxType']).'\'';
+            $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
+            $oDB->query($sSQL);
+        }
+        if (isset($aP['iPopulation']))
+        {
+            $sSQL = 'update wikipedia_article set ';
+            $sSQL .= 'population = \''.pg_escape_string($aP['iPopulation']).'\'';
+            $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
+            $oDB->query($sSQL);
+        }
+        if (isset($aP['sWebsite']))
+        {
+            $sSQL = 'update wikipedia_article set ';
+            $sSQL .= 'website = \''.pg_escape_string($aP['sWebsite']).'\'';
+            $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
+            $oDB->query($sSQL);
+        }
+        if (isset($aP['fLat']) && ($aP['fLat']!='-0' || $aP['fLon']!='-0'))
+        {
+            if (!isset($aP['sInfoboxType'])) $aP['sInfoboxType'] = '';
+            echo $sArticleName.'|'.$aP['sInfoboxType'].'|'.$aP['fLat'].'|'.$aP['fLon'] ."\n";
+            $sSQL = 'update wikipedia_article set ';
+            $sSQL .= 'lat = \''.pg_escape_string($aP['fLat']).'\',';
+            $sSQL .= 'lon = \''.pg_escape_string($aP['fLon']).'\'';
+            $sSQL .= ' where language = \'en\' and title = \''.pg_escape_string($sArticleName).'\';';
+            $oDB->query($sSQL);
+        }
+    }
+}
+
+function nominatimXMLStart($hParser, $sName, $aAttr)
+{
+        global $aNominatRecords;
+        switch($sName)
+        {
+        case 'PLACE':
+                $aNominatRecords[] = $aAttr;
+                break;
+        }
+}
+
+function nominatimXMLEnd($hParser, $sName)
+{
+}
+
+
+if (isset($aCMDResult['link']))
+{
+    $oDB =& getDB();
+    $aWikiArticles = $oDB->getAll("select * from wikipedia_article where language = 'en' and lat is not null and osm_type is null and totalcount < 31 order by importance desc limit 200000");
+
+    // If you point this script at production OSM you will be blocked
+    $sNominatimBaseURL = 'http://SEVERNAME/search.php';
+
+    foreach($aWikiArticles as $aRecord)
+    {
+        $aRecord['name'] = str_replace('_',' ',$aRecord['title']);
+
+        $sURL = $sNominatimBaseURL.'?format=xml&accept-language=en';
+
+        echo "\n-- ".$aRecord['name'].", ".$aRecord['infobox_type']."\n";
+        $fMaxDist = 0.0000001;
+        $bUnknown = false;
+        switch(strtolower($aRecord['infobox_type']))
+        {
+        case 'former country':
+            continue 2;
+        case 'sea':
+            $fMaxDist = 60; // effectively turn it off
+            $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
+            break;
+        case 'country':
+        case 'island':
+        case 'islands':
+        case 'continent':
+            $fMaxDist = 60; // effectively turn it off
+            $sURL .= "&featuretype=country";
+            $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
+            break;
+        case 'prefecture japan':
+            $aRecord['name'] = trim(str_replace(' Prefecture',' ', $aRecord['name']));
+        case 'state':
+        case '#us state':
+        case 'county':
+        case 'u.s. state':
+        case 'u.s. state symbols':
+        case 'german state':
+        case 'province or territory of canada';
+        case 'indian jurisdiction';
+        case 'province';
+        case 'french region':
+        case 'region of italy':
+        case 'kommune':
+        case '#australia state or territory':
+        case 'russian federal subject':
+            $fMaxDist = 4;
+            $sURL .= "&featuretype=state";
+            $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
+            break;
+        case 'protected area':
+            $fMaxDist = 1;
+            $sURL .= "&nearlat=".$aRecord['lat'];
+            $sURL .= "&nearlon=".$aRecord['lon'];
+            $sURL .= "&viewbox=".($aRecord['lon']-$fMaxDist).",".($aRecord['lat']+$fMaxDist).",".($aRecord['lon']+$fMaxDist).",".($aRecord['lat']-$fMaxDist);
+            break;
+        case 'settlement':
+            $bUnknown = true;
+        case 'french commune':
+        case 'italian comune':
+        case 'uk place':
+        case 'italian comune':
+        case 'australian place':
+        case 'german place':
+        case '#geobox':
+        case 'u.s. county':
+        case 'municipality':
+        case 'city japan':
+        case 'russian inhabited locality':
+        case 'finnish municipality/land area':
+        case 'england county':
+        case 'israel municipality':
+        case 'russian city':
+        case 'city':
+            $fMaxDist = 0.2;
+            $sURL .= "&featuretype=settlement";
+            $sURL .= "&viewbox=".($aRecord['lon']-0.5).",".($aRecord['lat']+0.5).",".($aRecord['lon']+0.5).",".($aRecord['lat']-0.5);
+            break;
+        case 'mountain':
+        case 'mountain pass':
+        case 'river':
+        case 'lake':
+        case 'airport':
+            $fMaxDist = 0.2;
+            $sURL .= "&viewbox=".($aRecord['lon']-0.5).",".($aRecord['lat']+0.5).",".($aRecord['lon']+0.5).",".($aRecord['lat']-0.5);
+
+        case 'ship begin':
+            $fMaxDist = 0.1;
+            $aTypes = array('wreck');
+            $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
+            $sURL .= "&nearlat=".$aRecord['lat'];
+            $sURL .= "&nearlon=".$aRecord['lon'];
+            break;
+        case 'road':
+        case 'university':
+        case 'company':
+        case 'department':
+            $fMaxDist = 0.005;
+            $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
+            $sURL .= "&bounded=1";
+            $sURL .= "&nearlat=".$aRecord['lat'];
+            $sURL .= "&nearlon=".$aRecord['lon'];
+            break;
+        default:
+            $bUnknown = true;
+            $fMaxDist = 0.005;
+            $sURL .= "&viewbox=".($aRecord['lon']-0.01).",".($aRecord['lat']+0.01).",".($aRecord['lon']+0.01).",".($aRecord['lat']-0.01);
+//              $sURL .= "&bounded=1";
+            $sURL .= "&nearlat=".$aRecord['lat'];
+            $sURL .= "&nearlon=".$aRecord['lon'];
+            echo "-- Unknown: ".$aRecord['infobox_type']."\n";
+            break;
+        }
+        $sNameURL = $sURL.'&q='.urlencode($aRecord['name']);
+
+        var_Dump($sNameURL);
+        $sXML = file_get_contents($sNameURL);
+
+        $aNominatRecords = array();
+        $hXMLParser = xml_parser_create();
+        xml_set_element_handler($hXMLParser, 'nominatimXMLStart', 'nominatimXMLEnd');
+        xml_parse($hXMLParser, $sXML, true);
+        xml_parser_free($hXMLParser);
+
+        if (!isset($aNominatRecords[0]))
+        {
+            $aNameParts = preg_split('#[(,]#',$aRecord['name']);
+            if (sizeof($aNameParts) > 1)
+            {
+                $sNameURL = $sURL.'&q='.urlencode(trim($aNameParts[0]));
+                var_Dump($sNameURL);
+                $sXML = file_get_contents($sNameURL);
+
+                $aNominatRecords = array();
+                $hXMLParser = xml_parser_create();
+                xml_set_element_handler($hXMLParser, 'nominatimXMLStart', 'nominatimXMLEnd');
+                xml_parse($hXMLParser, $sXML, true);
+                xml_parser_free($hXMLParser);#
+            }
+        }
+
+        // assume first is best/right
+        for($i = 0; $i < sizeof($aNominatRecords); $i++)
+        {
+            $fDiff = ($aRecord['lat']-$aNominatRecords[$i]['LAT']) * ($aRecord['lat']-$aNominatRecords[$i]['LAT']);
+            $fDiff += ($aRecord['lon']-$aNominatRecords[$i]['LON']) * ($aRecord['lon']-$aNominatRecords[$i]['LON']);
+            $fDiff = sqrt($fDiff);
+            if ($bUnknown) {
+                // If it was an unknown type base it on the rank of the found result
+                $iRank = (int)$aNominatRecords[$i]['PLACE_RANK'];
+                if ($iRank <= 4) $fMaxDist = 2;
+                elseif ($iRank <= 8) $fMaxDist = 1;
+                elseif ($iRank <= 10) $fMaxDist = 0.8;
+                elseif ($iRank <= 12) $fMaxDist = 0.6;
+                elseif ($iRank <= 17) $fMaxDist = 0.2;
+                elseif ($iRank <= 18) $fMaxDist = 0.1;
+                elseif ($iRank <= 22) $fMaxDist = 0.02;
+                elseif ($iRank <= 26) $fMaxDist = 0.001;
+                else $fMaxDist = 0.001;
+            }
+            echo "-- FOUND \"".substr($aNominatRecords[$i]['DISPLAY_NAME'],0,50)."\", ".$aNominatRecords[$i]['CLASS'].", ".$aNominatRecords[$i]['TYPE'].", ".$aNominatRecords[$i]['PLACE_RANK'].", ".$aNominatRecords[$i]['OSM_TYPE']." (dist:$fDiff, max:$fMaxDist)\n";
+            if ($fDiff > $fMaxDist)
+            {
+                echo "-- Diff too big $fDiff (max: $fMaxDist)".$aRecord['lat'].','.$aNominatRecords[$i]['LAT'].' & '.$aRecord['lon'].','.$aNominatRecords[$i]['LON']." \n";
+            }
+            else
+            {
+                $sSQL = "update wikipedia_article set osm_type=";
+                switch($aNominatRecords[$i]['OSM_TYPE'])
+                {
+                case 'relation': $sSQL .= "'R'"; break;
+                case 'way': $sSQL .= "'W'"; break;
+                case 'node': $sSQL .= "'N'"; break;
+                }
+                $sSQL .= ", osm_id=".$aNominatRecords[$i]['OSM_ID']." where language = '".pg_escape_string($aRecord['language'])."' and title = '".pg_escape_string($aRecord['title'])."'";
+                $oDB->query($sSQL);
+                break;
+            }
+        }
+    }
+}
index 0a15e2d016909a7bbd5657a4e08dac28a3b40151..f053499c0d830d6c3f2d550df7564fb9ef373a3c 100755 (executable)
@@ -11,32 +11,32 @@ echo "CREATE TABLE wikipedia_redirect (language text, from_title text, to_title
 
 for i in "${language[@]}"
 do
-       wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-page.sql.gz
-       wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-pagelinks.sql.gz
-       wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-langlinks.sql.gz
-       wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-redirect.sql.gz
+    wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-page.sql.gz
+    wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-pagelinks.sql.gz
+    wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-langlinks.sql.gz
+    wget http://dumps.wikimedia.org/${i}wiki/latest/${i}wiki-latest-redirect.sql.gz
 done
 
 for i in "${language[@]}"
 do
-  gzip -dc ${i}wiki-latest-pagelinks.sql.gz | sed "s/\`pagelinks\`/\`${i}pagelinks\`/g" | $mysql2pgsqlcmd | $psqlcmd
-  gzip -dc ${i}wiki-latest-page.sql.gz | sed "s/\`page\`/\`${i}page\`/g" | $mysql2pgsqlcmd | $psqlcmd
-  gzip -dc ${i}wiki-latest-langlinks.sql.gz | sed "s/\`langlinks\`/\`${i}langlinks\`/g" | $mysql2pgsqlcmd | $psqlcmd
-  gzip -dc ${i}wiki-latest-redirect.sql.gz | sed "s/\`redirect\`/\`${i}redirect\`/g" | $mysql2pgsqlcmd | $psqlcmd
+    gzip -dc ${i}wiki-latest-pagelinks.sql.gz | sed "s/\`pagelinks\`/\`${i}pagelinks\`/g" | $mysql2pgsqlcmd | $psqlcmd
+    gzip -dc ${i}wiki-latest-page.sql.gz | sed "s/\`page\`/\`${i}page\`/g" | $mysql2pgsqlcmd | $psqlcmd
+    gzip -dc ${i}wiki-latest-langlinks.sql.gz | sed "s/\`langlinks\`/\`${i}langlinks\`/g" | $mysql2pgsqlcmd | $psqlcmd
+    gzip -dc ${i}wiki-latest-redirect.sql.gz | sed "s/\`redirect\`/\`${i}redirect\`/g" | $mysql2pgsqlcmd | $psqlcmd
 done
 
 for i in "${language[@]}"
 do
-  echo "create table ${i}pagelinkcount as select pl_title as title,count(*) as count from ${i}pagelinks where pl_namespace = 0 group by pl_title;" | $psqlcmd
-  echo "insert into linkcounts select '${i}',pl_title,count(*) from ${i}pagelinks where pl_namespace = 0 group by pl_title;" | $psqlcmd
-  echo "insert into wikipedia_redirect select '${i}',page_title,rd_title from ${i}redirect join ${i}page on (rd_from = page_id) where page_namespace = 0 and rd_namespace = 0;" | $psqlcmd
-  echo "alter table ${i}pagelinkcount add column othercount integer;" | $psqlcmd
-  echo "update ${i}pagelinkcount set othercount = 0;" | $psqlcmd
-  for j in "${language[@]}"
-  do
-    echo "update ${i}pagelinkcount set othercount = ${i}pagelinkcount.othercount + x.count from (select page_title as title,count from ${i}langlinks join ${i}page on (ll_from = page_id) join ${j}pagelinkcount on (ll_lang = '${j}' and ll_title = title)) as x where x.title = ${i}pagelinkcount.title;" | $psqlcmd
-  done
-  echo "insert into wikipedia_article select '${i}', title, count, othercount, count+othercount from ${i}pagelinkcount;" | $psqlcmd
+    echo "create table ${i}pagelinkcount as select pl_title as title,count(*) as count from ${i}pagelinks where pl_namespace = 0 group by pl_title;" | $psqlcmd
+    echo "insert into linkcounts select '${i}',pl_title,count(*) from ${i}pagelinks where pl_namespace = 0 group by pl_title;" | $psqlcmd
+    echo "insert into wikipedia_redirect select '${i}',page_title,rd_title from ${i}redirect join ${i}page on (rd_from = page_id) where page_namespace = 0 and rd_namespace = 0;" | $psqlcmd
+    echo "alter table ${i}pagelinkcount add column othercount integer;" | $psqlcmd
+    echo "update ${i}pagelinkcount set othercount = 0;" | $psqlcmd
+    for j in "${language[@]}"
+    do
+        echo "update ${i}pagelinkcount set othercount = ${i}pagelinkcount.othercount + x.count from (select page_title as title,count from ${i}langlinks join ${i}page on (ll_from = page_id) join ${j}pagelinkcount on (ll_lang = '${j}' and ll_title = title)) as x where x.title = ${i}pagelinkcount.title;" | $psqlcmd
+    done
+    echo "insert into wikipedia_article select '${i}', title, count, othercount, count+othercount from ${i}pagelinkcount;" | $psqlcmd
 done
 
 echo "update wikipedia_article set importance = log(totalcount)/log((select max(totalcount) from wikipedia_article))" | $psqlcmd
index a3a4848e9d0c5eb62031a1690b7b598c115ca44e..8b03bf1247181b65b6a695aa94b2e082fe04a673 100755 (executable)
@@ -1,61 +1,61 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
-
-       $aCMDOptions = array(
-               "Create and setup nominatim search system",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-
-               array('parse-tiger', '', 0, 1, 1, 1, 'realpath', 'Convert tiger edge files to nominatim sql import - datafiles from 2011 or later (source: edges directory of tiger data)'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
-
-
-       if (isset($aCMDResult['parse-tiger']))
-       {
-               if (!file_exists(CONST_Tiger_Data_Path)) mkdir(CONST_Tiger_Data_Path);
-
-               $sTempDir = tempnam('/tmp', 'tiger');
-               unlink($sTempDir);
-               mkdir($sTempDir);
-
-               foreach(glob($aCMDResult['parse-tiger'].'/tl_20??_?????_edges.zip', 0) as $sImportFile)
-               {
-                       set_time_limit(30);
-                       preg_match('#([0-9]{5})_(.*)#',basename($sImportFile), $aMatch);
-                       $sCountyID = $aMatch[1];
-                       echo "Processing ".$sCountyID."...\n";
-                       $sUnzipCmd = "unzip -d $sTempDir $sImportFile";
-                       exec($sUnzipCmd);
-                       $sShapeFile = $sTempDir.'/'.basename($sImportFile, '.zip').'.shp';
-                       if (!file_exists($sShapeFile))
-                       {
-                               echo "Failed unzip ($sImportFile)\n";
-                       }
-                       else
-                       {
-                               $sParseCmd = CONST_BasePath.'/utils/tigerAddressImport.py '.$sShapeFile;
-                               exec($sParseCmd);
-                               $sOsmFile = $sTempDir.'/'.basename($sImportFile, '.zip').'.osm1.osm';
-                               if (!file_exists($sOsmFile))
-                               {
-                                       echo "Failed parse ($sImportFile)\n";
-                               }
-                               else
-                               {
-                                       copy($sOsmFile, CONST_Tiger_Data_Path.'/'.$sCountyID.'.sql');
-                               }
-                       }
-                       // Cleanup
-                       foreach(glob($sTempDir.'/*') as $sTmpFile)
-                       {
-                               unlink($sTmpFile);
-                       }
-
-               }
-       }
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
+
+$aCMDOptions = array(
+    "Create and setup nominatim search system",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+
+    array('parse-tiger', '', 0, 1, 1, 1, 'realpath', 'Convert tiger edge files to nominatim sql import - datafiles from 2011 or later (source: edges directory of tiger data)'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+
+
+if (isset($aCMDResult['parse-tiger']))
+{
+    if (!file_exists(CONST_Tiger_Data_Path)) mkdir(CONST_Tiger_Data_Path);
+
+    $sTempDir = tempnam('/tmp', 'tiger');
+    unlink($sTempDir);
+    mkdir($sTempDir);
+
+    foreach(glob($aCMDResult['parse-tiger'].'/tl_20??_?????_edges.zip', 0) as $sImportFile)
+    {
+        set_time_limit(30);
+        preg_match('#([0-9]{5})_(.*)#',basename($sImportFile), $aMatch);
+        $sCountyID = $aMatch[1];
+        echo "Processing ".$sCountyID."...\n";
+        $sUnzipCmd = "unzip -d $sTempDir $sImportFile";
+        exec($sUnzipCmd);
+        $sShapeFile = $sTempDir.'/'.basename($sImportFile, '.zip').'.shp';
+        if (!file_exists($sShapeFile))
+        {
+            echo "Failed unzip ($sImportFile)\n";
+        }
+        else
+        {
+            $sParseCmd = CONST_BasePath.'/utils/tigerAddressImport.py '.$sShapeFile;
+            exec($sParseCmd);
+            $sOsmFile = $sTempDir.'/'.basename($sImportFile, '.zip').'.osm1.osm';
+            if (!file_exists($sOsmFile))
+            {
+                echo "Failed parse ($sImportFile)\n";
+            }
+            else
+            {
+                copy($sOsmFile, CONST_Tiger_Data_Path.'/'.$sCountyID.'.sql');
+            }
+        }
+        // Cleanup
+        foreach(glob($sTempDir.'/*') as $sTmpFile)
+        {
+            unlink($sTmpFile);
+        }
+
+    }
+}
index a3f51f74604632b5a80f15b47b20ac8439690f90..06d7f13b162840b5cb512b92b1d7858bc53ac0d3 100755 (executable)
@@ -1,55 +1,52 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       require_once(CONST_BasePath.'/lib/Geocode.php');
-       require_once(CONST_BasePath.'/lib/ParameterParser.php');
-       ini_set('memory_limit', '800M');
-
-       $aCMDOptions = array(
-               "Query database from command line. Returns search result as JSON.",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-
-               array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'),
-
-               array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'),
-               array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'),
-               array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'),
-               array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'),
-               array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'),
-               array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'),
-               array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'),
-               array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box')
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
-
-       $oDB =& getDB();
-       $oParams = new ParameterParser($aCMDResult);
-
-       if ($oParams->getBool('search'))
-       {
-               if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false';
-
-               $oGeocode = new Geocode($oDB);
-
-               $oGeocode->setLanguagePreference($oParams->getPreferredLanguages(false));
-               $oGeocode->loadParamArray($oParams);
-               $oGeocode->setQuery($aCMDResult['search']);
-
-               $aSearchResults = $oGeocode->lookup();
-
-               if (version_compare(phpversion(), "5.4.0", '<'))
-                       echo json_encode($aSearchResults);
-               else
-                       echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n";
-       }
-       else
-       {
-               showUsage($aCMDOptions, true);
-       }
-
-
-
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+require_once(CONST_BasePath.'/lib/Geocode.php');
+require_once(CONST_BasePath.'/lib/ParameterParser.php');
+ini_set('memory_limit', '800M');
+
+$aCMDOptions = array(
+    "Query database from command line. Returns search result as JSON.",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+
+    array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'),
+
+    array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'),
+    array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'),
+    array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'),
+    array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'),
+    array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'),
+    array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'),
+    array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'),
+    array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box')
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+
+$oDB =& getDB();
+$oParams = new ParameterParser($aCMDResult);
+
+if ($oParams->getBool('search'))
+{
+    if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false';
+
+    $oGeocode = new Geocode($oDB);
+
+    $oGeocode->setLanguagePreference($oParams->getPreferredLanguages(false));
+    $oGeocode->loadParamArray($oParams);
+    $oGeocode->setQuery($aCMDResult['search']);
+
+    $aSearchResults = $oGeocode->lookup();
+
+    if (version_compare(phpversion(), "5.4.0", '<'))
+        echo json_encode($aSearchResults);
+    else
+        echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n";
+}
+else
+{
+    showUsage($aCMDOptions, true);
+}
index 8464677d134ded396f7255079c5f1af19c9c284f..8564ae577c2ca2d21e028ff42dc5d52dec6a6757 100755 (executable)
@@ -1,78 +1,78 @@
 #!/usr/bin/php -Cq
 <?php
 
-       // Apache log file
-       $sFile = "sample.log.txt";
-       $sHost1 = 'http://mq-open-search-lm02.ihost.aol.com:8000/nominatim/v1';
-       $sHost2 = 'http://mq-open-search-lm03.ihost.aol.com:8000/nominatim/v1';
+// Apache log file
+$sFile = "sample.log.txt";
+$sHost1 = 'http://mq-open-search-lm02.ihost.aol.com:8000/nominatim/v1';
+$sHost2 = 'http://mq-open-search-lm03.ihost.aol.com:8000/nominatim/v1';
 
 
-       $sHost1Escaped = str_replace('/', '\\/', $sHost1);
-       $sHost2Escaped = str_replace('/', '\\/', $sHost2);
+$sHost1Escaped = str_replace('/', '\\/', $sHost1);
+$sHost2Escaped = str_replace('/', '\\/', $sHost2);
 
-       $aToDo = array(251, 293, 328, 399.1, 455.1, 479, 496, 499, 574, 609, 702, 790, 846, 865, 878, 894, 902, 961, 980);
+$aToDo = array(251, 293, 328, 399.1, 455.1, 479, 496, 499, 574, 609, 702, 790, 846, 865, 878, 894, 902, 961, 980);
 
-       $hFile = @fopen($sFile, "r");
-       if (!$hFile)
-       {
-               echo "Unable to open file: $sFile\n";
-               exit;
-       }
+$hFile = @fopen($sFile, "r");
+if (!$hFile)
+{
+    echo "Unable to open file: $sFile\n";
+    exit;
+}
 
-       $i = 0;
-       while (($sLine = fgets($hFile, 10000)) !== false)
-       {
-               $i++;
-               if (!in_array($i, $aToDo)) continue;
+$i = 0;
+while (($sLine = fgets($hFile, 10000)) !== false)
+{
+    $i++;
+    if (!in_array($i, $aToDo)) continue;
 
-               if (preg_match('#"GET (.*) HTTP/1.[01]"#', $sLine, $aResult))
-               {
-                       $sURL1 = $sHost1.$aResult[1];
-                       $sURL2 = $sHost2.$aResult[1];
+    if (preg_match('#"GET (.*) HTTP/1.[01]"#', $sLine, $aResult))
+    {
+        $sURL1 = $sHost1.$aResult[1];
+        $sURL2 = $sHost2.$aResult[1];
 
-                       $sRes1 = '';
-                       $k = 0;
-                       while(!$sRes1 && $k < 10)
-                       {
-                               $sRes1 = file_get_contents($sURL1);
-                               $k++;
-                               if (!$sRes1) sleep(10);
-                       }
-                       $sRes2 = file_get_contents($sURL2);
+        $sRes1 = '';
+        $k = 0;
+        while(!$sRes1 && $k < 10)
+        {
+            $sRes1 = file_get_contents($sURL1);
+            $k++;
+            if (!$sRes1) sleep(10);
+        }
+        $sRes2 = file_get_contents($sURL2);
 
-                       // Strip out the things that will always change
-                       $sRes1 =  preg_replace('# timestamp=\'[^\']*\'#', '', $sRes1);
-                       $sRes1 =  str_replace($sHost1, '', $sRes1);
-                       $sRes1 =  str_replace($sHost1Escaped, '', $sRes1);
-                       $sRes2 =  preg_replace('# timestamp=\'[^\']*\'#', '', $sRes2);
-                       $sRes2 =  str_replace($sHost2, '', $sRes2);
-                       $sRes2 =  str_replace($sHost2Escaped, '', $sRes2);
+        // Strip out the things that will always change
+        $sRes1 =  preg_replace('# timestamp=\'[^\']*\'#', '', $sRes1);
+        $sRes1 =  str_replace($sHost1, '', $sRes1);
+        $sRes1 =  str_replace($sHost1Escaped, '', $sRes1);
+        $sRes2 =  preg_replace('# timestamp=\'[^\']*\'#', '', $sRes2);
+        $sRes2 =  str_replace($sHost2, '', $sRes2);
+        $sRes2 =  str_replace($sHost2Escaped, '', $sRes2);
 
-                       if ($sRes1 != $sRes2)
-                       {
-                               echo "$i:\n";
-                               var_dump($sURL1, $sURL2);
+        if ($sRes1 != $sRes2)
+        {
+            echo "$i:\n";
+            var_dump($sURL1, $sURL2);
 
-                               $sRes = $sURL1.":\n";
-                               for ($j = 0; $j < strlen($sRes1); $j+=40)
-                               {
-                                       $sRes  .= substr($sRes1, $j, 40)."\n";
-                               }
-                               file_put_contents('log/'.$i.'.1', $sRes);
+            $sRes = $sURL1.":\n";
+            for ($j = 0; $j < strlen($sRes1); $j+=40)
+            {
+                $sRes  .= substr($sRes1, $j, 40)."\n";
+            }
+            file_put_contents('log/'.$i.'.1', $sRes);
 
-                               $sRes = $sURL2.":\n";
-                               for ($j = 0; $j < strlen($sRes2); $j+=40)
-                               {
-                                       $sRes  .= substr($sRes2, $j, 40)."\n";
-                               }
-                               file_put_contents('log/'.$i.'.2', $sRes);
-                       }
-                       echo ".\n";
-               }
-               else
-               {
-                       var_dump($sLine);
-               }
-       }
+            $sRes = $sURL2.":\n";
+            for ($j = 0; $j < strlen($sRes2); $j+=40)
+            {
+                $sRes  .= substr($sRes2, $j, 40)."\n";
+            }
+            file_put_contents('log/'.$i.'.2', $sRes);
+        }
+        echo ".\n";
+    }
+    else
+    {
+        var_dump($sLine);
+    }
+}
 
-       fclose($hFile);
+fclose($hFile);
index 992034c77943cbbe94e5603894cc73722b13a5a4..9dc499be4d7a082bf9c0d8c66323fceb94d3e8e0 100755 (executable)
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
-
-       $aCMDOptions = array(
-               "Create and setup nominatim search system",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-
-               array('osm-file', '', 0, 1, 1, 1, 'realpath', 'File to import'),
-               array('threads', '', 0, 1, 1, 1, 'int', 'Number of threads (where possible)'),
-
-               array('all', '', 0, 1, 0, 0, 'bool', 'Do the complete process'),
-
-               array('create-db', '', 0, 1, 0, 0, 'bool', 'Create nominatim db'),
-               array('setup-db', '', 0, 1, 0, 0, 'bool', 'Build a blank nominatim db'),
-               array('import-data', '', 0, 1, 0, 0, 'bool', 'Import a osm file'),
-               array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
-               array('create-functions', '', 0, 1, 0, 0, 'bool', 'Create functions'),
-               array('enable-diff-updates', '', 0, 1, 0, 0, 'bool', 'Turn on the code required to make diff updates work'),
-               array('enable-debug-statements', '', 0, 1, 0, 0, 'bool', 'Include debug warning statements in pgsql commands'),
-               array('ignore-errors', '', 0, 1, 0, 0, 'bool', 'Continue import even when errors in SQL are present (EXPERT)'),
-               array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create main tables'),
-               array('create-partition-tables', '', 0, 1, 0, 0, 'bool', 'Create required partition tables'),
-               array('create-partition-functions', '', 0, 1, 0, 0, 'bool', 'Create required partition triggers'),
-               array('no-partitions', '', 0, 1, 0, 0, 'bool', "Do not partition search indices (speeds up import of single country extracts)"),
-               array('import-wikipedia-articles', '', 0, 1, 0, 0, 'bool', 'Import wikipedia article dump'),
-               array('load-data', '', 0, 1, 0, 0, 'bool', 'Copy data to live tables from import table'),
-               array('disable-token-precalc', '', 0, 1, 0, 0, 'bool', 'Disable name precalculation (EXPERT)'),
-               array('import-tiger-data', '', 0, 1, 0, 0, 'bool', 'Import tiger data (not included in \'all\')'),
-               array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Calculate postcode centroids'),
-               array('osmosis-init', '', 0, 1, 0, 0, 'bool', 'Generate default osmosis configuration'),
-               array('index', '', 0, 1, 0, 0, 'bool', 'Index the data'),
-               array('index-noanalyse', '', 0, 1, 0, 0, 'bool', 'Do not perform analyse operations during index (EXPERT)'),
-               array('create-search-indices', '', 0, 1, 0, 0, 'bool', 'Create additional indices required for search and update'),
-               array('drop', '', 0, 1, 0, 0, 'bool', 'Drop tables needed for updates, making the database readonly (EXPERIMENTAL)'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
-
-       $bDidSomething = false;
-
-       // Check if osm-file is set and points to a valid file if --all or --import-data is given
-       if ($aCMDResult['import-data'] || $aCMDResult['all'])
-       {
-               if (!isset($aCMDResult['osm-file']))
-               {
-                       fail('missing --osm-file for data import');
-               }
-
-               if (!file_exists($aCMDResult['osm-file']))
-               {
-                       fail('the path supplied to --osm-file does not exist');
-               }
-
-               if (!is_readable($aCMDResult['osm-file']))
-               {
-                       fail('osm-file "'.$aCMDResult['osm-file'].'" not readable');
-               }
-       }
-
-
-       // This is a pretty hard core default - the number of processors in the box - 1
-       $iInstances = isset($aCMDResult['threads'])?$aCMDResult['threads']:(getProcessorCount()-1);
-       if ($iInstances < 1)
-       {
-               $iInstances = 1;
-               echo "WARNING: resetting threads to $iInstances\n";
-       }
-       if ($iInstances > getProcessorCount())
-       {
-               $iInstances = getProcessorCount();
-               echo "WARNING: resetting threads to $iInstances\n";
-       }
-
-       // Assume we can steal all the cache memory in the box (unless told otherwise)
-       if (isset($aCMDResult['osm2pgsql-cache']))
-       {
-               $iCacheMemory = $aCMDResult['osm2pgsql-cache'];
-       }
-       else
-       {
-               $iCacheMemory = getCacheMemoryMB();
-       }
-
-       $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-       if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-
-       if ($aCMDResult['create-db'] || $aCMDResult['all'])
-       {
-               echo "Create DB\n";
-               $bDidSomething = true;
-               $oDB = DB::connect(CONST_Database_DSN, false);
-               if (!PEAR::isError($oDB))
-               {
-                       fail('database already exists ('.CONST_Database_DSN.')');
-               }
-               passthruCheckReturn('createdb -E UTF-8 -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']);
-       }
-
-       if ($aCMDResult['setup-db'] || $aCMDResult['all'])
-       {
-               echo "Setup DB\n";
-               $bDidSomething = true;
-               // TODO: path detection, detection memory, etc.
-
-               $oDB =& getDB();
-
-               $fPostgresVersion = getPostgresVersion($oDB);
-               echo 'Postgres version found: '.$fPostgresVersion."\n";
-
-               if ($fPostgresVersion < 9.1)
-               {
-                       fail("Minimum supported version of Postgresql is 9.1.");
-               }
-
-               pgsqlRunScript('CREATE EXTENSION IF NOT EXISTS hstore');
-               pgsqlRunScript('CREATE EXTENSION IF NOT EXISTS postgis');
-
-               // For extratags and namedetails the hstore_to_json converter is
-               // needed which is only available from Postgresql 9.3+. For older
-               // versions add a dummy function that returns nothing.
-               $iNumFunc = chksql($oDB->getOne("select count(*) from pg_proc where proname = 'hstore_to_json'"));
-
-               if ($iNumFunc == 0)
-               {
-                       pgsqlRunScript("create function hstore_to_json(dummy hstore) returns text AS 'select null::text' language sql immutable");
-                       echo "WARNING: Postgresql is too old. extratags and namedetails API not available.";
-               }
-
-               $fPostgisVersion = getPostgisVersion($oDB);
-               echo 'Postgis version found: '.$fPostgisVersion."\n";
-
-               if ($fPostgisVersion < 2.1)
-               {
-                       // Function was renamed in 2.1 and throws an annoying deprecation warning
-                       pgsqlRunScript('ALTER FUNCTION st_line_interpolate_point(geometry, double precision) RENAME TO ST_LineInterpolatePoint');
-               }
-
-               pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
-               pgsqlRunScriptFile(CONST_BasePath.'/data/country_naturalearthdata.sql');
-               pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql');
-               pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_table.sql');
-               if (file_exists(CONST_BasePath.'/data/gb_postcode_data.sql.gz'))
-               {
-                       pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_data.sql.gz');
-               }
-               else
-               {
-                       echo "WARNING: external UK postcode table not found.\n";
-               }
-               if (CONST_Use_Extra_US_Postcodes)
-               {
-                       pgsqlRunScriptFile(CONST_BasePath.'/data/us_postcode.sql');
-               }
-
-               if ($aCMDResult['no-partitions'])
-               {
-                       pgsqlRunScript('update country_name set partition = 0');
-               }
-
-               // the following will be needed by create_functions later but
-               // is only defined in the subsequently called create_tables.
-               // Create dummies here that will be overwritten by the proper
-               // versions in create-tables.
-               pgsqlRunScript('CREATE TABLE place_boundingbox ()');
-               pgsqlRunScript('create type wikipedia_article_match as ()');
-       }
-
-       if ($aCMDResult['import-data'] || $aCMDResult['all'])
-       {
-               echo "Import\n";
-               $bDidSomething = true;
-
-               $osm2pgsql = CONST_Osm2pgsql_Binary;
-               if (!file_exists($osm2pgsql))
-               {
-                       echo "Please download and build osm2pgsql.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n";
-                       fail("osm2pgsql not found in '$osm2pgsql'");
-               }
-
-               if (!is_null(CONST_Osm2pgsql_Flatnode_File))
-               {
-                       $osm2pgsql .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
-               }
-               if (CONST_Tablespace_Osm2pgsql_Data)
-                       $osm2pgsql .= ' --tablespace-slim-data '.CONST_Tablespace_Osm2pgsql_Data;
-               if (CONST_Tablespace_Osm2pgsql_Index)
-                       $osm2pgsql .= ' --tablespace-slim-index '.CONST_Tablespace_Osm2pgsql_Index;
-               if (CONST_Tablespace_Place_Data)
-                       $osm2pgsql .= ' --tablespace-main-data '.CONST_Tablespace_Place_Data;
-               if (CONST_Tablespace_Place_Index)
-                       $osm2pgsql .= ' --tablespace-main-index '.CONST_Tablespace_Place_Index;
-               $osm2pgsql .= ' -lsc -O gazetteer --hstore --number-processes 1';
-               $osm2pgsql .= ' -C '.$iCacheMemory;
-               $osm2pgsql .= ' -P '.$aDSNInfo['port'];
-               $osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file'];
-               passthruCheckReturn($osm2pgsql);
-
-               $oDB =& getDB();
-               if (!chksql($oDB->getRow('select * from place limit 1')))
-               {
-                       fail('No Data');
-               }
-       }
-
-       if ($aCMDResult['create-functions'] || $aCMDResult['all'])
-       {
-               echo "Functions\n";
-               $bDidSomething = true;
-               if (!file_exists(CONST_InstallPath.'/module/nominatim.so')) fail("nominatim module not built");
-               create_sql_functions($aCMDResult);
-       }
-
-       if ($aCMDResult['create-tables'] || $aCMDResult['all'])
-       {
-               $bDidSomething = true;
-
-               echo "Tables\n";
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/tables.sql');
-               $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:address-data}',
-                                               CONST_Tablespace_Address_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:address-index}',
-                                               CONST_Tablespace_Address_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:search-data}',
-                                               CONST_Tablespace_Search_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:search-index}',
-                                               CONST_Tablespace_Search_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-data}',
-                                               CONST_Tablespace_Aux_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-index}',
-                                               CONST_Tablespace_Aux_Index, $sTemplate);
-               pgsqlRunScript($sTemplate, false);
-
-               // re-run the functions
-               echo "Functions\n";
-               create_sql_functions($aCMDResult);
-       }
-
-       if ($aCMDResult['create-partition-tables'] || $aCMDResult['all'])
-       {
-               echo "Partition Tables\n";
-               $bDidSomething = true;
-
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-tables.src.sql');
-               $sTemplate = replace_tablespace('{ts:address-data}',
-                                               CONST_Tablespace_Address_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:address-index}',
-                                               CONST_Tablespace_Address_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:search-data}',
-                                               CONST_Tablespace_Search_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:search-index}',
-                                               CONST_Tablespace_Search_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-data}',
-                                               CONST_Tablespace_Aux_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-index}',
-                                               CONST_Tablespace_Aux_Index, $sTemplate);
-
-               pgsqlRunPartitionScript($sTemplate);
-       }
-
-
-       if ($aCMDResult['create-partition-functions'] || $aCMDResult['all'])
-       {
-               echo "Partition Functions\n";
-               $bDidSomething = true;
-
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-functions.src.sql');
-
-               pgsqlRunPartitionScript($sTemplate);
-       }
-
-       if ($aCMDResult['import-wikipedia-articles'] || $aCMDResult['all'])
-       {
-               $bDidSomething = true;
-               $sWikiArticlesFile = CONST_BasePath.'/data/wikipedia_article.sql.bin';
-               $sWikiRedirectsFile = CONST_BasePath.'/data/wikipedia_redirect.sql.bin';
-               if (file_exists($sWikiArticlesFile))
-               {
-                       echo "Importing wikipedia articles...";
-                       pgsqlRunDropAndRestore($sWikiArticlesFile);
-                       echo "...done\n";
-               }
-               else
-               {
-                       echo "WARNING: wikipedia article dump file not found - places will have default importance\n";
-               }
-               if (file_exists($sWikiRedirectsFile))
-               {
-                       echo "Importing wikipedia redirects...";
-                       pgsqlRunDropAndRestore($sWikiRedirectsFile);
-                       echo "...done\n";
-               }
-               else
-               {
-                       echo "WARNING: wikipedia redirect dump file not found - some place importance values may be missing\n";
-               }
-       }
-
-
-       if ($aCMDResult['load-data'] || $aCMDResult['all'])
-       {
-               echo "Drop old Data\n";
-               $bDidSomething = true;
-
-               $oDB =& getDB();
-               if (!pg_query($oDB->connection, 'TRUNCATE word')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE placex')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE location_property_osmline')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE place_addressline')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE place_boundingbox')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE location_area')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE search_name')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'TRUNCATE search_name_blank')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'DROP SEQUENCE seq_place')) fail(pg_last_error($oDB->connection));
-               echo '.';
-               if (!pg_query($oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($oDB->connection));
-               echo '.';
-
-               $sSQL = 'select distinct partition from country_name';
-               $aPartitions = chksql($oDB->getCol($sSQL));
-               if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
-               foreach($aPartitions as $sPartition)
-               {
-                       if (!pg_query($oDB->connection, 'TRUNCATE location_road_'.$sPartition)) fail(pg_last_error($oDB->connection));
-                       echo '.';
-               }
-
-               // used by getorcreate_word_id to ignore frequent partial words
-               if (!pg_query($oDB->connection, 'CREATE OR REPLACE FUNCTION get_maxwordfreq() RETURNS integer AS $$ SELECT '.CONST_Max_Word_Frequency.' as maxwordfreq; $$ LANGUAGE SQL IMMUTABLE')) fail(pg_last_error($oDB->connection));
-               echo ".\n";
-
-               // pre-create the word list
-               if (!$aCMDResult['disable-token-precalc'])
-               {
-                       echo "Loading word list\n";
-                       pgsqlRunScriptFile(CONST_BasePath.'/data/words.sql');
-               }
-
-               echo "Load Data\n";
-               $aDBInstances = array();
-               $iLoadThreads = max(1, $iInstances - 1);
-               for($i = 0; $i < $iLoadThreads; $i++)
-               {
-                       $aDBInstances[$i] =& getDB(true);
-                       $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, ';
-                       $sSQL .= 'housenumber, street, addr_place, isin, postcode, country_code, extratags, ';
-                       $sSQL .= 'geometry) select * from place where osm_id % '.$iLoadThreads.' = '.$i;
-                       $sSQL .= " and not (class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString')";
-                       if ($aCMDResult['verbose']) echo "$sSQL\n";
-                       if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
-               }
-               // last thread for interpolation lines
-               $aDBInstances[$iLoadThreads] =& getDB(true);
-               $sSQL = 'select insert_osmline (osm_id, housenumber, street, addr_place, postcode, country_code, ';
-               $sSQL .= 'geometry) from place where ';
-               $sSQL .= "class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'";
-               if ($aCMDResult['verbose']) echo "$sSQL\n";
-               if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
-
-               $bAnyBusy = true;
-               while($bAnyBusy)
-               {
-                       $bAnyBusy = false;
-                       for($i = 0; $i <= $iLoadThreads; $i++)
-                       {
-                               if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
-                       }
-                       sleep(1);
-                       echo '.';
-               }
-               echo "\n";
-               echo "Reanalysing database...\n";
-               pgsqlRunScript('ANALYSE');
-       }
-
-       if ($aCMDResult['import-tiger-data'])
-       {
-               $bDidSomething = true;
-
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_start.sql');
-               $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-data}',
-                                               CONST_Tablespace_Aux_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-index}',
-                                               CONST_Tablespace_Aux_Index, $sTemplate);
-               pgsqlRunScript($sTemplate, false);
-
-               $aDBInstances = array();
-               for($i = 0; $i < $iInstances; $i++)
-               {
-                       $aDBInstances[$i] =& getDB(true);
-               }
-
-               foreach(glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile)
-               {
-                       echo $sFile.': ';
-                       $hFile = fopen($sFile, "r");
-                       $sSQL = fgets($hFile, 100000);
-                       $iLines = 0;
-
-                       while(true)
-                       {
-                               for($i = 0; $i < $iInstances; $i++)
-                               {
-                                       if (!pg_connection_busy($aDBInstances[$i]->connection))
-                                       {
-                                               while(pg_get_result($aDBInstances[$i]->connection));
-                                               $sSQL = fgets($hFile, 100000);
-                                               if (!$sSQL) break 2;
-                                               if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
-                                               $iLines++;
-                                               if ($iLines == 1000)
-                                               {
-                                                       echo ".";
-                                                       $iLines = 0;
-                                               }
-                                       }
-                               }
-                               usleep(10);
-                       }
-
-                       fclose($hFile);
-
-                       $bAnyBusy = true;
-                       while($bAnyBusy)
-                       {
-                               $bAnyBusy = false;
-                               for($i = 0; $i < $iInstances; $i++)
-                               {
-                                       if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
-                               }
-                               usleep(10);
-                       }
-                       echo "\n";
-               }
-
-               echo "Creating indexes\n";
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_finish.sql');
-               $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-data}',
-                                               CONST_Tablespace_Aux_Data, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-index}',
-                                               CONST_Tablespace_Aux_Index, $sTemplate);
-               pgsqlRunScript($sTemplate, false);
-       }
-
-       if ($aCMDResult['calculate-postcodes'] || $aCMDResult['all'])
-       {
-               $bDidSomething = true;
-               $oDB =& getDB();
-               if (!pg_query($oDB->connection, 'DELETE from placex where osm_type=\'P\'')) fail(pg_last_error($oDB->connection));
-               $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) ";
-               $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,calculated_country_code,";
-               $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from (select calculated_country_code,postcode,";
-               $sSQL .= "avg(st_x(st_centroid(geometry))) as x,avg(st_y(st_centroid(geometry))) as y ";
-               $sSQL .= "from placex where postcode is not null group by calculated_country_code,postcode) as x";
-               if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
-
-               if (CONST_Use_Extra_US_Postcodes)
-               {
-                       $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) ";
-                       $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,'us',";
-                       $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from us_postcode";
-                       if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
-               }
-       }
-
-       if ($aCMDResult['osmosis-init'] || ($aCMDResult['all'] && !$aCMDResult['drop'])) // no use doing osmosis-init when dropping update tables
-       {
-               $bDidSomething = true;
-               $oDB =& getDB();
-
-               if (!file_exists(CONST_Osmosis_Binary))
-               {
-                       echo "Please download osmosis.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n";
-                       if (!$aCMDResult['all'])
-                       {
-                               fail("osmosis not found in '".CONST_Osmosis_Binary."'");
-                       }
-               }
-               else
-               {
-                       if (file_exists(CONST_InstallPath.'/settings/configuration.txt'))
-                       {
-                               echo "settings/configuration.txt already exists\n";
-                       }
-                       else
-                       {
-                               passthru(CONST_Osmosis_Binary.' --read-replication-interval-init '.CONST_InstallPath.'/settings');
-                               // update osmosis configuration.txt with our settings
-                               passthru("sed -i 's!baseUrl=.*!baseUrl=".CONST_Replication_Url."!' ".CONST_InstallPath.'/settings/configuration.txt');
-                               passthru("sed -i 's:maxInterval = .*:maxInterval = ".CONST_Replication_MaxInterval.":' ".CONST_InstallPath.'/settings/configuration.txt');
-                       }
-
-                       // Find the last node in the DB
-                       $iLastOSMID = $oDB->getOne("select max(osm_id) from place where osm_type = 'N'");
-
-                       // Lookup the timestamp that node was created (less 3 hours for margin for changsets to be closed)
-                       $sLastNodeURL = 'http://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID."/1";
-                       $sLastNodeXML = file_get_contents($sLastNodeURL);
-                       preg_match('#timestamp="(([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z)"#', $sLastNodeXML, $aLastNodeDate);
-                       $iLastNodeTimestamp = strtotime($aLastNodeDate[1]) - (3*60*60);
-
-                       // Search for the correct state file - uses file timestamps so need to sort by date descending
-                       $sRepURL = CONST_Replication_Url."/";
-                       $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
-                       // download.geofabrik.de:    <a href="000/">000/</a></td><td align="right">26-Feb-2013 11:53  </td>
-                       // planet.openstreetmap.org: <a href="273/">273/</a>                    2013-03-11 07:41    -
-                       preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
-                       if ($aRepMatches)
-                       {
-                               $aPrevRepMatch = false;
-                               foreach($aRepMatches as $aRepMatch)
-                               {
-                                       if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
-                                       $aPrevRepMatch = $aRepMatch;
-                               }
-                               if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
-
-                               $sRepURL .= $aRepMatch[1];
-                               $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
-                               preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
-                               $aPrevRepMatch = false;
-                               foreach($aRepMatches as $aRepMatch)
-                               {
-                                       if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
-                                       $aPrevRepMatch = $aRepMatch;
-                               }
-                               if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
-
-                               $sRepURL .= $aRepMatch[1];
-                               $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
-                               preg_match_all('#<a href="[0-9]{3}.state.txt">([0-9]{3}).state.txt</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
-                               $aPrevRepMatch = false;
-                               foreach($aRepMatches as $aRepMatch)
-                               {
-                                       if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
-                                       $aPrevRepMatch = $aRepMatch;
-                               }
-                               if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
-
-                               $sRepURL .= $aRepMatch[1].'.state.txt';
-                               echo "Getting state file: $sRepURL\n";
-                               $sStateFile = file_get_contents($sRepURL);
-                               if (!$sStateFile || strlen($sStateFile) > 1000) fail("unable to obtain state file");
-                               file_put_contents(CONST_InstallPath.'/settings/state.txt', $sStateFile);
-                               echo "Updating DB status\n";
-                               pg_query($oDB->connection, 'TRUNCATE import_status');
-                               $sSQL = "INSERT INTO import_status VALUES('".$aRepMatch[2]."')";
-                               pg_query($oDB->connection, $sSQL);
-                       }
-                       else
-                       {
-                               if (!$aCMDResult['all'])
-                               {
-                                       fail("Cannot read state file directory.");
-                               }
-                       }
-               }
-       }
-
-       if ($aCMDResult['index'] || $aCMDResult['all'])
-       {
-               $bDidSomething = true;
-               $sOutputFile = '';
-               $sBaseCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$iInstances.$sOutputFile;
-               passthruCheckReturn($sBaseCmd.' -R 4');
-               if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE');
-               passthruCheckReturn($sBaseCmd.' -r 5 -R 25');
-               if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE');
-               passthruCheckReturn($sBaseCmd.' -r 26');
-       }
-
-       if ($aCMDResult['create-search-indices'] || $aCMDResult['all'])
-       {
-               echo "Search indices\n";
-               $bDidSomething = true;
-
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/indices.src.sql');
-               $sTemplate = replace_tablespace('{ts:address-index}',
-                                               CONST_Tablespace_Address_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:search-index}',
-                                               CONST_Tablespace_Search_Index, $sTemplate);
-               $sTemplate = replace_tablespace('{ts:aux-index}',
-                                               CONST_Tablespace_Aux_Index, $sTemplate);
-
-               pgsqlRunScript($sTemplate);
-       }
-
-       if ($aCMDResult['drop'])
-       {
-               // The implementation is potentially a bit dangerous because it uses
-               // a positive selection of tables to keep, and deletes everything else.
-               // Including any tables that the unsuspecting user might have manually
-               // created. USE AT YOUR OWN PERIL.
-               $bDidSomething = true;
-
-               // tables we want to keep. everything else goes.
-               $aKeepTables = array(
-                  "*columns",
-                  "import_polygon_*",
-                  "import_status",
-                  "place_addressline",
-                  "location_property*",
-                  "placex",
-                  "search_name",
-                  "seq_*",
-                  "word",
-                  "query_log",
-                  "new_query_log",
-                  "gb_postcode",
-                  "spatial_ref_sys",
-                  "country_name",
-                  "place_classtype_*"
-               );
-
-               $oDB =& getDB();
-               $aDropTables = array();
-               $aHaveTables = chksql($oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'"));
-
-               foreach($aHaveTables as $sTable)
-               {
-                       $bFound = false;
-                       foreach ($aKeepTables as $sKeep)
-                       {
-                               if (fnmatch($sKeep, $sTable))
-                               {
-                                       $bFound = true;
-                                       break;
-                               }
-                       }
-                       if (!$bFound) array_push($aDropTables, $sTable);
-               }
-
-               foreach ($aDropTables as $sDrop)
-               {
-                       if ($aCMDResult['verbose']) echo "dropping table $sDrop\n";
-                       @pg_query($oDB->connection, "DROP TABLE $sDrop CASCADE");
-                       // ignore warnings/errors as they might be caused by a table having
-                       // been deleted already by CASCADE
-               }
-
-               if (!is_null(CONST_Osm2pgsql_Flatnode_File))
-               {
-                       if ($aCMDResult['verbose']) echo "deleting ".CONST_Osm2pgsql_Flatnode_File."\n";
-                       unlink(CONST_Osm2pgsql_Flatnode_File);
-               }
-       }
-
-       if (!$bDidSomething)
-       {
-               showUsage($aCMDOptions, true);
-       }
-       else
-       {
-               echo "Setup finished.\n";
-       }
-
-       function pgsqlRunScriptFile($sFilename)
-       {
-               if (!file_exists($sFilename)) fail('unable to find '.$sFilename);
-
-               // Convert database DSN to psql parameters
-               $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-               if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-               $sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
-
-               $ahGzipPipes = null;
-               if (preg_match('/\\.gz$/', $sFilename))
-               {
-                       $aDescriptors = array(
-                               0 => array('pipe', 'r'),
-                               1 => array('pipe', 'w'),
-                               2 => array('file', '/dev/null', 'a')
-                       );
-                       $hGzipProcess = proc_open('zcat '.$sFilename, $aDescriptors, $ahGzipPipes);
-                       if (!is_resource($hGzipProcess)) fail('unable to start zcat');
-                       $aReadPipe = $ahGzipPipes[1];
-                       fclose($ahGzipPipes[0]);
-               }
-               else
-               {
-                       $sCMD .= ' -f '.$sFilename;
-                       $aReadPipe = array('pipe', 'r');
-               }
-
-               $aDescriptors = array(
-                       0 => $aReadPipe,
-                       1 => array('pipe', 'w'),
-                       2 => array('file', '/dev/null', 'a')
-               );
-               $ahPipes = null;
-               $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
-               if (!is_resource($hProcess)) fail('unable to start pgsql');
-
-
-               // TODO: error checking
-               while(!feof($ahPipes[1]))
-               {
-                       echo fread($ahPipes[1], 4096);
-               }
-               fclose($ahPipes[1]);
-
-               $iReturn = proc_close($hProcess);
-               if ($iReturn > 0)
-               {
-                       fail("pgsql returned with error code ($iReturn)");
-               }
-               if ($ahGzipPipes)
-               {
-                       fclose($ahGzipPipes[1]);
-                       proc_close($hGzipProcess);
-               }
-
-       }
-
-       function pgsqlRunScript($sScript, $bfatal = true)
-       {
-               global $aCMDResult;
-               // Convert database DSN to psql parameters
-               $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-               if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-               $sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
-               if ($bfatal && !$aCMDResult['ignore-errors'])
-                       $sCMD .= ' -v ON_ERROR_STOP=1';
-               $aDescriptors = array(
-                       0 => array('pipe', 'r'),
-                       1 => STDOUT, 
-                       2 => STDERR
-               );
-               $ahPipes = null;
-               $hProcess = @proc_open($sCMD, $aDescriptors, $ahPipes);
-               if (!is_resource($hProcess)) fail('unable to start pgsql');
-
-               while(strlen($sScript))
-               {
-                       $written = fwrite($ahPipes[0], $sScript);
-                       if ($written <= 0) break;
-                       $sScript = substr($sScript, $written);
-               }
-               fclose($ahPipes[0]);
-               $iReturn = proc_close($hProcess);
-               if ($bfatal && $iReturn > 0)
-               {
-                       fail("pgsql returned with error code ($iReturn)");
-               }
-       }
-
-       function pgsqlRunPartitionScript($sTemplate)
-       {
-               global $aCMDResult;
-               $oDB =& getDB();
-
-               $sSQL = 'select distinct partition from country_name';
-               $aPartitions = chksql($oDB->getCol($sSQL));
-               if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
-
-               preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
-               foreach($aMatches as $aMatch)
-               {
-                       $sResult = '';
-                       foreach($aPartitions as $sPartitionName)
-                       {
-                               $sResult .= str_replace('-partition-', $sPartitionName, $aMatch[1]);
-                       }
-                       $sTemplate = str_replace($aMatch[0], $sResult, $sTemplate);
-               }
-
-               pgsqlRunScript($sTemplate);
-       }
-
-       function pgsqlRunRestoreData($sDumpFile)
-       {
-               // Convert database DSN to psql parameters
-               $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-               if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-               $sCMD = 'pg_restore -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'].' -Fc -a '.$sDumpFile;
-
-               $aDescriptors = array(
-                       0 => array('pipe', 'r'),
-                       1 => array('pipe', 'w'),
-                       2 => array('file', '/dev/null', 'a')
-               );
-               $ahPipes = null;
-               $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
-               if (!is_resource($hProcess)) fail('unable to start pg_restore');
-
-               fclose($ahPipes[0]);
-
-               // TODO: error checking
-               while(!feof($ahPipes[1]))
-               {
-                       echo fread($ahPipes[1], 4096);
-               }
-               fclose($ahPipes[1]);
-
-               $iReturn = proc_close($hProcess);
-       }
-
-       function pgsqlRunDropAndRestore($sDumpFile)
-       {
-               // Convert database DSN to psql parameters
-               $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-               if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-               $sCMD = 'pg_restore -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'].' -Fc --clean '.$sDumpFile;
-
-               $aDescriptors = array(
-                       0 => array('pipe', 'r'),
-                       1 => array('pipe', 'w'),
-                       2 => array('file', '/dev/null', 'a')
-               );
-               $ahPipes = null;
-               $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
-               if (!is_resource($hProcess)) fail('unable to start pg_restore');
-
-               fclose($ahPipes[0]);
-
-               // TODO: error checking
-               while(!feof($ahPipes[1]))
-               {
-                       echo fread($ahPipes[1], 4096);
-               }
-               fclose($ahPipes[1]);
-
-               $iReturn = proc_close($hProcess);
-       }
-
-       function passthruCheckReturn($cmd)
-       {
-               $result = -1;
-               passthru($cmd, $result);
-               if ($result != 0) fail('Error executing external command: '.$cmd);
-       }
-
-       function replace_tablespace($sTemplate, $sTablespace, $sSql)
-       {
-               if ($sTablespace)
-                       $sSql = str_replace($sTemplate, 'TABLESPACE "'.$sTablespace.'"',
-                                           $sSql);
-               else
-                       $sSql = str_replace($sTemplate, '', $sSql);
-
-               return $sSql;
-       }
-
-       function create_sql_functions($aCMDResult)
-       {
-               $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
-               $sTemplate = str_replace('{modulepath}', CONST_InstallPath.'/module', $sTemplate);
-               if ($aCMDResult['enable-diff-updates'])
-               {
-                       $sTemplate = str_replace('RETURN NEW; -- %DIFFUPDATES%', '--', $sTemplate);
-               }
-               if ($aCMDResult['enable-debug-statements'])
-               {
-                       $sTemplate = str_replace('--DEBUG:', '', $sTemplate);
-               }
-               if (CONST_Limit_Reindexing)
-               {
-                       $sTemplate = str_replace('--LIMIT INDEXING:', '', $sTemplate);
-               }
-               if (!CONST_Use_US_Tiger_Data)
-               {
-                       $sTemplate = str_replace('-- %NOTIGERDATA% ', '', $sTemplate);
-               }
-               if (!CONST_Use_Aux_Location_data)
-               {
-                       $sTemplate = str_replace('-- %NOAUXDATA% ', '', $sTemplate);
-               }
-               pgsqlRunScript($sTemplate);
-
-       }
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
+
+$aCMDOptions = array(
+    "Create and setup nominatim search system",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+
+    array('osm-file', '', 0, 1, 1, 1, 'realpath', 'File to import'),
+    array('threads', '', 0, 1, 1, 1, 'int', 'Number of threads (where possible)'),
+
+    array('all', '', 0, 1, 0, 0, 'bool', 'Do the complete process'),
+
+    array('create-db', '', 0, 1, 0, 0, 'bool', 'Create nominatim db'),
+    array('setup-db', '', 0, 1, 0, 0, 'bool', 'Build a blank nominatim db'),
+    array('import-data', '', 0, 1, 0, 0, 'bool', 'Import a osm file'),
+    array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
+    array('create-functions', '', 0, 1, 0, 0, 'bool', 'Create functions'),
+    array('enable-diff-updates', '', 0, 1, 0, 0, 'bool', 'Turn on the code required to make diff updates work'),
+    array('enable-debug-statements', '', 0, 1, 0, 0, 'bool', 'Include debug warning statements in pgsql commands'),
+    array('ignore-errors', '', 0, 1, 0, 0, 'bool', 'Continue import even when errors in SQL are present (EXPERT)'),
+    array('create-tables', '', 0, 1, 0, 0, 'bool', 'Create main tables'),
+    array('create-partition-tables', '', 0, 1, 0, 0, 'bool', 'Create required partition tables'),
+    array('create-partition-functions', '', 0, 1, 0, 0, 'bool', 'Create required partition triggers'),
+    array('no-partitions', '', 0, 1, 0, 0, 'bool', "Do not partition search indices (speeds up import of single country extracts)"),
+    array('import-wikipedia-articles', '', 0, 1, 0, 0, 'bool', 'Import wikipedia article dump'),
+    array('load-data', '', 0, 1, 0, 0, 'bool', 'Copy data to live tables from import table'),
+    array('disable-token-precalc', '', 0, 1, 0, 0, 'bool', 'Disable name precalculation (EXPERT)'),
+    array('import-tiger-data', '', 0, 1, 0, 0, 'bool', 'Import tiger data (not included in \'all\')'),
+    array('calculate-postcodes', '', 0, 1, 0, 0, 'bool', 'Calculate postcode centroids'),
+    array('osmosis-init', '', 0, 1, 0, 0, 'bool', 'Generate default osmosis configuration'),
+    array('index', '', 0, 1, 0, 0, 'bool', 'Index the data'),
+    array('index-noanalyse', '', 0, 1, 0, 0, 'bool', 'Do not perform analyse operations during index (EXPERT)'),
+    array('create-search-indices', '', 0, 1, 0, 0, 'bool', 'Create additional indices required for search and update'),
+    array('drop', '', 0, 1, 0, 0, 'bool', 'Drop tables needed for updates, making the database readonly (EXPERIMENTAL)'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+
+$bDidSomething = false;
+
+// Check if osm-file is set and points to a valid file if --all or --import-data is given
+if ($aCMDResult['import-data'] || $aCMDResult['all'])
+{
+    if (!isset($aCMDResult['osm-file']))
+    {
+        fail('missing --osm-file for data import');
+    }
+
+    if (!file_exists($aCMDResult['osm-file']))
+    {
+        fail('the path supplied to --osm-file does not exist');
+    }
+
+    if (!is_readable($aCMDResult['osm-file']))
+    {
+        fail('osm-file "'.$aCMDResult['osm-file'].'" not readable');
+    }
+}
+
+
+// This is a pretty hard core default - the number of processors in the box - 1
+$iInstances = isset($aCMDResult['threads'])?$aCMDResult['threads']:(getProcessorCount()-1);
+if ($iInstances < 1)
+{
+    $iInstances = 1;
+    echo "WARNING: resetting threads to $iInstances\n";
+}
+if ($iInstances > getProcessorCount())
+{
+    $iInstances = getProcessorCount();
+    echo "WARNING: resetting threads to $iInstances\n";
+}
+
+// Assume we can steal all the cache memory in the box (unless told otherwise)
+if (isset($aCMDResult['osm2pgsql-cache']))
+{
+    $iCacheMemory = $aCMDResult['osm2pgsql-cache'];
+}
+else
+{
+    $iCacheMemory = getCacheMemoryMB();
+}
+
+$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+
+if ($aCMDResult['create-db'] || $aCMDResult['all'])
+{
+    echo "Create DB\n";
+    $bDidSomething = true;
+    $oDB = DB::connect(CONST_Database_DSN, false);
+    if (!PEAR::isError($oDB))
+    {
+        fail('database already exists ('.CONST_Database_DSN.')');
+    }
+    passthruCheckReturn('createdb -E UTF-8 -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']);
+}
+
+if ($aCMDResult['setup-db'] || $aCMDResult['all'])
+{
+    echo "Setup DB\n";
+    $bDidSomething = true;
+    // TODO: path detection, detection memory, etc.
+
+    $oDB =& getDB();
+
+    $fPostgresVersion = getPostgresVersion($oDB);
+    echo 'Postgres version found: '.$fPostgresVersion."\n";
+
+    if ($fPostgresVersion < 9.1)
+    {
+        fail("Minimum supported version of Postgresql is 9.1.");
+    }
+
+    pgsqlRunScript('CREATE EXTENSION IF NOT EXISTS hstore');
+    pgsqlRunScript('CREATE EXTENSION IF NOT EXISTS postgis');
+
+    // For extratags and namedetails the hstore_to_json converter is
+    // needed which is only available from Postgresql 9.3+. For older
+    // versions add a dummy function that returns nothing.
+    $iNumFunc = chksql($oDB->getOne("select count(*) from pg_proc where proname = 'hstore_to_json'"));
+
+    if ($iNumFunc == 0)
+    {
+        pgsqlRunScript("create function hstore_to_json(dummy hstore) returns text AS 'select null::text' language sql immutable");
+        echo "WARNING: Postgresql is too old. extratags and namedetails API not available.";
+    }
+
+    $fPostgisVersion = getPostgisVersion($oDB);
+    echo 'Postgis version found: '.$fPostgisVersion."\n";
+
+    if ($fPostgisVersion < 2.1)
+    {
+        // Function was renamed in 2.1 and throws an annoying deprecation warning
+        pgsqlRunScript('ALTER FUNCTION st_line_interpolate_point(geometry, double precision) RENAME TO ST_LineInterpolatePoint');
+    }
+
+    pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
+    pgsqlRunScriptFile(CONST_BasePath.'/data/country_naturalearthdata.sql');
+    pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql');
+    pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_table.sql');
+    if (file_exists(CONST_BasePath.'/data/gb_postcode_data.sql.gz'))
+    {
+        pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_data.sql.gz');
+    }
+    else
+    {
+        echo "WARNING: external UK postcode table not found.\n";
+    }
+    if (CONST_Use_Extra_US_Postcodes)
+    {
+        pgsqlRunScriptFile(CONST_BasePath.'/data/us_postcode.sql');
+    }
+
+    if ($aCMDResult['no-partitions'])
+    {
+        pgsqlRunScript('update country_name set partition = 0');
+    }
+
+    // the following will be needed by create_functions later but
+    // is only defined in the subsequently called create_tables.
+    // Create dummies here that will be overwritten by the proper
+    // versions in create-tables.
+    pgsqlRunScript('CREATE TABLE place_boundingbox ()');
+    pgsqlRunScript('create type wikipedia_article_match as ()');
+}
+
+if ($aCMDResult['import-data'] || $aCMDResult['all'])
+{
+    echo "Import\n";
+    $bDidSomething = true;
+
+    $osm2pgsql = CONST_Osm2pgsql_Binary;
+    if (!file_exists($osm2pgsql))
+    {
+        echo "Please download and build osm2pgsql.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n";
+        fail("osm2pgsql not found in '$osm2pgsql'");
+    }
+
+    if (!is_null(CONST_Osm2pgsql_Flatnode_File))
+    {
+        $osm2pgsql .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
+    }
+    if (CONST_Tablespace_Osm2pgsql_Data)
+        $osm2pgsql .= ' --tablespace-slim-data '.CONST_Tablespace_Osm2pgsql_Data;
+    if (CONST_Tablespace_Osm2pgsql_Index)
+        $osm2pgsql .= ' --tablespace-slim-index '.CONST_Tablespace_Osm2pgsql_Index;
+    if (CONST_Tablespace_Place_Data)
+        $osm2pgsql .= ' --tablespace-main-data '.CONST_Tablespace_Place_Data;
+    if (CONST_Tablespace_Place_Index)
+        $osm2pgsql .= ' --tablespace-main-index '.CONST_Tablespace_Place_Index;
+    $osm2pgsql .= ' -lsc -O gazetteer --hstore --number-processes 1';
+    $osm2pgsql .= ' -C '.$iCacheMemory;
+    $osm2pgsql .= ' -P '.$aDSNInfo['port'];
+    $osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file'];
+    passthruCheckReturn($osm2pgsql);
+
+    $oDB =& getDB();
+    if (!chksql($oDB->getRow('select * from place limit 1')))
+    {
+        fail('No Data');
+    }
+}
+
+if ($aCMDResult['create-functions'] || $aCMDResult['all'])
+{
+    echo "Functions\n";
+    $bDidSomething = true;
+    if (!file_exists(CONST_InstallPath.'/module/nominatim.so')) fail("nominatim module not built");
+    create_sql_functions($aCMDResult);
+}
+
+if ($aCMDResult['create-tables'] || $aCMDResult['all'])
+{
+    $bDidSomething = true;
+
+    echo "Tables\n";
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/tables.sql');
+    $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:address-data}',
+                                    CONST_Tablespace_Address_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:address-index}',
+                                    CONST_Tablespace_Address_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:search-data}',
+                                    CONST_Tablespace_Search_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:search-index}',
+                                    CONST_Tablespace_Search_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-data}',
+                                    CONST_Tablespace_Aux_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-index}',
+                                    CONST_Tablespace_Aux_Index, $sTemplate);
+    pgsqlRunScript($sTemplate, false);
+
+    // re-run the functions
+    echo "Functions\n";
+    create_sql_functions($aCMDResult);
+}
+
+if ($aCMDResult['create-partition-tables'] || $aCMDResult['all'])
+{
+    echo "Partition Tables\n";
+    $bDidSomething = true;
+
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-tables.src.sql');
+    $sTemplate = replace_tablespace('{ts:address-data}',
+                                    CONST_Tablespace_Address_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:address-index}',
+                                    CONST_Tablespace_Address_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:search-data}',
+                                    CONST_Tablespace_Search_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:search-index}',
+                                    CONST_Tablespace_Search_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-data}',
+                                    CONST_Tablespace_Aux_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-index}',
+                                    CONST_Tablespace_Aux_Index, $sTemplate);
+
+    pgsqlRunPartitionScript($sTemplate);
+}
+
+
+if ($aCMDResult['create-partition-functions'] || $aCMDResult['all'])
+{
+    echo "Partition Functions\n";
+    $bDidSomething = true;
+
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/partition-functions.src.sql');
+
+    pgsqlRunPartitionScript($sTemplate);
+}
+
+if ($aCMDResult['import-wikipedia-articles'] || $aCMDResult['all'])
+{
+    $bDidSomething = true;
+    $sWikiArticlesFile = CONST_BasePath.'/data/wikipedia_article.sql.bin';
+    $sWikiRedirectsFile = CONST_BasePath.'/data/wikipedia_redirect.sql.bin';
+    if (file_exists($sWikiArticlesFile))
+    {
+        echo "Importing wikipedia articles...";
+        pgsqlRunDropAndRestore($sWikiArticlesFile);
+        echo "...done\n";
+    }
+    else
+    {
+        echo "WARNING: wikipedia article dump file not found - places will have default importance\n";
+    }
+    if (file_exists($sWikiRedirectsFile))
+    {
+        echo "Importing wikipedia redirects...";
+        pgsqlRunDropAndRestore($sWikiRedirectsFile);
+        echo "...done\n";
+    }
+    else
+    {
+        echo "WARNING: wikipedia redirect dump file not found - some place importance values may be missing\n";
+    }
+}
+
+
+if ($aCMDResult['load-data'] || $aCMDResult['all'])
+{
+    echo "Drop old Data\n";
+    $bDidSomething = true;
+
+    $oDB =& getDB();
+    if (!pg_query($oDB->connection, 'TRUNCATE word')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE placex')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE location_property_osmline')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE place_addressline')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE place_boundingbox')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE location_area')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE search_name')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'TRUNCATE search_name_blank')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'DROP SEQUENCE seq_place')) fail(pg_last_error($oDB->connection));
+    echo '.';
+    if (!pg_query($oDB->connection, 'CREATE SEQUENCE seq_place start 100000')) fail(pg_last_error($oDB->connection));
+    echo '.';
+
+    $sSQL = 'select distinct partition from country_name';
+    $aPartitions = chksql($oDB->getCol($sSQL));
+    if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
+    foreach($aPartitions as $sPartition)
+    {
+        if (!pg_query($oDB->connection, 'TRUNCATE location_road_'.$sPartition)) fail(pg_last_error($oDB->connection));
+        echo '.';
+    }
+
+    // used by getorcreate_word_id to ignore frequent partial words
+    if (!pg_query($oDB->connection, 'CREATE OR REPLACE FUNCTION get_maxwordfreq() RETURNS integer AS $$ SELECT '.CONST_Max_Word_Frequency.' as maxwordfreq; $$ LANGUAGE SQL IMMUTABLE')) fail(pg_last_error($oDB->connection));
+    echo ".\n";
+
+    // pre-create the word list
+    if (!$aCMDResult['disable-token-precalc'])
+    {
+        echo "Loading word list\n";
+        pgsqlRunScriptFile(CONST_BasePath.'/data/words.sql');
+    }
+
+    echo "Load Data\n";
+    $aDBInstances = array();
+    $iLoadThreads = max(1, $iInstances - 1);
+    for($i = 0; $i < $iLoadThreads; $i++)
+    {
+        $aDBInstances[$i] =& getDB(true);
+        $sSQL = 'insert into placex (osm_type, osm_id, class, type, name, admin_level, ';
+        $sSQL .= 'housenumber, street, addr_place, isin, postcode, country_code, extratags, ';
+        $sSQL .= 'geometry) select * from place where osm_id % '.$iLoadThreads.' = '.$i;
+        $sSQL .= " and not (class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString')";
+        if ($aCMDResult['verbose']) echo "$sSQL\n";
+        if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
+    }
+    // last thread for interpolation lines
+    $aDBInstances[$iLoadThreads] =& getDB(true);
+    $sSQL = 'select insert_osmline (osm_id, housenumber, street, addr_place, postcode, country_code, ';
+    $sSQL .= 'geometry) from place where ';
+    $sSQL .= "class='place' and type='houses' and osm_type='W' and ST_GeometryType(geometry) = 'ST_LineString'";
+    if ($aCMDResult['verbose']) echo "$sSQL\n";
+    if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
+
+    $bAnyBusy = true;
+    while($bAnyBusy)
+    {
+        $bAnyBusy = false;
+        for($i = 0; $i <= $iLoadThreads; $i++)
+        {
+            if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
+        }
+        sleep(1);
+        echo '.';
+    }
+    echo "\n";
+    echo "Reanalysing database...\n";
+    pgsqlRunScript('ANALYSE');
+}
+
+if ($aCMDResult['import-tiger-data'])
+{
+    $bDidSomething = true;
+
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_start.sql');
+    $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-data}',
+                                    CONST_Tablespace_Aux_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-index}',
+                                    CONST_Tablespace_Aux_Index, $sTemplate);
+    pgsqlRunScript($sTemplate, false);
+
+    $aDBInstances = array();
+    for($i = 0; $i < $iInstances; $i++)
+    {
+        $aDBInstances[$i] =& getDB(true);
+    }
+
+    foreach(glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile)
+    {
+        echo $sFile.': ';
+        $hFile = fopen($sFile, "r");
+        $sSQL = fgets($hFile, 100000);
+        $iLines = 0;
+
+        while(true)
+        {
+            for($i = 0; $i < $iInstances; $i++)
+            {
+                if (!pg_connection_busy($aDBInstances[$i]->connection))
+                {
+                    while(pg_get_result($aDBInstances[$i]->connection));
+                    $sSQL = fgets($hFile, 100000);
+                    if (!$sSQL) break 2;
+                    if (!pg_send_query($aDBInstances[$i]->connection, $sSQL)) fail(pg_last_error($oDB->connection));
+                    $iLines++;
+                    if ($iLines == 1000)
+                    {
+                        echo ".";
+                        $iLines = 0;
+                    }
+                }
+            }
+            usleep(10);
+        }
+
+        fclose($hFile);
+
+        $bAnyBusy = true;
+        while($bAnyBusy)
+        {
+            $bAnyBusy = false;
+            for($i = 0; $i < $iInstances; $i++)
+            {
+                if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true;
+            }
+            usleep(10);
+        }
+        echo "\n";
+    }
+
+    echo "Creating indexes\n";
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_finish.sql');
+    $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-data}',
+                                    CONST_Tablespace_Aux_Data, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-index}',
+                                    CONST_Tablespace_Aux_Index, $sTemplate);
+    pgsqlRunScript($sTemplate, false);
+}
+
+if ($aCMDResult['calculate-postcodes'] || $aCMDResult['all'])
+{
+    $bDidSomething = true;
+    $oDB =& getDB();
+    if (!pg_query($oDB->connection, 'DELETE from placex where osm_type=\'P\'')) fail(pg_last_error($oDB->connection));
+    $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) ";
+    $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,calculated_country_code,";
+    $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from (select calculated_country_code,postcode,";
+    $sSQL .= "avg(st_x(st_centroid(geometry))) as x,avg(st_y(st_centroid(geometry))) as y ";
+    $sSQL .= "from placex where postcode is not null group by calculated_country_code,postcode) as x";
+    if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
+
+    if (CONST_Use_Extra_US_Postcodes)
+    {
+        $sSQL = "insert into placex (osm_type,osm_id,class,type,postcode,calculated_country_code,geometry) ";
+        $sSQL .= "select 'P',nextval('seq_postcodes'),'place','postcode',postcode,'us',";
+        $sSQL .= "ST_SetSRID(ST_Point(x,y),4326) as geometry from us_postcode";
+        if (!pg_query($oDB->connection, $sSQL)) fail(pg_last_error($oDB->connection));
+    }
+}
+
+if ($aCMDResult['osmosis-init'] || ($aCMDResult['all'] && !$aCMDResult['drop'])) // no use doing osmosis-init when dropping update tables
+{
+    $bDidSomething = true;
+    $oDB =& getDB();
+
+    if (!file_exists(CONST_Osmosis_Binary))
+    {
+        echo "Please download osmosis.\nIf it is already installed, check the path in your local settings (settings/local.php) file.\n";
+        if (!$aCMDResult['all'])
+        {
+            fail("osmosis not found in '".CONST_Osmosis_Binary."'");
+        }
+    }
+    else
+    {
+        if (file_exists(CONST_InstallPath.'/settings/configuration.txt'))
+        {
+            echo "settings/configuration.txt already exists\n";
+        }
+        else
+        {
+            passthru(CONST_Osmosis_Binary.' --read-replication-interval-init '.CONST_InstallPath.'/settings');
+            // update osmosis configuration.txt with our settings
+            passthru("sed -i 's!baseUrl=.*!baseUrl=".CONST_Replication_Url."!' ".CONST_InstallPath.'/settings/configuration.txt');
+            passthru("sed -i 's:maxInterval = .*:maxInterval = ".CONST_Replication_MaxInterval.":' ".CONST_InstallPath.'/settings/configuration.txt');
+        }
+
+        // Find the last node in the DB
+        $iLastOSMID = $oDB->getOne("select max(osm_id) from place where osm_type = 'N'");
+
+        // Lookup the timestamp that node was created (less 3 hours for margin for changsets to be closed)
+        $sLastNodeURL = 'http://www.openstreetmap.org/api/0.6/node/'.$iLastOSMID."/1";
+        $sLastNodeXML = file_get_contents($sLastNodeURL);
+        preg_match('#timestamp="(([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z)"#', $sLastNodeXML, $aLastNodeDate);
+        $iLastNodeTimestamp = strtotime($aLastNodeDate[1]) - (3*60*60);
+
+        // Search for the correct state file - uses file timestamps so need to sort by date descending
+        $sRepURL = CONST_Replication_Url."/";
+        $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
+        // download.geofabrik.de:    <a href="000/">000/</a></td><td align="right">26-Feb-2013 11:53  </td>
+        // planet.openstreetmap.org: <a href="273/">273/</a>                    2013-03-11 07:41    -
+        preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
+        if ($aRepMatches)
+        {
+            $aPrevRepMatch = false;
+            foreach($aRepMatches as $aRepMatch)
+            {
+                if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
+                $aPrevRepMatch = $aRepMatch;
+            }
+            if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
+
+            $sRepURL .= $aRepMatch[1];
+            $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
+            preg_match_all('#<a href="[0-9]{3}/">([0-9]{3}/)</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
+            $aPrevRepMatch = false;
+            foreach($aRepMatches as $aRepMatch)
+            {
+                if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
+                $aPrevRepMatch = $aRepMatch;
+            }
+            if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
+
+            $sRepURL .= $aRepMatch[1];
+            $sRep = file_get_contents($sRepURL."?C=M;O=D;F=1");
+            preg_match_all('#<a href="[0-9]{3}.state.txt">([0-9]{3}).state.txt</a>\s*([-0-9a-zA-Z]+ [0-9]{2}:[0-9]{2})#', $sRep, $aRepMatches, PREG_SET_ORDER);
+            $aPrevRepMatch = false;
+            foreach($aRepMatches as $aRepMatch)
+            {
+                if (strtotime($aRepMatch[2]) < $iLastNodeTimestamp) break;
+                $aPrevRepMatch = $aRepMatch;
+            }
+            if ($aPrevRepMatch) $aRepMatch = $aPrevRepMatch;
+
+            $sRepURL .= $aRepMatch[1].'.state.txt';
+            echo "Getting state file: $sRepURL\n";
+            $sStateFile = file_get_contents($sRepURL);
+            if (!$sStateFile || strlen($sStateFile) > 1000) fail("unable to obtain state file");
+            file_put_contents(CONST_InstallPath.'/settings/state.txt', $sStateFile);
+            echo "Updating DB status\n";
+            pg_query($oDB->connection, 'TRUNCATE import_status');
+            $sSQL = "INSERT INTO import_status VALUES('".$aRepMatch[2]."')";
+            pg_query($oDB->connection, $sSQL);
+        }
+        else
+        {
+            if (!$aCMDResult['all'])
+            {
+                fail("Cannot read state file directory.");
+            }
+        }
+    }
+}
+
+if ($aCMDResult['index'] || $aCMDResult['all'])
+{
+    $bDidSomething = true;
+    $sOutputFile = '';
+    $sBaseCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$iInstances.$sOutputFile;
+    passthruCheckReturn($sBaseCmd.' -R 4');
+    if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE');
+    passthruCheckReturn($sBaseCmd.' -r 5 -R 25');
+    if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE');
+    passthruCheckReturn($sBaseCmd.' -r 26');
+}
+
+if ($aCMDResult['create-search-indices'] || $aCMDResult['all'])
+{
+    echo "Search indices\n";
+    $bDidSomething = true;
+
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/indices.src.sql');
+    $sTemplate = replace_tablespace('{ts:address-index}',
+                                    CONST_Tablespace_Address_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:search-index}',
+                                    CONST_Tablespace_Search_Index, $sTemplate);
+    $sTemplate = replace_tablespace('{ts:aux-index}',
+                                    CONST_Tablespace_Aux_Index, $sTemplate);
+
+    pgsqlRunScript($sTemplate);
+}
+
+if ($aCMDResult['drop'])
+{
+    // The implementation is potentially a bit dangerous because it uses
+    // a positive selection of tables to keep, and deletes everything else.
+    // Including any tables that the unsuspecting user might have manually
+    // created. USE AT YOUR OWN PERIL.
+    $bDidSomething = true;
+
+    // tables we want to keep. everything else goes.
+    $aKeepTables = array(
+       "*columns",
+       "import_polygon_*",
+       "import_status",
+       "place_addressline",
+       "location_property*",
+       "placex",
+       "search_name",
+       "seq_*",
+       "word",
+       "query_log",
+       "new_query_log",
+       "gb_postcode",
+       "spatial_ref_sys",
+       "country_name",
+       "place_classtype_*"
+    );
+
+    $oDB =& getDB();
+    $aDropTables = array();
+    $aHaveTables = chksql($oDB->getCol("SELECT tablename FROM pg_tables WHERE schemaname='public'"));
+
+    foreach($aHaveTables as $sTable)
+    {
+        $bFound = false;
+        foreach ($aKeepTables as $sKeep)
+        {
+            if (fnmatch($sKeep, $sTable))
+            {
+                $bFound = true;
+                break;
+            }
+        }
+        if (!$bFound) array_push($aDropTables, $sTable);
+    }
+
+    foreach ($aDropTables as $sDrop)
+    {
+        if ($aCMDResult['verbose']) echo "dropping table $sDrop\n";
+        @pg_query($oDB->connection, "DROP TABLE $sDrop CASCADE");
+        // ignore warnings/errors as they might be caused by a table having
+        // been deleted already by CASCADE
+    }
+
+    if (!is_null(CONST_Osm2pgsql_Flatnode_File))
+    {
+        if ($aCMDResult['verbose']) echo "deleting ".CONST_Osm2pgsql_Flatnode_File."\n";
+        unlink(CONST_Osm2pgsql_Flatnode_File);
+    }
+}
+
+if (!$bDidSomething)
+{
+    showUsage($aCMDOptions, true);
+}
+else
+{
+    echo "Setup finished.\n";
+}
+
+function pgsqlRunScriptFile($sFilename)
+{
+    if (!file_exists($sFilename)) fail('unable to find '.$sFilename);
+
+    // Convert database DSN to psql parameters
+    $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+    if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+    $sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
+
+    $ahGzipPipes = null;
+    if (preg_match('/\\.gz$/', $sFilename))
+    {
+        $aDescriptors = array(
+            0 => array('pipe', 'r'),
+            1 => array('pipe', 'w'),
+            2 => array('file', '/dev/null', 'a')
+        );
+        $hGzipProcess = proc_open('zcat '.$sFilename, $aDescriptors, $ahGzipPipes);
+        if (!is_resource($hGzipProcess)) fail('unable to start zcat');
+        $aReadPipe = $ahGzipPipes[1];
+        fclose($ahGzipPipes[0]);
+    }
+    else
+    {
+        $sCMD .= ' -f '.$sFilename;
+        $aReadPipe = array('pipe', 'r');
+    }
+
+    $aDescriptors = array(
+        0 => $aReadPipe,
+        1 => array('pipe', 'w'),
+        2 => array('file', '/dev/null', 'a')
+    );
+    $ahPipes = null;
+    $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
+    if (!is_resource($hProcess)) fail('unable to start pgsql');
+
+
+    // TODO: error checking
+    while(!feof($ahPipes[1]))
+    {
+        echo fread($ahPipes[1], 4096);
+    }
+    fclose($ahPipes[1]);
+
+    $iReturn = proc_close($hProcess);
+    if ($iReturn > 0)
+    {
+        fail("pgsql returned with error code ($iReturn)");
+    }
+    if ($ahGzipPipes)
+    {
+        fclose($ahGzipPipes[1]);
+        proc_close($hGzipProcess);
+    }
+
+}
+
+function pgsqlRunScript($sScript, $bfatal = true)
+{
+    global $aCMDResult;
+    // Convert database DSN to psql parameters
+    $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+    if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+    $sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'];
+    if ($bfatal && !$aCMDResult['ignore-errors'])
+        $sCMD .= ' -v ON_ERROR_STOP=1';
+    $aDescriptors = array(
+        0 => array('pipe', 'r'),
+        1 => STDOUT, 
+        2 => STDERR
+    );
+    $ahPipes = null;
+    $hProcess = @proc_open($sCMD, $aDescriptors, $ahPipes);
+    if (!is_resource($hProcess)) fail('unable to start pgsql');
+
+    while(strlen($sScript))
+    {
+        $written = fwrite($ahPipes[0], $sScript);
+        if ($written <= 0) break;
+        $sScript = substr($sScript, $written);
+    }
+    fclose($ahPipes[0]);
+    $iReturn = proc_close($hProcess);
+    if ($bfatal && $iReturn > 0)
+    {
+        fail("pgsql returned with error code ($iReturn)");
+    }
+}
+
+function pgsqlRunPartitionScript($sTemplate)
+{
+    global $aCMDResult;
+    $oDB =& getDB();
+
+    $sSQL = 'select distinct partition from country_name';
+    $aPartitions = chksql($oDB->getCol($sSQL));
+    if (!$aCMDResult['no-partitions']) $aPartitions[] = 0;
+
+    preg_match_all('#^-- start(.*?)^-- end#ms', $sTemplate, $aMatches, PREG_SET_ORDER);
+    foreach($aMatches as $aMatch)
+    {
+        $sResult = '';
+        foreach($aPartitions as $sPartitionName)
+        {
+            $sResult .= str_replace('-partition-', $sPartitionName, $aMatch[1]);
+        }
+        $sTemplate = str_replace($aMatch[0], $sResult, $sTemplate);
+    }
+
+    pgsqlRunScript($sTemplate);
+}
+
+function pgsqlRunRestoreData($sDumpFile)
+{
+    // Convert database DSN to psql parameters
+    $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+    if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+    $sCMD = 'pg_restore -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'].' -Fc -a '.$sDumpFile;
+
+    $aDescriptors = array(
+        0 => array('pipe', 'r'),
+        1 => array('pipe', 'w'),
+        2 => array('file', '/dev/null', 'a')
+    );
+    $ahPipes = null;
+    $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
+    if (!is_resource($hProcess)) fail('unable to start pg_restore');
+
+    fclose($ahPipes[0]);
+
+    // TODO: error checking
+    while(!feof($ahPipes[1]))
+    {
+        echo fread($ahPipes[1], 4096);
+    }
+    fclose($ahPipes[1]);
+
+    $iReturn = proc_close($hProcess);
+}
+
+function pgsqlRunDropAndRestore($sDumpFile)
+{
+    // Convert database DSN to psql parameters
+    $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+    if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+    $sCMD = 'pg_restore -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'].' -Fc --clean '.$sDumpFile;
+
+    $aDescriptors = array(
+        0 => array('pipe', 'r'),
+        1 => array('pipe', 'w'),
+        2 => array('file', '/dev/null', 'a')
+    );
+    $ahPipes = null;
+    $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes);
+    if (!is_resource($hProcess)) fail('unable to start pg_restore');
+
+    fclose($ahPipes[0]);
+
+    // TODO: error checking
+    while(!feof($ahPipes[1]))
+    {
+        echo fread($ahPipes[1], 4096);
+    }
+    fclose($ahPipes[1]);
+
+    $iReturn = proc_close($hProcess);
+}
+
+function passthruCheckReturn($cmd)
+{
+    $result = -1;
+    passthru($cmd, $result);
+    if ($result != 0) fail('Error executing external command: '.$cmd);
+}
+
+function replace_tablespace($sTemplate, $sTablespace, $sSql)
+{
+    if ($sTablespace)
+        $sSql = str_replace($sTemplate, 'TABLESPACE "'.$sTablespace.'"',
+                            $sSql);
+    else
+        $sSql = str_replace($sTemplate, '', $sSql);
+
+    return $sSql;
+}
+
+function create_sql_functions($aCMDResult)
+{
+    $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql');
+    $sTemplate = str_replace('{modulepath}', CONST_InstallPath.'/module', $sTemplate);
+    if ($aCMDResult['enable-diff-updates'])
+    {
+        $sTemplate = str_replace('RETURN NEW; -- %DIFFUPDATES%', '--', $sTemplate);
+    }
+    if ($aCMDResult['enable-debug-statements'])
+    {
+        $sTemplate = str_replace('--DEBUG:', '', $sTemplate);
+    }
+    if (CONST_Limit_Reindexing)
+    {
+        $sTemplate = str_replace('--LIMIT INDEXING:', '', $sTemplate);
+    }
+    if (!CONST_Use_US_Tiger_Data)
+    {
+        $sTemplate = str_replace('-- %NOTIGERDATA% ', '', $sTemplate);
+    }
+    if (!CONST_Use_Aux_Location_data)
+    {
+        $sTemplate = str_replace('-- %NOAUXDATA% ', '', $sTemplate);
+    }
+    pgsqlRunScript($sTemplate);
+
+}
 
index 189a7a3e00fef086a0d002dc69665e6a58c380c3..10001e9d4db0e210737f52e42c6709df91fc3474 100755 (executable)
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
-       ini_set('display_errors', 'stderr');
-
-        $aCMDOptions = array(
-                "Import and export special phrases",
-                array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-                array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-                array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-                array('countries', '', 0, 1, 0, 0, 'bool', 'Create import script for country codes and names'),
-                array('wiki-import', '', 0, 1, 0, 0, 'bool', 'Create import script for search phrases '),
-        );
-        getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
-
-               include(CONST_InstallPath.'/settings/phrase_settings.php');
-
-
-    if ($aCMDResult['countries']) {
-        echo "select getorcreate_country(make_standard_name('uk'), 'gb');\n";
-        echo "select getorcreate_country(make_standard_name('united states'), 'us');\n";
-        echo "select count(*) from (select getorcreate_country(make_standard_name(country_code), country_code) from country_name where country_code is not null) as x;\n";
-
-        echo "select count(*) from (select getorcreate_country(make_standard_name(get_name_by_language(country_name.name,ARRAY['name'])), country_code) from country_name where get_name_by_language(country_name.name, ARRAY['name']) is not null) as x;\n";
-        foreach($aLanguageIn as $sLanguage)
-               {
-            echo "select count(*) from (select getorcreate_country(make_standard_name(get_name_by_language(country_name.name,ARRAY['name:".$sLanguage."'])), country_code) from country_name where get_name_by_language(country_name.name, ARRAY['name:".$sLanguage."']) is not null) as x;\n";
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
+ini_set('display_errors', 'stderr');
+
+    $aCMDOptions = array(
+            "Import and export special phrases",
+            array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+            array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+            array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+            array('countries', '', 0, 1, 0, 0, 'bool', 'Create import script for country codes and names'),
+            array('wiki-import', '', 0, 1, 0, 0, 'bool', 'Create import script for search phrases '),
+    );
+    getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true);
+
+    include(CONST_InstallPath.'/settings/phrase_settings.php');
+
+
+if ($aCMDResult['countries']) {
+    echo "select getorcreate_country(make_standard_name('uk'), 'gb');\n";
+    echo "select getorcreate_country(make_standard_name('united states'), 'us');\n";
+    echo "select count(*) from (select getorcreate_country(make_standard_name(country_code), country_code) from country_name where country_code is not null) as x;\n";
+
+    echo "select count(*) from (select getorcreate_country(make_standard_name(get_name_by_language(country_name.name,ARRAY['name'])), country_code) from country_name where get_name_by_language(country_name.name, ARRAY['name']) is not null) as x;\n";
+    foreach($aLanguageIn as $sLanguage)
+    {
+        echo "select count(*) from (select getorcreate_country(make_standard_name(get_name_by_language(country_name.name,ARRAY['name:".$sLanguage."'])), country_code) from country_name where get_name_by_language(country_name.name, ARRAY['name:".$sLanguage."']) is not null) as x;\n";
+    }
+}
+
+if ($aCMDResult['wiki-import'])
+{
+    $aPairs = array();
+
+    foreach($aLanguageIn as $sLanguage)
+    {
+        $sURL = 'http://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/'.strtoupper($sLanguage);
+        $sWikiPageXML = file_get_contents($sURL);
+        if (preg_match_all('#\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([\\-YN])#', $sWikiPageXML, $aMatches, PREG_SET_ORDER))
+        {
+            foreach($aMatches as $aMatch)
+            {
+                $sLabel = trim($aMatch[1]);
+                $sClass = trim($aMatch[2]);
+                $sType = trim($aMatch[3]);
+                # hack around a bug where building=yes was imported with
+                # quotes into the wiki
+                $sType = preg_replace('/&quot;/', '', $sType);
+                # sanity check, in case somebody added garbage in the wiki
+                if (preg_match('/^\\w+$/', $sClass) < 1 ||
+                    preg_match('/^\\w+$/', $sType) < 1) {
+                    trigger_error("Bad class/type for language $sLanguage: $sClass=$sType");
+                    exit;
+                }
+                # blacklisting: disallow certain class/type combinations
+                if (isset($aTagsBlacklist[$sClass]) && in_array($sType, $aTagsBlacklist[$sClass])) {
+                    # fwrite(STDERR, "Blacklisted: ".$sClass."/".$sType."\n");
+                    continue;
+                }
+                # whitelisting: if class is in whitelist, allow only tags in the list
+                if (isset($aTagsWhitelist[$sClass]) && !in_array($sType, $aTagsWhitelist[$sClass])) {
+                    # fwrite(STDERR, "Non-Whitelisted: ".$sClass."/".$sType."\n");
+                    continue;
+                }
+                $aPairs[$sClass.'|'.$sType] = array($sClass, $sType);
+
+                switch(trim($aMatch[4]))
+                {
+                case 'near':
+                    echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType', 'near');\n";
+                    break;
+                case 'in':
+                    echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType', 'in');\n";
+                    break;
+                default:
+                    echo "select getorcreate_amenity(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType');\n";
+                    break;
+                }
+            }
         }
     }
 
-       if ($aCMDResult['wiki-import'])
-       {
-               $aPairs = array();
-
-               foreach($aLanguageIn as $sLanguage)
-               {
-                       $sURL = 'http://wiki.openstreetmap.org/wiki/Special:Export/Nominatim/Special_Phrases/'.strtoupper($sLanguage);
-                       $sWikiPageXML = file_get_contents($sURL);
-                       if (preg_match_all('#\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([^|]+) \\|\\| ([\\-YN])#', $sWikiPageXML, $aMatches, PREG_SET_ORDER))
-                       {
-                               foreach($aMatches as $aMatch)
-                               {
-                                       $sLabel = trim($aMatch[1]);
-                                       $sClass = trim($aMatch[2]);
-                                       $sType = trim($aMatch[3]);
-                                       # hack around a bug where building=yes was imported with
-                                       # quotes into the wiki
-                                       $sType = preg_replace('/&quot;/', '', $sType);
-                                       # sanity check, in case somebody added garbage in the wiki
-                                       if (preg_match('/^\\w+$/', $sClass) < 1 ||
-                                               preg_match('/^\\w+$/', $sType) < 1) {
-                                               trigger_error("Bad class/type for language $sLanguage: $sClass=$sType");
-                                               exit;
-                                       }
-                                       # blacklisting: disallow certain class/type combinations
-                                       if (isset($aTagsBlacklist[$sClass]) && in_array($sType, $aTagsBlacklist[$sClass])) {
-                                               # fwrite(STDERR, "Blacklisted: ".$sClass."/".$sType."\n");
-                                               continue;
-                                       }
-                                       # whitelisting: if class is in whitelist, allow only tags in the list
-                                       if (isset($aTagsWhitelist[$sClass])     && !in_array($sType, $aTagsWhitelist[$sClass])) {
-                                               # fwrite(STDERR, "Non-Whitelisted: ".$sClass."/".$sType."\n");
-                                               continue;
-                                       }
-                                       $aPairs[$sClass.'|'.$sType] = array($sClass, $sType);
-
-                                       switch(trim($aMatch[4]))
-                                       {
-                                       case 'near':
-                                               echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType', 'near');\n";
-                                               break;
-                                       case 'in':
-                                               echo "select getorcreate_amenityoperator(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType', 'in');\n";
-                                               break;
-                                       default:
-                                               echo "select getorcreate_amenity(make_standard_name('".pg_escape_string($sLabel)."'), '$sClass', '$sType');\n";
-                                               break;
-                                       }
-                               }
-                       }
-               }
-
-        echo "create index idx_placex_classtype on placex (class, type);";
-
-               foreach($aPairs as $aPair)
-               {
-                       echo "create table place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]);
-                       if (CONST_Tablespace_Aux_Data)
-                               echo " tablespace ".CONST_Tablespace_Aux_Data;
-                       echo " as select place_id as place_id,st_centroid(geometry) as centroid from placex where ";
-                       echo "class = '".pg_escape_string($aPair[0])."' and type = '".pg_escape_string($aPair[1])."'";
-                       echo ";\n";
-
-                       echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_centroid ";
-                       echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING GIST (centroid)";
-                       if (CONST_Tablespace_Aux_Index)
-                               echo " tablespace ".CONST_Tablespace_Aux_Index;
-                       echo ";\n";
-
-                       echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_place_id ";
-                       echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING btree(place_id)";
-                       if (CONST_Tablespace_Aux_Index)
-                               echo " tablespace ".CONST_Tablespace_Aux_Index;
-                       echo ";\n";
-
-            echo "GRANT SELECT ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]).' TO "'.CONST_Database_Web_User."\";\n";
-
-               }
-
-        echo "drop index idx_placex_classtype;";
-       }
+    echo "create index idx_placex_classtype on placex (class, type);";
+
+    foreach($aPairs as $aPair)
+    {
+        echo "create table place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]);
+        if (CONST_Tablespace_Aux_Data)
+            echo " tablespace ".CONST_Tablespace_Aux_Data;
+        echo " as select place_id as place_id,st_centroid(geometry) as centroid from placex where ";
+        echo "class = '".pg_escape_string($aPair[0])."' and type = '".pg_escape_string($aPair[1])."'";
+        echo ";\n";
+
+        echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_centroid ";
+        echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING GIST (centroid)";
+        if (CONST_Tablespace_Aux_Index)
+            echo " tablespace ".CONST_Tablespace_Aux_Index;
+        echo ";\n";
+
+        echo "CREATE INDEX idx_place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])."_place_id ";
+        echo "ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1])." USING btree(place_id)";
+        if (CONST_Tablespace_Aux_Index)
+            echo " tablespace ".CONST_Tablespace_Aux_Index;
+        echo ";\n";
+
+        echo "GRANT SELECT ON place_classtype_".pg_escape_string($aPair[0])."_".pg_escape_string($aPair[1]).' TO "'.CONST_Database_Web_User."\";\n";
+
+    }
+
+    echo "drop index idx_placex_classtype;";
+}
index 82362b3119c174993583f38bc42904ec6f42efab..84fb24e5ed8a1c6acc977361a0b431c85305d620 100755 (executable)
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
-
-       $aCMDOptions = array(
-               "Import / update / index osm data",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-
-               array('import-osmosis', '', 0, 1, 0, 0, 'bool', 'Import using osmosis'),
-               array('import-osmosis-all', '', 0, 1, 0, 0, 'bool', 'Import using osmosis forever'),
-               array('no-npi', '', 0, 1, 0, 0, 'bool', '(obsolate)'),
-               array('no-index', '', 0, 1, 0, 0, 'bool', 'Do not index the new data'),
-
-               array('import-all', '', 0, 1, 0, 0, 'bool', 'Import all available files'),
-
-               array('import-file', '', 0, 1, 1, 1, 'realpath', 'Re-import data from an OSM file'),
-               array('import-diff', '', 0, 1, 1, 1, 'realpath', 'Import a diff (osc) file from local file system'),
-               array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
-
-               array('import-node', '', 0, 1, 1, 1, 'int', 'Re-import node'),
-               array('import-way', '', 0, 1, 1, 1, 'int', 'Re-import way'),
-               array('import-relation', '', 0, 1, 1, 1, 'int', 'Re-import relation'),
-               array('import-from-main-api', '', 0, 1, 0, 0, 'bool', 'Use OSM API instead of Overpass to download objects'),
-
-               array('index', '', 0, 1, 0, 0, 'bool', 'Index'),
-               array('index-rank', '', 0, 1, 1, 1, 'int', 'Rank to start indexing from'),
-               array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
-
-               array('deduplicate', '', 0, 1, 0, 0, 'bool', 'Deduplicate tokens'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
-
-       if (!isset($aResult['index-instances'])) $aResult['index-instances'] = 1;
-       if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
-
-       date_default_timezone_set('Etc/UTC');
-
-       $oDB =& getDB();
-
-       $aDSNInfo = DB::parseDSN(CONST_Database_DSN);
-       if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
-
-       // cache memory to be used by osm2pgsql, should not be more than the available memory
-       $iCacheMemory = (isset($aResult['osm2pgsql-cache'])?$aResult['osm2pgsql-cache']:2000);
-       if ($iCacheMemory + 500 > getTotalMemoryMB())
-       {
-               $iCacheMemory = getCacheMemoryMB();
-               echo "WARNING: resetting cache memory to $iCacheMemory\n";
-       }
-       $sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
-       if (!is_null(CONST_Osm2pgsql_Flatnode_File))
-       {
-               $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
-       }
-
-
-       if (isset($aResult['import-diff']))
-       {
-               // import diff directly (e.g. from osmosis --rri)
-               $sNextFile = $aResult['import-diff'];
-               if (!file_exists($sNextFile))
-               {
-                       fail("Cannot open $sNextFile\n");
-               }
-
-               // Import the file
-               $sCMD = $sOsm2pgsqlCmd.' '.$sNextFile;
-               echo $sCMD."\n";
-               exec($sCMD, $sJunk, $iErrorLevel);
-
-               if ($iErrorLevel)
-               {
-                       fail("Error from osm2pgsql, $iErrorLevel\n");
-               }
-
-               // Don't update the import status - we don't know what this file contains
-       }
-
-       $sTemporaryFile = CONST_BasePath.'/data/osmosischange.osc';
-       $bHaveDiff = false;
-       if (isset($aResult['import-file']) && $aResult['import-file'])
-       {
-               $bHaveDiff = true;
-               $sCMD = CONST_Osmosis_Binary.' --read-xml \''.$aResult['import-file'].'\' --read-empty --derive-change --write-xml-change '.$sTemporaryFile;
-               echo $sCMD."\n";
-               exec($sCMD, $sJunk, $iErrorLevel);
-               if ($iErrorLevel)
-               {
-                       fail("Error converting osm to osc, osmosis returned: $iErrorLevel\n");
-               }
-       }
-
-       $bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
-       $sContentURL = '';
-       if (isset($aResult['import-node']) && $aResult['import-node'])
-       {
-               if ($bUseOSMApi)
-               {
-                       $sContentURL = 'http://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
-               }
-               else
-               {
-                       $sContentURL = 'http://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
-               }
-       }
-       if (isset($aResult['import-way']) && $aResult['import-way'])
-       {
-               if ($bUseOSMApi)
-               {
-                       $sContentURL = 'http://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
-               }
-               else
-               {
-                       $sContentURL = 'http://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');node(w););out%20meta;';
-               }
-       }
-       if (isset($aResult['import-relation']) && $aResult['import-relation'])
-       {
-               if ($bUseOSMApi)
-               {
-                       $sContentURLsModifyXMLstr = 'http://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
-               }
-               else
-               {
-                       $sContentURL = 'http://overpass-api.de/api/interpreter?data=((rel('.$aResult['import-relation'].');way(r);node(w));node(r));out%20meta;';
-               }
-       }
-       if ($sContentURL)
-       {
-               $sModifyXMLstr = file_get_contents($sContentURL);
-               $bHaveDiff = true;
-
-               $aSpec = array(
-                       0 => array("pipe", "r"),  // stdin
-                       1 => array("pipe", "w"),  // stdout
-                       2 => array("pipe", "w") // stderr
-               );
-               $sCMD = CONST_Osmosis_Binary.' --read-xml - --read-empty --derive-change --write-xml-change '.$sTemporaryFile;
-               echo $sCMD."\n";
-               $hProc = proc_open($sCMD, $aSpec, $aPipes);
-               if (!is_resource($hProc))
-               {
-                       fail("Error converting osm to osc, osmosis failed\n");
-               }
-               fwrite($aPipes[0], $sModifyXMLstr);
-               fclose($aPipes[0]);
-               $sOut = stream_get_contents($aPipes[1]);
-               if ($aResult['verbose']) echo $sOut;
-               fclose($aPipes[1]);
-               $sErrors = stream_get_contents($aPipes[2]);
-               if ($aResult['verbose']) echo $sErrors;
-               fclose($aPipes[2]);
-               if ($iError = proc_close($hProc))
-               {
-                       echo $sOut;
-                       echo $sErrors;
-                       fail("Error converting osm to osc, osmosis returned: $iError\n");
-               }
-       }
-
-       if ($bHaveDiff)
-       {
-               // import generated change file
-               $sCMD = $sOsm2pgsqlCmd.' '.$sTemporaryFile;
-               echo $sCMD."\n";
-               exec($sCMD, $sJunk, $iErrorLevel);
-               if ($iErrorLevel)
-               {
-                       fail("osm2pgsql exited with error level $iErrorLevel\n");
-               }
-       }
-
-       if ($aResult['deduplicate'])
-       {
-
-               if (getPostgresVersion() < 9.3)
-               {
-                       fail("ERROR: deduplicate is only currently supported in postgresql 9.3");
-               }
-
-               $oDB =& getDB();
-               $sSQL = 'select partition from country_name order by country_code';
-               $aPartitions = chksql($oDB->getCol($sSQL));
-               $aPartitions[] = 0;
-
-               $sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' ' and class is null and type is null and country_code is null group by word_token having count(*) > 1 order by word_token";
-               $aDuplicateTokens = chksql($oDB->getAll($sSQL));
-               foreach($aDuplicateTokens as $aToken)
-               {
-                       if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
-                       echo "Deduping ".$aToken['word_token']."\n";
-                       $sSQL = "select word_id,(select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num from word where word_token = '".$aToken['word_token']."' and class is null and type is null and country_code is null order by num desc";
-                       $aTokenSet = chksql($oDB->getAll($sSQL));
-
-                       $aKeep = array_shift($aTokenSet);
-                       $iKeepID = $aKeep['word_id'];
-
-                       foreach($aTokenSet as $aRemove)
-                       {
-                               $sSQL = "update search_name set";
-                               $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID."),";
-                               $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
-                               $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
-                               chksql($oDB->query($sSQL));
-
-                               $sSQL = "update search_name set";
-                               $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
-                               $sSQL .= " where nameaddress_vector @> ARRAY[".$aRemove['word_id']."]";
-                               chksql($oDB->query($sSQL));
-
-                               $sSQL = "update location_area_country set";
-                               $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
-                               $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
-                               chksql($oDB->query($sSQL));
-
-                               foreach ($aPartitions as $sPartition)
-                               {
-                                       $sSQL = "update search_name_".$sPartition." set";
-                                       $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID.")";
-                                       $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
-                                       chksql($oDB->query($sSQL));
-
-                                       $sSQL = "update location_area_country set";
-                                       $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
-                                       $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
-                                       chksql($oDB->query($sSQL));
-                               }
-
-                               $sSQL = "delete from word where word_id = ".$aRemove['word_id'];
-                               chksql($oDB->query($sSQL));
-                       }
-               }
-       }
-
-       if ($aResult['index'])
-       {
-               passthru(CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']);
-       }
-
-       if ($aResult['import-osmosis'] || $aResult['import-osmosis-all'])
-       {
-
-               if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
-                       fail("Error: Update interval too low for download.geofabrik.de.  Please check install documentation (http://wiki.openstreetmap.org/wiki/Nominatim/Installation#Updates)\n");
-               }
-
-               $sImportFile = CONST_BasePath.'/data/osmosischange.osc';
-               $sOsmosisConfigDirectory = CONST_InstallPath.'/settings';
-               $sCMDDownload = CONST_Osmosis_Binary.' --read-replication-interval workingDirectory='.$sOsmosisConfigDirectory.' --simplify-change --write-xml-change '.$sImportFile;
-               $sCMDCheckReplicationLag = CONST_Osmosis_Binary.' -q --read-replication-lag workingDirectory='.$sOsmosisConfigDirectory;
-               $sCMDImport = $sOsm2pgsqlCmd.' '.$sImportFile;
-               $sCMDIndex = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'];
-
-               while(true)
-               {
-                       $fStartTime = time();
-                       $iFileSize = 1001;
-
-                       if (!file_exists($sImportFile))
-                       {
-                               // First check if there are new updates published (except for minutelies - there's always new diffs to process)
-                               if ( CONST_Replication_Update_Interval > 60 )
-                               {
-
-                                       unset($aReplicationLag);
-                                       exec($sCMDCheckReplicationLag, $aReplicationLag, $iErrorLevel); 
-                                       while ($iErrorLevel > 0 || $aReplicationLag[0] < 1)
-                                       {
-                                               if ($iErrorLevel)
-                                               {
-                                                       echo "Error: $iErrorLevel. ";
-                                                       echo "Re-trying: ".$sCMDCheckReplicationLag." in ".CONST_Replication_Recheck_Interval." secs\n";
-                                               }
-                                               else
-                                               {
-                                                       echo ".";
-                                               }
-                                               sleep(CONST_Replication_Recheck_Interval);
-                                               unset($aReplicationLag);
-                                               exec($sCMDCheckReplicationLag, $aReplicationLag, $iErrorLevel); 
-                                       }
-                                       // There are new replication files - use osmosis to download the file
-                                       echo "\n".date('Y-m-d H:i:s')." Replication Delay is ".$aReplicationLag[0]."\n";
-                               }
-                               $fStartTime = time();
-                               $fCMDStartTime = time();
-                               echo $sCMDDownload."\n";
-                               exec($sCMDDownload, $sJunk, $iErrorLevel);
-                               while ($iErrorLevel > 0)
-                               {
-                                       echo "Error: $iErrorLevel\n";
-                                       sleep(60);
-                                       echo 'Re-trying: '.$sCMDDownload."\n";
-                                       exec($sCMDDownload, $sJunk, $iErrorLevel);
-                               }
-                               $iFileSize = filesize($sImportFile);
-                               $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
-                               $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','osmosis')";
-                               var_Dump($sSQL);
-                               $oDB->query($sSQL);
-                               echo date('Y-m-d H:i:s')." Completed osmosis step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
-                       }
-
-                       $iFileSize = filesize($sImportFile);
-                       $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
-       
-                       // Import the file
-                       $fCMDStartTime = time();
-                       echo $sCMDImport."\n";
-                       exec($sCMDImport, $sJunk, $iErrorLevel);
-                       if ($iErrorLevel)
-                       {
-                               echo "Error: $iErrorLevel\n";
-                               exit($iErrorLevel);
-                       }
-                       $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','osm2pgsql')";
-                       var_Dump($sSQL);
-                       $oDB->query($sSQL);
-                       echo date('Y-m-d H:i:s')." Completed osm2pgsql step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
-
-                       // Archive for debug?
-                       unlink($sImportFile);
-
-                       $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
-
-                       // Index file
-                       $sThisIndexCmd = $sCMDIndex;
-                       $fCMDStartTime = time();
-
-                       if (!$aResult['no-index'])
-                       {
-                               echo "$sThisIndexCmd\n";
-                               exec($sThisIndexCmd, $sJunk, $iErrorLevel);
-                               if ($iErrorLevel)
-                               {
-                                       echo "Error: $iErrorLevel\n";
-                                       exit($iErrorLevel);
-                               }
-                       }
-
-                       $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','index')";
-                       var_Dump($sSQL);
-                       $oDB->query($sSQL);
-                       echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
-
-                       $sSQL = "update import_status set lastimportdate = '$sBatchEnd'";
-                       $oDB->query($sSQL);
-
-                       $fDuration = time() - $fStartTime;
-                       echo date('Y-m-d H:i:s')." Completed all for $sBatchEnd in ".round($fDuration/60,2)." minutes\n";
-                       if (!$aResult['import-osmosis-all']) exit(0);
-
-                       if ( CONST_Replication_Update_Interval > 60 )
-                       {
-                               $iSleep = max(0,(strtotime($sBatchEnd)+CONST_Replication_Update_Interval-time()));
-                       }
-                       else
-                       {
-                               $iSleep = max(0,CONST_Replication_Update_Interval-$fDuration);
-                       }
-                       echo date('Y-m-d H:i:s')." Sleeping $iSleep seconds\n";
-                       sleep($iSleep);
-               }
-       }
-
-       function getosmosistimestamp($sOsmosisConfigDirectory)
-       {
-               $sStateFile = file_get_contents($sOsmosisConfigDirectory.'/state.txt');
-               preg_match('#timestamp=(.+)#', $sStateFile, $aResult);
-               return str_replace('\:',':',$aResult[1]);
-       }
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
+
+$aCMDOptions = array(
+    "Import / update / index osm data",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+
+    array('import-osmosis', '', 0, 1, 0, 0, 'bool', 'Import using osmosis'),
+    array('import-osmosis-all', '', 0, 1, 0, 0, 'bool', 'Import using osmosis forever'),
+    array('no-npi', '', 0, 1, 0, 0, 'bool', '(obsolate)'),
+    array('no-index', '', 0, 1, 0, 0, 'bool', 'Do not index the new data'),
+
+    array('import-all', '', 0, 1, 0, 0, 'bool', 'Import all available files'),
+
+    array('import-file', '', 0, 1, 1, 1, 'realpath', 'Re-import data from an OSM file'),
+    array('import-diff', '', 0, 1, 1, 1, 'realpath', 'Import a diff (osc) file from local file system'),
+    array('osm2pgsql-cache', '', 0, 1, 1, 1, 'int', 'Cache size used by osm2pgsql'),
+
+    array('import-node', '', 0, 1, 1, 1, 'int', 'Re-import node'),
+    array('import-way', '', 0, 1, 1, 1, 'int', 'Re-import way'),
+    array('import-relation', '', 0, 1, 1, 1, 'int', 'Re-import relation'),
+    array('import-from-main-api', '', 0, 1, 0, 0, 'bool', 'Use OSM API instead of Overpass to download objects'),
+
+    array('index', '', 0, 1, 0, 0, 'bool', 'Index'),
+    array('index-rank', '', 0, 1, 1, 1, 'int', 'Rank to start indexing from'),
+    array('index-instances', '', 0, 1, 1, 1, 'int', 'Number of indexing instances (threads)'),
+
+    array('deduplicate', '', 0, 1, 0, 0, 'bool', 'Deduplicate tokens'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
+
+if (!isset($aResult['index-instances'])) $aResult['index-instances'] = 1;
+if (!isset($aResult['index-rank'])) $aResult['index-rank'] = 0;
+
+date_default_timezone_set('Etc/UTC');
+
+$oDB =& getDB();
+
+$aDSNInfo = DB::parseDSN(CONST_Database_DSN);
+if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432;
+
+// cache memory to be used by osm2pgsql, should not be more than the available memory
+$iCacheMemory = (isset($aResult['osm2pgsql-cache'])?$aResult['osm2pgsql-cache']:2000);
+if ($iCacheMemory + 500 > getTotalMemoryMB())
+{
+    $iCacheMemory = getCacheMemoryMB();
+    echo "WARNING: resetting cache memory to $iCacheMemory\n";
+}
+$sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'];
+if (!is_null(CONST_Osm2pgsql_Flatnode_File))
+{
+    $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
+}
+
+
+if (isset($aResult['import-diff']))
+{
+    // import diff directly (e.g. from osmosis --rri)
+    $sNextFile = $aResult['import-diff'];
+    if (!file_exists($sNextFile))
+    {
+        fail("Cannot open $sNextFile\n");
+    }
+
+    // Import the file
+    $sCMD = $sOsm2pgsqlCmd.' '.$sNextFile;
+    echo $sCMD."\n";
+    exec($sCMD, $sJunk, $iErrorLevel);
+
+    if ($iErrorLevel)
+    {
+        fail("Error from osm2pgsql, $iErrorLevel\n");
+    }
+
+    // Don't update the import status - we don't know what this file contains
+}
+
+$sTemporaryFile = CONST_BasePath.'/data/osmosischange.osc';
+$bHaveDiff = false;
+if (isset($aResult['import-file']) && $aResult['import-file'])
+{
+    $bHaveDiff = true;
+    $sCMD = CONST_Osmosis_Binary.' --read-xml \''.$aResult['import-file'].'\' --read-empty --derive-change --write-xml-change '.$sTemporaryFile;
+    echo $sCMD."\n";
+    exec($sCMD, $sJunk, $iErrorLevel);
+    if ($iErrorLevel)
+    {
+        fail("Error converting osm to osc, osmosis returned: $iErrorLevel\n");
+    }
+}
+
+$bUseOSMApi = isset($aResult['import-from-main-api']) && $aResult['import-from-main-api'];
+$sContentURL = '';
+if (isset($aResult['import-node']) && $aResult['import-node'])
+{
+    if ($bUseOSMApi)
+    {
+        $sContentURL = 'http://www.openstreetmap.org/api/0.6/node/'.$aResult['import-node'];
+    }
+    else
+    {
+        $sContentURL = 'http://overpass-api.de/api/interpreter?data=node('.$aResult['import-node'].');out%20meta;';
+    }
+}
+if (isset($aResult['import-way']) && $aResult['import-way'])
+{
+    if ($bUseOSMApi)
+    {
+        $sContentURL = 'http://www.openstreetmap.org/api/0.6/way/'.$aResult['import-way'].'/full';
+    }
+    else
+    {
+        $sContentURL = 'http://overpass-api.de/api/interpreter?data=(way('.$aResult['import-way'].');node(w););out%20meta;';
+    }
+}
+if (isset($aResult['import-relation']) && $aResult['import-relation'])
+{
+    if ($bUseOSMApi)
+    {
+        $sContentURLsModifyXMLstr = 'http://www.openstreetmap.org/api/0.6/relation/'.$aResult['import-relation'].'/full';
+    }
+    else
+    {
+        $sContentURL = 'http://overpass-api.de/api/interpreter?data=((rel('.$aResult['import-relation'].');way(r);node(w));node(r));out%20meta;';
+    }
+}
+if ($sContentURL)
+{
+    $sModifyXMLstr = file_get_contents($sContentURL);
+    $bHaveDiff = true;
+
+    $aSpec = array(
+        0 => array("pipe", "r"),  // stdin
+        1 => array("pipe", "w"),  // stdout
+        2 => array("pipe", "w") // stderr
+    );
+    $sCMD = CONST_Osmosis_Binary.' --read-xml - --read-empty --derive-change --write-xml-change '.$sTemporaryFile;
+    echo $sCMD."\n";
+    $hProc = proc_open($sCMD, $aSpec, $aPipes);
+    if (!is_resource($hProc))
+    {
+        fail("Error converting osm to osc, osmosis failed\n");
+    }
+    fwrite($aPipes[0], $sModifyXMLstr);
+    fclose($aPipes[0]);
+    $sOut = stream_get_contents($aPipes[1]);
+    if ($aResult['verbose']) echo $sOut;
+    fclose($aPipes[1]);
+    $sErrors = stream_get_contents($aPipes[2]);
+    if ($aResult['verbose']) echo $sErrors;
+    fclose($aPipes[2]);
+    if ($iError = proc_close($hProc))
+    {
+        echo $sOut;
+        echo $sErrors;
+        fail("Error converting osm to osc, osmosis returned: $iError\n");
+    }
+}
+
+if ($bHaveDiff)
+{
+    // import generated change file
+    $sCMD = $sOsm2pgsqlCmd.' '.$sTemporaryFile;
+    echo $sCMD."\n";
+    exec($sCMD, $sJunk, $iErrorLevel);
+    if ($iErrorLevel)
+    {
+        fail("osm2pgsql exited with error level $iErrorLevel\n");
+    }
+}
+
+if ($aResult['deduplicate'])
+{
+
+    if (getPostgresVersion() < 9.3)
+    {
+        fail("ERROR: deduplicate is only currently supported in postgresql 9.3");
+    }
+
+    $oDB =& getDB();
+    $sSQL = 'select partition from country_name order by country_code';
+    $aPartitions = chksql($oDB->getCol($sSQL));
+    $aPartitions[] = 0;
+
+    $sSQL = "select word_token,count(*) from word where substr(word_token, 1, 1) = ' ' and class is null and type is null and country_code is null group by word_token having count(*) > 1 order by word_token";
+    $aDuplicateTokens = chksql($oDB->getAll($sSQL));
+    foreach($aDuplicateTokens as $aToken)
+    {
+        if (trim($aToken['word_token']) == '' || trim($aToken['word_token']) == '-') continue;
+        echo "Deduping ".$aToken['word_token']."\n";
+        $sSQL = "select word_id,(select count(*) from search_name where nameaddress_vector @> ARRAY[word_id]) as num from word where word_token = '".$aToken['word_token']."' and class is null and type is null and country_code is null order by num desc";
+        $aTokenSet = chksql($oDB->getAll($sSQL));
+
+        $aKeep = array_shift($aTokenSet);
+        $iKeepID = $aKeep['word_id'];
+
+        foreach($aTokenSet as $aRemove)
+        {
+            $sSQL = "update search_name set";
+            $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID."),";
+            $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
+            $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
+            chksql($oDB->query($sSQL));
+
+            $sSQL = "update search_name set";
+            $sSQL .= " nameaddress_vector = array_replace(nameaddress_vector,".$aRemove['word_id'].",".$iKeepID.")";
+            $sSQL .= " where nameaddress_vector @> ARRAY[".$aRemove['word_id']."]";
+            chksql($oDB->query($sSQL));
+
+            $sSQL = "update location_area_country set";
+            $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
+            $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
+            chksql($oDB->query($sSQL));
+
+            foreach ($aPartitions as $sPartition)
+            {
+                $sSQL = "update search_name_".$sPartition." set";
+                $sSQL .= " name_vector = array_replace(name_vector,".$aRemove['word_id'].",".$iKeepID.")";
+                $sSQL .= " where name_vector @> ARRAY[".$aRemove['word_id']."]";
+                chksql($oDB->query($sSQL));
+
+                $sSQL = "update location_area_country set";
+                $sSQL .= " keywords = array_replace(keywords,".$aRemove['word_id'].",".$iKeepID.")";
+                $sSQL .= " where keywords @> ARRAY[".$aRemove['word_id']."]";
+                chksql($oDB->query($sSQL));
+            }
+
+            $sSQL = "delete from word where word_id = ".$aRemove['word_id'];
+            chksql($oDB->query($sSQL));
+        }
+    }
+}
+
+if ($aResult['index'])
+{
+    passthru(CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']);
+}
+
+if ($aResult['import-osmosis'] || $aResult['import-osmosis-all'])
+{
+
+    if (strpos(CONST_Replication_Url, 'download.geofabrik.de') !== false && CONST_Replication_Update_Interval < 86400) {
+        fail("Error: Update interval too low for download.geofabrik.de.  Please check install documentation (http://wiki.openstreetmap.org/wiki/Nominatim/Installation#Updates)\n");
+    }
+
+    $sImportFile = CONST_BasePath.'/data/osmosischange.osc';
+    $sOsmosisConfigDirectory = CONST_InstallPath.'/settings';
+    $sCMDDownload = CONST_Osmosis_Binary.' --read-replication-interval workingDirectory='.$sOsmosisConfigDirectory.' --simplify-change --write-xml-change '.$sImportFile;
+    $sCMDCheckReplicationLag = CONST_Osmosis_Binary.' -q --read-replication-lag workingDirectory='.$sOsmosisConfigDirectory;
+    $sCMDImport = $sOsm2pgsqlCmd.' '.$sImportFile;
+    $sCMDIndex = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'];
+
+    while(true)
+    {
+        $fStartTime = time();
+        $iFileSize = 1001;
+
+        if (!file_exists($sImportFile))
+        {
+            // First check if there are new updates published (except for minutelies - there's always new diffs to process)
+            if ( CONST_Replication_Update_Interval > 60 )
+            {
+
+                unset($aReplicationLag);
+                exec($sCMDCheckReplicationLag, $aReplicationLag, $iErrorLevel); 
+                while ($iErrorLevel > 0 || $aReplicationLag[0] < 1)
+                {
+                    if ($iErrorLevel)
+                    {
+                        echo "Error: $iErrorLevel. ";
+                        echo "Re-trying: ".$sCMDCheckReplicationLag." in ".CONST_Replication_Recheck_Interval." secs\n";
+                    }
+                    else
+                    {
+                        echo ".";
+                    }
+                    sleep(CONST_Replication_Recheck_Interval);
+                    unset($aReplicationLag);
+                    exec($sCMDCheckReplicationLag, $aReplicationLag, $iErrorLevel); 
+                }
+                // There are new replication files - use osmosis to download the file
+                echo "\n".date('Y-m-d H:i:s')." Replication Delay is ".$aReplicationLag[0]."\n";
+            }
+            $fStartTime = time();
+            $fCMDStartTime = time();
+            echo $sCMDDownload."\n";
+            exec($sCMDDownload, $sJunk, $iErrorLevel);
+            while ($iErrorLevel > 0)
+            {
+                echo "Error: $iErrorLevel\n";
+                sleep(60);
+                echo 'Re-trying: '.$sCMDDownload."\n";
+                exec($sCMDDownload, $sJunk, $iErrorLevel);
+            }
+            $iFileSize = filesize($sImportFile);
+            $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
+            $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','osmosis')";
+            var_Dump($sSQL);
+            $oDB->query($sSQL);
+            echo date('Y-m-d H:i:s')." Completed osmosis step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
+        }
+
+        $iFileSize = filesize($sImportFile);
+        $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
+
+        // Import the file
+        $fCMDStartTime = time();
+        echo $sCMDImport."\n";
+        exec($sCMDImport, $sJunk, $iErrorLevel);
+        if ($iErrorLevel)
+        {
+            echo "Error: $iErrorLevel\n";
+            exit($iErrorLevel);
+        }
+        $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','osm2pgsql')";
+        var_Dump($sSQL);
+        $oDB->query($sSQL);
+        echo date('Y-m-d H:i:s')." Completed osm2pgsql step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
+
+        // Archive for debug?
+        unlink($sImportFile);
+
+        $sBatchEnd = getosmosistimestamp($sOsmosisConfigDirectory);
+
+        // Index file
+        $sThisIndexCmd = $sCMDIndex;
+        $fCMDStartTime = time();
+
+        if (!$aResult['no-index'])
+        {
+            echo "$sThisIndexCmd\n";
+            exec($sThisIndexCmd, $sJunk, $iErrorLevel);
+            if ($iErrorLevel)
+            {
+                echo "Error: $iErrorLevel\n";
+                exit($iErrorLevel);
+            }
+        }
+
+        $sSQL = "INSERT INTO import_osmosis_log values ('$sBatchEnd',$iFileSize,'".date('Y-m-d H:i:s',$fCMDStartTime)."','".date('Y-m-d H:i:s')."','index')";
+        var_Dump($sSQL);
+        $oDB->query($sSQL);
+        echo date('Y-m-d H:i:s')." Completed index step for $sBatchEnd in ".round((time()-$fCMDStartTime)/60,2)." minutes\n";
+
+        $sSQL = "update import_status set lastimportdate = '$sBatchEnd'";
+        $oDB->query($sSQL);
+
+        $fDuration = time() - $fStartTime;
+        echo date('Y-m-d H:i:s')." Completed all for $sBatchEnd in ".round($fDuration/60,2)." minutes\n";
+        if (!$aResult['import-osmosis-all']) exit(0);
+
+        if ( CONST_Replication_Update_Interval > 60 )
+        {
+            $iSleep = max(0,(strtotime($sBatchEnd)+CONST_Replication_Update_Interval-time()));
+        }
+        else
+        {
+            $iSleep = max(0,CONST_Replication_Update_Interval-$fDuration);
+        }
+        echo date('Y-m-d H:i:s')." Sleeping $iSleep seconds\n";
+        sleep($iSleep);
+    }
+}
+
+function getosmosistimestamp($sOsmosisConfigDirectory)
+{
+    $sStateFile = file_get_contents($sOsmosisConfigDirectory.'/state.txt');
+    preg_match('#timestamp=(.+)#', $sStateFile, $aResult);
+    return str_replace('\:',':',$aResult[1]);
+}
index 18121eb66fb470ca4ceb78bcc0024811fa38cd9a..55a5855996896e8ed24ec1a3f8e16715b082551a 100755 (executable)
@@ -1,69 +1,69 @@
 #!/usr/bin/php -Cq
 <?php
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-cmd.php');
-       ini_set('memory_limit', '800M');
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-cmd.php');
+ini_set('memory_limit', '800M');
 
-       $aCMDOptions = array(
-               "Tools to warm nominatim db",
-               array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
-               array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
-               array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
-               array('reverse-only', '', 0, 1, 0, 0, 'bool', 'Warm reverse only'),
-               array('search-only', '', 0, 1, 0, 0, 'bool', 'Warm reverse only'),
-       );
-       getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
+$aCMDOptions = array(
+    "Tools to warm nominatim db",
+    array('help', 'h', 0, 1, 0, 0, false, 'Show Help'),
+    array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'),
+    array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'),
+    array('reverse-only', '', 0, 1, 0, 0, 'bool', 'Warm reverse only'),
+    array('search-only', '', 0, 1, 0, 0, 'bool', 'Warm reverse only'),
+);
+getCmdOpt($_SERVER['argv'], $aCMDOptions, $aResult, true, true);
 
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/Geocode.php');
-       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
-       require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/Geocode.php');
+require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
 
-       $oDB =& getDB();
+$oDB =& getDB();
 
-       $bVerbose = $aResult['verbose'];
+$bVerbose = $aResult['verbose'];
 
-       if (!$aResult['search-only']) {
+if (!$aResult['search-only']) {
 
-               $oReverseGeocode = new ReverseGeocode($oDB);
-               $oReverseGeocode->setZoom(20);
-               $oPlaceLookup = new PlaceLookup($oDB);
-               $oPlaceLookup->setIncludeAddressDetails(true);
-               $oPlaceLookup->setLanguagePreference(array('en'));
+    $oReverseGeocode = new ReverseGeocode($oDB);
+    $oReverseGeocode->setZoom(20);
+    $oPlaceLookup = new PlaceLookup($oDB);
+    $oPlaceLookup->setIncludeAddressDetails(true);
+    $oPlaceLookup->setLanguagePreference(array('en'));
 
-               echo "Warm reverse: ";
-               if ($bVerbose) echo "\n";
-               for($i = 0; $i < 1000; $i++) {
-                       $fLat = rand(-9000, 9000) / 100;
-                       $fLon = rand(-18000, 18000) / 100;
-                       if ($bVerbose) echo "$fLat, $fLon = ";
-                       $aLookup = $oReverseGeocode->lookup($fLat, $fLon);
-                       if ($aLookup && $aLookup['place_id'])
-                       {
-                               $aDetails = $oPlaceLookup->lookup((int)$aLookup['place_id'],
-                                                                 $aLookup['type'], $aLookup['fraction']);
-                               if ($bVerbose) echo $aDetails['langaddress']."\n";
-                       }
-                       else echo ".";
-               }
-               echo "\n";
-       }
+    echo "Warm reverse: ";
+    if ($bVerbose) echo "\n";
+    for($i = 0; $i < 1000; $i++) {
+        $fLat = rand(-9000, 9000) / 100;
+        $fLon = rand(-18000, 18000) / 100;
+        if ($bVerbose) echo "$fLat, $fLon = ";
+        $aLookup = $oReverseGeocode->lookup($fLat, $fLon);
+        if ($aLookup && $aLookup['place_id'])
+        {
+            $aDetails = $oPlaceLookup->lookup((int)$aLookup['place_id'],
+                                              $aLookup['type'], $aLookup['fraction']);
+            if ($bVerbose) echo $aDetails['langaddress']."\n";
+        }
+        else echo ".";
+    }
+    echo "\n";
+}
 
-       if (!$aResult['reverse-only']) {
+if (!$aResult['reverse-only']) {
 
-               $oGeocode =& new Geocode($oDB);
+    $oGeocode =& new Geocode($oDB);
 
-               echo "Warm search: ";
-               if ($bVerbose) echo "\n";
-               $sSQL = 'select word from word where word is not null order by search_name_count desc limit 1000';
-               foreach($oDB->getCol($sSQL) as $sWord) {
-                       if ($bVerbose) echo "$sWord = ";
-                       $oGeocode->setLanguagePreference(array('en'));
-                       $oGeocode->setQuery($sWord);
-                       $aSearchResults = $oGeocode->lookup();
-                       if ($bVerbose) echo $aSearchResults[0]['langaddress']."\n";
-                       else echo ".";
-               }
-       }
+    echo "Warm search: ";
+    if ($bVerbose) echo "\n";
+    $sSQL = 'select word from word where word is not null order by search_name_count desc limit 1000';
+    foreach($oDB->getCol($sSQL) as $sWord) {
+        if ($bVerbose) echo "$sWord = ";
+        $oGeocode->setLanguagePreference(array('en'));
+        $oGeocode->setQuery($sWord);
+        $aSearchResults = $oGeocode->lookup();
+        if ($bVerbose) echo $aSearchResults[0]['langaddress']."\n";
+        else echo ".";
+    }
+}
 
index c55cb20f1e531b73406d2aa09fdb1307ccf9f3f2..6d57262d741386061d6a952604b47838d322d366 100755 (executable)
@@ -1,66 +1,66 @@
 <?php
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
+    require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+    require_once(CONST_BasePath.'/lib/init-website.php');
+    require_once(CONST_BasePath.'/lib/log.php');
+    require_once(CONST_BasePath.'/lib/output.php');
+    ini_set('memory_limit', '200M');
 
-       $sOutputFormat = 'html';
+    $sOutputFormat = 'html';
 
-       $oDB =& getDB();
+    $oDB =& getDB();
 
-       $sSQL = "select placex.place_id, calculated_country_code as country_code, name->'name' as name, i.* from placex, import_polygon_delete i where placex.osm_id = i.osm_id and placex.osm_type = i.osm_type and placex.class = i.class and placex.type = i.type";
-       $aPolygons = chksql($oDB->getAll($sSQL),
-                           "Could not get list of deleted OSM elements.");
+    $sSQL = "select placex.place_id, calculated_country_code as country_code, name->'name' as name, i.* from placex, import_polygon_delete i where placex.osm_id = i.osm_id and placex.osm_type = i.osm_type and placex.class = i.class and placex.type = i.type";
+    $aPolygons = chksql($oDB->getAll($sSQL),
+                        "Could not get list of deleted OSM elements.");
 
-       if (CONST_DEBUG)
-       {
-               var_dump($aPolygons);
-               exit;
-       }
+    if (CONST_DEBUG)
+    {
+        var_dump($aPolygons);
+        exit;
+    }
 ?>
 <!DOCTYPE html>
 <html>
 <head>
-       <meta charset="utf-8"/>
-       <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
-       
-       <title>Nominatim Deleted Data</title>
-       
-       <meta name="description" content="List of OSM data that has been deleted" lang="en-US" />
+    <meta charset="utf-8"/>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    
+    <title>Nominatim Deleted Data</title>
+    
+    <meta name="description" content="List of OSM data that has been deleted" lang="en-US" />
 
 </head>
 
 <body>
 <style type="text/css">
 table {
-       border-width: 1px;
-       border-spacing: 0px;
-       border-style: solid;
-       border-color: gray;
-       border-collapse: collapse;
-       background-color: white;
-       margin: 10px;
+    border-width: 1px;
+    border-spacing: 0px;
+    border-style: solid;
+    border-color: gray;
+    border-collapse: collapse;
+    background-color: white;
+    margin: 10px;
 }
 table th {
-       border-width: 1px;
-       padding: 2px;
-       border-style: inset;
-       border-color: gray;
-       border-left-color: #ddd;
-       border-right-color: #ddd;
-       background-color: #eee;
-       -moz-border-radius: 0px 0px 0px 0px;
+    border-width: 1px;
+    padding: 2px;
+    border-style: inset;
+    border-color: gray;
+    border-left-color: #ddd;
+    border-right-color: #ddd;
+    background-color: #eee;
+    -moz-border-radius: 0px 0px 0px 0px;
 }
 table td {
-       border-width: 1px;
-       padding: 2px;
-       border-style: inset;
-       border-color: gray;
-       border-left-color: #ddd;
-       border-right-color: #ddd;
-       background-color: white;
-       -moz-border-radius: 0px 0px 0px 0px;
+    border-width: 1px;
+    padding: 2px;
+    border-style: inset;
+    border-color: gray;
+    border-left-color: #ddd;
+    border-right-color: #ddd;
+    background-color: white;
+    -moz-border-radius: 0px 0px 0px 0px;
 }
 </style>
 
@@ -68,34 +68,34 @@ table td {
 
 <table>
 <?php
-       if (!$aPolygons) exit;
-       echo "<tr>";
+    if (!$aPolygons) exit;
+    echo "<tr>";
 //var_dump($aPolygons[0]);
-       foreach($aPolygons[0] as $sCol => $sVal)
-       {
-               echo "<th>".$sCol."</th>";
-       }
-       echo "</tr>";
-       foreach($aPolygons as $aRow)
-       {
-               echo "<tr>";
-               foreach($aRow as $sCol => $sVal)
-               {
-                       switch($sCol)
-                       {
-                               case 'osm_id':
-                                       echo '<td>'.osmLink($aRow).'</td>';
-                                       break;
-                               case 'place_id':
-                                       echo '<td>'.detailsLink($aRow).'</td>';
-                                       break;
-                               default:
-                                       echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
-                                       break;
-                       }
-               }
-               echo "</tr>";
-       }
+    foreach($aPolygons[0] as $sCol => $sVal)
+    {
+        echo "<th>".$sCol."</th>";
+    }
+    echo "</tr>";
+    foreach($aPolygons as $aRow)
+    {
+        echo "<tr>";
+        foreach($aRow as $sCol => $sVal)
+        {
+            switch($sCol)
+            {
+                case 'osm_id':
+                    echo '<td>'.osmLink($aRow).'</td>';
+                    break;
+                case 'place_id':
+                    echo '<td>'.detailsLink($aRow).'</td>';
+                    break;
+                default:
+                    echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
+                    break;
+            }
+        }
+        echo "</tr>";
+    }
 ?>
 </table>
 
index 10490097cdd29de857b78bc1a089da04c992bbf9..c73b4cf3ef58615d7b1e997ed0d4a4d5d1716a49 100755 (executable)
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Details');
-
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
-
-       $oParams = new ParameterParser();
-
-       $sOutputFormat = 'html';
-       $aLangPrefOrder = $oParams->getPreferredLanguages();
-       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
-
-       $sPlaceId = $oParams->getString('place_id');
-       $sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
-       $iOsmId = $oParams->getInt('osmid', -1);
-
-       $oDB =& getDB();
-
-       if ($sOsmType && $iOsmId > 0)
-       {
-               $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
-
-               // Be nice about our error messages for broken geometry
-
-               if (!$sPlaceId)
-               {
-                       $aPointDetails = chksql($oDB->getRow("select osm_type, osm_id, errormessage, class, type, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom from import_polygon_error where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by updated desc limit 1"));
-                       if (!PEAR::isError($aPointDetails) && $aPointDetails) {
-                               if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches))
-                               {
-                                       $aPointDetails['error_x'] = $aMatches[1];
-                                       $aPointDetails['error_y'] = $aMatches[2];
-                               }
-                               else
-                               {
-                                       $aPointDetails['error_x'] = 0;
-                                       $aPointDetails['error_y'] = 0;
-                               }
-                               include(CONST_BasePath.'/lib/template/details-error-'.$sOutputFormat.'.php');
-                               exit;
-                       }
-               }
-       }
-
-
-       if (!$sPlaceId) userError("Please select a place id");
-
-       $iPlaceID = (int)$sPlaceId;
-
-       if (CONST_Use_US_Tiger_Data)
-       {
-               $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID));
-               if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
-       }
-
-       if (CONST_Use_Aux_Location_data)
-       {
-               $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID));
-               if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
-       }
-
-       $hLog = logStart($oDB, 'details', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
-
-       // Get the details for this point
-       $sSQL = "select place_id, osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, calculated_country_code as country_code, importance, wikipedia,";
-       $sSQL .= " to_char(indexed_date, 'YYYY-MM-DD HH24:MI') as indexed_date, parent_place_id, rank_address, rank_search, get_searchrank_label(rank_search) as rank_search_label, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ";
-       $sSQL .= " ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ";
-       //$sSQL .= " ST_Area(geometry::geography) as area, ";
-       $sSQL .= " ST_y(centroid) as lat, ST_x(centroid) as lon,";
-       $sSQL .= " case when importance = 0 OR importance IS NULL then 0.75-(rank_search::float/40) else importance end as calculated_importance, ";
-       $sSQL .= " ST_AsText(CASE WHEN ST_NPoints(geometry) > 5000 THEN ST_SimplifyPreserveTopology(geometry, 0.0001) ELSE geometry END) as outlinestring";
-       $sSQL .= " from placex where place_id = $iPlaceID";
-       $aPointDetails = chksql($oDB->getRow($sSQL),
-                               "Could not get details of place object.");
-       $aPointDetails['localname'] = $aPointDetails['localname']?$aPointDetails['localname']:$aPointDetails['housenumber'];
-
-       $aClassType = getClassTypesWithImportance();
-       $aPointDetails['icon'] = $aClassType[$aPointDetails['class'].':'.$aPointDetails['type']]['icon'];
-
-       // Get all alternative names (languages, etc)
-       $sSQL = "select (each(name)).key,(each(name)).value from placex where place_id = $iPlaceID order by (each(name)).key";
-       $aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
-       if (PEAR::isError($aPointDetails['aNames'])) // possible timeout
-       {
-               $aPointDetails['aNames'] = [];
-       }
-
-       // Extra tags
-       $sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = $iPlaceID order by (each(extratags)).key";
-       $aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
-       if (PEAR::isError($aPointDetails['aExtraTags'])) // possible timeout
-       {
-               $aPointDetails['aExtraTags'] = [];
-       }
-
-       // Address
-       $aAddressLines = getAddressDetails($oDB, $sLanguagePrefArraySQL, $iPlaceID, $aPointDetails['country_code'], -1, true);
-
-       // Linked places
-       $sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
-       $sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
-       $sSQL .= " from placex, (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
-       $sSQL .= " where linked_place_id = $iPlaceID";
-       $sSQL .= " order by rank_address asc,rank_search asc,get_name_by_language(name,$sLanguagePrefArraySQL),housenumber";
-       $aLinkedLines = $oDB->getAll($sSQL);
-       if (PEAR::isError($aLinkedLines)) // possible timeout
-       {
-               $aLinkedLines = [];
-       }
-
-       // All places this is an imediate parent of
-       $sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
-       $sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
-       $sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
-       $sSQL .= " where parent_place_id = $iPlaceID order by rank_address asc,rank_search asc limit 500) as obj,";
-       $sSQL .= " (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
-       $sSQL .= " order by rank_address asc,rank_search asc,localname,housenumber";
-       $aParentOfLines = $oDB->getAll($sSQL);
-       if (PEAR::isError($aParentOfLines)) // possible timeout
-       {
-               $aParentOfLines = [];
-       }
-
-       $aPlaceSearchNameKeywords = false;
-       $aPlaceSearchAddressKeywords = false;
-       if ($oParams->getBool('keywords'))
-       {
-               $sSQL = "select * from search_name where place_id = $iPlaceID";
-               $aPlaceSearchName = $oDB->getRow($sSQL);
-               if (PEAR::isError($aPlaceSearchName)) // possible timeout
-               {
-                       $aPlaceSearchName = [];
-               }
-
-               $sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['name_vector'],1,-1).")";
-               $aPlaceSearchNameKeywords = $oDB->getAll($sSQL);
-               if (PEAR::isError($aPlaceSearchNameKeywords)) // possible timeout
-               {
-                       $aPlaceSearchNameKeywords = [];
-               }
-
-
-               $sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['nameaddress_vector'],1,-1).")";
-               $aPlaceSearchAddressKeywords = $oDB->getAll($sSQL);
-               if (PEAR::isError($aPlaceSearchAddressKeywords)) // possible timeout
-               {
-                       $aPlaceSearchAddressKeywords = [];
-               }
-
-       }
-
-       logEnd($oDB, $hLog, 1);
-
-       if ($sOutputFormat=='html')
-       {
-               $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
-               $sTileURL = CONST_Map_Tile_URL;
-               $sTileAttribution = CONST_Map_Tile_Attribution;
-       }
-
-       include(CONST_BasePath.'/lib/template/details-'.$sOutputFormat.'.php');
+@define('CONST_ConnectionBucket_PageType', 'Details');
+
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/output.php');
+ini_set('memory_limit', '200M');
+
+$oParams = new ParameterParser();
+
+$sOutputFormat = 'html';
+$aLangPrefOrder = $oParams->getPreferredLanguages();
+$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
+
+$sPlaceId = $oParams->getString('place_id');
+$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
+$iOsmId = $oParams->getInt('osmid', -1);
+
+$oDB =& getDB();
+
+if ($sOsmType && $iOsmId > 0)
+{
+    $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
+
+    // Be nice about our error messages for broken geometry
+
+    if (!$sPlaceId)
+    {
+        $aPointDetails = chksql($oDB->getRow("select osm_type, osm_id, errormessage, class, type, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom from import_polygon_error where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by updated desc limit 1"));
+        if (!PEAR::isError($aPointDetails) && $aPointDetails) {
+            if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches))
+            {
+                $aPointDetails['error_x'] = $aMatches[1];
+                $aPointDetails['error_y'] = $aMatches[2];
+            }
+            else
+            {
+                $aPointDetails['error_x'] = 0;
+                $aPointDetails['error_y'] = 0;
+            }
+            include(CONST_BasePath.'/lib/template/details-error-'.$sOutputFormat.'.php');
+            exit;
+        }
+    }
+}
+
+
+if (!$sPlaceId) userError("Please select a place id");
+
+$iPlaceID = (int)$sPlaceId;
+
+if (CONST_Use_US_Tiger_Data)
+{
+    $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID));
+    if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
+}
+
+if (CONST_Use_Aux_Location_data)
+{
+    $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID));
+    if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
+}
+
+$hLog = logStart($oDB, 'details', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
+
+// Get the details for this point
+$sSQL = "select place_id, osm_type, osm_id, class, type, name, admin_level, housenumber, street, isin, postcode, calculated_country_code as country_code, importance, wikipedia,";
+$sSQL .= " to_char(indexed_date, 'YYYY-MM-DD HH24:MI') as indexed_date, parent_place_id, rank_address, rank_search, get_searchrank_label(rank_search) as rank_search_label, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ";
+$sSQL .= " ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ";
+//$sSQL .= " ST_Area(geometry::geography) as area, ";
+$sSQL .= " ST_y(centroid) as lat, ST_x(centroid) as lon,";
+$sSQL .= " case when importance = 0 OR importance IS NULL then 0.75-(rank_search::float/40) else importance end as calculated_importance, ";
+$sSQL .= " ST_AsText(CASE WHEN ST_NPoints(geometry) > 5000 THEN ST_SimplifyPreserveTopology(geometry, 0.0001) ELSE geometry END) as outlinestring";
+$sSQL .= " from placex where place_id = $iPlaceID";
+$aPointDetails = chksql($oDB->getRow($sSQL),
+                        "Could not get details of place object.");
+$aPointDetails['localname'] = $aPointDetails['localname']?$aPointDetails['localname']:$aPointDetails['housenumber'];
+
+$aClassType = getClassTypesWithImportance();
+$aPointDetails['icon'] = $aClassType[$aPointDetails['class'].':'.$aPointDetails['type']]['icon'];
+
+// Get all alternative names (languages, etc)
+$sSQL = "select (each(name)).key,(each(name)).value from placex where place_id = $iPlaceID order by (each(name)).key";
+$aPointDetails['aNames'] = $oDB->getAssoc($sSQL);
+if (PEAR::isError($aPointDetails['aNames'])) // possible timeout
+{
+    $aPointDetails['aNames'] = [];
+}
+
+// Extra tags
+$sSQL = "select (each(extratags)).key,(each(extratags)).value from placex where place_id = $iPlaceID order by (each(extratags)).key";
+$aPointDetails['aExtraTags'] = $oDB->getAssoc($sSQL);
+if (PEAR::isError($aPointDetails['aExtraTags'])) // possible timeout
+{
+    $aPointDetails['aExtraTags'] = [];
+}
+
+// Address
+$aAddressLines = getAddressDetails($oDB, $sLanguagePrefArraySQL, $iPlaceID, $aPointDetails['country_code'], -1, true);
+
+// Linked places
+$sSQL = "select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
+$sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
+$sSQL .= " from placex, (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
+$sSQL .= " where linked_place_id = $iPlaceID";
+$sSQL .= " order by rank_address asc,rank_search asc,get_name_by_language(name,$sLanguagePrefArraySQL),housenumber";
+$aLinkedLines = $oDB->getAll($sSQL);
+if (PEAR::isError($aLinkedLines)) // possible timeout
+{
+    $aLinkedLines = [];
+}
+
+// All places this is an imediate parent of
+$sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea, ST_Distance_Spheroid(geometry, placegeometry, 'SPHEROID[\"WGS 84\",6378137,298.257223563, AUTHORITY[\"EPSG\",\"7030\"]]') as distance, ";
+$sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
+$sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
+$sSQL .= " where parent_place_id = $iPlaceID order by rank_address asc,rank_search asc limit 500) as obj,";
+$sSQL .= " (select centroid as placegeometry from placex where place_id = $iPlaceID) as x";
+$sSQL .= " order by rank_address asc,rank_search asc,localname,housenumber";
+$aParentOfLines = $oDB->getAll($sSQL);
+if (PEAR::isError($aParentOfLines)) // possible timeout
+{
+    $aParentOfLines = [];
+}
+
+$aPlaceSearchNameKeywords = false;
+$aPlaceSearchAddressKeywords = false;
+if ($oParams->getBool('keywords'))
+{
+    $sSQL = "select * from search_name where place_id = $iPlaceID";
+    $aPlaceSearchName = $oDB->getRow($sSQL);
+    if (PEAR::isError($aPlaceSearchName)) // possible timeout
+    {
+        $aPlaceSearchName = [];
+    }
+
+    $sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['name_vector'],1,-1).")";
+    $aPlaceSearchNameKeywords = $oDB->getAll($sSQL);
+    if (PEAR::isError($aPlaceSearchNameKeywords)) // possible timeout
+    {
+        $aPlaceSearchNameKeywords = [];
+    }
+
+
+    $sSQL = "select * from word where word_id in (".substr($aPlaceSearchName['nameaddress_vector'],1,-1).")";
+    $aPlaceSearchAddressKeywords = $oDB->getAll($sSQL);
+    if (PEAR::isError($aPlaceSearchAddressKeywords)) // possible timeout
+    {
+        $aPlaceSearchAddressKeywords = [];
+    }
+
+}
+
+logEnd($oDB, $hLog, 1);
+
+if ($sOutputFormat=='html')
+{
+    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
+    $sTileURL = CONST_Map_Tile_URL;
+    $sTileAttribution = CONST_Map_Tile_Attribution;
+}
+
+include(CONST_BasePath.'/lib/template/details-'.$sOutputFormat.'.php');
index 60d77d6a9d6f69e3004ddf26eaf4dc4e6754f794..959facc7ea74082da49b99815d843d6390b88745 100755 (executable)
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Details');
-
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
-
-       $oParams = new ParameterParser();
-
-       $sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
-       $aLangPrefOrder = $oParams->getPreferredLanguages();
-       $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
-
-       $sPlaceId = $oParams->getString('place_id');
-       $sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
-       $iOsmId = $oParams->getInt('osmid', -1);
-
-       $oDB =& getDB();
-
-       if ($sOsmType && $iOsmId > 0)
-       {
-               $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
-
-               // Be nice about our error messages for broken geometry
-               if (!$sPlaceId)
-               {
-                       $aPointDetails = chksql($oDB->getRow("select osm_type, osm_id, errormessage, class, type, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom from import_polygon_error where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by updated desc limit 1"));
-                       if ($aPointDetails) {
-                               if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches))
-                               {
-                                       $aPointDetails['error_x'] = $aMatches[1];
-                                       $aPointDetails['error_y'] = $aMatches[2];
-                               }
-                               include(CONST_BasePath.'/lib/template/details-error-'.$sOutputFormat.'.php');
-                               exit;
-                       }
-               }
-       }
-
-       if (!$sPlaceId) userError("Please select a place id");
-
-       $iPlaceID = (int)$sPlaceId;
-
-       if (CONST_Use_US_Tiger_Data)
-       {
-               $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID));
-               if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
-       }
-
-       if (CONST_Use_Aux_Location_data)
-       {
-               $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID));
-               if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
-       }
-
-       $oPlaceLookup = new PlaceLookup($oDB);
-       $oPlaceLookup->setLanguagePreference($aLangPrefOrder);
-       $oPlaceLookup->setIncludeAddressDetails(true);
-
-       $aPlaceAddress = array_reverse($oPlaceLookup->getAddressDetails($iPlaceID));
-
-       if (!sizeof($aPlaceAddress)) userError("Unknown place id.");
-
-       $aBreadcrums = array();
-       foreach($aPlaceAddress as $i => $aPlace)
-       {
-               if (!$aPlace['place_id']) continue;
-               $aBreadcrums[] = array('placeId'   => $aPlace['place_id'],
-                                      'osmType'   => $aPlace['osm_type'],
-                                      'osmId'     => $aPlace['osm_id'],
-                                      'localName' => $aPlace['localname']);
-
-               if ($sOutputFormat == 'html')
-               {
-                       $sPlaceUrl = 'hierarchy.php?place_id='.$aPlace['place_id'];
-                       if ($i) echo " &gt; ";
-                       echo '<a href="'.$sPlaceUrl.'">'.$aPlace['localname'].'</a> ('.osmLink($aPlace).')';
-               }
-       }
-
-
-       if ($sOutputFormat == 'json')
-       {
-               header("content-type: application/json; charset=UTF-8");
-               $aDetails = array();
-               $aDetails['breadcrumbs'] = $aBreadcrums;
-               javascript_renderData($aDetails);
-               exit;
-       }
-
-       $aRelatedPlaceIDs = chksql($oDB->getCol($sSQL = "select place_id from placex where linked_place_id = $iPlaceID or place_id = $iPlaceID"));
-
-       $sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea,  st_area(geometry) as area, ";
-       $sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
-       $sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
-       $sSQL .= " where parent_place_id in (".join(',',$aRelatedPlaceIDs).") and name is not null order by rank_address asc,rank_search asc limit 500) as obj";
-       $sSQL .= " order by rank_address asc,rank_search asc,localname,class, type,housenumber";
-       $aParentOfLines = chksql($oDB->getAll($sSQL));
-
-       if (sizeof($aParentOfLines))
-       {
-               echo '<h2>Parent Of:</h2>';
-               $aClassType = getClassTypesWithImportance();
-               $aGroupedAddressLines = array();
-               foreach($aParentOfLines as $aAddressLine)
-               {
-                       if (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'])
-                             && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'])
-                       {
-                               $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'];
-                       }
-                       elseif (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'])
-                               && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'])
-                       {
-                               $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'];
-                       }
-                       else $aAddressLine['label'] = ucwords($aAddressLine['type']);
-
-                       if (!isset($aGroupedAddressLines[$aAddressLine['label']])) $aGroupedAddressLines[$aAddressLine['label']] = array();
-                               $aGroupedAddressLines[$aAddressLine['label']][] = $aAddressLine;
-               }
-
-               foreach($aGroupedAddressLines as $sGroupHeading => $aParentOfLines)
-               {
-                       echo "<h3>$sGroupHeading</h3>";
-                       foreach($aParentOfLines as $aAddressLine)
-                       {
-                               $aAddressLine['localname'] = $aAddressLine['localname']?$aAddressLine['localname']:$aAddressLine['housenumber'];
-                               $sOSMType = formatOSMType($aAddressLine['osm_type'], false);
-
-                               echo '<div class="line">';
-                               echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
-                               echo ' (';
-                               echo '<span class="area">'.($aAddressLine['isarea']=='t'?'Polygon':'Point').'</span>';
-                               if ($sOSMType) echo ', <span class="osm"><span class="label"></span>'.$sOSMType.' '.osmLink($aAddressLine).'</span>';
-                               echo ', <a href="hierarchy.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
-                               echo ', '.$aAddressLine['area'];
-                               echo ')';
-                               echo '</div>';
-                       }
-               }
-               if (sizeof($aParentOfLines) >= 500) {
-                       echo '<p>There are more child objects which are not shown.</p>';
-               }
-               echo '</div>';
-       }
+@define('CONST_ConnectionBucket_PageType', 'Details');
+
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/output.php');
+ini_set('memory_limit', '200M');
+
+$oParams = new ParameterParser();
+
+$sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html');
+$aLangPrefOrder = $oParams->getPreferredLanguages();
+$sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]";
+
+$sPlaceId = $oParams->getString('place_id');
+$sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R'));
+$iOsmId = $oParams->getInt('osmid', -1);
+
+$oDB =& getDB();
+
+if ($sOsmType && $iOsmId > 0)
+{
+    $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc"));
+
+    // Be nice about our error messages for broken geometry
+    if (!$sPlaceId)
+    {
+        $aPointDetails = chksql($oDB->getRow("select osm_type, osm_id, errormessage, class, type, get_name_by_language(name,$sLanguagePrefArraySQL) as localname, ST_AsText(prevgeometry) as prevgeom, ST_AsText(newgeometry) as newgeom from import_polygon_error where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by updated desc limit 1"));
+        if ($aPointDetails) {
+            if (preg_match('/\[(-?\d+\.\d+) (-?\d+\.\d+)\]/', $aPointDetails['errormessage'], $aMatches))
+            {
+                $aPointDetails['error_x'] = $aMatches[1];
+                $aPointDetails['error_y'] = $aMatches[2];
+            }
+            include(CONST_BasePath.'/lib/template/details-error-'.$sOutputFormat.'.php');
+            exit;
+        }
+    }
+}
+
+if (!$sPlaceId) userError("Please select a place id");
+
+$iPlaceID = (int)$sPlaceId;
+
+if (CONST_Use_US_Tiger_Data)
+{
+    $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_tiger where place_id = '.$iPlaceID));
+    if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
+}
+
+if (CONST_Use_Aux_Location_data)
+{
+    $iParentPlaceID = chksql($oDB->getOne('select parent_place_id from location_property_aux where place_id = '.$iPlaceID));
+    if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
+}
+
+$oPlaceLookup = new PlaceLookup($oDB);
+$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
+$oPlaceLookup->setIncludeAddressDetails(true);
+
+$aPlaceAddress = array_reverse($oPlaceLookup->getAddressDetails($iPlaceID));
+
+if (!sizeof($aPlaceAddress)) userError("Unknown place id.");
+
+$aBreadcrums = array();
+foreach($aPlaceAddress as $i => $aPlace)
+{
+    if (!$aPlace['place_id']) continue;
+    $aBreadcrums[] = array('placeId'   => $aPlace['place_id'],
+                           'osmType'   => $aPlace['osm_type'],
+                           'osmId'     => $aPlace['osm_id'],
+                           'localName' => $aPlace['localname']);
+
+    if ($sOutputFormat == 'html')
+    {
+        $sPlaceUrl = 'hierarchy.php?place_id='.$aPlace['place_id'];
+        if ($i) echo " &gt; ";
+        echo '<a href="'.$sPlaceUrl.'">'.$aPlace['localname'].'</a> ('.osmLink($aPlace).')';
+    }
+}
+
+
+if ($sOutputFormat == 'json')
+{
+    header("content-type: application/json; charset=UTF-8");
+    $aDetails = array();
+    $aDetails['breadcrumbs'] = $aBreadcrums;
+    javascript_renderData($aDetails);
+    exit;
+}
+
+$aRelatedPlaceIDs = chksql($oDB->getCol($sSQL = "select place_id from placex where linked_place_id = $iPlaceID or place_id = $iPlaceID"));
+
+$sSQL = "select obj.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, ST_GeometryType(geometry) in ('ST_Polygon','ST_MultiPolygon') as isarea,  st_area(geometry) as area, ";
+$sSQL .= " get_name_by_language(name,$sLanguagePrefArraySQL) as localname, length(name::text) as namelength ";
+$sSQL .= " from (select placex.place_id, osm_type, osm_id, class, type, housenumber, admin_level, rank_address, rank_search, geometry, name from placex ";
+$sSQL .= " where parent_place_id in (".join(',',$aRelatedPlaceIDs).") and name is not null order by rank_address asc,rank_search asc limit 500) as obj";
+$sSQL .= " order by rank_address asc,rank_search asc,localname,class, type,housenumber";
+$aParentOfLines = chksql($oDB->getAll($sSQL));
+
+if (sizeof($aParentOfLines))
+{
+    echo '<h2>Parent Of:</h2>';
+    $aClassType = getClassTypesWithImportance();
+    $aGroupedAddressLines = array();
+    foreach($aParentOfLines as $aAddressLine)
+    {
+        if (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'])
+              && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'])
+        {
+            $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'];
+        }
+        elseif (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'])
+                && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'])
+        {
+            $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'];
+        }
+        else $aAddressLine['label'] = ucwords($aAddressLine['type']);
+
+        if (!isset($aGroupedAddressLines[$aAddressLine['label']])) $aGroupedAddressLines[$aAddressLine['label']] = array();
+            $aGroupedAddressLines[$aAddressLine['label']][] = $aAddressLine;
+    }
+
+    foreach($aGroupedAddressLines as $sGroupHeading => $aParentOfLines)
+    {
+        echo "<h3>$sGroupHeading</h3>";
+        foreach($aParentOfLines as $aAddressLine)
+        {
+            $aAddressLine['localname'] = $aAddressLine['localname']?$aAddressLine['localname']:$aAddressLine['housenumber'];
+            $sOSMType = formatOSMType($aAddressLine['osm_type'], false);
+
+            echo '<div class="line">';
+            echo '<span class="name">'.(trim($aAddressLine['localname'])?$aAddressLine['localname']:'<span class="noname">No Name</span>').'</span>';
+            echo ' (';
+            echo '<span class="area">'.($aAddressLine['isarea']=='t'?'Polygon':'Point').'</span>';
+            if ($sOSMType) echo ', <span class="osm"><span class="label"></span>'.$sOSMType.' '.osmLink($aAddressLine).'</span>';
+            echo ', <a href="hierarchy.php?place_id='.$aAddressLine['place_id'].'">GOTO</a>';
+            echo ', '.$aAddressLine['area'];
+            echo ')';
+            echo '</div>';
+        }
+    }
+    if (sizeof($aParentOfLines) >= 500) {
+        echo '<p>There are more child objects which are not shown.</p>';
+    }
+    echo '</div>';
+}
index d1cd4548badf8b0bee5f65cab146ab54b8b8f615..e32385f7fb73e0863eab52ea00c8d4652c40e2cd 100644 (file)
@@ -3,201 +3,201 @@ var last_click_latlng;
 
 jQuery(document).on('ready', function(){
 
-       if ( !$('#search-page,#reverse-page').length ){ return; }
-       
-       var is_reverse_search = !!( $('#reverse-page').length );
+    if ( !$('#search-page,#reverse-page').length ){ return; }
+    
+    var is_reverse_search = !!( $('#reverse-page').length );
 
-       $('#q').focus();
+    $('#q').focus();
 
-       map = new L.map('map', {
-                               attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
-                               scrollWheelZoom:    !L.Browser.touch,
-                               touchZoom:          false
-                       });
-
-       L.tileLayer(nominatim_map_init.tile_url, {
-               noWrap: true, // otherwise we end up with click coordinates like latitude -728
-               // moved to footer
-               attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
-       }).addTo(map);
-
-       map.setView([nominatim_map_init.lat, nominatim_map_init.lon], nominatim_map_init.zoom);
-
-       if ( is_reverse_search ){
-               // We don't need a marker, but an L.circle instance changes radius once you zoom in/out
-               var cm = L.circleMarker([nominatim_map_init.lat,nominatim_map_init.lon], { radius: 5, weight: 2, fillColor: '#ff7800', color: 'red', opacity: 0.75, clickable: false});
-               cm.addTo(map);
-       }
-
-       var MapPositionControl = L.Control.extend({
-                       options: {
-                                       position: 'topright'
-                       },
-
-                       onAdd: function (map) {
-                                       var container = L.DomUtil.create('div', 'my-custom-control');
-
-                                       $(container).text('show map bounds').addClass('leaflet-bar btn btn-sm btn-default').on('click', function(e){
-                                               e.preventDefault();
-                                               e.stopPropagation();
-                                               $('#map-position').show();
-                                               $(container).hide();
-                                       });
-                                       $('#map-position-close a').on('click', function(e){
-                                               e.preventDefault();
-                                               e.stopPropagation();
-                                               $('#map-position').hide();
-                                               $(container).show();
-                                       });
-
-                                       return container;
-                       }
-       });
-
-       map.addControl(new MapPositionControl());
-
-
-       function display_map_position(mouse_lat_lng){
-
-               html_mouse = "mouse position " + (mouse_lat_lng ? [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(',') : '-');
-               html_click = "last click: " + (last_click_latlng ? [last_click_latlng.lat.toFixed(5),last_click_latlng.lng.toFixed(5)].join(',') : '-');
-
-               html_center = 
-                       "map center: " + 
-                       map.getCenter().lat.toFixed(5) + ',' + map.getCenter().lng.toFixed(5) +
-                       " <a target='_blank' href='" + map_link_to_osm() + "'>view on osm.org</a>";
-
-               html_zoom = "map zoom: " + map.getZoom();
-
-               html_viewbox = "viewbox: " + map_viewbox_as_string();
-
-               $('#map-position-inner').html([html_center,html_zoom,html_viewbox,html_click,html_mouse].join('<br/>'));
-               $('input#use_viewbox').trigger('change');
-       }
-
-       map.on('move', function(e) {
-               display_map_position();
-       });
-
-       map.on('mousemove', function(e) {
-               display_map_position(e.latlng);
-       });
-
-       map.on('click', function(e) {
-               last_click_latlng = e.latlng;
-               display_map_position();
-       });
-
-       map.on('load', function(e){
-               display_map_position();
-       });
-
-
-       $('input#use_viewbox').on('change', function(){
-               $('input[name=viewbox]').val( $(this).prop('checked') ? map_viewbox_as_string() : '');
-       });
-
-
-
-       function map_viewbox_as_string() {
-               // since .toBBoxString() doesn't round numbers
-               return [
-                       map.getBounds().getSouthWest().lat.toFixed(5),
-                       map.getBounds().getSouthWest().lng.toFixed(5),
-                       map.getBounds().getNorthEast().lat.toFixed(5),
-                       map.getBounds().getNorthEast().lng.toFixed(5) ].join(',');
-       }
-       function map_link_to_osm(){
-               return "http://openstreetmap.org/#map=" + map.getZoom() + "/" + map.getCenter().lat + "/" + map.getCenter().lng;
-       }
-
-       function get_result_element(position){
-               return $('.result').eq(position);
-       }
-       function marker_for_result(result){
-               return L.marker([result.lat,result.lon], {riseOnHover:true,title:result.name });
-       }
-       function circle_for_result(result){
-               return L.circleMarker([result.lat,result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75, clickable: !is_reverse_search});
-       }
-
-       var layerGroup = new L.layerGroup().addTo(map);
-       function highlight_result(position, bool_focus){
-               var result = nominatim_results[position];
-               if (!result){ return }
-               var result_el = get_result_element(position);
-
-               $('.result').removeClass('highlight');
-               result_el.addClass('highlight');
-
-               layerGroup.clearLayers();
-
-               if (result.lat){
-                       var circle = circle_for_result(result);
-                       circle.on('click', function(){
-                               highlight_result(position);
-                       });
-                       layerGroup.addLayer(circle);                    
-               }
-               if (result.aBoundingBox){
-
-                       var bounds = [[result.aBoundingBox[0]*1,result.aBoundingBox[2]*1], [result.aBoundingBox[1]*1,result.aBoundingBox[3]*1]];
-                       map.fitBounds(bounds);
-                       if (result.astext && result.astext.match(/(POLY)|(LINE)/) ){
-                               var geojson_layer = L.geoJson(null, {
-                                       // http://leafletjs.com/reference.html#geojson-style
-                                       style: function(feature) { return { clickable: false, color: 'blue' }; }
-                               });
-                               omnivore.wkt.parse(result.astext,null,geojson_layer);
-                               layerGroup.addLayer(geojson_layer);
-                       }
-                       else {
-                               // var layer = L.rectangle(bounds, {color: "#ff7800", weight: 1} );
-                               // layerGroup.addLayer(layer);
-                       }
-               }
-               else {
-                       if ( is_reverse_search ){
-                               // make sure the search coordinates are in the map view as well
-                               map.fitBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {padding: [50,50], maxZoom: map.getZoom()});
-
-                               // better, but causes a leaflet warning
-                               // map.panInsideBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {animate: false});
-                       }
-                       else {
-                               map.panTo([result.lat,result.lon], result.zoom || nominatim_map_init.zoom);
-                       }
-               }
-
-               // var crosshairIcon = L.icon({
-               //      iconUrl:     'images/crosshair.png',
-               //      iconSize:    [12, 12],
-               //      iconAnchor:  [6, 6],
-               // });
-               // var crossMarker = new L.Marker([result.lat,result.lon], { icon: crosshairIcon, clickable: false});
-               // layerGroup.addLayer(crossMarker);
-
-
-
-               if (bool_focus){
-                       $('#map').focus();
-               }
-       }
-
-
-       $('.result').on('click', function(e){
-               highlight_result($(this).data('position'), true);
-       });
-
-       if ( is_reverse_search ){
-               map.on('click', function(e){
-                       $('form input[name=lat]').val( e.latlng.lat);
-                       $('form input[name=lon]').val( e.latlng.lng);
-                       $('form').submit();
-               });
-       }
-
-       highlight_result(0, false);
+    map = new L.map('map', {
+                attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
+                scrollWheelZoom:    !L.Browser.touch,
+                touchZoom:          false
+            });
+
+    L.tileLayer(nominatim_map_init.tile_url, {
+        noWrap: true, // otherwise we end up with click coordinates like latitude -728
+        // moved to footer
+        attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
+    }).addTo(map);
+
+    map.setView([nominatim_map_init.lat, nominatim_map_init.lon], nominatim_map_init.zoom);
+
+    if ( is_reverse_search ){
+        // We don't need a marker, but an L.circle instance changes radius once you zoom in/out
+        var cm = L.circleMarker([nominatim_map_init.lat,nominatim_map_init.lon], { radius: 5, weight: 2, fillColor: '#ff7800', color: 'red', opacity: 0.75, clickable: false});
+        cm.addTo(map);
+    }
+
+    var MapPositionControl = L.Control.extend({
+            options: {
+                    position: 'topright'
+            },
+
+            onAdd: function (map) {
+                    var container = L.DomUtil.create('div', 'my-custom-control');
+
+                    $(container).text('show map bounds').addClass('leaflet-bar btn btn-sm btn-default').on('click', function(e){
+                        e.preventDefault();
+                        e.stopPropagation();
+                        $('#map-position').show();
+                        $(container).hide();
+                    });
+                    $('#map-position-close a').on('click', function(e){
+                        e.preventDefault();
+                        e.stopPropagation();
+                        $('#map-position').hide();
+                        $(container).show();
+                    });
+
+                    return container;
+            }
+    });
+
+    map.addControl(new MapPositionControl());
+
+
+    function display_map_position(mouse_lat_lng){
+
+        html_mouse = "mouse position " + (mouse_lat_lng ? [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(',') : '-');
+        html_click = "last click: " + (last_click_latlng ? [last_click_latlng.lat.toFixed(5),last_click_latlng.lng.toFixed(5)].join(',') : '-');
+
+        html_center = 
+            "map center: " + 
+            map.getCenter().lat.toFixed(5) + ',' + map.getCenter().lng.toFixed(5) +
+            " <a target='_blank' href='" + map_link_to_osm() + "'>view on osm.org</a>";
+
+        html_zoom = "map zoom: " + map.getZoom();
+
+        html_viewbox = "viewbox: " + map_viewbox_as_string();
+
+        $('#map-position-inner').html([html_center,html_zoom,html_viewbox,html_click,html_mouse].join('<br/>'));
+        $('input#use_viewbox').trigger('change');
+    }
+
+    map.on('move', function(e) {
+        display_map_position();
+    });
+
+    map.on('mousemove', function(e) {
+        display_map_position(e.latlng);
+    });
+
+    map.on('click', function(e) {
+        last_click_latlng = e.latlng;
+        display_map_position();
+    });
+
+    map.on('load', function(e){
+        display_map_position();
+    });
+
+
+    $('input#use_viewbox').on('change', function(){
+        $('input[name=viewbox]').val( $(this).prop('checked') ? map_viewbox_as_string() : '');
+    });
+
+
+
+    function map_viewbox_as_string() {
+        // since .toBBoxString() doesn't round numbers
+        return [
+            map.getBounds().getSouthWest().lat.toFixed(5),
+            map.getBounds().getSouthWest().lng.toFixed(5),
+            map.getBounds().getNorthEast().lat.toFixed(5),
+            map.getBounds().getNorthEast().lng.toFixed(5) ].join(',');
+    }
+    function map_link_to_osm(){
+        return "http://openstreetmap.org/#map=" + map.getZoom() + "/" + map.getCenter().lat + "/" + map.getCenter().lng;
+    }
+
+    function get_result_element(position){
+        return $('.result').eq(position);
+    }
+    function marker_for_result(result){
+        return L.marker([result.lat,result.lon], {riseOnHover:true,title:result.name });
+    }
+    function circle_for_result(result){
+        return L.circleMarker([result.lat,result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75, clickable: !is_reverse_search});
+    }
+
+    var layerGroup = new L.layerGroup().addTo(map);
+    function highlight_result(position, bool_focus){
+        var result = nominatim_results[position];
+        if (!result){ return }
+        var result_el = get_result_element(position);
+
+        $('.result').removeClass('highlight');
+        result_el.addClass('highlight');
+
+        layerGroup.clearLayers();
+
+        if (result.lat){
+            var circle = circle_for_result(result);
+            circle.on('click', function(){
+                highlight_result(position);
+            });
+            layerGroup.addLayer(circle);            
+        }
+        if (result.aBoundingBox){
+
+            var bounds = [[result.aBoundingBox[0]*1,result.aBoundingBox[2]*1], [result.aBoundingBox[1]*1,result.aBoundingBox[3]*1]];
+            map.fitBounds(bounds);
+            if (result.astext && result.astext.match(/(POLY)|(LINE)/) ){
+                var geojson_layer = L.geoJson(null, {
+                    // http://leafletjs.com/reference.html#geojson-style
+                    style: function(feature) { return { clickable: false, color: 'blue' }; }
+                });
+                omnivore.wkt.parse(result.astext,null,geojson_layer);
+                layerGroup.addLayer(geojson_layer);
+            }
+            else {
+                // var layer = L.rectangle(bounds, {color: "#ff7800", weight: 1} );
+                // layerGroup.addLayer(layer);
+            }
+        }
+        else {
+            if ( is_reverse_search ){
+                // make sure the search coordinates are in the map view as well
+                map.fitBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {padding: [50,50], maxZoom: map.getZoom()});
+
+                // better, but causes a leaflet warning
+                // map.panInsideBounds([[result.lat,result.lon], [nominatim_map_init.lat,nominatim_map_init.lon]], {animate: false});
+            }
+            else {
+                map.panTo([result.lat,result.lon], result.zoom || nominatim_map_init.zoom);
+            }
+        }
+
+        // var crosshairIcon = L.icon({
+        //  iconUrl:     'images/crosshair.png',
+        //  iconSize:    [12, 12],
+        //  iconAnchor:  [6, 6],
+        // });
+        // var crossMarker = new L.Marker([result.lat,result.lon], { icon: crosshairIcon, clickable: false});
+        // layerGroup.addLayer(crossMarker);
+
+
+
+        if (bool_focus){
+            $('#map').focus();
+        }
+    }
+
+
+    $('.result').on('click', function(e){
+        highlight_result($(this).data('position'), true);
+    });
+
+    if ( is_reverse_search ){
+        map.on('click', function(e){
+            $('form input[name=lat]').val( e.latlng.lat);
+            $('form input[name=lon]').val( e.latlng.lng);
+            $('form').submit();
+        });
+    }
+
+    highlight_result(0, false);
 
 
 });
@@ -205,41 +205,41 @@ jQuery(document).on('ready', function(){
 
 jQuery(document).on('ready', function(){
 
-       if ( !$('#details-page').length ){ return; }
+    if ( !$('#details-page').length ){ return; }
 
 
-               map = new L.map('map', {
-                                       // center: [nominatim_map_init.lat, nominatim_map_init.lon],
-                                       // zoom:   nominatim_map_init.zoom,
-                                       attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
-                                       scrollWheelZoom:    false,
-                                       touchZoom:          false,
-                               });
+        map = new L.map('map', {
+                    // center: [nominatim_map_init.lat, nominatim_map_init.lon],
+                    // zoom:   nominatim_map_init.zoom,
+                    attributionControl: (nominatim_map_init.tile_attribution && nominatim_map_init.tile_attribution.length),
+                    scrollWheelZoom:    false,
+                    touchZoom:          false,
+                });
 
 
-               L.tileLayer(nominatim_map_init.tile_url, {
-                       // moved to footer
-                       attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
-               }).addTo(map);
+        L.tileLayer(nominatim_map_init.tile_url, {
+            // moved to footer
+            attribution: (nominatim_map_init.tile_attribution || null ) //'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
+        }).addTo(map);
 
 
-               var layerGroup = new L.layerGroup().addTo(map);
+        var layerGroup = new L.layerGroup().addTo(map);
 
-               var circle = L.circleMarker([nominatim_result.lat,nominatim_result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75});
-               map.addLayer(circle);
+        var circle = L.circleMarker([nominatim_result.lat,nominatim_result.lon], { radius: 10, weight: 2, fillColor: '#ff7800', color: 'blue', opacity: 0.75});
+        map.addLayer(circle);
 
-               if ( nominatim_result.outlinestring ){
+        if ( nominatim_result.outlinestring ){
 
-                       var geojson_layer = L.geoJson(null, {
-                               // http://leafletjs.com/reference.html#geojson-style
-                               style: function(feature) { return { clickable: false, color: 'blue' }; }
-                       });
-                       omnivore.wkt.parse(nominatim_result.outlinestring,null,geojson_layer);
-                       layerGroup.addLayer(geojson_layer);
-                       map.fitBounds(geojson_layer.getBounds());
-               } else {
-                       map.setView([nominatim_result.lat,nominatim_result.lon],10);
-               }
+            var geojson_layer = L.geoJson(null, {
+                // http://leafletjs.com/reference.html#geojson-style
+                style: function(feature) { return { clickable: false, color: 'blue' }; }
+            });
+            omnivore.wkt.parse(nominatim_result.outlinestring,null,geojson_layer);
+            layerGroup.addLayer(geojson_layer);
+            map.fitBounds(geojson_layer.getBounds());
+        } else {
+            map.setView([nominatim_result.lat,nominatim_result.lon],10);
+        }
 
 
 
index cd29d4dad20dd4216408093f2f437990af96014b..22ee2f5af2d5896ff3f925b2e397207ae3997b8e 100755 (executable)
@@ -1,5 +1,5 @@
 div.olMap {
-       z-index: 0;
+    z-index: 0;
     padding: 0px!important;
     margin: 0px!important;
     cursor: default;
index 0129f21748a4f03d0dd55e58c638d96d611e28b1..3529aa5c651b97cea03866d0a2a3ab9268f5c09f 100755 (executable)
@@ -1,75 +1,75 @@
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Reverse');
+@define('CONST_ConnectionBucket_PageType', 'Reverse');
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/output.php');
+ini_set('memory_limit', '200M');
 
-       $oParams = new ParameterParser();
+$oParams = new ParameterParser();
 
-       // Format for output
-       $sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml');
+// Format for output
+$sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml');
 
-       // Preferred language
-       $aLangPrefOrder = $oParams->getPreferredLanguages();
+// Preferred language
+$aLangPrefOrder = $oParams->getPreferredLanguages();
 
-       $oDB =& getDB();
+$oDB =& getDB();
 
-       $hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
+$hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
 
-       $aSearchResults = array();
-       $aCleanedQueryParts = array();
+$aSearchResults = array();
+$aCleanedQueryParts = array();
 
-       $oPlaceLookup = new PlaceLookup($oDB);
-       $oPlaceLookup->setLanguagePreference($aLangPrefOrder);
-       $oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
-       $oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
-       $oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
+$oPlaceLookup = new PlaceLookup($oDB);
+$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
+$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
+$oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
+$oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
 
-       $aOsmIds = explode(',', $oParams->getString('osm_ids', ''));
+$aOsmIds = explode(',', $oParams->getString('osm_ids', ''));
 
-       if (count($aOsmIds) > CONST_Places_Max_ID_count)
-       {
-               userError('Bulk User: Only ' . CONST_Places_Max_ID_count . " ids are allowed in one request.");
-       }
+if (count($aOsmIds) > CONST_Places_Max_ID_count)
+{
+    userError('Bulk User: Only ' . CONST_Places_Max_ID_count . " ids are allowed in one request.");
+}
 
-       foreach ($aOsmIds AS $sItem)
-       {
-               // Skip empty sItem
-               if (empty($sItem)) continue;
-               
-               $sType = $sItem[0];
-               $iId = (int) substr($sItem, 1);
-               if ( $iId > 0 && ($sType == 'N' || $sType == 'W' || $sType == 'R') )
-               {
-                       $aCleanedQueryParts[] = $sType . $iId;
-                       $oPlace = $oPlaceLookup->lookupOSMID($sType, $iId);
-                       if ($oPlace){
-                               // we want to use the search-* output templates, so we need to fill
-                               // $aSearchResults and slightly change the (reverse search) oPlace
-                               // key names
-                               $oResult = $oPlace;
-                               unset($oResult['aAddress']);
-                               if (isset($oPlace['aAddress'])) $oResult['address'] = $oPlace['aAddress'];
-                               unset($oResult['langaddress']);
-                               $oResult['name'] = $oPlace['langaddress'];
-                               $aSearchResults[] = $oResult;
-                       }
-               }
-       }
+foreach ($aOsmIds AS $sItem)
+{
+    // Skip empty sItem
+    if (empty($sItem)) continue;
+    
+    $sType = $sItem[0];
+    $iId = (int) substr($sItem, 1);
+    if ( $iId > 0 && ($sType == 'N' || $sType == 'W' || $sType == 'R') )
+    {
+        $aCleanedQueryParts[] = $sType . $iId;
+        $oPlace = $oPlaceLookup->lookupOSMID($sType, $iId);
+        if ($oPlace){
+            // we want to use the search-* output templates, so we need to fill
+            // $aSearchResults and slightly change the (reverse search) oPlace
+            // key names
+            $oResult = $oPlace;
+            unset($oResult['aAddress']);
+            if (isset($oPlace['aAddress'])) $oResult['address'] = $oPlace['aAddress'];
+            unset($oResult['langaddress']);
+            $oResult['name'] = $oPlace['langaddress'];
+            $aSearchResults[] = $oResult;
+        }
+    }
+}
 
 
-       if (CONST_Debug) exit;
+if (CONST_Debug) exit;
 
-       $sXmlRootTag = 'lookupresults';
-       $sQuery = join(',',$aCleanedQueryParts);
-       // we initialize these to avoid warnings in our logfile
-       $sViewBox = '';
-       $bShowPolygons = '';
-       $aExcludePlaceIDs = [];
-       $sMoreURL = '';
+$sXmlRootTag = 'lookupresults';
+$sQuery = join(',',$aCleanedQueryParts);
+// we initialize these to avoid warnings in our logfile
+$sViewBox = '';
+$bShowPolygons = '';
+$aExcludePlaceIDs = [];
+$sMoreURL = '';
 
-       include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php');
+include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php');
index 1e0f5f7ea757012d329afec46967f9d6f19b2162..a8abd83b1ce4066c64ba3d1c3a642f3137513628 100755 (executable)
 <?php
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
+    require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+    require_once(CONST_BasePath.'/lib/init-website.php');
+    require_once(CONST_BasePath.'/lib/log.php');
+    require_once(CONST_BasePath.'/lib/output.php');
+    ini_set('memory_limit', '200M');
 
-       $oParams = new ParameterParser();
+    $oParams = new ParameterParser();
 
-       $sOutputFormat = 'html';
-       $iDays = $oParams->getInt('days', 1);
-       $bReduced = $oParams->getBool('reduced', false);
-       $sClass = $oParams->getString('class', false);
+    $sOutputFormat = 'html';
+    $iDays = $oParams->getInt('days', 1);
+    $bReduced = $oParams->getBool('reduced', false);
+    $sClass = $oParams->getString('class', false);
 
-       $oDB =& getDB();
+    $oDB =& getDB();
 
-       $iTotalBroken = (int) chksql($oDB->getOne('select count(*) from import_polygon_error'));
+    $iTotalBroken = (int) chksql($oDB->getOne('select count(*) from import_polygon_error'));
 
-       $aPolygons = array();
-       while($iTotalBroken && !sizeof($aPolygons))
-       {
-               $sSQL = 'select osm_type as "type",osm_id as "id",class as "key",type as "value",name->\'name\' as "name",';
-               $sSQL .= 'country_code as "country",errormessage as "error message",updated';
-               $sSQL .= " from import_polygon_error";
-               $sSQL .= " where updated > 'now'::timestamp - '".$iDays." day'::interval";
-               $iDays++;
+    $aPolygons = array();
+    while($iTotalBroken && !sizeof($aPolygons))
+    {
+        $sSQL = 'select osm_type as "type",osm_id as "id",class as "key",type as "value",name->\'name\' as "name",';
+        $sSQL .= 'country_code as "country",errormessage as "error message",updated';
+        $sSQL .= " from import_polygon_error";
+        $sSQL .= " where updated > 'now'::timestamp - '".$iDays." day'::interval";
+        $iDays++;
 
-               if ($bReduced) $sSQL .= " and errormessage like 'Area reduced%'";
-               if ($sClass) $sSQL .= " and class = '".pg_escape_string($sClass)."'";
-               $sSQL .= " order by updated desc limit 1000";
-               $aPolygons = chksql($oDB->getAll($sSQL));
-       }
+        if ($bReduced) $sSQL .= " and errormessage like 'Area reduced%'";
+        if ($sClass) $sSQL .= " and class = '".pg_escape_string($sClass)."'";
+        $sSQL .= " order by updated desc limit 1000";
+        $aPolygons = chksql($oDB->getAll($sSQL));
+    }
 
-       if (CONST_Debug)
-       {
-               var_dump($aPolygons);
-               exit;
-       }
+    if (CONST_Debug)
+    {
+        var_dump($aPolygons);
+        exit;
+    }
 ?>
 <!DOCTYPE html>
 <html>
 <head>
-       <meta charset="utf-8"/>
-       <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
-       
-       <title>Nominatim Broken Polygon Data</title>
-       
-       <meta name="description" content="List of broken OSM polygon data by date" lang="en-US" />
+    <meta charset="utf-8"/>
+    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
+    
+    <title>Nominatim Broken Polygon Data</title>
+    
+    <meta name="description" content="List of broken OSM polygon data by date" lang="en-US" />
 
 </head>
 
 <body>
 <style type="text/css">
 table {
-       border-width: 1px;
-       border-spacing: 0px;
-       border-style: solid;
-       border-color: gray;
-       border-collapse: collapse;
-       background-color: white;
-       margin: 10px;
+    border-width: 1px;
+    border-spacing: 0px;
+    border-style: solid;
+    border-color: gray;
+    border-collapse: collapse;
+    background-color: white;
+    margin: 10px;
 }
 table th {
-       border-width: 1px;
-       padding: 2px;
-       border-style: inset;
-       border-color: gray;
-       border-left-color: #ddd;
-       border-right-color: #ddd;
-       background-color: #eee;
-       -moz-border-radius: 0px 0px 0px 0px;
+    border-width: 1px;
+    padding: 2px;
+    border-style: inset;
+    border-color: gray;
+    border-left-color: #ddd;
+    border-right-color: #ddd;
+    background-color: #eee;
+    -moz-border-radius: 0px 0px 0px 0px;
 }
 table td {
-       border-width: 1px;
-       padding: 2px;
-       border-style: inset;
-       border-color: gray;
-       border-left-color: #ddd;
-       border-right-color: #ddd;
-       background-color: white;
-       -moz-border-radius: 0px 0px 0px 0px;
+    border-width: 1px;
+    padding: 2px;
+    border-style: inset;
+    border-color: gray;
+    border-left-color: #ddd;
+    border-right-color: #ddd;
+    background-color: white;
+    -moz-border-radius: 0px 0px 0px 0px;
 }
 </style>
 
 <?php
 
-       echo "<p>Total number of broken polygons: $iTotalBroken</p>";
-       if (!$aPolygons) exit;
-       echo "<table>";
-       echo "<tr>";
+    echo "<p>Total number of broken polygons: $iTotalBroken</p>";
+    if (!$aPolygons) exit;
+    echo "<table>";
+    echo "<tr>";
 //var_dump($aPolygons[0]);
-       foreach($aPolygons[0] as $sCol => $sVal)
-       {
-               echo "<th>".$sCol."</th>";
-       }
-       echo "<th>&nbsp;</th>";
-       echo "<th>&nbsp;</th>";
-       echo "</tr>";
-       $aSeen = array();
-       foreach($aPolygons as $aRow)
-       {
-               if (isset($aSeen[$aRow['type'].$aRow['id']])) continue;
-               $aSeen[$aRow['type'].$aRow['id']] = 1;
-               echo "<tr>";
-               foreach($aRow as $sCol => $sVal)
-               {
-                       switch($sCol)
-                       {
-                       case 'error message':
-                               if (preg_match('/Self-intersection\\[([0-9.\\-]+) ([0-9.\\-]+)\\]/',$sVal,$aMatch))
-                               {
-                                       $aRow['lat'] = $aMatch[2];
-                                       $aRow['lon'] = $aMatch[1];
-                                       echo "<td><a href=\"http://www.openstreetmap.org/?lat=".$aMatch[2]."&lon=".$aMatch[1]."&zoom=18&layers=M&".$sOSMType."=".$aRow['id']."\">".($sVal?$sVal:'&nbsp;')."</a></td>";
-                               }
-                               else
-                               {
-                                       echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
-                               }
-                               break;
-                       case 'id':
-                               echo '<td>'.osmLink($aRow).'</td>';
-                               break;
-                       default:
-                               echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
-                               break;
-                       }
-               }
-               echo "<td><a href=\"http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/".$sOSMType.'/'.$aRow['id']."/full\" target=\"josm\">josm</a></td>";
-               if (isset($aRow['lat']))
-               {
-                       echo "<td><a href=\"http://open.mapquestapi.com/dataedit/index_flash.html?lat=".$aRow['lat']."&lon=".$aRow['lon']."&zoom=18\" target=\"potlatch2\">P2</a></td>";
-               }
-               else
-               {
-                       echo "<td>&nbsp;</td>"; 
-               }
-               echo "</tr>";
-       }
-       echo "</table>";
+    foreach($aPolygons[0] as $sCol => $sVal)
+    {
+        echo "<th>".$sCol."</th>";
+    }
+    echo "<th>&nbsp;</th>";
+    echo "<th>&nbsp;</th>";
+    echo "</tr>";
+    $aSeen = array();
+    foreach($aPolygons as $aRow)
+    {
+        if (isset($aSeen[$aRow['type'].$aRow['id']])) continue;
+        $aSeen[$aRow['type'].$aRow['id']] = 1;
+        echo "<tr>";
+        foreach($aRow as $sCol => $sVal)
+        {
+            switch($sCol)
+            {
+            case 'error message':
+                if (preg_match('/Self-intersection\\[([0-9.\\-]+) ([0-9.\\-]+)\\]/',$sVal,$aMatch))
+                {
+                    $aRow['lat'] = $aMatch[2];
+                    $aRow['lon'] = $aMatch[1];
+                    echo "<td><a href=\"http://www.openstreetmap.org/?lat=".$aMatch[2]."&lon=".$aMatch[1]."&zoom=18&layers=M&".$sOSMType."=".$aRow['id']."\">".($sVal?$sVal:'&nbsp;')."</a></td>";
+                }
+                else
+                {
+                    echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
+                }
+                break;
+            case 'id':
+                echo '<td>'.osmLink($aRow).'</td>';
+                break;
+            default:
+                echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
+                break;
+            }
+        }
+        echo "<td><a href=\"http://localhost:8111/import?url=http://www.openstreetmap.org/api/0.6/".$sOSMType.'/'.$aRow['id']."/full\" target=\"josm\">josm</a></td>";
+        if (isset($aRow['lat']))
+        {
+            echo "<td><a href=\"http://open.mapquestapi.com/dataedit/index_flash.html?lat=".$aRow['lat']."&lon=".$aRow['lon']."&zoom=18\" target=\"potlatch2\">P2</a></td>";
+        }
+        else
+        {
+            echo "<td>&nbsp;</td>"; 
+        }
+        echo "</tr>";
+    }
+    echo "</table>";
 ?>
 </body>
 </html>
index 50ce4787350ecd2b5c76824fde1fa197f500f757..8864ab649f820177f14a854c1944723c27848068 100755 (executable)
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Reverse');
-
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
-       require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
-
-       $oParams = new ParameterParser();
-
-       $bAsGeoJSON = $oParams->getBool('polygon_geojson');
-       $bAsKML = $oParams->getBool('polygon_kml');
-       $bAsSVG = $oParams->getBool('polygon_svg');
-       $bAsText = $oParams->getBool('polygon_text');
-       if ((($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0)
-               + ($bAsText?1:0)) > CONST_PolygonOutput_MaximumTypes)
-       {
-               if (CONST_PolygonOutput_MaximumTypes)
-               {
-                       userError("Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option");
-               }
-               else
-               {
-                       userError("Polygon output is disabled");
-               }
-       }
-
-       // Polygon simplification threshold (optional)
-       $fThreshold = $oParams->getFloat('polygon_threshold', 0.0);
-
-       // Format for output
-       $sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml');
-
-       // Preferred language
-       $aLangPrefOrder = $oParams->getPreferredLanguages();
-
-       $oDB =& getDB();
-
-       $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
-
-
-       $oPlaceLookup = new PlaceLookup($oDB);
-       $oPlaceLookup->setLanguagePreference($aLangPrefOrder);
-       $oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
-       $oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
-       $oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
-
-       $sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R'));
-       $iOsmId = $oParams->getInt('osm_id', -1);
-       $fLat = $oParams->getFloat('lat');
-       $fLon = $oParams->getFloat('lon');
-       if ($sOsmType && $iOsmId > 0)
-       {
-               $aPlace = $oPlaceLookup->lookupOSMID($sOsmType, $iOsmId);
-       }
-       else if ($fLat !== false && $fLon !== false)
-       {
-               $oReverseGeocode = new ReverseGeocode($oDB);
-               $oReverseGeocode->setZoom($oParams->getInt('zoom', 18));
-
-               $aLookup = $oReverseGeocode->lookup($fLat, $fLon);
-               if (CONST_Debug) var_dump($aLookup);
-
-               $aPlace = $oPlaceLookup->lookup((int)$aLookup['place_id'],
-                                               $aLookup['type'], $aLookup['fraction']);
-       }
-       else if ($sOutputFormat != 'html')
-       {
-               userError("Need coordinates or OSM object to lookup.");
-       }
-
-       if ($aPlace)
-       {
-               $oPlaceLookup->setIncludePolygonAsPoints(false);
-               $oPlaceLookup->setIncludePolygonAsText($bAsText);
-               $oPlaceLookup->setIncludePolygonAsGeoJSON($bAsGeoJSON);
-               $oPlaceLookup->setIncludePolygonAsKML($bAsKML);
-               $oPlaceLookup->setIncludePolygonAsSVG($bAsSVG);
-               $oPlaceLookup->setPolygonSimplificationThreshold($fThreshold);
-
-               $fRadius = $fDiameter = getResultDiameter($aPlace);
-               $aOutlineResult = $oPlaceLookup->getOutlines($aPlace['place_id'],
-                                                            $aPlace['lon'], $aPlace['lat'],
-                                                            $fRadius);
-
-               if ($aOutlineResult)
-               {
-                       $aPlace = array_merge($aPlace, $aOutlineResult);
-               }
-       }
-
-
-       if (CONST_Debug)
-       {
-               var_dump($aPlace);
-               exit;
-       }
-
-       if ($sOutputFormat=='html')
-       {
-               $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
-               $sTileURL = CONST_Map_Tile_URL;
-               $sTileAttribution = CONST_Map_Tile_Attribution;
-       }
-       include(CONST_BasePath.'/lib/template/address-'.$sOutputFormat.'.php');
+@define('CONST_ConnectionBucket_PageType', 'Reverse');
+
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
+require_once(CONST_BasePath.'/lib/output.php');
+ini_set('memory_limit', '200M');
+
+$oParams = new ParameterParser();
+
+$bAsGeoJSON = $oParams->getBool('polygon_geojson');
+$bAsKML = $oParams->getBool('polygon_kml');
+$bAsSVG = $oParams->getBool('polygon_svg');
+$bAsText = $oParams->getBool('polygon_text');
+if ((($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0)
+    + ($bAsText?1:0)) > CONST_PolygonOutput_MaximumTypes)
+{
+    if (CONST_PolygonOutput_MaximumTypes)
+    {
+        userError("Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option");
+    }
+    else
+    {
+        userError("Polygon output is disabled");
+    }
+}
+
+// Polygon simplification threshold (optional)
+$fThreshold = $oParams->getFloat('polygon_threshold', 0.0);
+
+// Format for output
+$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml');
+
+// Preferred language
+$aLangPrefOrder = $oParams->getPreferredLanguages();
+
+$oDB =& getDB();
+
+$hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
+
+
+$oPlaceLookup = new PlaceLookup($oDB);
+$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
+$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
+$oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false));
+$oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false));
+
+$sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R'));
+$iOsmId = $oParams->getInt('osm_id', -1);
+$fLat = $oParams->getFloat('lat');
+$fLon = $oParams->getFloat('lon');
+if ($sOsmType && $iOsmId > 0)
+{
+    $aPlace = $oPlaceLookup->lookupOSMID($sOsmType, $iOsmId);
+}
+else if ($fLat !== false && $fLon !== false)
+{
+    $oReverseGeocode = new ReverseGeocode($oDB);
+    $oReverseGeocode->setZoom($oParams->getInt('zoom', 18));
+
+    $aLookup = $oReverseGeocode->lookup($fLat, $fLon);
+    if (CONST_Debug) var_dump($aLookup);
+
+    $aPlace = $oPlaceLookup->lookup((int)$aLookup['place_id'],
+                                    $aLookup['type'], $aLookup['fraction']);
+}
+else if ($sOutputFormat != 'html')
+{
+    userError("Need coordinates or OSM object to lookup.");
+}
+
+if ($aPlace)
+{
+    $oPlaceLookup->setIncludePolygonAsPoints(false);
+    $oPlaceLookup->setIncludePolygonAsText($bAsText);
+    $oPlaceLookup->setIncludePolygonAsGeoJSON($bAsGeoJSON);
+    $oPlaceLookup->setIncludePolygonAsKML($bAsKML);
+    $oPlaceLookup->setIncludePolygonAsSVG($bAsSVG);
+    $oPlaceLookup->setPolygonSimplificationThreshold($fThreshold);
+
+    $fRadius = $fDiameter = getResultDiameter($aPlace);
+    $aOutlineResult = $oPlaceLookup->getOutlines($aPlace['place_id'],
+                                                 $aPlace['lon'], $aPlace['lat'],
+                                                 $fRadius);
+
+    if ($aOutlineResult)
+    {
+        $aPlace = array_merge($aPlace, $aOutlineResult);
+    }
+}
+
+
+if (CONST_Debug)
+{
+    var_dump($aPlace);
+    exit;
+}
+
+if ($sOutputFormat=='html')
+{
+    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
+    $sTileURL = CONST_Map_Tile_URL;
+    $sTileAttribution = CONST_Map_Tile_Attribution;
+}
+include(CONST_BasePath.'/lib/template/address-'.$sOutputFormat.'.php');
index cff9bb373d1e963724b8f07d0107d7f7e84e80f2..bcec4f18952bfd4e7c02d81d2b8813582dd86899 100755 (executable)
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Search');
-
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
-       require_once(CONST_BasePath.'/lib/log.php');
-       require_once(CONST_BasePath.'/lib/Geocode.php');
-       require_once(CONST_BasePath.'/lib/output.php');
-       ini_set('memory_limit', '200M');
-
-       $oDB =& getDB();
-       $oParams = new ParameterParser();
-
-       $oGeocode = new Geocode($oDB);
-
-       $aLangPrefOrder = $oParams->getPreferredLanguages();
-       $oGeocode->setLanguagePreference($aLangPrefOrder);
-
-       if (CONST_Search_ReversePlanForAll
-               || isset($aLangPrefOrder['name:de'])
-               || isset($aLangPrefOrder['name:ru'])
-               || isset($aLangPrefOrder['name:ja'])
-               || isset($aLangPrefOrder['name:pl']))
-       {
-               $oGeocode->setReverseInPlan(true);
-       }
-
-       // Format for output
-       $sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html');
-
-       // Show / use polygons
-       if ($sOutputFormat == 'html')
-       {
-               $oGeocode->setIncludePolygonAsText($oParams->getBool('polygon'));
-               $bAsText = false;
-       }
-       else
-       {
-               $bAsPoints = $oParams->getBool('polygon');
-               $bAsGeoJSON = $oParams->getBool('polygon_geojson');
-               $bAsKML = $oParams->getBool('polygon_kml');
-               $bAsSVG = $oParams->getBool('polygon_svg');
-               $bAsText = $oParams->getBool('polygon_text');
-               if ( ( ($bAsGeoJSON?1:0)
-                                + ($bAsKML?1:0)
-                                + ($bAsSVG?1:0)
-                                + ($bAsText?1:0)
-                                + ($bAsPoints?1:0)
-                                ) > CONST_PolygonOutput_MaximumTypes)
-               {
-                       if (CONST_PolygonOutput_MaximumTypes)
-                       {
-                               userError("Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option");
-                       }
-                       else
-                       {
-                               userError("Polygon output is disabled");
-                       }
-                       exit;
-               }
-               $oGeocode->setIncludePolygonAsPoints($bAsPoints);
-               $oGeocode->setIncludePolygonAsText($bAsText);
-               $oGeocode->setIncludePolygonAsGeoJSON($bAsGeoJSON);
-               $oGeocode->setIncludePolygonAsKML($bAsKML);
-               $oGeocode->setIncludePolygonAsSVG($bAsSVG);
-       }
-
-       // Polygon simplification threshold (optional)
-       $oGeocode->setPolygonSimplificationThreshold($oParams->getFloat('polygon_threshold', 0.0));
-
-       $oGeocode->loadParamArray($oParams);
-
-       if (CONST_Search_BatchMode && isset($_GET['batch']))
-       {
-               $aBatch = json_decode($_GET['batch'], true);
-               $aBatchResults = array();
-               foreach($aBatch as $aBatchParams)
-               {
-                       $oBatchGeocode = clone $oGeocode;
-                       $oBatchParams = new ParameterParser($aBatchParams);
-                       $oBatchGeocode->loadParamArray($oBatchParams);
-                       $oBatchGeocode->setQueryFromParams($oBatchParams);
-                       $aSearchResults = $oBatchGeocode->lookup();
-                       $aBatchResults[] = $aSearchResults;
-               }
-               include(CONST_BasePath.'/lib/template/search-batch-json.php');
-               exit;
-       }
-
-       $oGeocode->setQueryFromParams($oParams);
-
-       if (!$oGeocode->getQueryString()
-           && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/')
-       {
-               $sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1);
-
-               // reverse order of '/' separated string
-               $aPhrases = explode('/', $sQuery);
-               $aPhrases = array_reverse($aPhrases);
-               $sQuery = join(', ',$aPhrases);
-               $oGeocode->setQuery($sQuery);
-       }
-
-       $hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder);
-
-       $aSearchResults = $oGeocode->lookup();
-       if ($aSearchResults === false) $aSearchResults = array();
-
-       if ($sOutputFormat=='html')
-       {
-               $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
-       }
-       logEnd($oDB, $hLog, sizeof($aSearchResults));
-
-       $sQuery = $oGeocode->getQueryString();
-       $sViewBox = $oGeocode->getViewBoxString();
-       $bShowPolygons = (isset($_GET['polygon']) && $_GET['polygon']);
-       $aExcludePlaceIDs = $oGeocode->getExcludedPlaceIDs();
-
-       $sMoreURL = CONST_Website_BaseURL.'search.php?format='.urlencode($sOutputFormat).'&exclude_place_ids='.join(',',$aExcludePlaceIDs);
-       if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) $sMoreURL .= '&accept-language='.$_SERVER["HTTP_ACCEPT_LANGUAGE"];
-       if ($bShowPolygons) $sMoreURL .= '&polygon=1';
-       if ($oGeocode->getIncludeAddressDetails()) $sMoreURL .= '&addressdetails=1';
-       if ($oGeocode->getIncludeExtraTags()) $sMoreURL .= '&extratags=1';
-       if ($oGeocode->getIncludeNameDetails()) $sMoreURL .= '&namedetails=1';
-       if ($sViewBox) $sMoreURL .= '&viewbox='.urlencode($sViewBox);
-       if (isset($_GET['nearlat']) && isset($_GET['nearlon'])) $sMoreURL .= '&nearlat='.(float)$_GET['nearlat'].'&nearlon='.(float)$_GET['nearlon'];
-       $sMoreURL .= '&q='.urlencode($sQuery);
-
-       if (CONST_Debug) exit;
-
-       include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php');
+@define('CONST_ConnectionBucket_PageType', 'Search');
+
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(CONST_BasePath.'/lib/log.php');
+require_once(CONST_BasePath.'/lib/Geocode.php');
+require_once(CONST_BasePath.'/lib/output.php');
+ini_set('memory_limit', '200M');
+
+$oDB =& getDB();
+$oParams = new ParameterParser();
+
+$oGeocode = new Geocode($oDB);
+
+$aLangPrefOrder = $oParams->getPreferredLanguages();
+$oGeocode->setLanguagePreference($aLangPrefOrder);
+
+if (CONST_Search_ReversePlanForAll
+    || isset($aLangPrefOrder['name:de'])
+    || isset($aLangPrefOrder['name:ru'])
+    || isset($aLangPrefOrder['name:ja'])
+    || isset($aLangPrefOrder['name:pl']))
+{
+    $oGeocode->setReverseInPlan(true);
+}
+
+// Format for output
+$sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html');
+
+// Show / use polygons
+if ($sOutputFormat == 'html')
+{
+    $oGeocode->setIncludePolygonAsText($oParams->getBool('polygon'));
+    $bAsText = false;
+}
+else
+{
+    $bAsPoints = $oParams->getBool('polygon');
+    $bAsGeoJSON = $oParams->getBool('polygon_geojson');
+    $bAsKML = $oParams->getBool('polygon_kml');
+    $bAsSVG = $oParams->getBool('polygon_svg');
+    $bAsText = $oParams->getBool('polygon_text');
+    if ( ( ($bAsGeoJSON?1:0)
+             + ($bAsKML?1:0)
+             + ($bAsSVG?1:0)
+             + ($bAsText?1:0)
+             + ($bAsPoints?1:0)
+             ) > CONST_PolygonOutput_MaximumTypes)
+    {
+        if (CONST_PolygonOutput_MaximumTypes)
+        {
+            userError("Select only ".CONST_PolygonOutput_MaximumTypes." polgyon output option");
+        }
+        else
+        {
+            userError("Polygon output is disabled");
+        }
+        exit;
+    }
+    $oGeocode->setIncludePolygonAsPoints($bAsPoints);
+    $oGeocode->setIncludePolygonAsText($bAsText);
+    $oGeocode->setIncludePolygonAsGeoJSON($bAsGeoJSON);
+    $oGeocode->setIncludePolygonAsKML($bAsKML);
+    $oGeocode->setIncludePolygonAsSVG($bAsSVG);
+}
+
+// Polygon simplification threshold (optional)
+$oGeocode->setPolygonSimplificationThreshold($oParams->getFloat('polygon_threshold', 0.0));
+
+$oGeocode->loadParamArray($oParams);
+
+if (CONST_Search_BatchMode && isset($_GET['batch']))
+{
+    $aBatch = json_decode($_GET['batch'], true);
+    $aBatchResults = array();
+    foreach($aBatch as $aBatchParams)
+    {
+        $oBatchGeocode = clone $oGeocode;
+        $oBatchParams = new ParameterParser($aBatchParams);
+        $oBatchGeocode->loadParamArray($oBatchParams);
+        $oBatchGeocode->setQueryFromParams($oBatchParams);
+        $aSearchResults = $oBatchGeocode->lookup();
+        $aBatchResults[] = $aSearchResults;
+    }
+    include(CONST_BasePath.'/lib/template/search-batch-json.php');
+    exit;
+}
+
+$oGeocode->setQueryFromParams($oParams);
+
+if (!$oGeocode->getQueryString()
+    && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/')
+{
+    $sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1);
+
+    // reverse order of '/' separated string
+    $aPhrases = explode('/', $sQuery);
+    $aPhrases = array_reverse($aPhrases);
+    $sQuery = join(', ',$aPhrases);
+    $oGeocode->setQuery($sQuery);
+}
+
+$hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder);
+
+$aSearchResults = $oGeocode->lookup();
+if ($aSearchResults === false) $aSearchResults = array();
+
+if ($sOutputFormat=='html')
+{
+    $sDataDate = chksql($oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1"));
+}
+logEnd($oDB, $hLog, sizeof($aSearchResults));
+
+$sQuery = $oGeocode->getQueryString();
+$sViewBox = $oGeocode->getViewBoxString();
+$bShowPolygons = (isset($_GET['polygon']) && $_GET['polygon']);
+$aExcludePlaceIDs = $oGeocode->getExcludedPlaceIDs();
+
+$sMoreURL = CONST_Website_BaseURL.'search.php?format='.urlencode($sOutputFormat).'&exclude_place_ids='.join(',',$aExcludePlaceIDs);
+if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) $sMoreURL .= '&accept-language='.$_SERVER["HTTP_ACCEPT_LANGUAGE"];
+if ($bShowPolygons) $sMoreURL .= '&polygon=1';
+if ($oGeocode->getIncludeAddressDetails()) $sMoreURL .= '&addressdetails=1';
+if ($oGeocode->getIncludeExtraTags()) $sMoreURL .= '&extratags=1';
+if ($oGeocode->getIncludeNameDetails()) $sMoreURL .= '&namedetails=1';
+if ($sViewBox) $sMoreURL .= '&viewbox='.urlencode($sViewBox);
+if (isset($_GET['nearlat']) && isset($_GET['nearlon'])) $sMoreURL .= '&nearlat='.(float)$_GET['nearlat'].'&nearlon='.(float)$_GET['nearlon'];
+$sMoreURL .= '&q='.urlencode($sQuery);
+
+if (CONST_Debug) exit;
+
+include(CONST_BasePath.'/lib/template/search-'.$sOutputFormat.'.php');
index f4e696a4014263cd201c3c4292a977bc8d287f1a..b40f135227c8d9b277f85d065be1a3d7f09e3608 100644 (file)
@@ -1,42 +1,42 @@
 <?php
-       @define('CONST_ConnectionBucket_PageType', 'Status');
+@define('CONST_ConnectionBucket_PageType', 'Status');
 
-       require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
-       require_once(CONST_BasePath.'/lib/init-website.php');
+require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
+require_once(CONST_BasePath.'/lib/init-website.php');
 
-       function statusError($sMsg)
-       {
-               header("HTTP/1.0 500 Internal Server Error");
-               echo "ERROR: ".$sMsg;
-               exit;
-       }
+function statusError($sMsg)
+{
+    header("HTTP/1.0 500 Internal Server Error");
+    echo "ERROR: ".$sMsg;
+    exit;
+}
 
-       $oDB =& DB::connect(CONST_Database_DSN, false);
-       if (!$oDB || PEAR::isError($oDB))
-       {
-               statusError("No database");
-       }
+$oDB =& DB::connect(CONST_Database_DSN, false);
+if (!$oDB || PEAR::isError($oDB))
+{
+    statusError("No database");
+}
 
-       $sStandardWord = $oDB->getOne("select make_standard_name('a')");
-       if (PEAR::isError($sStandardWord))
-       {
-               statusError("Module failed");
-       }
-       if ($sStandardWord != 'a')
-       {
-               statusError("Module call failed");
-       }
+$sStandardWord = $oDB->getOne("select make_standard_name('a')");
+if (PEAR::isError($sStandardWord))
+{
+    statusError("Module failed");
+}
+if ($sStandardWord != 'a')
+{
+    statusError("Module call failed");
+}
 
-       $iWordID = $oDB->getOne("select word_id,word_token, word, class, type, country_code, operator, search_name_count from word where word_token in (' a')");
-       if (PEAR::isError($iWordID))
-       {
-               statusError("Query failed");
-       }
-       if (!$iWordID)
-       {
-               statusError("No value");
-       }
+$iWordID = $oDB->getOne("select word_id,word_token, word, class, type, country_code, operator, search_name_count from word where word_token in (' a')");
+if (PEAR::isError($iWordID))
+{
+    statusError("Query failed");
+}
+if (!$iWordID)
+{
+    statusError("No value");
+}
 
-       echo "OK";
-       exit;
+echo "OK";
+exit;
 
index e1b0687fbbd475beea4e42dbf0aa8310c3a12b9a..8a59c3d8e57890568ed74bc6def99025c25211ca 100755 (executable)
@@ -17,172 +17,172 @@ $iNS = false;
 $iID = false;
 
 if ($hFile) {
-       while (($sLine = fgets($hFile, 4000000)) !== false) {
-               if (substr($sLine, 0, 11) == '    <title>') {
-                       $sTitle = substr($sLine, 11, -9);
-               }
-               else if (substr($sLine, 0, 8) == '    <ns>') {
-                       $iNS = (int)substr($sLine, 8, -6);
-               }
-               else if (substr($sLine, 0, 8) == '    <id>') {
-                       $iID = (int)substr($sLine, 8, -6);
-               }
-               else if (substr($sLine, 0, 33) == '      <text xml:space="preserve">') {
-                       if ($iNS == -2) continue;
-                       if ($iNS == -1) continue;
-                       if ($iNS == 1) continue;
-                       if ($iNS == 2) continue;
-                       if ($iNS == 3) continue;
-                       if ($iNS == 4) continue;
-                       if ($iNS == 5) continue;
-                       if ($iNS == 6) continue;
-                       if ($iNS == 7) continue;
-                       if ($iNS == 8) continue;
-                       if ($iNS == 9) continue;
-                       if ($iNS == 10) continue;
-                       if ($iNS == 11) continue;
-                       if ($iNS == 12) continue;
-                       if ($iNS == 13) continue;
-                       if ($iNS == 14) continue;
-                       if ($iNS == 15) continue;
-                       if ($iNS == 121) continue;
-                       if ($iNS == 123) continue;
-                       if ($iNS == 829) continue;
-                       if ($iNS == 1198) continue;
-                       if ($iNS == 1199) continue;
-                       $sText = html_entity_decode(substr($sLine, 33, -8), ENT_COMPAT, 'UTF-8');
-                       $aArticle = json_decode($sText, true);
-
-                       if (array_diff(array_keys($aArticle), array("label", "description", "aliases", "links", "entity", "claims", "datatype")) != array()) {
-                               // DEBUG
-                               var_dump($sTitle);
-                               var_dump(array_keys($aArticle));
-                               var_dump($aArticle);
-                               exit;
-                       }
-
-                       $iPID = $iQID = null;
-                       if ($aArticle['entity'][0] == 'p') {
-                               $iPID = (int)substr($aArticle['entity'], 1);
-                       } else if ($aArticle['entity'][0] == 'q') {
-                               $iQID = (int)substr($aArticle['entity'], 1);
-                       } else {
-                               continue;
-                       }
-
-                       echo ".";
-
-                       fputcsv($hFileEntity, array($iID,$sTitle,$iPID,$iQID,@$aArticle['datatype']));
-
-                       foreach($aArticle['label'] as $sLang => $sLabel) {
-                               fputcsv($hFileEntityLabel, array($iID,$sLang,$sLabel));
-                               // echo "insert into entity_label values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
-                       }
-
-                       foreach($aArticle['description'] as $sLang => $sLabel) {
-                               fputcsv($hFileEntityDescription, array($iID,$sLang,$sLabel));
-                               // echo "insert into entity_description values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
-                       }
-
-                       foreach($aArticle['aliases'] as $sLang => $aLabels) {
-                               $aUniqueAlias = array();
-                               foreach($aLabels as $sLabel) {
-                                       if (!isset($aUniqueAlias[$sLabel]) && $sLabel) {
-                                       fputcsv($hFileEntityAlias, array($iID,$sLang,$sLabel));
-                                       // echo "insert into entity_alias values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
-                                       $aUniqueAlias[$sLabel] = true;
-                               }
-                       }
-               }
-
-               foreach($aArticle['links'] as $sLang => $sLabel) {
-                       fputcsv($hFileEntityLink, array($iID,$sLang,$sLabel));
-                       // echo "insert into entity_link values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
-               }
-
-
-               if (isset($aArticle['claims'])) {
-
-                       foreach($aArticle['claims'] as $iClaim => $aClaim) {
-
-                               $bFail = false;
-                       if ($aClaim['m'][0] == 'novalue') continue;
-                       if ($aClaim['m'][0] == 'somevalue') continue;
-                       $iPID = (int)$aClaim['m'][1];
-                       if ($aClaim['m'][0] != 'value') $bFail = true;
-                       if ($aClaim['m'][2]== 'wikibase-entityid') {
-
-                               if ($aClaim['m'][3]['entity-type'] != 'item') $bFail = true;
-                               fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,$aClaim['m'][3]['numeric-id'],null,null));
-                               // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",null,".$aClaim['m'][3]['numeric-id'].",null);\n";
-
-                       } elseif ($aClaim['m'][2] == 'globecoordinate') {
-
-                               if ($aClaim['m'][3]['globe'] != 'http://www.wikidata.org/entity/Q2') $bFail = true;
-                               fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,null,"SRID=4326;POINT(".((float)$aClaim['m'][3]['longitude'])." ".((float)$aClaim['m'][3]['latitude']).")",null));
-                               // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",null,null,ST_SetSRID(ST_MakePoint(".((float)$aClaim['m'][3]['longitude']).", ".((float)$aClaim['m'][3]['latitude'])."),4326));\n";
-
-                       } elseif ($aClaim['m'][2] == 'time') {
-                               // TODO!
+    while (($sLine = fgets($hFile, 4000000)) !== false) {
+        if (substr($sLine, 0, 11) == '    <title>') {
+            $sTitle = substr($sLine, 11, -9);
+        }
+        else if (substr($sLine, 0, 8) == '    <ns>') {
+            $iNS = (int)substr($sLine, 8, -6);
+        }
+        else if (substr($sLine, 0, 8) == '    <id>') {
+            $iID = (int)substr($sLine, 8, -6);
+        }
+        else if (substr($sLine, 0, 33) == '      <text xml:space="preserve">') {
+            if ($iNS == -2) continue;
+            if ($iNS == -1) continue;
+            if ($iNS == 1) continue;
+            if ($iNS == 2) continue;
+            if ($iNS == 3) continue;
+            if ($iNS == 4) continue;
+            if ($iNS == 5) continue;
+            if ($iNS == 6) continue;
+            if ($iNS == 7) continue;
+            if ($iNS == 8) continue;
+            if ($iNS == 9) continue;
+            if ($iNS == 10) continue;
+            if ($iNS == 11) continue;
+            if ($iNS == 12) continue;
+            if ($iNS == 13) continue;
+            if ($iNS == 14) continue;
+            if ($iNS == 15) continue;
+            if ($iNS == 121) continue;
+            if ($iNS == 123) continue;
+            if ($iNS == 829) continue;
+            if ($iNS == 1198) continue;
+            if ($iNS == 1199) continue;
+            $sText = html_entity_decode(substr($sLine, 33, -8), ENT_COMPAT, 'UTF-8');
+            $aArticle = json_decode($sText, true);
+
+            if (array_diff(array_keys($aArticle), array("label", "description", "aliases", "links", "entity", "claims", "datatype")) != array()) {
+                // DEBUG
+                var_dump($sTitle);
+                var_dump(array_keys($aArticle));
+                var_dump($aArticle);
+                exit;
+            }
+
+            $iPID = $iQID = null;
+            if ($aArticle['entity'][0] == 'p') {
+                $iPID = (int)substr($aArticle['entity'], 1);
+            } else if ($aArticle['entity'][0] == 'q') {
+                $iQID = (int)substr($aArticle['entity'], 1);
+            } else {
+                continue;
+            }
+
+            echo ".";
+
+            fputcsv($hFileEntity, array($iID,$sTitle,$iPID,$iQID,@$aArticle['datatype']));
+
+            foreach($aArticle['label'] as $sLang => $sLabel) {
+                fputcsv($hFileEntityLabel, array($iID,$sLang,$sLabel));
+                // echo "insert into entity_label values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
+            }
+
+            foreach($aArticle['description'] as $sLang => $sLabel) {
+                fputcsv($hFileEntityDescription, array($iID,$sLang,$sLabel));
+                // echo "insert into entity_description values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
+            }
+
+            foreach($aArticle['aliases'] as $sLang => $aLabels) {
+                $aUniqueAlias = array();
+                foreach($aLabels as $sLabel) {
+                    if (!isset($aUniqueAlias[$sLabel]) && $sLabel) {
+                    fputcsv($hFileEntityAlias, array($iID,$sLang,$sLabel));
+                    // echo "insert into entity_alias values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
+                    $aUniqueAlias[$sLabel] = true;
+                }
+            }
+        }
+
+        foreach($aArticle['links'] as $sLang => $sLabel) {
+            fputcsv($hFileEntityLink, array($iID,$sLang,$sLabel));
+            // echo "insert into entity_link values (".$iID.",'".pg_escape_string($sLang)."','".pg_escape_string($sLabel)."');\n";
+        }
+
+
+        if (isset($aArticle['claims'])) {
+
+            foreach($aArticle['claims'] as $iClaim => $aClaim) {
+
+                $bFail = false;
+            if ($aClaim['m'][0] == 'novalue') continue;
+            if ($aClaim['m'][0] == 'somevalue') continue;
+            $iPID = (int)$aClaim['m'][1];
+            if ($aClaim['m'][0] != 'value') $bFail = true;
+            if ($aClaim['m'][2]== 'wikibase-entityid') {
+
+                if ($aClaim['m'][3]['entity-type'] != 'item') $bFail = true;
+                fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,$aClaim['m'][3]['numeric-id'],null,null));
+                // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",null,".$aClaim['m'][3]['numeric-id'].",null);\n";
+
+            } elseif ($aClaim['m'][2] == 'globecoordinate') {
+
+                if ($aClaim['m'][3]['globe'] != 'http://www.wikidata.org/entity/Q2') $bFail = true;
+                fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,null,"SRID=4326;POINT(".((float)$aClaim['m'][3]['longitude'])." ".((float)$aClaim['m'][3]['latitude']).")",null));
+                // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",null,null,ST_SetSRID(ST_MakePoint(".((float)$aClaim['m'][3]['longitude']).", ".((float)$aClaim['m'][3]['latitude'])."),4326));\n";
+
+            } elseif ($aClaim['m'][2] == 'time') {
+                // TODO!
 /*
-               if ($aClaim['m'][3]['calendarmodel'] == 'http://www.wikidata.org/entity/Q1985727') {
-                       // Gregorian
-                       if (preg_match('#(\\+|-)0*([0-9]{4})-([0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2})Z#', $aClaim['m'][3]['time'], $aMatch)) {
-                               if ((int)$aMatch[2] < 4700 && ) {
-                                       $sDateString = $aMatch[2].'-'.$aMatch[3].($aClaim['m'][3]['timezone']>=0?'+':'').$aClaim['m'][3]['timezone'].($aMatch[1]=='-'?' bc':'');
-                                       fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,null,null,$sDateString));
-                               }
-                       } else {
-//                             $bFail = true;
-                       }
-               } elseif ( $aClaim['m'][3]['calendarmodel'] != 'http://www.wikidata.org/entity/Q1985786') {
+        if ($aClaim['m'][3]['calendarmodel'] == 'http://www.wikidata.org/entity/Q1985727') {
+            // Gregorian
+            if (preg_match('#(\\+|-)0*([0-9]{4})-([0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2})Z#', $aClaim['m'][3]['time'], $aMatch)) {
+                if ((int)$aMatch[2] < 4700 && ) {
+                    $sDateString = $aMatch[2].'-'.$aMatch[3].($aClaim['m'][3]['timezone']>=0?'+':'').$aClaim['m'][3]['timezone'].($aMatch[1]=='-'?' bc':'');
+                    fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,null,null,null,$sDateString));
+                }
+            } else {
+//              $bFail = true;
+            }
+        } elseif ( $aClaim['m'][3]['calendarmodel'] != 'http://www.wikidata.org/entity/Q1985786') {
 / *
-                       // Julian
-                       if (preg_match('#(\\+|-)0*([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})Z#', $aClaim['m'][3]['time'], $aMatch)) {
+            // Julian
+            if (preg_match('#(\\+|-)0*([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}:[0-9]{2}:[0-9]{2})Z#', $aClaim['m'][3]['time'], $aMatch)) {
 var_dump($aMatch);
 exit;
 $iDayCount = juliantojd(2, 11, 1732);
 var_dump($iDayCount, jdtogregorian($iDayCount));
-                       } else {
-                               $bFail = true;
+            } else {
+                $bFail = true;
 exit;
-                       }
+            }
 exit;
 * /
-               } else {
-//                     $bFail = true;
-               }
+        } else {
+//          $bFail = true;
+        }
 */
-                       } elseif ($aClaim['m'][2] == 'string') {
+            } elseif ($aClaim['m'][2] == 'string') {
 
-                               // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",'".pg_escape_string($aClaim['m'][3])."',null,null);\n";
-                               fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,$aClaim['m'][3],null,null,null));
+                // echo "insert into entity_property values (nextval('seq_entity_property'),".$iID.",".$iPID.",'".pg_escape_string($aClaim['m'][3])."',null,null);\n";
+                fputcsv($hFileEntityProperty, array($iID,$iClaim,$iPID,$aClaim['m'][3],null,null,null));
 
-                       } else {
+            } else {
 
-                               $bFail = true;
+                $bFail = true;
 
-                       }
+            }
 
-                       // Don't care about sources:    if ($aClaim['refs'] != array()) $bFail = true;
+            // Don't care about sources:    if ($aClaim['refs'] != array()) $bFail = true;
 
-                       if ($bFail) {
-                               var_dump($sTitle);
-                               var_dump($aClaim);
-                       } else {
-                               // process
-                       }
+            if ($bFail) {
+                var_dump($sTitle);
+                var_dump($aClaim);
+            } else {
+                // process
+            }
 
-               }
+        }
 
-                       }
-               }
-       }
-       fclose($hFile);
-       fclose($hFileEntity);
-       fclose($hFileEntityLabel);
-       fclose($hFileEntityDescription);
-       fclose($hFileEntityAlias);
-       fclose($hFileEntityLink);
-       fclose($hFileEntityProperty);
+            }
+        }
+    }
+    fclose($hFile);
+    fclose($hFileEntity);
+    fclose($hFileEntityLabel);
+    fclose($hFileEntityDescription);
+    fclose($hFileEntityAlias);
+    fclose($hFileEntityLink);
+    fclose($hFileEntityProperty);
 }
index 8dfabbb1c1a0fc588c0e78379444a1119fb96f87..3c5f5dfe168213c5698a5fdc79edaa0e1769d910 100644 (file)
@@ -1,91 +1,91 @@
 <?php
 
-       for($iTimestamp = mktime(0, 0, 0, 5, 1, 2013); $iTimestamp < mktime(0, 0, 0, 6, 15, 2013); $iTimestamp += 24*60*60)
-       {
-               $sYear = date("Y", $iTimestamp);
-               $sMonth = date("Y-m", $iTimestamp);
-               $sDay = date("Ymd", $iTimestamp);
+for($iTimestamp = mktime(0, 0, 0, 5, 1, 2013); $iTimestamp < mktime(0, 0, 0, 6, 15, 2013); $iTimestamp += 24*60*60)
+{
+    $sYear = date("Y", $iTimestamp);
+    $sMonth = date("Y-m", $iTimestamp);
+    $sDay = date("Ymd", $iTimestamp);
 
-               for($iHour = 0; $iHour < 24; $iHour++)
-               {
-                       $sFilename = sprintf("pagecounts-".$sDay."-%02d0000", $iHour);
-                       echo $sFilename."\n";
-                       if (!file_exists($sFilename.'.gz'))
-                       {
-                               exec('wget http://dumps.wikimedia.org/other/pagecounts-raw/'.$sYear.'/'.$sMonth.'/'.$sFilename.'.gz');
-                       }
+    for($iHour = 0; $iHour < 24; $iHour++)
+    {
+        $sFilename = sprintf("pagecounts-".$sDay."-%02d0000", $iHour);
+        echo $sFilename."\n";
+        if (!file_exists($sFilename.'.gz'))
+        {
+            exec('wget http://dumps.wikimedia.org/other/pagecounts-raw/'.$sYear.'/'.$sMonth.'/'.$sFilename.'.gz');
+        }
 
-                       exec('gzip -dc '.$sFilename.'.gz'.' | grep -e "^[a-z]\{2\} [^ :]\+ [0-9]\+" > hour.txt');
+        exec('gzip -dc '.$sFilename.'.gz'.' | grep -e "^[a-z]\{2\} [^ :]\+ [0-9]\+" > hour.txt');
 
-                       $hPrevTotals = @fopen("totals.txt", "r");
-                       $hDayTotals = @fopen("hour.txt", "r");
-                       $hNewTotals = @fopen("newtotals.txt", "w");
+        $hPrevTotals = @fopen("totals.txt", "r");
+        $hDayTotals = @fopen("hour.txt", "r");
+        $hNewTotals = @fopen("newtotals.txt", "w");
 
-                       $sPrevKey = $sDayKey = true;
-                       $sPrevLine = true;
-                       $sDayLine = true;
+        $sPrevKey = $sDayKey = true;
+        $sPrevLine = true;
+        $sDayLine = true;
 
-                       do
-                       {
-                               if ($sPrevKey === $sDayKey)
-                               {
-                                       if ($sPrevLine !== true) fputs($hNewTotals, "$sPrevKey ".($iPrevValue+$iDayValue)."\n");
-                                       $sPrevLine = true;
-                                       $sDayLine = true;
-                               }
-                               else if ($sDayKey !== false && ($sPrevKey > $sDayKey || $sPrevKey === false))
-                               {
-                                       fputs($hNewTotals, "$sDayKey ".($iDayValue)."\n");
-                                       $sDayLine = true;
-                               }
-                               else if ($sPrevKey !== false && ($sDayKey > $sPrevKey || $sDayKey === false))
-                               {
-                                       fputs($hNewTotals, "$sPrevKey ".($iPrevValue)."\n");
-                                       $sPrevLine = true;
-                               }
+        do
+        {
+            if ($sPrevKey === $sDayKey)
+            {
+                if ($sPrevLine !== true) fputs($hNewTotals, "$sPrevKey ".($iPrevValue+$iDayValue)."\n");
+                $sPrevLine = true;
+                $sDayLine = true;
+            }
+            else if ($sDayKey !== false && ($sPrevKey > $sDayKey || $sPrevKey === false))
+            {
+                fputs($hNewTotals, "$sDayKey ".($iDayValue)."\n");
+                $sDayLine = true;
+            }
+            else if ($sPrevKey !== false && ($sDayKey > $sPrevKey || $sDayKey === false))
+            {
+                fputs($hNewTotals, "$sPrevKey ".($iPrevValue)."\n");
+                $sPrevLine = true;
+            }
 
-                               if ($sPrevLine === true)
-                               {
-                                       $sPrevLine = $hPrevTotals?fgets($hPrevTotals, 4096):false;
-                                       if ($sPrevLine !== false)
-                                       {
-                                               $aPrevLine = explode(' ', $sPrevLine);
-                                               $sPrevKey = $aPrevLine[0].' '.$aPrevLine[1];
-                                               $iPrevValue = (int)$aPrevLine[2];
-                                       }
-                                       else
-                                       {
-                                               $sPrevKey = false;
-                                               $iPrevValue =  0;
-                                       }
-                               }
+            if ($sPrevLine === true)
+            {
+                $sPrevLine = $hPrevTotals?fgets($hPrevTotals, 4096):false;
+                if ($sPrevLine !== false)
+                {
+                    $aPrevLine = explode(' ', $sPrevLine);
+                    $sPrevKey = $aPrevLine[0].' '.$aPrevLine[1];
+                    $iPrevValue = (int)$aPrevLine[2];
+                }
+                else
+                {
+                    $sPrevKey = false;
+                    $iPrevValue =  0;
+                }
+            }
 
-                               if ($sDayLine === true)
-                               {
-                                       $sDayLine = $hDayTotals?fgets($hDayTotals, 4096):false;
-                                       if ($sDayLine !== false)
-                                       {
-                                               preg_match('#^([a-z]{2}) ([^ :]+) ([0-9]+) [0-9]+$#', $sDayLine, $aMatch);
-                                               $sDayKey = $aMatch[1].' '.$aMatch[2];
-                                               $iDayValue = (int)$aMatch[3];
-                                       }
-                                       else
-                                       {
-                                               $sDayKey = false;
-                                               $iDayValue = 0;
-                                       }
-                               }
+            if ($sDayLine === true)
+            {
+                $sDayLine = $hDayTotals?fgets($hDayTotals, 4096):false;
+                if ($sDayLine !== false)
+                {
+                    preg_match('#^([a-z]{2}) ([^ :]+) ([0-9]+) [0-9]+$#', $sDayLine, $aMatch);
+                    $sDayKey = $aMatch[1].' '.$aMatch[2];
+                    $iDayValue = (int)$aMatch[3];
+                }
+                else
+                {
+                    $sDayKey = false;
+                    $iDayValue = 0;
+                }
+            }
 
-                       } while ($sPrevLine !== false || $sDayLine !== false);
+        } while ($sPrevLine !== false || $sDayLine !== false);
 
-                       @fclose($hPrevTotals);
-                       @fclose($hDayTotals);
-                       @fclose($hNewTotals);
+        @fclose($hPrevTotals);
+        @fclose($hDayTotals);
+        @fclose($hNewTotals);
 
-                       @unlink("totals.txt");
-                       rename("newtotals.txt", "totals.txt");
-               }
-       }
+        @unlink("totals.txt");
+        rename("newtotals.txt", "totals.txt");
+    }
+}
 
 // Notes:
 /*