]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge remote-tracking branch 'upstream/master'
authorSarah Hoffmann <lonvia@denofr.de>
Mon, 15 Mar 2021 13:09:19 +0000 (14:09 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Mon, 15 Mar 2021 13:09:19 +0000 (14:09 +0100)
lib-php/ReverseGeocode.php
lib-php/admin/setup.php
lib-php/setup/SetupClass.php
nominatim/clicmd/setup.py
nominatim/clicmd/transition.py
nominatim/tools/database_import.py
nominatim/tools/refresh.py
test/bdd/api/reverse/queries.feature
test/python/test_cli.py
test/python/test_tools_database_import.py

index b420e5dd99f8ba69fadc0488684784a7ffcb3794..cf396b7ab8fa0352f8554111dac87dd942950f52 100644 (file)
@@ -280,29 +280,6 @@ class ReverseGeocode
                 $iPlaceID = $aPlace['place_id'];
                 $oResult = new Result($iPlaceID);
                 $iRankAddress = $aPlace['rank_address'];
-                $iParentPlaceID = $aPlace['parent_place_id'];
-            }
-
-            if ($bDoInterpolation && $iMaxRank >= 30) {
-                $fDistance = $fSearchDiam;
-                if ($aPlace) {
-                    // We can't reliably go from the closest street to an
-                    // interpolation line because the closest interpolation
-                    // may have a different street segments as a parent.
-                    // Therefore allow an interpolation line to take precendence
-                    // even when the street is closer.
-                    $fDistance = $iRankAddress < 28 ? 0.001 : $aPlace['distance'];
-                }
-
-                $aHouse = $this->lookupInterpolation($sPointSQL, $fDistance);
-                Debug::printVar('Interpolation result', $aPlace);
-
-                if ($aHouse) {
-                    $oResult = new Result($aHouse['place_id'], Result::TABLE_OSMLINE);
-                    $oResult->iHouseNumber = closestHouseNumber($aHouse);
-                    $aPlace = $aHouse;
-                    $iRankAddress = 30;
-                }
             }
 
             if ($aPlace) {
@@ -328,7 +305,9 @@ class ReverseGeocode
                     Debug::printVar('Closest POI result', $aStreet);
 
                     if ($aStreet) {
+                        $aPlace = $aStreet;
                         $oResult = new Result($aStreet['place_id']);
+                        $iRankAddress = 30;
                     }
                 }
 
@@ -351,11 +330,37 @@ class ReverseGeocode
                     Debug::printVar('Tiger house number result', $aPlaceTiger);
 
                     if ($aPlaceTiger) {
+                        $aPlace = $aPlaceTiger;
                         $oResult = new Result($aPlaceTiger['place_id'], Result::TABLE_TIGER);
                         $oResult->iHouseNumber = closestHouseNumber($aPlaceTiger);
+                        $iRankAddress = 30;
                     }
                 }
-            } else {
+            }
+
+            if ($bDoInterpolation && $iMaxRank >= 30) {
+                $fDistance = $fSearchDiam;
+                if ($aPlace) {
+                    // We can't reliably go from the closest street to an
+                    // interpolation line because the closest interpolation
+                    // may have a different street segments as a parent.
+                    // Therefore allow an interpolation line to take precendence
+                    // even when the street is closer.
+                    $fDistance = $iRankAddress < 28 ? 0.001 : $aPlace['distance'];
+                }
+
+                $aHouse = $this->lookupInterpolation($sPointSQL, $fDistance);
+                Debug::printVar('Interpolation result', $aPlace);
+
+                if ($aHouse) {
+                    $oResult = new Result($aHouse['place_id'], Result::TABLE_OSMLINE);
+                    $oResult->iHouseNumber = closestHouseNumber($aHouse);
+                    $aPlace = $aHouse;
+                    $iRankAddress = 30;
+                }
+            }
+
+            if (!$aPlace) {
                 // if no POI or street is found ...
                 $oResult = $this->lookupLargeArea($sPointSQL, 25);
             }
index 0b0084957d6ecef3081409ce3a6e21da7cb6cfb9..7523527a0192ebe5d8a59d02e621a6cf645e596d 100644 (file)
@@ -198,7 +198,7 @@ if ($aCMDResult['create-search-indices'] || $aCMDResult['all']) {
 
 if ($aCMDResult['create-country-names'] || $aCMDResult['all']) {
     $bDidSomething = true;
-    $oSetup->createCountryNames($aCMDResult);
+    run(clone($oNominatimCmd))->addParams('transition', '--create-country-names');
 }
 
 if ($aCMDResult['setup-website'] || $aCMDResult['all']) {
index cf2ac6da29ff0749c58f9cb92fa31725ca0e9e83..d07adce73a61992a038ad1bf8eb559fb9797d50d 100755 (executable)
@@ -130,33 +130,6 @@ class SetupFunctions
         $this->db()->exec($sSQL);
     }
 
-    public function createCountryNames()
-    {
-        info('Create search index for default country names');
-
-        $this->pgsqlRunScript("select getorcreate_country(make_standard_name('uk'), 'gb')");
-        $this->pgsqlRunScript("select getorcreate_country(make_standard_name('united states'), 'us')");
-        $this->pgsqlRunScript('select count(*) from (select getorcreate_country(make_standard_name(country_code), country_code) from country_name where country_code is not null) as x');
-        $this->pgsqlRunScript("select count(*) from (select getorcreate_country(make_standard_name(name->'name'), country_code) from country_name where name ? 'name') as x");
-        $sSQL = 'select count(*) from (select getorcreate_country(make_standard_name(v),'
-            .'country_code) from (select country_code, skeys(name) as k, svals(name) as v from country_name) x where k ';
-        $sLanguages = getSetting('LANGUAGES');
-        if ($sLanguages) {
-            $sSQL .= 'in ';
-            $sDelim = '(';
-            foreach (explode(',', $sLanguages) as $sLang) {
-                $sSQL .= $sDelim."'name:$sLang'";
-                $sDelim = ',';
-            }
-            $sSQL .= ')';
-        } else {
-            // all include all simple name tags
-            $sSQL .= "like 'name:%'";
-        }
-        $sSQL .= ') v';
-        $this->pgsqlRunScript($sSQL);
-    }
-
     /**
      * Return the connection to the database.
      *
index 71980739756c2e0f3a885689e3ad547e6ae1e6e7..056643aabfbbcd459bd874a307f0a41029fe8750 100644 (file)
@@ -130,8 +130,8 @@ class SetupAll:
             database_import.create_search_indices(conn, args.config,
                                                   args.sqllib_dir,
                                                   drop=args.no_updates)
-        run_legacy_script('setup.php', '--create-country-names',
-                          nominatim_env=args, throw_on_fail=not args.ignore_errors)
+            LOG.warning('Create search index for default country names.')
+            database_import.create_country_names(conn, args.config)
 
         webdir = args.project_dir / 'website'
         LOG.warning('Setup website at %s', webdir)
index 0a89cb037260dfa7eeb9344d9da68c215a1b2dfa..c9341f496d57efac9fd3527fdfffe3ba73618be1 100644 (file)
@@ -43,6 +43,8 @@ class AdminTransition:
                            help='Index the data')
         group.add_argument('--create-search-indices', action='store_true',
                            help='Create additional indices required for search and update')
+        group.add_argument('--create-country-names', action='store_true',
+                           help='Create search index for default country names.')
         group = parser.add_argument_group('Options')
         group.add_argument('--no-partitions', action='store_true',
                            help='Do not partition search indices')
@@ -62,7 +64,7 @@ class AdminTransition:
                            help='File to import')
 
     @staticmethod
-    def run(args):
+    def run(args): # pylint: disable=too-many-statements
         from ..tools import database_import, tiger_data
         from ..tools import refresh
 
@@ -137,3 +139,8 @@ class AdminTransition:
                                       args.threads or 1,
                                       args.config,
                                       args.sqllib_dir)
+
+        if args.create_country_names:
+            LOG.warning('Create search index for default country names.')
+            with connect(args.config.get_libpq_dsn()) as conn:
+                database_import.create_country_names(conn, args.config)
index 017c74b6186781e6ba49970d3bcfd9ffd65e30ae..433cd8afaca30372ab58698821fee06092748b1a 100644 (file)
@@ -306,3 +306,35 @@ def create_search_indices(conn, config, sqllib_dir, drop=False):
     sql = SQLPreprocessor(conn, config, sqllib_dir)
 
     sql.run_sql_file(conn, 'indices.sql', drop=drop)
+
+def create_country_names(conn, config):
+    """ Create search index for default country names.
+    """
+
+    with conn.cursor() as cur:
+        cur.execute("""SELECT getorcreate_country(make_standard_name('uk'), 'gb')""")
+        cur.execute("""SELECT getorcreate_country(make_standard_name('united states'), 'us')""")
+        cur.execute("""SELECT COUNT(*) FROM
+                       (SELECT getorcreate_country(make_standard_name(country_code),
+                       country_code) FROM country_name WHERE country_code is not null) AS x""")
+        cur.execute("""SELECT COUNT(*) FROM
+                       (SELECT getorcreate_country(make_standard_name(name->'name'), country_code) 
+                       FROM country_name WHERE name ? 'name') AS x""")
+        sql_statement = """SELECT COUNT(*) FROM (SELECT getorcreate_country(make_standard_name(v),
+                           country_code) FROM (SELECT country_code, skeys(name)
+                           AS k, svals(name) AS v FROM country_name) x WHERE k"""
+
+        languages = config.LANGUAGES
+
+        if languages:
+            sql_statement = "{} IN (".format(sql_statement)
+            delim = ''
+            for language in languages.split(','):
+                sql_statement = "{}{}'name:{}'".format(sql_statement, delim, language)
+                delim = ', '
+            sql_statement = '{})'.format(sql_statement)
+        else:
+            sql_statement = "{} LIKE 'name:%'".format(sql_statement)
+        sql_statement = "{}) v".format(sql_statement)
+        cur.execute(sql_statement)
+    conn.commit()
index c00a2e10e0fa56b365991c738e2f455f3ebc51df..581c69e8a110875406dfc76cf4a0f245ef0e3d9a 100644 (file)
@@ -84,7 +84,7 @@ def create_functions(conn, config, sqllib_dir,
     sql = SQLPreprocessor(conn, config, sqllib_dir)
 
     sql.run_sql_file(conn, 'functions.sql',
-                     disable_diff_update=not enable_diff_updates,
+                     disable_diff_updates=not enable_diff_updates,
                      debug=enable_debug)
 
 
index 204751a075478e566f974822d25c3fe86996d71d..303af2c35734120872587911f1d7282a15f24c39 100644 (file)
@@ -70,6 +70,23 @@ Feature: Reverse geocoding
          | display_name |
          | 1021, Grosssteg, Sücka, Triesenberg, Oberland, 9497, Liechtenstein |
 
+    # github 2214
+    Scenario: Interpolations do not override house numbers when they are closer
+        When sending jsonv2 reverse coordinates 47.11778,9.57255
+         | zoom |
+         | 18 |
+        Then results contain
+         | display_name |
+         | 5, Grosssteg, Steg, Triesenberg, Oberland, 9497, Liechtenstein |
+
+    Scenario: Interpolations do not override house numbers when they are closer (2)
+        When sending jsonv2 reverse coordinates 47.11834,9.57167
+         | zoom |
+         | 18 |
+        Then results contain
+         | display_name |
+         | 3, Grosssteg, Sücka, Triesenberg, Oberland, 9497, Liechtenstein |
+
     Scenario: When on a street with zoom 18, the closest housenumber is returned
         When sending jsonv2 reverse coordinates 47.11755503977281,9.572722250405036
          | zoom |
index 1f9cd06d4be7e0401e6162ac2cc60da2bea49149..918d84993d603270638209aadd37eadd920d8f32 100644 (file)
@@ -95,6 +95,7 @@ def test_import_full(temp_db, mock_func_factory):
         mock_func_factory(nominatim.tools.database_import, 'create_table_triggers'),
         mock_func_factory(nominatim.tools.database_import, 'create_partition_tables'),
         mock_func_factory(nominatim.tools.database_import, 'create_search_indices'),
+        mock_func_factory(nominatim.tools.database_import, 'create_country_names'),
         mock_func_factory(nominatim.tools.refresh, 'load_address_levels_from_file'),
         mock_func_factory(nominatim.indexer.indexer.Indexer, 'index_full'),
         mock_func_factory(nominatim.tools.refresh, 'setup_website'),
index 453248340d9b876132ee21cdee709eef7c860f98..e2852acb45adae34d5761b0e70ac6636341c9ea2 100644 (file)
@@ -200,3 +200,32 @@ def test_load_data(dsn, src_dir, place_row, placex_table, osmline_table, word_ta
 
     assert temp_db_cursor.table_rows('placex') == 30
     assert temp_db_cursor.table_rows('location_property_osmline') == 1
+
+@pytest.mark.parametrize("languages", (False, True))
+def test_create_country_names(temp_db_conn, temp_db_cursor, def_config,
+                              temp_db_with_extensions, monkeypatch, languages):
+    if languages:
+        monkeypatch.setenv('NOMINATIM_LANGUAGES', 'fr,en')
+    temp_db_cursor.execute("""CREATE FUNCTION make_standard_name (name TEXT)
+                                  RETURNS TEXT AS $$ SELECT 'a'::TEXT $$ LANGUAGE SQL
+                               """)
+    temp_db_cursor.execute('CREATE TABLE country_name (country_code varchar(2), name hstore)')
+    temp_db_cursor.execute('CREATE TABLE word (code varchar(2))')
+    temp_db_cursor.execute("""INSERT INTO country_name VALUES ('us',
+                              '"name"=>"us","name:af"=>"us"')""")
+    temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION getorcreate_country(lookup_word TEXT,
+                            lookup_country_code varchar(2))
+                            RETURNS INTEGER
+                            AS $$
+                            BEGIN
+                                INSERT INTO word VALUES (lookup_country_code);
+                                RETURN 5;
+                            END;
+                            $$
+                            LANGUAGE plpgsql;
+                               """)
+    database_import.create_country_names(temp_db_conn, def_config)
+    if languages:
+        assert temp_db_cursor.table_rows('word') == 4
+    else:
+        assert temp_db_cursor.table_rows('word') == 5