]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Tue, 17 Jul 2018 20:39:13 +0000 (22:39 +0200)
committerSarah Hoffmann <lonvia@denofr.de>
Tue, 17 Jul 2018 20:39:13 +0000 (22:39 +0200)
27 files changed:
docs/admin/Faq.md
docs/api/Lookup.md
docs/api/Reverse.md
docs/api/Search.md
lib/AddressDetails.php [new file with mode: 0644]
lib/ClassTypes.php [new file with mode: 0644]
lib/Geocode.php
lib/PlaceLookup.php
lib/TokenSpecialTerm.php
lib/lib.php
lib/template/address-geocodejson.php
lib/template/address-geojson.php
lib/template/address-json.php
lib/template/address-xml.php
lib/template/search-batch-json.php
lib/template/search-geocodejson.php
lib/template/search-geojson.php
lib/template/search-json.php
lib/template/search-xml.php
test/bdd/api/reverse/simple.feature
test/bdd/api/search/simple.feature
test/bdd/steps/queries.py
test/php/Nominatim/LibTest.php
website/details.php
website/hierarchy.php
website/lookup.php
website/reverse.php

index a1624d263a83b38bd141148013bffbbe3808cd15..f3ad670a6e836344c5fe61985d96e0255730337b 100644 (file)
@@ -1,6 +1,6 @@
 # Running Your Own Instance
 
-### Can I import only a few countries and also keep them up to date?
+### Can I import multiple countries and keep them up to date?
 
 You should use the extracts and updates from https://download.geofabrik.de.
 For the initial import, download the countries you need and merge them.
@@ -16,14 +16,22 @@ once per day and apply them **separately** using
 See [this issue](https://github.com/openstreetmap/Nominatim/issues/60#issuecomment-18679446)
 for a script that runs the updates using osmosis.
 
-### My website shows: `XML Parsing Error: XML or text declaration not at start of entity Location</code>.`
+### Can I import negative OSM ids into Nominatim?
+
+See [https://help.openstreetmap.org/questions/64662/nominatim-flatnode-with-negative-id]()
+
+### Missing XML or text declaration
+
+The website might show: `XML Parsing Error: XML or text declaration not at start of entity Location.`
 
 Make sure there are no spaces at the beginning of your `settings/local.php` file.
 
 
 # Installation
 
-### I accidentally killed the import process after it has been running for many hours. Can it be resumed?
+### Can a stopped/killed import process be resumed?
+
+"I accidentally killed the import process after it has been running for many hours. Can it be resumed?"
 
 It is possible if the import already got to the indexing stage.
 Check the last line of output that was logged before the process
@@ -41,11 +49,12 @@ then you can resume with the following command:
 If the reported rank is 26 or higher, you can also safely add `--index-noanalyse`.
 
 
-### When running the setup.php script I get a warning:
+### PHP "open_basedir restriction in effect" warnings
+
     `PHP Warning:  file_get_contents(): open_basedir restriction in effect.`
 
 You need to adjust the [open_basedir](http://www.php.net/manual/en/ini.core.php#ini.open-basedir) setting
-in your PHP configuration (php.ini file). By default this setting may look like this:
+in your PHP configuration (`php.ini file`). By default this setting may look like this:
 
     open_basedir = /srv/http/:/home/:/tmp/:/usr/share/pear/
 
@@ -54,7 +63,9 @@ dding ";" at the beginning of the line. Don't forget to enable this setting agai
 once you are done with the PHP command line operations.
 
 
-### The Apache log contains lots of PHP warnings like this:
+### PHP timzeone warnings
+
+The Apache log may contain lots of PHP warnings like this:
     `PHP Warning:  date_default_timezone_set() function.`
 
 You should set the default time zone as instructed in the warning in
@@ -71,28 +82,32 @@ Or
 echo "date.timezone = 'America/Denver'" > /etc/php.d/timezone.ini
 ```
 
-### When running the import I get a version mismatch:
-    `COPY_END for place failed: ERROR: incompatible library "/opt/Nominatim/module/nominatim.so": version mismatch`
+### nominatim.so version mismatch
+
+When running the import you may get a version mismatch:
+`COPY_END for place failed: ERROR: incompatible library "/srv/Nominatim/nominatim/build/module/nominatim.so": version mismatch`
 
 pg_config seems to use bad includes sometimes when multiple versions
 of PostgreSQL are available in the system. Make sure you remove the
-server development libraries (`postgresql-server-dev-9.1` on Ubuntu)
+server development libraries (`postgresql-server-dev-9.5` on Ubuntu)
 and recompile (`cmake .. && make`).
 
 
-### I see the error: `function transliteration(text) does not exist`
+### I see the error: "function transliteration(text) does not exist"
 
 Reinstall the nominatim functions with `setup.php --create--functions`
 and check for any errors, e.g. a missing `nominatim.so` file.
 
 
-### The website shows: `Could not get word tokens`
+### The website shows: "Could not get word tokens"
 
 The server cannot access your database. Add `&debug=1` to your URL
 to get the full error message.
 
 
-### On CentOS the website shows `could not connect to server: No such file or directory`
+### On CentOS the website shows "Could not connect to server"
+
+`could not connect to server: No such file or directory`
 
 On CentOS v7 the PostgreSQL server is started with `systemd`.
 Check if `/usr/lib/systemd/system/httpd.service` contains a line `PrivateTmp=true`.
@@ -105,22 +120,60 @@ However, you can solve this the quick and dirty way by commenting out that line
     sudo systemctl restart httpd
 
 
-### Setup.php fails with the message: `DB Error: extension not found`
+### Website reports "DB Error: insufficient permissions"
+
+The user the webserver, e.g. Apache, runs under needs to have access to the Nominatim database. You can find the user like [this](https://serverfault.com/questions/125865/finding-out-what-user-apache-is-running-as), for default Ubuntu operating system for example it's `www-data`.
+
+1. Repeat the `createuser` step of the installation instructions.
+
+2. Give the user permission to existing tables
+
+```
+   GRANT usage ON SCHEMA public TO "www-data";
+   GRANT SELECT ON ALL TABLES IN SCHEMA public TO "www-data";
+```
+
+### Website reports "Could not load library "nominatim.so"
+
+Example error message
+
+```
+   SELECT make_standard_name('3039 E MEADOWLARK LN') [nativecode=ERROR: could not
+   load library "/srv/nominatim/Nominatim-3.1.0/build/module/nominatim.so":
+   /srv/nominatim/Nominatim-3.1.0/build/module/nominatim.so: cannot open shared
+   object file: Permission denied
+   CONTEXT: PL/pgSQL function make_standard_name(text) line 5 at assignment]
+```
+
+The user the webserver, e.g. Apache, runs under needs to have access to that file. Same for the user the Postgres runs as. You can find the user like [this](https://serverfault.com/questions/125865/finding-out-what-user-apache-is-running-as), for default Ubuntu operating system for example it's `www-data`.
+
+The permission need to be read&executable by everybody, e.g.
+
+```
+   -rwxr-xr-x 1 nominatim nominatim 297984 build/module/nominatim.so
+```
+
+Try `chmod a+r nominatim.so; chmod a+x nominatim.so`.
+
+### Setup.php fails with "DB Error: extension not found"
 
 Make sure you have the Postgres extensions hstore and postgis installed.
 See the installation instruction for a full list of required packages.
 
-### When running the setup.php script I get a error:
-    `Cannot redeclare getDB() (previously declared in /your/path/Nominatim/lib/db.php:4)`
+
+### Setup.php reports "Cannot redeclare getDB()"
+
+`Cannot redeclare getDB() (previously declared in /your/path/Nominatim/lib/db.php:4)`
 
 The message is a bit misleading as PHP needs to load the file `DB.php` and
 instead re-loads Nominatim's `db.php`. To solve this make sure you
-have the [http://pear.php.net/package/DB/ Pear module 'DB'] installed.
+have the [Pear module 'DB'](http://pear.php.net/package/DB/) installed.
 
     sudo pear install DB
 
 ### I forgot to delete the flatnodes file before starting an import.
 
 That's fine. For each import the flatnodes file get overwritten.
-See https://help.openstreetmap.org/questions/52419/nominatim-flatnode-storage
+See [https://help.openstreetmap.org/questions/52419/nominatim-flatnode-storage]()
 for more information.
+
index 3b6472ad4861601376f1ca630b57205eaac30880..21c0bab24e36e5bb274a3d4bda6aa3a6f9c5d108 100644 (file)
@@ -7,9 +7,10 @@ Lookup the address of one or multiple OSM objects like node, way or relation.
   https://nominatim.openstreetmap.org/lookup?<query>
 ```
 
-* `format=[xml|json]`
+* `format=[xml|json|geojson]`
 
     * Output format
+    * Defaults to `xml`
 
 * `json_callback=<string>`
 
@@ -41,7 +42,9 @@ Lookup the address of one or multiple OSM objects like node, way or relation.
 
 ### Example
 
-* [https://nominatim.openstreetmap.org/lookup?osm_ids=R146656,W104393803,N240109189](https://nominatim.openstreetmap.org/lookup?osm_ids=R146656,W104393803,N240109189)
+##### XML
+
+[https://nominatim.openstreetmap.org/lookup?osm_ids=R146656,W104393803,N240109189](https://nominatim.openstreetmap.org/lookup?osm_ids=R146656,W104393803,N240109189)
 
 ```xml
   <lookupresults timestamp="Mon, 29 Jun 15 18:01:33 +0000" attribution="Data © OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright" querystring="R146656,W104393803,N240109189" polygon="false">
@@ -73,3 +76,41 @@ Lookup the address of one or multiple OSM objects like node, way or relation.
     </place>
   </lookupresults>
 ```
+
+##### JSON with extratags
+
+[https://nominatim.openstreetmap.org/lookup?osm_ids=W50637691&format=json](https://nominatim.openstreetmap.org/lookup?osm_ids=W50637691&format=json)
+
+```json
+[
+  {
+    "place_id": "84271358",
+    "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
+    "osm_type": "way",
+    "osm_id": "50637691",
+    "lat": "52.39955055",
+    "lon": "13.04806574678",
+    "display_name": "Brandenburger Tor, Brandenburger Straße, Nördliche Innenstadt, Innenstadt, Potsdam, Brandenburg, 14467, Germany",
+    "class": "historic",
+    "type": "city_gate",
+    "importance": "0.221233780277011",
+    "address": {
+      "address29": "Brandenburger Tor",
+      "pedestrian": "Brandenburger Straße",
+      "suburb": "Nördliche Innenstadt",
+      "city": "Potsdam",
+      "state": "Brandenburg",
+      "postcode": "14467",
+      "country": "Germany",
+      "country_code": "de"
+    },
+    "extratags": {
+      "image": "http://commons.wikimedia.org/wiki/File:Potsdam_brandenburger_tor.jpg",
+      "wikidata": "Q695045",
+      "wikipedia": "de:Brandenburger Tor (Potsdam)",
+      "wheelchair": "yes",
+      "description": "Kleines Brandenburger Tor in Potsdam"
+    }
+  }
+]
+```
index 0c3c3d6500ca33a1597bd30c28b291daf9594439..ee8c3ea58c03c5daf0039bc71a7edf72f638bbc2 100644 (file)
@@ -7,9 +7,10 @@ Reverse geocoding generates an address from a latitude and longitude.  The optio
 https://nominatim.openstreetmap.org/reverse?<query>
 ```
 
-* `format=[xml|json|jsonv2]`
+* `format=[xml|json|jsonv2|geojson|geocodejson]`
 
-    * Output format.
+    * Output format
+    * defaults to `xml`
     * `jsonv2` adds the next fields to response:
         * `place_rank`
         * `category`
@@ -125,6 +126,105 @@ https://nominatim.openstreetmap.org/reverse?<query>
 }
 ```
 
+##### Example with `format=geojson`
+
+* [https://nominatim.openstreetmap.org/reverse?format=geojson&lat=44.50155&lon=11.33989](https://nominatim.openstreetmap.org/reverse?format=geojson&lat=44.50155&lon=11.33989)
+
+```json
+{
+  "type": "FeatureCollection",
+  "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {
+        "place_id": "18512203",
+        "osm_type": "node",
+        "osm_id": "1704756187",
+        "place_rank": "30",
+        "category": "place",
+        "type": "house",
+        "importance": "0",
+        "addresstype": "place",
+        "name": null,
+        "display_name": "71, Via Guglielmo Marconi, Saragozza-Porto, Bologna, BO, Emilia-Romagna, 40122, Italy",
+        "address": {
+          "house_number": "71",
+          "road": "Via Guglielmo Marconi",
+          "suburb": "Saragozza-Porto",
+          "city": "Bologna",
+          "county": "BO",
+          "state": "Emilia-Romagna",
+          "postcode": "40122",
+          "country": "Italy",
+          "country_code": "it"
+        }
+      },
+      "bbox": [
+        11.3397676,
+        44.5014307,
+        11.3399676,
+        44.5016307
+      ],
+      "geometry": {
+        "type": "Point",
+        "coordinates": [
+          11.3398676,
+          44.5015307
+        ]
+      }
+    }
+  ]
+}
+```
+
+##### Example with `format=geocodejson`
+
+[https://nominatim.openstreetmap.org/reverse?format=geocodejson&lat=60.2299&lon=11.1663](https://nominatim.openstreetmap.org/reverse?format=geocodejson&lat=60.2299&lon=11.1663)
+
+```json
+{
+  "type": "FeatureCollection",
+  "geocoding": {
+    "version": "0.1.0",
+    "attribution": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
+    "licence": "ODbL",
+    "query": "60.229917843587,11.16630979382"
+  },
+  "features": {
+    "type": "Feature",
+    "properties": {
+      "geocoding": {
+        "place_id": "42700574",
+        "osm_type": "node",
+        "osm_id": "3110596255",
+        "type": "house",
+        "accuracy": 0,
+        "label": "1, Løvenbergvegen, Mogreina, Ullensaker, Akershus, 2054, Norway",
+        "name": null,
+        "housenumber": "1",
+        "street": "Løvenbergvegen",
+        "postcode": "2054",
+        "county": "Akershus",
+        "country": "Norway",
+        "admin": {
+          "level7": "Ullensaker",
+          "level4": "Akershus",
+          "level2": "Norway"
+        }
+      }
+    },
+    "geometry": {
+      "type": "Point",
+      "coordinates": [
+        11.1658572,
+        60.2301296
+      ]
+    }
+  }
+}
+```
+
 ### Hierarchy
 
 * Admin level => XML entity
index 17e745877e74e3bbe707ad3cae54d5672fae6abf..e2c55fa59d8406f2716e8f1deb1c01ede4012e11 100644 (file)
@@ -20,7 +20,7 @@ Various keywords are translated into searches for specific osm tags (e.g. Pub =>
    https://nominatim.openstreetmap.org/search/<query>?<params>
 ```
 
-* `format=[html|xml|json|jsonv2]`
+* `format=[html|xml|json|jsonv2|geojson|geocodejson]`
 
     * Output format
     * defaults to `html`
@@ -121,9 +121,12 @@ Structured requests are faster and require fewer server resources. **Do not comb
 
 ### Examples
 
+
+##### XML with polygon points
+
 * [https://nominatim.openstreetmap.org/search?q=135+pilkington+avenue,+birmingham&format=xml&polygon=1&addressdetails=1](https://nominatim.openstreetmap.org/search?q=135+pilkington+avenue,+birmingham&format=xml&polygon=1&addressdetails=1)
-* [https://nominatim.openstreetmap.org/search/135%20pilkington%20avenue,%20birmingham?format=xml&polygon=1&addressdetails=1](https://nominatim.openstreetmap.org/search/135%20pilkington%20avenue,%20birmingham?format=xml&polygon=1&addressdetails=1)
 * [https://nominatim.openstreetmap.org/search/gb/birmingham/pilkington%20avenue/135?format=xml&polygon=1&addressdetails=1](https://nominatim.openstreetmap.org/search/gb/birmingham/pilkington%20avenue/135?format=xml&polygon=1&addressdetails=1)
+* [https://nominatim.openstreetmap.org/search/135%20pilkington%20avenue,%20birmingham?format=xml&polygon=1&addressdetails=1](https://nominatim.openstreetmap.org/search/135%20pilkington%20avenue,%20birmingham?format=xml&polygon=1&addressdetails=1)
 
 ```xml
   <searchresults timestamp="Sat, 07 Nov 09 14:42:10 +0000" querystring="135 pilkington, avenue birmingham" polygon="true">
@@ -147,7 +150,9 @@ Structured requests are faster and require fewer server resources. **Do not comb
   </searchresults>
 ```
 
-* [https://nominatim.openstreetmap.org/search/Unter%20den%20Linden%201%20Berlin?format=json&addressdetails=1&limit=1&polygon_svg=1](https://nominatim.openstreetmap.org/search/Unter%20den%20Linden%201%20Berlin?format=json&addressdetails=1&limit=1&polygon_svg=1)
+##### JSON with SVG polygon
+
+[https://nominatim.openstreetmap.org/search/Unter%20den%20Linden%201%20Berlin?format=json&addressdetails=1&limit=1&polygon_svg=1](https://nominatim.openstreetmap.org/search/Unter%20den%20Linden%201%20Berlin?format=json&addressdetails=1&limit=1&polygon_svg=1)
 
 ```json
     {
@@ -185,7 +190,9 @@ Structured requests are faster and require fewer server resources. **Do not comb
     }
 ```
 
-* [https://nominatim.openstreetmap.org/?format=json&addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1](https://nominatim.openstreetmap.org/?format=json&addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1)
+##### JSON with address details
+
+[https://nominatim.openstreetmap.org/?format=json&addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1](https://nominatim.openstreetmap.org/?format=json&addressdetails=1&q=bakery+in+berlin+wedding&format=json&limit=1)
 
 ```json
     {
@@ -220,3 +227,78 @@ Structured requests are faster and require fewer server resources. **Do not comb
         "type": "bakery"
     }
 ```
+
+##### GeoJSON
+
+[https://nominatim.openstreetmap.org/search?q=17+Strada+Pictor+Alexandru+Romano%2C+Bukarest&format=geojson](https://nominatim.openstreetmap.org/search?q=17+Strada+Pictor+Alexandru+Romano%2C+Bukarest&format=geojson)
+
+```json
+{
+  "type": "FeatureCollection",
+  "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {
+        "place_id": "35811445",
+        "osm_type": "node",
+        "osm_id": "2846295644",
+        "display_name": "17, Strada Pictor Alexandru Romano, Bukarest, Bucharest, Sector 2, Bucharest, 023964, Romania",
+        "place_rank": "30",
+        "category": "place",
+        "type": "house",
+        "importance": 0.62025
+      },
+      "bbox": [
+        26.1156689,
+        44.4354754,
+        26.1157689,
+        44.4355754
+      ],
+      "geometry": {
+        "type": "Point",
+        "coordinates": [
+          26.1157189,
+          44.4355254
+        ]
+      }
+    }
+  ]
+}
+```
+
+##### GeocodeJSON
+
+[https://nominatim.openstreetmap.org/search?q=%CE%91%CE%B3%CE%AF%CE%B1+%CE%A4%CF%81%CE%B9%CE%AC%CE%B4%CE%B1%2C+%CE%91%CE%B4%CF%89%CE%BD%CE%B9%CE%B4%CE%BF%CF%82%2C+Athens%2C+Greece&format=geocodejson](https://nominatim.openstreetmap.org/search?q=%CE%91%CE%B3%CE%AF%CE%B1+%CE%A4%CF%81%CE%B9%CE%AC%CE%B4%CE%B1%2C+%CE%91%CE%B4%CF%89%CE%BD%CE%B9%CE%B4%CE%BF%CF%82%2C+Athens%2C+Greece&format=geocodejson)
+
+```json
+{
+  "type": "FeatureCollection",
+  "geocoding": {
+    "version": "0.1.0",
+    "attribution": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
+    "licence": "ODbL",
+    "query": "Αγία Τριάδα, Αδωνιδος, Athens, Greece"
+  },
+  "features": [
+    {
+      "type": "Feature",
+      "properties": {
+        "geocoding": {
+          "type": "place_of_worship",
+          "label": "Αγία Τριάδα, Αδωνιδος, Άγιος Νικόλαος, 5º Δημοτικό Διαμέρισμα Αθηνών, Athens, Municipality of Athens, Regional Unit of Central Athens, Region of Attica, Attica, 11472, Greece",
+          "name": "Αγία Τριάδα",
+          "admin": null
+        }
+      },
+      "geometry": {
+        "type": "Point",
+        "coordinates": [
+          23.72949633941,
+          38.0051697
+        ]
+      }
+    }
+  ]
+}
+```
\ No newline at end of file
diff --git a/lib/AddressDetails.php b/lib/AddressDetails.php
new file mode 100644 (file)
index 0000000..8a4005d
--- /dev/null
@@ -0,0 +1,117 @@
+<?php
+
+namespace Nominatim;
+
+require_once(CONST_BasePath.'/lib/ClassTypes.php');
+
+/**
+ * Detailed list of address parts for a single result
+ */
+class AddressDetails
+{
+    private $aAddressLines;
+
+    public function __construct(&$oDB, $iPlaceID, $sHousenumber, $mLangPref)
+    {
+        if (is_array($mLangPref)) {
+            $mLangPref = 'ARRAY['.join(',', array_map('getDBQuoted', $mLangPref)).']';
+        }
+
+        if (!$sHousenumber) {
+            $sHousenumber = -1;
+        }
+
+        $sSQL = 'SELECT *,';
+        $sSQL .= '  get_name_by_language(name,'.$mLangPref.') as localname';
+        $sSQL .= ' FROM get_addressdata('.$iPlaceID.','.$sHousenumber.')';
+        $sSQL .= ' ORDER BY rank_address desc,isaddress DESC';
+
+        $this->aAddressLines = chksql($oDB->getAll($sSQL));
+    }
+
+    private static function isAddress($aLine)
+    {
+        return $aLine['isaddress'] == 't' || $aLine['type'] == 'country_code';
+    }
+
+    public function getAddressDetails($bAll = false)
+    {
+        if ($bAll) {
+            return $this->aAddressLines;
+        }
+
+        return array_filter($this->aAddressLines, 'AddressDetails::isAddress');
+    }
+
+    public function getLocaleAddress()
+    {
+        $aParts = array();
+        $sPrevResult = '';
+
+        foreach ($this->aAddressLines as $aLine) {
+            if ($aLine['isaddress'] == 't' && $sPrevResult != $aLine['localname']) {
+                $sPrevResult = $aLine['localname'];
+                $aParts[] = $sPrevResult;
+            }
+        }
+
+        return join(', ', $aParts);
+    }
+
+    public function getAddressNames()
+    {
+        $aAddress = array();
+        $aFallback = array();
+
+        foreach ($this->aAddressLines as $aLine) {
+            if (!self::isAddress($aLine)) {
+                continue;
+            }
+
+            $bFallback = false;
+            $aTypeLabel = ClassTypes\getInfo($aLine);
+
+            if ($aTypeLabel === false) {
+                $aTypeLabel = ClassTypes\getFallbackInfo($aLine);
+                $bFallback = true;
+            }
+
+            $sName = false;
+            if (isset($aLine['localname']) && $aLine['localname']) {
+                $sName = $aLine['localname'];
+            } elseif (isset($aLine['housenumber']) && $aLine['housenumber']) {
+                $sName = $aLine['housenumber'];
+            }
+
+            if ($sName) {
+                $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel']) ? $aTypeLabel['simplelabel'] : $aTypeLabel['label']);
+                $sTypeLabel = str_replace(' ', '_', $sTypeLabel);
+                if (!isset($aAddress[$sTypeLabel])
+                    || isset($aFallback[$sTypeLabel])
+                    || $aLine['class'] == 'place'
+                ) {
+                    $aAddress[$sTypeLabel] = $sName;
+                    if ($bFallback) {
+                        $aFallback[$sTypeLabel] = $bFallback;
+                    }
+                }
+            }
+        }
+        return $aAddress;
+    }
+
+    public function getAdminLevels()
+    {
+        $aAddress = array();
+        foreach ($this->aAddressLines as $aLine) {
+            if (self::isAddress($aLine)
+                && isset($aLine['admin_level'])
+                && $aLine['admin_level'] < 15
+                && !isset($aAddress['level'.$aLine['admin_level']])
+            ) {
+                $aAddress['level'.$aLine['admin_level']] = $aLine['localname'];
+            }
+        }
+        return $aAddress;
+    }
+}
diff --git a/lib/ClassTypes.php b/lib/ClassTypes.php
new file mode 100644 (file)
index 0000000..c56e514
--- /dev/null
@@ -0,0 +1,374 @@
+<?php
+
+namespace Nominatim\ClassTypes;
+
+function getInfo($aPlace)
+{
+    $aClassType = getList();
+
+    if (isset($aPlace['admin_level'])) {
+        $sName = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
+        if (isset($aClassType[$sName])) {
+            return $aClassType[$sName];
+        }
+    }
+
+    $sName = $aPlace['class'].':'.$aPlace['type'];
+    if (isset($aClassType[$sName])) {
+        return $aClassType[$sName];
+    }
+
+    return false;
+}
+
+function getFallbackInfo($aPlace)
+{
+    $aClassType = getList();
+
+    $sFallback = 'boundary:administrative:'.((int)($aPlace['rank_address']/2));
+    if (isset($aClassType[$sFallback])) {
+        return $aClassType[$sFallback];
+    }
+
+    return array('simplelabel' => 'address'.$aPlace['rank_address']);
+}
+
+function getProperty($aPlace, $sProp, $mDefault = false)
+{
+    $aClassType = getList();
+
+    if (isset($aPlace['admin_level'])) {
+        $sName = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
+        if (isset($aClassType[$sName]) && isset($aClassType[$sName][$sProp])) {
+            return $aClassType[$sName][$sProp];
+        }
+    }
+
+    $sName = $aPlace['class'].':'.$aPlace['type'];
+    if (isset($aClassType[$sName]) && isset($aClassType[$sName][$sProp])) {
+        return $aClassType[$sName][$sProp];
+    }
+
+    return $mDefault;
+}
+
+function getListWithImportance()
+{
+    static $aOrders = null;
+    if ($aOrders === null) {
+        $aOrders = getList();
+        $i = 1;
+        foreach ($aOrders as $sID => $a) {
+            $aOrders[$sID]['importance'] = $i++;
+        }
+    }
+
+    return $aOrders;
+}
+
+function getList()
+{
+    return array(
+            'boundary:administrative:1' => array('label' => 'Continent', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:2' => array('label' => 'Country', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:country' => array('label' => 'Country', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 6, 'defdiameter' => 15),
+            'boundary:administrative:3' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:4' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:state' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 8, 'defdiameter' => 5.12),
+            'boundary:administrative:5' => array('label' => 'State District', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:6' => array('label' => 'County', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:7' => array('label' => 'County', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:county' => array('label' => 'County', 'frequency' => 108, 'icon' => 'poi_boundary_administrative', 'defzoom' => 10, 'defdiameter' => 1.28),
+            'boundary:administrative:8' => array('label' => 'City', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:city' => array('label' => 'City', 'frequency' => 66, 'icon' => 'poi_place_city', 'defzoom' => 12, 'defdiameter' => 0.32),
+            'boundary:administrative:9' => array('label' => 'City District', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:10' => array('label' => 'Suburb', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:administrative:11' => array('label' => 'Neighbourhood', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:region' => array('label' => 'Region', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 8, 'defdiameter' => 0.04),
+            'place:island' => array('label' => 'Island', 'frequency' => 288, 'icon' => '', 'defzoom' => 11, 'defdiameter' => 0.64),
+            'boundary:administrative' => array('label' => 'Administrative', 'frequency' => 413, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'boundary:postal_code' => array('label' => 'Postcode', 'frequency' => 413, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
+            'place:town' => array('label' => 'Town', 'frequency' => 1497, 'icon' => 'poi_place_town', 'defzoom' => 14, 'defdiameter' => 0.08),
+            'place:village' => array('label' => 'Village', 'frequency' => 11230, 'icon' => 'poi_place_village', 'defzoom' => 15, 'defdiameter' => 0.04),
+            'place:hamlet' => array('label' => 'Hamlet', 'frequency' => 7075, 'icon' => 'poi_place_village', 'defzoom' => 15, 'defdiameter' => 0.04),
+            'place:suburb' => array('label' => 'Suburb', 'frequency' => 2528, 'icon' => 'poi_place_village', 'defdiameter' => 0.04),
+            'place:locality' => array('label' => 'Locality', 'frequency' => 4113, 'icon' => 'poi_place_village', 'defdiameter' => 0.02),
+            'landuse:farm' => array('label' => 'Farm', 'frequency' => 1201, 'icon' => '', 'defdiameter' => 0.02),
+            'place:farm' => array('label' => 'Farm', 'frequency' => 1162, 'icon' => '', 'defdiameter' => 0.02),
+
+            'highway:motorway_junction' => array('label' => 'Motorway Junction', 'frequency' => 1126, 'icon' => '', 'simplelabel' => 'Junction'),
+            'highway:motorway' => array('label' => 'Motorway', 'frequency' => 4627, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:trunk' => array('label' => 'Trunk', 'frequency' => 23084, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:primary' => array('label' => 'Primary', 'frequency' => 32138, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:secondary' => array('label' => 'Secondary', 'frequency' => 25807, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:tertiary' => array('label' => 'Tertiary', 'frequency' => 29829, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:residential' => array('label' => 'Residential', 'frequency' => 361498, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:unclassified' => array('label' => 'Unclassified', 'frequency' => 66441, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:living_street' => array('label' => 'Living Street', 'frequency' => 710, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:service' => array('label' => 'Service', 'frequency' => 9963, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:track' => array('label' => 'Track', 'frequency' => 2565, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:road' => array('label' => 'Road', 'frequency' => 591, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:byway' => array('label' => 'Byway', 'frequency' => 346, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:bridleway' => array('label' => 'Bridleway', 'frequency' => 1556, 'icon' => ''),
+            'highway:cycleway' => array('label' => 'Cycleway', 'frequency' => 2419, 'icon' => ''),
+            'highway:pedestrian' => array('label' => 'Pedestrian', 'frequency' => 2757, 'icon' => ''),
+            'highway:footway' => array('label' => 'Footway', 'frequency' => 15008, 'icon' => ''),
+            'highway:steps' => array('label' => 'Steps', 'frequency' => 444, 'icon' => '', 'simplelabel' => 'Footway'),
+            'highway:motorway_link' => array('label' => 'Motorway Link', 'frequency' => 795, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:trunk_link' => array('label' => 'Trunk Link', 'frequency' => 1258, 'icon' => '', 'simplelabel' => 'Road'),
+            'highway:primary_link' => array('label' => 'Primary Link', 'frequency' => 313, 'icon' => '', 'simplelabel' => 'Road'),
+
+            'landuse:industrial' => array('label' => 'Industrial', 'frequency' => 1062, 'icon' => ''),
+            'landuse:residential' => array('label' => 'Residential', 'frequency' => 886, 'icon' => ''),
+            'landuse:retail' => array('label' => 'Retail', 'frequency' => 754, 'icon' => ''),
+            'landuse:commercial' => array('label' => 'Commercial', 'frequency' => 657, 'icon' => ''),
+
+            'place:airport' => array('label' => 'Airport', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
+            'aeroway:aerodrome' => array('label' => 'Aerodrome', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
+            'aeroway' => array('label' => 'Aeroway', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
+            'railway:station' => array('label' => 'Station', 'frequency' => 3431, 'icon' => 'transport_train_station2', 'defdiameter' => 0.01),
+            'amenity:place_of_worship' => array('label' => 'Place Of Worship', 'frequency' => 9049, 'icon' => 'place_of_worship_unknown3'),
+            'amenity:pub' => array('label' => 'Pub', 'frequency' => 18969, 'icon' => 'food_pub'),
+            'amenity:bar' => array('label' => 'Bar', 'frequency' => 164, 'icon' => 'food_bar'),
+            'amenity:university' => array('label' => 'University', 'frequency' => 607, 'icon' => 'education_university'),
+            'tourism:museum' => array('label' => 'Museum', 'frequency' => 543, 'icon' => 'tourist_museum'),
+            'amenity:arts_centre' => array('label' => 'Arts Centre', 'frequency' => 136, 'icon' => 'tourist_art_gallery2'),
+            'tourism:zoo' => array('label' => 'Zoo', 'frequency' => 47, 'icon' => 'tourist_zoo'),
+            'tourism:theme_park' => array('label' => 'Theme Park', 'frequency' => 24, 'icon' => 'poi_point_of_interest'),
+            'tourism:attraction' => array('label' => 'Attraction', 'frequency' => 1463, 'icon' => 'poi_point_of_interest'),
+            'leisure:golf_course' => array('label' => 'Golf Course', 'frequency' => 712, 'icon' => 'sport_golf'),
+            'historic:castle' => array('label' => 'Castle', 'frequency' => 316, 'icon' => 'tourist_castle'),
+            'amenity:hospital' => array('label' => 'Hospital', 'frequency' => 879, 'icon' => 'health_hospital'),
+            'amenity:school' => array('label' => 'School', 'frequency' => 8192, 'icon' => 'education_school'),
+            'amenity:theatre' => array('label' => 'Theatre', 'frequency' => 371, 'icon' => 'tourist_theatre'),
+            'amenity:public_building' => array('label' => 'Public Building', 'frequency' => 985, 'icon' => ''),
+            'amenity:library' => array('label' => 'Library', 'frequency' => 794, 'icon' => 'amenity_library'),
+            'amenity:townhall' => array('label' => 'Townhall', 'frequency' => 242, 'icon' => ''),
+            'amenity:community_centre' => array('label' => 'Community Centre', 'frequency' => 157, 'icon' => ''),
+            'amenity:fire_station' => array('label' => 'Fire Station', 'frequency' => 221, 'icon' => 'amenity_firestation3'),
+            'amenity:police' => array('label' => 'Police', 'frequency' => 334, 'icon' => 'amenity_police2'),
+            'amenity:bank' => array('label' => 'Bank', 'frequency' => 1248, 'icon' => 'money_bank2'),
+            'amenity:post_office' => array('label' => 'Post Office', 'frequency' => 859, 'icon' => 'amenity_post_office'),
+            'leisure:park' => array('label' => 'Park', 'frequency' => 2378, 'icon' => ''),
+            'amenity:park' => array('label' => 'Park', 'frequency' => 53, 'icon' => ''),
+            'landuse:park' => array('label' => 'Park', 'frequency' => 50, 'icon' => ''),
+            'landuse:recreation_ground' => array('label' => 'Recreation Ground', 'frequency' => 517, 'icon' => ''),
+            'tourism:hotel' => array('label' => 'Hotel', 'frequency' => 2150, 'icon' => 'accommodation_hotel2'),
+            'tourism:motel' => array('label' => 'Motel', 'frequency' => 43, 'icon' => ''),
+            'amenity:cinema' => array('label' => 'Cinema', 'frequency' => 277, 'icon' => 'tourist_cinema'),
+            'tourism:artwork' => array('label' => 'Artwork', 'frequency' => 171, 'icon' => 'tourist_art_gallery2'),
+            'historic:archaeological_site' => array('label' => 'Archaeological Site', 'frequency' => 407, 'icon' => 'tourist_archaeological2'),
+            'amenity:doctors' => array('label' => 'Doctors', 'frequency' => 581, 'icon' => 'health_doctors'),
+            'leisure:sports_centre' => array('label' => 'Sports Centre', 'frequency' => 767, 'icon' => 'sport_leisure_centre'),
+            'leisure:swimming_pool' => array('label' => 'Swimming Pool', 'frequency' => 24, 'icon' => 'sport_swimming_outdoor'),
+            'shop:supermarket' => array('label' => 'Supermarket', 'frequency' => 2673, 'icon' => 'shopping_supermarket'),
+            'shop:convenience' => array('label' => 'Convenience', 'frequency' => 1469, 'icon' => 'shopping_convenience'),
+            'amenity:restaurant' => array('label' => 'Restaurant', 'frequency' => 3179, 'icon' => 'food_restaurant'),
+            'amenity:fast_food' => array('label' => 'Fast Food', 'frequency' => 2289, 'icon' => 'food_fastfood'),
+            'amenity:cafe' => array('label' => 'Cafe', 'frequency' => 1780, 'icon' => 'food_cafe'),
+            'tourism:guest_house' => array('label' => 'Guest House', 'frequency' => 223, 'icon' => 'accommodation_bed_and_breakfast'),
+            'amenity:pharmacy' => array('label' => 'Pharmacy', 'frequency' => 733, 'icon' => 'health_pharmacy_dispensing'),
+            'amenity:fuel' => array('label' => 'Fuel', 'frequency' => 1308, 'icon' => 'transport_fuel'),
+            'natural:peak' => array('label' => 'Peak', 'frequency' => 3212, 'icon' => 'poi_peak'),
+            'waterway:waterfall' => array('label' => 'Waterfall', 'frequency' => 24, 'icon' => ''),
+            'natural:wood' => array('label' => 'Wood', 'frequency' => 1845, 'icon' => 'landuse_coniferous_and_deciduous'),
+            'natural:water' => array('label' => 'Water', 'frequency' => 1790, 'icon' => ''),
+            'landuse:forest' => array('label' => 'Forest', 'frequency' => 467, 'icon' => ''),
+            'landuse:cemetery' => array('label' => 'Cemetery', 'frequency' => 463, 'icon' => ''),
+            'landuse:allotments' => array('label' => 'Allotments', 'frequency' => 408, 'icon' => ''),
+            'landuse:farmyard' => array('label' => 'Farmyard', 'frequency' => 397, 'icon' => ''),
+            'railway:rail' => array('label' => 'Rail', 'frequency' => 4894, 'icon' => ''),
+            'waterway:canal' => array('label' => 'Canal', 'frequency' => 1723, 'icon' => ''),
+            'waterway:river' => array('label' => 'River', 'frequency' => 4089, 'icon' => ''),
+            'waterway:stream' => array('label' => 'Stream', 'frequency' => 2684, 'icon' => ''),
+            'shop:bicycle' => array('label' => 'Bicycle', 'frequency' => 349, 'icon' => 'shopping_bicycle'),
+            'shop:clothes' => array('label' => 'Clothes', 'frequency' => 315, 'icon' => 'shopping_clothes'),
+            'shop:hairdresser' => array('label' => 'Hairdresser', 'frequency' => 312, 'icon' => 'shopping_hairdresser'),
+            'shop:doityourself' => array('label' => 'Doityourself', 'frequency' => 247, 'icon' => 'shopping_diy'),
+            'shop:estate_agent' => array('label' => 'Estate Agent', 'frequency' => 162, 'icon' => 'shopping_estateagent2'),
+            'shop:car' => array('label' => 'Car', 'frequency' => 159, 'icon' => 'shopping_car'),
+            'shop:garden_centre' => array('label' => 'Garden Centre', 'frequency' => 143, 'icon' => 'shopping_garden_centre'),
+            'shop:car_repair' => array('label' => 'Car Repair', 'frequency' => 141, 'icon' => 'shopping_car_repair'),
+            'shop:newsagent' => array('label' => 'Newsagent', 'frequency' => 132, 'icon' => ''),
+            'shop:bakery' => array('label' => 'Bakery', 'frequency' => 129, 'icon' => 'shopping_bakery'),
+            'shop:furniture' => array('label' => 'Furniture', 'frequency' => 124, 'icon' => ''),
+            'shop:butcher' => array('label' => 'Butcher', 'frequency' => 105, 'icon' => 'shopping_butcher'),
+            'shop:apparel' => array('label' => 'Apparel', 'frequency' => 98, 'icon' => 'shopping_clothes'),
+            'shop:electronics' => array('label' => 'Electronics', 'frequency' => 96, 'icon' => ''),
+            'shop:department_store' => array('label' => 'Department Store', 'frequency' => 86, 'icon' => ''),
+            'shop:books' => array('label' => 'Books', 'frequency' => 85, 'icon' => ''),
+            'shop:yes' => array('label' => 'Shop', 'frequency' => 68, 'icon' => ''),
+            'shop:outdoor' => array('label' => 'Outdoor', 'frequency' => 67, 'icon' => ''),
+            'shop:mall' => array('label' => 'Mall', 'frequency' => 63, 'icon' => ''),
+            'shop:florist' => array('label' => 'Florist', 'frequency' => 61, 'icon' => ''),
+            'shop:charity' => array('label' => 'Charity', 'frequency' => 60, 'icon' => ''),
+            'shop:hardware' => array('label' => 'Hardware', 'frequency' => 59, 'icon' => ''),
+            'shop:laundry' => array('label' => 'Laundry', 'frequency' => 51, 'icon' => 'shopping_laundrette'),
+            'shop:shoes' => array('label' => 'Shoes', 'frequency' => 49, 'icon' => ''),
+            'shop:beverages' => array('label' => 'Beverages', 'frequency' => 48, 'icon' => 'shopping_alcohol'),
+            'shop:dry_cleaning' => array('label' => 'Dry Cleaning', 'frequency' => 46, 'icon' => ''),
+            'shop:carpet' => array('label' => 'Carpet', 'frequency' => 45, 'icon' => ''),
+            'shop:computer' => array('label' => 'Computer', 'frequency' => 44, 'icon' => ''),
+            'shop:alcohol' => array('label' => 'Alcohol', 'frequency' => 44, 'icon' => 'shopping_alcohol'),
+            'shop:optician' => array('label' => 'Optician', 'frequency' => 55, 'icon' => 'health_opticians'),
+            'shop:chemist' => array('label' => 'Chemist', 'frequency' => 42, 'icon' => 'health_pharmacy'),
+            'shop:gallery' => array('label' => 'Gallery', 'frequency' => 38, 'icon' => 'tourist_art_gallery2'),
+            'shop:mobile_phone' => array('label' => 'Mobile Phone', 'frequency' => 37, 'icon' => ''),
+            'shop:sports' => array('label' => 'Sports', 'frequency' => 37, 'icon' => ''),
+            'shop:jewelry' => array('label' => 'Jewelry', 'frequency' => 32, 'icon' => 'shopping_jewelry'),
+            'shop:pet' => array('label' => 'Pet', 'frequency' => 29, 'icon' => ''),
+            'shop:beauty' => array('label' => 'Beauty', 'frequency' => 28, 'icon' => ''),
+            'shop:stationery' => array('label' => 'Stationery', 'frequency' => 25, 'icon' => ''),
+            'shop:shopping_centre' => array('label' => 'Shopping Centre', 'frequency' => 25, 'icon' => ''),
+            'shop:general' => array('label' => 'General', 'frequency' => 25, 'icon' => ''),
+            'shop:electrical' => array('label' => 'Electrical', 'frequency' => 25, 'icon' => ''),
+            'shop:toys' => array('label' => 'Toys', 'frequency' => 23, 'icon' => ''),
+            'shop:jeweller' => array('label' => 'Jeweller', 'frequency' => 23, 'icon' => ''),
+            'shop:betting' => array('label' => 'Betting', 'frequency' => 23, 'icon' => ''),
+            'shop:household' => array('label' => 'Household', 'frequency' => 21, 'icon' => ''),
+            'shop:travel_agency' => array('label' => 'Travel Agency', 'frequency' => 21, 'icon' => ''),
+            'shop:hifi' => array('label' => 'Hifi', 'frequency' => 21, 'icon' => ''),
+            'amenity:shop' => array('label' => 'Shop', 'frequency' => 61, 'icon' => ''),
+            'tourism:information' => array('label' => 'Information', 'frequency' => 224, 'icon' => 'amenity_information'),
+
+            'place:house' => array('label' => 'House', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
+            'place:house_name' => array('label' => 'House', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
+            'place:house_number' => array('label' => 'House Number', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
+            'place:country_code' => array('label' => 'Country Code', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
+
+            //
+
+            'leisure:pitch' => array('label' => 'Pitch', 'frequency' => 762, 'icon' => ''),
+            'highway:unsurfaced' => array('label' => 'Unsurfaced', 'frequency' => 492, 'icon' => ''),
+            'historic:ruins' => array('label' => 'Ruins', 'frequency' => 483, 'icon' => 'tourist_ruin'),
+            'amenity:college' => array('label' => 'College', 'frequency' => 473, 'icon' => 'education_school'),
+            'historic:monument' => array('label' => 'Monument', 'frequency' => 470, 'icon' => 'tourist_monument'),
+            'railway:subway' => array('label' => 'Subway', 'frequency' => 385, 'icon' => ''),
+            'historic:memorial' => array('label' => 'Memorial', 'frequency' => 382, 'icon' => 'tourist_monument'),
+            'leisure:nature_reserve' => array('label' => 'Nature Reserve', 'frequency' => 342, 'icon' => ''),
+            'leisure:common' => array('label' => 'Common', 'frequency' => 322, 'icon' => ''),
+            'waterway:lock_gate' => array('label' => 'Lock Gate', 'frequency' => 321, 'icon' => ''),
+            'natural:fell' => array('label' => 'Fell', 'frequency' => 308, 'icon' => ''),
+            'amenity:nightclub' => array('label' => 'Nightclub', 'frequency' => 292, 'icon' => ''),
+            'highway:path' => array('label' => 'Path', 'frequency' => 287, 'icon' => ''),
+            'leisure:garden' => array('label' => 'Garden', 'frequency' => 285, 'icon' => ''),
+            'landuse:reservoir' => array('label' => 'Reservoir', 'frequency' => 276, 'icon' => ''),
+            'leisure:playground' => array('label' => 'Playground', 'frequency' => 264, 'icon' => ''),
+            'leisure:stadium' => array('label' => 'Stadium', 'frequency' => 212, 'icon' => ''),
+            'historic:mine' => array('label' => 'Mine', 'frequency' => 193, 'icon' => 'poi_mine'),
+            'natural:cliff' => array('label' => 'Cliff', 'frequency' => 193, 'icon' => ''),
+            'tourism:caravan_site' => array('label' => 'Caravan Site', 'frequency' => 183, 'icon' => 'accommodation_caravan_park'),
+            'amenity:bus_station' => array('label' => 'Bus Station', 'frequency' => 181, 'icon' => 'transport_bus_station'),
+            'amenity:kindergarten' => array('label' => 'Kindergarten', 'frequency' => 179, 'icon' => ''),
+            'highway:construction' => array('label' => 'Construction', 'frequency' => 176, 'icon' => ''),
+            'amenity:atm' => array('label' => 'Atm', 'frequency' => 172, 'icon' => 'money_atm2'),
+            'amenity:emergency_phone' => array('label' => 'Emergency Phone', 'frequency' => 164, 'icon' => ''),
+            'waterway:lock' => array('label' => 'Lock', 'frequency' => 146, 'icon' => ''),
+            'waterway:riverbank' => array('label' => 'Riverbank', 'frequency' => 143, 'icon' => ''),
+            'natural:coastline' => array('label' => 'Coastline', 'frequency' => 142, 'icon' => ''),
+            'tourism:viewpoint' => array('label' => 'Viewpoint', 'frequency' => 140, 'icon' => 'tourist_view_point'),
+            'tourism:hostel' => array('label' => 'Hostel', 'frequency' => 140, 'icon' => ''),
+            'tourism:bed_and_breakfast' => array('label' => 'Bed And Breakfast', 'frequency' => 140, 'icon' => 'accommodation_bed_and_breakfast'),
+            'railway:halt' => array('label' => 'Halt', 'frequency' => 135, 'icon' => ''),
+            'railway:platform' => array('label' => 'Platform', 'frequency' => 134, 'icon' => ''),
+            'railway:tram' => array('label' => 'Tram', 'frequency' => 130, 'icon' => 'transport_tram_stop'),
+            'amenity:courthouse' => array('label' => 'Courthouse', 'frequency' => 129, 'icon' => 'amenity_court'),
+            'amenity:recycling' => array('label' => 'Recycling', 'frequency' => 126, 'icon' => 'amenity_recycling'),
+            'amenity:dentist' => array('label' => 'Dentist', 'frequency' => 124, 'icon' => 'health_dentist'),
+            'natural:beach' => array('label' => 'Beach', 'frequency' => 121, 'icon' => 'tourist_beach'),
+            'place:moor' => array('label' => 'Moor', 'frequency' => 118, 'icon' => ''),
+            'amenity:grave_yard' => array('label' => 'Grave Yard', 'frequency' => 110, 'icon' => ''),
+            'waterway:drain' => array('label' => 'Drain', 'frequency' => 108, 'icon' => ''),
+            'landuse:grass' => array('label' => 'Grass', 'frequency' => 106, 'icon' => ''),
+            'landuse:village_green' => array('label' => 'Village Green', 'frequency' => 106, 'icon' => ''),
+            'natural:bay' => array('label' => 'Bay', 'frequency' => 102, 'icon' => ''),
+            'railway:tram_stop' => array('label' => 'Tram Stop', 'frequency' => 101, 'icon' => 'transport_tram_stop'),
+            'leisure:marina' => array('label' => 'Marina', 'frequency' => 98, 'icon' => ''),
+            'highway:stile' => array('label' => 'Stile', 'frequency' => 97, 'icon' => ''),
+            'natural:moor' => array('label' => 'Moor', 'frequency' => 95, 'icon' => ''),
+            'railway:light_rail' => array('label' => 'Light Rail', 'frequency' => 91, 'icon' => ''),
+            'railway:narrow_gauge' => array('label' => 'Narrow Gauge', 'frequency' => 90, 'icon' => ''),
+            'natural:land' => array('label' => 'Land', 'frequency' => 86, 'icon' => ''),
+            'amenity:village_hall' => array('label' => 'Village Hall', 'frequency' => 82, 'icon' => ''),
+            'waterway:dock' => array('label' => 'Dock', 'frequency' => 80, 'icon' => ''),
+            'amenity:veterinary' => array('label' => 'Veterinary', 'frequency' => 79, 'icon' => ''),
+            'landuse:brownfield' => array('label' => 'Brownfield', 'frequency' => 77, 'icon' => ''),
+            'leisure:track' => array('label' => 'Track', 'frequency' => 76, 'icon' => ''),
+            'railway:historic_station' => array('label' => 'Historic Station', 'frequency' => 74, 'icon' => ''),
+            'landuse:construction' => array('label' => 'Construction', 'frequency' => 72, 'icon' => ''),
+            'amenity:prison' => array('label' => 'Prison', 'frequency' => 71, 'icon' => 'amenity_prison'),
+            'landuse:quarry' => array('label' => 'Quarry', 'frequency' => 71, 'icon' => ''),
+            'amenity:telephone' => array('label' => 'Telephone', 'frequency' => 70, 'icon' => ''),
+            'highway:traffic_signals' => array('label' => 'Traffic Signals', 'frequency' => 66, 'icon' => ''),
+            'natural:heath' => array('label' => 'Heath', 'frequency' => 62, 'icon' => ''),
+            'historic:house' => array('label' => 'House', 'frequency' => 61, 'icon' => ''),
+            'amenity:social_club' => array('label' => 'Social Club', 'frequency' => 61, 'icon' => ''),
+            'landuse:military' => array('label' => 'Military', 'frequency' => 61, 'icon' => ''),
+            'amenity:health_centre' => array('label' => 'Health Centre', 'frequency' => 59, 'icon' => ''),
+            'historic:building' => array('label' => 'Building', 'frequency' => 58, 'icon' => ''),
+            'amenity:clinic' => array('label' => 'Clinic', 'frequency' => 57, 'icon' => ''),
+            'highway:services' => array('label' => 'Services', 'frequency' => 56, 'icon' => ''),
+            'amenity:ferry_terminal' => array('label' => 'Ferry Terminal', 'frequency' => 55, 'icon' => ''),
+            'natural:marsh' => array('label' => 'Marsh', 'frequency' => 55, 'icon' => ''),
+            'natural:hill' => array('label' => 'Hill', 'frequency' => 54, 'icon' => ''),
+            'highway:raceway' => array('label' => 'Raceway', 'frequency' => 53, 'icon' => ''),
+            'amenity:taxi' => array('label' => 'Taxi', 'frequency' => 47, 'icon' => ''),
+            'amenity:take_away' => array('label' => 'Take Away', 'frequency' => 45, 'icon' => ''),
+            'amenity:car_rental' => array('label' => 'Car Rental', 'frequency' => 44, 'icon' => ''),
+            'place:islet' => array('label' => 'Islet', 'frequency' => 44, 'icon' => ''),
+            'amenity:nursery' => array('label' => 'Nursery', 'frequency' => 44, 'icon' => ''),
+            'amenity:nursing_home' => array('label' => 'Nursing Home', 'frequency' => 43, 'icon' => ''),
+            'amenity:toilets' => array('label' => 'Toilets', 'frequency' => 38, 'icon' => ''),
+            'amenity:hall' => array('label' => 'Hall', 'frequency' => 38, 'icon' => ''),
+            'waterway:boatyard' => array('label' => 'Boatyard', 'frequency' => 36, 'icon' => ''),
+            'highway:mini_roundabout' => array('label' => 'Mini Roundabout', 'frequency' => 35, 'icon' => ''),
+            'historic:manor' => array('label' => 'Manor', 'frequency' => 35, 'icon' => ''),
+            'tourism:chalet' => array('label' => 'Chalet', 'frequency' => 34, 'icon' => ''),
+            'amenity:bicycle_parking' => array('label' => 'Bicycle Parking', 'frequency' => 34, 'icon' => ''),
+            'amenity:hotel' => array('label' => 'Hotel', 'frequency' => 34, 'icon' => ''),
+            'waterway:weir' => array('label' => 'Weir', 'frequency' => 33, 'icon' => ''),
+            'natural:wetland' => array('label' => 'Wetland', 'frequency' => 33, 'icon' => ''),
+            'natural:cave_entrance' => array('label' => 'Cave Entrance', 'frequency' => 32, 'icon' => ''),
+            'amenity:crematorium' => array('label' => 'Crematorium', 'frequency' => 31, 'icon' => ''),
+            'tourism:picnic_site' => array('label' => 'Picnic Site', 'frequency' => 31, 'icon' => ''),
+            'landuse:wood' => array('label' => 'Wood', 'frequency' => 30, 'icon' => ''),
+            'landuse:basin' => array('label' => 'Basin', 'frequency' => 30, 'icon' => ''),
+            'natural:tree' => array('label' => 'Tree', 'frequency' => 30, 'icon' => ''),
+            'leisure:slipway' => array('label' => 'Slipway', 'frequency' => 29, 'icon' => ''),
+            'landuse:meadow' => array('label' => 'Meadow', 'frequency' => 29, 'icon' => ''),
+            'landuse:piste' => array('label' => 'Piste', 'frequency' => 28, 'icon' => ''),
+            'amenity:care_home' => array('label' => 'Care Home', 'frequency' => 28, 'icon' => ''),
+            'amenity:club' => array('label' => 'Club', 'frequency' => 28, 'icon' => ''),
+            'amenity:medical_centre' => array('label' => 'Medical Centre', 'frequency' => 27, 'icon' => ''),
+            'historic:roman_road' => array('label' => 'Roman Road', 'frequency' => 27, 'icon' => ''),
+            'historic:fort' => array('label' => 'Fort', 'frequency' => 26, 'icon' => ''),
+            'railway:subway_entrance' => array('label' => 'Subway Entrance', 'frequency' => 26, 'icon' => ''),
+            'historic:yes' => array('label' => 'Historic', 'frequency' => 25, 'icon' => ''),
+            'highway:gate' => array('label' => 'Gate', 'frequency' => 25, 'icon' => ''),
+            'leisure:fishing' => array('label' => 'Fishing', 'frequency' => 24, 'icon' => ''),
+            'historic:museum' => array('label' => 'Museum', 'frequency' => 24, 'icon' => ''),
+            'amenity:car_wash' => array('label' => 'Car Wash', 'frequency' => 24, 'icon' => ''),
+            'railway:level_crossing' => array('label' => 'Level Crossing', 'frequency' => 23, 'icon' => ''),
+            'leisure:bird_hide' => array('label' => 'Bird Hide', 'frequency' => 23, 'icon' => ''),
+            'natural:headland' => array('label' => 'Headland', 'frequency' => 21, 'icon' => ''),
+            'tourism:apartments' => array('label' => 'Apartments', 'frequency' => 21, 'icon' => ''),
+            'amenity:shopping' => array('label' => 'Shopping', 'frequency' => 21, 'icon' => ''),
+            'natural:scrub' => array('label' => 'Scrub', 'frequency' => 20, 'icon' => ''),
+            'natural:fen' => array('label' => 'Fen', 'frequency' => 20, 'icon' => ''),
+            'building:yes' => array('label' => 'Building', 'frequency' => 200, 'icon' => ''),
+            'mountain_pass:yes' => array('label' => 'Mountain Pass', 'frequency' => 200, 'icon' => ''),
+
+            'amenity:parking' => array('label' => 'Parking', 'frequency' => 3157, 'icon' => ''),
+            'highway:bus_stop' => array('label' => 'Bus Stop', 'frequency' => 35777, 'icon' => 'transport_bus_stop2'),
+            'place:postcode' => array('label' => 'Postcode', 'frequency' => 27267, 'icon' => ''),
+            'amenity:post_box' => array('label' => 'Post Box', 'frequency' => 9613, 'icon' => ''),
+
+            'place:houses' => array('label' => 'Houses', 'frequency' => 85, 'icon' => ''),
+            'railway:preserved' => array('label' => 'Preserved', 'frequency' => 227, 'icon' => ''),
+            'waterway:derelict_canal' => array('label' => 'Derelict Canal', 'frequency' => 21, 'icon' => ''),
+            'amenity:dead_pub' => array('label' => 'Dead Pub', 'frequency' => 20, 'icon' => ''),
+            'railway:disused_station' => array('label' => 'Disused Station', 'frequency' => 114, 'icon' => ''),
+            'railway:abandoned' => array('label' => 'Abandoned', 'frequency' => 641, 'icon' => ''),
+            'railway:disused' => array('label' => 'Disused', 'frequency' => 72, 'icon' => ''),
+           );
+}
index acd2f76cca713e6c1ab98f79deae0972dee3587e..598306235867e8afc7137241ef265f4353f321d9 100644 (file)
@@ -17,8 +17,6 @@ class Geocode
 
     protected $aLangPrefOrder = array();
 
-    protected $bIncludeAddressDetails = false;
-
     protected $aExcludePlaceIDs = array();
     protected $bReverseInPlan = true;
 
@@ -87,7 +85,6 @@ class Geocode
             $aParams['exclude_place_ids'] = implode(',', $this->aExcludePlaceIDs);
         }
 
-        if ($this->bIncludeAddressDetails) $aParams['addressdetails'] = '1';
         if ($this->bBoundedSearch) $aParams['bounded'] = '1';
 
         if ($this->aCountryCodes) {
@@ -183,9 +180,6 @@ class Geocode
 
     public function loadParamArray($oParams, $sForceGeometryType = null)
     {
-        $this->bIncludeAddressDetails
-         = $oParams->getBool('addressdetails', $this->bIncludeAddressDetails);
-
         $this->bBoundedSearch = $oParams->getBool('bounded', $this->bBoundedSearch);
 
         $this->setLimit($oParams->getInt('limit', $this->iFinalLimit));
@@ -247,14 +241,8 @@ class Geocode
         }
 
         $this->oPlaceLookup->loadParamArray($oParams, $sForceGeometryType);
-        $this->oPlaceLookup->setIncludeAddressDetails(false);
         $this->oPlaceLookup->setIncludePolygonAsPoints($oParams->getBool('polygon'));
-
-        if ($this->bIncludeAddressDetails
-            && $oParams->getString('format', '') == 'geocodejson'
-           ) {
-            $this->oPlaceLookup->setAddressAdminLevels(true);
-        }
+        $this->oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', false));
     }
 
     public function setQueryFromParams($oParams)
@@ -868,7 +856,7 @@ class Geocode
 
         $aSearchResults = $this->oPlaceLookup->lookup($aResults);
 
-        $aClassType = getClassTypesWithImportance();
+        $aClassType = ClassTypes\getListWithImportance();
         $aRecheckWords = preg_split('/\b[\s,\\-]*/u', $sQuery);
         foreach ($aRecheckWords as $i => $sWord) {
             if (!preg_match('/[\pL\pN]/', $sWord)) unset($aRecheckWords[$i]);
@@ -878,7 +866,7 @@ class Geocode
 
         foreach ($aSearchResults as $iIdx => $aResult) {
             // Default
-            $fDiameter = getResultDiameter($aResult);
+            $fDiameter = ClassTypes\getProperty($aResult, 'defdiameter', 0.0001);
 
             $aOutlineResult = $this->oPlaceLookup->getOutlines($aResult['place_id'], $aResult['lon'], $aResult['lat'], $fDiameter/2);
             if ($aOutlineResult) {
@@ -892,27 +880,15 @@ class Geocode
             }
 
             // Is there an icon set for this type of result?
-            if (isset($aClassType[$aResult['class'].':'.$aResult['type']]['icon'])
-                && $aClassType[$aResult['class'].':'.$aResult['type']]['icon']
-            ) {
-                $aResult['icon'] = CONST_Website_BaseURL.'images/mapicons/'.$aClassType[$aResult['class'].':'.$aResult['type']]['icon'].'.p.20.png';
-            }
+            $aClassInfo = ClassTypes\getInfo($aResult);
 
-            if (isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'])
-                && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label']
-            ) {
-                $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['label'];
-            } elseif (isset($aClassType[$aResult['class'].':'.$aResult['type']]['label'])
-                && $aClassType[$aResult['class'].':'.$aResult['type']]['label']
-            ) {
-                $aResult['label'] = $aClassType[$aResult['class'].':'.$aResult['type']]['label'];
-            }
-            // if tag '&addressdetails=1' is set in query
-            if ($this->bIncludeAddressDetails) {
-                // getAddressDetails() is defined in lib.php and uses the SQL function get_addressdata in functions.sql
-                $aResult['address'] = getAddressDetails($this->oDB, $sLanguagePrefArraySQL, $aResult['place_id'], $aResult['country_code'], $aResults[$aResult['place_id']]->iHouseNumber);
-                if ($aResult['extra_place'] == 'city' && !isset($aResult['address']['city'])) {
-                    $aResult['address'] = array_merge(array('city' => array_values($aResult['address'])[0]), $aResult['address']);
+            if ($aClassInfo) {
+                if (isset($aClassInfo['icon'])) {
+                    $aResult['icon'] = CONST_Website_BaseURL.'images/mapicons/'.$aClassInfo['icon'].'.p.20.png';
+                }
+
+                if (isset($aClassInfo['label'])) {
+                    $aResult['label'] = $aClassInfo['label'];
                 }
             }
 
@@ -994,7 +970,6 @@ class Geocode
                 'Query' => $this->sQuery,
                 'Structured query' => $this->aStructuredQuery,
                 'Name keys' => Debug::fmtArrayVals($this->aLangPrefOrder),
-                'Include address' => $this->bIncludeAddressDetails,
                 'Excluded place IDs' => Debug::fmtArrayVals($this->aExcludePlaceIDs),
                 'Try reversed query'=> $this->bReverseInPlan,
                 'Limit (for searches)' => $this->iLimit,
index c94121f8983121356254434fd0ce3aad344ba835..9e19db902f4d92590d9b8e8d4fcb148b9fd9ee8f 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Nominatim;
 
+require_once(CONST_BasePath.'/lib/AddressDetails.php');
 require_once(CONST_BasePath.'/lib/Result.php');
 
 class PlaceLookup
@@ -11,7 +12,6 @@ class PlaceLookup
     protected $aLangPrefOrderSql = "''";
 
     protected $bAddressDetails = false;
-    protected $bAddressAdminLevels = false;
     protected $bExtraTags = false;
     protected $bNameDetails = false;
 
@@ -43,9 +43,9 @@ class PlaceLookup
         $this->bIncludePolygonAsPoints = $b;
     }
 
-    public function setAddressAdminLevels($b = true)
+    public function setIncludeAddressDetails($b)
     {
-        $this->bAddressAdminLevels = $b;
+        $this->bAddressDetails = $b;
     }
 
     public function loadParamArray($oParams, $sGeomType = null)
@@ -54,7 +54,6 @@ class PlaceLookup
         $this->aLangPrefOrderSql =
             'ARRAY['.join(',', array_map('getDBQuoted', $aLangs)).']';
 
-        $this->bAddressDetails = $oParams->getBool('addressdetails', true);
         $this->bExtraTags = $oParams->getBool('extratags', false);
         $this->bNameDetails = $oParams->getBool('namedetails', false);
 
@@ -137,11 +136,6 @@ class PlaceLookup
             'ARRAY['.join(',', array_map('getDBQuoted', $aLangPrefOrder)).']';
     }
 
-    public function setIncludeAddressDetails($bAddressDetails = true)
-    {
-        $this->bAddressDetails = $bAddressDetails;
-    }
-
     private function addressImportanceSql($sGeometry, $sPlaceId)
     {
         if ($this->sAnchorSql) {
@@ -160,6 +154,9 @@ class PlaceLookup
 
     private function langAddressSql($sHousenumber)
     {
+        if ($this->bAddressDetails)
+            return ''; // langaddress will be computed from address details
+
         return 'get_address_by_language(place_id,'.$sHousenumber.','.$this->aLangPrefOrderSql.') AS langaddress,';
     }
 
@@ -245,7 +242,7 @@ class PlaceLookup
             $sSQL .= '     country_code, ';
             $sSQL .= '     importance, ';
             if (!$this->bDeDupe) $sSQL .= 'place_id,';
-            $sSQL .= '     langaddress, ';
+            if (!$this->bAddressDetails) $sSQL .= 'langaddress, ';
             $sSQL .= '     placename, ';
             $sSQL .= '     ref, ';
             if ($this->bExtraTags) $sSQL .= 'extratags, ';
@@ -429,21 +426,16 @@ class PlaceLookup
         Debug::printSQL($sSQL);
         $aPlaces = chksql($this->oDB->getAll($sSQL), 'Could not lookup place');
 
-        $aClassType = getClassTypes();
         foreach ($aPlaces as &$aPlace) {
             if ($this->bAddressDetails) {
                 // to get addressdetails for tiger data, the housenumber is needed
-                $aPlace['aAddress'] = $this->getAddressNames(
+                $aPlace['address'] = new AddressDetails(
+                    $this->oDB,
                     $aPlace['place_id'],
-                    $aPlace['housenumber']
-                );
-            }
-
-            if ($this->bAddressAdminLevels) {
-                $aPlace['aAddressAdminLevels'] = $this->getAddressAdminLevels(
-                    $aPlace['place_id'],
-                    $aPlace['housenumber']
+                    $aPlace['housenumber'],
+                    $this->aLangPrefOrderSql
                 );
+                $aPlace['langaddress'] = $aPlace['address']->getLocaleAddress();
             }
 
             if ($this->bExtraTags) {
@@ -462,18 +454,11 @@ class PlaceLookup
                 }
             }
 
-            $sAddressType = '';
-            $sClassType = $aPlace['class'].':'.$aPlace['type'].':'.$aPlace['admin_level'];
-            if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel'])) {
-                $sAddressType = $aClassType[$aClassType]['simplelabel'];
-            } else {
-                $sClassType = $aPlace['class'].':'.$aPlace['type'];
-                if (isset($aClassType[$sClassType]) && isset($aClassType[$sClassType]['simplelabel']))
-                    $sAddressType = $aClassType[$sClassType]['simplelabel'];
-                else $sAddressType = $aPlace['class'];
-            }
-
-            $aPlace['addresstype'] = $sAddressType;
+            $aPlace['addresstype'] = ClassTypes\getProperty(
+                $aPlace,
+                'simplelabel',
+                $aPlace['class']
+            );
         }
 
         Debug::printVar('Places', $aPlaces);
@@ -481,87 +466,6 @@ class PlaceLookup
         return $aPlaces;
     }
 
-    public function getAddressDetails($iPlaceID, $bAll = false, $sHousenumber = -1)
-    {
-        $sSQL = 'SELECT *,';
-        $sSQL .= '  get_name_by_language(name,'.$this->aLangPrefOrderSql.') as localname';
-        $sSQL .= ' FROM get_addressdata('.$iPlaceID.','.$sHousenumber.')';
-        if (!$bAll) {
-            $sSQL .= " WHERE isaddress OR type = 'country_code'";
-        }
-        $sSQL .= ' ORDER BY rank_address desc,isaddress DESC';
-
-        return chksql($this->oDB->getAll($sSQL));
-    }
-
-    public function getAddressNames($iPlaceID, $sHousenumber = null)
-    {
-        $aAddressLines = $this->getAddressDetails(
-            $iPlaceID,
-            false,
-            $sHousenumber === null ? -1 : $sHousenumber
-        );
-
-        $aAddress = array();
-        $aFallback = array();
-        $aClassType = getClassTypes();
-        foreach ($aAddressLines as $aLine) {
-            $bFallback = false;
-            $aTypeLabel = false;
-            if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) {
-                $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
-            } elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) {
-                $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
-            } elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))])) {
-                $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
-                $bFallback = true;
-            } else {
-                $aTypeLabel = array('simplelabel' => 'address'.$aLine['rank_address']);
-                $bFallback = true;
-            }
-            if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber']))) {
-                $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
-                $sTypeLabel = str_replace(' ', '_', $sTypeLabel);
-                if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place') {
-                    $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
-                }
-                $aFallback[$sTypeLabel] = $bFallback;
-            }
-        }
-        return $aAddress;
-    }
-
-    /* "Downing Street, London"
-     * [
-     *   "level15" => "Covent Garden",
-     *   "level8" => "Westminster",
-     *   "level6" => "London",
-     *   "level5" => "Greater London",
-     *   "level4" => "England",
-     *   "level2" => "United Kingdom"
-     * ]
-     */
-
-    public function getAddressAdminLevels($iPlaceID, $sHousenumber = null)
-    {
-        $aAddressLines = $this->getAddressDetails(
-            $iPlaceID,
-            true,
-            $sHousenumber === null ? -1 : $sHousenumber
-        );
-
-        $aAddress = array();
-        foreach ($aAddressLines as $aLine) {
-            if (isset($aLine['admin_level'])
-                && $aLine['admin_level'] < 15
-                && !isset($aAddress['level'.$aLine['admin_level']])) {
-                $aAddress['level'.$aLine['admin_level']] = $aLine['localname'];
-            }
-        }
-        return $aAddress;
-    }
-
-
     /* returns an array which will contain the keys
      *   aBoundingBox
      * and may also contain one or more of the keys
index 46966a8a1bed1e22ec8096bd700f2e2039856cf1..64e4b3d4786b591640be21c84dccdb25ece8e70a 100644 (file)
@@ -34,7 +34,7 @@ class SpecialTerm
                 'Info' => array(
                            'class' => $this->sClass,
                            'type' => $this->sType,
-                           'operator' => Operator::toString($this->iOperator)
+                           'operator' => \Nominatim\Operator::toString($this->iOperator)
                           )
                );
     }
index 317ba54997b66c3061440b0772904f004ec9542b..0f87c37eca00c1f4f6077ef0452218ed25030abf 100644 (file)
@@ -1,6 +1,5 @@
 <?php
 
-
 function fail($sError, $sUserError = false)
 {
     if (!$sUserError) $sUserError = $sError;
@@ -60,349 +59,6 @@ function byImportance($a, $b)
 }
 
 
-function getClassTypes()
-{
-    return array(
-            'boundary:administrative:1' => array('label' => 'Continent', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:2' => array('label' => 'Country', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:country' => array('label' => 'Country', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 6, 'defdiameter' => 15),
-            'boundary:administrative:3' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:4' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:state' => array('label' => 'State', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 8, 'defdiameter' => 5.12),
-            'boundary:administrative:5' => array('label' => 'State District', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:6' => array('label' => 'County', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:7' => array('label' => 'County', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:county' => array('label' => 'County', 'frequency' => 108, 'icon' => 'poi_boundary_administrative', 'defzoom' => 10, 'defdiameter' => 1.28),
-            'boundary:administrative:8' => array('label' => 'City', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:city' => array('label' => 'City', 'frequency' => 66, 'icon' => 'poi_place_city', 'defzoom' => 12, 'defdiameter' => 0.32),
-            'boundary:administrative:9' => array('label' => 'City District', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:10' => array('label' => 'Suburb', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:administrative:11' => array('label' => 'Neighbourhood', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:region' => array('label' => 'Region', 'frequency' => 0, 'icon' => 'poi_boundary_administrative', 'defzoom' => 8, 'defdiameter' => 0.04),
-            'place:island' => array('label' => 'Island', 'frequency' => 288, 'icon' => '', 'defzoom' => 11, 'defdiameter' => 0.64),
-            'boundary:administrative' => array('label' => 'Administrative', 'frequency' => 413, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'boundary:postal_code' => array('label' => 'Postcode', 'frequency' => 413, 'icon' => 'poi_boundary_administrative', 'defdiameter' => 0.32),
-            'place:town' => array('label' => 'Town', 'frequency' => 1497, 'icon' => 'poi_place_town', 'defzoom' => 14, 'defdiameter' => 0.08),
-            'place:village' => array('label' => 'Village', 'frequency' => 11230, 'icon' => 'poi_place_village', 'defzoom' => 15, 'defdiameter' => 0.04),
-            'place:hamlet' => array('label' => 'Hamlet', 'frequency' => 7075, 'icon' => 'poi_place_village', 'defzoom' => 15, 'defdiameter' => 0.04),
-            'place:suburb' => array('label' => 'Suburb', 'frequency' => 2528, 'icon' => 'poi_place_village', 'defdiameter' => 0.04),
-            'place:locality' => array('label' => 'Locality', 'frequency' => 4113, 'icon' => 'poi_place_village', 'defdiameter' => 0.02),
-            'landuse:farm' => array('label' => 'Farm', 'frequency' => 1201, 'icon' => '', 'defdiameter' => 0.02),
-            'place:farm' => array('label' => 'Farm', 'frequency' => 1162, 'icon' => '', 'defdiameter' => 0.02),
-
-            'highway:motorway_junction' => array('label' => 'Motorway Junction', 'frequency' => 1126, 'icon' => '', 'simplelabel' => 'Junction'),
-            'highway:motorway' => array('label' => 'Motorway', 'frequency' => 4627, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:trunk' => array('label' => 'Trunk', 'frequency' => 23084, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:primary' => array('label' => 'Primary', 'frequency' => 32138, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:secondary' => array('label' => 'Secondary', 'frequency' => 25807, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:tertiary' => array('label' => 'Tertiary', 'frequency' => 29829, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:residential' => array('label' => 'Residential', 'frequency' => 361498, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:unclassified' => array('label' => 'Unclassified', 'frequency' => 66441, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:living_street' => array('label' => 'Living Street', 'frequency' => 710, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:service' => array('label' => 'Service', 'frequency' => 9963, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:track' => array('label' => 'Track', 'frequency' => 2565, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:road' => array('label' => 'Road', 'frequency' => 591, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:byway' => array('label' => 'Byway', 'frequency' => 346, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:bridleway' => array('label' => 'Bridleway', 'frequency' => 1556, 'icon' => ''),
-            'highway:cycleway' => array('label' => 'Cycleway', 'frequency' => 2419, 'icon' => ''),
-            'highway:pedestrian' => array('label' => 'Pedestrian', 'frequency' => 2757, 'icon' => ''),
-            'highway:footway' => array('label' => 'Footway', 'frequency' => 15008, 'icon' => ''),
-            'highway:steps' => array('label' => 'Steps', 'frequency' => 444, 'icon' => '', 'simplelabel' => 'Footway'),
-            'highway:motorway_link' => array('label' => 'Motorway Link', 'frequency' => 795, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:trunk_link' => array('label' => 'Trunk Link', 'frequency' => 1258, 'icon' => '', 'simplelabel' => 'Road'),
-            'highway:primary_link' => array('label' => 'Primary Link', 'frequency' => 313, 'icon' => '', 'simplelabel' => 'Road'),
-
-            'landuse:industrial' => array('label' => 'Industrial', 'frequency' => 1062, 'icon' => ''),
-            'landuse:residential' => array('label' => 'Residential', 'frequency' => 886, 'icon' => ''),
-            'landuse:retail' => array('label' => 'Retail', 'frequency' => 754, 'icon' => ''),
-            'landuse:commercial' => array('label' => 'Commercial', 'frequency' => 657, 'icon' => ''),
-
-            'place:airport' => array('label' => 'Airport', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
-            'aeroway:aerodrome' => array('label' => 'Aerodrome', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
-            'aeroway' => array('label' => 'Aeroway', 'frequency' => 36, 'icon' => 'transport_airport2', 'defdiameter' => 0.03),
-            'railway:station' => array('label' => 'Station', 'frequency' => 3431, 'icon' => 'transport_train_station2', 'defdiameter' => 0.01),
-            'amenity:place_of_worship' => array('label' => 'Place Of Worship', 'frequency' => 9049, 'icon' => 'place_of_worship_unknown3'),
-            'amenity:pub' => array('label' => 'Pub', 'frequency' => 18969, 'icon' => 'food_pub'),
-            'amenity:bar' => array('label' => 'Bar', 'frequency' => 164, 'icon' => 'food_bar'),
-            'amenity:university' => array('label' => 'University', 'frequency' => 607, 'icon' => 'education_university'),
-            'tourism:museum' => array('label' => 'Museum', 'frequency' => 543, 'icon' => 'tourist_museum'),
-            'amenity:arts_centre' => array('label' => 'Arts Centre', 'frequency' => 136, 'icon' => 'tourist_art_gallery2'),
-            'tourism:zoo' => array('label' => 'Zoo', 'frequency' => 47, 'icon' => 'tourist_zoo'),
-            'tourism:theme_park' => array('label' => 'Theme Park', 'frequency' => 24, 'icon' => 'poi_point_of_interest'),
-            'tourism:attraction' => array('label' => 'Attraction', 'frequency' => 1463, 'icon' => 'poi_point_of_interest'),
-            'leisure:golf_course' => array('label' => 'Golf Course', 'frequency' => 712, 'icon' => 'sport_golf'),
-            'historic:castle' => array('label' => 'Castle', 'frequency' => 316, 'icon' => 'tourist_castle'),
-            'amenity:hospital' => array('label' => 'Hospital', 'frequency' => 879, 'icon' => 'health_hospital'),
-            'amenity:school' => array('label' => 'School', 'frequency' => 8192, 'icon' => 'education_school'),
-            'amenity:theatre' => array('label' => 'Theatre', 'frequency' => 371, 'icon' => 'tourist_theatre'),
-            'amenity:public_building' => array('label' => 'Public Building', 'frequency' => 985, 'icon' => ''),
-            'amenity:library' => array('label' => 'Library', 'frequency' => 794, 'icon' => 'amenity_library'),
-            'amenity:townhall' => array('label' => 'Townhall', 'frequency' => 242, 'icon' => ''),
-            'amenity:community_centre' => array('label' => 'Community Centre', 'frequency' => 157, 'icon' => ''),
-            'amenity:fire_station' => array('label' => 'Fire Station', 'frequency' => 221, 'icon' => 'amenity_firestation3'),
-            'amenity:police' => array('label' => 'Police', 'frequency' => 334, 'icon' => 'amenity_police2'),
-            'amenity:bank' => array('label' => 'Bank', 'frequency' => 1248, 'icon' => 'money_bank2'),
-            'amenity:post_office' => array('label' => 'Post Office', 'frequency' => 859, 'icon' => 'amenity_post_office'),
-            'leisure:park' => array('label' => 'Park', 'frequency' => 2378, 'icon' => ''),
-            'amenity:park' => array('label' => 'Park', 'frequency' => 53, 'icon' => ''),
-            'landuse:park' => array('label' => 'Park', 'frequency' => 50, 'icon' => ''),
-            'landuse:recreation_ground' => array('label' => 'Recreation Ground', 'frequency' => 517, 'icon' => ''),
-            'tourism:hotel' => array('label' => 'Hotel', 'frequency' => 2150, 'icon' => 'accommodation_hotel2'),
-            'tourism:motel' => array('label' => 'Motel', 'frequency' => 43, 'icon' => ''),
-            'amenity:cinema' => array('label' => 'Cinema', 'frequency' => 277, 'icon' => 'tourist_cinema'),
-            'tourism:artwork' => array('label' => 'Artwork', 'frequency' => 171, 'icon' => 'tourist_art_gallery2'),
-            'historic:archaeological_site' => array('label' => 'Archaeological Site', 'frequency' => 407, 'icon' => 'tourist_archaeological2'),
-            'amenity:doctors' => array('label' => 'Doctors', 'frequency' => 581, 'icon' => 'health_doctors'),
-            'leisure:sports_centre' => array('label' => 'Sports Centre', 'frequency' => 767, 'icon' => 'sport_leisure_centre'),
-            'leisure:swimming_pool' => array('label' => 'Swimming Pool', 'frequency' => 24, 'icon' => 'sport_swimming_outdoor'),
-            'shop:supermarket' => array('label' => 'Supermarket', 'frequency' => 2673, 'icon' => 'shopping_supermarket'),
-            'shop:convenience' => array('label' => 'Convenience', 'frequency' => 1469, 'icon' => 'shopping_convenience'),
-            'amenity:restaurant' => array('label' => 'Restaurant', 'frequency' => 3179, 'icon' => 'food_restaurant'),
-            'amenity:fast_food' => array('label' => 'Fast Food', 'frequency' => 2289, 'icon' => 'food_fastfood'),
-            'amenity:cafe' => array('label' => 'Cafe', 'frequency' => 1780, 'icon' => 'food_cafe'),
-            'tourism:guest_house' => array('label' => 'Guest House', 'frequency' => 223, 'icon' => 'accommodation_bed_and_breakfast'),
-            'amenity:pharmacy' => array('label' => 'Pharmacy', 'frequency' => 733, 'icon' => 'health_pharmacy_dispensing'),
-            'amenity:fuel' => array('label' => 'Fuel', 'frequency' => 1308, 'icon' => 'transport_fuel'),
-            'natural:peak' => array('label' => 'Peak', 'frequency' => 3212, 'icon' => 'poi_peak'),
-            'waterway:waterfall' => array('label' => 'Waterfall', 'frequency' => 24, 'icon' => ''),
-            'natural:wood' => array('label' => 'Wood', 'frequency' => 1845, 'icon' => 'landuse_coniferous_and_deciduous'),
-            'natural:water' => array('label' => 'Water', 'frequency' => 1790, 'icon' => ''),
-            'landuse:forest' => array('label' => 'Forest', 'frequency' => 467, 'icon' => ''),
-            'landuse:cemetery' => array('label' => 'Cemetery', 'frequency' => 463, 'icon' => ''),
-            'landuse:allotments' => array('label' => 'Allotments', 'frequency' => 408, 'icon' => ''),
-            'landuse:farmyard' => array('label' => 'Farmyard', 'frequency' => 397, 'icon' => ''),
-            'railway:rail' => array('label' => 'Rail', 'frequency' => 4894, 'icon' => ''),
-            'waterway:canal' => array('label' => 'Canal', 'frequency' => 1723, 'icon' => ''),
-            'waterway:river' => array('label' => 'River', 'frequency' => 4089, 'icon' => ''),
-            'waterway:stream' => array('label' => 'Stream', 'frequency' => 2684, 'icon' => ''),
-            'shop:bicycle' => array('label' => 'Bicycle', 'frequency' => 349, 'icon' => 'shopping_bicycle'),
-            'shop:clothes' => array('label' => 'Clothes', 'frequency' => 315, 'icon' => 'shopping_clothes'),
-            'shop:hairdresser' => array('label' => 'Hairdresser', 'frequency' => 312, 'icon' => 'shopping_hairdresser'),
-            'shop:doityourself' => array('label' => 'Doityourself', 'frequency' => 247, 'icon' => 'shopping_diy'),
-            'shop:estate_agent' => array('label' => 'Estate Agent', 'frequency' => 162, 'icon' => 'shopping_estateagent2'),
-            'shop:car' => array('label' => 'Car', 'frequency' => 159, 'icon' => 'shopping_car'),
-            'shop:garden_centre' => array('label' => 'Garden Centre', 'frequency' => 143, 'icon' => 'shopping_garden_centre'),
-            'shop:car_repair' => array('label' => 'Car Repair', 'frequency' => 141, 'icon' => 'shopping_car_repair'),
-            'shop:newsagent' => array('label' => 'Newsagent', 'frequency' => 132, 'icon' => ''),
-            'shop:bakery' => array('label' => 'Bakery', 'frequency' => 129, 'icon' => 'shopping_bakery'),
-            'shop:furniture' => array('label' => 'Furniture', 'frequency' => 124, 'icon' => ''),
-            'shop:butcher' => array('label' => 'Butcher', 'frequency' => 105, 'icon' => 'shopping_butcher'),
-            'shop:apparel' => array('label' => 'Apparel', 'frequency' => 98, 'icon' => 'shopping_clothes'),
-            'shop:electronics' => array('label' => 'Electronics', 'frequency' => 96, 'icon' => ''),
-            'shop:department_store' => array('label' => 'Department Store', 'frequency' => 86, 'icon' => ''),
-            'shop:books' => array('label' => 'Books', 'frequency' => 85, 'icon' => ''),
-            'shop:yes' => array('label' => 'Shop', 'frequency' => 68, 'icon' => ''),
-            'shop:outdoor' => array('label' => 'Outdoor', 'frequency' => 67, 'icon' => ''),
-            'shop:mall' => array('label' => 'Mall', 'frequency' => 63, 'icon' => ''),
-            'shop:florist' => array('label' => 'Florist', 'frequency' => 61, 'icon' => ''),
-            'shop:charity' => array('label' => 'Charity', 'frequency' => 60, 'icon' => ''),
-            'shop:hardware' => array('label' => 'Hardware', 'frequency' => 59, 'icon' => ''),
-            'shop:laundry' => array('label' => 'Laundry', 'frequency' => 51, 'icon' => 'shopping_laundrette'),
-            'shop:shoes' => array('label' => 'Shoes', 'frequency' => 49, 'icon' => ''),
-            'shop:beverages' => array('label' => 'Beverages', 'frequency' => 48, 'icon' => 'shopping_alcohol'),
-            'shop:dry_cleaning' => array('label' => 'Dry Cleaning', 'frequency' => 46, 'icon' => ''),
-            'shop:carpet' => array('label' => 'Carpet', 'frequency' => 45, 'icon' => ''),
-            'shop:computer' => array('label' => 'Computer', 'frequency' => 44, 'icon' => ''),
-            'shop:alcohol' => array('label' => 'Alcohol', 'frequency' => 44, 'icon' => 'shopping_alcohol'),
-            'shop:optician' => array('label' => 'Optician', 'frequency' => 55, 'icon' => 'health_opticians'),
-            'shop:chemist' => array('label' => 'Chemist', 'frequency' => 42, 'icon' => 'health_pharmacy'),
-            'shop:gallery' => array('label' => 'Gallery', 'frequency' => 38, 'icon' => 'tourist_art_gallery2'),
-            'shop:mobile_phone' => array('label' => 'Mobile Phone', 'frequency' => 37, 'icon' => ''),
-            'shop:sports' => array('label' => 'Sports', 'frequency' => 37, 'icon' => ''),
-            'shop:jewelry' => array('label' => 'Jewelry', 'frequency' => 32, 'icon' => 'shopping_jewelry'),
-            'shop:pet' => array('label' => 'Pet', 'frequency' => 29, 'icon' => ''),
-            'shop:beauty' => array('label' => 'Beauty', 'frequency' => 28, 'icon' => ''),
-            'shop:stationery' => array('label' => 'Stationery', 'frequency' => 25, 'icon' => ''),
-            'shop:shopping_centre' => array('label' => 'Shopping Centre', 'frequency' => 25, 'icon' => ''),
-            'shop:general' => array('label' => 'General', 'frequency' => 25, 'icon' => ''),
-            'shop:electrical' => array('label' => 'Electrical', 'frequency' => 25, 'icon' => ''),
-            'shop:toys' => array('label' => 'Toys', 'frequency' => 23, 'icon' => ''),
-            'shop:jeweller' => array('label' => 'Jeweller', 'frequency' => 23, 'icon' => ''),
-            'shop:betting' => array('label' => 'Betting', 'frequency' => 23, 'icon' => ''),
-            'shop:household' => array('label' => 'Household', 'frequency' => 21, 'icon' => ''),
-            'shop:travel_agency' => array('label' => 'Travel Agency', 'frequency' => 21, 'icon' => ''),
-            'shop:hifi' => array('label' => 'Hifi', 'frequency' => 21, 'icon' => ''),
-            'amenity:shop' => array('label' => 'Shop', 'frequency' => 61, 'icon' => ''),
-            'tourism:information' => array('label' => 'Information', 'frequency' => 224, 'icon' => 'amenity_information'),
-
-            'place:house' => array('label' => 'House', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
-            'place:house_name' => array('label' => 'House', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
-            'place:house_number' => array('label' => 'House Number', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
-            'place:country_code' => array('label' => 'Country Code', 'frequency' => 2086, 'icon' => '', 'defzoom' => 18),
-
-            //
-
-            'leisure:pitch' => array('label' => 'Pitch', 'frequency' => 762, 'icon' => ''),
-            'highway:unsurfaced' => array('label' => 'Unsurfaced', 'frequency' => 492, 'icon' => ''),
-            'historic:ruins' => array('label' => 'Ruins', 'frequency' => 483, 'icon' => 'tourist_ruin'),
-            'amenity:college' => array('label' => 'College', 'frequency' => 473, 'icon' => 'education_school'),
-            'historic:monument' => array('label' => 'Monument', 'frequency' => 470, 'icon' => 'tourist_monument'),
-            'railway:subway' => array('label' => 'Subway', 'frequency' => 385, 'icon' => ''),
-            'historic:memorial' => array('label' => 'Memorial', 'frequency' => 382, 'icon' => 'tourist_monument'),
-            'leisure:nature_reserve' => array('label' => 'Nature Reserve', 'frequency' => 342, 'icon' => ''),
-            'leisure:common' => array('label' => 'Common', 'frequency' => 322, 'icon' => ''),
-            'waterway:lock_gate' => array('label' => 'Lock Gate', 'frequency' => 321, 'icon' => ''),
-            'natural:fell' => array('label' => 'Fell', 'frequency' => 308, 'icon' => ''),
-            'amenity:nightclub' => array('label' => 'Nightclub', 'frequency' => 292, 'icon' => ''),
-            'highway:path' => array('label' => 'Path', 'frequency' => 287, 'icon' => ''),
-            'leisure:garden' => array('label' => 'Garden', 'frequency' => 285, 'icon' => ''),
-            'landuse:reservoir' => array('label' => 'Reservoir', 'frequency' => 276, 'icon' => ''),
-            'leisure:playground' => array('label' => 'Playground', 'frequency' => 264, 'icon' => ''),
-            'leisure:stadium' => array('label' => 'Stadium', 'frequency' => 212, 'icon' => ''),
-            'historic:mine' => array('label' => 'Mine', 'frequency' => 193, 'icon' => 'poi_mine'),
-            'natural:cliff' => array('label' => 'Cliff', 'frequency' => 193, 'icon' => ''),
-            'tourism:caravan_site' => array('label' => 'Caravan Site', 'frequency' => 183, 'icon' => 'accommodation_caravan_park'),
-            'amenity:bus_station' => array('label' => 'Bus Station', 'frequency' => 181, 'icon' => 'transport_bus_station'),
-            'amenity:kindergarten' => array('label' => 'Kindergarten', 'frequency' => 179, 'icon' => ''),
-            'highway:construction' => array('label' => 'Construction', 'frequency' => 176, 'icon' => ''),
-            'amenity:atm' => array('label' => 'Atm', 'frequency' => 172, 'icon' => 'money_atm2'),
-            'amenity:emergency_phone' => array('label' => 'Emergency Phone', 'frequency' => 164, 'icon' => ''),
-            'waterway:lock' => array('label' => 'Lock', 'frequency' => 146, 'icon' => ''),
-            'waterway:riverbank' => array('label' => 'Riverbank', 'frequency' => 143, 'icon' => ''),
-            'natural:coastline' => array('label' => 'Coastline', 'frequency' => 142, 'icon' => ''),
-            'tourism:viewpoint' => array('label' => 'Viewpoint', 'frequency' => 140, 'icon' => 'tourist_view_point'),
-            'tourism:hostel' => array('label' => 'Hostel', 'frequency' => 140, 'icon' => ''),
-            'tourism:bed_and_breakfast' => array('label' => 'Bed And Breakfast', 'frequency' => 140, 'icon' => 'accommodation_bed_and_breakfast'),
-            'railway:halt' => array('label' => 'Halt', 'frequency' => 135, 'icon' => ''),
-            'railway:platform' => array('label' => 'Platform', 'frequency' => 134, 'icon' => ''),
-            'railway:tram' => array('label' => 'Tram', 'frequency' => 130, 'icon' => 'transport_tram_stop'),
-            'amenity:courthouse' => array('label' => 'Courthouse', 'frequency' => 129, 'icon' => 'amenity_court'),
-            'amenity:recycling' => array('label' => 'Recycling', 'frequency' => 126, 'icon' => 'amenity_recycling'),
-            'amenity:dentist' => array('label' => 'Dentist', 'frequency' => 124, 'icon' => 'health_dentist'),
-            'natural:beach' => array('label' => 'Beach', 'frequency' => 121, 'icon' => 'tourist_beach'),
-            'place:moor' => array('label' => 'Moor', 'frequency' => 118, 'icon' => ''),
-            'amenity:grave_yard' => array('label' => 'Grave Yard', 'frequency' => 110, 'icon' => ''),
-            'waterway:drain' => array('label' => 'Drain', 'frequency' => 108, 'icon' => ''),
-            'landuse:grass' => array('label' => 'Grass', 'frequency' => 106, 'icon' => ''),
-            'landuse:village_green' => array('label' => 'Village Green', 'frequency' => 106, 'icon' => ''),
-            'natural:bay' => array('label' => 'Bay', 'frequency' => 102, 'icon' => ''),
-            'railway:tram_stop' => array('label' => 'Tram Stop', 'frequency' => 101, 'icon' => 'transport_tram_stop'),
-            'leisure:marina' => array('label' => 'Marina', 'frequency' => 98, 'icon' => ''),
-            'highway:stile' => array('label' => 'Stile', 'frequency' => 97, 'icon' => ''),
-            'natural:moor' => array('label' => 'Moor', 'frequency' => 95, 'icon' => ''),
-            'railway:light_rail' => array('label' => 'Light Rail', 'frequency' => 91, 'icon' => ''),
-            'railway:narrow_gauge' => array('label' => 'Narrow Gauge', 'frequency' => 90, 'icon' => ''),
-            'natural:land' => array('label' => 'Land', 'frequency' => 86, 'icon' => ''),
-            'amenity:village_hall' => array('label' => 'Village Hall', 'frequency' => 82, 'icon' => ''),
-            'waterway:dock' => array('label' => 'Dock', 'frequency' => 80, 'icon' => ''),
-            'amenity:veterinary' => array('label' => 'Veterinary', 'frequency' => 79, 'icon' => ''),
-            'landuse:brownfield' => array('label' => 'Brownfield', 'frequency' => 77, 'icon' => ''),
-            'leisure:track' => array('label' => 'Track', 'frequency' => 76, 'icon' => ''),
-            'railway:historic_station' => array('label' => 'Historic Station', 'frequency' => 74, 'icon' => ''),
-            'landuse:construction' => array('label' => 'Construction', 'frequency' => 72, 'icon' => ''),
-            'amenity:prison' => array('label' => 'Prison', 'frequency' => 71, 'icon' => 'amenity_prison'),
-            'landuse:quarry' => array('label' => 'Quarry', 'frequency' => 71, 'icon' => ''),
-            'amenity:telephone' => array('label' => 'Telephone', 'frequency' => 70, 'icon' => ''),
-            'highway:traffic_signals' => array('label' => 'Traffic Signals', 'frequency' => 66, 'icon' => ''),
-            'natural:heath' => array('label' => 'Heath', 'frequency' => 62, 'icon' => ''),
-            'historic:house' => array('label' => 'House', 'frequency' => 61, 'icon' => ''),
-            'amenity:social_club' => array('label' => 'Social Club', 'frequency' => 61, 'icon' => ''),
-            'landuse:military' => array('label' => 'Military', 'frequency' => 61, 'icon' => ''),
-            'amenity:health_centre' => array('label' => 'Health Centre', 'frequency' => 59, 'icon' => ''),
-            'historic:building' => array('label' => 'Building', 'frequency' => 58, 'icon' => ''),
-            'amenity:clinic' => array('label' => 'Clinic', 'frequency' => 57, 'icon' => ''),
-            'highway:services' => array('label' => 'Services', 'frequency' => 56, 'icon' => ''),
-            'amenity:ferry_terminal' => array('label' => 'Ferry Terminal', 'frequency' => 55, 'icon' => ''),
-            'natural:marsh' => array('label' => 'Marsh', 'frequency' => 55, 'icon' => ''),
-            'natural:hill' => array('label' => 'Hill', 'frequency' => 54, 'icon' => ''),
-            'highway:raceway' => array('label' => 'Raceway', 'frequency' => 53, 'icon' => ''),
-            'amenity:taxi' => array('label' => 'Taxi', 'frequency' => 47, 'icon' => ''),
-            'amenity:take_away' => array('label' => 'Take Away', 'frequency' => 45, 'icon' => ''),
-            'amenity:car_rental' => array('label' => 'Car Rental', 'frequency' => 44, 'icon' => ''),
-            'place:islet' => array('label' => 'Islet', 'frequency' => 44, 'icon' => ''),
-            'amenity:nursery' => array('label' => 'Nursery', 'frequency' => 44, 'icon' => ''),
-            'amenity:nursing_home' => array('label' => 'Nursing Home', 'frequency' => 43, 'icon' => ''),
-            'amenity:toilets' => array('label' => 'Toilets', 'frequency' => 38, 'icon' => ''),
-            'amenity:hall' => array('label' => 'Hall', 'frequency' => 38, 'icon' => ''),
-            'waterway:boatyard' => array('label' => 'Boatyard', 'frequency' => 36, 'icon' => ''),
-            'highway:mini_roundabout' => array('label' => 'Mini Roundabout', 'frequency' => 35, 'icon' => ''),
-            'historic:manor' => array('label' => 'Manor', 'frequency' => 35, 'icon' => ''),
-            'tourism:chalet' => array('label' => 'Chalet', 'frequency' => 34, 'icon' => ''),
-            'amenity:bicycle_parking' => array('label' => 'Bicycle Parking', 'frequency' => 34, 'icon' => ''),
-            'amenity:hotel' => array('label' => 'Hotel', 'frequency' => 34, 'icon' => ''),
-            'waterway:weir' => array('label' => 'Weir', 'frequency' => 33, 'icon' => ''),
-            'natural:wetland' => array('label' => 'Wetland', 'frequency' => 33, 'icon' => ''),
-            'natural:cave_entrance' => array('label' => 'Cave Entrance', 'frequency' => 32, 'icon' => ''),
-            'amenity:crematorium' => array('label' => 'Crematorium', 'frequency' => 31, 'icon' => ''),
-            'tourism:picnic_site' => array('label' => 'Picnic Site', 'frequency' => 31, 'icon' => ''),
-            'landuse:wood' => array('label' => 'Wood', 'frequency' => 30, 'icon' => ''),
-            'landuse:basin' => array('label' => 'Basin', 'frequency' => 30, 'icon' => ''),
-            'natural:tree' => array('label' => 'Tree', 'frequency' => 30, 'icon' => ''),
-            'leisure:slipway' => array('label' => 'Slipway', 'frequency' => 29, 'icon' => ''),
-            'landuse:meadow' => array('label' => 'Meadow', 'frequency' => 29, 'icon' => ''),
-            'landuse:piste' => array('label' => 'Piste', 'frequency' => 28, 'icon' => ''),
-            'amenity:care_home' => array('label' => 'Care Home', 'frequency' => 28, 'icon' => ''),
-            'amenity:club' => array('label' => 'Club', 'frequency' => 28, 'icon' => ''),
-            'amenity:medical_centre' => array('label' => 'Medical Centre', 'frequency' => 27, 'icon' => ''),
-            'historic:roman_road' => array('label' => 'Roman Road', 'frequency' => 27, 'icon' => ''),
-            'historic:fort' => array('label' => 'Fort', 'frequency' => 26, 'icon' => ''),
-            'railway:subway_entrance' => array('label' => 'Subway Entrance', 'frequency' => 26, 'icon' => ''),
-            'historic:yes' => array('label' => 'Historic', 'frequency' => 25, 'icon' => ''),
-            'highway:gate' => array('label' => 'Gate', 'frequency' => 25, 'icon' => ''),
-            'leisure:fishing' => array('label' => 'Fishing', 'frequency' => 24, 'icon' => ''),
-            'historic:museum' => array('label' => 'Museum', 'frequency' => 24, 'icon' => ''),
-            'amenity:car_wash' => array('label' => 'Car Wash', 'frequency' => 24, 'icon' => ''),
-            'railway:level_crossing' => array('label' => 'Level Crossing', 'frequency' => 23, 'icon' => ''),
-            'leisure:bird_hide' => array('label' => 'Bird Hide', 'frequency' => 23, 'icon' => ''),
-            'natural:headland' => array('label' => 'Headland', 'frequency' => 21, 'icon' => ''),
-            'tourism:apartments' => array('label' => 'Apartments', 'frequency' => 21, 'icon' => ''),
-            'amenity:shopping' => array('label' => 'Shopping', 'frequency' => 21, 'icon' => ''),
-            'natural:scrub' => array('label' => 'Scrub', 'frequency' => 20, 'icon' => ''),
-            'natural:fen' => array('label' => 'Fen', 'frequency' => 20, 'icon' => ''),
-            'building:yes' => array('label' => 'Building', 'frequency' => 200, 'icon' => ''),
-            'mountain_pass:yes' => array('label' => 'Mountain Pass', 'frequency' => 200, 'icon' => ''),
-
-            'amenity:parking' => array('label' => 'Parking', 'frequency' => 3157, 'icon' => ''),
-            'highway:bus_stop' => array('label' => 'Bus Stop', 'frequency' => 35777, 'icon' => 'transport_bus_stop2'),
-            'place:postcode' => array('label' => 'Postcode', 'frequency' => 27267, 'icon' => ''),
-            'amenity:post_box' => array('label' => 'Post Box', 'frequency' => 9613, 'icon' => ''),
-
-            'place:houses' => array('label' => 'Houses', 'frequency' => 85, 'icon' => ''),
-            'railway:preserved' => array('label' => 'Preserved', 'frequency' => 227, 'icon' => ''),
-            'waterway:derelict_canal' => array('label' => 'Derelict Canal', 'frequency' => 21, 'icon' => ''),
-            'amenity:dead_pub' => array('label' => 'Dead Pub', 'frequency' => 20, 'icon' => ''),
-            'railway:disused_station' => array('label' => 'Disused Station', 'frequency' => 114, 'icon' => ''),
-            'railway:abandoned' => array('label' => 'Abandoned', 'frequency' => 641, 'icon' => ''),
-            'railway:disused' => array('label' => 'Disused', 'frequency' => 72, 'icon' => ''),
-           );
-}
-
-
-function getClassTypesWithImportance()
-{
-    $aOrders = getClassTypes();
-    $i = 1;
-    foreach ($aOrders as $sID => $a) {
-        $aOrders[$sID]['importance'] = $i++;
-    }
-    return $aOrders;
-}
-
-function getResultDiameter($aResult)
-{
-    $aClassType = getClassTypes();
-
-    $fDiameter = 0.0001;
-
-    if (isset($aResult['class'])
-        && isset($aResult['type'])
-        && isset($aResult['admin_level'])
-        && isset($aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'])
-        && $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter']
-    ) {
-        $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type'].':'.$aResult['admin_level']]['defdiameter'];
-    } elseif (isset($aResult['class'])
-        && isset($aResult['type'])
-        && isset($aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'])
-        && $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter']
-    ) {
-        $fDiameter = $aClassType[$aResult['class'].':'.$aResult['type']]['defdiameter'];
-    }
-
-    return $fDiameter;
-}
-
-
 function javascript_renderData($xVal, $iOptions = 0)
 {
     $iOptions |= JSON_UNESCAPED_UNICODE;
@@ -425,47 +81,6 @@ function javascript_renderData($xVal, $iOptions = 0)
     }
 }
 
-
-function getAddressDetails(&$oDB, $sLanguagePrefArraySQL, $iPlaceID, $sCountryCode = false, $housenumber = -1, $bRaw = false)
-{
-    $sSQL = "select *,get_name_by_language(name,$sLanguagePrefArraySQL) as localname from get_addressdata($iPlaceID, $housenumber)";
-    if (!$bRaw) $sSQL .= " WHERE isaddress OR type = 'country_code'";
-    $sSQL .= ' order by rank_address desc,isaddress desc';
-
-    $aAddressLines = chksql($oDB->getAll($sSQL));
-    if ($bRaw) return $aAddressLines;
-    //echo "<pre>";
-    //var_dump($aAddressLines);
-    $aAddress = array();
-    $aFallback = array();
-    $aClassType = getClassTypes();
-    foreach ($aAddressLines as $aLine) {
-        $bFallback = false;
-        $aTypeLabel = false;
-        if (isset($aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']])) {
-            $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type'].':'.$aLine['admin_level']];
-        } elseif (isset($aClassType[$aLine['class'].':'.$aLine['type']])) {
-            $aTypeLabel = $aClassType[$aLine['class'].':'.$aLine['type']];
-        } elseif (isset($aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))])) {
-            $aTypeLabel = $aClassType['boundary:administrative:'.((int)($aLine['rank_address']/2))];
-            $bFallback = true;
-        } else {
-            $aTypeLabel = array('simplelabel' => 'address'.$aLine['rank_address']);
-            $bFallback = true;
-        }
-        if ($aTypeLabel && ((isset($aLine['localname']) && $aLine['localname']) || (isset($aLine['housenumber']) && $aLine['housenumber']))) {
-            $sTypeLabel = strtolower(isset($aTypeLabel['simplelabel'])?$aTypeLabel['simplelabel']:$aTypeLabel['label']);
-            $sTypeLabel = str_replace(' ', '_', $sTypeLabel);
-            if (!isset($aAddress[$sTypeLabel]) || (isset($aFallback[$sTypeLabel]) && $aFallback[$sTypeLabel]) || $aLine['class'] == 'place') {
-                $aAddress[$sTypeLabel] = $aLine['localname']?$aLine['localname']:$aLine['housenumber'];
-            }
-            $aFallback[$sTypeLabel] = $bFallback;
-        }
-    }
-    return $aAddress;
-}
-
-
 function addQuotes($s)
 {
     return "'".$s."'";
index 92efc8fec784a12b302d61d99bac8969601cd6ef..68fae7d1605dcde0b883be5e806dec791d662291 100644 (file)
@@ -32,25 +32,29 @@ if (empty($aPlace)) {
 
     $aFilteredPlaces['properties']['geocoding']['name'] = $aPlace['placename'];
 
-    $aFieldMappings = array(
-                       'house_number' => 'housenumber',
-                       'road' => 'street',
-                       'locality' => 'locality',
-                       'postcode' => 'postcode',
-                       'city' => 'city',
-                       'district' => 'district',
-                       'county' => 'county',
-                       'state' => 'state',
-                       'country' => 'country'
-                      );
+    if (isset($aPlace['address'])) {
+        $aFieldMappings = array(
+                           'house_number' => 'housenumber',
+                           'road' => 'street',
+                           'locality' => 'locality',
+                           'postcode' => 'postcode',
+                           'city' => 'city',
+                           'district' => 'district',
+                           'county' => 'county',
+                           'state' => 'state',
+                           'country' => 'country'
+                          );
 
-    foreach ($aFieldMappings as $sFrom => $sTo) {
-        if (isset($aPlace['aAddress'][$sFrom])) {
-            $aFilteredPlaces['properties']['geocoding'][$sTo] = $aPlace['aAddress'][$sFrom];
+        $aAddressNames = $aPlace['address']->getAddressNames();
+        foreach ($aFieldMappings as $sFrom => $sTo) {
+            if (isset($aAddressNames[$sFrom])) {
+                $aFilteredPlaces['properties']['geocoding'][$sTo] = $aAddressNames[$sFrom];
+            }
         }
-    }
 
-    $aFilteredPlaces['properties']['geocoding']['admin'] = $aPlace['aAddressAdminLevels'];
+        $aFilteredPlaces['properties']['geocoding']['admin']
+            = $aPlace['address']->getAdminLevels();
+    }
 
     if (isset($aPlace['asgeojson'])) {
         $aFilteredPlaces['geometry'] = json_decode($aPlace['asgeojson']);
@@ -72,6 +76,6 @@ if (empty($aPlace)) {
                                            'licence' => 'ODbL',
                                            'query' => $sQuery
                                           ),
-                           'features' => $aFilteredPlaces
+                           'features' => [$aFilteredPlaces]
                           ));
 }
index 8ef5713bedbe75e155dad3cc81863350b9c5448d..089a86b683273bb9c147af66d6f34bee0ce872dd 100644 (file)
@@ -33,7 +33,9 @@ if (empty($aPlace)) {
 
     $aFilteredPlaces['properties']['display_name'] = $aPlace['langaddress'];
 
-    if (isset($aPlace['aAddress'])) $aFilteredPlaces['properties']['address'] = $aPlace['aAddress'];
+    if (isset($aPlace['address'])) {
+        $aFilteredPlaces['properties']['address'] = $aPlace['address']->getAddressNames();
+    }
     if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['properties']['extratags'] = $aPlace['sExtraTags'];
     if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['properties']['namedetails'] = $aPlace['sNameDetails'];
 
index b620c63e831a504d9fca78adf4df33fc35b37cf9..691d6a749f8e32f09932b3c75be72b99f2172a07 100644 (file)
@@ -32,7 +32,9 @@ if (empty($aPlace)) {
 
     $aFilteredPlaces['display_name'] = $aPlace['langaddress'];
 
-    if (isset($aPlace['aAddress'])) $aFilteredPlaces['address'] = $aPlace['aAddress'];
+    if (isset($aPlace['address'])) {
+        $aFilteredPlaces['address'] = $aPlace['address']->getAddressNames();
+    }
     if (isset($aPlace['sExtraTags'])) $aFilteredPlaces['extratags'] = $aPlace['sExtraTags'];
     if (isset($aPlace['sNameDetails'])) $aFilteredPlaces['namedetails'] = $aPlace['sNameDetails'];
 
index 5eddfa3e2410a262d74d02655e4f4537bdf0bfdc..a17da738215b0ee0c354aa239750df4698f3999e 100644 (file)
@@ -48,9 +48,9 @@ if (empty($aPlace)) {
     }
     echo '>'.htmlspecialchars($aPlace['langaddress']).'</result>';
 
-    if (isset($aPlace['aAddress'])) {
+    if (isset($aPlace['address'])) {
         echo '<addressparts>';
-        foreach ($aPlace['aAddress'] as $sKey => $sValue) {
+        foreach ($aPlace['address']->getAddressNames() as $sKey => $sValue) {
             $sKey = str_replace(' ', '_', $sKey);
             echo "<$sKey>";
             echo htmlspecialchars($sValue);
index 513f3c2b8833a8ea6a20617aa9e961ca47ea6ea2..40b27a72e9dc9b607f4de61756b9bc335c6ce7e3 100644 (file)
@@ -49,8 +49,8 @@ foreach ($aBatchResults as $aSearchResults) {
             $aPlace['icon'] = $aPointDetails['icon'];
         }
 
-        if (isset($aPointDetails['address']) && !empty($aPointDetails['address'])) {
-            $aPlace['address'] = $aPointDetails['address'];
+        if (isset($aPointDetails['address'])) {
+            $aPlace['address'] = $aPointDetails['address']->getAddressNames();
         }
 
         if (isset($aPointDetails['asgeojson'])) {
index 6f822799dbc0161eaacfc0ae3b5a956e3142f498..29bfe0bf58d4fae3be47896c26d64b00e6bfcf03 100644 (file)
@@ -9,8 +9,8 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
                                )
               );
 
-    if (isset($aPlace['place_id'])) $aPlace['properties']['geocoding']['place_id'] = $aPointDetails['place_id'];
-    $sOSMType = formatOSMType($aPlace['osm_type']);
+    if (isset($aPointDetails['place_id'])) $aPlace['properties']['geocoding']['place_id'] = $aPointDetails['place_id'];
+    $sOSMType = formatOSMType($aPointDetails['osm_type']);
     if ($sOSMType) {
         $aPlace['properties']['geocoding']['osm_type'] = $sOSMType;
         $aPlace['properties']['geocoding']['osm_id'] = $aPointDetails['osm_id'];
@@ -22,25 +22,29 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
 
     $aPlace['properties']['geocoding']['name'] = $aPointDetails['placename'];
 
-    $aFieldMappings = array(
-                       'house_number' => 'housenumber',
-                       'road' => 'street',
-                       'locality' => 'locality',
-                       'postcode' => 'postcode',
-                       'city' => 'city',
-                       'district' => 'district',
-                       'county' => 'county',
-                       'state' => 'state',
-                       'country' => 'country'
-                      );
+    if (isset($aPointDetails['address'])) {
+        $aFieldMappings = array(
+                           'house_number' => 'housenumber',
+                           'road' => 'street',
+                           'locality' => 'locality',
+                           'postcode' => 'postcode',
+                           'city' => 'city',
+                           'district' => 'district',
+                           'county' => 'county',
+                           'state' => 'state',
+                           'country' => 'country'
+                          );
 
-    foreach ($aFieldMappings as $sFrom => $sTo) {
-        if (isset($aPointDetails['address'][$sFrom])) {
-            $aPlace['properties']['geocoding'][$sTo] = $aPointDetails['address'][$sFrom];
+        $aAddrNames = $aPointDetails['address']->getAddressNames();
+        foreach ($aFieldMappings as $sFrom => $sTo) {
+            if (isset($aAddrNames[$sFrom])) {
+                $aPlace['properties']['geocoding'][$sTo] = $aAddrNames[$sFrom];
+            }
         }
-    }
 
-    $aPlace['properties']['geocoding']['admin'] = $aPointDetails['aAddressAdminLevels'];
+        $aPlace['properties']['geocoding']['admin']
+            = $aPointDetails['address']->getAdminLevels();
+    }
 
     if (isset($aPointDetails['asgeojson'])) {
         $aPlace['geometry'] = json_decode($aPointDetails['asgeojson']);
index 0d04ddc70371b745a650eb2bed5cfee16de678ef..0847fba411b6713d2ea33fae56a42a2a7a8f4f82 100644 (file)
@@ -41,8 +41,8 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
         $aPlace['properties']['icon'] = $aPointDetails['icon'];
     }
 
-    if (isset($aPointDetails['address']) && !empty($aPointDetails['address'])) {
-        $aPlace['properties']['address'] = $aPointDetails['address'];
+    if (isset($aPointDetails['address'])) {
+        $aPlace['properties']['address'] = $aPointDetails['address']->getAddressNames();
     }
 
     if (isset($aPointDetails['asgeojson'])) {
index 30817c04025114210eb49e0649d6bf123d07ca68..6108aca4e005582d9446a75ca44737a0ab0ae5c3 100644 (file)
@@ -44,8 +44,8 @@ foreach ($aSearchResults as $iResNum => $aPointDetails) {
         $aPlace['icon'] = $aPointDetails['icon'];
     }
 
-    if (isset($aPointDetails['address']) && !empty($aPointDetails['address'])) {
-        $aPlace['address'] = $aPointDetails['address'];
+    if (isset($aPointDetails['address'])) {
+        $aPlace['address'] = $aPointDetails['address']->getAddressNames();
     }
 
     if (isset($aPointDetails['asgeojson'])) {
index 94bb7ec96a44cdbfae7a150e6044883650a4ead2..f67ba33bd2b7e56fa6cdfe2b8444dba502f8dd17 100644 (file)
@@ -116,7 +116,7 @@ foreach ($aSearchResults as $iResNum => $aResult) {
             echo '>';
         }
         echo "\n";
-        foreach ($aResult['address'] as $sKey => $sValue) {
+        foreach ($aResult['address']->getAddressNames() as $sKey => $sValue) {
             $sKey = str_replace(' ', '_', $sKey);
             echo "<$sKey>";
             echo htmlspecialchars($sValue);
index 115b0fd39554e33252d9051ebdb0ce9febf7572c..ccd0becdbb8a837fa62dd64e0b66481ee98ca276 100644 (file)
@@ -48,6 +48,10 @@ Feature: Simple Reverse Tests
           | param       | value   |
           | <parameter> | <value> |
         Then the result is valid geojson
+        When sending geocodejson reverse coordinates 53.603,10.041
+          | param       | value   |
+          | <parameter> | <value> |
+        Then the result is valid geocodejson
 
     Examples:
      | parameter        | value |
index 06c24a2ee014f002ea47ed50be2f9e76975f97db..5cd80a83de36f77dbd7fe643f0262bd0780c49b2 100644 (file)
@@ -27,6 +27,10 @@ Feature: Simple Tests
           | param       | value   |
           | <parameter> | <value> |
         Then at least 1 result is returned
+        When sending geocodejson search query "Hamburg"
+          | param       | value   |
+          | <parameter> | <value> |
+        Then at least 1 result is returned
 
     Examples:
      | parameter        | value |
index 1584d1ed7eeb78b316285f16270a75f3f8beaae8..62bc295eea0ca72bec9d5a1cbb753b94b2cda41a 100644 (file)
@@ -114,6 +114,9 @@ class SearchResponse(GenericResponse):
         self.parse_json()
         self.result = geojson_results_to_json_results(self.result)
 
+    def parse_geocodejson(self):
+        return self.parse_geojson()
+
     def parse_html(self):
         content, errors = tidy_document(self.page,
                                         options={'char-encoding' : 'utf8'})
@@ -195,6 +198,9 @@ class ReverseResponse(GenericResponse):
             return
         self.result = geojson_results_to_json_results(self.result[0])
 
+    def parse_geocodejson(self):
+        return self.parse_geojson()
+
     def parse_xml(self):
         et = ET.fromstring(self.page)
 
index 533188adea7c98e612a1d645e68eccb8c1864cc2..55ae1aaa055eaf93dfb4693bdf9c9b33edf77381 100644 (file)
@@ -3,12 +3,13 @@
 namespace Nominatim;
 
 require_once '../../lib/lib.php';
+require_once '../../lib/ClassTypes.php';
 
 class LibTest extends \PHPUnit_Framework_TestCase
 {
     public function testGetClassTypesWithImportance()
     {
-        $aClasses = getClassTypesWithImportance();
+        $aClasses = ClassTypes\getListWithImportance();
 
         $this->assertGreaterThan(
             200,
@@ -31,22 +32,22 @@ class LibTest extends \PHPUnit_Framework_TestCase
 
     public function testGetResultDiameter()
     {
-        $aResult = array();
+        $aResult = array('class' => '', 'type' => '');
         $this->assertEquals(
             0.0001,
-            getResultDiameter($aResult)
+            ClassTypes\getProperty($aResult, 'defdiameter', 0.0001)
         );
 
         $aResult = array('class' => 'place', 'type' => 'country');
         $this->assertEquals(
             15,
-            getResultDiameter($aResult)
+            ClassTypes\getProperty($aResult, 'defdiameter', 0.0001)
         );
 
         $aResult = array('class' => 'boundary', 'type' => 'administrative', 'admin_level' => 6);
         $this->assertEquals(
             0.32,
-            getResultDiameter($aResult)
+            ClassTypes\getProperty($aResult, 'defdiameter', 0.0001)
         );
     }
 
index 08d1d2d86571eaedb40ba6cf3650521cc7928203..c9e86312c9cc63a8c9da6954db45b214c9adff4e 100755 (executable)
@@ -5,6 +5,7 @@ require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
 require_once(CONST_BasePath.'/lib/init-website.php');
 require_once(CONST_BasePath.'/lib/log.php');
 require_once(CONST_BasePath.'/lib/output.php');
+require_once(CONST_BasePath.'/lib/AddressDetails.php');
 ini_set('memory_limit', '200M');
 
 $oParams = new Nominatim\ParameterParser();
@@ -135,15 +136,7 @@ if (!$aPointDetails) {
 }
 
 $aPointDetails['localname'] = $aPointDetails['localname']?$aPointDetails['localname']:$aPointDetails['housenumber'];
-
-$aClassType = getClassTypesWithImportance();
-
-$sPointClassType = $aPointDetails['class'].':'.$aPointDetails['type'];
-if (isset($aClassType[$sPointClassType]) && $aClassType[$sPointClassType]['icon']) {
-    $aPointDetails['icon'] = $aClassType[$sPointClassType]['icon'];
-} else {
-    $aPointDetails['icon'] = false;
-}
+$aPointDetails['icon'] = Nominatim\ClassTypes\getProperty($aPointDetails, 'icon', false);
 
 // Get all alternative names (languages, etc)
 $sSQL = 'SELECT (each(name)).key,(each(name)).value FROM placex ';
@@ -172,14 +165,8 @@ if (PEAR::isError($aPointDetails['aExtraTags'])) { // possible timeout
 // Address
 $aAddressLines = false;
 if ($bIncludeAddressDetails) {
-    $aAddressLines = getAddressDetails(
-        $oDB,
-        $sLanguagePrefArraySQL,
-        $iPlaceID,
-        $aPointDetails['country_code'],
-        -1,
-        true
-    );
+    $oDetails = new Nominatim\AddressDetails($oDB, $iPlaceID, -1, $sLanguagePrefArraySQL);
+    $aAddressLines = $oDetails->getAddressDetails(true);
 }
 
 // Linked places
index 9b488f8352b5fae1df0d4df3d13a3a8f0e1b4f97..3ac4f3231a8a8f2d43a22c3db8ea41f5c1cd3b16 100755 (executable)
@@ -4,7 +4,7 @@
 require_once(dirname(dirname(__FILE__)).'/settings/settings.php');
 require_once(CONST_BasePath.'/lib/init-website.php');
 require_once(CONST_BasePath.'/lib/log.php');
-require_once(CONST_BasePath.'/lib/PlaceLookup.php');
+require_once(CONST_BasePath.'/lib/AddressDetails.php');
 require_once(CONST_BasePath.'/lib/output.php');
 ini_set('memory_limit', '200M');
 
@@ -56,11 +56,9 @@ if (CONST_Use_Aux_Location_data) {
     if ($iParentPlaceID) $iPlaceID = $iParentPlaceID;
 }
 
-$oPlaceLookup = new Nominatim\PlaceLookup($oDB);
-$oPlaceLookup->setLanguagePreference($aLangPrefOrder);
-$oPlaceLookup->setIncludeAddressDetails(true);
 
-$aPlaceAddress = array_reverse($oPlaceLookup->getAddressDetails($iPlaceID));
+$oAddressLookup = new AddressDetails($oDB, $iPlaceID, -1, $aLangPrefOrder);
+$aPlaceAddress = array_reverse($oAddressLookup->getAddressDetails());
 
 if (empty($aPlaceAddress)) userError('Unknown place id.');
 
@@ -102,18 +100,12 @@ $aParentOfLines = chksql($oDB->getAll($sSQL));
 
 if (!empty($aParentOfLines)) {
     echo '<h2>Parent Of:</h2>';
-    $aClassType = getClassTypesWithImportance();
     $aGroupedAddressLines = array();
     foreach ($aParentOfLines as $aAddressLine) {
-        if (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'])
-            && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label']
-        ) {
-            $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type'].':'.$aAddressLine['admin_level']]['label'];
-        } elseif (isset($aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'])
-            && $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label']
-        ) {
-            $aAddressLine['label'] = $aClassType[$aAddressLine['class'].':'.$aAddressLine['type']]['label'];
-        } else $aAddressLine['label'] = ucwords($aAddressLine['type']);
+        $aAddressLine['label'] = Nominatim\ClassTypes\getProperty($aAddressLine, 'label');
+        if (!$aAddressLine['label']) {
+            $aAddressLine['label'] = ucwords($aAddressLine['type']);
+        }
 
         if (!isset($aGroupedAddressLines[$aAddressLine['label']])) $aGroupedAddressLines[$aAddressLine['label']] = array();
             $aGroupedAddressLines[$aAddressLine['label']][] = $aAddressLine;
index 695a083a4fb3c5acb800f55c36b0e856048e7e99..f09506a4c0de7ae1aef97afa22b38a4aecc9cae1 100755 (executable)
@@ -25,6 +25,7 @@ $aCleanedQueryParts = array();
 
 $oPlaceLookup = new Nominatim\PlaceLookup($oDB);
 $oPlaceLookup->loadParamArray($oParams);
+$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
 
 $aOsmIds = explode(',', $oParams->getString('osm_ids', ''));
 
index 952517235d81903ddb3b3188172251935b618d0b..5f9268c680e31e222370b001b8f9edcdeb355134 100755 (executable)
@@ -23,10 +23,7 @@ $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder);
 
 $oPlaceLookup = new Nominatim\PlaceLookup($oDB);
 $oPlaceLookup->loadParamArray($oParams);
-if ($sOutputFormat == 'geocodejson') {
-    $oPlaceLookup->setIncludeAddressDetails(true);
-    $oPlaceLookup->setAddressAdminLevels(true);
-}
+$oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true));
 
 $sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R'));
 $iOsmId = $oParams->getInt('osm_id', -1);
@@ -54,12 +51,11 @@ if ($sOsmType && $iOsmId > 0) {
 }
 
 if (isset($aPlace)) {
-    $fRadius = $fDiameter = getResultDiameter($aPlace);
     $aOutlineResult = $oPlaceLookup->getOutlines(
         $aPlace['place_id'],
         $aPlace['lon'],
         $aPlace['lat'],
-        $fRadius,
+        Nominatim\ClassTypes\getProperty($aPlace, 'defdiameter', 0.0001),
         $fLat,
         $fLon
     );