From: Sarah Hoffmann Date: Sat, 4 Aug 2018 21:19:32 +0000 (+0200) Subject: Merge pull request #1110 from lonvia/remove-address-check-for-long-lines X-Git-Tag: v3.2.0~34 X-Git-Url: https://git.openstreetmap.org/nominatim.git/commitdiff_plain/9bdbbec0c8141bdcb22fb562b4e1235dadcc446c?hp=713ea080d2cf6b5a5e412b63111f81336fa2f7f0 Merge pull request #1110 from lonvia/remove-address-check-for-long-lines Remove special search for address part for long ways --- diff --git a/.travis.yml b/.travis.yml index 1184d283..2397e0c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,16 +16,17 @@ install: before_script: - psql -U postgres -c "create extension postgis" script: - - cd $TRAVIS_BUILD_DIR/build - - if [[ $TEST_SUITE == "monaco" ]]; then wget --no-verbose --output-document=../data/monaco.osm.pbf http://download.geofabrik.de/europe/monaco-latest.osm.pbf; fi - - if [[ $TEST_SUITE == "monaco" ]]; then /usr/bin/env php ./utils/setup.php --osm-file ../data/monaco.osm.pbf --osm2pgsql-cache 1000 --all 2>&1 | grep -v 'ETA (seconds)'; fi - - if [[ $TEST_SUITE == "monaco" ]]; then /usr/bin/env php ./utils/specialphrases.php --wiki-import | psql -d test_api_nominatim >/dev/null; fi + - cd $TRAVIS_BUILD_DIR/ + - if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi - cd $TRAVIS_BUILD_DIR/test/php - if [[ $TEST_SUITE == "tests" ]]; then phpunit ./ ; fi - - if [[ $TEST_SUITE == "tests" ]]; then phpcs --report-width=120 . ; fi - cd $TRAVIS_BUILD_DIR/test/bdd - # behave --format=progress3 api - if [[ $TEST_SUITE == "tests" ]]; then behave --format=progress3 db ; fi - if [[ $TEST_SUITE == "tests" ]]; then behave --format=progress3 osm2pgsql ; fi + - cd $TRAVIS_BUILD_DIR/build + - if [[ $TEST_SUITE == "monaco" ]]; then wget --no-verbose --output-document=../data/monaco.osm.pbf http://download.geofabrik.de/europe/monaco-latest.osm.pbf; fi + - if [[ $TEST_SUITE == "monaco" ]]; then /usr/bin/env php ./utils/setup.php --osm-file ../data/monaco.osm.pbf --osm2pgsql-cache 1000 --all 2>&1 | grep -v 'ETA (seconds)'; fi + - if [[ $TEST_SUITE == "monaco" ]]; then /usr/bin/env php ./utils/specialphrases.php --wiki-import | psql -d test_api_nominatim >/dev/null; fi notifications: email: false diff --git a/data/words.sql b/data/words.sql index 85578f20..ac250739 100644 --- a/data/words.sql +++ b/data/words.sql @@ -18,12 +18,13 @@ SET default_with_oids = false; -- Name: word_frequencies; Type: TABLE; Schema: public; Owner: -; Tablespace: -- +DROP TABLE IF EXISTS word_frequencies; + CREATE TABLE word_frequencies ( word_token text, count bigint ); - -- -- Data for Name: word_frequencies; Type: TABLE DATA; Schema: public; Owner: - -- diff --git a/lib/AddressDetails.php b/lib/AddressDetails.php index 8a4005d9..badf868d 100644 --- a/lib/AddressDetails.php +++ b/lib/AddressDetails.php @@ -114,4 +114,9 @@ class AddressDetails } return $aAddress; } + + public function debugInfo() + { + return $this->aAddressLines; + } } diff --git a/lib/ClassTypes.php b/lib/ClassTypes.php index c56e514e..d46847f1 100644 --- a/lib/ClassTypes.php +++ b/lib/ClassTypes.php @@ -85,7 +85,7 @@ function getList() '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), + 'place:island' => array('label' => 'Island', 'frequency' => 288, '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), @@ -93,35 +93,35 @@ function getList() '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), + 'landuse:farm' => array('label' => 'Farm', 'frequency' => 1201, 'defdiameter' => 0.02), + 'place:farm' => array('label' => 'Farm', 'frequency' => 1162, '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'), + 'highway:motorway_junction' => array('label' => 'Motorway Junction', 'frequency' => 1126, 'simplelabel' => 'Junction'), + 'highway:motorway' => array('label' => 'Motorway', 'frequency' => 4627, 'simplelabel' => 'Road'), + 'highway:trunk' => array('label' => 'Trunk', 'frequency' => 23084, 'simplelabel' => 'Road'), + 'highway:primary' => array('label' => 'Primary', 'frequency' => 32138, 'simplelabel' => 'Road'), + 'highway:secondary' => array('label' => 'Secondary', 'frequency' => 25807, 'simplelabel' => 'Road'), + 'highway:tertiary' => array('label' => 'Tertiary', 'frequency' => 29829, 'simplelabel' => 'Road'), + 'highway:residential' => array('label' => 'Residential', 'frequency' => 361498, 'simplelabel' => 'Road'), + 'highway:unclassified' => array('label' => 'Unclassified', 'frequency' => 66441, 'simplelabel' => 'Road'), + 'highway:living_street' => array('label' => 'Living Street', 'frequency' => 710, 'simplelabel' => 'Road'), + 'highway:service' => array('label' => 'Service', 'frequency' => 9963, 'simplelabel' => 'Road'), + 'highway:track' => array('label' => 'Track', 'frequency' => 2565, 'simplelabel' => 'Road'), + 'highway:road' => array('label' => 'Road', 'frequency' => 591, 'simplelabel' => 'Road'), + 'highway:byway' => array('label' => 'Byway', 'frequency' => 346, 'simplelabel' => 'Road'), + 'highway:bridleway' => array('label' => 'Bridleway', 'frequency' => 1556), + 'highway:cycleway' => array('label' => 'Cycleway', 'frequency' => 2419), + 'highway:pedestrian' => array('label' => 'Pedestrian', 'frequency' => 2757), + 'highway:footway' => array('label' => 'Footway', 'frequency' => 15008), + 'highway:steps' => array('label' => 'Steps', 'frequency' => 444, 'simplelabel' => 'Footway'), + 'highway:motorway_link' => array('label' => 'Motorway Link', 'frequency' => 795, 'simplelabel' => 'Road'), + 'highway:trunk_link' => array('label' => 'Trunk Link', 'frequency' => 1258, 'simplelabel' => 'Road'), + 'highway:primary_link' => array('label' => 'Primary Link', 'frequency' => 313, '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' => ''), + 'landuse:industrial' => array('label' => 'Industrial', 'frequency' => 1062), + 'landuse:residential' => array('label' => 'Residential', 'frequency' => 886), + 'landuse:retail' => array('label' => 'Retail', 'frequency' => 754), + 'landuse:commercial' => array('label' => 'Commercial', 'frequency' => 657), '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), @@ -141,20 +141,20 @@ function getList() '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:public_building' => array('label' => 'Public Building', 'frequency' => 985), '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:townhall' => array('label' => 'Townhall', 'frequency' => 242), + 'amenity:community_centre' => array('label' => 'Community Centre', 'frequency' => 157), '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' => ''), + 'leisure:park' => array('label' => 'Park', 'frequency' => 2378), + 'amenity:park' => array('label' => 'Park', 'frequency' => 53), + 'landuse:park' => array('label' => 'Park', 'frequency' => 50), + 'landuse:recreation_ground' => array('label' => 'Recreation Ground', 'frequency' => 517), 'tourism:hotel' => array('label' => 'Hotel', 'frequency' => 2150, 'icon' => 'accommodation_hotel2'), - 'tourism:motel' => array('label' => 'Motel', 'frequency' => 43, 'icon' => ''), + 'tourism:motel' => array('label' => 'Motel', 'frequency' => 43), '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'), @@ -170,17 +170,17 @@ function getList() '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' => ''), + 'waterway:waterfall' => array('label' => 'Waterfall', 'frequency' => 24), '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' => ''), + 'natural:water' => array('label' => 'Water', 'frequency' => 1790), + 'landuse:forest' => array('label' => 'Forest', 'frequency' => 467), + 'landuse:cemetery' => array('label' => 'Cemetery', 'frequency' => 463), + 'landuse:allotments' => array('label' => 'Allotments', 'frequency' => 408), + 'landuse:farmyard' => array('label' => 'Farmyard', 'frequency' => 397), + 'railway:rail' => array('label' => 'Rail', 'frequency' => 4894), + 'waterway:canal' => array('label' => 'Canal', 'frequency' => 1723), + 'waterway:river' => array('label' => 'River', 'frequency' => 4089), + 'waterway:stream' => array('label' => 'Stream', 'frequency' => 2684), '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'), @@ -189,186 +189,186 @@ function getList() '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:newsagent' => array('label' => 'Newsagent', 'frequency' => 132), 'shop:bakery' => array('label' => 'Bakery', 'frequency' => 129, 'icon' => 'shopping_bakery'), - 'shop:furniture' => array('label' => 'Furniture', 'frequency' => 124, 'icon' => ''), + 'shop:furniture' => array('label' => 'Furniture', 'frequency' => 124), '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:electronics' => array('label' => 'Electronics', 'frequency' => 96), + 'shop:department_store' => array('label' => 'Department Store', 'frequency' => 86), + 'shop:books' => array('label' => 'Books', 'frequency' => 85), + 'shop:yes' => array('label' => 'Shop', 'frequency' => 68), + 'shop:outdoor' => array('label' => 'Outdoor', 'frequency' => 67), + 'shop:mall' => array('label' => 'Mall', 'frequency' => 63), + 'shop:florist' => array('label' => 'Florist', 'frequency' => 61), + 'shop:charity' => array('label' => 'Charity', 'frequency' => 60), + 'shop:hardware' => array('label' => 'Hardware', 'frequency' => 59), 'shop:laundry' => array('label' => 'Laundry', 'frequency' => 51, 'icon' => 'shopping_laundrette'), - 'shop:shoes' => array('label' => 'Shoes', 'frequency' => 49, 'icon' => ''), + 'shop:shoes' => array('label' => 'Shoes', 'frequency' => 49), '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:dry_cleaning' => array('label' => 'Dry Cleaning', 'frequency' => 46), + 'shop:carpet' => array('label' => 'Carpet', 'frequency' => 45), + 'shop:computer' => array('label' => 'Computer', 'frequency' => 44), '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:mobile_phone' => array('label' => 'Mobile Phone', 'frequency' => 37), + 'shop:sports' => array('label' => 'Sports', 'frequency' => 37), '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' => ''), + 'shop:pet' => array('label' => 'Pet', 'frequency' => 29), + 'shop:beauty' => array('label' => 'Beauty', 'frequency' => 28), + 'shop:stationery' => array('label' => 'Stationery', 'frequency' => 25), + 'shop:shopping_centre' => array('label' => 'Shopping Centre', 'frequency' => 25), + 'shop:general' => array('label' => 'General', 'frequency' => 25), + 'shop:electrical' => array('label' => 'Electrical', 'frequency' => 25), + 'shop:toys' => array('label' => 'Toys', 'frequency' => 23), + 'shop:jeweller' => array('label' => 'Jeweller', 'frequency' => 23), + 'shop:betting' => array('label' => 'Betting', 'frequency' => 23), + 'shop:household' => array('label' => 'Household', 'frequency' => 21), + 'shop:travel_agency' => array('label' => 'Travel Agency', 'frequency' => 21), + 'shop:hifi' => array('label' => 'Hifi', 'frequency' => 21), + 'amenity:shop' => array('label' => 'Shop', 'frequency' => 61), '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), + 'place:house' => array('label' => 'House', 'frequency' => 2086, 'defzoom' => 18), + 'place:house_name' => array('label' => 'House', 'frequency' => 2086, 'defzoom' => 18), + 'place:house_number' => array('label' => 'House Number', 'frequency' => 2086, 'defzoom' => 18), + 'place:country_code' => array('label' => 'Country Code', 'frequency' => 2086, 'defzoom' => 18), // - 'leisure:pitch' => array('label' => 'Pitch', 'frequency' => 762, 'icon' => ''), - 'highway:unsurfaced' => array('label' => 'Unsurfaced', 'frequency' => 492, 'icon' => ''), + 'leisure:pitch' => array('label' => 'Pitch', 'frequency' => 762), + 'highway:unsurfaced' => array('label' => 'Unsurfaced', 'frequency' => 492), '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' => ''), + 'railway:subway' => array('label' => 'Subway', 'frequency' => 385), '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' => ''), + 'leisure:nature_reserve' => array('label' => 'Nature Reserve', 'frequency' => 342), + 'leisure:common' => array('label' => 'Common', 'frequency' => 322), + 'waterway:lock_gate' => array('label' => 'Lock Gate', 'frequency' => 321), + 'natural:fell' => array('label' => 'Fell', 'frequency' => 308), + 'amenity:nightclub' => array('label' => 'Nightclub', 'frequency' => 292), + 'highway:path' => array('label' => 'Path', 'frequency' => 287), + 'leisure:garden' => array('label' => 'Garden', 'frequency' => 285), + 'landuse:reservoir' => array('label' => 'Reservoir', 'frequency' => 276), + 'leisure:playground' => array('label' => 'Playground', 'frequency' => 264), + 'leisure:stadium' => array('label' => 'Stadium', 'frequency' => 212), 'historic:mine' => array('label' => 'Mine', 'frequency' => 193, 'icon' => 'poi_mine'), - 'natural:cliff' => array('label' => 'Cliff', 'frequency' => 193, 'icon' => ''), + 'natural:cliff' => array('label' => 'Cliff', 'frequency' => 193), '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:kindergarten' => array('label' => 'Kindergarten', 'frequency' => 179), + 'highway:construction' => array('label' => 'Construction', 'frequency' => 176), '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' => ''), + 'amenity:emergency_phone' => array('label' => 'Emergency Phone', 'frequency' => 164), + 'waterway:lock' => array('label' => 'Lock', 'frequency' => 146), + 'waterway:riverbank' => array('label' => 'Riverbank', 'frequency' => 143), + 'natural:coastline' => array('label' => 'Coastline', 'frequency' => 142), 'tourism:viewpoint' => array('label' => 'Viewpoint', 'frequency' => 140, 'icon' => 'tourist_view_point'), - 'tourism:hostel' => array('label' => 'Hostel', 'frequency' => 140, 'icon' => ''), + 'tourism:hostel' => array('label' => 'Hostel', 'frequency' => 140), '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:halt' => array('label' => 'Halt', 'frequency' => 135), + 'railway:platform' => array('label' => 'Platform', 'frequency' => 134), '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' => ''), + 'place:moor' => array('label' => 'Moor', 'frequency' => 118), + 'amenity:grave_yard' => array('label' => 'Grave Yard', 'frequency' => 110), + 'waterway:drain' => array('label' => 'Drain', 'frequency' => 108), + 'landuse:grass' => array('label' => 'Grass', 'frequency' => 106), + 'landuse:village_green' => array('label' => 'Village Green', 'frequency' => 106), + 'natural:bay' => array('label' => 'Bay', 'frequency' => 102), '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' => ''), + 'leisure:marina' => array('label' => 'Marina', 'frequency' => 98), + 'highway:stile' => array('label' => 'Stile', 'frequency' => 97), + 'natural:moor' => array('label' => 'Moor', 'frequency' => 95), + 'railway:light_rail' => array('label' => 'Light Rail', 'frequency' => 91), + 'railway:narrow_gauge' => array('label' => 'Narrow Gauge', 'frequency' => 90), + 'natural:land' => array('label' => 'Land', 'frequency' => 86), + 'amenity:village_hall' => array('label' => 'Village Hall', 'frequency' => 82), + 'waterway:dock' => array('label' => 'Dock', 'frequency' => 80), + 'amenity:veterinary' => array('label' => 'Veterinary', 'frequency' => 79), + 'landuse:brownfield' => array('label' => 'Brownfield', 'frequency' => 77), + 'leisure:track' => array('label' => 'Track', 'frequency' => 76), + 'railway:historic_station' => array('label' => 'Historic Station', 'frequency' => 74), + 'landuse:construction' => array('label' => 'Construction', 'frequency' => 72), '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' => ''), + 'landuse:quarry' => array('label' => 'Quarry', 'frequency' => 71), + 'amenity:telephone' => array('label' => 'Telephone', 'frequency' => 70), + 'highway:traffic_signals' => array('label' => 'Traffic Signals', 'frequency' => 66), + 'natural:heath' => array('label' => 'Heath', 'frequency' => 62), + 'historic:house' => array('label' => 'House', 'frequency' => 61), + 'amenity:social_club' => array('label' => 'Social Club', 'frequency' => 61), + 'landuse:military' => array('label' => 'Military', 'frequency' => 61), + 'amenity:health_centre' => array('label' => 'Health Centre', 'frequency' => 59), + 'historic:building' => array('label' => 'Building', 'frequency' => 58), + 'amenity:clinic' => array('label' => 'Clinic', 'frequency' => 57), + 'highway:services' => array('label' => 'Services', 'frequency' => 56), + 'amenity:ferry_terminal' => array('label' => 'Ferry Terminal', 'frequency' => 55), + 'natural:marsh' => array('label' => 'Marsh', 'frequency' => 55), + 'natural:hill' => array('label' => 'Hill', 'frequency' => 54), + 'highway:raceway' => array('label' => 'Raceway', 'frequency' => 53), + 'amenity:taxi' => array('label' => 'Taxi', 'frequency' => 47), + 'amenity:take_away' => array('label' => 'Take Away', 'frequency' => 45), + 'amenity:car_rental' => array('label' => 'Car Rental', 'frequency' => 44), + 'place:islet' => array('label' => 'Islet', 'frequency' => 44), + 'amenity:nursery' => array('label' => 'Nursery', 'frequency' => 44), + 'amenity:nursing_home' => array('label' => 'Nursing Home', 'frequency' => 43), + 'amenity:toilets' => array('label' => 'Toilets', 'frequency' => 38), + 'amenity:hall' => array('label' => 'Hall', 'frequency' => 38), + 'waterway:boatyard' => array('label' => 'Boatyard', 'frequency' => 36), + 'highway:mini_roundabout' => array('label' => 'Mini Roundabout', 'frequency' => 35), + 'historic:manor' => array('label' => 'Manor', 'frequency' => 35), + 'tourism:chalet' => array('label' => 'Chalet', 'frequency' => 34), + 'amenity:bicycle_parking' => array('label' => 'Bicycle Parking', 'frequency' => 34), + 'amenity:hotel' => array('label' => 'Hotel', 'frequency' => 34), + 'waterway:weir' => array('label' => 'Weir', 'frequency' => 33), + 'natural:wetland' => array('label' => 'Wetland', 'frequency' => 33), + 'natural:cave_entrance' => array('label' => 'Cave Entrance', 'frequency' => 32), + 'amenity:crematorium' => array('label' => 'Crematorium', 'frequency' => 31), + 'tourism:picnic_site' => array('label' => 'Picnic Site', 'frequency' => 31), + 'landuse:wood' => array('label' => 'Wood', 'frequency' => 30), + 'landuse:basin' => array('label' => 'Basin', 'frequency' => 30), + 'natural:tree' => array('label' => 'Tree', 'frequency' => 30), + 'leisure:slipway' => array('label' => 'Slipway', 'frequency' => 29), + 'landuse:meadow' => array('label' => 'Meadow', 'frequency' => 29), + 'landuse:piste' => array('label' => 'Piste', 'frequency' => 28), + 'amenity:care_home' => array('label' => 'Care Home', 'frequency' => 28), + 'amenity:club' => array('label' => 'Club', 'frequency' => 28), + 'amenity:medical_centre' => array('label' => 'Medical Centre', 'frequency' => 27), + 'historic:roman_road' => array('label' => 'Roman Road', 'frequency' => 27), + 'historic:fort' => array('label' => 'Fort', 'frequency' => 26), + 'railway:subway_entrance' => array('label' => 'Subway Entrance', 'frequency' => 26), + 'historic:yes' => array('label' => 'Historic', 'frequency' => 25), + 'highway:gate' => array('label' => 'Gate', 'frequency' => 25), + 'leisure:fishing' => array('label' => 'Fishing', 'frequency' => 24), + 'historic:museum' => array('label' => 'Museum', 'frequency' => 24), + 'amenity:car_wash' => array('label' => 'Car Wash', 'frequency' => 24), + 'railway:level_crossing' => array('label' => 'Level Crossing', 'frequency' => 23), + 'leisure:bird_hide' => array('label' => 'Bird Hide', 'frequency' => 23), + 'natural:headland' => array('label' => 'Headland', 'frequency' => 21), + 'tourism:apartments' => array('label' => 'Apartments', 'frequency' => 21), + 'amenity:shopping' => array('label' => 'Shopping', 'frequency' => 21), + 'natural:scrub' => array('label' => 'Scrub', 'frequency' => 20), + 'natural:fen' => array('label' => 'Fen', 'frequency' => 20), + 'building:yes' => array('label' => 'Building', 'frequency' => 200), + 'mountain_pass:yes' => array('label' => 'Mountain Pass', 'frequency' => 200), - 'amenity:parking' => array('label' => 'Parking', 'frequency' => 3157, 'icon' => ''), + 'amenity:parking' => array('label' => 'Parking', 'frequency' => 3157), '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:postcode' => array('label' => 'Postcode', 'frequency' => 27267), + 'amenity:post_box' => array('label' => 'Post Box', 'frequency' => 9613), - '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' => ''), + 'place:houses' => array('label' => 'Houses', 'frequency' => 85), + 'railway:preserved' => array('label' => 'Preserved', 'frequency' => 227), + 'waterway:derelict_canal' => array('label' => 'Derelict Canal', 'frequency' => 21), + 'amenity:dead_pub' => array('label' => 'Dead Pub', 'frequency' => 20), + 'railway:disused_station' => array('label' => 'Disused Station', 'frequency' => 114), + 'railway:abandoned' => array('label' => 'Abandoned', 'frequency' => 641), + 'railway:disused' => array('label' => 'Disused', 'frequency' => 72), ); } diff --git a/lib/DebugHtml.php b/lib/DebugHtml.php index ff1724d2..a600fae5 100644 --- a/lib/DebugHtml.php +++ b/lib/DebugHtml.php @@ -153,6 +153,8 @@ class Debug $sPre = ', '; } } + } elseif (is_object($mVar) && method_exists($mVar, 'debugInfo')) { + Debug::outputVar($mVar->debugInfo(), $sPreNL); } else { Debug::outputSimpleVar($mVar); } diff --git a/lib/ReverseGeocode.php b/lib/ReverseGeocode.php index 8e5e8bd1..5648fedf 100644 --- a/lib/ReverseGeocode.php +++ b/lib/ReverseGeocode.php @@ -106,17 +106,21 @@ class ReverseGeocode if ($aPoly) { $sCountryCode = $aPoly['country_code']; - $sSQL = 'SELECT place_id, ST_distance('.$sPointSQL.', geometry) as distance'; + // look for place nodes with the given country code + $sSQL = 'SELECT place_id FROM'; + $sSQL .= ' (SELECT place_id, rank_search,'; + $sSQL .= ' ST_distance('.$sPointSQL.', geometry) as distance'; $sSQL .= ' FROM placex'; $sSQL .= ' WHERE osm_type = \'N\''; $sSQL .= ' AND country_code = \''.$sCountryCode.'\''; - $sSQL .= ' AND rank_address > 0'; - $sSQL .= ' AND rank_address <= ' .min(25, $iMaxRank); + $sSQL .= ' AND rank_search > 4'; + $sSQL .= ' AND rank_search <= ' .min(25, $iMaxRank); $sSQL .= ' AND type != \'postcode\''; $sSQL .= ' AND name IS NOT NULL '; $sSQL .= ' and indexed_status = 0 and linked_place_id is null'; - $sSQL .= ' AND ST_DWithin('.$sPointSQL.', geometry, 1.0)'; - $sSQL .= ' ORDER BY distance ASC, rank_address DESC'; + $sSQL .= ' AND ST_DWithin('.$sPointSQL.', geometry, 5.0)) p '; + $sSQL .= 'WHERE distance <= reverse_place_diameter(rank_search)'; + $sSQL .= ' ORDER BY rank_search DESC, distance ASC'; $sSQL .= ' LIMIT 1'; if (CONST_Debug) var_dump($sSQL); @@ -127,6 +131,23 @@ class ReverseGeocode if ($aPlacNode) { return $aPlacNode; } + + // still nothing, then return the country object + $sSQL = 'SELECT place_id, ST_distance('.$sPointSQL.', centroid) as distance'; + $sSQL .= ' FROM placex'; + $sSQL .= ' WHERE country_code = \''.$sCountryCode.'\''; + $sSQL .= ' AND rank_search = 4 AND rank_address = 4'; + $sSQL .= ' AND class in (\'boundary\', \'place\')'; + $sSQL .= ' ORDER BY distance ASC'; + + if (CONST_Debug) var_dump($sSQL); + $aPlacNode = chksql( + $this->oDB->getRow($sSQL), + 'Could not determine place node.' + ); + if ($aPlacNode) { + return $aPlacNode; + } } } @@ -138,13 +159,13 @@ class ReverseGeocode // polygon search begins at suburb-level if ($iMaxRank > 25) $iMaxRank = 25; // no polygon search over country-level - if ($iMaxRank < 4) $iMaxRank = 4; + if ($iMaxRank < 5) $iMaxRank = 5; // search for polygon $sSQL = 'SELECT place_id, parent_place_id, rank_address, rank_search FROM'; $sSQL .= '(select place_id, parent_place_id, rank_address, rank_search, country_code, geometry'; $sSQL .= ' FROM placex'; $sSQL .= ' WHERE ST_GeometryType(geometry) in (\'ST_Polygon\', \'ST_MultiPolygon\')'; - $sSQL .= ' AND rank_address Between 4 AND ' .$iMaxRank; + $sSQL .= ' AND rank_address Between 5 AND ' .$iMaxRank; $sSQL .= ' AND geometry && '.$sPointSQL; $sSQL .= ' AND type != \'postcode\' '; $sSQL .= ' AND name is not null'; @@ -165,49 +186,27 @@ class ReverseGeocode $iPlaceID = $aPoly['place_id']; if ($iRankAddress != $iMaxRank) { - //search diameter for the place node search - if ($iMaxRank <= 4) { - $fSearchDiam = 4; - } elseif ($iMaxRank <= 8) { - $fSearchDiam = 2; - } elseif ($iMaxRank <= 10) { - $fSearchDiam = 1; - } elseif ($iMaxRank <= 12) { - $fSearchDiam = 0.8; - } elseif ($iMaxRank <= 17) { - $fSearchDiam = 0.6; - } elseif ($iMaxRank <= 18) { - $fSearchDiam = 0.2; - } elseif ($iMaxRank <= 25) { - $fSearchDiam = 0.1; - } - - $sSQL = 'SELECT place_id'; - $sSQL .= ' FROM ('; - $sSQL .= ' SELECT place_id, rank_address,country_code, geometry,'; + $sSQL = 'SELECT place_id FROM '; + $sSQL .= '(SELECT place_id, rank_search, country_code, geometry,'; $sSQL .= ' ST_distance('.$sPointSQL.', geometry) as distance'; $sSQL .= ' FROM placex'; $sSQL .= ' WHERE osm_type = \'N\''; - if ($iRankAddress = 16) { - // using rank_search because of a better differentiation for place nodes at rank_address 16 - $sSQL .= ' AND rank_search > '.$iRankSearch; - $sSQL .= ' AND rank_search <= ' .$iMaxRank; - $sSQL .= ' AND class = \'place\''; - } else { - $sSQL .= ' AND rank_address > '.$iRankAddress; - $sSQL .= ' AND rank_address <= ' .$iMaxRank; - } - $sSQL .= ' AND ST_DWithin('.$sPointSQL.', geometry, '.$fSearchDiam.')'; + // using rank_search because of a better differentiation + // for place nodes at rank_address 16 + $sSQL .= ' AND rank_search > '.$iRankSearch; + $sSQL .= ' AND rank_search <= ' .$iMaxRank; + $sSQL .= ' AND class = \'place\''; $sSQL .= ' AND type != \'postcode\''; $sSQL .= ' AND name IS NOT NULL '; - $sSQL .= ' and indexed_status = 0 and linked_place_id is null'; + $sSQL .= ' AND indexed_status = 0 AND linked_place_id is null'; // preselection through bbox $sSQL .= ' AND (SELECT geometry FROM placex WHERE place_id = '.$iPlaceID.') && geometry'; $sSQL .= ' ORDER BY distance ASC,'; $sSQL .= ' rank_address DESC'; $sSQL .= ' limit 500) as a'; $sSQL .= ' WHERE ST_CONTAINS((SELECT geometry FROM placex WHERE place_id = '.$iPlaceID.'), geometry )'; - $sSQL .= ' ORDER BY distance ASC, rank_address DESC'; + $sSQL .= ' AND distance <= reverse_place_diameter(rank_search)'; + $sSQL .= ' ORDER BY distance ASC, rank_search DESC'; $sSQL .= ' LIMIT 1'; if (CONST_Debug) var_dump($sSQL); diff --git a/lib/cmd.php b/lib/cmd.php index 28d56f2e..9ec290d1 100644 --- a/lib/cmd.php +++ b/lib/cmd.php @@ -158,6 +158,16 @@ function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreError $aDSNInfo = DB::parseDSN(CONST_Database_DSN); if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432; $sCMD = 'psql -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database']; + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCMD .= ' -h ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCMD .= ' -U ' . $aDSNInfo['username']; + } + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); + } if (!$bVerbose) { $sCMD .= ' -q'; } @@ -170,15 +180,15 @@ function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreError 2 => STDERR ); $ahPipes = null; - $hProcess = @proc_open($sCMD, $aDescriptors, $ahPipes); + $hProcess = @proc_open($sCMD, $aDescriptors, $ahPipes, null, $aProcEnv); if (!is_resource($hProcess)) { fail('unable to start pgsql'); } while (strlen($sScript)) { - $written = fwrite($ahPipes[0], $sScript); - if ($written <= 0) break; - $sScript = substr($sScript, $written); + $iWritten = fwrite($ahPipes[0], $sScript); + if ($iWritten <= 0) break; + $sScript = substr($sScript, $iWritten); } fclose($ahPipes[0]); $iReturn = proc_close($hProcess); @@ -186,3 +196,22 @@ function runSQLScript($sScript, $bfatal = true, $bVerbose = false, $bIgnoreError fail("pgsql returned with error code ($iReturn)"); } } + + +function runWithEnv($sCmd, $aEnv) +{ + $aFDs = array( + 0 => array('pipe', 'r'), + 1 => STDOUT, + 2 => STDERR); + $aPipes = null; + $hProc = @proc_open($sCmd, $aFDs, $aPipes, null, $aEnv); + if (!is_resource($hProc)) { + fail('unable to run command:' . $sCmd); + } + + fclose($aPipes[0]); // no stdin + + $iStat = proc_close($hProc); + return $iStat; +} diff --git a/lib/template/address-geocodejson.php b/lib/template/address-geocodejson.php index 68fae7d1..032dcf43 100644 --- a/lib/template/address-geocodejson.php +++ b/lib/template/address-geocodejson.php @@ -76,6 +76,6 @@ if (empty($aPlace)) { 'licence' => 'ODbL', 'query' => $sQuery ), - 'features' => [$aFilteredPlaces] + 'features' => array($aFilteredPlaces) )); } diff --git a/nominatim/index.c b/nominatim/index.c index c16aba9e..bb553f7e 100644 --- a/nominatim/index.c +++ b/nominatim/index.c @@ -262,13 +262,16 @@ struct index_thread_data * thread_data, const char *structuredoutputfile) void nominatim_index(int rank_min, int rank_max, int num_threads, const char *conninfo, const char *structuredoutputfile) { - struct index_thread_data * thread_data; + struct index_thread_data *thread_data; PGconn *conn; - PGresult * res; + PGresult *res; + int num_rows = 0, status_code = 0; + int db_has_locale = 0; + char *result_string = NULL; int rank; - + int i; xmlTextWriterPtr writer; @@ -283,6 +286,23 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co exit(EXIT_FAILURE); } + res = PQexec(conn, "SHOW lc_messages"); + status_code = PQresultStatus(res); + if (status_code != PGRES_TUPLES_OK && status_code != PGRES_SINGLE_TUPLE) { + fprintf(stderr, "Failed determining database locale: %s\n", PQerrorMessage(conn)); + exit(EXIT_FAILURE); + } + num_rows = PQntuples(res); + if (num_rows > 0) + { + result_string = PQgetvalue(res, 0, 0); + if (result_string && (strlen(result_string) > 0) && (strcasecmp(result_string, "C") != 0)) + { + // non-default locale if the result exists, is non-empty, and is not "C" + db_has_locale = 1; + } + } + pg_prepare_params[0] = PG_OID_INT4; res = PQprepare(conn, "index_sectors", "select geometry_sector,count(*) from placex where rank_search = $1 and indexed_status > 0 group by geometry_sector order by geometry_sector", @@ -392,19 +412,20 @@ void nominatim_index(int rank_min, int rank_max, int num_threads, const char *co } PQclear(res); - // Make sure the error message is not localized as we parse it later. - res = PQexec(thread_data[i].conn, "SET lc_messages TO 'C'"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) + if (db_has_locale) { - fprintf(stderr, "Failed to set langauge: %s\n", PQerrorMessage(thread_data[i].conn)); - exit(EXIT_FAILURE); + // Make sure the error message is not localized as we parse it later. + res = PQexec(thread_data[i].conn, "SET lc_messages TO 'C'"); + if (PQresultStatus(res) != PGRES_COMMAND_OK) + { + fprintf(stderr, "Failed to set langauge: %s\n", PQerrorMessage(thread_data[i].conn)); + exit(EXIT_FAILURE); + } + PQclear(res); } - PQclear(res); - nominatim_exportCreatePreparedQueries(thread_data[i].conn); } - fprintf(stderr, "Starting indexing rank (%i to %i) using %i threads\n", rank_min, rank_max, num_threads); for (rank = rank_min; rank <= rank_max; rank++) diff --git a/settings/defaults.php b/settings/defaults.php index 2d8f47d0..8cdbcb5a 100644 --- a/settings/defaults.php +++ b/settings/defaults.php @@ -9,6 +9,7 @@ if (isset($_GET['debug']) && $_GET['debug']) @define('CONST_Debug', true); @define('CONST_Debug', false); @define('CONST_Database_DSN', 'pgsql://@/nominatim'); // ://:@:/ @define('CONST_Database_Web_User', 'www-data'); +@define('CONST_Database_Module_Path', CONST_InstallPath.'/module'); @define('CONST_Max_Word_Frequency', '50000'); @define('CONST_Limit_Reindexing', true); // Restrict search languages. diff --git a/sql/functions.sql b/sql/functions.sql index 993084ef..ae6c73df 100644 --- a/sql/functions.sql +++ b/sql/functions.sql @@ -35,7 +35,7 @@ CREATE OR REPLACE FUNCTION make_standard_name(name TEXT) RETURNS TEXT DECLARE o TEXT; BEGIN - o := gettokenstring(transliteration(name)); + o := public.gettokenstring(public.transliteration(name)); RETURN trim(substr(o,1,length(o))); END; $$ @@ -256,6 +256,28 @@ END; $$ LANGUAGE plpgsql IMMUTABLE; +CREATE OR REPLACE FUNCTION reverse_place_diameter(rank_search SMALLINT) + RETURNS FLOAT + AS $$ +BEGIN + IF rank_search <= 4 THEN + RETURN 5.0; + ELSIF rank_search <= 8 THEN + RETURN 1.8; + ELSIF rank_search <= 12 THEN + RETURN 0.6; + ELSIF rank_search <= 17 THEN + RETURN 0.16; + ELSIF rank_search <= 18 THEN + RETURN 0.08; + ELSIF rank_search <= 19 THEN + RETURN 0.04; + END IF; + + RETURN 0.02; +END; +$$ +LANGUAGE plpgsql IMMUTABLE; CREATE OR REPLACE FUNCTION get_postcode_rank(country_code VARCHAR(2), postcode TEXT, OUT rank_search SMALLINT, OUT rank_address SMALLINT) diff --git a/sql/partition-tables.src.sql b/sql/partition-tables.src.sql index 61ed5281..20dafcd7 100644 --- a/sql/partition-tables.src.sql +++ b/sql/partition-tables.src.sql @@ -48,6 +48,7 @@ CREATE INDEX idx_search_name_-partition-_place_id ON search_name_-partition- USI CREATE INDEX idx_search_name_-partition-_centroid ON search_name_-partition- USING GIST (centroid) {ts:address-index}; CREATE INDEX idx_search_name_-partition-_name_vector ON search_name_-partition- USING GIN (name_vector) WITH (fastupdate = off) {ts:address-index}; +DROP TABLE IF EXISTS location_road_-partition-; CREATE TABLE location_road_-partition- ( place_id BIGINT, partition SMALLINT, diff --git a/test/README.md b/test/README.md index 2a357e40..0487fd40 100644 --- a/test/README.md +++ b/test/README.md @@ -73,6 +73,11 @@ The tests can be configured with a set of environment variables: the test databases (db tests) * `TEST_DB` - name of test database (db tests) * `ABI_TEST_DB` - name of the database containing the API test data (api tests) + * `DB_HOST` - (optional) hostname of database host + * `DB_USER` - (optional) username of database login + * `DB_PASS` - (optional) password for database login + * `SERVER_MODULE_PATH` - (optional) path on the Postgres server to Nominatim + * module shared library file * `TEST_SETTINGS_TEMPLATE` - file to write temporary Nominatim settings to * `REMOVE_TEMPLATE` - if true, the template database will not be reused during the next run. Reusing the base templates speeds up tests diff --git a/test/bdd/api/reverse/queries.feature b/test/bdd/api/reverse/queries.feature index a6c1dd34..e06b1775 100644 --- a/test/bdd/api/reverse/queries.feature +++ b/test/bdd/api/reverse/queries.feature @@ -48,8 +48,14 @@ Feature: Reverse geocoding Scenario: Location off the coast When sending jsonv2 reverse coordinates 54.046489113,8.5546870529 + Then results contain + | display_name | + | Freie und Hansestadt Hamburg, Deutschland | + + Scenario: When slightly outside town, the town is not shown + When sending jsonv2 reverse coordinates -32.122,-56.114 | zoom | - | 5 | + | 15 | Then results contain - | error | - | Unable to geocode | + | display_name | + | Tacuarembó, Uruguay | diff --git a/test/bdd/api/search/params.feature b/test/bdd/api/search/params.feature index fcd2b603..feacd5f9 100644 --- a/test/bdd/api/search/params.feature +++ b/test/bdd/api/search/params.feature @@ -111,7 +111,7 @@ Feature: Search queries When sending json search query "restaurant" | bounded | viewbox | | 1 | 9.93027,53.61634,10.10073,53.54500 | - Then result has bounding box in 53.54500,53.61634,9.93027,10.10073 + Then result has centroid in 53.54500,53.61634,9.93027,10.10073 Scenario: Prefer results within viewbox When sending json search query "25 de Mayo" with address diff --git a/test/bdd/environment.py b/test/bdd/environment.py index 162346de..fdc65a5e 100644 --- a/test/bdd/environment.py +++ b/test/bdd/environment.py @@ -14,10 +14,14 @@ userconfig = { 'BUILDDIR' : os.path.join(os.path.split(__file__)[0], "../../build"), 'REMOVE_TEMPLATE' : False, 'KEEP_TEST_DB' : False, + 'DB_HOST' : None, + 'DB_USER' : None, + 'DB_PASS' : None, 'TEMPLATE_DB' : 'test_template_nominatim', 'TEST_DB' : 'test_nominatim', 'API_TEST_DB' : 'test_api_nominatim', 'TEST_SETTINGS_FILE' : '/tmp/nominatim_settings.php', + 'SERVER_MODULE_PATH' : None, 'PHPCOV' : False, # set to output directory to enable code coverage } @@ -30,9 +34,13 @@ class NominatimEnvironment(object): def __init__(self, config): self.build_dir = os.path.abspath(config['BUILDDIR']) self.src_dir = os.path.abspath(os.path.join(os.path.split(__file__)[0], "../..")) + self.db_host = config['DB_HOST'] + self.db_user = config['DB_USER'] + self.db_pass = config['DB_PASS'] self.template_db = config['TEMPLATE_DB'] self.test_db = config['TEST_DB'] self.api_test_db = config['API_TEST_DB'] + self.server_module_path = config['SERVER_MODULE_PATH'] self.local_settings_file = config['TEST_SETTINGS_FILE'] self.reuse_template = not config['REMOVE_TEMPLATE'] self.keep_scenario_db = config['KEEP_TEST_DB'] @@ -42,6 +50,17 @@ class NominatimEnvironment(object): self.template_db_done = False + def connect_database(self, dbname): + dbargs = {'database': dbname} + if self.db_host: + dbargs['host'] = self.db_host + if self.db_user: + dbargs['user'] = self.db_user + if self.db_pass: + dbargs['password'] = self.db_pass + conn = psycopg2.connect(**dbargs) + return conn + def next_code_coverage_file(self): fn = os.path.join(self.code_coverage_path, "%06d.cov" % self.code_coverage_id) self.code_coverage_id += 1 @@ -50,7 +69,11 @@ class NominatimEnvironment(object): def write_nominatim_config(self, dbname): f = open(self.local_settings_file, 'w') - f.write("\d+ )?has centroid in (?P[\d,.-]+)') +def step_impl(context, lid, coords): + if lid is None: + context.execute_steps("then at least 1 result is returned") + bboxes = zip(context.response.property_list('lat'), + context.response.property_list('lon')) + else: + context.execute_steps("then more than %sresults are returned" % lid) + res = context.response.result[int(lid)] + bboxes = [ (res['lat'], res['lon']) ] + + coord = [ float(x) for x in coords.split(',') ] + + for lat, lon in bboxes: + lat = float(lat) + lon = float(lon) + assert_greater_equal(lat, coord[0]) + assert_less_equal(lat, coord[1]) + assert_greater_equal(lon, coord[2]) + assert_less_equal(lon, coord[3]) + @then(u'there are(?P no)? duplicates') def check_for_duplicates(context, neg): context.execute_steps("then at least 1 result is returned") diff --git a/utils/setup.php b/utils/setup.php index 501ad3f2..95eda0f4 100755 --- a/utils/setup.php +++ b/utils/setup.php @@ -5,6 +5,8 @@ require_once(dirname(dirname(__FILE__)).'/settings/settings.php'); require_once(CONST_BasePath.'/lib/init-cmd.php'); ini_set('memory_limit', '800M'); +# (long-opt, short-opt, min-occurs, max-occurs, num-arguments, num-arguments, type, help) + $aCMDOptions = array( 'Create and setup nominatim search system', @@ -60,7 +62,6 @@ if ($aCMDResult['import-data'] || $aCMDResult['all']) { } } - // by default, use all but one processor, but never more than 15. $iInstances = isset($aCMDResult['threads']) ? $aCMDResult['threads'] @@ -70,10 +71,6 @@ if ($iInstances < 1) { $iInstances = 1; warn("resetting threads to $iInstances"); } -if ($iInstances > getProcessorCount()) { - $iInstances = getProcessorCount(); - warn("resetting threads to $iInstances"); -} // Assume we can steal all the cache memory in the box (unless told otherwise) if (isset($aCMDResult['osm2pgsql-cache'])) { @@ -82,6 +79,9 @@ if (isset($aCMDResult['osm2pgsql-cache'])) { $iCacheMemory = getCacheMemoryMB(); } +$sModulePath = CONST_Database_Module_Path; +info('module path: ' . $sModulePath); + $aDSNInfo = DB::parseDSN(CONST_Database_DSN); if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432; @@ -92,7 +92,22 @@ if ($aCMDResult['create-db'] || $aCMDResult['all']) { if (!PEAR::isError($oDB)) { fail('database already exists ('.CONST_Database_DSN.')'); } - passthruCheckReturn('createdb -E UTF-8 -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']); + + $sCreateDBCmd = 'createdb -E UTF-8 -p '.$aDSNInfo['port'].' '.$aDSNInfo['database']; + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCreateDBCmd .= ' -U ' . $aDSNInfo['username']; + } + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCreateDBCmd .= ' -h ' . $aDSNInfo['hostspec']; + } + + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); + } + + $result = runWithEnv($sCreateDBCmd, $aProcEnv); + if ($result != 0) fail('Error executing external command: '.$sCreateDBCmd); } if ($aCMDResult['setup-db'] || $aCMDResult['all']) { @@ -140,17 +155,8 @@ if ($aCMDResult['setup-db'] || $aCMDResult['all']) { exit(1); } - // Try accessing the C module, so we know early if something is wrong - // and can simply error out. - $sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '"; - $sSQL .= CONST_InstallPath."/module/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT"; - $sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);'; - $oResult = $oDB->query($sSQL); - - if (PEAR::isError($oResult)) { - echo "\nERROR: Failed to load nominatim module. Reason:\n"; - echo $oResult->userinfo."\n\n"; - exit(1); + if (!checkModulePresence()) { + fail('error loading nominatim.so module'); } if (!file_exists(CONST_ExtraDataPath.'/country_osm_grid.sql.gz')) { @@ -180,8 +186,8 @@ if ($aCMDResult['setup-db'] || $aCMDResult['all']) { // is only defined in the subsequently called create_tables. // Create dummies here that will be overwritten by the proper // versions in create-tables. - pgsqlRunScript('CREATE TABLE place_boundingbox ()'); - pgsqlRunScript('create type wikipedia_article_match as ()'); + pgsqlRunScript('CREATE TABLE IF NOT EXISTS place_boundingbox ()'); + pgsqlRunScript('CREATE TYPE wikipedia_article_match AS ()', false); } if ($aCMDResult['import-data'] || $aCMDResult['all']) { @@ -209,8 +215,20 @@ if ($aCMDResult['import-data'] || $aCMDResult['all']) { $osm2pgsql .= ' -lsc -O gazetteer --hstore --number-processes 1'; $osm2pgsql .= ' -C '.$iCacheMemory; $osm2pgsql .= ' -P '.$aDSNInfo['port']; + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $osm2pgsql .= ' -U ' . $aDSNInfo['username']; + } + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $osm2pgsql .= ' -H ' . $aDSNInfo['hostspec']; + } + + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); + } + $osm2pgsql .= ' -d '.$aDSNInfo['database'].' '.$aCMDResult['osm-file']; - passthruCheckReturn($osm2pgsql); + runWithEnv($osm2pgsql, $aProcEnv); $oDB =& getDB(); if (!$aCMDResult['ignore-errors'] && !chksql($oDB->getRow('select * from place limit 1'))) { @@ -221,9 +239,11 @@ if ($aCMDResult['import-data'] || $aCMDResult['all']) { if ($aCMDResult['create-functions'] || $aCMDResult['all']) { info('Create Functions'); $bDidSomething = true; - if (!file_exists(CONST_InstallPath.'/module/nominatim.so')) { - fail('nominatim module not built'); + + if (!checkModulePresence()) { + fail('error loading nominatim.so module'); } + create_sql_functions($aCMDResult); } @@ -413,14 +433,23 @@ if ($aCMDResult['load-data'] || $aCMDResult['all']) { fail(pg_last_error($aDBInstances[$iLoadThreads]->connection)); } - $bAnyBusy = true; - while ($bAnyBusy) { - $bAnyBusy = false; - for ($i = 0; $i <= $iLoadThreads; $i++) { - if (pg_connection_busy($aDBInstances[$i]->connection)) $bAnyBusy = true; + $bFailed = false; + for ($i = 0; $i <= $iLoadThreads; $i++) { + while (($hPGresult = pg_get_result($aDBInstances[$i]->connection)) !== false) { + $resultStatus = pg_result_status($hPGresult); + // PGSQL_EMPTY_QUERY, PGSQL_COMMAND_OK, PGSQL_TUPLES_OK, + // PGSQL_COPY_OUT, PGSQL_COPY_IN, PGSQL_BAD_RESPONSE, + // PGSQL_NONFATAL_ERROR and PGSQL_FATAL_ERROR + echo 'Query result ' . $i . ' is: ' . $resultStatus . "\n"; + if ($resultStatus != PGSQL_COMMAND_OK && $resultStatus != PGSQL_TUPLES_OK) { + $resultError = pg_result_error($hPGresult); + echo '-- error text ' . $i . ': ' . $resultError . "\n"; + $bFailed = true; + } } - sleep(1); - echo '.'; + } + if ($bFailed) { + fail('SQL errors loading placex and/or location_property_osmline tables'); } echo "\n"; info('Reanalysing database'); @@ -579,14 +608,34 @@ if ($aCMDResult['index'] || $aCMDResult['all']) { $bDidSomething = true; $sOutputFile = ''; $sBaseCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$iInstances.$sOutputFile; + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sBaseCmd .= ' -H ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sBaseCmd .= ' -U ' . $aDSNInfo['username']; + } + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); + } + info('Index ranks 0 - 4'); - passthruCheckReturn($sBaseCmd.' -R 4'); + $iStatus = runWithEnv($sBaseCmd.' -R 4', $aProcEnv); + if ($iStatus != 0) { + fail('error status ' . $iStatus . ' running nominatim!'); + } if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE'); info('Index ranks 5 - 25'); - passthruCheckReturn($sBaseCmd.' -r 5 -R 25'); + $iStatus = runWithEnv($sBaseCmd.' -r 5 -R 25', $aProcEnv); + if ($iStatus != 0) { + fail('error status ' . $iStatus . ' running nominatim!'); + } if (!$aCMDResult['index-noanalyse']) pgsqlRunScript('ANALYSE'); info('Index ranks 26 - 30'); - passthruCheckReturn($sBaseCmd.' -r 26'); + $iStatus = runWithEnv($sBaseCmd.' -r 26', $aProcEnv); + if ($iStatus != 0) { + fail('error status ' . $iStatus . ' running nominatim!'); + } info('Index postcodes'); $oDB =& getDB(); @@ -722,6 +771,16 @@ function pgsqlRunScriptFile($sFilename) if (!$aCMDResult['verbose']) { $sCMD .= ' -q'; } + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCMD .= ' -h ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCMD .= ' -U ' . $aDSNInfo['username']; + } + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); + } $ahGzipPipes = null; if (preg_match('/\\.gz$/', $sFilename)) { @@ -745,10 +804,9 @@ function pgsqlRunScriptFile($sFilename) 2 => array('file', '/dev/null', 'a') ); $ahPipes = null; - $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes); + $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes, null, $aProcEnv); if (!is_resource($hProcess)) fail('unable to start pgsql'); - // TODO: error checking while (!feof($ahPipes[1])) { echo fread($ahPipes[1], 4096); @@ -830,32 +888,24 @@ function pgsqlRunDropAndRestore($sDumpFile) $aDSNInfo = DB::parseDSN(CONST_Database_DSN); if (!isset($aDSNInfo['port']) || !$aDSNInfo['port']) $aDSNInfo['port'] = 5432; $sCMD = 'pg_restore -p '.$aDSNInfo['port'].' -d '.$aDSNInfo['database'].' -Fc --clean '.$sDumpFile; - - $aDescriptors = array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('file', '/dev/null', 'a') - ); - $ahPipes = null; - $hProcess = proc_open($sCMD, $aDescriptors, $ahPipes); - if (!is_resource($hProcess)) fail('unable to start pg_restore'); - - fclose($ahPipes[0]); - - // TODO: error checking - while (!feof($ahPipes[1])) { - echo fread($ahPipes[1], 4096); + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCMD .= ' -h ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCMD .= ' -U ' . $aDSNInfo['username']; + } + $aProcEnv = null; + if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); } - fclose($ahPipes[1]); - $iReturn = proc_close($hProcess); + $iReturn = runWithEnv($sCMD, $aProcEnv); } -function passthruCheckReturn($cmd) +function passthruCheckReturn($sCmd) { - $result = -1; - passthru($cmd, $result); - if ($result != 0) fail('Error executing external command: '.$cmd); + $iResult = -1; + passthru($sCmd, $iResult); } function replace_tablespace($sTemplate, $sTablespace, $sSql) @@ -871,8 +921,9 @@ function replace_tablespace($sTemplate, $sTablespace, $sSql) function create_sql_functions($aCMDResult) { + global $sModulePath; $sTemplate = file_get_contents(CONST_BasePath.'/sql/functions.sql'); - $sTemplate = str_replace('{modulepath}', CONST_InstallPath.'/module', $sTemplate); + $sTemplate = str_replace('{modulepath}', $sModulePath, $sTemplate); if ($aCMDResult['enable-diff-updates']) { $sTemplate = str_replace('RETURN NEW; -- %DIFFUPDATES%', '--', $sTemplate); } @@ -890,3 +941,26 @@ function create_sql_functions($aCMDResult) } pgsqlRunScript($sTemplate); } + +function checkModulePresence() +{ + // Try accessing the C module, so we know early if something is wrong + // and can simply error out. + global $sModulePath; + $sSQL = "CREATE FUNCTION nominatim_test_import_func(text) RETURNS text AS '"; + $sSQL .= $sModulePath."/nominatim.so', 'transliteration' LANGUAGE c IMMUTABLE STRICT"; + $sSQL .= ';DROP FUNCTION nominatim_test_import_func(text);'; + + $oDB =& getDB(); + $oResult = $oDB->query($sSQL); + + $bResult = true; + + if (PEAR::isError($oResult)) { + echo "\nERROR: Failed to load nominatim module. Reason:\n"; + echo $oResult->userinfo."\n\n"; + $bResult = false; + } + + return $bResult; +} diff --git a/utils/update.php b/utils/update.php index 6caa7e4b..c70bdf54 100755 --- a/utils/update.php +++ b/utils/update.php @@ -5,6 +5,8 @@ require_once(dirname(dirname(__FILE__)).'/settings/settings.php'); require_once(CONST_BasePath.'/lib/init-cmd.php'); ini_set('memory_limit', '800M'); +# (long-opt, short-opt, min-occurs, max-occurs, num-arguments, num-arguments, type, help) + $aCMDOptions = array( 'Import / update / index osm data', @@ -14,6 +16,7 @@ $aCMDOptions array('init-updates', '', 0, 1, 0, 0, 'bool', 'Set up database for updating'), array('check-for-updates', '', 0, 1, 0, 0, 'bool', 'Check if new updates are available'), + array('no-update-functions', '', 0, 1, 0, 0, 'bool', 'Do not update trigger functions to support differential updates (assuming the diff update logic is already present)'), array('import-osmosis', '', 0, 1, 0, 0, 'bool', 'Import updates once'), array('import-osmosis-all', '', 0, 1, 0, 0, 'bool', 'Import updates forever'), array('no-index', '', 0, 1, 0, 0, 'bool', 'Do not index the new data'), @@ -56,6 +59,17 @@ if ($iCacheMemory + 500 > getTotalMemoryMB()) { echo "WARNING: resetting cache memory to $iCacheMemory\n"; } $sOsm2pgsqlCmd = CONST_Osm2pgsql_Binary.' -klas --number-processes 1 -C '.$iCacheMemory.' -O gazetteer -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port']; +if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sOsm2pgsqlCmd .= ' -U ' . $aDSNInfo['username']; +} +if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sOsm2pgsqlCmd .= ' -H ' . $aDSNInfo['hostspec']; +} +$aProcEnv = null; +if (isset($aDSNInfo['password']) && $aDSNInfo['password']) { + $aProcEnv = array_merge(array('PGPASSWORD' => $aDSNInfo['password']), $_ENV); +} + if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) { $sOsm2pgsqlCmd .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File; } @@ -84,11 +98,13 @@ if ($aResult['init-updates']) { echo "and have set up CONST_Pyosmium_Binary to point to pyosmium-get-changes.\n"; fail('pyosmium-get-changes not found or not usable'); } - $sSetup = CONST_InstallPath.'/utils/setup.php'; - $iRet = -1; - passthru($sSetup.' --create-functions --enable-diff-updates', $iRet); - if ($iRet != 0) { - fail('Error running setup script'); + if (!$aResult['no-update-functions']) { + $sSetup = CONST_InstallPath.'/utils/setup.php'; + $iRet = -1; + passthru($sSetup.' --create-functions --enable-diff-updates', $iRet); + if ($iRet != 0) { + fail('Error running setup script'); + } } $sDatabaseDate = getDatabaseDate($oDB); @@ -137,7 +153,7 @@ if (isset($aResult['import-diff']) || isset($aResult['import-file'])) { // Import the file $sCMD = $sOsm2pgsqlCmd.' '.$sNextFile; echo $sCMD."\n"; - exec($sCMD, $sJunk, $iErrorLevel); + $iErrorLevel = runWithEnv($sCMD, $aProcEnv); if ($iErrorLevel) { fail("Error from osm2pgsql, $iErrorLevel\n"); @@ -189,7 +205,7 @@ if ($bHaveDiff) { // import generated change file $sCMD = $sOsm2pgsqlCmd.' '.$sTemporaryFile; echo $sCMD."\n"; - exec($sCMD, $sJunk, $iErrorLevel); + $iErrorLevel = runWithEnv($sCMD, $aProcEnv); if ($iErrorLevel) { fail("osm2pgsql exited with error level $iErrorLevel\n"); } @@ -273,7 +289,15 @@ if ($aResult['recompute-word-counts']) { } if ($aResult['index']) { - passthru(CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']); + $sCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances'].' -r '.$aResult['index-rank']; + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCmd .= ' -H ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCmd .= ' -U ' . $aDSNInfo['username']; + } + + runWithEnv($sCmd, $aProcEnv); } if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) { @@ -287,6 +311,12 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) { $sCMDDownload = CONST_Pyosmium_Binary.' --server '.CONST_Replication_Url.' -o '.$sImportFile.' -s '.CONST_Replication_Max_Diff_size; $sCMDImport = $sOsm2pgsqlCmd.' '.$sImportFile; $sCMDIndex = CONST_InstallPath.'/nominatim/nominatim -i -d '.$aDSNInfo['database'].' -P '.$aDSNInfo['port'].' -t '.$aResult['index-instances']; + if (isset($aDSNInfo['hostspec']) && $aDSNInfo['hostspec']) { + $sCMDIndex .= ' -H ' . $aDSNInfo['hostspec']; + } + if (isset($aDSNInfo['username']) && $aDSNInfo['username']) { + $sCMDIndex .= ' -U ' . $aDSNInfo['username']; + } while (true) { $fStartTime = time(); @@ -354,7 +384,7 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) { $fCMDStartTime = time(); echo $sCMDImport."\n"; unset($sJunk); - exec($sCMDImport, $sJunk, $iErrorLevel); + $iErrorLevel = runWithEnv($sCMDImport, $aProcEnv); if ($iErrorLevel) { echo "Error executing osm2pgsql: $iErrorLevel\n"; exit($iErrorLevel); @@ -383,7 +413,7 @@ if ($aResult['import-osmosis'] || $aResult['import-osmosis-all']) { $fCMDStartTime = time(); echo "$sThisIndexCmd\n"; - exec($sThisIndexCmd, $sJunk, $iErrorLevel); + $iErrorLevel = runWithEnv($sThisIndexCmd, $aProcEnv); if ($iErrorLevel) { echo "Error: $iErrorLevel\n"; exit($iErrorLevel);