]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 9 Mar 2016 22:28:33 +0000 (23:28 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Wed, 9 Mar 2016 22:28:33 +0000 (23:28 +0100)
35 files changed:
ChangeLog
VAGRANT.md
Vagrantfile
lib/Geocode.php
lib/PlaceLookup.php
lib/ReverseGeocode.php
lib/init-website.php
lib/leakybucket.php
lib/lib.php
lib/template/address-html.php
lib/template/address-json.php
lib/template/address-jsonv2.php
lib/template/address-xml.php
lib/template/details-html.php
lib/template/includes/html-footer.php
lib/template/includes/html-top-navigation.php
lib/template/search-batch-json.php
lib/template/search-json.php
lib/template/search-jsonv2.php
lib/template/search-xml.php
settings/phrase_settings.php
tests-php/Nominatim/NominatimTest.php
tests/features/api/reverse.feature
tests/features/api/reverse_simple.feature
tests/features/api/search_params.feature
tests/steps/api_result.py
vagrant/centos-7-provision.sh [new file with mode: 0644]
vagrant/ubuntu-trusty-provision.sh [moved from vagrant-provision.sh with 81% similarity]
website/deletable.php
website/details.php
website/hierarchy.php
website/js/nominatim-ui.js
website/polygons.php
website/reverse.php
website/search.php

index d6002d4389cbce9d74ff4af4de006b4df7ae9667..87275f2ab3627f343d5243fb1cc07339c369b32c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
- * reverse geocoding looking includes looking up Tiger data
+2.5
 
+ * reverse geocoding includes looking up housenumbers from Tiger data
+ * added parameter to return simplified geometries
+ * new lookup call for getting address information for OSM objects
+ * new namedetails and extratags parameters that expose the name and extratags
+   fields of the placex table
+ * mobile website
+ * reverse web view
 
 2.4
 
index 3a8e479bde7283329dfc4c02064d1a4bead35ed8..e6a0fbb371c66f787a45c18c239f4a5ced60d320 100644 (file)
@@ -30,11 +30,11 @@ is.
 
 1. Start the virtual machine
 
-        vagrant up
+        vagrant up ubuntu
 
 2. Log into the virtual machine
 
-        vagrant ssh
+        vagrant ssh ubuntu
 
 3. Import a small country (Monaco)
 
@@ -54,7 +54,7 @@ is.
 
   To repeat an import you'd need to delete the database first
 
-        dropdb --username postgres -if-exists nominatim
+        dropdb -if-exists nominatim
 
 
 
@@ -131,9 +131,11 @@ bug fixes) get added since those usually only get applied to new/changed data.
 Also this document skips the optional Wikipedia data import which affects ranking
 of search results. See [Nominatim installation](http://wiki.openstreetmap.org/wiki/Nominatim/Installation) for details.
 
-##### Why Ubuntu, can I test CentOS/CoreOS/FreeBSD?
+##### Why Ubuntu and CentOS, can I test CentOS/CoreOS/FreeBSD?
 
-In general Nominatim will run in all these environment. The installation steps
+There is a Vagrant script for CentOS available. Simply start your box
+with `vagrant up centos` and then log in with `vagrant ssh centos`.
+In general Nominatim will also run in the other environments. The installation steps
 are slightly different, e.g. the name of the package manager, Apache2 package
 name, location of files. We chose Ubuntu because that is closest to the
 nominatim.openstreetmap.org production environment.
index 843dd668227c6aeec154dc9ba21584577e573a24..30bc93754bda3e92aaf3fa1a147d64ff8855f08b 100644 (file)
@@ -2,30 +2,28 @@
 # vi: set ft=ruby :
 
 Vagrant.configure("2") do |config|
-
-  # Ubuntu LTS 14.04
-  config.vm.box = "ubuntu/trusty64" 
-
   # Apache webserver
   config.vm.network "forwarded_port", guest: 8089, host: 8089
 
-
   # If true, then any SSH connections made will enable agent forwarding.
   config.ssh.forward_agent = true
 
   config.vm.synced_folder ".", "/home/vagrant/Nominatim"
 
-
-
-  # provision using a simple shell script
-  config.vm.provision :shell, :path => "vagrant-provision.sh"
-
+  config.vm.define "ubuntu" do |sub|
+      sub.vm.box = "ubuntu/trusty64"
+      sub.vm.provision :shell, :path => "vagrant/ubuntu-trusty-provision.sh"
+  end
+  config.vm.define "centos" do |sub|
+      sub.vm.box = "bento/centos-7.2"
+      sub.vm.provision :shell, :path => "vagrant/centos-7-provision.sh"
+  end
 
   # configure shared package cache if possible
-  if Vagrant.has_plugin?("vagrant-cachier")
-    config.cache.enable :apt
-    config.cache.scope = :box
-  end
+  #if Vagrant.has_plugin?("vagrant-cachier")
+  #  config.cache.enable :apt
+  #  config.cache.scope = :box
+  #end
 
 
   config.vm.provider "virtualbox" do |vb|
index afeaf68767614dae8165a1533c509bbb59dcd3ff..48055ec6780cbfe708a843e33070fc7ed869c22d 100644 (file)
@@ -1,4 +1,6 @@
 <?php
+       require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+
        class Geocode
        {
                protected $oDB;
                function getGroupedSearches($aSearches, $aPhraseTypes, $aPhrases, $aValidTokens, $aWordFrequencyScores, $bStructuredPhrases)
                {
                        /*
-                          Calculate all searches using aValidTokens i.e.
-                          'Wodsworth Road, Sheffield' =>
+                                Calculate all searches using aValidTokens i.e.
+                                'Wodsworth Road, Sheffield' =>
 
-                          Phrase Wordset
-                          0      0       (wodsworth road)
-                          0      1       (wodsworth)(road)
-                          1      0       (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
+                                Score how good the search is so they can be ordered
                         */
                        foreach($aPhrases as $iPhrase => $sPhrase)
                        {
                /* Perform the actual query lookup.
 
                        Returns an ordered list of results, each with the following fields:
-                         osm_type: type of corresponding OSM object
+                               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
+                               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
+                               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()
                {
                        {
                                // 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'=>'')
+                                       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?
                                                                {
                                                                        $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)";
+                                                                       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 = $this->oDB->getCol($sSQL);
                                if (!preg_match('/\pL/', $sWord)) unset($aRecheckWords[$i]);
                        }
 
-            if (CONST_Debug) { echo '<i>Recheck words:<\i>'; var_dump($aRecheckWords); }
+                       if (CONST_Debug) { echo '<i>Recheck words:<\i>'; var_dump($aRecheckWords); }
 
                        foreach($aSearchResults as $iResNum => $aResult)
                        {
                                // Default
-                               $fDiameter = 0.0001;
-
-                               if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
-                                               && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
-                               {
-                                       $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'];
-                               }
-                               elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
-                                               && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
-                               {
-                                       $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
-                               }
-                               $fRadius = $fDiameter / 2;
-
-                               if (CONST_Search_AreaPolygons)
-                               {
-                                       // Get the bounding box and outline polygon
-                                       $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 = ".$aResult['place_id'];
-                                       if ($this->fPolygonSimplificationThreshold > 0)
-                                       {
-                                               $sSQL .= " from (select place_id,centroid,ST_SimplifyPreserveTopology(geometry,".$this->fPolygonSimplificationThreshold.") as geometry".$sFrom.") as plx";
-                                       }
-                                       else
-                                       {
-                                               $sSQL .= $sFrom;
-                                       }
+                               $fDiameter = getResultDiameter($aResult);
 
-                                       $aPointPolygon = $this->oDB->getRow($sSQL);
-                                       if (PEAR::IsError($aPointPolygon))
-                                       {
-                                               failInternalError("Could not get outline.", $sSQL, $aPointPolygon);
-                                       }
+                               $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);
 
-                                       if ($aPointPolygon['place_id'])
-                                       {
-                                               if ($this->bIncludePolygonAsGeoJSON) $aResult['asgeojson'] = $aPointPolygon['asgeojson'];
-                                               if ($this->bIncludePolygonAsKML) $aResult['askml'] = $aPointPolygon['askml'];
-                                               if ($this->bIncludePolygonAsSVG) $aResult['assvg'] = $aPointPolygon['assvg'];
-                                               if ($this->bIncludePolygonAsText) $aResult['astext'] = $aPointPolygon['astext'];
-
-                                               if ($aPointPolygon['centrelon'] !== null && $aPointPolygon['centrelat'] !== null )
-                                               {
-                                                       $aResult['lat'] = $aPointPolygon['centrelat'];
-                                                       $aResult['lon'] = $aPointPolygon['centrelon'];
-                                               }
-
-                                               if ($this->bIncludePolygonAsPoints)
-                                               {
-                                                       // Translate geometry string to point array
-                                                       if (preg_match('#POLYGON\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch))
-                                                       {
-                                                               preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
-                                                       }
-                            /*
-                                                       elseif (preg_match('#MULTIPOLYGON\\(\\(\\(([- 0-9.,]+)#',$aPointPolygon['astext'],$aMatch))
-                                                       {
-                                                               preg_match_all('/(-?[0-9.]+) (-?[0-9.]+)/',$aMatch[1],$aPolyPoints,PREG_SET_ORDER);
-                                                       }
-                            */
-                                                       elseif (preg_match('#POINT\\((-?[0-9.]+) (-?[0-9.]+)\\)#',$aPointPolygon['astext'],$aMatch))
-                                                       {
-                                                               $iSteps = max(8, min(100, ($fRadius * 40000)^2));
-                                                               $fStepSize = (2*pi())/$iSteps;
-                                                               $aPolyPoints = array();
-                                                               for($f = 0; $f < 2*pi(); $f += $fStepSize)
-                                                               {
-                                                                       $aPolyPoints[] = array('',$aMatch[1]+($fRadius*sin($f)),$aMatch[2]+($fRadius*cos($f)));
-                                                               }
-                                                       }
-                                               }
-
-                                               // Output data suitable for display (points and a bounding box)
-                                               if ($this->bIncludePolygonAsPoints && isset($aPolyPoints))
-                                               {
-                                                       $aResult['aPolyPoints'] = array();
-                                                       foreach($aPolyPoints as $aPoint)
-                                                       {
-                                                               $aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
-                                                       }
-                                               }
-
-                                               if (abs($aPointPolygon['minlat'] - $aPointPolygon['maxlat']) < 0.0000001)
-                                               {
-                                                       $aPointPolygon['minlat'] = $aPointPolygon['minlat'] - $fRadius;
-                                                       $aPointPolygon['maxlat'] = $aPointPolygon['maxlat'] + $fRadius;
-                                               }
-                                               if (abs($aPointPolygon['minlon'] - $aPointPolygon['maxlon']) < 0.0000001)
-                                               {
-                                                       $aPointPolygon['minlon'] = $aPointPolygon['minlon'] - $fRadius;
-                                                       $aPointPolygon['maxlon'] = $aPointPolygon['maxlon'] + $fRadius;
-                                               }
-                                               $aResult['aBoundingBox'] = array((string)$aPointPolygon['minlat'],(string)$aPointPolygon['maxlat'],(string)$aPointPolygon['minlon'],(string)$aPointPolygon['maxlon']);
-                                       }
-                               }
+                               $aOutlineResult = $oPlaceLookup->getOutlines($aResult['place_id'], $aResult['lon'], $aResult['lat'], $fDiameter/2);
+                               $aResult = array_merge($aResult, $aOutlineResult);
 
                                if ($aResult['extra_place'] == 'city')
                                {
                                        $aResult['rank_search'] = 16;
                                }
 
-                               if (!isset($aResult['aBoundingBox']))
-                               {
-                                       $iSteps = max(8,min(100,$fRadius * 3.14 * 100000));
-                                       $fStepSize = (2*pi())/$iSteps;
-                                       $aPointPolygon['minlat'] = $aResult['lat'] - $fRadius;
-                                       $aPointPolygon['maxlat'] = $aResult['lat'] + $fRadius;
-                                       $aPointPolygon['minlon'] = $aResult['lon'] - $fRadius;
-                                       $aPointPolygon['maxlon'] = $aResult['lon'] + $fRadius;
-
-                                       // Output data suitable for display (points and a bounding box)
-                                       if ($this->bIncludePolygonAsPoints)
-                                       {
-                                               $aPolyPoints = array();
-                                               for($f = 0; $f < 2*pi(); $f += $fStepSize)
-                                               {
-                                                       $aPolyPoints[] = array('',$aResult['lon']+($fRadius*sin($f)),$aResult['lat']+($fRadius*cos($f)));
-                                               }
-                                               $aResult['aPolyPoints'] = array();
-                                               foreach($aPolyPoints as $aPoint)
-                                               {
-                                                       $aResult['aPolyPoints'][] = array($aPoint[1], $aPoint[2]);
-                                               }
-                                       }
-                                       $aResult['aBoundingBox'] = array((string)$aPointPolygon['minlat'],(string)$aPointPolygon['maxlat'],(string)$aPointPolygon['minlon'],(string)$aPointPolygon['maxlon']);
-                               }
-
                                // Is there an icon set for this type of result?
                                if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
                                                && $aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
index c5129fee31006d47a011251a82a08237458703a3..04e45d5aba704657c933614900fdef835fd9c403 100644 (file)
 
                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 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 setPlaceID($iPlaceID)
                {
                        $this->iPlaceID = $iPlaceID;
                        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 = $this->oDB->getRow($sSQL);
+                               if (PEAR::IsError($aPointPolygon))
+                               {
+                                       echo var_dump($aPointPolygon);
+                                       failInternalError("Could not get outline.", $sSQL, $aPointPolygon);
+                               }
+
+                               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 e40ce6cceaa23f2904be061914c46a3bdf73b718..d96527643fa67603c525de016d59319d432d9835 100644 (file)
@@ -9,6 +9,14 @@
 
                protected $aLangPrefOrder = array();
 
+               protected $bIncludePolygonAsPoints = false;
+               protected $bIncludePolygonAsText = false;
+               protected $bIncludePolygonAsGeoJSON = false;
+               protected $bIncludePolygonAsKML = false;
+               protected $bIncludePolygonAsSVG = false;
+               protected $fPolygonSimplificationThreshold = 0.0;
+
+
                function ReverseGeocode(&$oDB)
                {
                        $this->oDB =& $oDB;
                        $this->iMaxRank = (isset($iZoom) && isset($aZoomRank[$iZoom]))?$aZoomRank[$iZoom]:28;
                }
 
+                               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;
+               }
+
+               // returns { place_id =>, type => '(osm|tiger)' }
+               // fails if no place was found
                function lookup()
                {
                        $sPointSQL = 'ST_SetSRID(ST_Point('.$this->fLon.','.$this->fLat.'),4326)';
                                if ($fSearchDiam > 0.008 && $iMaxRank > 22) $iMaxRank = 22;
                                if ($fSearchDiam > 0.001 && $iMaxRank > 26) $iMaxRank = 26;
 
-                               $sSQL = 'select place_id,parent_place_id,rank_search,calculated_country_code from placex';
+                               $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)';
                                {
                                        $iPlaceID = $iParentPlaceID;
                                }
-                               $sSQL = "select address_place_id from place_addressline where place_id = $iPlaceID order by abs(cached_rank_address - $iMaxRank) asc,cached_rank_address desc,isaddress desc,distance desc limit 1";
+                               $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 = $this->oDB->getOne($sSQL);
                                if (PEAR::IsError($iPlaceID))
                                {
                        }
 
                        return array('place_id' => $iPlaceID,
-                                            'type' => $bPlaceIsTiger ? 'tiger' : 'osm');
+                                    'type' => $bPlaceIsTiger ? 'tiger' : 'osm');
                }
+               
        }
 ?>
index 013aee4b4a1c07daf07dde2389baff9f85069a11..03e269656a0516fcad57db2bd687413c4b25b113 100644 (file)
@@ -13,4 +13,4 @@
        }
        if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') exit;
 
-    header('Content-type: text/html; charset=utf-8');
+       header('Content-type: text/html; charset=utf-8');
index 6d4e8f293d4987bc1619419c9345ab32a477fc22..47e8447704695f958f258d1f21feb16c1b98e80b 100644 (file)
@@ -7,39 +7,39 @@
                if (!CONST_ConnectionBucket_MemcacheServerAddress) return null;
                if (!isset($m))
                {
-                       $m = new Memcached();
-                       $m->addServer(CONST_ConnectionBucket_MemcacheServerAddress, CONST_ConnectionBucket_MemcacheServerPort);
+                       $m = new Memcached();
+                       $m->addServer(CONST_ConnectionBucket_MemcacheServerAddress, CONST_ConnectionBucket_MemcacheServerPort);
                }
                return $m;
        }
 
        function doBucket($asKey, $iRequestCost, $iLeakPerSecond, $iThreshold)
        {
-               $m = getBucketMemcache();
+               $m = getBucketMemcache();
                if (!$m) return 0;
 
                $iMaxVal = 0;
-               $t = time();
+               $t = time();
 
                foreach($asKey as $sKey)
                {
-                       $aCurrentBlock = $m->get($sKey);
-                       if (!$aCurrentBlock)
+                       $aCurrentBlock = $m->get($sKey);
+                       if (!$aCurrentBlock)
                        {
-                               $aCurrentBlock = array($iRequestCost, $t, false);
-                       }
+                               $aCurrentBlock = array($iRequestCost, $t, false);
+                       }
                        else
                        {
                                // add RequestCost
                                // remove leak * the time since the last request 
-                               $aCurrentBlock[0] += $iRequestCost - ($t - $aCurrentBlock[1])*$iLeakPerSecond;
-                               $aCurrentBlock[1] = $t;
+                               $aCurrentBlock[0] += $iRequestCost - ($t - $aCurrentBlock[1])*$iLeakPerSecond;
+                               $aCurrentBlock[1] = $t;
                        }
 
-                       if ($aCurrentBlock[0] <= 0)
+                       if ($aCurrentBlock[0] <= 0)
                        {
-                               $m->delete($sKey);
-                       }
+                               $m->delete($sKey);
+                       }
                        else
                        {
                                // If we have hit the threshold stop and record this to the block list
@@ -77,7 +77,7 @@
                                        }
                                }
                                // Only keep in memcache until the time it would have expired (to avoid clutering memcache)
-                               $m->set($sKey, $aCurrentBlock, $t + 1 + $aCurrentBlock[0]/$iLeakPerSecond);
+                                               $m->set($sKey, $aCurrentBlock, $t + 1 + $aCurrentBlock[0]/$iLeakPerSecond);
                        }
 
                        // Bucket result in the largest bucket we find
                }
 
                return $iMaxVal;
-        }
+       }
 
        function isBucketSleeping($asKey)
        {
-               $m = getBucketMemcache();
+               $m = getBucketMemcache();
                if (!$m) return false;
 
                foreach($asKey as $sKey)
                {
-                       $aCurrentBlock = $m->get($sKey);
+                       $aCurrentBlock = $m->get($sKey);
                        if ($aCurrentBlock[2]) return true;
                }
                return false;
 
        function setBucketSleeping($asKey, $bVal)
        {
-               $m = getBucketMemcache();
+               $m = getBucketMemcache();
                if (!$m) return false;
 
                $iMaxVal = 0;
-               $t = time();
+               $t = time();
 
                foreach($asKey as $sKey)
                {
-                       $aCurrentBlock = $m->get($sKey);
+                       $aCurrentBlock = $m->get($sKey);
                        $aCurrentBlock[2] = $bVal;
                        $m->set($sKey, $aCurrentBlock, $t + 1 + $aCurrentBlock[0]/CONST_ConnectionBucket_LeakRate);
                }
 
        function getBucketBlocks()
        {
-               $m = getBucketMemcache();
+               $m = getBucketMemcache();
                if (!$m) return null;
-               $t = time();
+               $t = time();
                $aBlockedList = $m->get('blockedList', null, $hCasToken);
                if (!$aBlockedList) $aBlockedList = array();
                foreach($aBlockedList as $sKey => $aDetails)
 
        function clearBucketBlocks()
        {
-               $m = getBucketMemcache();
+               $m = getBucketMemcache();
                if (!$m) return false;
                $m->delete('blockedList');
                return true;
index d1afedbd68414278f90dbcb1906c6c067c06147c..e657daf4207c7bd433e85425990b0ccf5cc20ffe 100644 (file)
        function bySearchRank($a, $b)
        {
                if ($a['iSearchRank'] == $b['iSearchRank'])
-            return strlen($a['sOperator']) + strlen($a['sHouseNumber']) - strlen($b['sOperator']) - strlen($b['sHouseNumber']);
+                       return strlen($a['sOperator']) + strlen($a['sHouseNumber']) - strlen($b['sOperator']) - strlen($b['sHouseNumber']);
                return ($a['iSearchRank'] < $b['iSearchRank']?-1:1);
        }
 
                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)
        {
 
                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 f8d425e20808f93e2e10d789f42fe9507eb4aa08..b943c5302f9125928d0a60e2c06152c628aebddd 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>
-      <div id="map"></div>
-    </div>
+               <div id="map-wrapper">
+                       <div id="map-position"></div>
+                       <div id="map"></div>
+               </div>
 
-  </div> <!-- /content -->
+       </div> <!-- /content -->
 
 
 
 
 
 
-  <script type="text/javascript">
-  <?php
+       <script type="text/javascript">
+       <?php
 
-    $aNominatimMapInit = [
-      '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 = [
+                       '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 ff245e145f4dac3414cd073592634c6cd933115e..6fd101bbaac0f97c511c7250b99e62554c52e654 100644 (file)
                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 = ($aPlace['osm_type'] == 'N'?'node':($aPlace['osm_type'] == 'W'?'way':($aPlace['osm_type'] == 'R'?'relation':'')));
-                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'];
+               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['aPolyPoints']) && $bAsPoints)
+                       {
+                               $aFilteredPlaces['polygonpoints'] = $aPlace['aPolyPoints'];
+                       }
+               }
+
+               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 a8a05dd48cfa3c5a7e34c81372630245e93864bb..894038758411117edf6ed9a9a6350a3b3b3c0ec3 100644 (file)
                if ($aPlace['place_id']) $aFilteredPlaces['place_id'] = $aPlace['place_id'];
                $aFilteredPlaces['licence'] = "Data Â© OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright";
                $sOSMType = ($aPlace['osm_type'] == 'N'?'node':($aPlace['osm_type'] == 'W'?'way':($aPlace['osm_type'] == 'R'?'relation':'')));
-                if ($sOSMType)
-                {
-                        $aFilteredPlaces['osm_type'] = $sOSMType;
-                        $aFilteredPlaces['osm_id'] = $aPlace['osm_id'];
-                }
+               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'];
 
                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['aPolyPoints']) && $bAsPoints)
+                       {
+                               $aFilteredPlaces['polygonpoints'] = $aPlace['aPolyPoints'];
+                       }
+               }
+
+               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 39d9a14792171a0c0d0cd0efc60ff8fa73c7257b..109e66a17ef41d2e3426f6b4061c535817be6435 100644 (file)
                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 ($bAsPoints && isset($aPlace['aPolyPoints']))
+                       {
+                               echo ' polygonpoints=\'';
+                               echo json_encode($aPlace['aPolyPoints']);
+                               echo '\'';
+                       }
+               }
+
+               if (isset($aPlace['asgeojson']))
+               {
+                       echo ' geojson=\'';
+                       echo $aPlace['asgeojson'];
+                       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['aAddress']))
                        }
                        echo "</namedetails>";
                }
+
+               if (isset($aPlace['askml']))
+               {
+                       echo "\n<geokml>";
+                       echo $aPlace['askml'];
+                       echo "</geokml>";
+               }
+
        }
 
        echo "</reversegeocode>";
index 6845cbb22821df791093d0ce3b5d4a187faa2ec5..3e9e39d75c4fa31a3734ba9546a701339f6c747d 100644 (file)
                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";
+       }
+
 ?>
 
 
                headline('Name Keywords');
                foreach($aPlaceSearchNameKeywords as $aRow)
                {
-                       echo '<div>'.$aRow['word_token']."</div>\n";
+                       _one_keyword_row($aRow['word_token'], $aRow['word_id']);
                }
        }
 
                headline('Address Keywords');
                foreach($aPlaceSearchAddressKeywords as $aRow)
                {
-                       echo '<div>'.($aRow['word_token'][0]==' '?'*':'').$aRow['word_token'].'('.$aRow['word_id'].')'."</div>\n";
+                       _one_keyword_row($aRow['word_token'], $aRow['word_id']);
                }
        }
        
        <script type="text/javascript">
        <?php
 
-    $aNominatimMapInit = [
-      'tile_url' => $sTileURL,
-      'tile_attribution' => $sTileAttribution
-    ];
-    echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
+               $aNominatimMapInit = [
+                 'tile_url' => $sTileURL,
+                 'tile_attribution' => $sTileAttribution
+               ];
+               echo 'var nominatim_map_init = ' . json_encode($aNominatimMapInit, JSON_PRETTY_PRINT) . ';';
 
-    $aPlace = [
-                       'outlinestring' => $aPointDetails['outlinestring'],
-                       'lon' => $aPointDetails['lon'],
-                       'lat' => $aPointDetails['lat'],
-    ];
-         echo 'var nominatim_result = ' . json_encode($aPlace, JSON_PRETTY_PRINT) . ';'; 
+               $aPlace = [
+                               'outlinestring' => $aPointDetails['outlinestring'],
+                               'lon' => $aPointDetails['lon'],
+                               'lat' => $aPointDetails['lat'],
+               ];
+               echo 'var nominatim_result = ' . json_encode($aPlace, JSON_PRETTY_PRINT) . ';'; 
 
 
-  ?>
+       ?>
        </script>
 
 
index 3083c11bb8be4022d89b4121cddb718bbfb87b01..3d73b1e47cf81166131939b227f2a8766319d8d3 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 e0b367b420b74a57a5c98324b8bbefe463dfc618..d72fcb7c1c91d1cee1625f8730a299e134ce6ac6 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 ($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 ef2c143abf16ae9b440127f1f6397758062fad52..edfe3871403684842fa822afcb2f4722a09db5b7 100644 (file)
@@ -11,8 +11,8 @@
                foreach($aSearchResults as $iResNum => $aPointDetails)
                {
                        $aPlace = array(
-                                       'place_id'=>$aPointDetails['place_id'],
-                                 );
+                                               'place_id'=>$aPointDetails['place_id'],
+                                       );
 
                        $sOSMType = ($aPointDetails['osm_type'] == 'N'?'node':($aPointDetails['osm_type'] == 'W'?'way':($aPointDetails['osm_type'] == 'R'?'relation':'')));
                        if ($sOSMType)
@@ -21,8 +21,8 @@
                                $aPlace['osm_id'] = $aPointDetails['osm_id'];
                        }
 
-                       if (isset($aPointDetails['aBoundingBox']))
-                       {
+                       if (isset($aPointDetails['aBoundingBox']))
+                       {
                                $aPlace['boundingbox'] = array(
                                        $aPointDetails['aBoundingBox'][0],
                                        $aPointDetails['aBoundingBox'][1],
@@ -33,7 +33,7 @@
                                {
                                        $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
                                }
-                       }
+                       }
 
                        if (isset($aPointDetails['zoom']))
                        {
                        if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
                        {
                                $aPlace['address'] = $aPointDetails['address'];
-                       }
+                       }
 
-                       if (isset($aPointDetails['asgeojson']))
-                       {
+                       if (isset($aPointDetails['asgeojson']))
+                       {
                                $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-                       }
+                       }
 
-                       if (isset($aPointDetails['assvg']))
-                       {
+                       if (isset($aPointDetails['assvg']))
+                       {
                                $aPlace['svg'] = $aPointDetails['assvg'];
-                       }
+                       }
 
-                       if (isset($aPointDetails['astext']))
-                       {
-                               $aPlace['geotext'] = $aPointDetails['astext'];
-                       }
+                       if (isset($aPointDetails['astext']))
+                       {
+                               $aPlace['geotext'] = $aPointDetails['astext'];
+                       }
 
-                       if (isset($aPointDetails['askml']))
-                       {
-                               $aPlace['geokml'] = $aPointDetails['askml'];
-                       }
+                       if (isset($aPointDetails['askml']))
+                       {
+                               $aPlace['geokml'] = $aPointDetails['askml'];
+                       }
 
                        $aFilteredPlaces[] = $aPlace;
                }
index 3dcaabdbd6393a94bc27b375c1c401db11626a69..fc50ee0e09b2554916271e00f11cac6082418ba3 100644 (file)
                        $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['aBoundingBox']))
+               {
+                       $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
 
                        if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
                        {
                                $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
                        }
-                }
+               }
 
                if (isset($aPointDetails['zoom']))
                {
                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['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']))
                {
index e974772023393a39818205bc22abe0201c2207c3..773cfd96679dd7b27d88f368930a599753485033 100644 (file)
                        $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['aBoundingBox']))
+               {
+                       $aPlace['boundingbox'] = $aPointDetails['aBoundingBox'];
 
                        if (isset($aPointDetails['aPolyPoints']) && $bShowPolygons)
                        {
                                $aPlace['polygonpoints'] = $aPointDetails['aPolyPoints'];
                        }
-                }
+               }
 
                if (isset($aPointDetails['zoom']))
                {
                if (isset($aPointDetails['address']) && sizeof($aPointDetails['address'])>0)
                {
                        $aPlace['address'] = $aPointDetails['address'];
-                }
+               }
 
-                if (isset($aPointDetails['asgeojson']))
-                {
+               if (isset($aPointDetails['asgeojson']))
+               {
                        $aPlace['geojson'] = json_decode($aPointDetails['asgeojson']);
-                }
+               }
 
-                if (isset($aPointDetails['assvg']))
-                {
+               if (isset($aPointDetails['assvg']))
+               {
                        $aPlace['svg'] = $aPointDetails['assvg'];
-                }
+               }
 
-                if (isset($aPointDetails['astext']))
-                {
-                        $aPlace['geotext'] = $aPointDetails['astext'];
-                }
+               if (isset($aPointDetails['astext']))
+               {
+                       $aPlace['geotext'] = $aPointDetails['astext'];
+               }
 
-                if (isset($aPointDetails['askml']))
-                {
-                        $aPlace['geokml'] = $aPointDetails['askml'];
-                }
+               if (isset($aPointDetails['askml']))
+               {
+                       $aPlace['geokml'] = $aPointDetails['askml'];
+               }
 
                if (isset($aPointDetails['sExtraTags'])) $aPlace['extratags'] = $aPointDetails['sExtraTags'];
                if (isset($aPointDetails['sNameDetails'])) $aPlace['namedetails'] = $aPointDetails['sNameDetails'];
index b61ff22f55fe2eed589466c682a8f650ac14b52b..6a382ebf7bcb4bde0c83783e05211f9ba8241ccb 100644 (file)
                if (isset($aResult['aBoundingBox']))
                {
                        echo ' boundingbox="';
-                       echo $aResult['aBoundingBox'][0];
-                       echo ','.$aResult['aBoundingBox'][1];
-                       echo ','.$aResult['aBoundingBox'][2];
-                       echo ','.$aResult['aBoundingBox'][3];
+                       echo join(',',$aResult['aBoundingBox']);
                        echo '"';
 
                        if ($bShowPolygons && isset($aResult['aPolyPoints']))
index 4456316e39981349d588c21b4dffc858105ec30b..2e199ada0ffffe718934da125d297ef6f87ab330 100644 (file)
@@ -38,14 +38,14 @@ $aLanguageIn = array(
 
 # 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 4c5638b14eaebaa26f25ab2b310b720c49bec1fb..d50a8da4a4a0f487ca1686cdfc450da36fd86415 100644 (file)
@@ -12,6 +12,51 @@ class NominatimTest extends \PHPUnit_Framework_TestCase
        }
 
 
+       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
@@ -142,10 +187,74 @@ class NominatimTest extends \PHPUnit_Framework_TestCase
                        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 fa636acf548b773f9b5df287f9f7ef6ab812512e..39519177be9be4cd5b9afba5b614eca314d4efec 100644 (file)
@@ -11,6 +11,15 @@ Feature: Reverse geocoding
          | ID | country
          | 0  | Deutschland
 
+
+    Scenario: Boundingbox is returned
+        Given the request parameters
+          | format | zoom
+          | xml    | 4
+        When looking up coordinates 53.9788769,13.0830313
+        And results contain valid boundingboxes
+
+
     @Tiger
     Scenario: TIGER house number
         Given the request parameters
@@ -61,3 +70,75 @@ Feature: Reverse geocoding
         | xml
         | json
         | jsonv2
+
+
+   Scenario Outline: Reverse Geocoding contains TEXT geometry
+        Given the request parameters
+          | polygon_text
+          | 1
+        When looking up <format> coordinates 48.86093,2.2978
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geotext
+        | json     | geotext
+        | jsonv2   | geotext
+
+   Scenario Outline: Reverse Geocoding contains polygon-as-points geometry
+        Given the request parameters
+          | polygon
+          | 1
+        When looking up <format> coordinates 48.86093,2.2978
+        Then result 0 has not attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | polygonpoints
+        | json     | polygonpoints
+        | jsonv2   | polygonpoints
+
+
+
+   Scenario Outline: Reverse Geocoding contains SVG geometry
+        Given the request parameters
+          | polygon_svg
+          | 1
+        When looking up <format> coordinates 48.86093,2.2978
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geosvg
+        | json     | svg
+        | jsonv2   | svg
+
+
+   Scenario Outline: Reverse Geocoding contains KML geometry
+        Given the request parameters
+          | polygon_kml
+          | 1
+        When looking up <format> coordinates 48.86093,2.2978
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geokml
+        | json     | geokml
+        | jsonv2   | geokml
+
+
+   Scenario Outline: Reverse Geocoding contains GEOJSON geometry
+        Given the request parameters
+          | polygon_geojson
+          | 1
+        When looking up <format> coordinates 48.86093,2.2978
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geojson
+        | json     | geojson
+        | jsonv2   | geojson
+
+
index 8621ec655903d80006909b7ecf9fff097287cf48..5d79fd4b8af1e22bb61343fe2d7af3d5ba620171 100644 (file)
@@ -17,6 +17,49 @@ Feature: Simple Reverse Tests
      | -79.34   | 23.5
      | 0.23     | -178.555
 
+    Scenario Outline: Testing different parameters
+        Given the request parameters
+          | <parameter>
+          | <value>
+        When sending search query "Manchester"
+        Then the result is valid html
+        Given the request parameters
+          | <parameter>
+          | <value>
+        When sending html search query "Manchester"
+        Then the result is valid html
+        Given the request parameters
+          | <parameter>
+          | <value>
+        When sending xml search query "Manchester"
+        Then the result is valid xml
+        Given the request parameters
+          | <parameter>
+          | <value>
+        When sending json search query "Manchester"
+        Then the result is valid json
+        Given the request parameters
+          | <parameter>
+          | <value>
+        When sending jsonv2 search query "Manchester"
+        Then the result is valid json
+
+    Examples:
+     | parameter        | value
+     | polygon          | 1
+     | polygon          | 0
+     | polygon_text     | 1
+     | polygon_text     | 0
+     | polygon_kml      | 1
+     | polygon_kml      | 0
+     | polygon_geojson  | 1
+     | polygon_geojson  | 0
+     | polygon_svg      | 1
+     | polygon_svg      | 0
+
+
+
+
     Scenario Outline: Wrapping of legal jsonp requests
         Given the request parameters
         | json_callback
index a4885a1577933fcdfbb3ef80cb928a99acaf5320..34e43328d50d1c1a68a8a6ad0ecd36cf7e238497 100644 (file)
@@ -8,6 +8,7 @@ Feature: Search queries
         And result 0 has attributes lat,lon,display_name
         And result 0 has attributes class,type,importance,icon
         And result 0 has not attributes address
+        And results contain valid boundingboxes
 
     Scenario: Simple JSON search
         When sending json search query "Vaduz"
@@ -15,6 +16,7 @@ Feature: Search queries
         And result 0 has attributes osm_type,osm_id,boundingbox
         And result 0 has attributes lat,lon,display_name,importance
         And result 0 has not attributes address
+        And results contain valid boundingboxes
 
     Scenario: JSON search with addressdetails
         When sending json search query "Montevideo" with address
@@ -230,3 +232,73 @@ Feature: Search queries
         | xml
         | json
         | jsonv2
+
+
+   Scenario Outline: Search result with contains TEXT geometry
+        Given the request parameters
+          | polygon_text
+          | 1
+        When sending <format> search query "switzerland"
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geotext
+        | json     | geotext
+        | jsonv2   | geotext
+
+   Scenario Outline: Search result contains polygon-as-points geometry
+        Given the request parameters
+          | polygon
+          | 1
+        When sending <format> search query "switzerland"
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | polygonpoints
+        | json     | polygonpoints
+        | jsonv2   | polygonpoints
+
+
+
+   Scenario Outline: Search result contains SVG geometry
+        Given the request parameters
+          | polygon_svg
+          | 1
+        When sending <format> search query "switzerland"
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geosvg
+        | json     | svg
+        | jsonv2   | svg
+
+
+   Scenario Outline: Search result contains KML geometry
+        Given the request parameters
+          | polygon_kml
+          | 1
+        When sending <format> search query "switzerland"
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geokml
+        | json     | geokml
+        | jsonv2   | geokml
+
+
+   Scenario Outline: Search result contains GEOJSON geometry
+        Given the request parameters
+          | polygon_geojson
+          | 1
+        When sending <format> search query "switzerland"
+        Then result 0 has attributes <response_attribute>
+
+   Examples:
+        | format   | response_attribute
+        | xml      | geojson
+        | json     | geojson
+        | jsonv2   | geojson
index 4910c157649d17bc7f818abeca610f366eb75c18..2644d4a20c7489589ab5045d01c4c44fc06a67eb 100644 (file)
@@ -98,6 +98,8 @@ def _parse_xml():
                     attrs = dict(tag.attributes.items())
                     assert_in('desc', attrs)
                     world.results[0]['namedetails'][attrs['desc']] = tag.firstChild.nodeValue.strip()
+            elif node.nodeName == "geokml":
+                world.results[0]['geokml'] = node
             elif node.nodeName == "#text":
                 pass
             else:
@@ -209,6 +211,15 @@ def api_result_contains(step):
                         m = re.match("%s$" % (v,), curres[k])
                         assert_is_not_none(m, msg="field %s does not match: %s$ != %s." % (k, v, curres[k]))
 
+@step(u'results contain valid boundingboxes$')
+def api_result_address_contains(step):
+    step.given('the result is valid')
+    for curres in world.results:
+        bb = curres['boundingbox']
+        if world.response_format == 'json':
+            bb = ','.join(bb)
+        m = re.match('^(-?\d+\.\d+),(-?\d+\.\d+),(-?\d+\.\d+),(-?\d+\.\d+)$', bb)
+        assert_is_not_none(m, msg="invalid boundingbox: %s." % (curres['boundingbox']))
 
 @step(u'result addresses contain$')
 def api_result_address_contains(step):
diff --git a/vagrant/centos-7-provision.sh b/vagrant/centos-7-provision.sh
new file mode 100644 (file)
index 0000000..93139a2
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+# This script sets up a Nominatim installation on a CentOS 7 box.
+#
+# For more detailed CentOS installation instructions see also
+# http://wiki.openstreetmap.org/wiki/Nominatim/Installation_on_CentOS
+
+## Part 1: System preparation
+
+## During 'vagrant provision' this script runs as root and the current
+## directory is '/root'
+USERNAME=vagrant
+
+yum update -y
+yum install -y epel-release
+
+yum install -y postgresql-server postgresql-contrib postgresql-devel postgis postgis-utils \
+               make automake gcc gcc-c++ libtool policycoreutils-python \
+               php-pgsql php php-pear php-pear-DB libpqxx-devel proj-epsg \
+               bzip2-devel proj-devel geos-devel libxml2-devel boost-devel \
+               expat-devel zlib-devel
+
+# Create a cluster and start up postgresql.
+postgresql-setup initdb
+systemctl enable postgresql
+systemctl start postgresql
+
+# We leave postgresql in its default configuration here. This is only
+# suitable for small extracts.
+
+# Create the necessary postgres users.
+sudo -u postgres createuser -s vagrant
+sudo -u postgres createuser apache
+
+# Create the website directory.
+mkdir -m 755 /var/www/html/nominatim
+chown vagrant /var/www/html/nominatim
+
+# Set up the necessary rights on SELinux.
+semanage fcontext -a -t httpd_sys_content_t "/home/vagrant/Nominatim/(website|lib|settings)(/.*)?"
+semanage fcontext -a -t lib_t "/home/vagrant/Nominatim/module/nominatim.so"
+semanage port -a -t http_port_t -p tcp 8089
+restorecon -R -v /home/vagrant/Nominatim
+
+# Configure apache site.
+echo '
+Listen 8089
+<VirtualHost *:8089>
+    # DirectoryIndex index.html
+    # ErrorDocument 403 /index.html
+
+    DocumentRoot "/var/www/html/"
+    <Directory "/var/www/html/nominatim/">
+      Options FollowSymLinks MultiViews
+      AddType text/html   .php
+    </Directory>
+</VirtualHost>
+' | sudo tee /etc/httpd/conf.d/nominatim.conf > /dev/null
+
+# Restart apache to enable the site configuration.
+systemctl enable httpd
+systemctl restart httpd
+
+## Part 2: Nominatim installaion
+
+# now ideally login as $USERNAME and continue
+cd /home/$USERNAME
+
+# If the Nominatim source is not being shared with the host, check out source.
+if [ ! -d "Nominatim" ]; then
+  yum install -y git
+  sudo -u $USERNAME git clone --recursive https://github.com/twain47/Nominatim.git
+fi
+
+# Configure and compile the source.
+cd Nominatim
+sudo -u $USERNAME ./autogen.sh
+sudo -u $USERNAME ./configure
+sudo -u $USERNAME make
+
+# Make sure that postgres has access to the nominatim library.
+chmod +x /home/$USERNAME
+chmod +x ./
+chmod +x ./module
+
+# Create customized settings suitable for this VM installation.
+LOCALSETTINGS_FILE='settings/local.php'
+if [[ -e "$LOCALSETTINGS_FILE" ]]; then
+  echo "$LOCALSETTINGS_FILE already exist, writing to settings/local-vagrant.php instead."
+  LOCALSETTINGS_FILE='settings/local-vagrant.php'
+fi
+
+IP=localhost
+echo "<?php
+   // General settings
+   @define('CONST_Database_DSN', 'pgsql://@/nominatim');
+   // Paths
+   @define('CONST_Postgresql_Version', '9.2');
+   @define('CONST_Postgis_Version', '2.0');
+   @define('CONST_Database_Web_User', 'apache');
+   // Website settings
+   @define('CONST_Website_BaseURL', 'http://$IP:8089/nominatim/');
+" > $LOCALSETTINGS_FILE
+
+# Install the web interface.
+sudo -u $USERNAME ./utils/setup.php --create-website /var/www/html/nominatim
similarity index 81%
rename from vagrant-provision.sh
rename to vagrant/ubuntu-trusty-provision.sh
index 1a7702263ea4bb5a9cc32b59e26b3dd5aee5db6f..84e98e23797644d82b9182ffa421cdf88a112d44 100755 (executable)
@@ -1,5 +1,11 @@
 #!/bin/bash
 
+# This script sets up a Nominatim installation on a Ubuntu box.
+#
+# For more detailed installation instructions see also
+# http://wiki.openstreetmap.org/wiki/Nominatim/Installation
+
+## Part 1: System preparation
 
 ## During 'vagrant provision' this script runs as root and the current
 ## directory is '/root'
@@ -75,20 +81,22 @@ echo "date.timezone = 'Etc/UTC'" | sudo tee /etc/php5/cli/conf.d/99-timezone.ini
 ###
 sudo apt-get install -y libgeos-c1 libgeos++-dev libxml2-dev
 
+## Part 2: Nominatim installaion
+
 # now ideally login as $USERNAME and continue
-su $USERNAME -l
-cd /home/vagrant
+cd /home/$USERNAME
 
+# If the Nominatim source is not being shared with the host, check out source.
 if [ ! -d "Nominatim" ]; then
   sudo apt-get install -y git
-  git clone --recursive https://github.com/twain47/Nominatim.git
+  sudo -u $USERNAME git clone --recursive https://github.com/twain47/Nominatim.git
 fi
 
 cd Nominatim
 
-./autogen.sh
-./configure
-make
+sudo -u $USERNAME ./autogen.sh
+sudo -u $USERNAME ./configure
+sudo -u $USERNAME make
 chmod +x ./
 chmod +x ./module
 
@@ -139,12 +147,12 @@ Listen 8089
 ' | sudo tee /etc/apache2/sites-enabled/nominatim.conf > /dev/null
 
 
-sudo apache2ctl graceful
+apache2ctl graceful
 
 
-sudo mkdir -m 755 /var/www/nominatim
-sudo chown $USERNAME /var/www/nominatim
-./utils/setup.php --threads 1 --create-website /var/www/nominatim
+mkdir -m 755 /var/www/nominatim
+chown $USERNAME /var/www/nominatim
+sudo -u $USERNAME ./utils/setup.php --create-website /var/www/nominatim
 
 
 # if you get 'permission denied for relation word', then try
@@ -155,12 +163,12 @@ sudo chown $USERNAME /var/www/nominatim
 ## Test suite (Python)
 ## https://github.com/twain47/Nominatim/tree/master/tests
 ##
-sudo apt-get install -y python-dev python-pip python-Levenshtein python-shapely \
+apt-get install -y python-dev python-pip python-Levenshtein python-shapely \
                         python-psycopg2 tidy python-nose python-tidylib
-sudo pip install lettuce==0.2.18 six==1.7 haversine
+pip install lettuce==0.2.18 six==1.7 haversine
 
 ## Test suite (PHP)
 ## https://github.com/twain47/Nominatim/tree/master/tests-php
-sudo apt-get install -y phpunit
+apt-get install -y phpunit
 
 
index 4e2e623c3c43a8f2834bd4bf9cb55dc5f009913b..5d6ee15ddb1bc3dbc6c92c12b2486e481cc040c2 100755 (executable)
@@ -1,6 +1,6 @@
 <?php
-        require_once(dirname(dirname(__FILE__)).'/lib/init-website.php');
-        require_once(CONST_BasePath.'/lib/log.php');
+       require_once(dirname(dirname(__FILE__)).'/lib/init-website.php');
+       require_once(CONST_BasePath.'/lib/log.php');
 
        $sOutputFormat = 'html';
        ini_set('memory_limit', '200M');
 <!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>
 
@@ -79,16 +79,16 @@ table td {
                {
                        switch($sCol)
                        {
-            case 'osm_id':
-                $sOSMType = ($aRow['osm_type'] == 'N'?'node':($aRow['osm_type'] == 'W'?'way':($aRow['osm_type'] == 'R'?'relation':'')));
-                echo '<td><a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$sVal.'" target="_new">'.$sVal.'</a></td>';
-                                break;
-                       case 'place_id':
-                               echo '<td><a href="'.CONST_Website_BaseURL.'details?place_id='.$sVal.'">'.$sVal.'</a></td>';
-                               break;
-                       default:
-                               echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
-                               break;
+                               case 'osm_id':
+                                       $sOSMType = ($aRow['osm_type'] == 'N'?'node':($aRow['osm_type'] == 'W'?'way':($aRow['osm_type'] == 'R'?'relation':'')));
+                                       echo '<td><a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$sVal.'" target="_new">'.$sVal.'</a></td>';
+                                       break;
+                               case 'place_id':
+                                       echo '<td><a href="'.CONST_Website_BaseURL.'details?place_id='.$sVal.'">'.$sVal.'</a></td>';
+                                       break;
+                               default:
+                                       echo "<td>".($sVal?$sVal:'&nbsp;')."</td>";
+                                       break;
                        }
                }
                echo "</tr>";
index ad753a82a5bb93075deb5bf466287e3bb4bb6304..3a0fee82a29fb2d70dc9e0b2138dc15e6671a71b 100755 (executable)
 
        logEnd($oDB, $hLog, 1);
 
-       $sTileURL = CONST_Map_Tile_URL;
-       $sTileAttribution = CONST_Map_Tile_Attribution;
+       if ($sOutputFormat=='html')
+       {
+               $sDataDate = $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 d99040a2f2d31596002aafeb020cb599b29cdf91..de83ca4464a4d3e8f21a333a0be6de28014c02e0 100755 (executable)
@@ -78,7 +78,7 @@
                $aBreadcrums[] = array('placeId'=>$aPlace['place_id'], 'osmType'=>$aPlace['osm_type'], 'osmId'=>$aPlace['osm_id'], 'localName'=>$aPlace['localname']);
                $sPlaceUrl = 'hierarchy.php?place_id='.$aPlace['place_id'];
                $sOSMType = ($aPlace['osm_type'] == 'N'?'node':($aPlace['osm_type'] == 'W'?'way':($aPlace['osm_type'] == 'R'?'relation':'')));
-                $sOSMUrl = 'http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aPlace['osm_id'];
+                               $sOSMUrl = 'http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aPlace['osm_id'];
                if ($sOutputFormat == 'html') if ($i) echo " > ";
                if ($sOutputFormat == 'html') echo '<a href="'.$sPlaceUrl.'">'.$aPlace['localname'].'</a> (<a href="'.$sOSMUrl.'">osm</a>)';
        }
        $sSQL .= " order by rank_address asc,rank_search asc,localname,class, type,housenumber";
        $aParentOfLines = $oDB->getAll($sSQL);
 
-        if (sizeof($aParentOfLines))
-        {
-                echo '<h2>Parent Of:</h2>';
+       if (sizeof($aParentOfLines))
+       {
+               echo '<h2>Parent Of:</h2>';
                $aClassType = getClassTypesWithImportance();
-                $aGroupedAddressLines = array();
-                foreach($aParentOfLines as $aAddressLine)
-                {
+               $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'];
-                                }
+                             && $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'];
-                                }
+                               && $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 = ($aAddressLine['osm_type'] == 'N'?'node':($aAddressLine['osm_type'] == 'W'?'way':($aAddressLine['osm_type'] == 'R'?'relation':'')));
-
-                        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.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></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>';
-        }
+                       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 = ($aAddressLine['osm_type'] == 'N'?'node':($aAddressLine['osm_type'] == 'W'?'way':($aAddressLine['osm_type'] == 'R'?'relation':'')));
+
+                                       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.' <a href="http://www.openstreetmap.org/browse/'.$sOSMType.'/'.$aAddressLine['osm_id'].'">'.$aAddressLine['osm_id'].'</a></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>';
+               }
 exit;
 
 
index be10807453161cd96e4c1dcd516bf9bf44ebaf59..3e0aabd2370fba5b52627ed37bd64b7e8ec38b1c 100644 (file)
@@ -117,7 +117,7 @@ jQuery(document).on('ready', function(){
 
                        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/) ){
+                       if (result.astext && result.astext.match(/(POLY)|(LINE)/) ){
                                var layer = omnivore.wkt.parse(result.astext);
                                layerGroup.addLayer(layer);
                        }
index 5a5be9f067398bfe9027630d86d91cb432e07e64..423374c7a08b6678bc95e38a9046c63606de3ba0 100755 (executable)
 <!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>
 
index d1603fa1e1752f68b55544ea44150dc96bf294a5..1f6e0aad1114f9acbd14e5baf210ef8cc4e792a9 100755 (executable)
@@ -6,6 +6,35 @@
        require_once(CONST_BasePath.'/lib/PlaceLookup.php');
        require_once(CONST_BasePath.'/lib/ReverseGeocode.php');
 
+       $bAsPoints = false;
+       $bAsGeoJSON = (boolean)isset($_GET['polygon_geojson']) && $_GET['polygon_geojson'];
+       $bAsKML = (boolean)isset($_GET['polygon_kml']) && $_GET['polygon_kml'];
+       $bAsSVG = (boolean)isset($_GET['polygon_svg']) && $_GET['polygon_svg'];
+       $bAsText = (boolean)isset($_GET['polygon_text']) && $_GET['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;
+       }
+
+
+       // Polygon simplification threshold (optional)
+       $fThreshold = 0.0;
+       if (isset($_GET['polygon_threshold'])) $fThreshold = (float)$_GET['polygon_threshold'];
+
+
        $oDB =& getDB();
        ini_set('memory_limit', '200M');
 
                $oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false));
 
                $aPlace = $oPlaceLookup->lookupPlace($aLookup);
+
+               $oPlaceLookup->setIncludePolygonAsPoints($bAsPoints);
+               $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);
+
+               $aPlace = array_merge($aPlace, $aOutlineResult);
        }
        else
        {
                exit;
        }
 
-       $sTileURL = CONST_Map_Tile_URL;
-       $sTileAttribution = CONST_Map_Tile_Attribution;
+       if ($sOutputFormat=='html')
+       {
+               $sDataDate = $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 f2c327c07fefe6760d5c51426d588c0c214c4c56..c216c8848c3a07063fd448e92d1a2222ba1da2fa 100755 (executable)
@@ -13,8 +13,6 @@
        $fLat = CONST_Default_Lat;
        $fLon = CONST_Default_Lon;
        $iZoom = CONST_Default_Zoom;
-       $sTileURL = CONST_Map_Tile_URL;
-       $sTileAttribution = CONST_Map_Tile_Attribution;
 
        $oGeocode =& new Geocode($oDB);
 
        {
                if (!(isset($_GET['q']) && $_GET['q']) && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/')
                {
-                               $sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1);
+                       $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);
+                       // reverse order of '/' separated string
+                       $aPhrases = explode('/', $sQuery);
+                       $aPhrases = array_reverse($aPhrases);
+                       $sQuery = join(', ',$aPhrases);
+                       $oGeocode->setQuery($sQuery);
                }
                else
                {
-                               $oGeocode->setQueryFromParams($_GET);
+                       $oGeocode->setQueryFromParams($_GET);
                }
        }
 
        $aSearchResults = $oGeocode->lookup();
        if ($aSearchResults === false) $aSearchResults = array();
 
-       $sDataDate = $oDB->getOne("select TO_CHAR(lastimportdate - '2 minutes'::interval,'YYYY/MM/DD HH24:MI')||' GMT' from import_status limit 1");
-
+       if ($sOutputFormat=='html')
+       {
+               $sDataDate = $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;
+       }
        logEnd($oDB, $hLog, sizeof($aSearchResults));
 
        $bAsText = $oGeocode->getIncludePolygonAsText();